Elim cr-checkbox
[chromium-blink-merge.git] / gpu / command_buffer / tests / gl_chromium_path_rendering_unittest.cc
blob57f5dd02ea7993eeb64602c590762d63426d4a23
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>
7 #include <GLES2/gl2extchromium.h>
8 #include <cmath>
10 #include "base/command_line.h"
11 #include "gpu/command_buffer/service/gpu_switches.h"
12 #include "gpu/command_buffer/tests/gl_manager.h"
13 #include "gpu/command_buffer/tests/gl_test_utils.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 #define SHADER(Src) #Src
19 namespace gpu {
21 class CHROMIUMPathRenderingTest : public testing::Test {
22 public:
23 static const GLsizei kResolution = 100;
25 protected:
26 void SetUp() override {
27 GLManager::Options options;
28 options.size = gfx::Size(kResolution, kResolution);
29 base::CommandLine command_line(*base::CommandLine::ForCurrentProcess());
30 command_line.AppendSwitch(switches::kEnableGLPathRendering);
31 gl_.InitializeWithCommandLine(options, &command_line);
34 void TearDown() override { gl_.Destroy(); }
36 void ExpectEqualMatrix(const GLfloat* expected, const GLfloat* actual) {
37 for (size_t i = 0; i < 16; ++i) {
38 EXPECT_EQ(expected[i], actual[i]);
41 void ExpectEqualMatrix(const GLfloat* expected, const GLint* actual) {
42 for (size_t i = 0; i < 16; ++i) {
43 EXPECT_EQ(static_cast<GLint>(round(expected[i])), actual[i]);
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);
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; });
60 GLuint program =
61 GLTestHelper::LoadProgram(kVertexShaderSource, kFragmentShaderSource);
62 glUseProgram(program);
63 color_loc_ = glGetUniformLocation(program, "color");
64 glDeleteProgram(program);
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);
86 glEnable(GL_STENCIL_TEST);
88 GLTestHelper::CheckGLError("no errors at state setup", __LINE__);
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};
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};
113 glPathCommandsCHROMIUM(path, arraysize(kCommands), kCommands,
114 arraysize(kCoords), GL_FLOAT, kCoords);
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);
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};
130 for (size_t i = 0; i < arraysize(kFillCoords); i += 2) {
131 float fx = kFillCoords[i];
132 float fy = kFillCoords[i + 1];
134 EXPECT_TRUE(GLTestHelper::CheckPixels(x + fx, y + fy, 1, 1, 0, kBlue));
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};
142 for (size_t i = 0; i < arraysize(kBackgroundCoords); i += 2) {
143 float bx = kBackgroundCoords[i];
144 float by = kBackgroundCoords[i + 1];
146 EXPECT_TRUE(
147 GLTestHelper::CheckPixels(x + bx, y + by, 1, 1, 0, kExpectedColor));
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));
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));
163 void TryAllDrawFunctions(GLuint path, GLenum expected_error) {
164 glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F);
165 EXPECT_EQ(expected_error, glGetError());
167 glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F);
168 EXPECT_EQ(expected_error, glGetError());
170 glStencilStrokePathCHROMIUM(path, 0x80, 0x80);
171 EXPECT_EQ(expected_error, glGetError());
173 glCoverFillPathCHROMIUM(path, GL_BOUNDING_BOX_CHROMIUM);
174 EXPECT_EQ(expected_error, glGetError());
176 glCoverStrokePathCHROMIUM(path, GL_BOUNDING_BOX_CHROMIUM);
177 EXPECT_EQ(expected_error, glGetError());
179 glStencilThenCoverStrokePathCHROMIUM(path, 0x80, 0x80,
180 GL_BOUNDING_BOX_CHROMIUM);
181 EXPECT_EQ(expected_error, glGetError());
183 glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F,
184 GL_BOUNDING_BOX_CHROMIUM);
185 EXPECT_EQ(expected_error, glGetError());
188 GLManager gl_;
189 GLint color_loc_;
192 TEST_F(CHROMIUMPathRenderingTest, TestMatrix) {
193 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering"))
194 return;
196 static const GLfloat kIdentityMatrix[16] = {
197 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
198 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
199 static const GLfloat kSeqMatrix[16] = {
200 0.5f, -0.5f, -0.1f, -0.8f, 4.4f, 5.5f, 6.6f, 7.7f,
201 8.8f, 9.9f, 10.11f, 11.22f, 12.33f, 13.44f, 14.55f, 15.66f};
202 static const GLenum kMatrixModes[] = {GL_PATH_MODELVIEW_CHROMIUM,
203 GL_PATH_PROJECTION_CHROMIUM};
204 static const GLenum kGetMatrixModes[] = {GL_PATH_MODELVIEW_MATRIX_CHROMIUM,
205 GL_PATH_PROJECTION_MATRIX_CHROMIUM};
207 for (size_t i = 0; i < arraysize(kMatrixModes); ++i) {
208 GLfloat mf[16];
209 GLint mi[16];
210 memset(mf, 0, sizeof(mf));
211 memset(mi, 0, sizeof(mi));
212 glGetFloatv(kGetMatrixModes[i], mf);
213 glGetIntegerv(kGetMatrixModes[i], mi);
214 ExpectEqualMatrix(kIdentityMatrix, mf);
215 ExpectEqualMatrix(kIdentityMatrix, mi);
217 glMatrixLoadfCHROMIUM(kMatrixModes[i], kSeqMatrix);
218 memset(mf, 0, sizeof(mf));
219 memset(mi, 0, sizeof(mi));
220 glGetFloatv(kGetMatrixModes[i], mf);
221 glGetIntegerv(kGetMatrixModes[i], mi);
222 ExpectEqualMatrix(kSeqMatrix, mf);
223 ExpectEqualMatrix(kSeqMatrix, mi);
225 glMatrixLoadIdentityCHROMIUM(kMatrixModes[i]);
226 memset(mf, 0, sizeof(mf));
227 memset(mi, 0, sizeof(mi));
228 glGetFloatv(kGetMatrixModes[i], mf);
229 glGetIntegerv(kGetMatrixModes[i], mi);
230 ExpectEqualMatrix(kIdentityMatrix, mf);
231 ExpectEqualMatrix(kIdentityMatrix, mi);
233 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
237 TEST_F(CHROMIUMPathRenderingTest, TestMatrixErrors) {
238 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering"))
239 return;
241 GLfloat mf[16];
242 memset(mf, 0, sizeof(mf));
244 glMatrixLoadfCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM, mf);
245 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
247 glMatrixLoadIdentityCHROMIUM(GL_PATH_PROJECTION_CHROMIUM);
248 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
250 // Test that invalid matrix targets fail.
251 glMatrixLoadfCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM - 1, mf);
252 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError());
254 // Test that invalid matrix targets fail.
255 glMatrixLoadIdentityCHROMIUM(GL_PATH_PROJECTION_CHROMIUM + 1);
256 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError());
259 TEST_F(CHROMIUMPathRenderingTest, TestSimpleCalls) {
260 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering"))
261 return;
263 // This is unspecified in NV_path_rendering.
264 EXPECT_EQ(0u, glGenPathsCHROMIUM(0));
266 GLuint path = glGenPathsCHROMIUM(1);
267 EXPECT_NE(path, 0u);
268 glDeletePathsCHROMIUM(path, 1);
269 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
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());
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());
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());
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));
304 TEST_F(CHROMIUMPathRenderingTest, TestGenDeleteErrors) {
305 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering"))
306 return;
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());
314 first_path = glGenPathsCHROMIUM(-1);
315 EXPECT_EQ(first_path, 0u);
316 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError());
318 glDeletePathsCHROMIUM(1, -5);
319 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError());
321 first_path = glGenPathsCHROMIUM(-1);
322 EXPECT_EQ(first_path, 0u);
323 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError());
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());
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());
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());
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());
357 TEST_F(CHROMIUMPathRenderingTest, TestPathParameterErrors) {
358 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering"))
359 return;
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());
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());
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);
385 TEST_F(CHROMIUMPathRenderingTest, TestPathObjectState) {
386 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering"))
387 return;
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);
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);
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);
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);
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);
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));
444 TEST_F(CHROMIUMPathRenderingTest, TestUnnamedPathsErrors) {
445 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering"))
446 return;
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());
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());
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());
467 TEST_F(CHROMIUMPathRenderingTest, TestPathCommandsErrors) {
468 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering"))
469 return;
471 static const GLenum kInvalidCoordType = GL_NONE;
473 GLuint path = glGenPathsCHROMIUM(1);
474 GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM};
475 GLfloat coords[] = {50.0f, 50.0f};
477 glPathCommandsCHROMIUM(path, arraysize(commands), commands, -4, GL_FLOAT,
478 coords);
479 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError());
481 glPathCommandsCHROMIUM(path, -1, commands, arraysize(coords), GL_FLOAT,
482 coords);
483 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError());
485 glPathCommandsCHROMIUM(path, arraysize(commands), commands, arraysize(coords),
486 kInvalidCoordType, coords);
487 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError());
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());
498 glDeletePathsCHROMIUM(path, 1);
501 TEST_F(CHROMIUMPathRenderingTest, TestPathRenderingInvalidArgs) {
502 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering"))
503 return;
505 GLuint path = glGenPathsCHROMIUM(1);
506 glPathCommandsCHROMIUM(path, 0, NULL, 0, GL_FLOAT, NULL);
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());
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());
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());
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());
537 glDeletePathsCHROMIUM(path, 1);
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;
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};
548 SetupStateForTestPattern();
550 GLuint path = glGenPathsCHROMIUM(1);
551 SetupPathStateForTestPattern(path);
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.
562 glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0xFF);
563 glStencilStrokePathCHROMIUM(path, 0x80, 0x80);
565 glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0x7F);
566 glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F);
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);
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);
578 glDeletePathsCHROMIUM(path, 1);
580 // Verify the image.
581 VerifyTestPatternFill(0.0f, 0.0f);
582 VerifyTestPatternBg(0.0f, 0.0f);
583 VerifyTestPatternStroke(0.0f, 0.0f);
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;
592 static float kBlue[] = {0.0f, 0.0f, 1.0f, 1.0f};
593 static float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f};
595 SetupStateForTestPattern();
597 GLuint path = glGenPathsCHROMIUM(1);
598 SetupPathStateForTestPattern(path);
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);
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);
614 glDeletePathsCHROMIUM(path, 1);
616 // Verify the image.
617 VerifyTestPatternFill(0.0f, 0.0f);
618 VerifyTestPatternBg(0.0f, 0.0f);
619 VerifyTestPatternStroke(0.0f, 0.0f);
622 } // namespace gpu