// Copyright (c) 2012 The Chromium 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 "gpu/command_buffer/tests/gl_test_utils.h"

#include <GLES2/gl2extchromium.h>
#include <stdint.h>
#include <stdio.h>

#include <memory>
#include <string>

#include "base/command_line.h"
#include "base/stl_util.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/config/gpu_driver_bug_workarounds.h"
#include "gpu/config/gpu_info_collector.h"
#include "gpu/config/gpu_preferences.h"
#include "gpu/config/gpu_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gl/init/gl_factory.h"

#if defined(OS_LINUX)
#include "ui/gl/gl_image_native_pixmap.h"
#endif

namespace gpu {

// GCC requires these declarations, but MSVC requires they not be present.
#ifndef COMPILER_MSVC
const uint8_t GLTestHelper::kCheckClearValue;
#endif

bool GLTestHelper::InitializeGL(gl::GLImplementation gl_impl) {
  if (gl_impl == gl::GLImplementation::kGLImplementationNone) {
    if (!gl::init::InitializeGLNoExtensionsOneOff())
      return false;
  } else {
    if (!gl::init::InitializeGLOneOffImplementation(
            gl_impl,
            false,  // fallback_to_software_gl
            false,  // gpu_service_logging
            false,  // disable_gl_drawing
            false   // init_extensions
            )) {
      return false;
    }
  }

  gpu::GPUInfo gpu_info;
  gpu::CollectGraphicsInfoForTesting(&gpu_info);
  gpu::GLManager::g_gpu_feature_info = gpu::ComputeGpuFeatureInfo(
      gpu_info, gpu::GpuPreferences(), base::CommandLine::ForCurrentProcess(),
      nullptr  // needs_more_info
      );

  gl::init::SetDisabledExtensionsPlatform(
      gpu::GLManager::g_gpu_feature_info.disabled_extensions);
  return gl::init::InitializeExtensionSettingsOneOffPlatform();
}

bool GLTestHelper::InitializeGLDefault() {
  return GLTestHelper::InitializeGL(
      gl::GLImplementation::kGLImplementationNone);
}

bool GLTestHelper::HasExtension(const char* extension) {
  // Pad with an extra space to ensure that |extension| is not a substring of
  // another extension.
  std::string extensions =
      std::string(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))) +
      " ";
  std::string extension_padded = std::string(extension) + " ";
  return extensions.find(extension_padded) != std::string::npos;
}

bool GLTestHelper::CheckGLError(const char* msg, int line) {
   bool success = true;
   GLenum error = GL_NO_ERROR;
   while ((error = glGetError()) != GL_NO_ERROR) {
     success = false;
     EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), error)
         << "GL ERROR in " << msg << " at line " << line << " : " << error;
   }
   return success;
}

GLuint GLTestHelper::CompileShader(GLenum type, const char* shaderSrc) {
  GLuint shader = glCreateShader(type);
  // Load the shader source
  glShaderSource(shader, 1, &shaderSrc, nullptr);
  // Compile the shader
  glCompileShader(shader);

  return shader;
}

GLuint GLTestHelper::LoadShader(GLenum type, const char* shaderSrc) {
  GLuint shader = CompileShader(type, shaderSrc);

  // Check the compile status
  GLint value = 0;
  glGetShaderiv(shader, GL_COMPILE_STATUS, &value);
  if (value == 0) {
    char buffer[1024];
    GLsizei length = 0;
    glGetShaderInfoLog(shader, sizeof(buffer), &length, buffer);
    std::string log(buffer, length);
    EXPECT_EQ(1, value) << "Error compiling shader: " << log;
    glDeleteShader(shader);
    shader = 0;
  }
  return shader;
}

GLuint GLTestHelper::LinkProgram(
    GLuint vertex_shader, GLuint fragment_shader) {
  // Create the program object
  GLuint program = glCreateProgram();
  glAttachShader(program, vertex_shader);
  glAttachShader(program, fragment_shader);
  // Link the program
  glLinkProgram(program);

  return program;
}

GLuint GLTestHelper::SetupProgram(
    GLuint vertex_shader, GLuint fragment_shader) {
  GLuint program = LinkProgram(vertex_shader, fragment_shader);
  // Check the link status
  GLint linked = 0;
  glGetProgramiv(program, GL_LINK_STATUS, &linked);
  if (linked == 0) {
    char buffer[1024];
    GLsizei length = 0;
    glGetProgramInfoLog(program, sizeof(buffer), &length, buffer);
    std::string log(buffer, length);
    EXPECT_EQ(1, linked) << "Error linking program: " << log;
    glDeleteProgram(program);
    program = 0;
  }
  return program;
}

