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.
6 #include <GLES2/gl2ext.h>
7 #include <GLES2/gl2extchromium.h>
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
21 class CHROMIUMPathRenderingTest
: public testing::Test
{
23 static const GLsizei kResolution
= 100;
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);
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
; });
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),
72 2.0f
/ (kResolution
- 1),
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
,
94 GL_QUADRATIC_CURVE_TO_CHROMIUM
,
95 GL_CUBIC_CURVE_TO_CHROMIUM
,
96 GL_CLOSE_PATH_CHROMIUM
};
98 static const GLfloat kCoords
[] = {50.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
,
121 glPathParameteriCHROMIUM(path
, GL_PATH_END_CAPS_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];
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());
192 TEST_F(CHROMIUMPathRenderingTest
, TestMatrix
) {
193 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering"))
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
) {
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"))
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"))
263 // This is unspecified in NV_path_rendering.
264 EXPECT_EQ(0u, glGenPathsCHROMIUM(0));
266 GLuint path
= glGenPathsCHROMIUM(1);
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
),
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"))
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
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"))
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"))
389 glViewport(0, 0, kResolution
, kResolution
);
390 glClearColor(0.0f
, 0.0f
, 0.0f
, 0.0f
);
391 glStencilMask(0xffffffff);
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
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
),
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
439 const uint8 black
[] = {0, 0, 0, 0};
441 GLTestHelper::CheckPixels(0, 0, kResolution
, kResolution
, 0, black
));
444 TEST_F(CHROMIUMPathRenderingTest
, TestUnnamedPathsErrors
) {
445 if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering"))
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
),
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"))
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
,
479 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), glGetError());
481 glPathCommandsCHROMIUM(path
, -1, commands
, arraysize(coords
), GL_FLOAT
,
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"))
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
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"))
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
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);
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"))
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);
617 VerifyTestPatternFill(0.0f
, 0.0f
);
618 VerifyTestPatternBg(0.0f
, 0.0f
);
619 VerifyTestPatternStroke(0.0f
, 0.0f
);