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