// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdio.h>
#include <sys/mman.h>

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"

#include "glbench/main.h"
#include "glbench/testbase.h"
#include "glbench/utils.h"
#include "glbench/yuv2rgb.h"

namespace glbench {

class YuvToRgbTest : public DrawArraysTestFunc {
 public:
  YuvToRgbTest() {
    memset(textures_, 0, sizeof(textures_));
  }
  virtual ~YuvToRgbTest() {
    glDeleteTextures(arraysize(textures_), textures_);
  }
  virtual bool Run();
  virtual const char* Name() const { return "yuv_to_rgb"; }

  enum YuvTestFlavor {
    YUV_PLANAR_ONE_TEXTURE_SLOW,
    YUV_PLANAR_ONE_TEXTURE_FASTER,
    YUV_PLANAR_THREE_TEXTURES,
    YUV_SEMIPLANAR_TWO_TEXTURES,
  };

 private:
  GLuint textures_[6];
  YuvTestFlavor flavor_;
  GLuint YuvToRgbShaderProgram(GLuint vertex_buffer, int width, int height);
  bool SetupTextures();
  DISALLOW_COPY_AND_ASSIGN(YuvToRgbTest);
};


GLuint YuvToRgbTest::YuvToRgbShaderProgram(GLuint vertex_buffer,
                                           int width, int height) {
  const char *vertex = NULL;
  const char *fragment = NULL;

  switch (flavor_) {
    case YUV_PLANAR_ONE_TEXTURE_SLOW:
      vertex = YUV2RGB_VERTEX_1;
      fragment = YUV2RGB_FRAGMENT_1;
      break;
    case YUV_PLANAR_ONE_TEXTURE_FASTER:
      vertex = YUV2RGB_VERTEX_2;
      fragment = YUV2RGB_FRAGMENT_2;
      break;
    case YUV_PLANAR_THREE_TEXTURES:
      vertex = YUV2RGB_VERTEX_34;
      fragment = YUV2RGB_FRAGMENT_3;
      break;
    case YUV_SEMIPLANAR_TWO_TEXTURES:
      vertex = YUV2RGB_VERTEX_34;
      fragment = YUV2RGB_FRAGMENT_4;
      break;
  }

  size_t size_vertex = 0;
  size_t size_fragment = 0;
  char *yuv_to_rgb_vertex = static_cast<char *>(
      MmapFile(vertex, &size_vertex));
  char *yuv_to_rgb_fragment = static_cast<char *>(
      MmapFile(fragment, &size_fragment));
  GLuint program = 0;

  if (!yuv_to_rgb_fragment || !yuv_to_rgb_vertex)
    goto done;

  {
    program = InitShaderProgramWithHeader(NULL, yuv_to_rgb_vertex,
                                          yuv_to_rgb_fragment);

    int imageWidthUniform = glGetUniformLocation(program, "imageWidth");
    int imageHeightUniform = glGetUniformLocation(program, "imageHeight");

    int textureSampler = glGetUniformLocation(program, "textureSampler");
    int evenLinesSampler = glGetUniformLocation(program, "paritySampler");
    int ySampler = glGetUniformLocation(program, "ySampler");
    int uSampler = glGetUniformLocation(program, "uSampler");
    int vSampler = glGetUniformLocation(program, "vSampler");
    int uvSampler = glGetUniformLocation(program, "uvSampler");

    glUniform1f(imageWidthUniform, width);
    glUniform1f(imageHeightUniform, height);
    glUniform1i(textureSampler, 0);
    glUniform1i(evenLinesSampler, 1);

    glUniform1i(ySampler, 2);
    glUniform1i(uSampler, 3);
    glUniform1i(vSampler, 4);
    glUniform1i(uvSampler, 5);

    {
      // This is used only if USE_UNIFORM_MATRIX is enabled in fragment
      // shaders.
      float c[] = {
        1.0,    1.0,    1.0,   0.0,
        0.0,   -0.344,  1.772, 0.0,
        1.402, -0.714,  0.0,   0.0,
        -0.701,  0.529, -0.886, 1.0
      };
      int conversion = glGetUniformLocation(program, "conversion");
      glUniformMatrix4fv(conversion, 1, GL_FALSE, c);
      assert(glGetError() == 0);
    }

    int attribute_index = glGetAttribLocation(program, "c");
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
    glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(attribute_index);
    return program;
  }


done:
  munmap(yuv_to_rgb_fragment, size_fragment);
  munmap(yuv_to_rgb_fragment, size_vertex);
  return program;
}


bool YuvToRgbTest::SetupTextures() {
  bool ret = false;
  size_t size = 0;
  char evenodd[2] = {0, static_cast<char>(-1)};
  char* pixels = static_cast<char *>(MmapFile(YUV2RGB_NAME, &size));
  const int luma_size = YUV2RGB_WIDTH * YUV2RGB_PIXEL_HEIGHT;
  const int chroma_size = YUV2RGB_WIDTH/2 * YUV2RGB_PIXEL_HEIGHT/2;
  const char* u_plane = pixels + luma_size;
  const char* v_plane = pixels + luma_size + chroma_size;
  if (!pixels) {
    printf("# Error: Could not open image file: %s\n", YUV2RGB_NAME);
    goto done;
  }
  if (size != YUV2RGB_SIZE) {
    printf("# Error: Image file of wrong size, got %d, expected %d\n",
           static_cast<int>(size), YUV2RGB_SIZE);
    goto done;
  }

  glGenTextures(arraysize(textures_), textures_);
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, textures_[0]);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, YUV2RGB_WIDTH, YUV2RGB_HEIGHT,
               0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels);

  glActiveTexture(GL_TEXTURE1);
  glBindTexture(GL_TEXTURE_2D, textures_[1]);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 1,
               0, GL_LUMINANCE, GL_UNSIGNED_BYTE, evenodd);

  glActiveTexture(GL_TEXTURE2);
  glBindTexture(GL_TEXTURE_2D, textures_[2]);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
               YUV2RGB_WIDTH, YUV2RGB_PIXEL_HEIGHT,
               0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels);

  glActiveTexture(GL_TEXTURE3);
  glBindTexture(GL_TEXTURE_2D, textures_[3]);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
               YUV2RGB_WIDTH/2, YUV2RGB_PIXEL_HEIGHT/2,
               0, GL_LUMINANCE, GL_UNSIGNED_BYTE, u_plane);

  glActiveTexture(GL_TEXTURE4);
  glBindTexture(GL_TEXTURE_2D, textures_[4]);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
               YUV2RGB_WIDTH/2, YUV2RGB_PIXEL_HEIGHT/2,
               0, GL_LUMINANCE, GL_UNSIGNED_BYTE, v_plane);

  {
    scoped_ptr<char[]> buf_uv(new char[chroma_size * 2]);
    char* buf_uv_ptr = buf_uv.get();
    for (int i = 0; i < chroma_size; i++) {
        *buf_uv_ptr++ = u_plane[i];
        *buf_uv_ptr++ = v_plane[i];
    }

    glActiveTexture(GL_TEXTURE5);
    glBindTexture(GL_TEXTURE_2D, textures_[5]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA,
                 YUV2RGB_WIDTH/2, YUV2RGB_PIXEL_HEIGHT/2,
                 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, buf_uv.get());
  }

  for (unsigned int i = 0; i < arraysize(textures_); i++) {
    glActiveTexture(GL_TEXTURE0 + i);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  }

  ret = true;

