| 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 |