15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <GLES2/gl2.h>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <GLES2/gl2ext.h>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/tests/gl_manager.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/tests/gl_test_utils.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SHADER(Src) #Src
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DepthTextureTest : public testing::Test {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLsizei kResolution = 64;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLManager::Options options;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    options.size = gfx::Size(kResolution, kResolution);
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gl_.Initialize(options);
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gl_.Destroy();
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLuint SetupUnitQuad(GLint position_location);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLManager gl_;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLuint DepthTextureTest::SetupUnitQuad(GLint position_location) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLuint vbo = 0;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGenBuffers(1, &vbo);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glBindBuffer(GL_ARRAY_BUFFER, vbo);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static float vertices[] = {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1.0f,  1.0f,  1.0f,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     -1.0f,  1.0f,  0.0f,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     -1.0f, -1.0f, -1.0f,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1.0f,  1.0f,  1.0f,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     -1.0f, -1.0f, -1.0f,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1.0f, -1.0f,  0.0f,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glEnableVertexAttribArray(position_location);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glVertexAttribPointer(position_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return vbo;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct FormatType {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLenum format;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLenum type;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // anonymous namespace
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// crbug.com/135229
64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Fails on all Windows platforms and on Linux Intel.
65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(OS_WIN) || (defined(OS_LINUX) && defined(NDEBUG))
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_RenderTo DISABLED_RenderTo
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_RenderTo RenderTo
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(DepthTextureTest, MAYBE_RenderTo) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GLTestHelper::HasExtension("GL_CHROMIUM_depth_texture")) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool have_depth_stencil = GLTestHelper::HasExtension(
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GL_OES_packed_depth_stencil");
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* v_shader_str = SHADER(
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      attribute vec4 v_position;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      void main()
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         gl_Position = v_position;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  );
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* f_shader_str = SHADER(
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      precision mediump float;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      uniform sampler2D u_texture;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      uniform vec2 u_resolution;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      void main()
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        vec2 texcoord = gl_FragCoord.xy / u_resolution;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gl_FragColor = texture2D(u_texture, texcoord);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  );
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint position_loc = glGetAttribLocation(program, "v_position");
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint resolution_loc = glGetUniformLocation(program, "u_resolution");
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetupUnitQuad(position_loc);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Depth test needs to be on for the depth buffer to be updated.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glEnable(GL_DEPTH_TEST);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // create an fbo
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLuint fbo = 0;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGenFramebuffers(1, &fbo);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // create a depth texture.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLuint color_texture = 0;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLuint depth_texture = 0;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGenTextures(1, &color_texture);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glBindTexture(GL_TEXTURE_2D, color_texture);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glTexImage2D(
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GL_TEXTURE_2D, 0, GL_RGBA, kResolution, kResolution,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glFramebufferTexture2D(
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture, 0);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGenTextures(1, &depth_texture);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glBindTexture(GL_TEXTURE_2D, depth_texture);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glFramebufferTexture2D(
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glUseProgram(program);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glUniform2f(resolution_loc, kResolution, kResolution);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const FormatType format_types[] = {
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    { GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT },
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    { GL_DEPTH_COMPONENT, GL_UNSIGNED_INT },
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    { GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES },
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t ii = 0; ii < arraysize(format_types); ++ii) {
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const FormatType& format_type = format_types[ii];
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GLenum format = format_type.format;
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GLenum type = format_type.type;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (format == GL_DEPTH_STENCIL_OES && !have_depth_stencil) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glBindTexture(GL_TEXTURE_2D, depth_texture);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glTexImage2D(
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GL_TEXTURE_2D, 0, format, kResolution, kResolution,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        0, format, type, NULL);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), status)
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        << "iteration: " << ii;
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (status != GL_FRAMEBUFFER_COMPLETE) {
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!GLTestHelper::CheckGLError("no errors after setup", __LINE__)) {
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Disconnect the texture so we'll render with the default texture.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glBindTexture(GL_TEXTURE_2D, 0);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Render to the fbo.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glDrawArrays(GL_TRIANGLES, 0, 6);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!GLTestHelper::CheckGLError("no errors after depth draw", __LINE__)) {
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Render with the depth texture.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glBindFramebuffer(GL_FRAMEBUFFER, 0);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glBindTexture(GL_TEXTURE_2D, depth_texture);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glDrawArrays(GL_TRIANGLES, 0, 6);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!GLTestHelper::CheckGLError("no errors after texture draw", __LINE__)) {
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8 actual_pixels[kResolution * kResolution * 4] = { 0, };
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glReadPixels(
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        0, 0, kResolution, kResolution, GL_RGBA, GL_UNSIGNED_BYTE,
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        actual_pixels);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!GLTestHelper::CheckGLError("no errors after readpixels", __LINE__)) {
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check that each pixel's RGB are the same and that it's value is less
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // than the previous pixel in either direction. Basically verify we have a
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // gradient.
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int bad_count = 0;  // used to not spam the log with too many messages.
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for (GLint yy = 0; bad_count < 16 && yy < kResolution; ++yy) {
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for (GLint xx = 0; bad_count < 16 && xx < kResolution; ++xx) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const uint8* actual = &actual_pixels[(yy * kResolution + xx) * 4];
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const uint8* left = actual - 4;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const uint8* down = actual - kResolution * 4;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        EXPECT_EQ(actual[0], actual[1]) << "pixel at " << xx << ", " << yy;
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        EXPECT_EQ(actual[1], actual[2]) << "pixel at " << xx << ", " << yy;
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        bad_count += (actual[0] == actual[1] ? 0 : 1);
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // NOTE: Qualcomm on Nexus 4 the right most column has the same
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // values as the next to right most column. (bad interpolator?)
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (xx > 0 && xx < kResolution - 1) {
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          EXPECT_GT(actual[0], left[0])
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              << "pixel at " << xx << ", " << yy
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              << " actual[0] =" << static_cast<unsigned>(actual[0])
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              << " left[0] =" << static_cast<unsigned>(left[0])
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              << " actual =" << reinterpret_cast<const void*>(actual)
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              << " left =" << reinterpret_cast<const void*>(left);
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          bad_count += (actual[0] > left[0] ? 0 : 1);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (yy > 0 && yy < kResolution - 1) {
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          EXPECT_GT(actual[0], down[0]) << "pixel at " << xx << ", " << yy;
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          bad_count += (actual[0] > down[0] ? 0 : 1);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        EXPECT_TRUE(actual[3] == actual[0] || actual[3] == 0xFF)
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            << "pixel at " << xx << ", " << yy;
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        bad_count += ((actual[3] == actual[0] || actual[3] == 0xFF) ? 0 : 1);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check that bottom left corner is vastly different thatn top right.
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_GT(
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        actual_pixels[(kResolution * kResolution - 1) * 4] - actual_pixels[0],
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        0xC0);
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GLTestHelper::CheckGLError("no errors after everything", __LINE__);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
254