chromium / chromium / src / 9dfcc3526f661b1bbc9b0214d44e59624b942d03 / . / gpu / GLES2 / extensions / CHROMIUM / CHROMIUM_path_rendering.txt

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 ï¬‚oating-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 |