done:
  munmap(pixels, size);
  return ret;
}


bool YuvToRgbTest::Run() {
  glClearColor(0.f, 1.f, 0.f, 1.f);

  GLuint program = 0;
  GLuint vertex_buffer = 0;
  GLfloat vertices[8] = {
    0.f, 0.f,
    1.f, 0.f,
    0.f, 1.f,
    1.f, 1.f,
  };
  vertex_buffer = SetupVBO(GL_ARRAY_BUFFER, sizeof(vertices), vertices);

  if (!SetupTextures())
    return false;

  glViewport(0, 0, YUV2RGB_WIDTH, YUV2RGB_PIXEL_HEIGHT);

  YuvTestFlavor flavors[] = {
    YUV_PLANAR_ONE_TEXTURE_SLOW, YUV_PLANAR_ONE_TEXTURE_FASTER,
    YUV_PLANAR_THREE_TEXTURES, YUV_SEMIPLANAR_TWO_TEXTURES
  };
  const char* flavor_names[] = {
    "yuv_shader_1", "yuv_shader_2", "yuv_shader_3", "yuv_shader_4"
  };
  for (unsigned int f = 0; f < arraysize(flavors); f++) {
    flavor_ = flavors[f];

    program = YuvToRgbShaderProgram(vertex_buffer,
                                    YUV2RGB_WIDTH, YUV2RGB_PIXEL_HEIGHT);
    if (program) {
      FillRateTestNormalSubWindow(flavor_names[f],
                                  std::min(YUV2RGB_WIDTH, g_width),
                                  std::min(YUV2RGB_PIXEL_HEIGHT, g_height));
    } else {
      printf("# Error: Could not set up YUV shader.\n");
    }

    glDeleteProgram(program);
  }

  glDeleteBuffers(1, &vertex_buffer);

  return true;
}


TestBase* GetYuvToRgbTest() {
  return new YuvToRgbTest();
}

}  // namespace glbench