GLuint GLTestHelper::LoadProgram(
    const char* vertex_shader_source,
    const char* fragment_shader_source) {
  GLuint vertex_shader = LoadShader(
      GL_VERTEX_SHADER, vertex_shader_source);
  GLuint fragment_shader = LoadShader(
      GL_FRAGMENT_SHADER, fragment_shader_source);
  if (!vertex_shader || !fragment_shader) {
    return 0;
  }
  return SetupProgram(vertex_shader, fragment_shader);
}

GLuint GLTestHelper::SetupUnitQuad(GLint position_location) {
  GLuint vbo = 0;
  glGenBuffers(1, &vbo);
  glBindBuffer(GL_ARRAY_BUFFER, vbo);
  static const float vertices[] = {
      1.0f, 1.0f, -1.0f, 1.0f,  -1.0f, -1.0f,
      1.0f, 1.0f, -1.0f, -1.0f, 1.0f,  -1.0f,
  };
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  glEnableVertexAttribArray(position_location);
  glVertexAttribPointer(position_location, 2, GL_FLOAT, GL_FALSE, 0, 0);

  return vbo;
}

std::vector<GLuint> GLTestHelper::SetupIndexedUnitQuad(
    GLint position_location) {
  GLuint array_buffer = SetupUnitQuad(position_location);
  static const uint8_t indices[] = {0, 1, 2, 3, 4, 5};
  GLuint index_buffer = 0;
  glGenBuffers(1, &index_buffer);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6, indices, GL_STATIC_DRAW);
  std::vector<GLuint> buffers(2);
  buffers[0] = array_buffer;
  buffers[1] = index_buffer;
  return buffers;
}

GLuint GLTestHelper::SetupColorsForUnitQuad(
    GLint location, const GLfloat color[4], GLenum usage) {
  GLuint vbo = 0;
  glGenBuffers(1, &vbo);
  glBindBuffer(GL_ARRAY_BUFFER, vbo);
  GLfloat vertices[6 * 4];
  for (int ii = 0; ii < 6; ++ii) {
    for (int jj = 0; jj < 4; ++jj) {
      vertices[ii * 4 + jj] = color[jj];
    }
  }
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, usage);
  glEnableVertexAttribArray(location);
  glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, 0, 0);

  return vbo;
}

bool GLTestHelper::CheckPixels(GLint x,
                               GLint y,
                               GLsizei width,
                               GLsizei height,
                               GLint tolerance,
                               const uint8_t* color,
                               const uint8_t* mask) {
  GLsizei size = width * height * 4;
  std::unique_ptr<uint8_t[]> pixels(new uint8_t[size]);
  memset(pixels.get(), kCheckClearValue, size);
  glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get());
  int bad_count = 0;
  for (GLint yy = 0; yy < height; ++yy) {
    for (GLint xx = 0; xx < width; ++xx) {
      int offset = yy * width * 4 + xx * 4;
      for (int jj = 0; jj < 4; ++jj) {
        uint8_t actual = pixels[offset + jj];
        uint8_t expected = color[jj];
        int diff = actual - expected;
        diff = diff < 0 ? -diff: diff;
        if ((!mask || mask[jj]) && diff > tolerance) {
          EXPECT_EQ(expected, actual) << " at " << (xx + x) << ", " << (yy + y)
                                      << " channel " << jj;
          ++bad_count;
          // Exit early just so we don't spam the log but we print enough
          // to hopefully make it easy to diagnose the issue.
          if (bad_count > 16) {
            return false;
          }
        }
      }
    }
  }
  return bad_count == 0;
}

