blob: 74f7632972619bb85df8f7200cc1dc819d89238e [file] [log] [blame]
Name
CHROMIUM_path_rendering
Name Strings
GL_CHROMIUM_path_rendering
Version
Last Modifed Date: August 14, 2014
Dependencies
OpenGL ES 3.0 is required.
Overview
This extensions implements path rendering using
OpenGL API.
New Tokens
Accepted by the <matrixMode> parameter of MatrixLoadfCHROMIUM and
MatrixLoadIdentityCHROMIUM:
PATH_MODELVIEW_CHROMIUM 0x1700
PATH_PROJECTION_CHROMIUM 0x1701
Accepted in elements of the <commands> array parameter of
PathCommandsCHROMIUM:
CLOSE_PATH_CHROMIUM 0x00
MOVE_TO_CHROMIUM 0x02
LINE_TO_CHROMIUM 0x04
QUADRATIC_CURVE_TO_CHROMIUM 0x0A
CUBIC_CURVE_TO_CHROMIUM 0x0C
CONIC_CURVE_TO_CHROMIUM 0x1A
Accepted by the <pname> parameter of GetIntegerv,
GetFloatv:
PATH_MODELVIEW_MATRIX_CHROMIUM 0x0BA6
PATH_PROJECTION_MATRIX_CHROMIUM 0x0BA7
Accepted by the <pname> parameter of PathParameter{if}CHROMIUM:
PATH_STROKE_WIDTH_CHROMIUM 0x9075
PATH_END_CAPS_CHROMIUM 0x9076
PATH_JOIN_STYLE_CHROMIUM 0x9079
PATH_MITER_LIMIT_CHROMIUM 0x907a
PATH_STROKE_BOUND_CHROMIUM 0x9086
Accepted by the <value> parameter of PathParameter{if}CHROMIUM:
FLAT_CHROMIUM 0x1D00
SQUARE_CHROMIUM 0x90a3
ROUND_CHROMIUM 0x90a4
BEVEL_CHROMIUM 0x90A6
MITER_REVERT_CHROMIUM 0x90A7
Accepted by the <fillMode> parameter of StencilFillPathCHROMIUM
StencilFillPathInstancedCHROMIUM and
StencilThenCoverFillPathInstancedCHROMIUM:
COUNT_UP_CHROMIUM 0x9088
COUNT_DOWN_CHROMIUM 0x9089
Accepted by the <coverMode> parameter of CoverFillPathCHROMIUM,
CoverStrokePath, StencilThenCoverFillPathCHROMIUM and
StencilThenCoverStrokePathCHROMIUM:
CONVEX_HULL_CHROMIUM 0x908B
BOUNDING_BOX_CHROMIUM 0x908D
Accepted by the <coverMode> parameter of CoverFillPathInstancedCHROMIUM,
CoverStrokePathInstanced, StencilThenCoverFillPathInstancedCHROMIUM and
StencilThenCoverStrokePathInstancedCHROMIUM:
CONVEX_HULL_CHROMIUM see above
BOUNDING_BOX_CHROMIUM see above
BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM 0x909C
Accepted by the <genMode> parameter of ProgramPathFragmentInputGen:
EYE_LINEAR_CHROMIUM 0x2400
OBJECT_LINEAR_CHROMIUM 0x2401
CONSTANT_CHROMIUM 0x8576
Accepted by the <transformType> parameter of
StencilFillPathInstancedCHROMIUM, StencilStrokePathInstancedCHROMIUM,
CoverFillPathInstancedCHROMIUM, CoverStrokePathInstancedCHROMIUM,
StencilThenCoverFillPathInstancedCHROMIUM and
StencilThenCoverStrokePathInstancedCHROMIUM:
TRANSLATE_X_CHROMIUM 0x908E
TRANSLATE_Y_CHROMIUM 0x908F
TRANSLATE_2D_CHROMIUM 0x9090
TRANSLATE_3D_CHROMIUM 0x9091
AFFINE_2D_CHROMIUM 0x9092
AFFINE_3D_CHROMIUM 0x9094
TRANSPOSE_AFFINE_2D_CHROMIUM 0x9096
TRANSPOSE_AFFINE_3D_CHROMIUM 0x9098
New Procedures and Functions
void MatrixLoadfCHROMIUM(enum matrixMode, float* matrix)
Takes a pointer to a 4x4 matrix stored in column-major order as 16
consecutive floating-point values. The matrixMode specifies which
matrix, PATH_MODELVIEW_CHROMIUM or PATH_PROJECTION_CHROMIUM is used.
The funcition specifies either modelview or projection matrix
to be used with path rendering API calls.
void MatrixLoadIdentityCHROMIUM(enum matrixMode)
Effectively calls MatrixLoadf with the identity matrix.
uint GenPathsCHROMIUM(sizei range)
Returns an integer /n/ such that names /n/, ..., /n+range-1/ are
previously unused (i.e. there are /range/ previously unused path object
names starting at /n/). These names are marked as used, for the
purposes of subsequent GenPathsCHROMIUM only, but they do not acquire
path object state until each particular name is used to specify
a path object.
Returns 0 if no new path name was marked as used. Reasons for this
include lack of free path names or range being 0 or a GL error
was generated.
INVALID_VALUE error is generated if range is negative.
INVALID_OPERATION error is generated if range does not fit in
32-bit uint.
void DeletePathsCHROMIUM(uint path, sizei range)
Deletes a path object where /path/ contains /range/ names of path objects to
be delete. After a path object is deleted, its name is again unused.
Unused names in /paths/ are silently ignored.
INVALID_VALUE error is generated if /range/ is negative.
INVALID_OPERATION error is generated if /range/ does not
fit in 32-bit uint.
INVALID_OPERATION error is generated if /path/ + /range/ does not fit
32-bit uint.
boolean IsPathCHROMIUM(uint path);
The query returns TRUE if /path/ is the name of a path object. If path is
not the name of a path object, or if an error condition occurs,
IsPathCHROMIUM returns FALSE. A name retuned by GenPathsCHROMIUM, but
without a path specified for it yet, is not the name of a path object.
void PathCommandsCHROMIUM(uint path, sizei numCommands,
const ubyte* commands, sizei numCoords,
enum coordType, const GLvoid* coords)
Specifies a path object commands for /path/ where /numCommands/
indicates the number of path commands, read from the array
/commands/, with which to initialize that path's command sequence.
The type of the coordinates read from the /coords/ array is
determined by the /coordType/ parameter which must be one of BYTE,
UNSIGNED_BYTE, SHORT, UNSIGNED_SHORT, or FLOAT, otherwise the
INVALID_ENUM error is generated. These path commands reference
coordinates read sequentially from the /coords/ array.
The /numCommands/ elements of the /commands/ array must be tokens
in Table 5.pathCommands. The command sequence matches
the element order of the /commands/ array. Each command references
a number of coordinates specified by "Coordinate count" column of
Table 5.pathCommands, starting with the first (zero) element of
the /coords/ array and advancing by the coordinate count for each
command. If any of these /numCommands/ command values are not
listed in the "Token" column of Table
5.pathCommands, the INVALID_ENUM error is generated.
The INVALID_OPERATION error is generated if /numCoords/ does not
equal the number of coordinates referenced by the command sequence
specified by /numCommands/ and /commands/ (so /numCoords/ provides a
sanity check that the /coords/ array is being interpreted properly).
The error INVALID_VALUE is generated if either /numCommands/ or
/numCoords/ is negative.
The error INVALID_OPERATION is generated if /path/ is
not an existing path object.
The error INVALID_OPERATION is generated if
/numCommands/ + (size of /coordType/ data type) * /numCoords/
does not fit in 32-bit uint.
If the PathCommandsCHROMIUM command results in an error, the path object
named /path/ is not changed; if there is no error, the prior contents
of /path/, if /path/ was an existent path object, are lost and the
path object name /path/ becomes used.
void PathParameterfCHROMIUM(uint path, enum pname, float value)
void PathParameteriCHROMIUM(uint path, enum pname, int value)
The commands specify the value of path parameters for the specified path
object named /path/. The error INVALID_OPERATION is generated if /path/ is
not an existing path object.
Each parameter has a single (scalar) value.
/pname/ must be one of the tokens in the "Name" column of
Table 5.pathParameters.
The required values or range of each allowed parameter name token
is listed in Table 5.pathParameter's "Required Values/Range" column.
For values of /pname/ listed in Table 5.pathsParameters, the specified
parameter is specified by /value/ when /value/ is a float or int,
or if /value/ is a pointer to a float or int, accessed through that
pointer. The error INVALID_VALUE is generated if the specified
value is negative for parameters required to be non-negative in
Table 5.pathParameters.
The error INVALID_VALUE is generated if the specified parameter value
is not within the require range for parameters typed float or integer.
The error INVALID_ENUM is generated if the specified parameter value
is not one of the listed tokens for parameters typed enum.
void PathStencilFuncCHROMIUM(enum func, int ref, uint mask)
Configures the stencil function, stencil reference value, and stencil read
mask to be used by the StencilFillPathCHROMIUM and StencilStrokePathCHROMIUM
commands described subsequently. The parameters accept the same values
allowed by the StencilFunc command.
void StencilFillPathCHROMIUM(uint path, enum fillMode, uint mask)
The function transforms into window space the outline of the path object
named /path/ based on the current modelview, projection and viewport,
transforms (ignoring any vertex and/or geometry shader or program that might
be active/enabled) and then updates the stencil values of all /accessible
samples/ (explained below) in the framebuffer. Each sample's stencil buffer
value is updated based on the winding number of that sample with respect to
the transformed outline of the path object with any non-closed subpath
forced closed and the specified /fillMode/.
If /path/ does not name an existing path object, the command does
nothing (and no error is generated).
If the path's command sequence specifies unclosed subpaths (so not
contours) due to MOVE_TO_CHROMIUM commands, such subpaths are trivially
closed by connecting with a line segment the initial and terminal
control points of each such path command subsequence.
Transformation of a path's outline works by taking all positions on the
path's outline in 2D path space (x,y) and constructing an object space
position (x,y,0,1) that is then used similar to as with the (xo,yo,zo,wo)
position in section 2.12 ("Fixed-Function Vertex Transformation") of OpenGL
3.2 (unabridged) Specification (Special Functions) to compute corresponding
eye-space coordinates (xe,ye,ze,we) and clip-space coordinates
(xc,yc,zc,wc). A path outline's clip-space coordinates are further
transformed into window space similar to as described in section 2.16
("Coordinate Transformations"). This process provides a mapping 2D path
coordinates to 2D window coordinates. The resulting 2D window coordinates
are undefined if any of the transformations involved are singular or may be
inaccurate if any of the transformations (or their combination) are
ill-conditioned.
The winding number for a sample with respect to the path outline,
transformed into window space, is computed by counting the (signed)
number of revolutions around the sample point when traversing each
(trivially closed if necessary) contour once in the transformed path.
This traversal is performed in the order of the path's command
sequence. Starting from an initially zero winding count, each
counterclockwise revolution when the front face mode is CCW (or
clockwise revolution when the front face mode is CW) around the sample
point increments the winding count by one; while each clockwise
revolution when the front face mode is CCW (or counterclockwise
revolution when the front face mode is CW) around the sample point
decrements the winding count by one.
The /mask/ parameter controls what subset of stencil bits are affected
by the command.
The /fillMode/ parameter must be one of INVERT, COUNT_UP_CHROMIUM
or COUNT_DOWN_CHROMIUM; otherwise the INVALID_ENUM error
is generated. INVERT inverts the bits set in the effective /mask/
value for each sample's stencil value if the winding number for the
given sample is odd. COUNT_UP_CHROMIUM adds with modulo n arithmetic the
winding number of each sample with the sample's prior stencil buffer
value; the result of this addition is written into the sample's
stencil value but the bits of the stencil value not set in the
effective /mask/ value are left unchanged. COUNT_DOWN_CHROMIUM subtracts
with modulo /n/ arithmetic the winding number of each sample with the
sample's prior stencil buffer value; the result of this subtraction is
written into the sample's stencil value but the bits of the stencil
value not set in the effective /mask/ value are left unchanged.
The value of /n/ for the modulo /n/ arithmetic used by COUNT_UP_CHROMIUM
and COUNT_DOWN_CHROMIUM is the effective /mask/+1. The error INVALID_VALUE
is generated if /fillMode/ is COUNT_UP_CHROMIUM or COUNT_DOWN_CHROMIUM and
the effective /mask/+1 is not an integer power of two.
ACCESSIBLE SAMPLES WITH RESPECT TO A TRANSFORMED PATH
The accessible samples of a transformed path that are updated are
the samples that remain after discarding the following samples:
* Any sample that would be clipped similar to as specified in section
2.22 ("Primitive Clipping") of OpenGL 3.2 (unabridged) Specification
(Special Functions) because its corresponding position in clip space
(xc,yc,zc,wc) or (xe,ye,ze,we) would be clipped by the clip volume
or enabled client-defined clip planes.
* Any sample that would fail the pixel ownership test (section
4.1.1) if rasterized.
* Any sample that would fail the scissor test (section 4.1.2)
if SCISSOR_TEST is enabled.
And for the StencilFillPathCHROMIUM and StencilStrokePathCHROMIUM commands
(so not applicable to the CoverFillPathCHROMIUM and CoverStrokePathCHROMIUM
commands):
* Any sample that would fail the (implicitly enabled) stencil test
with the stencil function configured based on the path stencil
function state configured by PathStencilFuncCHROMIUM. In the case
of the StencilFillPathCHROMIUM and StencilStrokePathCHROMIUM
commands and their instanced versions, the effective stencil read
mask for the stencil mask is treated as the value of
PATH_STENCIL_VALUE_MASK bit-wise ANDed with the bit-invert of the
effective /mask/ parameter value; otherwise, for the cover commands,
the stencil test operates normally. In the case the stencil test
fails during a path stencil operation, the stencil fail operation is
ignored and the pixel's stencil value is left undisturbed (as if the
stencil operation was KEEP).
* The state of the face culling (CULL_FACE) enable is ignored.
void StencilStrokePathCHROMIUM(uint path, int reference, uint mask)
Transforms into window space the stroked region of the path object named
/path/ based on the current modelview, projection and viewport transforms
(ignoring any vertex and/or geometry shader or program that might be
active/enabled) and then updates the stencil values of a subset of the
accessible samples (see above) in the framebuffer.
If /path/ does not name an existing path object, the command does
nothing (and no error is generated).
The path object's specified stroke width (in path space) determines
the width of the path's stroked region.
The stroke of a transformed path's outline
is the region of window space defined by the union of:
* Sweeping an orthogonal centered line segment of the (above
determined) effective stroke width along each path segment
in the path's transformed outline.
* End cap regions (explained below) appended to the initial
and terminal control points of non-closed command sequences
in the path. For a sequence of commands that form a closed
contour, the end cap regions are ignored.
* Join style regions (explained below) between connected path
segments meet.
Any accessible samples within the union of these three regions are
considered within the path object's stroke.
If the stroke width is zero, each of the regions in the union will
be empty and there are no accessible samples within the stroke.
The /mask/ parameter controls what subset of stencil bits are affected
by the command.
A sample's stencil bits that are set in the effective /mask/ value
are updated with the specified stencil /reference/ value if the
sample is accessible (as specified above) and within the stroke of
the transformed path's outline.
Every path object has an end caps parameter
PATH_END_CAPS_CHROMIUM) that is one of FLAT_CHROMIUM,
SQUARE_CHROMIUM or ROUND_CHROMIUM. This parameter defines the
initial and terminal caps type. There are no samples within a
FLAT_CHROMIUM cap. The SQUARE_CHROMIUM cap extends centered and
tangent to the given end (initial or terminal) of the subpath for
half the effective stroke width; in other words, a square cap is a
half-square that kisses watertightly the end of a subpath. The
ROUND_CHROMIUM cap appends a semi-circle, centered and tangent,
with the diameter of the effective stroke width to the given end
(initial or terminal) of the subpath; in other words, a round cap
is a semi-circle that kisses watertightly the end of a subpath.
Every path object has a join style that is one of BEVEL_CHROMIUM,
ROUND_CHROMIUM or MITER_REVERT_CHROMIUM. Each path object also has a miter
limit value. The BEVEL_CHROMIUM join style inserts a triangle with two
vertices at the outside corners where two connected path segments join and a
third vertex at the common end point shared by the two path segments. The
ROUND_CHROMIUM join style inserts a wedge-shaped portion of a circle
centered at the common end point shared by the two path segments; the radius
of the circle is half the effective stroke width. The MITER_REVERT_CHROMIUM
join style inserts a quadrilateral with two opposite vertices at the outside
corners where the two connected path segments join and two opposite vertices
with one on the path's junction between the two joining path segments and
the other at the common end point shared by the two path segments. However,
the MITER_REVERT_CHROMIUM join style behaves as the BEVEL_CHROMIUM style if
the sine of half the angle between the two joined segments is less than the
path object's PATH_STROKE_WIDTH value divided by the path's
PATH_MITER_LIMIT_CHROMIUM value.
Every path object has a stroke approximation bound parameter
(PATH_STROKE_BOUND_CHROMIUM) that is a floating-point value /sab/ clamped
between 0.0 and 1.0 and set and queried with the PATH_STROKE_BOUND_CHROMIUM
path parameter. Exact determination of samples swept an orthogonal
centered line segment along cubic Bezier segments and rational
quadratic Bezier curves (so non-circular partial elliptical arcs) is
intractable for real-time rendering so an approximation is required;
/sab/ intuitively bounds the approximation error as a percentage of
the path object's stroke width. Specifically, this path parameter
requests the implementation to stencil any samples within /sweep/
object space units of the exact sweep of the path's cubic Bezier
segments or partial elliptical arcs to be sampled by the stroke where
sweep = ((1-sab)*sw)/2
where /sw/ is the path object's stroke width. The initial value
of /sab/ when a path is created is 0.2. In practical terms, this
initial value means the stencil sample positions coverage within 80%
(100%-20%) of the stroke width of cubic and rational quadratic stroke
segments should be sampled.
void CoverFillPathCHROMIUM(uint path, enum coverMode)
The command transforms into window space the outline of the path object
named /path/ based on the current modelview, projection and viewport
transforms (ignoring any vertex and/or geometry shader or program that might
be active/enabled) and rasterizes a subset of the accessible samples in the
framebuffer guaranteed to include all samples that would have a net
stencil value change if StencilFillPathCHROMIUM were issued with the same
modelview, projection, and viewport state. During this rasterization, the
stencil test operates normally and as configured; the expectation is the
stencil test will be used to discard samples not determined "covered" by a
prior StencilFillPathCHROMIUM command.
If /path/ does not name an existing path object, the command does
nothing (and no error is generated).
/coverMode/ must be one of CONVEX_HULL_CHROMIUM or BOUNDING_BOX_CHROMIUM.
Otherwise, INVALID_ENUM error is generated.
The subset of accessible pixels that are rasterized are within a bounding
box (expected to be reasonably tight) surrounding all the samples guaranteed
to be rasterized by CoverFillPathCHROMIUM. The bounding box must be
orthogonally aligned to the path space coordinate system. (The area of the
bounding box in path space is guaranteed to be greater than or equal the
area of the convex hull in path space.) Each rasterized sample will be
rasterized once and exactly once.
While samples with a net stencil change /must/ be rasterized,
implementations are explicitly allowed to vary in the rasterization
of samples for which StencilFillPathCHROMIUM would /not/ change sample's
net stencil value. This means implementations are allowed to (and,
in fact, are expected to) conservatively "exceed" the region strictly
stenciled by the path object.
CoverFillPathCHROMIUM /requires/ the following rasterization invariance:
calling CoverFillPathCHROMIUM for the same (unchanged) path object with
fixed (unchanged) modelview, projection, and viewport transform state
with the same (unchanged) set of accessible samples will rasterize
the exact same set of samples with identical interpolated values
for respective fragment/sample locations.
void CoverStrokePathCHROMIUM(uint path, enum coverMode)
The command operates in the same manner as CoverFillPathCHROMIUM except the
region guaranteed to be rasterized is, rather than the region within
/path/'s filled outline, instead the region within the /path/'s stroked
region as determined by StencilStrokePathCHROMIUM. During this
rasterization, the stencil test operates normally and as configured; the
expectation is the stencil test will be used to discard samples not
determined "covered" by a prior StencilStrokePathCHROMIUM command.
If /path/ does not name an existing path object, the command does
nothing (and no error is generated).
/coverMode/ must be one of CONVEX_HULL_CHROMIUM or BOUNDING_BOX_CHROMIUM.
Otherwise, INVALID_ENUM error is generated.
Analogous to the rasterization guarantee of CoverFillPathCHROMIUM with
respect to StencilFillPathCHROMIUM, CoverStrokePathCHROMIUM guarantees that
all samples rasterized by StencilStrokePathCHROMIUM, given the same
transforms and accessible pixels and stroke width, will also be rasterized
by the corresponding CoverStrokePathCHROMIUM.
CoverStrokePathCHROMIUM /requires/ the following rasterization invariance:
calling CoverStrokePathCHROMIUM for the same (unchanged) path object with
fixed (unchanged) modelview, projection, and viewport transform state and
with the same (unchanged) set of accessible samples will rasterize the exact
same set of samples with identical interpolated values for respective
fragment/sample locations.
void StencilThenCoverFillPathCHROMIUM(uint path, enum fillMode, uint mask, enum coverMode)
The command is equivalent to the two commands
StencilFillPathCHROMIUM(path, fillMode, mask);
CoverFillPathCHROMIUM(path, coverMode);
unless either command would generate an error; for any such error
other than OUT_OF_MEMORY, only that error is generated.
void StencilThenCoverStrokePathCHROMIUM(uint path, int reference, uint mask, enum coverMode)
The command is equivalent to the two commands
StencilStrokePathCHROMIUM(path, reference, mask);
CoverStrokePathCHROMIUM(path, coverMode);
unless either command would generate an error; for any such error
other than OUT_OF_MEMORY, only that error is generated.
void StencilFillPathInstancedCHROMIUM(sizei numPaths,
enum pathNameType,
const void *paths,
uint pathBase,
enum fillMode, uint mask,
enum transformType,
const float *transformValues);
The command stencils a sequence of filled paths.
The /numPaths/ has to be >= 0. Otherwise INVALID_VALUE error is
generated.
The /numPaths/ has to fit in 32-bit uint. Otherwise
INVALID_OPERATION is generated.
The /pathNameType/ determines the type of elements of the /paths/
array and must be one of UNSIGNED_BYTE, BYTE, UNSIGNED_SHORT, SHORT,
UNSIGNED_INT or INT. Otherwise INVALID_ENUM error is generated.
The /pathBase/ is an offset added to the /numPaths/ path names read
from the /paths/ array. Each result is 2's complement integer and it
is cast to uint path name..
The /transformType/ must be one of NONE, TRANSLATE_X_CHROMIUM,
TRANSLATE_Y_CHROMIUM, TRANSLATE_2D_CHROMIUM, TRANSLATE_3D_CHROMIUM,
AFFINE_2D_CHROMIUM, AFFINE_3D_CHROMIUM, TRANSPOSE_AFFINE_2D_CHROMIUM, or
TRANSPOSE_AFFINE_3D_CHROMIUM. Otherwise INVALID_ENUM error is generated.
The /fillMode/ and /mask/ are validated identically to the same-named
parameters of StencilFillPathCHROMIUM.
The /numPaths/ * (size of /pathNameType/ data type) + /numPaths/ *
(size of float) * (component count of /transformType/) must fit to
32-bit uint. Otherwise INVALID_OPERATION is generated.
The StencilFillPathInstancedCHROMIUM command is equivalent to:
float dm[16];
GetFloatv(PATH_MODELVIEW_MATRIX, dm);
const float *v = transformValues;
for (int i = 0; i<numPaths; i++) {
if (!applyPathTransform(dm, transformType, &v)) {
return;
}
uint pathName;
if (!getPathName(pathNameType, &paths, pathBase, &pathName)) {
return;
}
if (IsPathCHROMIUM(pathName)) {
StencilFillPathCHROMIUM(pathName, fillMode, mask);
}
}
glMatrixLoadfCHROMIUM(PATH_MODELVIEW_CHROMIUM, dm);
assuming these helper functions for applyPathTransform and
getPathName:
bool applyPathTransform(const float dm[], enum transformType, const float** v)
{
float m[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
switch (transformType) {
case NONE:
break;
case TRANSLATE_X_CHROMIUM:
m[12] = (*v)[0];
*v += 1;
break;
case TRANSLATE_Y_CHROMIUM:
m[13] = (*v)[0];
*v += 1;
break;
case TRANSLATE_2D_CHROMIUM:
m[12] = (*v)[0];
m[13] = (*v)[1];
*v += 2;
break;
case TRANSLATE_3D_CHROMIUM:
m[12] = (*v)[0];
m[13] = (*v)[1];
m[14] = (*v)[2];
*v += 3;
break;
case AFFINE_2D_CHROMIUM:
m[0] =(*v)[0]; m[4] =(*v)[2]; m[8] =0; m[12]=(*v)[4];
m[1] =(*v)[1]; m[5] =(*v)[3]; m[9] =0; m[13]=(*v)[5];
m[2] =0 ; m[6] =0; m[10]=1; m[14]=0;
m[3] =0; m[7] =0; m[11]=0; m[15]=1;
*v += 6;
break;
case TRANSPOSE_AFFINE_2D_CHROMIUM:
m[0] =(*v)[0]; m[4] =(*v)[1]; m[8] =0; m[12]=(*v)[2];
m[1] =(*v)[3]; m[5] =(*v)[4]; m[9] =0; m[13]=(*v)[5];
m[2] =0; m[6] =0; m[10]=1; m[14]=0;
m[3] =0; m[7] =0; m[11]=0; m[15]=1;
*v += 6;
break;
case AFFINE_3D_CHROMIUM:
m[0] =(*v)[0]; m[4] =(*v)[3]; m[8] =(*v)[6]; m[12]=(*v)[9];
m[1] =(*v)[1]; m[5] =(*v)[4]; m[9] =(*v)[7]; m[13]=(*v)[10];
m[2] =(*v)[2]; m[6] =(*v)[5]; m[10]=(*v)[8]; m[14]=(*v)[11];
m[3] =0; m[7] =0; m[11]=1; m[15]=0;
*v += 12;
break;
case TRANSPOSE_AFFINE_3D_CHROMIUM:
m[0] =(*v)[0]; m[4] =(*v)[1]; m[8] =(*v)[2]; m[12]=(*v)[3];
m[1] =(*v)[4]; m[5] =(*v)[5]; m[9] =(*v)[6]; m[13]=(*v)[7];
m[2] =(*v)[8]; m[6] =(*v)[9]; m[10]=(*v)[10]; m[14]=(*v)[11];
m[3] =0; m[7] =0; m[11]=1; m[15]=0;
*v += 12;
break;
default:
setError(INVALID_ENUM);
return FALSE;
}
multiplyMatrix(dm, m, m); // Multiplies dm and m and stores result to m.
glMatrixLoadfCHROMIUM(PATH_MODELVIEW_CHROMIUM, m);
return TRUE;
}
bool getPathName(enum pathNameType, const void** paths,
uint pathBase, uint* pathName)
{
switch (pathNameType) {
case BYTE:
{
const byte *p = (const byte*)*paths;
*pathName = pathBase + p[0];
*paths = p+1;
break;
}
case UNSIGNED_BYTE:
{
const ubyte *p = (const ubyte*)*paths;
*pathName = pathBase + p[0];
*paths = p+1;
break;
}
case SHORT:
{
const short *p = (const short*)*paths;
*pathName = pathBase + p[0];
*paths = p+1;
break;
}
case UNSIGNED_SHORT:
{
const ushort *p = (const ushort*)*paths;
*pathName = pathBase + p[0];
*paths = p+1;
break;
}
case INT:
{
const int *p = (const int*)*paths;
*pathName = pathBase + p[0];
*paths = p+1;
break;
}
case UNSIGNED_INT:
{
const uint *p = (const uint*)*paths;
*pathName = pathBase + p[0];
*paths = p+1;
break;
}
default:
setError(INVALID_ENUM);
return FALSE;
}
return TRUE;
}
void StencilStrokePathInstancedCHROMIUM(sizei numPaths,
enum pathNameType,
const void *paths,
uint pathBase,
int reference, uint mask,
enum transformType,
const float *transformValues);
The command stencils a sequence of stroked paths.
The command verifies /numPaths/, /pathNameType/ and
/transformType/ similarly to StencilFillPathInstancedCHROMIUM.
The command is equivalent to:
float dm[16];
GetFloatv(PATH_MODELVIEW_MATRIX, dm);
const float *v = transformValues;
for (int i = 0; i<numPaths; i++) {
if (!applyPathTransform(dm, transformType, &v)) {
return;
}
uint pathName;
if (!getPathName(pathNameType, &paths, pathBase, &pathName)) {
return;
}
if (IsPathCHROMIUM(pathName)) {
StencilStrokePathCHROMIUM(pathName, reference, mask);
}
}
glMatrixLoadfCHROMIUM(PATH_MODELVIEW_CHROMIUM, dm);
assume the helper functions for applyPathTransform and
getPathName defined above.
void CoverFillPathInstancedCHROMIUM(sizei numPaths,
enum pathNameType,
const void *paths,
uint pathBase,
enum coverMode,
enum transformType,
const float *transformValues);
The command covers a sequence of filled paths.
The command verifies /numPaths/, /pathNameType/ and
/transformType/ similarly to StencilFillPathInstancedCHROMIUM.
The command is equivalent to:
if (coverMode == BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM) {
renderBoundingBox(FALSE,
numPaths,
pathNameType,
paths,
pathBase,
transformType, transformValues);
} else if (coverMode == CONVEX_HULL_CHROMIUM || coverMode == BOUNDING_BOX_CHROMIUM) {
float dm[16];
GetFloatv(PATH_MODELVIEW_MATRIX, dm);
const float *v = transformValues;
for (int i = 0; i<numPaths; i++) {
if (!applyPathTransform(dm, transformType, &v)) {
return;
}
uint pathName;
if (!getPathName(pathNameType, &paths, pathBase, &pathName)) {
return;
}
if (IsPathCHROMIUM(pathName)) {
CoverFillPathCHROMIUM(pathName, coverMode);
}
}
glMatrixLoadfCHROMIUM(PATH_MODELVIEW_CHROMIUM, dm);
} else {
setError(INVALID_ENUM);
}
assuming these helper functions for applyPathTransform and
getPathName defined above as well as:
void renderBoundingBox(bool shouldRenderStroke,
sizei numPaths,
enum pathNameType,
const uint *paths,
uint pathBase,
enum transformType,
const float *transformValues)
{
boolean hasBounds = FALSE;
float boundsUnion[4], bounds[4];
const float *v = transformValues;
for (int i = 0; i<numPaths; i++) {
uint pathName;
if (!getPathName(pathNameType, paths, pathBase, &pathName)) {
return;
}
if (IsPathCHROMIUM(pathName)) {
GetPathBoundingBox(pathName, shouldRenderStroke, bounds);
switch (transformType) {
case NONE:
break;
case TRANSLATE_X_CHROMIUM:
bounds[0] += v[0];
bounds[2] += v[0];
v += 1;
break;
case TRANSLATE_Y_CHROMIUM:
bounds[1] += v[0];
bounds[3] += v[0];
v += 1;
break;
case TRANSLATE_2D_CHROMIUM:
bounds[0] += v[0];
bounds[1] += v[1];
bounds[2] += v[0];
bounds[3] += v[1];
v += 2;
break;
case TRANSLATE_3D_CHROMIUM: // ignores v[2]
bounds[0] += v[0];
bounds[1] += v[1];
bounds[2] += v[0];
bounds[3] += v[1];
v += 3;
break;
case AFFINE_2D_CHROMIUM:
bounds[0] = bounds[0]*v[0] + bounds[0]*v[2] + v[4];
bounds[1] = bounds[1]*v[1] + bounds[1]*v[3] + v[5];
bounds[2] = bounds[2]*v[0] + bounds[2]*v[2] + v[4];
bounds[3] = bounds[3]*v[1] + bounds[3]*v[3] + v[5];
v += 6;
break;
case TRANSPOSE_AFFINE_2D_CHROMIUM:
bounds[0] = bounds[0]*v[0] + bounds[0]*v[1] + v[2];
bounds[1] = bounds[1]*v[3] + bounds[1]*v[4] + v[5];
bounds[2] = bounds[2]*v[0] + bounds[2]*v[1] + v[2];
bounds[3] = bounds[3]*v[3] + bounds[3]*v[4] + v[5];
v += 6;
break;
case AFFINE_3D_CHROMIUM: // ignores v[2], v[5], v[6..8], v[11]
bounds[0] = bounds[0]*v[0] + bounds[0]*v[3] + v[9];
bounds[1] = bounds[1]*v[1] + bounds[1]*v[4] + v[10];
bounds[2] = bounds[2]*v[0] + bounds[2]*v[3] + v[9];
bounds[3] = bounds[3]*v[1] + bounds[3]*v[4] + v[10];
v += 12;
break;
case TRANSPOSE_AFFINE_3D_CHROMIUM: // ignores v[2], v[6], v[8..11]
bounds[0] = bounds[0]*v[0] + bounds[0]*v[1] + v[3];
bounds[1] = bounds[1]*v[4] + bounds[1]*v[5] + v[7];
bounds[2] = bounds[2]*v[0] + bounds[2]*v[1] + v[3];
bounds[3] = bounds[3]*v[4] + bounds[3]*v[5] + v[7];
v += 12;
break;
default:
setError(INVALID_ENUM);
return;
}
if (bounds[0] > bounds[2]) {
float t = bounds[2];
bounds[2] = bounds[0];
bounds[0] = t;
}
if (bounds[1] > bounds[3]) {
float t = bounds[3];
bounds[3] = bounds[1];
bounds[1] = t;
}
if (hasBounds) {
if (bounds[0] < boundsUnion[0]) {
boundsUnion[0] = bounds[0];
}
if (bounds[1] < boundsUnion[1]) {
boundsUnion[1] = bounds[1];
}
if (bounds[2] > boundsUnion[2]) {
boundsUnion[2] = bounds[2];
}
if (bounds[3] > boundsUnion[3]) {
boundsUnion[3] = bounds[3];
}
} else {
for (int i=0; i<4; i++) {
boundsUnion[i] = bounds[i];
}
hasBounds = TRUE;
}
}
}
if (hasBounds) {
Rectf(boundsUnion[0], boundsUnion[1], boundsUnion[2], boundsUnion[3]);
}
}
Where helper GetPathBoundingBox returns bounding box for the path with or without
stroking, and Rectf renders a rectangle.
/coverMode/ must be one of CONVEX_HULL_CHROMIUM or BOUNDING_BOX_CHROMIUM or
BOUNDING_BOX_OF_BOUNDING_BOXES. Otherwise, INVALID_ENUM error is generated.
void CoverStrokePathInstancedCHROMIUM(sizei numPaths,
enum pathNameType,
const void *paths,
uint pathBase,
enum coverMode,
enum transformType,
const float *transformValues);
The command covers a sequence of stroked paths.
The command verifies /numPaths/, /pathNameType/ and
/transformType/ similarly to StencilFillPathInstancedCHROMIUM.
The command is equivalent to:
if (coverage == BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM) {
renderBoundingBox(TRUE,
numPaths,
pathNameType, paths,
pathBase,
transformType, transformValues);
} else if (coverMode == CONVEX_HULL_CHROMIUM || coverMode == BOUNDING_BOX_CHROMIUM) {
float dm[16];
GetFloatv(PATH_MODELVIEW_MATRIX, dm);
const float *v = transformValues;
for (int i = 0; i<numPaths; i++) {
if (!applyPathTransform(dm, transformType, &v)) {
return;
}
uint pathName;
if (!getPathName(pathNameType, &paths, pathBase, &pathName)) {
return;
}
if (IsPathCHROMIUM(pathName)) {
CoverStrokePathCHROMIUM(pathName, coverMode);
}
}
glMatrixLoadfCHROMIUM(PATH_MODELVIEW_CHROMIUM, dm);
} else {
setError(INVALID_ENUM);
}
assuming these helper functions defined above.
/coverMode/ must be one of CONVEX_HULL_CHROMIUM or BOUNDING_BOX_CHROMIUM or
BOUNDING_BOX_OF_BOUNDING_BOXES. Otherwise, INVALID_ENUM error is generated.
void StencilThenCoverFillPathInstancedCHROMIUM(sizei numPaths,
enum pathNameType,
const void *paths,
uint pathBase,
enum coverMode,
enum fillMode,
uint mask,
enum transformType,
const float *transformValues);
The command is equivalent to the two commands
StencilFillPathInstancedCHROMIUM(numPaths
paths,
pathBase,
fillMode,
mask,
transformType,
transformValues);
CoverFillPathInstancedCHROMIUM(numPaths,
paths,
pathBase,
coverMode,
fillMode,
mask,
transformType,
transformValues);
unless either command would generate an error; for any such error
other than OUT_OF_MEMORY, only that error is generated.
void StencilThenCoverStrokePathInstancedCHROMIUM(sizei numPaths,
enum pathNameType,
const void *paths,
uint pathBase,
enum coverMode,
int reference,
uint mask,
enum transformType,
const float *transformValues);
The command is equivalent to the two commands
StencilStrokePathInstancedCHROMIUM(numPaths,
pathNameType,
paths,
pathBase,
reference,
mask,
transformType,
transformValues);
CoverStrokePathInstancedCHROMIUM(numPaths,
pathNameType,
paths,
pathBase,
coverMode,
transformType,
transformValues);
unless either command would generate an error; for any such error
other than OUT_OF_MEMORY, only that error is generated.
void BindFragmentInputLocationCHROMIUM(uint program, int location,
const char* name);
The call specifes that the fragment shader input varying named
/name/ in program /program/ should be bound to uniform location
/location/ when the program is next linked. If /name/ was bound
previously, its assigned binding is replaced with /location/. The
/name/ must be a null terminated string. The error INVALID_VALUE
is generated if /location/ is equal or greater than
MAX_VARYING_VECTORS * 4
or less than 0. BindFragmentInputLocation has no effect until the
program is linked. In particular, it doesn't modify the bindings of active
uniforms variables in a program that has already been linked.
The error INVALID_OPERATION is generated if /program/ is not name for a
program object.
The error INVALID_OPERATION is generated if name starts with the reserved
"gl_" prefix.
When a program is linked, any active uniforms without a binding specified
through BindFragmentInputLocation will be automatically be bound to
locations by the GL. Such bindings can not be queried.
BindFragmentInputLocation may be issued before any shader objects are
attached to a program object. Hence it is allowed to bind any name (except
a name starting with "gl_") to an index, including a name that is never used
as a varying in the fragment shader object. Assigned bindings for varying
variables that do not exist or are not active are ignored. Using such bindings
behaves as if passed location was -1.
It is possible for an application to bind more than one fragment
input name to the same location. This is referred to as aliasing.
This will only work if only one of the aliased fragment inputs is
active in the executable program, or if no path through the shader
consumes more than one fragment input of a set of fragment inputs
aliased to the same location. If two statically used fragment
inputs in a program are bound to the name location, link must
fail.
void ProgramPathFragmentInputGenCHROMIUM(uint program,
int location,
enum genMode,
int components,
const float *coeffs);
The command controls how a user-defined (non-built-in) fragment input of
a GLSL program object is computed for fragment shading operations that occur
as a result of CoverFillPathCHROMIUM or CoverStrokePathCHROMIUM.
/program/ names a GLSL program object. If /program/ has not been
successfully linked, the error INVALID_OPERATION is generated.
The given fragment input generation state is loaded into the fragment
input variable location identified by /location/. This location
is a value bound with BindFragmentInputLocation.
If the value of location is -1, the ProgramPathFragmentInputGenCHROMIUM
command will silently ignore the command, and the program's path fragment
input generation state will not be changed.
If any of the following conditions occur, an INVALID_OPERATION error is
generated by the ProgramPathFragmentInputGenCHROMIUM, and no state is
changed:
* if the size indicated in the /components/ of the
ProgramPathFragmentInputGenCHROMIUM command used does not match the
size of the fragment input scalar or vector declared in the
shader,
* if the fragment input declared in the shader is not
single-precision floating-point scalar or vector, or
* if no fragment input variable with a location of /location/
exists in the program object named by /program/ and location
is not -1, or
* if the fragment input declared in the shader is a built-in
variables (i.e. prefixed by "gl_").
When covering paths, fragment input variables are interpolated at
each shaded fragment based on the corresponding fragment input
generation state specified by ProgramPathFragmentInputGenCHROMIUM for
each respective fragment input.
The /genMode/, /components/, and /coeffs/ parameters are used to
generate the fragment input variable values. This is described in
subsection FRAGMENT INPUT GENERATION FOR PATH COVER COMMANDS.
When covering paths, if a fragment input variable has not had its
path fragment input generation state successfully generated, it as
if the values of this variable are always initialized to zero when
the fragment shader is executing.
FRAGMENT INPUT GENERATION FOR PATH COVER COMMANDS
The /genMode/, /components/, and /coeffs/ parameters of
ProgramPathFragmentInputGenCHROMIUM control how fragment inputs are computed
for fragment shading operations that occur as a result of
CoverFillPathCHROMIUM and CoverStrokePathCHROMIUM and their StencilThenCover
and instanced variants.
/genMode/ must be one of NONE, OBJECT_LINEAR_CHROMIUM, EYE_LINEAR_CHROMIUM
or CONSTANT_CHROMIUM; otherwise INVALID_ENUM is generated.
NONE means that the fragment input is not generated. OBJECT_LINEAR_CHROMIUM
means that the specified input is generated from a linear combination of the
2D path coordinates (x,y). EYE_LINEAR_CHROMIUM means the specified input is
generated from a linear combination of path's 2D coordinates transformed in
eye space, with (xe, ye, ze, we) calculated as in section 2.12
("Fixed-Function Vertex Transformation") of OpenGL 3.2 (unabridged)
Specification (Special Functions). CONSTANT_CHROMIUM means that the
specified input is set to corresponding constant value.
/components/ must be 0 if /genMode/ is NONE or for other allowed /genMode/
values must be one of 1, 2, 3, or 4; otherwise INVALID_VALUE is generated.
/components/ determines how many fragment input components, how many
coefficients read from the /coeffs/ array, and the linear equations used to
generate the s, t, r, and q coordinates of the fragment input specified by
/location/.
In the following equations, coeffs[i] is the /i/th element (base zero) of
the /coeffs/ array; x, y, z, and w are determined by the /genMode/.
When /genMode/ is EYE_LINEAR_CHROMIUM, xcoeffs[i] is the /i/th element (base
zero) of a /xcoeffs/ array generated by multiplying each respective vector
of four elements of coeffs by the current inverse modelview matrix when
ProgramPathFragmentInputGen is called.
xcoeffs[0..3] = coeffs[0..3] * MV^-1
xcoeffs[4..7] = coeffs[4..7] * MV^-1
xcoeffs[8..11] = coeffs[8..11] * MV^-1
xcoeffs[12..15] = coeffs[12..12] * MV^-1
[[ NOTATION:
xxx[0..3] is a vector form from xxx[0], xxx[1], xxx[2], and xxx[3]
MV^-1 is the inverse of the current PATH_MODELVIEW_CHROMIUM matrix when
ProgramPathFragmentInputGenCHROMIUM happens.
]]
If the /components/ is 0, no values from the /coeffs/ array are
accessed and the s, t, r, and q coordinates of a covered fragment's
fragment input for /location/ are computed:
s = 0
t = 0
r = 0
q = 0
If the /components/ is 1 and /genMode/ is OBJECT_LINEAR_CHROMIUM
3 values from the /coeffs/ array are
accessed and the s, t, r, and q coordinates of a covered fragment's
fragment input for /location/ are computed:
s = coeffs[0] * x + coeffs[1] * y + coeffs[2]
t = 0
r = 0
q = 0
Alternatively if the /genMode/ is EYE_LINEAR_CHROMIUM, then 4 values are
accessed and the fragment input for /location/ are
computed:
s = xcoeffs[0] * xe + xcoeffs[1] * ye + xcoeffs[2] * ze + xcoeffs[3] * we
t = 0
r = 0
q = 0
Alternatively if the /genMode/ is CONSTANT_CHROMIUM, then:
s = xcoeffs[0]
t = 0
r = 0
q = 0
If the /components/ is 2 and /genMode/ is OBJECT_LINEAR_CHROMIUM,
6 values from the /coeffs/ array are accessed and the
s, t, r, and q coordinates of a covered fragment's fragment input
coordinates are computed:
s = coeffs[0] * x + coeffs[1] * y + coeffs[2]
t = coeffs[3] * x + coeffs[4] * y + coeffs[5]
r = 0
q = 0
Alternatively if the /genMode/ is EYE_LINEAR_CHROMIUM, then 8 values are
accessed and the fragment input coordinates are computed:
s = xcoeffs[0] * xe + xcoeffs[1] * ye + xcoeffs[2] * ze + xcoeffs[3] * we
t = xcoeffs[4] * xe + xcoeffs[5] * ye + xcoeffs[6] * ze + xcoeffs[7] * we
r = 0
q = 0
Alternatively if the /genMode/ is CONSTANT_CHROMIUM, then:
s = xcoeffs[0]
t = xcoeffs[1]
r = 0
q = 0
If the /components/ is 3 and /genMode/ is OBJECT_LINEAR_CHROMIUM 9 values
from the /coeffs/ array are accessed and the s, t, r, and q coordinates of a
covered fragment's fragment input coordinates for /location/ are computed:
s = coeffs[0] * x + coeffs[1] * y + coeffs[2]
t = coeffs[3] * x + coeffs[4] * y + coeffs[5]
r = coeffs[6] * x + coeffs[7] * y + coeffs[8]
q = 0
Alternatively if the /genMode/ is CONSTANT_CHROMIUM, then:
s = xcoeffs[0]
t = xcoeffs[1]
r = xcoeffs[2]
q = 0
Alternatively if the /genMode/ is EYE_LINEAR_CHROMIUM, then 12 values are
accessed and the fragment input coodinates for /location/ are computed:
s = xcoeffs[0] * xe + xcoeffs[1] * ye + xcoeffs[2] * ze + xcoeffs[3] * we
t = xcoeffs[4] * xe + xcoeffs[5] * ye + xcoeffs[6] * ze + xcoeffs[7] * we
r = xcoeffs[8] * xe + xcoeffs[9] * ye + xcoeffs[10] * ze + xcoeffs[11] * we
q = 0
If the /components/ is 4 and /genMode/ is OBJECT_LINEAR_CHROMIUM,
12 values from the /coeffs/ array are accessed and the
s, t, r, and q coordinates of a covered fragment's fragment input
coordinates for /location/ are computed:
s = coeffs[0] * x + coeffs[1] * y + coeffs[2]
t = coeffs[3] * x + coeffs[4] * y + coeffs[5]
r = coeffs[6] * x + coeffs[7] * y + coeffs[8]
q = coeffs[9] * x + coeffs[10] * y + coeffs[11]
Alternatively if the /genMode/ is EYE_LINEAR_CHROMIUM, then 16 values are
accessed and the fragment input coordinates for /location/ are
computed:
s = xcoeffs[0] * xe + xcoeffs[1] * ye + xcoeffs[2] * ze + xcoeffs[3] * we
t = xcoeffs[4] * xe + xcoeffs[5] * ye + xcoeffs[6] * ze + xcoeffs[7] * we
r = xcoeffs[8] * xe + xcoeffs[9] * ye + xcoeffs[10] * ze + xcoeffs[11] * we
q = xcoeffs[12] * xe + xcoeffs[13] * ye + xcoeffs[14] * ze + xcoeffs[15] * we
Alternatively if the /genMode/ is CONSTANT_CHROMIUM, then:
s = xcoeffs[0]
t = xcoeffs[1]
r = xcoeffs[2]
q = xcoeffs[3]
The initial mode is NONE and the coefficients are all initially zero.
PATH COVERING RASTERIZATION DETAILS
The GL processes fragments rasterized by path cover commands in
much the same manner as fragments generated by conventional polygon
rasterization. However path rendering /ignores/ the following
operations:
* Interpolation of per-vertex data (section 3.6.1). Path
primitives have neither conventional vertices nor per-vertex
data. Instead fragments generate interpolated per-fragment
colors, texture coordinate sets, as a
linear function of object-space or eye-space path coordinate's
or using the current color or texture coordinate set state
directly.
Depth offset (section 3.6.2) and polygon multisample rasterization
(3.6.3) do apply to path covering.
Front and back face determination (explained in section 3.6.1 for
polygons) operates somewhat differently for transformed paths than
polygons. The path's convex hull or bounding box
(depending on the /coverMode/) is specified to wind counterclockwise
in object space, though the transformation of the convex hull into
window space could reverse this winding. Whether the GL's front face
state is CW or CCW (as set by the FrontFace command) determines
if the path is front facing or not. Because the specific vertices
that belong to the covering geometry are implementation-dependent,
when the signed area of the covering geometry (computed with equation
3.6) is sufficiently near zero, the facingness of the path in such
situations is ill-defined.
The determination of whether a path transformed into window space is
front facing or not affects face culling if enabled (section 3.6.1),
the gl_FrontFacing built-in variable (section 3.9.2), and separate
(two-sided) stencil testing (section 4.1.4).
Errors
None.
New State
Get Value Type Get Command Initial Description
----------------------------- ----- ------------ -------- -------------------
PATH_MODELVIEW_MATRIX_CHROMIUM 16xR GetFloatv all 0's Current modelview
matrix for path rendering
PATH_PROJECTION_MATRIX_CHROMIUM 16xR GetFloatv all 0's Current projection
matrix for path rendering
PATH_STENCIL_FUNC_CHROMIUM Z8 GetIntegerv ALWAYS path stenciling function
PATH_STENCIL_REF_CHROMIUM Z+ GetIntegerv 0 path stenciling
reference value
PATH_STENCIL_VALUE_MASK_CHROMIUM path stencil read
Z+ GetIntegerv 1's mask
Tables
Table 5.pathCommands: Path Commands
Coordinate
Token Description count
========================== ===================== ==========
MOVE_TO_CHROMIUM Absolute move 2
current point
-------------------------- --------------------- ----------
CLOSE_PATH_CHROMIUM Close path 0
-------------------------- --------------------- ----------
LINE_TO_CHROMIUM Absolute line 2
-------------------------- --------------------- ----------
QUADRATIC_CURVE_TO_CHROMIUM Absolute quadratic 4
-------------------------- --------------------- ----------
CUBIC_CURVE_TO_CHROMIUM Absolute cubic 6
Bezier segment
-------------------------- --------------------- ----------
CONIC_CURVE_TO_CHROMIUM Absolute conic 5
(rational Bezier)
segment
Table 5.pathParameters
Name Type Required Values or Range
------------------------------- ------- -----------------------------------------------
PATH_STROKE_WIDTH_CHROMIUM float non-negative
PATH_END_CAPS_CHROMIUM enum FLAT, SQUARE_CHROMIUM, ROUND_CHROMIUM
PATH_JOIN_STYLE_CHROMIUM enum MITER_REVERT_CHROMIUM, BEVEL_CHROMIUM, ROUND_CHROMIUM
PATH_MITER_LIMIT_CHROMIUM float non-negative
PATH_STROKE_BOUND_CHROMIUM float will be clamped to [0, 1.0], initially 0.2 (20%)
Issues
1. Should there be a distinct stencil function state for path
stenciling?
RESOLVED: YES. glPathStencilFunc sets the state. How the
stencil state needs to be configured for path covering is
different than how the stencil function is configured typically
for path stenciling.
For example, stencil covering might use
StencilFunc(NOT_EQUAL,0,~0) while path stenciling would
use ALWAYS for the path stenciling stencil test.
However there are other situations such as path clipping where it
is useful to have the path stencil function configured differently
such as PathStencilFunc(NOT_EQUAL, 0x00, 0x80) or other
similar path clipping test.
2. Since Cover*Path* skips the vertex shader, what does it mean exactly
wrt a fully linked program? What happens to the fragment shader's input
varyings that are not filled by the vertex shader + rasterizer?
It is possible that input varyings from a shader may not be written
as output varyings of a preceding shader. In this case, the unwritten
input varying values are set to constant zeros.
3. What is the defined behavior when stroking if PATH_STROKE_WIDTH is
zero?
There will not be any samples within the stroke. I.e. the stroke does
not produce any visible results.
4. How do you define a program that's valid to use with these calls.
There is no change with respect to validity of the programs. All
programs that are valid before this extension are valid after.
All programs that are invalid before this extension is invalid
after.
5. Can same programs be used to render regular GL primitives as well
as in covering paths?
Yes.
6. How is the fragment shader called when covering paths, and with
which values for the inputs?
gl_FragCoord: Interpolated coordinate of the path coverage.
gl_FrontFacing:
* Paths wind by default counterclockwise
* Window space transform can reverse this winding
* GL front face state CW/CCW selects whether the variable is true
or false
user-defined varyings: constant zeros.
Revision History
14/8/2014 Documented the extension