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 <GLES2/gl2.h> | 5 #include <GLES2/gl2.h> |
6 #include <GLES2/gl2ext.h> | 6 #include <GLES2/gl2ext.h> |
7 #include <GLES2/gl2extchromium.h> | 7 #include <GLES2/gl2extchromium.h> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
| 10 #include "base/command_line.h" |
| 11 #include "gpu/command_buffer/service/gpu_switches.h" |
10 #include "gpu/command_buffer/tests/gl_manager.h" | 12 #include "gpu/command_buffer/tests/gl_manager.h" |
11 #include "gpu/command_buffer/tests/gl_test_utils.h" | 13 #include "gpu/command_buffer/tests/gl_test_utils.h" |
12 #include "testing/gmock/include/gmock/gmock.h" | 14 #include "testing/gmock/include/gmock/gmock.h" |
13 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
14 | 16 |
| 17 #define SHADER(Src) #Src |
| 18 |
15 namespace gpu { | 19 namespace gpu { |
16 | 20 |
17 class CHROMIUMPathRenderingTest : public testing::Test { | 21 class CHROMIUMPathRenderingTest : public testing::Test { |
18 public: | 22 public: |
19 static const GLsizei kResolution = 100; | 23 static const GLsizei kResolution = 100; |
20 | 24 |
21 protected: | 25 protected: |
22 void SetUp() override { | 26 void SetUp() override { |
23 GLManager::Options options; | 27 GLManager::Options options; |
24 options.size = gfx::Size(kResolution, kResolution); | 28 options.size = gfx::Size(kResolution, kResolution); |
25 gl_.Initialize(options); | 29 base::CommandLine command_line(*base::CommandLine::ForCurrentProcess()); |
| 30 command_line.AppendSwitch(switches::kEnableGLPathRendering); |
| 31 gl_.InitializeWithCommandLine(options, &command_line); |
26 } | 32 } |
27 | 33 |
28 void TearDown() override { gl_.Destroy(); } | 34 void TearDown() override { gl_.Destroy(); } |
29 | 35 |
30 void ExpectEqualMatrix(const GLfloat* expected, const GLfloat* actual) { | 36 void ExpectEqualMatrix(const GLfloat* expected, const GLfloat* actual) { |
31 for (size_t i = 0; i < 16; ++i) { | 37 for (size_t i = 0; i < 16; ++i) { |
32 EXPECT_EQ(expected[i], actual[i]); | 38 EXPECT_EQ(expected[i], actual[i]); |
33 } | 39 } |
34 } | 40 } |
35 void ExpectEqualMatrix(const GLfloat* expected, const GLint* actual) { | 41 void ExpectEqualMatrix(const GLfloat* expected, const GLint* actual) { |
36 for (size_t i = 0; i < 16; ++i) { | 42 for (size_t i = 0; i < 16; ++i) { |
37 EXPECT_EQ(static_cast<GLint>(round(expected[i])), actual[i]); | 43 EXPECT_EQ(static_cast<GLint>(round(expected[i])), actual[i]); |
38 } | 44 } |
39 } | 45 } |
| 46 |
| 47 void SetupStateForTestPattern() { |
| 48 glViewport(0, 0, kResolution, kResolution); |
| 49 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| 50 glStencilMask(0xffffffff); |
| 51 glClearStencil(0); |
| 52 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
| 53 |
| 54 static const char* kVertexShaderSource = |
| 55 SHADER(void main() { gl_Position = vec4(1); }); |
| 56 static const char* kFragmentShaderSource = |
| 57 SHADER(precision mediump float; uniform vec4 color; |
| 58 void main() { gl_FragColor = color; }); |
| 59 |
| 60 GLuint program = |
| 61 GLTestHelper::LoadProgram(kVertexShaderSource, kFragmentShaderSource); |
| 62 glUseProgram(program); |
| 63 color_loc_ = glGetUniformLocation(program, "color"); |
| 64 glDeleteProgram(program); |
| 65 |
| 66 // Set up orthogonal projection with near/far plane distance of 2. |
| 67 static GLfloat matrix[16] = {2.0f / (kResolution - 1), |
| 68 0.0f, |
| 69 0.0f, |
| 70 0.0f, |
| 71 0.0f, |
| 72 2.0f / (kResolution - 1), |
| 73 0.0f, |
| 74 0.0f, |
| 75 0.0f, |
| 76 0.0f, |
| 77 -1.0f, |
| 78 0.0f, |
| 79 -1.0f, |
| 80 -1.0f, |
| 81 0.0f, |
| 82 1.0f}; |
| 83 glMatrixLoadfCHROMIUM(GL_PATH_PROJECTION_CHROMIUM, matrix); |
| 84 glMatrixLoadIdentityCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM); |
| 85 |
| 86 glEnable(GL_STENCIL_TEST); |
| 87 |
| 88 GLTestHelper::CheckGLError("no errors at state setup", __LINE__); |
| 89 } |
| 90 |
| 91 void SetupPathStateForTestPattern(GLuint path) { |
| 92 static const GLubyte kCommands[] = {GL_MOVE_TO_CHROMIUM, |
| 93 GL_LINE_TO_CHROMIUM, |
| 94 GL_QUADRATIC_CURVE_TO_CHROMIUM, |
| 95 GL_CUBIC_CURVE_TO_CHROMIUM, |
| 96 GL_CLOSE_PATH_CHROMIUM}; |
| 97 |
| 98 static const GLfloat kCoords[] = {50.0f, |
| 99 50.0f, |
| 100 75.0f, |
| 101 75.0f, |
| 102 100.0f, |
| 103 62.5f, |
| 104 50.0f, |
| 105 25.5f, |
| 106 0.0f, |
| 107 62.5f, |
| 108 50.0f, |
| 109 50.0f, |
| 110 25.0f, |
| 111 75.0f}; |
| 112 |
| 113 glPathCommandsCHROMIUM(path, arraysize(kCommands), kCommands, |
| 114 arraysize(kCoords), GL_FLOAT, kCoords); |
| 115 |
| 116 glPathParameterfCHROMIUM(path, GL_PATH_STROKE_WIDTH_CHROMIUM, 5.0f); |
| 117 glPathParameterfCHROMIUM(path, GL_PATH_MITER_LIMIT_CHROMIUM, 1.0f); |
| 118 glPathParameterfCHROMIUM(path, GL_PATH_STROKE_BOUND_CHROMIUM, .02f); |
| 119 glPathParameteriCHROMIUM(path, GL_PATH_JOIN_STYLE_CHROMIUM, |
| 120 GL_ROUND_CHROMIUM); |
| 121 glPathParameteriCHROMIUM(path, GL_PATH_END_CAPS_CHROMIUM, |
| 122 GL_SQUARE_CHROMIUM); |
| 123 } |
| 124 |
| 125 void VerifyTestPatternFill(float x, float y) { |
| 126 static const float kFillCoords[] = { |
| 127 55.0f, 55.0f, 50.0f, 28.0f, 66.0f, 63.0f}; |
| 128 static const uint8 kBlue[] = {0, 0, 255, 255}; |
| 129 |
| 130 for (size_t i = 0; i < arraysize(kFillCoords); i += 2) { |
| 131 float fx = kFillCoords[i]; |
| 132 float fy = kFillCoords[i + 1]; |
| 133 |
| 134 EXPECT_TRUE(GLTestHelper::CheckPixels(x + fx, y + fy, 1, 1, 0, kBlue)); |
| 135 } |
| 136 } |
| 137 |
| 138 void VerifyTestPatternBg(float x, float y) { |
| 139 const float kBackgroundCoords[] = {80.0f, 80.0f, 20.0f, 20.0f, 90.0f, 1.0f}; |
| 140 const uint8 kExpectedColor[] = {0, 0, 0, 0}; |
| 141 |
| 142 for (size_t i = 0; i < arraysize(kBackgroundCoords); i += 2) { |
| 143 float bx = kBackgroundCoords[i]; |
| 144 float by = kBackgroundCoords[i + 1]; |
| 145 |
| 146 EXPECT_TRUE( |
| 147 GLTestHelper::CheckPixels(x + bx, y + by, 1, 1, 0, kExpectedColor)); |
| 148 } |
| 149 } |
| 150 |
| 151 void VerifyTestPatternStroke(float x, float y) { |
| 152 // Inside the stroke we should have green. |
| 153 const uint8 kGreen[] = {0, 255, 0, 255}; |
| 154 EXPECT_TRUE(GLTestHelper::CheckPixels(x + 50, y + 53, 1, 1, 0, kGreen)); |
| 155 EXPECT_TRUE(GLTestHelper::CheckPixels(x + 26, y + 76, 1, 1, 0, kGreen)); |
| 156 |
| 157 // Outside the path we should have black. |
| 158 const uint8 black[] = {0, 0, 0, 0}; |
| 159 EXPECT_TRUE(GLTestHelper::CheckPixels(x + 10, y + 10, 1, 1, 0, black)); |
| 160 EXPECT_TRUE(GLTestHelper::CheckPixels(x + 80, y + 80, 1, 1, 0, black)); |
| 161 } |
| 162 |
| 163 void TryAllDrawFunctions(GLuint path, GLenum expected_error) { |
| 164 glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F); |
| 165 EXPECT_EQ(expected_error, glGetError()); |
| 166 |
| 167 glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F); |
| 168 EXPECT_EQ(expected_error, glGetError()); |
| 169 |
| 170 glStencilStrokePathCHROMIUM(path, 0x80, 0x80); |
| 171 EXPECT_EQ(expected_error, glGetError()); |
| 172 |
| 173 glCoverFillPathCHROMIUM(path, GL_BOUNDING_BOX_CHROMIUM); |
| 174 EXPECT_EQ(expected_error, glGetError()); |
| 175 |
| 176 glCoverStrokePathCHROMIUM(path, GL_BOUNDING_BOX_CHROMIUM); |
| 177 EXPECT_EQ(expected_error, glGetError()); |
| 178 |
| 179 glStencilThenCoverStrokePathCHROMIUM(path, 0x80, 0x80, |
| 180 GL_BOUNDING_BOX_CHROMIUM); |
| 181 EXPECT_EQ(expected_error, glGetError()); |
| 182 |
| 183 glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F, |
| 184 GL_BOUNDING_BOX_CHROMIUM); |
| 185 EXPECT_EQ(expected_error, glGetError()); |
| 186 } |
| 187 |
40 GLManager gl_; | 188 GLManager gl_; |
| 189 GLint color_loc_; |
41 }; | 190 }; |
42 | 191 |
43 TEST_F(CHROMIUMPathRenderingTest, TestMatrix) { | 192 TEST_F(CHROMIUMPathRenderingTest, TestMatrix) { |
44 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) { | 193 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) |
45 return; | 194 return; |
46 } | 195 |
47 static const GLfloat kIdentityMatrix[16] = { | 196 static const GLfloat kIdentityMatrix[16] = { |
48 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, | 197 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, |
49 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; | 198 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; |
50 static const GLfloat kSeqMatrix[16] = { | 199 static const GLfloat kSeqMatrix[16] = { |
51 0.5f, -0.5f, -0.1f, -0.8f, 4.4f, 5.5f, 6.6f, 7.7f, | 200 0.5f, -0.5f, -0.1f, -0.8f, 4.4f, 5.5f, 6.6f, 7.7f, |
52 8.8f, 9.9f, 10.11f, 11.22f, 12.33f, 13.44f, 14.55f, 15.66f}; | 201 8.8f, 9.9f, 10.11f, 11.22f, 12.33f, 13.44f, 14.55f, 15.66f}; |
53 static const GLenum kMatrixModes[] = {GL_PATH_MODELVIEW_CHROMIUM, | 202 static const GLenum kMatrixModes[] = {GL_PATH_MODELVIEW_CHROMIUM, |
54 GL_PATH_PROJECTION_CHROMIUM}; | 203 GL_PATH_PROJECTION_CHROMIUM}; |
55 static const GLenum kGetMatrixModes[] = {GL_PATH_MODELVIEW_MATRIX_CHROMIUM, | 204 static const GLenum kGetMatrixModes[] = {GL_PATH_MODELVIEW_MATRIX_CHROMIUM, |
56 GL_PATH_PROJECTION_MATRIX_CHROMIUM}; | 205 GL_PATH_PROJECTION_MATRIX_CHROMIUM}; |
(...skipping 22 matching lines...) Expand all Loading... |
79 glGetFloatv(kGetMatrixModes[i], mf); | 228 glGetFloatv(kGetMatrixModes[i], mf); |
80 glGetIntegerv(kGetMatrixModes[i], mi); | 229 glGetIntegerv(kGetMatrixModes[i], mi); |
81 ExpectEqualMatrix(kIdentityMatrix, mf); | 230 ExpectEqualMatrix(kIdentityMatrix, mf); |
82 ExpectEqualMatrix(kIdentityMatrix, mi); | 231 ExpectEqualMatrix(kIdentityMatrix, mi); |
83 | 232 |
84 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | 233 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
85 } | 234 } |
86 } | 235 } |
87 | 236 |
88 TEST_F(CHROMIUMPathRenderingTest, TestMatrixErrors) { | 237 TEST_F(CHROMIUMPathRenderingTest, TestMatrixErrors) { |
89 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) { | 238 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) |
90 return; | 239 return; |
91 } | 240 |
92 GLfloat mf[16]; | 241 GLfloat mf[16]; |
93 memset(mf, 0, sizeof(mf)); | 242 memset(mf, 0, sizeof(mf)); |
94 | 243 |
95 // This should fail. | 244 glMatrixLoadfCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM, mf); |
| 245 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 246 |
| 247 glMatrixLoadIdentityCHROMIUM(GL_PATH_PROJECTION_CHROMIUM); |
| 248 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 249 |
| 250 // Test that invalid matrix targets fail. |
96 glMatrixLoadfCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM - 1, mf); | 251 glMatrixLoadfCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM - 1, mf); |
97 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); | 252 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); |
98 | 253 |
99 glMatrixLoadfCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM, mf); | 254 // Test that invalid matrix targets fail. |
100 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | |
101 | |
102 // This should fail. | |
103 glMatrixLoadIdentityCHROMIUM(GL_PATH_PROJECTION_CHROMIUM + 1); | 255 glMatrixLoadIdentityCHROMIUM(GL_PATH_PROJECTION_CHROMIUM + 1); |
104 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); | 256 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); |
105 | 257 } |
106 glMatrixLoadIdentityCHROMIUM(GL_PATH_PROJECTION_CHROMIUM); | 258 |
107 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | 259 TEST_F(CHROMIUMPathRenderingTest, TestSimpleCalls) { |
| 260 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) |
| 261 return; |
| 262 |
| 263 // This is unspecified in NV_path_rendering. |
| 264 EXPECT_EQ(0u, glGenPathsCHROMIUM(0)); |
| 265 |
| 266 GLuint path = glGenPathsCHROMIUM(1); |
| 267 EXPECT_NE(path, 0u); |
| 268 glDeletePathsCHROMIUM(path, 1); |
| 269 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 270 |
| 271 GLuint first_path = glGenPathsCHROMIUM(5); |
| 272 EXPECT_NE(first_path, 0u); |
| 273 glDeletePathsCHROMIUM(first_path, 5); |
| 274 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 275 |
| 276 // Test deleting paths that are not actually allocated: |
| 277 // "unused names in /paths/ are silently ignored". |
| 278 first_path = glGenPathsCHROMIUM(5); |
| 279 EXPECT_NE(first_path, 0u); |
| 280 glDeletePathsCHROMIUM(first_path, 6); |
| 281 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 282 |
| 283 GLsizei big_range = 0xffff; |
| 284 // Setting big_range = std::numeric_limits<GLsizei>::max() should go through |
| 285 // too, as far as NV_path_rendering is concerned. Current chromium side id |
| 286 // allocator will use too much memory. |
| 287 first_path = glGenPathsCHROMIUM(big_range); |
| 288 EXPECT_NE(first_path, 0u); |
| 289 glDeletePathsCHROMIUM(first_path, big_range); |
| 290 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 291 |
| 292 // Test glIsPathCHROMIUM(). |
| 293 path = glGenPathsCHROMIUM(1); |
| 294 EXPECT_FALSE(glIsPathCHROMIUM(path)); |
| 295 GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM}; |
| 296 GLfloat coords[] = {50.0f, 50.0f}; |
| 297 glPathCommandsCHROMIUM(path, arraysize(commands), commands, arraysize(coords), |
| 298 GL_FLOAT, coords); |
| 299 EXPECT_TRUE(glIsPathCHROMIUM(path)); |
| 300 glDeletePathsCHROMIUM(path, 1); |
| 301 EXPECT_FALSE(glIsPathCHROMIUM(path)); |
| 302 } |
| 303 |
| 304 TEST_F(CHROMIUMPathRenderingTest, TestGenDeleteErrors) { |
| 305 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) |
| 306 return; |
| 307 |
| 308 // GenPaths / DeletePaths tests. |
| 309 // std::numeric_limits<GLuint>::max() is wrong for GLsizei. |
| 310 GLuint first_path = glGenPathsCHROMIUM(std::numeric_limits<GLuint>::max()); |
| 311 EXPECT_EQ(first_path, 0u); |
| 312 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); |
| 313 |
| 314 first_path = glGenPathsCHROMIUM(-1); |
| 315 EXPECT_EQ(first_path, 0u); |
| 316 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); |
| 317 |
| 318 glDeletePathsCHROMIUM(1, -5); |
| 319 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); |
| 320 |
| 321 first_path = glGenPathsCHROMIUM(-1); |
| 322 EXPECT_EQ(first_path, 0u); |
| 323 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); |
| 324 |
| 325 // Test that delete with first_id and range such that first_id + range |
| 326 // overflows the GLuint. Example: |
| 327 // Range is 0x7fffffff. First id is X. Last id will be X + 0x7ffffffe. |
| 328 // X = 0x80000001 would succeed, where as X = 0x80000002 would fail. |
| 329 // To get 0x80000002, we need to allocate first 0x7fffffff and then |
| 330 // 3 (0x80000000, 0x80000001 and 0x80000002). |
| 331 // While not guaranteed by the API, we expect the implementation |
| 332 // hands us deterministic ids. |
| 333 first_path = glGenPathsCHROMIUM(std::numeric_limits<GLsizei>::max()); |
| 334 EXPECT_EQ(first_path, 1u); |
| 335 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 336 |
| 337 GLuint additional_paths = glGenPathsCHROMIUM(3); |
| 338 EXPECT_EQ(additional_paths, |
| 339 static_cast<GLuint>(std::numeric_limits<GLsizei>::max()) + 1u); |
| 340 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 341 |
| 342 // Test that passing a range so big that it would overflow client_id |
| 343 // + range - 1 check causes an error. |
| 344 glDeletePathsCHROMIUM(additional_paths + 2u, |
| 345 std::numeric_limits<GLsizei>::max()); |
| 346 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); |
| 347 |
| 348 // Cleanup the above allocations. Also test that passing max value still |
| 349 // works. |
| 350 glDeletePathsCHROMIUM(1, std::numeric_limits<GLsizei>::max()); |
| 351 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 352 glDeletePathsCHROMIUM(std::numeric_limits<GLsizei>::max(), |
| 353 std::numeric_limits<GLsizei>::max()); |
| 354 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 355 } |
| 356 |
| 357 TEST_F(CHROMIUMPathRenderingTest, TestPathParameterErrors) { |
| 358 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) |
| 359 return; |
| 360 |
| 361 GLuint path = glGenPathsCHROMIUM(1); |
| 362 // PathParameter*: Wrong value for the pname should fail. |
| 363 glPathParameteriCHROMIUM(path, GL_PATH_JOIN_STYLE_CHROMIUM, GL_FLAT_CHROMIUM); |
| 364 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); |
| 365 glPathParameterfCHROMIUM(path, GL_PATH_END_CAPS_CHROMIUM, |
| 366 GL_MITER_REVERT_CHROMIUM); |
| 367 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); |
| 368 |
| 369 // PathParameter*: Wrong floating-point value should fail. |
| 370 glPathParameterfCHROMIUM(path, GL_PATH_STROKE_WIDTH_CHROMIUM, -0.1f); |
| 371 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); |
| 372 glPathParameterfCHROMIUM(path, GL_PATH_MITER_LIMIT_CHROMIUM, |
| 373 std::numeric_limits<float>::quiet_NaN()); |
| 374 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); |
| 375 glPathParameterfCHROMIUM(path, GL_PATH_MITER_LIMIT_CHROMIUM, |
| 376 std::numeric_limits<float>::infinity()); |
| 377 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); |
| 378 |
| 379 // PathParameter*: Wrong pname should fail. |
| 380 glPathParameteriCHROMIUM(path, GL_PATH_STROKE_WIDTH_CHROMIUM - 1, 5); |
| 381 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); |
| 382 glDeletePathsCHROMIUM(path, 1); |
| 383 } |
| 384 |
| 385 TEST_F(CHROMIUMPathRenderingTest, TestPathObjectState) { |
| 386 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) |
| 387 return; |
| 388 |
| 389 glViewport(0, 0, kResolution, kResolution); |
| 390 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| 391 glStencilMask(0xffffffff); |
| 392 glClearStencil(0); |
| 393 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
| 394 glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0xFF); |
| 395 glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); |
| 396 |
| 397 // Test that trying to draw non-existing paths does not produce errors or |
| 398 // results. |
| 399 GLuint non_existing_paths[] = {0, 55, 74744}; |
| 400 for (auto& p : non_existing_paths) { |
| 401 EXPECT_FALSE(glIsPathCHROMIUM(p)); |
| 402 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 403 TryAllDrawFunctions(p, GL_NO_ERROR); |
| 404 } |
| 405 |
| 406 // Path name marked as used but without path object state causes |
| 407 // a GL error upon any draw command. |
| 408 GLuint path = glGenPathsCHROMIUM(1); |
| 409 EXPECT_FALSE(glIsPathCHROMIUM(path)); |
| 410 TryAllDrawFunctions(path, GL_INVALID_OPERATION); |
| 411 glDeletePathsCHROMIUM(path, 1); |
| 412 |
| 413 // Document a bit of an inconsistency: path name marked as used but without |
| 414 // path object state causes a GL error upon any draw command (tested above). |
| 415 // Path name that had path object state, but then was "cleared", still has a |
| 416 // path object state, even though the state is empty. |
| 417 path = glGenPathsCHROMIUM(1); |
| 418 EXPECT_FALSE(glIsPathCHROMIUM(path)); |
| 419 GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM}; |
| 420 GLfloat coords[] = {50.0f, 50.0f}; |
| 421 glPathCommandsCHROMIUM(path, arraysize(commands), commands, arraysize(coords), |
| 422 GL_FLOAT, coords); |
| 423 EXPECT_TRUE(glIsPathCHROMIUM(path)); |
| 424 glPathCommandsCHROMIUM(path, 0, NULL, 0, GL_FLOAT, NULL); |
| 425 EXPECT_TRUE(glIsPathCHROMIUM(path)); // The surprise. |
| 426 TryAllDrawFunctions(path, GL_NO_ERROR); |
| 427 glDeletePathsCHROMIUM(path, 1); |
| 428 |
| 429 // Document a bit of an inconsistency: "clearing" a used path name causes |
| 430 // path to acquire state. |
| 431 path = glGenPathsCHROMIUM(1); |
| 432 EXPECT_FALSE(glIsPathCHROMIUM(path)); |
| 433 glPathCommandsCHROMIUM(path, 0, NULL, 0, GL_FLOAT, NULL); |
| 434 EXPECT_TRUE(glIsPathCHROMIUM(path)); // The surprise. |
| 435 glDeletePathsCHROMIUM(path, 1); |
| 436 |
| 437 // Make sure nothing got drawn by the drawing commands that should not produce |
| 438 // anything. |
| 439 const uint8 black[] = {0, 0, 0, 0}; |
| 440 EXPECT_TRUE( |
| 441 GLTestHelper::CheckPixels(0, 0, kResolution, kResolution, 0, black)); |
| 442 } |
| 443 |
| 444 TEST_F(CHROMIUMPathRenderingTest, TestUnnamedPathsErrors) { |
| 445 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) |
| 446 return; |
| 447 |
| 448 // Unnamed paths: Trying to create a path object with non-existing path name |
| 449 // produces error. (Not a error in real NV_path_rendering). |
| 450 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 451 GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM}; |
| 452 GLfloat coords[] = {50.0f, 50.0f}; |
| 453 glPathCommandsCHROMIUM(555, arraysize(commands), commands, arraysize(coords), |
| 454 GL_FLOAT, coords); |
| 455 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); |
| 456 |
| 457 // PathParameter*: Using non-existing path object produces error. |
| 458 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 459 glPathParameterfCHROMIUM(555, GL_PATH_STROKE_WIDTH_CHROMIUM, 5.0f); |
| 460 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); |
| 461 |
| 462 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 463 glPathParameteriCHROMIUM(555, GL_PATH_JOIN_STYLE_CHROMIUM, GL_ROUND_CHROMIUM); |
| 464 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); |
| 465 } |
| 466 |
| 467 TEST_F(CHROMIUMPathRenderingTest, TestPathCommandsErrors) { |
| 468 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) |
| 469 return; |
| 470 |
| 471 static const GLenum kInvalidCoordType = GL_NONE; |
| 472 |
| 473 GLuint path = glGenPathsCHROMIUM(1); |
| 474 GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM}; |
| 475 GLfloat coords[] = {50.0f, 50.0f}; |
| 476 |
| 477 glPathCommandsCHROMIUM(path, arraysize(commands), commands, -4, GL_FLOAT, |
| 478 coords); |
| 479 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); |
| 480 |
| 481 glPathCommandsCHROMIUM(path, -1, commands, arraysize(coords), GL_FLOAT, |
| 482 coords); |
| 483 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); |
| 484 |
| 485 glPathCommandsCHROMIUM(path, arraysize(commands), commands, arraysize(coords), |
| 486 kInvalidCoordType, coords); |
| 487 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); |
| 488 |
| 489 // These can not distinquish between the check that should fail them. |
| 490 // This should fail due to coord count * float size overflow. |
| 491 glPathCommandsCHROMIUM(path, arraysize(commands), commands, |
| 492 std::numeric_limits<GLsizei>::max(), GL_FLOAT, coords); |
| 493 // This should fail due to cmd count + coord count * short size. |
| 494 glPathCommandsCHROMIUM(path, arraysize(commands), commands, |
| 495 std::numeric_limits<GLsizei>::max(), GL_SHORT, coords); |
| 496 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); |
| 497 |
| 498 glDeletePathsCHROMIUM(path, 1); |
| 499 } |
| 500 |
| 501 TEST_F(CHROMIUMPathRenderingTest, TestPathRenderingInvalidArgs) { |
| 502 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) |
| 503 return; |
| 504 |
| 505 GLuint path = glGenPathsCHROMIUM(1); |
| 506 glPathCommandsCHROMIUM(path, 0, NULL, 0, GL_FLOAT, NULL); |
| 507 |
| 508 // Verify that normal calls work. |
| 509 glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F); |
| 510 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 511 glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F, |
| 512 GL_BOUNDING_BOX_CHROMIUM); |
| 513 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
| 514 |
| 515 // Using invalid fill mode causes INVALID_ENUM. |
| 516 glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM - 1, 0x7F); |
| 517 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); |
| 518 glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM - 1, 0x7F, |
| 519 GL_BOUNDING_BOX_CHROMIUM); |
| 520 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); |
| 521 |
| 522 // Using invalid cover mode causes INVALID_ENUM. |
| 523 glCoverFillPathCHROMIUM(path, GL_CONVEX_HULL_CHROMIUM - 1); |
| 524 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); |
| 525 glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F, |
| 526 GL_BOUNDING_BOX_CHROMIUM + 1); |
| 527 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); |
| 528 |
| 529 // Using mask+1 not being power of two causes INVALID_VALUE with up/down fill |
| 530 // mode. |
| 531 glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x40); |
| 532 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); |
| 533 glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_DOWN_CHROMIUM, 12, |
| 534 GL_BOUNDING_BOX_CHROMIUM); |
| 535 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); |
| 536 |
| 537 glDeletePathsCHROMIUM(path, 1); |
| 538 } |
| 539 |
| 540 // Tests that drawing with CHROMIUM_path_rendering functions work. |
| 541 TEST_F(CHROMIUMPathRenderingTest, TestPathRendering) { |
| 542 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) |
| 543 return; |
| 544 |
| 545 static const float kBlue[] = {0.0f, 0.0f, 1.0f, 1.0f}; |
| 546 static const float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f}; |
| 547 |
| 548 SetupStateForTestPattern(); |
| 549 |
| 550 GLuint path = glGenPathsCHROMIUM(1); |
| 551 SetupPathStateForTestPattern(path); |
| 552 |
| 553 // Do the stencil fill, cover fill, stencil stroke, cover stroke |
| 554 // in unconventional order: |
| 555 // 1) stencil the stroke in stencil high bit |
| 556 // 2) stencil the fill in low bits |
| 557 // 3) cover the fill |
| 558 // 4) cover the stroke |
| 559 // This is done to check that glPathStencilFunc works, eg the mask |
| 560 // goes through. Stencil func is not tested ATM, for simplicity. |
| 561 |
| 562 glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0xFF); |
| 563 glStencilStrokePathCHROMIUM(path, 0x80, 0x80); |
| 564 |
| 565 glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0x7F); |
| 566 glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F); |
| 567 |
| 568 glStencilFunc(GL_LESS, 0, 0x7F); |
| 569 glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); |
| 570 glUniform4fv(color_loc_, 1, kBlue); |
| 571 glCoverFillPathCHROMIUM(path, GL_BOUNDING_BOX_CHROMIUM); |
| 572 |
| 573 glStencilFunc(GL_EQUAL, 0x80, 0x80); |
| 574 glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); |
| 575 glUniform4fv(color_loc_, 1, kGreen); |
| 576 glCoverStrokePathCHROMIUM(path, GL_CONVEX_HULL_CHROMIUM); |
| 577 |
| 578 glDeletePathsCHROMIUM(path, 1); |
| 579 |
| 580 // Verify the image. |
| 581 VerifyTestPatternFill(0.0f, 0.0f); |
| 582 VerifyTestPatternBg(0.0f, 0.0f); |
| 583 VerifyTestPatternStroke(0.0f, 0.0f); |
| 584 } |
| 585 |
| 586 // Tests that drawing with CHROMIUM_path_rendering |
| 587 // StencilThenCover{Stroke,Fill}Path functions work. |
| 588 TEST_F(CHROMIUMPathRenderingTest, TestPathRenderingThenFunctions) { |
| 589 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) |
| 590 return; |
| 591 |
| 592 static float kBlue[] = {0.0f, 0.0f, 1.0f, 1.0f}; |
| 593 static float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f}; |
| 594 |
| 595 SetupStateForTestPattern(); |
| 596 |
| 597 GLuint path = glGenPathsCHROMIUM(1); |
| 598 SetupPathStateForTestPattern(path); |
| 599 |
| 600 glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0xFF); |
| 601 glStencilFunc(GL_EQUAL, 0x80, 0x80); |
| 602 glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); |
| 603 glUniform4fv(color_loc_, 1, kGreen); |
| 604 glStencilThenCoverStrokePathCHROMIUM(path, 0x80, 0x80, |
| 605 GL_BOUNDING_BOX_CHROMIUM); |
| 606 |
| 607 glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0x7F); |
| 608 glStencilFunc(GL_LESS, 0, 0x7F); |
| 609 glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); |
| 610 glUniform4fv(color_loc_, 1, kBlue); |
| 611 glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F, |
| 612 GL_CONVEX_HULL_CHROMIUM); |
| 613 |
| 614 glDeletePathsCHROMIUM(path, 1); |
| 615 |
| 616 // Verify the image. |
| 617 VerifyTestPatternFill(0.0f, 0.0f); |
| 618 VerifyTestPatternBg(0.0f, 0.0f); |
| 619 VerifyTestPatternStroke(0.0f, 0.0f); |
108 } | 620 } |
109 | 621 |
110 } // namespace gpu | 622 } // namespace gpu |
OLD | NEW |