Home | History | Annotate | Download | only in tests
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <GLES2/gl2.h>
      6 #include <GLES2/gl2ext.h>
      7 
      8 #include "gpu/command_buffer/tests/gl_manager.h"
      9 #include "gpu/command_buffer/tests/gl_test_utils.h"
     10 #include "testing/gmock/include/gmock/gmock.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 
     13 #define SHADER(Src) #Src
     14 
     15 namespace gpu {
     16 
     17 class DepthTextureTest : public testing::Test {
     18  protected:
     19   static const GLsizei kResolution = 64;
     20   virtual void SetUp() {
     21     GLManager::Options options;
     22     options.size = gfx::Size(kResolution, kResolution);
     23     gl_.Initialize(options);
     24   }
     25 
     26   virtual void TearDown() {
     27     gl_.Destroy();
     28   }
     29 
     30   GLuint SetupUnitQuad(GLint position_location);
     31 
     32   GLManager gl_;
     33 };
     34 
     35 GLuint DepthTextureTest::SetupUnitQuad(GLint position_location) {
     36   GLuint vbo = 0;
     37   glGenBuffers(1, &vbo);
     38   glBindBuffer(GL_ARRAY_BUFFER, vbo);
     39   static float vertices[] = {
     40       1.0f,  1.0f,  1.0f,
     41      -1.0f,  1.0f,  0.0f,
     42      -1.0f, -1.0f, -1.0f,
     43       1.0f,  1.0f,  1.0f,
     44      -1.0f, -1.0f, -1.0f,
     45       1.0f, -1.0f,  0.0f,
     46   };
     47   glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
     48   glEnableVertexAttribArray(position_location);
     49   glVertexAttribPointer(position_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
     50 
     51   return vbo;
     52 }
     53 
     54 namespace {
     55 
     56 struct FormatType {
     57   GLenum format;
     58   GLenum type;
     59 };
     60 
     61 }  // anonymous namespace
     62 
     63 // crbug.com/135229
     64 // Fails on all Windows platforms and on Linux Intel.
     65 #if defined(OS_WIN) || (defined(OS_LINUX) && defined(NDEBUG))
     66 #define MAYBE_RenderTo DISABLED_RenderTo
     67 #else
     68 #define MAYBE_RenderTo RenderTo
     69 #endif
     70 
     71 TEST_F(DepthTextureTest, MAYBE_RenderTo) {
     72   if (!GLTestHelper::HasExtension("GL_CHROMIUM_depth_texture")) {
     73     return;
     74   }
     75 
     76   bool have_depth_stencil = GLTestHelper::HasExtension(
     77       "GL_OES_packed_depth_stencil");
     78 
     79   static const char* v_shader_str = SHADER(
     80       attribute vec4 v_position;
     81       void main()
     82       {
     83          gl_Position = v_position;
     84       }
     85   );
     86   static const char* f_shader_str = SHADER(
     87       precision mediump float;
     88       uniform sampler2D u_texture;
     89       uniform vec2 u_resolution;
     90       void main()
     91       {
     92         vec2 texcoord = gl_FragCoord.xy / u_resolution;
     93         gl_FragColor = texture2D(u_texture, texcoord);
     94       }
     95   );
     96 
     97   GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
     98 
     99   GLint position_loc = glGetAttribLocation(program, "v_position");
    100   GLint resolution_loc = glGetUniformLocation(program, "u_resolution");
    101 
    102   SetupUnitQuad(position_loc);
    103 
    104   // Depth test needs to be on for the depth buffer to be updated.
    105   glEnable(GL_DEPTH_TEST);
    106 
    107   // create an fbo
    108   GLuint fbo = 0;
    109   glGenFramebuffers(1, &fbo);
    110   glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    111 
    112   // create a depth texture.
    113   GLuint color_texture = 0;
    114   GLuint depth_texture = 0;
    115 
    116   glGenTextures(1, &color_texture);
    117   glBindTexture(GL_TEXTURE_2D, color_texture);
    118   glTexImage2D(
    119       GL_TEXTURE_2D, 0, GL_RGBA, kResolution, kResolution,
    120       0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    121   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    122   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    123   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    124   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    125   glFramebufferTexture2D(
    126       GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture, 0);
    127 
    128   glGenTextures(1, &depth_texture);
    129   glBindTexture(GL_TEXTURE_2D, depth_texture);
    130   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    131   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    132   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    133   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    134   glFramebufferTexture2D(
    135       GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0);
    136 
    137   glUseProgram(program);
    138   glUniform2f(resolution_loc, kResolution, kResolution);
    139 
    140   static const FormatType format_types[] = {
    141     { GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT },
    142     { GL_DEPTH_COMPONENT, GL_UNSIGNED_INT },
    143     { GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES },
    144   };
    145   for (size_t ii = 0; ii < arraysize(format_types); ++ii) {
    146     const FormatType& format_type = format_types[ii];
    147     GLenum format = format_type.format;
    148     GLenum type = format_type.type;
    149 
    150     if (format == GL_DEPTH_STENCIL_OES && !have_depth_stencil) {
    151       continue;
    152     }
    153 
    154     glBindTexture(GL_TEXTURE_2D, depth_texture);
    155     glTexImage2D(
    156         GL_TEXTURE_2D, 0, format, kResolution, kResolution,
    157         0, format, type, NULL);
    158 
    159     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    160     GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    161     EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), status)
    162         << "iteration: " << ii;
    163     if (status != GL_FRAMEBUFFER_COMPLETE) {
    164       continue;
    165     }
    166 
    167     if (!GLTestHelper::CheckGLError("no errors after setup", __LINE__)) {
    168       continue;
    169     }
    170 
    171     glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    172     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    173 
    174     // Disconnect the texture so we'll render with the default texture.
    175     glBindTexture(GL_TEXTURE_2D, 0);
    176 
    177     // Render to the fbo.
    178     glDrawArrays(GL_TRIANGLES, 0, 6);
    179 
    180     if (!GLTestHelper::CheckGLError("no errors after depth draw", __LINE__)) {
    181       continue;
    182     }
    183 
    184     // Render with the depth texture.
    185     glBindFramebuffer(GL_FRAMEBUFFER, 0);
    186     glBindTexture(GL_TEXTURE_2D, depth_texture);
    187     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    188     glDrawArrays(GL_TRIANGLES, 0, 6);
    189 
    190     if (!GLTestHelper::CheckGLError("no errors after texture draw", __LINE__)) {
    191       continue;
    192     }
    193 
    194     uint8 actual_pixels[kResolution * kResolution * 4] = { 0, };
    195     glReadPixels(
    196         0, 0, kResolution, kResolution, GL_RGBA, GL_UNSIGNED_BYTE,
    197         actual_pixels);
    198 
    199     if (!GLTestHelper::CheckGLError("no errors after readpixels", __LINE__)) {
    200       continue;
    201     }
    202 
    203     // Check that each pixel's RGB are the same and that it's value is less
    204     // than the previous pixel in either direction. Basically verify we have a
    205     // gradient.
    206     int bad_count = 0;  // used to not spam the log with too many messages.
    207     for (GLint yy = 0; bad_count < 16 && yy < kResolution; ++yy) {
    208       for (GLint xx = 0; bad_count < 16 && xx < kResolution; ++xx) {
    209         const uint8* actual = &actual_pixels[(yy * kResolution + xx) * 4];
    210         const uint8* left = actual - 4;
    211         const uint8* down = actual - kResolution * 4;
    212 
    213         EXPECT_EQ(actual[0], actual[1]) << "pixel at " << xx << ", " << yy;
    214         EXPECT_EQ(actual[1], actual[2]) << "pixel at " << xx << ", " << yy;
    215         bad_count += (actual[0] == actual[1] ? 0 : 1);
    216 
    217         // NOTE: Qualcomm on Nexus 4 the right most column has the same
    218         // values as the next to right most column. (bad interpolator?)
    219         if (xx > 0 && xx < kResolution - 1) {
    220           EXPECT_GT(actual[0], left[0])
    221               << "pixel at " << xx << ", " << yy
    222               << " actual[0] =" << static_cast<unsigned>(actual[0])
    223               << " left[0] =" << static_cast<unsigned>(left[0])
    224               << " actual =" << reinterpret_cast<const void*>(actual)
    225               << " left =" << reinterpret_cast<const void*>(left);
    226           bad_count += (actual[0] > left[0] ? 0 : 1);
    227         }
    228 
    229         if (yy > 0 && yy < kResolution - 1) {
    230           EXPECT_GT(actual[0], down[0]) << "pixel at " << xx << ", " << yy;
    231           bad_count += (actual[0] > down[0] ? 0 : 1);
    232         }
    233 
    234         EXPECT_TRUE(actual[3] == actual[0] || actual[3] == 0xFF)
    235             << "pixel at " << xx << ", " << yy;
    236         bad_count += ((actual[3] == actual[0] || actual[3] == 0xFF) ? 0 : 1);
    237       }
    238     }
    239 
    240     // Check that bottom left corner is vastly different thatn top right.
    241     EXPECT_GT(
    242         actual_pixels[(kResolution * kResolution - 1) * 4] - actual_pixels[0],
    243         0xC0);
    244 
    245     GLTestHelper::CheckGLError("no errors after everything", __LINE__);
    246   }
    247 }
    248 
    249 }  // namespace gpu
    250 
    251 
    252 
    253 
    254