namespace {

void Set16BitValue(uint8_t dest[2], uint16_t value) {
  dest[0] = value & 0xFFu;
  dest[1] = value >> 8;
}

void Set32BitValue(uint8_t dest[4], uint32_t value) {
  dest[0] = (value >> 0) & 0xFFu;
  dest[1] = (value >> 8) & 0xFFu;
  dest[2] = (value >> 16) & 0xFFu;
  dest[3] = (value >> 24) & 0xFFu;
}

struct BitmapHeaderFile {
  uint8_t magic[2];
  uint8_t size[4];
  uint8_t reserved[4];
  uint8_t offset[4];
};

struct BitmapInfoHeader{
  uint8_t size[4];
  uint8_t width[4];
  uint8_t height[4];
  uint8_t planes[2];
  uint8_t bit_count[2];
  uint8_t compression[4];
  uint8_t size_image[4];
  uint8_t x_pels_per_meter[4];
  uint8_t y_pels_per_meter[4];
  uint8_t clr_used[4];
  uint8_t clr_important[4];
};

}

bool GLTestHelper::SaveBackbufferAsBMP(
    const char* filename, int width, int height) {
  FILE* fp = fopen(filename, "wb");
  EXPECT_TRUE(fp != nullptr);
  glPixelStorei(GL_PACK_ALIGNMENT, 1);
  int num_pixels = width * height;
  int size = num_pixels * 4;
  std::unique_ptr<uint8_t[]> data(new uint8_t[size]);
  uint8_t* pixels = data.get();
  glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

  // RGBA to BGRA
  for (int ii = 0; ii < num_pixels; ++ii) {
    int offset = ii * 4;
    uint8_t t = pixels[offset + 0];
    pixels[offset + 0] = pixels[offset + 2];
    pixels[offset + 2] = t;
  }

  BitmapHeaderFile bhf;
  BitmapInfoHeader bih;

  bhf.magic[0] = 'B';
  bhf.magic[1] = 'M';
  Set32BitValue(bhf.size, 0);
  Set32BitValue(bhf.reserved, 0);
  Set32BitValue(bhf.offset, sizeof(bhf) + sizeof(bih));

  Set32BitValue(bih.size, sizeof(bih));
  Set32BitValue(bih.width, width);
  Set32BitValue(bih.height, height);
  Set16BitValue(bih.planes, 1);
  Set16BitValue(bih.bit_count, 32);
  Set32BitValue(bih.compression, 0);
  Set32BitValue(bih.x_pels_per_meter, 0);
  Set32BitValue(bih.y_pels_per_meter, 0);
  Set32BitValue(bih.clr_used, 0);
  Set32BitValue(bih.clr_important, 0);

  fwrite(&bhf, sizeof(bhf), 1, fp);
  fwrite(&bih, sizeof(bih), 1, fp);
  fwrite(pixels, size, 1, fp);
  fclose(fp);
  return true;
}

void GLTestHelper::DrawTextureQuad(const GLenum texture_target,
                                   const char* vertex_src,
                                   const char* fragment_src,
                                   const char* position_name,
                                   const char* sampler_name,
                                   const char* face_name) {
  GLuint program = GLTestHelper::LoadProgram(vertex_src, fragment_src);
  EXPECT_NE(program, 0u);
  glUseProgram(program);

  GLint position_loc = glGetAttribLocation(program, position_name);
  GLint sampler_location = glGetUniformLocation(program, sampler_name);
  ASSERT_NE(position_loc, -1);
  ASSERT_NE(sampler_location, -1);
  GLint face_loc = -1;
  if (gpu::gles2::GLES2Util::GLFaceTargetToTextureTarget(texture_target) ==
      GL_TEXTURE_CUBE_MAP) {
    ASSERT_NE(face_name, nullptr);
    face_loc = glGetUniformLocation(program, face_name);
    ASSERT_NE(face_loc, -1);
    glUniform1i(face_loc, texture_target);
  }

  GLuint vertex_buffer = GLTestHelper::SetupUnitQuad(position_loc);
  ASSERT_NE(vertex_buffer, 0u);
  glActiveTexture(GL_TEXTURE0);
  glUniform1i(sampler_location, 0);

  glDrawArrays(GL_TRIANGLES, 0, 6);

  glDeleteProgram(program);
  glDeleteBuffers(1, &vertex_buffer);
}

GpuCommandBufferTestEGL::GpuCommandBufferTestEGL() : gl_reinitialized_(false) {}

GpuCommandBufferTestEGL::~GpuCommandBufferTestEGL() {}

