// 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 <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include "gpu/command_buffer/tests/gl_manager.h"
#include "gpu/command_buffer/tests/gl_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#define SHADER(Src) #Src

namespace gpu {

class DepthTextureTest : public testing::Test {
 protected:
  static const GLsizei kResolution = 64;
  virtual void SetUp() {
    GLManager::Options options;
    options.size = gfx::Size(kResolution, kResolution);
    gl_.Initialize(options);
  }

  virtual void TearDown() {
    gl_.Destroy();
  }

  GLuint SetupUnitQuad(GLint position_location);

  GLManager gl_;
};

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

  return vbo;
}

namespace {

struct FormatType {
  GLenum format;
  GLenum type;
};

}  // anonymous namespace

TEST_F(DepthTextureTest, RenderTo) {
  if (!GLTestHelper::HasExtension("GL_CHROMIUM_depth_texture")) {
    return;
  }

  bool have_depth_stencil = GLTestHelper::HasExtension(
      "GL_OES_packed_depth_stencil");

  static const char* v_shader_str = SHADER(
      attribute vec4 v_position;
      void main()
      {
         gl_Position = v_position;
      }
  );
  static const char* f_shader_str = SHADER(
      precision mediump float;
      uniform sampler2D u_texture;
      uniform vec2 u_resolution;
      void main()
      {
        vec2 texcoord = gl_FragCoord.xy / u_resolution;
        gl_FragColor = texture2D(u_texture, texcoord);
      }
  );

  GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);

  GLint position_loc = glGetAttribLocation(program, "v_position");
  GLint resolution_loc = glGetUniformLocation(program, "u_resolution");

  SetupUnitQuad(position_loc);

  // Depth test needs to be on for the depth buffer to be updated.
  glEnable(GL_DEPTH_TEST);

  // create an fbo
  GLuint fbo = 0;
  glGenFramebuffers(1, &fbo);
  glBindFramebuffer(GL_FRAMEBUFFER, fbo);

  // create a depth texture.
  GLuint color_texture = 0;
  GLuint depth_texture = 0;

  glGenTextures(1, &color_texture);
  glBindTexture(GL_TEXTURE_2D, color_texture);
  glTexImage2D(
      GL_TEXTURE_2D, 0, GL_RGBA, kResolution, kResolution,
      0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glFramebufferTexture2D(
      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture, 0);

  glGenTextures(1, &depth_texture);
  glBindTexture(GL_TEXTURE_2D, depth_texture);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glFramebufferTexture2D(
      GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0);

  glUseProgram(program);
  glUniform2f(resolution_loc, kResolution, kResolution);

  static const FormatType format_types[] = {
    { GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT },
    { GL_DEPTH_COMPONENT, GL_UNSIGNED_INT },
    { GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES },
  };
  for (size_t ii = 0; ii < arraysize(format_types); ++ii) {
    const FormatType& format_type = format_types[ii];
    GLenum format = format_type.format;
    GLenum type = format_type.type;

    if (format == GL_DEPTH_STENCIL_OES && !have_depth_stencil) {
      continue;
    }

    glBindTexture(GL_TEXTURE_2D, depth_texture);
    glTexImage2D(
        GL_TEXTURE_2D, 0, format, kResolution, kResolution,
        0, format, type, NULL);

    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), status)
        << "iteration: " << ii;
    if (status != GL_FRAMEBUFFER_COMPLETE) {
      continue;
    }

    if (!GLTestHelper::CheckGLError("no errors after setup", __LINE__)) {
      continue;
    }

    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Disconnect the texture so we'll render with the default texture.
    glBindTexture(GL_TEXTURE_2D, 0);

    // Render to the fbo.
    glDrawArrays(GL_TRIANGLES, 0, 6);

    if (!GLTestHelper::CheckGLError("no errors after depth draw", __LINE__)) {
      continue;
    }

    // Render with the depth texture.
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glBindTexture(GL_TEXTURE_2D, depth_texture);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    if (!GLTestHelper::CheckGLError("no errors after texture draw", __LINE__)) {
      continue;
    }

    uint8 actual_pixels[kResolution * kResolution * 4] = { 0, };
    glReadPixels(
        0, 0, kResolution, kResolution, GL_RGBA, GL_UNSIGNED_BYTE,
        actual_pixels);

    if (!GLTestHelper::CheckGLError("no errors after readpixels", __LINE__)) {
      continue;
    }

    // Check that each pixel's red value is less than the previous pixel in
    // either direction. Basically verify we have a gradient. No assumption is
    // made about the other channels green, blue and alpha since, according to
    // the GL_CHROMIUM_depth_texture spec, they have undefined values for
    // depth textures.
    int bad_count = 0;  // used to not spam the log with too many messages.
    for (GLint yy = 0; bad_count < 16 && yy < kResolution; ++yy) {
      for (GLint xx = 0; bad_count < 16 && xx < kResolution; ++xx) {
        const uint8* actual = &actual_pixels[(yy * kResolution + xx) * 4];
        const uint8* left = actual - 4;
        const uint8* down = actual - kResolution * 4;

        // NOTE: Qualcomm on Nexus 4 the right most column has the same
        // values as the next to right most column. (bad interpolator?)
        if (xx > 0 && xx < kResolution - 1) {
          EXPECT_GT(actual[0], left[0])
              << "pixel at " << xx << ", " << yy
              << " actual[0] =" << static_cast<unsigned>(actual[0])
              << " left[0] =" << static_cast<unsigned>(left[0])
              << " actual =" << reinterpret_cast<const void*>(actual)
              << " left =" << reinterpret_cast<const void*>(left);
          bad_count += (actual[0] > left[0] ? 0 : 1);
        }

        if (yy > 0 && yy < kResolution - 1) {
          EXPECT_GT(actual[0], down[0]) << "pixel at " << xx << ", " << yy;
          bad_count += (actual[0] > down[0] ? 0 : 1);
        }
      }
    }

    // Check that bottom left corner is vastly different thatn top right.
    EXPECT_GT(
        actual_pixels[(kResolution * kResolution - 1) * 4] - actual_pixels[0],
        0xC0);

    GLTestHelper::CheckGLError("no errors after everything", __LINE__);
  }
}

}  // namespace gpu




