// 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 <GLES2/gl2extchromium.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"

namespace gpu {

class GLChromiumFramebufferMultisampleTest : public testing::Test {
 protected:
  virtual void SetUp() {
    gl_.Initialize(GLManager::Options());
  }

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

  GLManager gl_;
};

// Test that GL is at least minimally working.
TEST_F(GLChromiumFramebufferMultisampleTest, CachedBindingsTest) {
  if (!GLTestHelper::HasExtension("GL_CHROMIUM_framebuffer_multisample")) {
    return;
  }

  GLuint fbo = 0;
  glGenFramebuffers(1, &fbo);
  glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
  glBindFramebuffer(GL_FRAMEBUFFER, 0);

  // If the caching is bad the second call to glBindFramebuffer will do nothing.
  // which means the draw buffer is bad and will not return
  // GL_FRAMEBUFFER_COMPLETE and rendering will generate an error.
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            glCheckFramebufferStatus(GL_FRAMEBUFFER));

  glClear(GL_COLOR_BUFFER_BIT);
  GLTestHelper::CheckGLError("no errors", __LINE__);
}

TEST_F(GLChromiumFramebufferMultisampleTest, DrawAndResolve) {
  if (!GLTestHelper::HasExtension("GL_CHROMIUM_framebuffer_multisample")) {
    return;
  }

  static const char* v_shader_str =
      "attribute vec4 a_Position;\n"
      "void main()\n"
      "{\n"
      "   gl_Position = a_Position;\n"
      "}\n";
  static const char* f_shader_str =
      "precision mediump float;\n"
      "void main()\n"
      "{\n"
      "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
      "}\n";

  GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
  glUseProgram(program);
  GLuint position_loc = glGetAttribLocation(program, "a_Position");

  GLTestHelper::SetupUnitQuad(position_loc);

  const GLuint width = 100;
  const GLuint height = 100;

  // Create a sample buffer.
  GLsizei num_samples = 4, max_samples = 0;
  glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
  num_samples = std::min(num_samples, max_samples);

  GLuint sample_fbo, sample_rb;
  glGenRenderbuffers(1, &sample_rb);
  glBindRenderbuffer(GL_RENDERBUFFER, sample_rb);
  glRenderbufferStorageMultisampleCHROMIUM(
      GL_RENDERBUFFER, num_samples, GL_RGBA8_OES, width, height);
  GLint param = 0;
  glGetRenderbufferParameteriv(
      GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &param);
  EXPECT_GE(param, num_samples);

  glGenFramebuffers(1, &sample_fbo);
  glBindFramebuffer(GL_FRAMEBUFFER, sample_fbo);
  glFramebufferRenderbuffer(GL_FRAMEBUFFER,
                            GL_COLOR_ATTACHMENT0,
                            GL_RENDERBUFFER,
                            sample_rb);
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            glCheckFramebufferStatus(GL_FRAMEBUFFER));

  // Create another FBO to resolve the multisample buffer into.
  GLuint resolve_fbo, resolve_tex;
  glGenTextures(1, &resolve_tex);
  glBindTexture(GL_TEXTURE_2D, resolve_tex);
  glTexImage2D(GL_TEXTURE_2D,
               0,
               GL_RGBA,
               width,
               height,
               0,
               GL_RGBA,
               GL_UNSIGNED_BYTE,
               NULL);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glGenFramebuffers(1, &resolve_fbo);
  glBindFramebuffer(GL_FRAMEBUFFER, resolve_fbo);
  glFramebufferTexture2D(GL_FRAMEBUFFER,
                         GL_COLOR_ATTACHMENT0,
                         GL_TEXTURE_2D,
                         resolve_tex,
                         0);
  EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
            glCheckFramebufferStatus(GL_FRAMEBUFFER));

  // Draw one triangle (bottom left half).
  glViewport(0, 0, width, height);
  glBindFramebuffer(GL_FRAMEBUFFER, sample_fbo);
  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  glClear(GL_COLOR_BUFFER_BIT);
  glDrawArrays(GL_TRIANGLES, 0, 3);

  // Resolve.
  glBindFramebuffer(GL_READ_FRAMEBUFFER, sample_fbo);
  glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolve_fbo);
  glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
  glClear(GL_COLOR_BUFFER_BIT);
  glBlitFramebufferCHROMIUM(0,
                            0,
                            width,
                            height,
                            0,
                            0,
                            width,
                            height,
                            GL_COLOR_BUFFER_BIT,
                            GL_NEAREST);

  // Verify.
  const uint8 green[] = {0, 255, 0, 255};
  const uint8 black[] = {0, 0, 0, 0};
  glBindFramebuffer(GL_READ_FRAMEBUFFER, resolve_fbo);
  EXPECT_TRUE(
      GLTestHelper::CheckPixels(width / 4, (3 * height) / 4, 1, 1, 0, green));
  EXPECT_TRUE(GLTestHelper::CheckPixels(width - 1, 0, 1, 1, 0, black));
}

}  // namespace gpu