bool GpuCommandBufferTestEGL::InitializeEGLGLES2(int width, int height) {
  if (gl::GetGLImplementation() !=
      gl::GLImplementation::kGLImplementationEGLGLES2) {
    const auto impls = gl::init::GetAllowedGLImplementations();
    if (!base::ContainsValue(impls,
          gl::GLImplementation::kGLImplementationEGLGLES2)) {
      LOG(INFO) << "Skip test, implementation EGLGLES2 is not available";
      return false;
    }

    gpu::GPUInfo gpu_info;
    gpu::CollectContextGraphicsInfo(&gpu_info, gpu::GpuPreferences());
    // See crbug.com/822716, the ATI proprietary driver has eglGetProcAddress
    // but eglInitialize crashes with x11.
    if (gpu_info.gl_vendor.find("ATI Technologies Inc.") != std::string::npos) {
      LOG(INFO) << "Skip test, ATI proprietary driver crashes with egl/x11";
      return false;
    }

    gl_reinitialized_ = true;
    gl::init::ShutdownGL(false /* due_to_fallback */);
    if (!GLTestHelper::InitializeGL(
            gl::GLImplementation::kGLImplementationEGLGLES2)) {
      LOG(INFO) << "Skip test, failed to initialize EGLGLES2";
      return false;
    }
  }

  DCHECK_EQ(gl::GLImplementation::kGLImplementationEGLGLES2,
            gl::GetGLImplementation());

  // Make the GL context current now to get all extensions.
  GLManager::Options options;
  options.size = gfx::Size(width, height);
  gl_.Initialize(options);
  gl_.MakeCurrent();

  bool result =
      gl::init::GetGLWindowSystemBindingInfo(&window_system_binding_info_);
  DCHECK(result);

  egl_extensions_ =
      gfx::MakeExtensionSet(window_system_binding_info_.extensions);
  gl_extensions_ =
      gfx::MakeExtensionSet(gl::GetGLExtensionsFromCurrentContext());

  return true;
}

void GpuCommandBufferTestEGL::RestoreGLDefault() {
  gl_.Destroy();

  if (gl_reinitialized_) {
    gl::init::ShutdownGL(false /* due_to_fallback */);
    GLTestHelper::InitializeGLDefault();
  }

  gl_reinitialized_ = false;
  gl_extensions_.clear();
  egl_extensions_.clear();
  window_system_binding_info_ = gl::GLWindowSystemBindingInfo();
}

#if defined(OS_LINUX)
scoped_refptr<gl::GLImageNativePixmap>
GpuCommandBufferTestEGL::CreateGLImageNativePixmap(gfx::BufferFormat format,
                                                   gfx::Size size,
                                                   uint8_t* pixels) const {
  // Upload raw pixels to a new GL texture.
  GLuint tex_client_id = 0;
  glGenTextures(1, &tex_client_id);
  DCHECK_NE(0u, tex_client_id);
  glBindTexture(GL_TEXTURE_2D, tex_client_id);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0,
               GL_RGBA, GL_UNSIGNED_BYTE, pixels);

  // Make sure the texture exists in the service side.
  glFinish();

  // This works because the test run in a similar mode as In-Process-GPU.
  unsigned int tex_service_id = 0;
  gl_.decoder()->GetServiceTextureId(tex_client_id, &tex_service_id);
  EXPECT_NE(0u, tex_service_id);

  // Create an EGLImage from the real texture id.
  scoped_refptr<gl::GLImageNativePixmap> image(new gl::GLImageNativePixmap(
      size, gl::GLImageNativePixmap::GetInternalFormatForTesting(format)));
  bool result = image->InitializeFromTexture(tex_service_id);
  DCHECK(result);

  // The test will own the EGLImage no need to keep a reference on the GL
  // texture after returning from this function. This is covered by the
  // EGL_KHR_image_base.txt specification, i.e. the underlying memory remains
  // allocated as long as there is at least one sibling (like ref count).
  glDeleteTextures(1, &tex_client_id);

  return image;
}

gfx::NativePixmapHandle GpuCommandBufferTestEGL::CreateNativePixmapHandle(
    gfx::BufferFormat format,
    gfx::Size size,
    uint8_t* pixels) {
  scoped_refptr<gl::GLImageNativePixmap> image =
      CreateGLImageNativePixmap(format, size, pixels);
  EXPECT_TRUE(image);
  EXPECT_EQ(size, image->GetSize());

  // Export the EGLImage as dmabuf fds
  // The test will own the dmabuf fds so no need to keep a reference on the
  // EGLImage after returning from this function.
  return image->ExportHandle();
}
#endif

}  // namespace gpu
