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.
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
17 class DepthTextureTest
: public testing::Test
{
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() {
30 GLuint
SetupUnitQuad(GLint position_location
);
35 GLuint
DepthTextureTest::SetupUnitQuad(GLint position_location
) {
37 glGenBuffers(1, &vbo
);
38 glBindBuffer(GL_ARRAY_BUFFER
, vbo
);
39 static float vertices
[] = {
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);
61 } // anonymous namespace
63 TEST_F(DepthTextureTest
, RenderTo
) {
64 if (!GLTestHelper::HasExtension("GL_CHROMIUM_depth_texture")) {
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
;
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
;
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
);
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
);
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
) {
146 glBindTexture(GL_TEXTURE_2D
, depth_texture
);
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
) {
159 if (!GLTestHelper::CheckGLError("no errors after setup", __LINE__
)) {
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__
)) {
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__
)) {
186 uint8 actual_pixels
[kResolution
* kResolution
* 4] = { 0, };
188 0, 0, kResolution
, kResolution
, GL_RGBA
, GL_UNSIGNED_BYTE
,
191 if (!GLTestHelper::CheckGLError("no errors after readpixels", __LINE__
)) {
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
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.
228 actual_pixels
[(kResolution
* kResolution
- 1) * 4] - actual_pixels
[0],
231 GLTestHelper::CheckGLError("no errors after everything", __LINE__
);