OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/tests/gl_test_utils.h" | 5 #include "gpu/command_buffer/tests/gl_test_utils.h" |
6 | 6 |
7 #include <GLES2/gl2extchromium.h> | 7 #include <GLES2/gl2extchromium.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 #include <stdio.h> | 9 #include <stdio.h> |
10 | 10 |
11 #include <memory> | 11 #include <memory> |
12 #include <string> | 12 #include <string> |
13 | 13 |
14 #include "base/logging.h" | |
15 #include "base/strings/stringize_macros.h" | |
16 #include "base/strings/stringprintf.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
18 #include "ui/gfx/geometry/size.h" | 15 #include "ui/gfx/geometry/size.h" |
19 | 16 |
20 // GCC requires these declarations, but MSVC requires they not be present. | 17 // GCC requires these declarations, but MSVC requires they not be present. |
21 #ifndef COMPILER_MSVC | 18 #ifndef COMPILER_MSVC |
22 const uint8_t GLTestHelper::kCheckClearValue; | 19 const uint8_t GLTestHelper::kCheckClearValue; |
23 #endif | 20 #endif |
24 | 21 |
25 // Compiles a fragment shader for sampling out of a texture of |size| bound to | |
26 // |target| and checks for compilation errors. | |
27 GLuint LoadFragmentShader(unsigned target, const gfx::Size& size) { | |
28 // clang-format off | |
29 const char kFragmentShader[] = STRINGIZE( | |
30 uniform SamplerType u_texture; | |
31 varying vec2 v_texCoord; | |
32 void main() { | |
33 gl_FragColor = TextureLookup(u_texture, v_texCoord * TextureScale); | |
34 } | |
35 ); | |
36 const char kShaderFloatPrecision[] = STRINGIZE( | |
37 precision mediump float; | |
38 ); | |
39 // clang-format on | |
40 | |
41 switch (target) { | |
42 case GL_TEXTURE_2D: | |
43 return GLTestHelper::LoadShader( | |
44 GL_FRAGMENT_SHADER, | |
45 base::StringPrintf("%s\n" | |
46 "#define SamplerType sampler2D\n" | |
47 "#define TextureLookup texture2D\n" | |
48 "#define TextureScale vec2(1.0, 1.0)\n" | |
49 "%s", | |
50 kShaderFloatPrecision, | |
51 kFragmentShader) | |
52 .c_str()); | |
53 case GL_TEXTURE_RECTANGLE_ARB: | |
54 return GLTestHelper::LoadShader( | |
55 GL_FRAGMENT_SHADER, | |
56 base::StringPrintf("%s\n" | |
57 "#extension GL_ARB_texture_rectangle : require\n" | |
58 "#define SamplerType sampler2DRect\n" | |
59 "#define TextureLookup texture2DRect\n" | |
60 "#define TextureScale vec2(%f, %f)\n" | |
61 "%s", | |
62 kShaderFloatPrecision, | |
63 static_cast<double>(size.width()), | |
64 static_cast<double>(size.height()), | |
65 kFragmentShader) | |
66 .c_str()); | |
67 default: | |
68 NOTREACHED(); | |
69 return 0; | |
70 } | |
71 } | |
72 | |
73 bool GLTestHelper::HasExtension(const char* extension) { | 22 bool GLTestHelper::HasExtension(const char* extension) { |
74 // Pad with an extra space to ensure that |extension| is not a substring of | 23 // Pad with an extra space to ensure that |extension| is not a substring of |
75 // another extension. | 24 // another extension. |
76 std::string extensions = | 25 std::string extensions = |
77 std::string(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))) + | 26 std::string(reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))) + |
78 " "; | 27 " "; |
79 std::string extension_padded = std::string(extension) + " "; | 28 std::string extension_padded = std::string(extension) + " "; |
80 return extensions.find(extension_padded) != std::string::npos; | 29 return extensions.find(extension_padded) != std::string::npos; |
81 } | 30 } |
82 | 31 |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, 0, 0); | 156 glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, 0, 0); |
208 | 157 |
209 return vbo; | 158 return vbo; |
210 } | 159 } |
211 | 160 |
212 bool GLTestHelper::CheckPixels(GLint x, | 161 bool GLTestHelper::CheckPixels(GLint x, |
213 GLint y, | 162 GLint y, |
214 GLsizei width, | 163 GLsizei width, |
215 GLsizei height, | 164 GLsizei height, |
216 GLint tolerance, | 165 GLint tolerance, |
217 const uint8_t* color) { | 166 const uint8_t* color, |
| 167 const uint8_t* mask) { |
218 GLsizei size = width * height * 4; | 168 GLsizei size = width * height * 4; |
219 std::unique_ptr<uint8_t[]> pixels(new uint8_t[size]); | 169 std::unique_ptr<uint8_t[]> pixels(new uint8_t[size]); |
220 memset(pixels.get(), kCheckClearValue, size); | 170 memset(pixels.get(), kCheckClearValue, size); |
221 glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get()); | 171 glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get()); |
222 int bad_count = 0; | 172 int bad_count = 0; |
223 for (GLint yy = 0; yy < height; ++yy) { | 173 for (GLint yy = 0; yy < height; ++yy) { |
224 for (GLint xx = 0; xx < width; ++xx) { | 174 for (GLint xx = 0; xx < width; ++xx) { |
225 int offset = yy * width * 4 + xx * 4; | 175 int offset = yy * width * 4 + xx * 4; |
226 for (int jj = 0; jj < 4; ++jj) { | 176 for (int jj = 0; jj < 4; ++jj) { |
227 uint8_t actual = pixels[offset + jj]; | 177 uint8_t actual = pixels[offset + jj]; |
228 uint8_t expected = color[jj]; | 178 uint8_t expected = color[jj]; |
229 int diff = actual - expected; | 179 int diff = actual - expected; |
230 diff = diff < 0 ? -diff: diff; | 180 diff = diff < 0 ? -diff: diff; |
231 if (diff > tolerance) { | 181 if ((!mask || mask[jj]) && diff > tolerance) { |
232 EXPECT_EQ(expected, actual) << " at " << (xx + x) << ", " << (yy + y) | 182 EXPECT_EQ(expected, actual) << " at " << (xx + x) << ", " << (yy + y) |
233 << " channel " << jj; | 183 << " channel " << jj; |
234 ++bad_count; | 184 ++bad_count; |
235 // Exit early just so we don't spam the log but we print enough | 185 // Exit early just so we don't spam the log but we print enough |
236 // to hopefully make it easy to diagnose the issue. | 186 // to hopefully make it easy to diagnose the issue. |
237 if (bad_count > 16) { | 187 if (bad_count > 16) { |
238 return false; | 188 return false; |
239 } | 189 } |
240 } | 190 } |
241 } | 191 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 Set32BitValue(bih.clr_used, 0); | 270 Set32BitValue(bih.clr_used, 0); |
321 Set32BitValue(bih.clr_important, 0); | 271 Set32BitValue(bih.clr_important, 0); |
322 | 272 |
323 fwrite(&bhf, sizeof(bhf), 1, fp); | 273 fwrite(&bhf, sizeof(bhf), 1, fp); |
324 fwrite(&bih, sizeof(bih), 1, fp); | 274 fwrite(&bih, sizeof(bih), 1, fp); |
325 fwrite(pixels, size, 1, fp); | 275 fwrite(pixels, size, 1, fp); |
326 fclose(fp); | 276 fclose(fp); |
327 return true; | 277 return true; |
328 } | 278 } |
329 | 279 |
330 void GLTestHelper::DrawTextureQuad(GLenum target, const gfx::Size& size) { | 280 void GLTestHelper::DrawTextureQuad(const char* vertex_src, |
331 // clang-format off | 281 const char* fragment_src, |
332 const char kVertexShader[] = STRINGIZE( | 282 const char* position_name, |
333 attribute vec2 a_position; | 283 const char* sampler_name) { |
334 varying vec2 v_texCoord; | 284 GLuint program = GLTestHelper::LoadProgram(vertex_src, fragment_src); |
335 void main() { | |
336 gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0); | |
337 v_texCoord = (a_position + vec2(1.0, 1.0)) * 0.5; | |
338 } | |
339 ); | |
340 // clang-format on | |
341 | |
342 // Setup program. | |
343 GLuint vertex_shader = | |
344 GLTestHelper::LoadShader(GL_VERTEX_SHADER, kVertexShader); | |
345 GLuint fragment_shader = LoadFragmentShader(target, size); | |
346 GLuint program = GLTestHelper::SetupProgram(vertex_shader, fragment_shader); | |
347 EXPECT_NE(program, 0u); | 285 EXPECT_NE(program, 0u); |
348 glUseProgram(program); | 286 glUseProgram(program); |
349 | 287 |
350 GLint position_loc = glGetAttribLocation(program, "a_position"); | 288 GLint position_loc = glGetAttribLocation(program, position_name); |
351 GLint sampler_location = glGetUniformLocation(program, "u_texture"); | 289 GLint sampler_location = glGetUniformLocation(program, sampler_name); |
352 ASSERT_NE(position_loc, -1); | 290 ASSERT_NE(position_loc, -1); |
353 ASSERT_NE(sampler_location, -1); | 291 ASSERT_NE(sampler_location, -1); |
354 | 292 |
355 GLuint vertex_buffer = GLTestHelper::SetupUnitQuad(position_loc); | 293 GLuint vertex_buffer = GLTestHelper::SetupUnitQuad(position_loc); |
356 ASSERT_NE(vertex_buffer, 0u); | 294 ASSERT_NE(vertex_buffer, 0u); |
| 295 glActiveTexture(GL_TEXTURE0); |
357 glUniform1i(sampler_location, 0); | 296 glUniform1i(sampler_location, 0); |
358 | 297 |
359 glDrawArrays(GL_TRIANGLES, 0, 6); | 298 glDrawArrays(GL_TRIANGLES, 0, 6); |
360 | 299 |
361 glDeleteShader(vertex_shader); | |
362 glDeleteShader(fragment_shader); | |
363 glDeleteProgram(program); | 300 glDeleteProgram(program); |
364 glDeleteBuffers(1, &vertex_buffer); | 301 glDeleteBuffers(1, &vertex_buffer); |
365 } | 302 } |
OLD | NEW |