Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / gpu / command_buffer / tests / gl_depth_texture_unittest.cc
blob5bbbb0683d3265525cbf66a0d4f03f2634282830
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 void SetUp() override {
21 GLManager::Options options;
22 options.size = gfx::Size(kResolution, kResolution);
23 gl_.Initialize(options);
26 void TearDown() override { gl_.Destroy(); }
28 GLuint SetupUnitQuad(GLint position_location);
30 GLManager gl_;
33 GLuint DepthTextureTest::SetupUnitQuad(GLint position_location) {
34 GLuint vbo = 0;
35 glGenBuffers(1, &vbo);
36 glBindBuffer(GL_ARRAY_BUFFER, vbo);
37 static float vertices[] = {
38 1.0f, 1.0f, 1.0f,
39 -1.0f, 1.0f, 0.0f,
40 -1.0f, -1.0f, -1.0f,
41 1.0f, 1.0f, 1.0f,
42 -1.0f, -1.0f, -1.0f,
43 1.0f, -1.0f, 0.0f,
45 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
46 glEnableVertexAttribArray(position_location);
47 glVertexAttribPointer(position_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
49 return vbo;
52 namespace {
54 struct FormatType {
55 GLenum format;
56 GLenum type;
59 } // anonymous namespace
61 TEST_F(DepthTextureTest, RenderTo) {
62 if (!GLTestHelper::HasExtension("GL_CHROMIUM_depth_texture")) {
63 return;
66 bool have_depth_stencil = GLTestHelper::HasExtension(
67 "GL_OES_packed_depth_stencil");
69 static const char* v_shader_str = SHADER(
70 attribute vec4 v_position;
71 void main()
73 gl_Position = v_position;
76 static const char* f_shader_str = SHADER(
77 precision mediump float;
78 uniform sampler2D u_texture;
79 uniform vec2 u_resolution;
80 void main()
82 vec2 texcoord = gl_FragCoord.xy / u_resolution;
83 gl_FragColor = texture2D(u_texture, texcoord);
87 GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
89 GLint position_loc = glGetAttribLocation(program, "v_position");
90 GLint resolution_loc = glGetUniformLocation(program, "u_resolution");
92 SetupUnitQuad(position_loc);
94 // Depth test needs to be on for the depth buffer to be updated.
95 glEnable(GL_DEPTH_TEST);
97 // create an fbo
98 GLuint fbo = 0;
99 glGenFramebuffers(1, &fbo);
100 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
102 // create a depth texture.
103 GLuint color_texture = 0;
104 GLuint depth_texture = 0;
106 glGenTextures(1, &color_texture);
107 glBindTexture(GL_TEXTURE_2D, color_texture);
108 glTexImage2D(
109 GL_TEXTURE_2D, 0, GL_RGBA, kResolution, kResolution,
110 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
111 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
113 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
114 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
115 glFramebufferTexture2D(
116 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture, 0);
118 glGenTextures(1, &depth_texture);
119 glBindTexture(GL_TEXTURE_2D, depth_texture);
120 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
121 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
122 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
123 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
124 glFramebufferTexture2D(
125 GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0);
127 glUseProgram(program);
128 glUniform2f(resolution_loc, kResolution, kResolution);
130 static const FormatType format_types[] = {
131 { GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT },
132 { GL_DEPTH_COMPONENT, GL_UNSIGNED_INT },
133 { GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES },
135 for (size_t ii = 0; ii < arraysize(format_types); ++ii) {
136 const FormatType& format_type = format_types[ii];
137 GLenum format = format_type.format;
138 GLenum type = format_type.type;
140 if (format == GL_DEPTH_STENCIL_OES && !have_depth_stencil) {
141 continue;
144 glBindTexture(GL_TEXTURE_2D, depth_texture);
145 glTexImage2D(
146 GL_TEXTURE_2D, 0, format, kResolution, kResolution,
147 0, format, type, NULL);
149 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
150 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
151 EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), status)
152 << "iteration: " << ii;
153 if (status != GL_FRAMEBUFFER_COMPLETE) {
154 continue;
157 if (!GLTestHelper::CheckGLError("no errors after setup", __LINE__)) {
158 continue;
161 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
162 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
164 // Disconnect the texture so we'll render with the default texture.
165 glBindTexture(GL_TEXTURE_2D, 0);
167 // Render to the fbo.
168 glDrawArrays(GL_TRIANGLES, 0, 6);
170 if (!GLTestHelper::CheckGLError("no errors after depth draw", __LINE__)) {
171 continue;
174 // Render with the depth texture.
175 glBindFramebuffer(GL_FRAMEBUFFER, 0);
176 glBindTexture(GL_TEXTURE_2D, depth_texture);
177 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
178 glDrawArrays(GL_TRIANGLES, 0, 6);
180 if (!GLTestHelper::CheckGLError("no errors after texture draw", __LINE__)) {
181 continue;
184 uint8 actual_pixels[kResolution * kResolution * 4] = { 0, };
185 glReadPixels(
186 0, 0, kResolution, kResolution, GL_RGBA, GL_UNSIGNED_BYTE,
187 actual_pixels);
189 if (!GLTestHelper::CheckGLError("no errors after readpixels", __LINE__)) {
190 continue;
193 // Check that each pixel's red value is less than the previous pixel in
194 // either direction. Basically verify we have a gradient. No assumption is
195 // made about the other channels green, blue and alpha since, according to
196 // the GL_CHROMIUM_depth_texture spec, they have undefined values for
197 // depth textures.
198 int bad_count = 0; // used to not spam the log with too many messages.
199 for (GLint yy = 0; bad_count < 16 && yy < kResolution; ++yy) {
200 for (GLint xx = 0; bad_count < 16 && xx < kResolution; ++xx) {
201 const uint8* actual = &actual_pixels[(yy * kResolution + xx) * 4];
202 const uint8* left = actual - 4;
203 const uint8* down = actual - kResolution * 4;
205 // NOTE: Qualcomm on Nexus 4 the right most column has the same
206 // values as the next to right most column. (bad interpolator?)
207 if (xx > 0 && xx < kResolution - 1) {
208 EXPECT_GT(actual[0], left[0])
209 << "pixel at " << xx << ", " << yy
210 << " actual[0] =" << static_cast<unsigned>(actual[0])
211 << " left[0] =" << static_cast<unsigned>(left[0])
212 << " actual =" << reinterpret_cast<const void*>(actual)
213 << " left =" << reinterpret_cast<const void*>(left);
214 bad_count += (actual[0] > left[0] ? 0 : 1);
217 if (yy > 0 && yy < kResolution - 1) {
218 EXPECT_GT(actual[0], down[0]) << "pixel at " << xx << ", " << yy;
219 bad_count += (actual[0] > down[0] ? 0 : 1);
224 // Check that bottom left corner is vastly different thatn top right.
225 EXPECT_GT(
226 actual_pixels[(kResolution * kResolution - 1) * 4] - actual_pixels[0],
227 0xC0);
229 GLTestHelper::CheckGLError("no errors after everything", __LINE__);
233 } // namespace gpu