Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / gpu / command_buffer / tests / gl_depth_texture_unittest.cc
blob83bb84c3d2e3e537e0f645d4ca45fc2f51434f95
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.
5 #include <GLES2/gl2.h>
6 #include <GLES2/gl2ext.h>
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"
13 #define SHADER(Src) #Src
15 namespace gpu {
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);
26 virtual void TearDown() {
27 gl_.Destroy();
30 GLuint SetupUnitQuad(GLint position_location);
32 GLManager gl_;
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,
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);
51 return vbo;
54 namespace {
56 struct FormatType {
57 GLenum format;
58 GLenum type;
61 } // anonymous namespace
63 TEST_F(DepthTextureTest, RenderTo) {
64 if (!GLTestHelper::HasExtension("GL_CHROMIUM_depth_texture")) {
65 return;
68 bool have_depth_stencil = GLTestHelper::HasExtension(
69 "GL_OES_packed_depth_stencil");
71 static const char* v_shader_str = SHADER(
72 attribute vec4 v_position;
73 void main()
75 gl_Position = v_position;
78 static const char* f_shader_str = SHADER(
79 precision mediump float;
80 uniform sampler2D u_texture;
81 uniform vec2 u_resolution;
82 void main()
84 vec2 texcoord = gl_FragCoord.xy / u_resolution;
85 gl_FragColor = texture2D(u_texture, texcoord);
89 GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
91 GLint position_loc = glGetAttribLocation(program, "v_position");
92 GLint resolution_loc = glGetUniformLocation(program, "u_resolution");
94 SetupUnitQuad(position_loc);
96 // Depth test needs to be on for the depth buffer to be updated.
97 glEnable(GL_DEPTH_TEST);
99 // create an fbo
100 GLuint fbo = 0;
101 glGenFramebuffers(1, &fbo);
102 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
104 // create a depth texture.
105 GLuint color_texture = 0;
106 GLuint depth_texture = 0;
108 glGenTextures(1, &color_texture);
109 glBindTexture(GL_TEXTURE_2D, color_texture);
110 glTexImage2D(
111 GL_TEXTURE_2D, 0, GL_RGBA, kResolution, kResolution,
112 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
113 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
114 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
116 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
117 glFramebufferTexture2D(
118 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture, 0);
120 glGenTextures(1, &depth_texture);
121 glBindTexture(GL_TEXTURE_2D, depth_texture);
122 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
123 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
126 glFramebufferTexture2D(
127 GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0);
129 glUseProgram(program);
130 glUniform2f(resolution_loc, kResolution, kResolution);
132 static const FormatType format_types[] = {
133 { GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT },
134 { GL_DEPTH_COMPONENT, GL_UNSIGNED_INT },
135 { GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES },
137 for (size_t ii = 0; ii < arraysize(format_types); ++ii) {
138 const FormatType& format_type = format_types[ii];
139 GLenum format = format_type.format;
140 GLenum type = format_type.type;
142 if (format == GL_DEPTH_STENCIL_OES && !have_depth_stencil) {
143 continue;
146 glBindTexture(GL_TEXTURE_2D, depth_texture);
147 glTexImage2D(
148 GL_TEXTURE_2D, 0, format, kResolution, kResolution,
149 0, format, type, NULL);
151 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
152 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
153 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), status)
154 << "iteration: " << ii;
155 if (status != GL_FRAMEBUFFER_COMPLETE) {
156 continue;
159 if (!GLTestHelper::CheckGLError("no errors after setup", __LINE__)) {
160 continue;
163 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
164 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
166 // Disconnect the texture so we'll render with the default texture.
167 glBindTexture(GL_TEXTURE_2D, 0);
169 // Render to the fbo.
170 glDrawArrays(GL_TRIANGLES, 0, 6);
172 if (!GLTestHelper::CheckGLError("no errors after depth draw", __LINE__)) {
173 continue;
176 // Render with the depth texture.
177 glBindFramebuffer(GL_FRAMEBUFFER, 0);
178 glBindTexture(GL_TEXTURE_2D, depth_texture);
179 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
180 glDrawArrays(GL_TRIANGLES, 0, 6);
182 if (!GLTestHelper::CheckGLError("no errors after texture draw", __LINE__)) {
183 continue;
186 uint8 actual_pixels[kResolution * kResolution * 4] = { 0, };
187 glReadPixels(
188 0, 0, kResolution, kResolution, GL_RGBA, GL_UNSIGNED_BYTE,
189 actual_pixels);
191 if (!GLTestHelper::CheckGLError("no errors after readpixels", __LINE__)) {
192 continue;
195 // Check that each pixel's red value is less than the previous pixel in
196 // either direction. Basically verify we have a gradient. No assumption is
197 // made about the other channels green, blue and alpha since, according to
198 // the GL_CHROMIUM_depth_texture spec, they have undefined values for
199 // depth textures.
200 int bad_count = 0; // used to not spam the log with too many messages.
201 for (GLint yy = 0; bad_count < 16 && yy < kResolution; ++yy) {
202 for (GLint xx = 0; bad_count < 16 && xx < kResolution; ++xx) {
203 const uint8* actual = &actual_pixels[(yy * kResolution + xx) * 4];
204 const uint8* left = actual - 4;
205 const uint8* down = actual - kResolution * 4;
207 // NOTE: Qualcomm on Nexus 4 the right most column has the same
208 // values as the next to right most column. (bad interpolator?)
209 if (xx > 0 && xx < kResolution - 1) {
210 EXPECT_GT(actual[0], left[0])
211 << "pixel at " << xx << ", " << yy
212 << " actual[0] =" << static_cast<unsigned>(actual[0])
213 << " left[0] =" << static_cast<unsigned>(left[0])
214 << " actual =" << reinterpret_cast<const void*>(actual)
215 << " left =" << reinterpret_cast<const void*>(left);
216 bad_count += (actual[0] > left[0] ? 0 : 1);
219 if (yy > 0 && yy < kResolution - 1) {
220 EXPECT_GT(actual[0], down[0]) << "pixel at " << xx << ", " << yy;
221 bad_count += (actual[0] > down[0] ? 0 : 1);
226 // Check that bottom left corner is vastly different thatn top right.
227 EXPECT_GT(
228 actual_pixels[(kResolution * kResolution - 1) * 4] - actual_pixels[0],
229 0xC0);
231 GLTestHelper::CheckGLError("no errors after everything", __LINE__);
235 } // namespace gpu