diff options
author | kkinnunen <kkinnunen@nvidia.com> | 2015-07-14 04:08:34 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-14 11:09:10 +0000 |
commit | b959a8467d84feb3431809fe4abafb9649c44b24 (patch) | |
tree | ef570319a26e2efb29bd1d6767a2f0ed1f3d73d0 | |
parent | a39e79ebcde16f7604bf5de6bed0c665c8afe5b0 (diff) | |
download | chromium_src-b959a8467d84feb3431809fe4abafb9649c44b24.zip chromium_src-b959a8467d84feb3431809fe4abafb9649c44b24.tar.gz chromium_src-b959a8467d84feb3431809fe4abafb9649c44b24.tar.bz2 |
command_buffer: Implement path rendering functions for CHROMIUM_path_rendering
Add support for path rendering functions with CHROMIUM_path_rendering in
gpu command buffer. CHROMIUM_path_rendering pseudo extension will use
NV_path_rendering (NVPR).
After this patch, CHROMIUM_path_rendering is able to draw solid color
paths.
Adds following functions to the command buffer:
glGenPathsCHROMIUM
glDeletePathsCHROMIUM
glIsPathCHROMIUM
glPathCommandsCHROMIUM
glPathParameterfCHROMIUM
glPathParameteriCHROMIUM
glPathStencilFuncCHROMIUM
glStencilFillPathCHROMIUM
glStencilStrokePathCHROMIUM
glCoverFillPathCHROMIUM
glCoverStrokePathCHROMIUM
glStencilThenCoverFillPathCHROMIUM
glStencilThenCoverStrokePathCHROMIUM
Noteworthy items:
NVPR has calls with multiple data arrays. These will be passed by
memcpy:ing the arrays into the same transfer buffer. The arrays
containing GLfloats are copied first, because floats have more strict
alignment needs than whatever is in the other array.
The functions exposed by the command buffer take in subset of the values
that plain NVPR functions accept. Also some functions do not take
exact same amount of parameters, rather only those parameters that
are expected to vary based on Skia implementation.
The change does not add vertexshader-less shader program support to the
command buffer. The caller is expected to use a dummy vertex
shader. NVPR calls will ignore the vertex shader.
Adds gpu::gles2::PathManager class that should be similar to other
resource manager classes. The intention is that paths can be shared in
similar manner as other resources.
Changes generator to generate feature_info check for Is -type of
functions.
Moves the path matrix related constants from glchromium.h to
gl2extchromium.h, the constants are not "normal" GLES constants, rather
they are part of the extension.
Skia will not yet use the extension, because texturing support and
instanced variants of the draw functions are not exposed by
CHROMIUM_path_rendering.
The extension will be available through flag --enable-gl-path-rendering
BUG=344330
Review URL: https://codereview.chromium.org/169403005
Cr-Commit-Position: refs/heads/master@{#338666}
67 files changed, 6775 insertions, 90 deletions
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn index dd737e7..e940614 100644 --- a/gpu/BUILD.gn +++ b/gpu/BUILD.gn @@ -202,6 +202,7 @@ test("gpu_unittests") { "command_buffer/service/memory_program_cache_unittest.cc", "command_buffer/service/mocks.cc", "command_buffer/service/mocks.h", + "command_buffer/service/path_manager_unittest.cc", "command_buffer/service/program_cache_unittest.cc", "command_buffer/service/program_manager_unittest.cc", "command_buffer/service/query_manager_unittest.cc", diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_path_rendering.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_path_rendering.txt index d2e8c93..824ee91 100644 --- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_path_rendering.txt +++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_path_rendering.txt @@ -26,11 +26,44 @@ New Tokens 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: + 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 + New Procedures and Functions @@ -47,6 +80,445 @@ New Procedures and Functions 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, 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. + + + 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. @@ -59,6 +531,102 @@ New State 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 diff --git a/gpu/GLES2/gl2chromium.h b/gpu/GLES2/gl2chromium.h index 0dc648d..42889dd 100644 --- a/gpu/GLES2/gl2chromium.h +++ b/gpu/GLES2/gl2chromium.h @@ -10,10 +10,6 @@ #include <GLES2/gl2platform.h> #define GL_CONTEXT_LOST 0x300E -#define GL_PATH_MODELVIEW_CHROMIUM 0x1700 -#define GL_PATH_PROJECTION_CHROMIUM 0x1701 -#define GL_PATH_MODELVIEW_MATRIX_CHROMIUM 0x0BA6 -#define GL_PATH_PROJECTION_MATRIX_CHROMIUM 0x0BA7 #if defined(GLES2_USE_MOJO) #define GLES2_GET_FUN(name) MojoGLES2gl ## name diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index b12dc74..ddd098d 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h @@ -333,6 +333,21 @@ #define glSwapInterval GLES2_GET_FUN(SwapInterval) #define glMatrixLoadfCHROMIUM GLES2_GET_FUN(MatrixLoadfCHROMIUM) #define glMatrixLoadIdentityCHROMIUM GLES2_GET_FUN(MatrixLoadIdentityCHROMIUM) +#define glGenPathsCHROMIUM GLES2_GET_FUN(GenPathsCHROMIUM) +#define glDeletePathsCHROMIUM GLES2_GET_FUN(DeletePathsCHROMIUM) +#define glIsPathCHROMIUM GLES2_GET_FUN(IsPathCHROMIUM) +#define glPathCommandsCHROMIUM GLES2_GET_FUN(PathCommandsCHROMIUM) +#define glPathParameterfCHROMIUM GLES2_GET_FUN(PathParameterfCHROMIUM) +#define glPathParameteriCHROMIUM GLES2_GET_FUN(PathParameteriCHROMIUM) +#define glPathStencilFuncCHROMIUM GLES2_GET_FUN(PathStencilFuncCHROMIUM) +#define glStencilFillPathCHROMIUM GLES2_GET_FUN(StencilFillPathCHROMIUM) +#define glStencilStrokePathCHROMIUM GLES2_GET_FUN(StencilStrokePathCHROMIUM) +#define glCoverFillPathCHROMIUM GLES2_GET_FUN(CoverFillPathCHROMIUM) +#define glCoverStrokePathCHROMIUM GLES2_GET_FUN(CoverStrokePathCHROMIUM) +#define glStencilThenCoverFillPathCHROMIUM \ + GLES2_GET_FUN(StencilThenCoverFillPathCHROMIUM) +#define glStencilThenCoverStrokePathCHROMIUM \ + GLES2_GET_FUN(StencilThenCoverStrokePathCHROMIUM) #define glGetGraphicsResetStatusKHR GLES2_GET_FUN(GetGraphicsResetStatusKHR) #define glBlendBarrierKHR GLES2_GET_FUN(BlendBarrierKHR) diff --git a/gpu/GLES2/gl2extchromium.h b/gpu/GLES2/gl2extchromium.h index 038a303..c3b10eb 100644 --- a/gpu/GLES2/gl2extchromium.h +++ b/gpu/GLES2/gl2extchromium.h @@ -795,12 +795,172 @@ typedef void(GL_APIENTRYP PFNGLSCHEDULEOVERLAYPLANECHROMIUMPROC)( GL_APICALL void GL_APIENTRY glMatrixLoadfCHROMIUM(GLenum mode, const GLfloat* m); GL_APICALL void GL_APIENTRY glMatrixLoadIdentityCHROMIUM(GLenum mode); +GL_APICALL GLuint GL_APIENTRY glGenPathsCHROMIUM(GLsizei range); +GL_APICALL void GL_APIENTRY glDeletePathsCHROMIUM(GLuint path, GLsizei range); +GL_APICALL GLboolean GL_APIENTRY glIsPathCHROMIUM(GLuint path); +GL_APICALL void GL_APIENTRY glPathCommandsCHROMIUM(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const void* coords); +GL_APICALL void GL_APIENTRY +glPathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY +glPathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat value); +GL_APICALL void GL_APIENTRY +glPathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY +glStencilFillPathCHROMIUM(GLuint path, GLenum fillMode, GLuint mask); +GL_APICALL void GL_APIENTRY +glStencilStrokePathCHROMIUM(GLuint path, GLint reference, GLuint mask); +GL_APICALL void GL_APIENTRY +glCoverFillPathCHROMIUM(GLuint path, GLenum coverMode); +GL_APICALL void GL_APIENTRY +glCoverStrokePathCHROMIUM(GLuint name, GLenum coverMode); +GL_APICALL void GL_APIENTRY +glStencilThenCoverFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode); +GL_APICALL void GL_APIENTRY +glStencilThenCoverStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode); + #endif typedef void(GL_APIENTRYP PFNGLMATRIXLOADFCHROMIUMPROC)(GLenum matrixMode, const GLfloat* m); typedef void(GL_APIENTRYP PFNGLMATRIXLOADIDENTITYCHROMIUMPROC)( GLenum matrixMode); +typedef GLuint(GL_APIENTRYP* PFNGLGENPATHSCHROMIUMPROC)(GLsizei range); +typedef void(GL_APIENTRYP* PFNGLDELETEPATHSCHROMIUMPROC)(GLuint path, + GLsizei range); +typedef GLboolean(GL_APIENTRYP* PFNGLISPATHCHROMIUMPROC)(GLuint path); +typedef void(GL_APIENTRYP* PFNGLPATHCOMMANDSCHROMIUMPROC)( + GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords); +typedef void(GL_APIENTRYP* PFNGLPATHPARAMETERICHROMIUMPROC)(GLuint path, + GLenum pname, + GLint value); +typedef void(GL_APIENTRYP* PFNGLPATHPARAMETERFCHROMIUMPROC)(GLuint path, + GLenum pname, + GLfloat value); +typedef void(GL_APIENTRYP* PFNGLPATHSTENCILFUNCCHROMIUMPROC)(GLenum func, + GLint ref, + GLuint mask); +typedef void(GL_APIENTRYP* PFNGLSTENCILFILLPATHCHROMIUMPROC)(GLuint path, + GLenum fillMode, + GLuint mask); +typedef void(GL_APIENTRYP* PFNGLSTENCILSTROKEPATHCHROMIUMPROC)(GLuint path, + GLint reference, + GLuint mask); +typedef void(GL_APIENTRYP* PFNGLCOVERFILLPATHCHROMIUMPROC)(GLuint path, + GLenum coverMode); +typedef void(GL_APIENTRYP* PFNGLCOVERSTROKEPATHCHROMIUMPROC)(GLuint name, + GLenum coverMode); + +typedef void(GL_APIENTRYP* PFNGLSTENCILTHENCOVERFILLPATHCHROMIUMPROC)( + GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode); +typedef void(GL_APIENTRYP* PFNGLSTENCILTHENCOVERSTROKEPATHCHROMIUMPROC)( + GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode); + +#ifndef GL_CLOSE_PATH_CHROMIUM +#define GL_CLOSE_PATH_CHROMIUM 0x00 +#endif +#ifndef GL_MOVE_TO_CHROMIUM +#define GL_MOVE_TO_CHROMIUM 0x02 +#endif +#ifndef GL_LINE_TO_CHROMIUM +#define GL_LINE_TO_CHROMIUM 0x04 +#endif +#ifndef GL_QUADRATIC_CURVE_TO_CHROMIUM +#define GL_QUADRATIC_CURVE_TO_CHROMIUM 0x0A +#endif +#ifndef GL_CUBIC_CURVE_TO_CHROMIUM +#define GL_CUBIC_CURVE_TO_CHROMIUM 0x0C +#endif +#ifndef GL_CONIC_CURVE_TO_CHROMIUM +#define GL_CONIC_CURVE_TO_CHROMIUM 0x1A +#endif +#ifndef GL_PATH_MODELVIEW_MATRIX_CHROMIUM +#define GL_PATH_MODELVIEW_MATRIX_CHROMIUM 0x0BA6 +#endif +#ifndef GL_PATH_PROJECTION_MATRIX_CHROMIUM +#define GL_PATH_PROJECTION_MATRIX_CHROMIUM 0x0BA7 +#endif +#ifndef GL_PATH_MODELVIEW_CHROMIUM +#define GL_PATH_MODELVIEW_CHROMIUM 0x1700 +#endif +#ifndef GL_PATH_PROJECTION_CHROMIUM +#define GL_PATH_PROJECTION_CHROMIUM 0x1701 +#endif +#ifndef GL_FLAT_CHROMIUM +#define GL_FLAT_CHROMIUM 0x1D00 +#endif +#ifndef GL_PATH_STROKE_WIDTH_CHROMIUM +#define GL_PATH_STROKE_WIDTH_CHROMIUM 0x9075 +#endif +#ifndef GL_PATH_END_CAPS_CHROMIUM +#define GL_PATH_END_CAPS_CHROMIUM 0x9076 +#endif +#ifndef GL_PATH_JOIN_STYLE_CHROMIUM +#define GL_PATH_JOIN_STYLE_CHROMIUM 0x9079 +#endif +#ifndef GL_PATH_MITER_LIMIT_CHROMIUM +#define GL_PATH_MITER_LIMIT_CHROMIUM 0x907a +#endif +#ifndef GL_PATH_STROKE_BOUND_CHROMIUM +#define GL_PATH_STROKE_BOUND_CHROMIUM 0x9086 +#endif +#ifndef GL_COUNT_UP_CHROMIUM +#define GL_COUNT_UP_CHROMIUM 0x9088 +#endif +#ifndef GL_COUNT_DOWN_CHROMIUM +#define GL_COUNT_DOWN_CHROMIUM 0x9089 +#endif +#ifndef GL_CONVEX_HULL_CHROMIUM +#define GL_CONVEX_HULL_CHROMIUM 0x908B +#endif +#ifndef GL_BOUNDING_BOX_CHROMIUM +#define GL_BOUNDING_BOX_CHROMIUM 0x908D +#endif +#ifndef GL_SQUARE_CHROMIUM +#define GL_SQUARE_CHROMIUM 0x90a3 +#endif +#ifndef GL_ROUND_CHROMIUM +#define GL_ROUND_CHROMIUM 0x90a4 +#endif +#ifndef GL_ROUND_CHROMIUM +#define GL_ROUND_CHROMIUM 0x90A4 +#endif +#ifndef GL_BEVEL_CHROMIUM +#define GL_BEVEL_CHROMIUM 0x90A6 +#endif +#ifndef GL_MITER_REVERT_CHROMIUM +#define GL_MITER_REVERT_CHROMIUM 0x90A7 +#endif +#ifndef GL_PATH_STENCIL_FUNC_CHROMIUM +#define GL_PATH_STENCIL_FUNC_CHROMIUM 0x90B7 +#endif +#ifndef GL_PATH_STENCIL_REF_CHROMIUM +#define GL_PATH_STENCIL_REF_CHROMIUM 0x90B8 +#endif +#ifndef GL_PATH_STENCIL_VALUE_MASK_CHROMIUM +#define GL_PATH_STENCIL_VALUE_MASK_CHROMIUM 0x90B9 +#endif #endif /* GL_CHROMIUM_path_rendering */ diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index dd6a050..09cdc7b 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -540,6 +540,31 @@ _STATES = { }, ], }, + 'PathStencilFuncCHROMIUM': { + 'type': 'Normal', + 'func': 'PathStencilFuncNV', + 'extension_flag': 'chromium_path_rendering', + 'states': [ + { + 'name': 'stencil_path_func', + 'type': 'GLenum', + 'enum': 'GL_PATH_STENCIL_FUNC_CHROMIUM', + 'default': 'GL_ALWAYS', + }, + { + 'name': 'stencil_path_ref', + 'type': 'GLint', + 'enum': 'GL_PATH_STENCIL_REF_CHROMIUM', + 'default': '0', + }, + { + 'name': 'stencil_path_mask', + 'type': 'GLuint', + 'enum': 'GL_PATH_STENCIL_VALUE_MASK_CHROMIUM', + 'default': '0xFFFFFFFFU', + }, + ], + }, } # Named type info object represents a named type that is used in OpenGL call @@ -1479,6 +1504,57 @@ _NAMED_TYPE_INFO = { 'GL_UNSIGNED_BYTE_3_3_2', ], }, + 'PathCoordType': { + 'type': 'GLenum', + 'valid': [ + 'GL_BYTE', + 'GL_UNSIGNED_BYTE', + 'GL_SHORT', + 'GL_UNSIGNED_SHORT', + 'GL_FLOAT', + ], + }, + 'PathCoverMode': { + 'type': 'GLenum', + 'valid': [ + 'GL_CONVEX_HULL_CHROMIUM', + 'GL_BOUNDING_BOX_CHROMIUM', + ], + }, + 'PathFillMode': { + 'type': 'GLenum', + 'valid': [ + 'GL_INVERT', + 'GL_COUNT_UP_CHROMIUM', + 'GL_COUNT_DOWN_CHROMIUM', + ], + }, + 'PathParameter': { + 'type': 'GLenum', + 'valid': [ + 'GL_PATH_STROKE_WIDTH_CHROMIUM', + 'GL_PATH_END_CAPS_CHROMIUM', + 'GL_PATH_JOIN_STYLE_CHROMIUM', + 'GL_PATH_MITER_LIMIT_CHROMIUM', + 'GL_PATH_STROKE_BOUND_CHROMIUM', + ] + }, + 'PathParameterCapValues': { + 'type': 'GLint', + 'valid': [ + 'GL_FLAT', + 'GL_SQUARE_CHROMIUM', + 'GL_ROUND_CHROMIUM', + ] + }, + 'PathParameterJoinValues': { + 'type': 'GLint', + 'valid': [ + 'GL_MITER_REVERT_CHROMIUM', + 'GL_BEVEL_CHROMIUM', + 'GL_ROUND_CHROMIUM', + ] + }, 'ReadPixelType': { 'type': 'GLenum', 'valid': [ @@ -3969,6 +4045,94 @@ _FUNCTION_INFO = { 'extension': True, 'extension_flag': 'chromium_path_rendering', }, + 'GenPathsCHROMIUM': { + 'type': 'Custom', + 'cmd_args': 'GLuint first_client_id, GLsizei range', + 'chromium': True, + 'extension': True, + 'extension_flag': 'chromium_path_rendering', + }, + 'DeletePathsCHROMIUM': { + 'type': 'Custom', + 'cmd_args': 'GLuint first_client_id, GLsizei range', + 'impl_func': False, + 'unit_test': False, + 'chromium': True, + 'extension': True, + 'extension_flag': 'chromium_path_rendering', + }, + 'IsPathCHROMIUM': { + 'type': 'Is', + 'decoder_func': 'DoIsPathCHROMIUM', + 'gl_test_func': 'glIsPathNV', + 'chromium': True, + 'extension': True, + 'extension_flag': 'chromium_path_rendering', + }, + 'PathCommandsCHROMIUM': { + 'type': 'Manual', + 'immediate': False, + 'chromium': True, + 'extension': True, + 'extension_flag': 'chromium_path_rendering', + }, + 'PathParameterfCHROMIUM': { + 'type': 'Custom', + 'chromium': True, + 'extension': True, + 'extension_flag': 'chromium_path_rendering', + }, + 'PathParameteriCHROMIUM': { + 'type': 'Custom', + 'chromium': True, + 'extension': True, + 'extension_flag': 'chromium_path_rendering', + }, + 'PathStencilFuncCHROMIUM': { + 'type': 'StateSet', + 'state': 'PathStencilFuncCHROMIUM', + 'decoder_func': 'glPathStencilFuncNV', + 'chromium': True, + 'extension': True, + 'extension_flag': 'chromium_path_rendering', + }, + 'StencilFillPathCHROMIUM': { + 'type': 'Custom', + 'chromium': True, + 'extension': True, + 'extension_flag': 'chromium_path_rendering', + }, + 'StencilStrokePathCHROMIUM': { + 'type': 'Custom', + 'chromium': True, + 'extension': True, + 'extension_flag': 'chromium_path_rendering', + }, + 'CoverFillPathCHROMIUM': { + 'type': 'Custom', + 'chromium': True, + 'extension': True, + 'extension_flag': 'chromium_path_rendering', + }, + 'CoverStrokePathCHROMIUM': { + 'type': 'Custom', + 'chromium': True, + 'extension': True, + 'extension_flag': 'chromium_path_rendering', + }, + 'StencilThenCoverFillPathCHROMIUM': { + 'type': 'Custom', + 'chromium': True, + 'extension': True, + 'extension_flag': 'chromium_path_rendering', + }, + 'StencilThenCoverStrokePathCHROMIUM': { + 'type': 'Custom', + 'chromium': True, + 'extension': True, + 'extension_flag': 'chromium_path_rendering', + }, + } @@ -7939,6 +8103,7 @@ TEST_P(%(test_name)s, %(name)sInvalidArgsBadSharedMemoryId) { def WriteServiceImplementation(self, func, file): """Overrriden from TypeHandler.""" self.WriteServiceHandlerFunctionHeader(func, file) + self.WriteHandlerExtensionCheck(func, file) args = func.GetOriginalArgs() for arg in args: arg.WriteGetCode(file) diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 4f96672a..4e304c1 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -1410,6 +1410,59 @@ void GLES2MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) { void GLES2MatrixLoadIdentityCHROMIUM(GLenum matrixMode) { gles2::GetGLContext()->MatrixLoadIdentityCHROMIUM(matrixMode); } +GLuint GLES2GenPathsCHROMIUM(GLsizei range) { + return gles2::GetGLContext()->GenPathsCHROMIUM(range); +} +void GLES2DeletePathsCHROMIUM(GLuint path, GLsizei range) { + gles2::GetGLContext()->DeletePathsCHROMIUM(path, range); +} +GLboolean GLES2IsPathCHROMIUM(GLuint path) { + return gles2::GetGLContext()->IsPathCHROMIUM(path); +} +void GLES2PathCommandsCHROMIUM(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords) { + gles2::GetGLContext()->PathCommandsCHROMIUM(path, numCommands, commands, + numCoords, coordType, coords); +} +void GLES2PathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat value) { + gles2::GetGLContext()->PathParameterfCHROMIUM(path, pname, value); +} +void GLES2PathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value) { + gles2::GetGLContext()->PathParameteriCHROMIUM(path, pname, value); +} +void GLES2PathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask) { + gles2::GetGLContext()->PathStencilFuncCHROMIUM(func, ref, mask); +} +void GLES2StencilFillPathCHROMIUM(GLuint path, GLenum fillMode, GLuint mask) { + gles2::GetGLContext()->StencilFillPathCHROMIUM(path, fillMode, mask); +} +void GLES2StencilStrokePathCHROMIUM(GLuint path, GLint reference, GLuint mask) { + gles2::GetGLContext()->StencilStrokePathCHROMIUM(path, reference, mask); +} +void GLES2CoverFillPathCHROMIUM(GLuint path, GLenum coverMode) { + gles2::GetGLContext()->CoverFillPathCHROMIUM(path, coverMode); +} +void GLES2CoverStrokePathCHROMIUM(GLuint path, GLenum coverMode) { + gles2::GetGLContext()->CoverStrokePathCHROMIUM(path, coverMode); +} +void GLES2StencilThenCoverFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) { + gles2::GetGLContext()->StencilThenCoverFillPathCHROMIUM(path, fillMode, mask, + coverMode); +} +void GLES2StencilThenCoverStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) { + gles2::GetGLContext()->StencilThenCoverStrokePathCHROMIUM(path, reference, + mask, coverMode); +} GLenum GLES2GetGraphicsResetStatusKHR() { return gles2::GetGLContext()->GetGraphicsResetStatusKHR(); } @@ -2648,6 +2701,59 @@ extern const NameToFunc g_gles2_function_table[] = { reinterpret_cast<GLES2FunctionPointer>(glMatrixLoadIdentityCHROMIUM), }, { + "glGenPathsCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glGenPathsCHROMIUM), + }, + { + "glDeletePathsCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glDeletePathsCHROMIUM), + }, + { + "glIsPathCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glIsPathCHROMIUM), + }, + { + "glPathCommandsCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glPathCommandsCHROMIUM), + }, + { + "glPathParameterfCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glPathParameterfCHROMIUM), + }, + { + "glPathParameteriCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glPathParameteriCHROMIUM), + }, + { + "glPathStencilFuncCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glPathStencilFuncCHROMIUM), + }, + { + "glStencilFillPathCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glStencilFillPathCHROMIUM), + }, + { + "glStencilStrokePathCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glStencilStrokePathCHROMIUM), + }, + { + "glCoverFillPathCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glCoverFillPathCHROMIUM), + }, + { + "glCoverStrokePathCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glCoverStrokePathCHROMIUM), + }, + { + "glStencilThenCoverFillPathCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>(glStencilThenCoverFillPathCHROMIUM), + }, + { + "glStencilThenCoverStrokePathCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>( + glStencilThenCoverStrokePathCHROMIUM), + }, + { "glGetGraphicsResetStatusKHR", reinterpret_cast<GLES2FunctionPointer>(glGetGraphicsResetStatusKHR), }, diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index ce32148..abf4902 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -2833,6 +2833,125 @@ void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) { } } +void GenPathsCHROMIUM(GLuint first_client_id, GLsizei range) { + gles2::cmds::GenPathsCHROMIUM* c = + GetCmdSpace<gles2::cmds::GenPathsCHROMIUM>(); + if (c) { + c->Init(first_client_id, range); + } +} + +void DeletePathsCHROMIUM(GLuint first_client_id, GLsizei range) { + gles2::cmds::DeletePathsCHROMIUM* c = + GetCmdSpace<gles2::cmds::DeletePathsCHROMIUM>(); + if (c) { + c->Init(first_client_id, range); + } +} + +void IsPathCHROMIUM(GLuint path, + uint32_t result_shm_id, + uint32_t result_shm_offset) { + gles2::cmds::IsPathCHROMIUM* c = GetCmdSpace<gles2::cmds::IsPathCHROMIUM>(); + if (c) { + c->Init(path, result_shm_id, result_shm_offset); + } +} + +void PathCommandsCHROMIUM(GLuint path, + GLsizei numCommands, + uint32_t commands_shm_id, + uint32_t commands_shm_offset, + GLsizei numCoords, + GLenum coordType, + uint32_t coords_shm_id, + uint32_t coords_shm_offset) { + gles2::cmds::PathCommandsCHROMIUM* c = + GetCmdSpace<gles2::cmds::PathCommandsCHROMIUM>(); + if (c) { + c->Init(path, numCommands, commands_shm_id, commands_shm_offset, numCoords, + coordType, coords_shm_id, coords_shm_offset); + } +} + +void PathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat value) { + gles2::cmds::PathParameterfCHROMIUM* c = + GetCmdSpace<gles2::cmds::PathParameterfCHROMIUM>(); + if (c) { + c->Init(path, pname, value); + } +} + +void PathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value) { + gles2::cmds::PathParameteriCHROMIUM* c = + GetCmdSpace<gles2::cmds::PathParameteriCHROMIUM>(); + if (c) { + c->Init(path, pname, value); + } +} + +void PathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask) { + gles2::cmds::PathStencilFuncCHROMIUM* c = + GetCmdSpace<gles2::cmds::PathStencilFuncCHROMIUM>(); + if (c) { + c->Init(func, ref, mask); + } +} + +void StencilFillPathCHROMIUM(GLuint path, GLenum fillMode, GLuint mask) { + gles2::cmds::StencilFillPathCHROMIUM* c = + GetCmdSpace<gles2::cmds::StencilFillPathCHROMIUM>(); + if (c) { + c->Init(path, fillMode, mask); + } +} + +void StencilStrokePathCHROMIUM(GLuint path, GLint reference, GLuint mask) { + gles2::cmds::StencilStrokePathCHROMIUM* c = + GetCmdSpace<gles2::cmds::StencilStrokePathCHROMIUM>(); + if (c) { + c->Init(path, reference, mask); + } +} + +void CoverFillPathCHROMIUM(GLuint path, GLenum coverMode) { + gles2::cmds::CoverFillPathCHROMIUM* c = + GetCmdSpace<gles2::cmds::CoverFillPathCHROMIUM>(); + if (c) { + c->Init(path, coverMode); + } +} + +void CoverStrokePathCHROMIUM(GLuint path, GLenum coverMode) { + gles2::cmds::CoverStrokePathCHROMIUM* c = + GetCmdSpace<gles2::cmds::CoverStrokePathCHROMIUM>(); + if (c) { + c->Init(path, coverMode); + } +} + +void StencilThenCoverFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) { + gles2::cmds::StencilThenCoverFillPathCHROMIUM* c = + GetCmdSpace<gles2::cmds::StencilThenCoverFillPathCHROMIUM>(); + if (c) { + c->Init(path, fillMode, mask, coverMode); + } +} + +void StencilThenCoverStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) { + gles2::cmds::StencilThenCoverStrokePathCHROMIUM* c = + GetCmdSpace<gles2::cmds::StencilThenCoverStrokePathCHROMIUM>(); + if (c) { + c->Init(path, reference, mask, coverMode); + } +} + void BlendBarrierKHR() { gles2::cmds::BlendBarrierKHR* c = GetCmdSpace<gles2::cmds::BlendBarrierKHR>(); if (c) { diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 5cc28ddc..5dcc9dd 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -255,6 +255,11 @@ IdHandlerInterface* GLES2Implementation::GetIdHandler(int namespace_id) const { return share_group_->GetIdHandler(namespace_id); } +RangeIdHandlerInterface* GLES2Implementation::GetRangeIdHandler( + int namespace_id) const { + return share_group_->GetRangeIdHandler(namespace_id); +} + IdAllocator* GLES2Implementation::GetIdAllocator(int namespace_id) const { if (namespace_id == id_namespaces::kQueries) return query_id_allocator_.get(); @@ -5824,6 +5829,164 @@ void GLES2Implementation::GetInternalformativ( CheckGLError(); } +GLuint GLES2Implementation::GenPathsCHROMIUM(GLsizei range) { + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenPathsCHROMIUM(" << range + << ")"); + GPU_CLIENT_SINGLE_THREAD_CHECK(); + static const char kFunctionName[] = "glGenPathsCHROMIUM"; + if (range < 0) { + SetGLError(GL_INVALID_VALUE, kFunctionName, "range < 0"); + return 0; + } + if (!base::IsValueInRangeForNumericType<int32_t>(range)) { + SetGLError(GL_INVALID_OPERATION, kFunctionName, "range more than 32-bit"); + return 0; + } + if (range == 0) + return 0; + + GLuint first_client_id = 0; + GetRangeIdHandler(id_namespaces::kPaths) + ->MakeIdRange(this, range, &first_client_id); + + if (first_client_id == 0) { + // Ran out of id space. Is not specified to raise any gl errors. + return 0; + } + + helper_->GenPathsCHROMIUM(first_client_id, range); + + GPU_CLIENT_LOG_CODE_BLOCK({ + for (GLsizei i = 0; i < range; ++i) { + GPU_CLIENT_LOG(" " << i << ": " << (first_client_id + i)); + } + }); + CheckGLError(); + return first_client_id; +} + +void GLES2Implementation::DeletePathsCHROMIUM(GLuint first_client_id, + GLsizei range) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeletePathsCHROMIUM(" + << first_client_id << ", " << range << ")"); + static const char kFunctionName[] = "glDeletePathsCHROMIUM"; + + if (range < 0) { + SetGLError(GL_INVALID_VALUE, kFunctionName, "range < 0"); + return; + } + if (!base::IsValueInRangeForNumericType<int32_t>(range)) { + SetGLError(GL_INVALID_OPERATION, kFunctionName, "range more than 32-bit"); + return; + } + if (range == 0) + return; + + GLuint last_client_id; + if (!SafeAddUint32(first_client_id, range - 1, &last_client_id)) { + SetGLError(GL_INVALID_OPERATION, kFunctionName, "overflow"); + return; + } + + GetRangeIdHandler(id_namespaces::kPaths) + ->FreeIdRange(this, first_client_id, range, + &GLES2Implementation::DeletePathsCHROMIUMStub); + CheckGLError(); +} + +void GLES2Implementation::DeletePathsCHROMIUMStub(GLuint first_client_id, + GLsizei range) { + helper_->DeletePathsCHROMIUM(first_client_id, range); +} + +void GLES2Implementation::PathCommandsCHROMIUM(GLuint path, + GLsizei num_commands, + const GLubyte* commands, + GLsizei num_coords, + GLenum coord_type, + const void* coords) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPathCommandsCHROMIUM(" << path + << ", " << num_commands << ", " << commands << ", " + << num_coords << ", " << coords << ")"); + static const char kFunctionName[] = "glPathCommandsCHROMIUM"; + if (path == 0) { + SetGLError(GL_INVALID_VALUE, kFunctionName, "invalid path object"); + return; + } + if (num_commands < 0) { + SetGLError(GL_INVALID_VALUE, kFunctionName, "numCommands < 0"); + return; + } + if (num_commands != 0 && !commands) { + SetGLError(GL_INVALID_VALUE, kFunctionName, "missing commands"); + return; + } + if (num_coords < 0) { + SetGLError(GL_INVALID_VALUE, kFunctionName, "numCoords < 0"); + return; + } + if (num_coords != 0 && !coords) { + SetGLError(GL_INVALID_VALUE, kFunctionName, "missing coords"); + return; + } + uint32 coord_type_size = GLES2Util::GetGLTypeSizeForPathCoordType(coord_type); + if (coord_type_size == 0) { + SetGLError(GL_INVALID_ENUM, kFunctionName, "invalid coordType"); + return; + } + if (num_commands == 0) { + // No commands must mean no coords, thus nothing to memcpy. Let + // the service validate the call. Validate coord_type above, so + // that the parameters will be checked the in the same order + // regardless of num_commands. + helper_->PathCommandsCHROMIUM(path, num_commands, 0, 0, num_coords, + coord_type, 0, 0); + CheckGLError(); + return; + } + + uint32 coords_size; + if (!SafeMultiplyUint32(num_coords, coord_type_size, &coords_size)) { + SetGLError(GL_INVALID_OPERATION, kFunctionName, "overflow"); + return; + } + + uint32 required_buffer_size; + if (!SafeAddUint32(coords_size, num_commands, &required_buffer_size)) { + SetGLError(GL_INVALID_OPERATION, kFunctionName, "overflow"); + return; + } + + ScopedTransferBufferPtr buffer(required_buffer_size, helper_, + transfer_buffer_); + if (!buffer.valid() || buffer.size() < required_buffer_size) { + SetGLError(GL_OUT_OF_MEMORY, kFunctionName, "too large"); + return; + } + + uint32 coords_shm_id = 0; + uint32 coords_shm_offset = 0; + // Copy coords first because they need more strict alignment. + if (coords_size > 0) { + unsigned char* coords_addr = static_cast<unsigned char*>(buffer.address()); + memcpy(coords_addr, coords, coords_size); + coords_shm_id = buffer.shm_id(); + coords_shm_offset = buffer.offset(); + } + + DCHECK(num_commands > 0); + unsigned char* commands_addr = + static_cast<unsigned char*>(buffer.address()) + coords_size; + memcpy(commands_addr, commands, num_commands); + + helper_->PathCommandsCHROMIUM(path, num_commands, buffer.shm_id(), + buffer.offset() + coords_size, num_coords, + coord_type, coords_shm_id, coords_shm_offset); + CheckGLError(); +} + // Include the auto-generated part of this file. We split this because it means // we can easily edit the non-auto generated parts right here in this file // instead of having to edit some template or the code generator. diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h index c642f9a..3446e76 100644 --- a/gpu/command_buffer/client/gles2_implementation.h +++ b/gpu/command_buffer/client/gles2_implementation.h @@ -510,6 +510,7 @@ class GLES2_IMPL_EXPORT GLES2Implementation void DeleteFramebuffersStub(GLsizei n, const GLuint* framebuffers); void DeleteRenderbuffersStub(GLsizei n, const GLuint* renderbuffers); void DeleteTexturesStub(GLsizei n, const GLuint* textures); + void DeletePathsCHROMIUMStub(GLuint first_client_id, GLsizei range); void DeleteProgramStub(GLsizei n, const GLuint* programs); void DeleteShaderStub(GLsizei n, const GLuint* shaders); void DeleteVertexArraysOESStub(GLsizei n, const GLuint* arrays); @@ -593,6 +594,7 @@ class GLES2_IMPL_EXPORT GLES2Implementation bool SetCapabilityState(GLenum cap, bool enabled); IdHandlerInterface* GetIdHandler(int id_namespace) const; + RangeIdHandlerInterface* GetRangeIdHandler(int id_namespace) const; // IdAllocators for objects that can't be shared among contexts. // For now, used only for Queries. TODO(hj.r.chung) Should be added for // Framebuffer and Vertex array objects. diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 5cb7a65..bee4f9c 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -1053,6 +1053,47 @@ void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) override; void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) override; +GLuint GenPathsCHROMIUM(GLsizei range) override; + +void DeletePathsCHROMIUM(GLuint path, GLsizei range) override; + +GLboolean IsPathCHROMIUM(GLuint path) override; + +void PathCommandsCHROMIUM(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords) override; + +void PathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat value) override; + +void PathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value) override; + +void PathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask) override; + +void StencilFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask) override; + +void StencilStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask) override; + +void CoverFillPathCHROMIUM(GLuint path, GLenum coverMode) override; + +void CoverStrokePathCHROMIUM(GLuint path, GLenum coverMode) override; + +void StencilThenCoverFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) override; + +void StencilThenCoverStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) override; + GLenum GetGraphicsResetStatusKHR() override; void BlendBarrierKHR() override; diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index 8586fe3..79a7650 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h @@ -3462,6 +3462,123 @@ void GLES2Implementation::MatrixLoadIdentityCHROMIUM(GLenum matrixMode) { CheckGLError(); } +GLboolean GLES2Implementation::IsPathCHROMIUM(GLuint path) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + TRACE_EVENT0("gpu", "GLES2Implementation::IsPathCHROMIUM"); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsPathCHROMIUM(" << path << ")"); + typedef cmds::IsPathCHROMIUM::Result Result; + Result* result = GetResultAs<Result*>(); + if (!result) { + return GL_FALSE; + } + *result = 0; + helper_->IsPathCHROMIUM(path, GetResultShmId(), GetResultShmOffset()); + WaitForCmd(); + GLboolean result_value = *result != 0; + GPU_CLIENT_LOG("returned " << result_value); + CheckGLError(); + return result_value; +} + +void GLES2Implementation::PathParameterfCHROMIUM(GLuint path, + GLenum pname, + GLfloat value) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPathParameterfCHROMIUM(" << path + << ", " << GLES2Util::GetStringPathParameter(pname) << ", " + << value << ")"); + helper_->PathParameterfCHROMIUM(path, pname, value); + CheckGLError(); +} + +void GLES2Implementation::PathParameteriCHROMIUM(GLuint path, + GLenum pname, + GLint value) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPathParameteriCHROMIUM(" << path + << ", " << GLES2Util::GetStringPathParameter(pname) << ", " + << value << ")"); + helper_->PathParameteriCHROMIUM(path, pname, value); + CheckGLError(); +} + +void GLES2Implementation::PathStencilFuncCHROMIUM(GLenum func, + GLint ref, + GLuint mask) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPathStencilFuncCHROMIUM(" + << GLES2Util::GetStringCmpFunction(func) << ", " << ref + << ", " << mask << ")"); + helper_->PathStencilFuncCHROMIUM(func, ref, mask); + CheckGLError(); +} + +void GLES2Implementation::StencilFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilFillPathCHROMIUM(" << path + << ", " << GLES2Util::GetStringPathFillMode(fillMode) + << ", " << mask << ")"); + helper_->StencilFillPathCHROMIUM(path, fillMode, mask); + CheckGLError(); +} + +void GLES2Implementation::StencilStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilStrokePathCHROMIUM(" + << path << ", " << reference << ", " << mask << ")"); + helper_->StencilStrokePathCHROMIUM(path, reference, mask); + CheckGLError(); +} + +void GLES2Implementation::CoverFillPathCHROMIUM(GLuint path, GLenum coverMode) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCoverFillPathCHROMIUM(" << path + << ", " << GLES2Util::GetStringPathCoverMode(coverMode) + << ")"); + helper_->CoverFillPathCHROMIUM(path, coverMode); + CheckGLError(); +} + +void GLES2Implementation::CoverStrokePathCHROMIUM(GLuint path, + GLenum coverMode) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCoverStrokePathCHROMIUM(" << path + << ", " << GLES2Util::GetStringPathCoverMode(coverMode) + << ")"); + helper_->CoverStrokePathCHROMIUM(path, coverMode); + CheckGLError(); +} + +void GLES2Implementation::StencilThenCoverFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG( + "[" << GetLogPrefix() << "] glStencilThenCoverFillPathCHROMIUM(" << path + << ", " << GLES2Util::GetStringPathFillMode(fillMode) << ", " << mask + << ", " << GLES2Util::GetStringPathCoverMode(coverMode) << ")"); + helper_->StencilThenCoverFillPathCHROMIUM(path, fillMode, mask, coverMode); + CheckGLError(); +} + +void GLES2Implementation::StencilThenCoverStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() + << "] glStencilThenCoverStrokePathCHROMIUM(" << path + << ", " << reference << ", " << mask << ", " + << GLES2Util::GetStringPathCoverMode(coverMode) << ")"); + helper_->StencilThenCoverStrokePathCHROMIUM(path, reference, mask, coverMode); + CheckGLError(); +} + void GLES2Implementation::BlendBarrierKHR() { GPU_CLIENT_SINGLE_THREAD_CHECK(); GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlendBarrierKHR(" diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index 7cf70eb..fef96d9 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h @@ -3119,4 +3119,136 @@ TEST_F(GLES2ImplementationTest, MatrixLoadIdentityCHROMIUM) { gl_->MatrixLoadIdentityCHROMIUM(GL_PATH_PROJECTION_CHROMIUM); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } +// TODO(zmo): Implement unit test for GenPathsCHROMIUM + +TEST_F(GLES2ImplementationTest, DeletePathsCHROMIUM) { + struct Cmds { + cmds::DeletePathsCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(1, 2); + + gl_->DeletePathsCHROMIUM(1, 2); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, IsPathCHROMIUM) { + struct Cmds { + cmds::IsPathCHROMIUM cmd; + }; + + Cmds expected; + ExpectedMemoryInfo result1 = + GetExpectedResultMemory(sizeof(cmds::IsPathCHROMIUM::Result)); + expected.cmd.Init(1, result1.id, result1.offset); + + EXPECT_CALL(*command_buffer(), OnFlush()) + .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE))) + .RetiresOnSaturation(); + + GLboolean result = gl_->IsPathCHROMIUM(1); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); + EXPECT_TRUE(result); +} +// TODO(zmo): Implement unit test for PathCommandsCHROMIUM + +TEST_F(GLES2ImplementationTest, PathParameterfCHROMIUM) { + struct Cmds { + cmds::PathParameterfCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(1, GL_PATH_STROKE_WIDTH_CHROMIUM, 3); + + gl_->PathParameterfCHROMIUM(1, GL_PATH_STROKE_WIDTH_CHROMIUM, 3); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, PathParameteriCHROMIUM) { + struct Cmds { + cmds::PathParameteriCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(1, GL_PATH_STROKE_WIDTH_CHROMIUM, 3); + + gl_->PathParameteriCHROMIUM(1, GL_PATH_STROKE_WIDTH_CHROMIUM, 3); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, PathStencilFuncCHROMIUM) { + struct Cmds { + cmds::PathStencilFuncCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(GL_NEVER, 2, 3); + + gl_->PathStencilFuncCHROMIUM(GL_NEVER, 2, 3); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, StencilFillPathCHROMIUM) { + struct Cmds { + cmds::StencilFillPathCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(1, GL_INVERT, 3); + + gl_->StencilFillPathCHROMIUM(1, GL_INVERT, 3); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, StencilStrokePathCHROMIUM) { + struct Cmds { + cmds::StencilStrokePathCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(1, 2, 3); + + gl_->StencilStrokePathCHROMIUM(1, 2, 3); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, CoverFillPathCHROMIUM) { + struct Cmds { + cmds::CoverFillPathCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(1, GL_CONVEX_HULL_CHROMIUM); + + gl_->CoverFillPathCHROMIUM(1, GL_CONVEX_HULL_CHROMIUM); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, CoverStrokePathCHROMIUM) { + struct Cmds { + cmds::CoverStrokePathCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(1, GL_CONVEX_HULL_CHROMIUM); + + gl_->CoverStrokePathCHROMIUM(1, GL_CONVEX_HULL_CHROMIUM); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, StencilThenCoverFillPathCHROMIUM) { + struct Cmds { + cmds::StencilThenCoverFillPathCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(1, GL_INVERT, 3, GL_CONVEX_HULL_CHROMIUM); + + gl_->StencilThenCoverFillPathCHROMIUM(1, GL_INVERT, 3, + GL_CONVEX_HULL_CHROMIUM); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, StencilThenCoverStrokePathCHROMIUM) { + struct Cmds { + cmds::StencilThenCoverStrokePathCHROMIUM cmd; + }; + Cmds expected; + expected.cmd.Init(1, 2, 3, GL_CONVEX_HULL_CHROMIUM); + + gl_->StencilThenCoverStrokePathCHROMIUM(1, 2, 3, GL_CONVEX_HULL_CHROMIUM); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_UNITTEST_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index 5e61f11..99d0577 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h @@ -781,6 +781,36 @@ virtual void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order, virtual void SwapInterval(GLint interval) = 0; virtual void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) = 0; virtual void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) = 0; +virtual GLuint GenPathsCHROMIUM(GLsizei range) = 0; +virtual void DeletePathsCHROMIUM(GLuint path, GLsizei range) = 0; +virtual GLboolean IsPathCHROMIUM(GLuint path) = 0; +virtual void PathCommandsCHROMIUM(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords) = 0; +virtual void PathParameterfCHROMIUM(GLuint path, + GLenum pname, + GLfloat value) = 0; +virtual void PathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value) = 0; +virtual void PathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask) = 0; +virtual void StencilFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask) = 0; +virtual void StencilStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask) = 0; +virtual void CoverFillPathCHROMIUM(GLuint path, GLenum coverMode) = 0; +virtual void CoverStrokePathCHROMIUM(GLuint path, GLenum coverMode) = 0; +virtual void StencilThenCoverFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) = 0; +virtual void StencilThenCoverStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) = 0; virtual GLenum GetGraphicsResetStatusKHR() = 0; virtual void BlendBarrierKHR() = 0; #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 1f70750..41358fb 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h @@ -759,6 +759,34 @@ void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order, void SwapInterval(GLint interval) override; void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) override; void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) override; +GLuint GenPathsCHROMIUM(GLsizei range) override; +void DeletePathsCHROMIUM(GLuint path, GLsizei range) override; +GLboolean IsPathCHROMIUM(GLuint path) override; +void PathCommandsCHROMIUM(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords) override; +void PathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat value) override; +void PathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value) override; +void PathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask) override; +void StencilFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask) override; +void StencilStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask) override; +void CoverFillPathCHROMIUM(GLuint path, GLenum coverMode) override; +void CoverStrokePathCHROMIUM(GLuint path, GLenum coverMode) override; +void StencilThenCoverFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) override; +void StencilThenCoverStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) override; GLenum GetGraphicsResetStatusKHR() override; void BlendBarrierKHR() override; #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index cf1baa2..6058760 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h @@ -1290,6 +1290,60 @@ void GLES2InterfaceStub::MatrixLoadfCHROMIUM(GLenum /* matrixMode */, } void GLES2InterfaceStub::MatrixLoadIdentityCHROMIUM(GLenum /* matrixMode */) { } +GLuint GLES2InterfaceStub::GenPathsCHROMIUM(GLsizei /* range */) { + return 0; +} +void GLES2InterfaceStub::DeletePathsCHROMIUM(GLuint /* path */, + GLsizei /* range */) { +} +GLboolean GLES2InterfaceStub::IsPathCHROMIUM(GLuint /* path */) { + return 0; +} +void GLES2InterfaceStub::PathCommandsCHROMIUM(GLuint /* path */, + GLsizei /* numCommands */, + const GLubyte* /* commands */, + GLsizei /* numCoords */, + GLenum /* coordType */, + const GLvoid* /* coords */) { +} +void GLES2InterfaceStub::PathParameterfCHROMIUM(GLuint /* path */, + GLenum /* pname */, + GLfloat /* value */) { +} +void GLES2InterfaceStub::PathParameteriCHROMIUM(GLuint /* path */, + GLenum /* pname */, + GLint /* value */) { +} +void GLES2InterfaceStub::PathStencilFuncCHROMIUM(GLenum /* func */, + GLint /* ref */, + GLuint /* mask */) { +} +void GLES2InterfaceStub::StencilFillPathCHROMIUM(GLuint /* path */, + GLenum /* fillMode */, + GLuint /* mask */) { +} +void GLES2InterfaceStub::StencilStrokePathCHROMIUM(GLuint /* path */, + GLint /* reference */, + GLuint /* mask */) { +} +void GLES2InterfaceStub::CoverFillPathCHROMIUM(GLuint /* path */, + GLenum /* coverMode */) { +} +void GLES2InterfaceStub::CoverStrokePathCHROMIUM(GLuint /* path */, + GLenum /* coverMode */) { +} +void GLES2InterfaceStub::StencilThenCoverFillPathCHROMIUM( + GLuint /* path */, + GLenum /* fillMode */, + GLuint /* mask */, + GLenum /* coverMode */) { +} +void GLES2InterfaceStub::StencilThenCoverStrokePathCHROMIUM( + GLuint /* path */, + GLint /* reference */, + GLuint /* mask */, + GLenum /* coverMode */) { +} GLenum GLES2InterfaceStub::GetGraphicsResetStatusKHR() { return 0; } diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 30743ea..ed48158 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h @@ -759,6 +759,34 @@ void ScheduleOverlayPlaneCHROMIUM(GLint plane_z_order, void SwapInterval(GLint interval) override; void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) override; void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) override; +GLuint GenPathsCHROMIUM(GLsizei range) override; +void DeletePathsCHROMIUM(GLuint path, GLsizei range) override; +GLboolean IsPathCHROMIUM(GLuint path) override; +void PathCommandsCHROMIUM(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords) override; +void PathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat value) override; +void PathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value) override; +void PathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask) override; +void StencilFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask) override; +void StencilStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask) override; +void CoverFillPathCHROMIUM(GLuint path, GLenum coverMode) override; +void CoverStrokePathCHROMIUM(GLuint path, GLenum coverMode) override; +void StencilThenCoverFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) override; +void StencilThenCoverStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) override; GLenum GetGraphicsResetStatusKHR() override; void BlendBarrierKHR() override; #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_TRACE_IMPLEMENTATION_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 13c215f..a0b41a2 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h @@ -2206,6 +2206,99 @@ void GLES2TraceImplementation::MatrixLoadIdentityCHROMIUM(GLenum matrixMode) { gl_->MatrixLoadIdentityCHROMIUM(matrixMode); } +GLuint GLES2TraceImplementation::GenPathsCHROMIUM(GLsizei range) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GenPathsCHROMIUM"); + return gl_->GenPathsCHROMIUM(range); +} + +void GLES2TraceImplementation::DeletePathsCHROMIUM(GLuint path, GLsizei range) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DeletePathsCHROMIUM"); + gl_->DeletePathsCHROMIUM(path, range); +} + +GLboolean GLES2TraceImplementation::IsPathCHROMIUM(GLuint path) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::IsPathCHROMIUM"); + return gl_->IsPathCHROMIUM(path); +} + +void GLES2TraceImplementation::PathCommandsCHROMIUM(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::PathCommandsCHROMIUM"); + gl_->PathCommandsCHROMIUM(path, numCommands, commands, numCoords, coordType, + coords); +} + +void GLES2TraceImplementation::PathParameterfCHROMIUM(GLuint path, + GLenum pname, + GLfloat value) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::PathParameterfCHROMIUM"); + gl_->PathParameterfCHROMIUM(path, pname, value); +} + +void GLES2TraceImplementation::PathParameteriCHROMIUM(GLuint path, + GLenum pname, + GLint value) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::PathParameteriCHROMIUM"); + gl_->PathParameteriCHROMIUM(path, pname, value); +} + +void GLES2TraceImplementation::PathStencilFuncCHROMIUM(GLenum func, + GLint ref, + GLuint mask) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::PathStencilFuncCHROMIUM"); + gl_->PathStencilFuncCHROMIUM(func, ref, mask); +} + +void GLES2TraceImplementation::StencilFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::StencilFillPathCHROMIUM"); + gl_->StencilFillPathCHROMIUM(path, fillMode, mask); +} + +void GLES2TraceImplementation::StencilStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::StencilStrokePathCHROMIUM"); + gl_->StencilStrokePathCHROMIUM(path, reference, mask); +} + +void GLES2TraceImplementation::CoverFillPathCHROMIUM(GLuint path, + GLenum coverMode) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CoverFillPathCHROMIUM"); + gl_->CoverFillPathCHROMIUM(path, coverMode); +} + +void GLES2TraceImplementation::CoverStrokePathCHROMIUM(GLuint path, + GLenum coverMode) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CoverStrokePathCHROMIUM"); + gl_->CoverStrokePathCHROMIUM(path, coverMode); +} + +void GLES2TraceImplementation::StencilThenCoverFillPathCHROMIUM( + GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", + "GLES2Trace::StencilThenCoverFillPathCHROMIUM"); + gl_->StencilThenCoverFillPathCHROMIUM(path, fillMode, mask, coverMode); +} + +void GLES2TraceImplementation::StencilThenCoverStrokePathCHROMIUM( + GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) { + TRACE_EVENT_BINARY_EFFICIENT0( + "gpu", "GLES2Trace::StencilThenCoverStrokePathCHROMIUM"); + gl_->StencilThenCoverStrokePathCHROMIUM(path, reference, mask, coverMode); +} + GLenum GLES2TraceImplementation::GetGraphicsResetStatusKHR() { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetGraphicsResetStatusKHR"); return gl_->GetGraphicsResetStatusKHR(); diff --git a/gpu/command_buffer/client/share_group.cc b/gpu/command_buffer/client/share_group.cc index 32e853b..e6ed66d 100644 --- a/gpu/command_buffer/client/share_group.cc +++ b/gpu/command_buffer/client/share_group.cc @@ -318,6 +318,35 @@ class NonReusedIdHandler : public IdHandlerInterface { GLuint last_id_; }; +class RangeIdHandler : public RangeIdHandlerInterface { + public: + RangeIdHandler() {} + + void MakeIdRange(GLES2Implementation* /*gl_impl*/, + GLsizei n, + GLuint* first_id) override { + base::AutoLock auto_lock(lock_); + *first_id = id_allocator_.AllocateIDRange(n); + } + + void FreeIdRange(GLES2Implementation* gl_impl, + const GLuint first_id, + GLsizei range, + DeleteRangeFn delete_fn) override { + base::AutoLock auto_lock(lock_); + DCHECK(range > 0); + id_allocator_.FreeIDRange(first_id, range); + (gl_impl->*delete_fn)(first_id, range); + gl_impl->helper()->CommandBufferHelper::OrderingBarrier(); + } + + void FreeContext(GLES2Implementation* gl_impl) override {} + + private: + base::Lock lock_; + IdAllocator id_allocator_; +}; + ShareGroup::ShareGroup(bool bind_generates_resource) : bind_generates_resource_(bind_generates_resource) { if (bind_generates_resource) { @@ -338,6 +367,9 @@ ShareGroup::ShareGroup(bool bind_generates_resource) } } program_info_manager_.reset(new ProgramInfoManager); + for (auto& range_id_handler : range_id_handlers_) { + range_id_handler.reset(new RangeIdHandler()); + } } void ShareGroup::set_program_info_manager(ProgramInfoManager* manager) { diff --git a/gpu/command_buffer/client/share_group.h b/gpu/command_buffer/client/share_group.h index c150004..2a6acc5 100644 --- a/gpu/command_buffer/client/share_group.h +++ b/gpu/command_buffer/client/share_group.h @@ -19,6 +19,8 @@ class GLES2ImplementationTest; class ProgramInfoManager; typedef void (GLES2Implementation::*DeleteFn)(GLsizei n, const GLuint* ids); +typedef void (GLES2Implementation::*DeleteRangeFn)(const GLuint first_id, + GLsizei range); typedef void (GLES2Implementation::*BindFn)(GLenum target, GLuint id); typedef void (GLES2Implementation::*BindIndexedFn)( \ GLenum target, GLuint index, GLuint id); @@ -86,6 +88,27 @@ class IdHandlerInterface { virtual void FreeContext(GLES2Implementation* gl_impl) = 0; }; +class RangeIdHandlerInterface { + public: + RangeIdHandlerInterface() {} + virtual ~RangeIdHandlerInterface() {} + + // Makes a continuous range of ids. Stores the first allocated id to + // |first_id| or 0 if allocation failed. + virtual void MakeIdRange(GLES2Implementation* gl_impl, + GLsizei n, + GLuint* first_id) = 0; + + // Frees a continuous |range| of ids beginning at |first_id|. + virtual void FreeIdRange(GLES2Implementation* gl_impl, + const GLuint first_id, + GLsizei range, + DeleteRangeFn delete_fn) = 0; + + // Called when a context in the share group is destructed. + virtual void FreeContext(GLES2Implementation* gl_impl) = 0; +}; + // ShareGroup manages shared resources for contexts that are sharing resources. class GLES2_IMPL_EXPORT ShareGroup : public gpu::RefCountedThreadSafe<ShareGroup> { @@ -100,6 +123,10 @@ class GLES2_IMPL_EXPORT ShareGroup return id_handlers_[namespace_id].get(); } + RangeIdHandlerInterface* GetRangeIdHandler(int range_namespace_id) const { + return range_id_handlers_[range_namespace_id].get(); + } + ProgramInfoManager* program_info_manager() { return program_info_manager_.get(); } @@ -108,6 +135,9 @@ class GLES2_IMPL_EXPORT ShareGroup for (int i = 0; i < id_namespaces::kNumIdNamespaces; ++i) { id_handlers_[i]->FreeContext(gl_impl); } + for (auto& range_id_handler : range_id_handlers_) { + range_id_handler->FreeContext(gl_impl); + } } private: @@ -119,6 +149,8 @@ class GLES2_IMPL_EXPORT ShareGroup void set_program_info_manager(ProgramInfoManager* manager); scoped_ptr<IdHandlerInterface> id_handlers_[id_namespaces::kNumIdNamespaces]; + scoped_ptr<RangeIdHandlerInterface> + range_id_handlers_[id_namespaces::kNumRangeIdNamespaces]; scoped_ptr<ProgramInfoManager> program_info_manager_; bool bind_generates_resource_; diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index bcd4204..890a5db 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt @@ -314,6 +314,19 @@ GL_APICALL void GL_APIENTRY glSwapInterval (GLint interval); // Extension CHROMIUM_path_rendering. GL_APICALL void GL_APIENTRY glMatrixLoadfCHROMIUM (GLenumMatrixMode matrixMode, const GLfloat* m); GL_APICALL void GL_APIENTRY glMatrixLoadIdentityCHROMIUM (GLenumMatrixMode matrixMode); +GL_APICALL GLuint GL_APIENTRY glGenPathsCHROMIUM (GLsizei range); +GL_APICALL void GL_APIENTRY glDeletePathsCHROMIUM (GLidPath path, GLsizei range); +GL_APICALL GLboolean GL_APIENTRY glIsPathCHROMIUM (GLidPath path); +GL_APICALL void GL_APIENTRY glPathCommandsCHROMIUM (GLidPath path, GLsizei numCommands, const GLubyte* commands, GLsizei numCoords, GLenumPathCoordType coordType, const GLvoid* coords); +GL_APICALL void GL_APIENTRY glPathParameterfCHROMIUM (GLidPath path, GLenumPathParameter pname, GLfloat value); +GL_APICALL void GL_APIENTRY glPathParameteriCHROMIUM (GLidPath path, GLenumPathParameter pname, GLint value); +GL_APICALL void GL_APIENTRY glPathStencilFuncCHROMIUM (GLenumCmpFunction func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFillPathCHROMIUM (GLidPath path, GLenumPathFillMode fillMode, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilStrokePathCHROMIUM (GLidPath path, GLint reference, GLuint mask); +GL_APICALL void GL_APIENTRY glCoverFillPathCHROMIUM (GLidPath path, GLenumPathCoverMode coverMode); +GL_APICALL void GL_APIENTRY glCoverStrokePathCHROMIUM (GLidPath path, GLenumPathCoverMode coverMode); +GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathCHROMIUM (GLidPath path, GLenumPathFillMode fillMode, GLuint mask, GLenumPathCoverMode coverMode); +GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathCHROMIUM (GLidPath path, GLint reference, GLuint mask, GLenumPathCoverMode coverMode); // Extension KHR_robustness GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusKHR (void); diff --git a/gpu/command_buffer/common/gles2_cmd_format.h b/gpu/command_buffer/common/gles2_cmd_format.h index db63594..325c334 100644 --- a/gpu/command_buffer/common/gles2_cmd_format.h +++ b/gpu/command_buffer/common/gles2_cmd_format.h @@ -70,12 +70,15 @@ enum IdNamespaces { kNumIdNamespaces }; +enum RangeIdNamespaces { kPaths, kNumRangeIdNamespaces }; + // These numbers must not change static_assert(kBuffers == 0, "kBuffers should equal 0"); static_assert(kFramebuffers == 1, "kFramebuffers should equal 1"); static_assert(kProgramsAndShaders == 2, "kProgramsAndShaders should equal 2"); static_assert(kRenderbuffers == 3, "kRenderbuffers should equal 3"); static_assert(kTextures == 4, "kTextures should equal 4"); +static_assert(kPaths == 0, "kPaths should equal 0"); } // namespace id_namespaces diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index e7a6272..ded8b6f 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -13780,6 +13780,590 @@ static_assert(offsetof(MatrixLoadIdentityCHROMIUM, header) == 0, static_assert(offsetof(MatrixLoadIdentityCHROMIUM, matrixMode) == 4, "offset of MatrixLoadIdentityCHROMIUM matrixMode should be 4"); +struct GenPathsCHROMIUM { + typedef GenPathsCHROMIUM ValueType; + static const CommandId kCmdId = kGenPathsCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _first_client_id, GLsizei _range) { + SetHeader(); + first_client_id = _first_client_id; + range = _range; + } + + void* Set(void* cmd, GLuint _first_client_id, GLsizei _range) { + static_cast<ValueType*>(cmd)->Init(_first_client_id, _range); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t first_client_id; + int32_t range; +}; + +static_assert(sizeof(GenPathsCHROMIUM) == 12, + "size of GenPathsCHROMIUM should be 12"); +static_assert(offsetof(GenPathsCHROMIUM, header) == 0, + "offset of GenPathsCHROMIUM header should be 0"); +static_assert(offsetof(GenPathsCHROMIUM, first_client_id) == 4, + "offset of GenPathsCHROMIUM first_client_id should be 4"); +static_assert(offsetof(GenPathsCHROMIUM, range) == 8, + "offset of GenPathsCHROMIUM range should be 8"); + +struct DeletePathsCHROMIUM { + typedef DeletePathsCHROMIUM ValueType; + static const CommandId kCmdId = kDeletePathsCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _first_client_id, GLsizei _range) { + SetHeader(); + first_client_id = _first_client_id; + range = _range; + } + + void* Set(void* cmd, GLuint _first_client_id, GLsizei _range) { + static_cast<ValueType*>(cmd)->Init(_first_client_id, _range); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t first_client_id; + int32_t range; +}; + +static_assert(sizeof(DeletePathsCHROMIUM) == 12, + "size of DeletePathsCHROMIUM should be 12"); +static_assert(offsetof(DeletePathsCHROMIUM, header) == 0, + "offset of DeletePathsCHROMIUM header should be 0"); +static_assert(offsetof(DeletePathsCHROMIUM, first_client_id) == 4, + "offset of DeletePathsCHROMIUM first_client_id should be 4"); +static_assert(offsetof(DeletePathsCHROMIUM, range) == 8, + "offset of DeletePathsCHROMIUM range should be 8"); + +struct IsPathCHROMIUM { + typedef IsPathCHROMIUM ValueType; + static const CommandId kCmdId = kIsPathCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + typedef uint32_t Result; + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _path, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + SetHeader(); + path = _path; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set(void* cmd, + GLuint _path, + uint32_t _result_shm_id, + uint32_t _result_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_path, _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t path; + uint32_t result_shm_id; + uint32_t result_shm_offset; +}; + +static_assert(sizeof(IsPathCHROMIUM) == 16, + "size of IsPathCHROMIUM should be 16"); +static_assert(offsetof(IsPathCHROMIUM, header) == 0, + "offset of IsPathCHROMIUM header should be 0"); +static_assert(offsetof(IsPathCHROMIUM, path) == 4, + "offset of IsPathCHROMIUM path should be 4"); +static_assert(offsetof(IsPathCHROMIUM, result_shm_id) == 8, + "offset of IsPathCHROMIUM result_shm_id should be 8"); +static_assert(offsetof(IsPathCHROMIUM, result_shm_offset) == 12, + "offset of IsPathCHROMIUM result_shm_offset should be 12"); + +struct PathCommandsCHROMIUM { + typedef PathCommandsCHROMIUM ValueType; + static const CommandId kCmdId = kPathCommandsCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _path, + GLsizei _numCommands, + uint32_t _commands_shm_id, + uint32_t _commands_shm_offset, + GLsizei _numCoords, + GLenum _coordType, + uint32_t _coords_shm_id, + uint32_t _coords_shm_offset) { + SetHeader(); + path = _path; + numCommands = _numCommands; + commands_shm_id = _commands_shm_id; + commands_shm_offset = _commands_shm_offset; + numCoords = _numCoords; + coordType = _coordType; + coords_shm_id = _coords_shm_id; + coords_shm_offset = _coords_shm_offset; + } + + void* Set(void* cmd, + GLuint _path, + GLsizei _numCommands, + uint32_t _commands_shm_id, + uint32_t _commands_shm_offset, + GLsizei _numCoords, + GLenum _coordType, + uint32_t _coords_shm_id, + uint32_t _coords_shm_offset) { + static_cast<ValueType*>(cmd) + ->Init(_path, _numCommands, _commands_shm_id, _commands_shm_offset, + _numCoords, _coordType, _coords_shm_id, _coords_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t path; + int32_t numCommands; + uint32_t commands_shm_id; + uint32_t commands_shm_offset; + int32_t numCoords; + uint32_t coordType; + uint32_t coords_shm_id; + uint32_t coords_shm_offset; +}; + +static_assert(sizeof(PathCommandsCHROMIUM) == 36, + "size of PathCommandsCHROMIUM should be 36"); +static_assert(offsetof(PathCommandsCHROMIUM, header) == 0, + "offset of PathCommandsCHROMIUM header should be 0"); +static_assert(offsetof(PathCommandsCHROMIUM, path) == 4, + "offset of PathCommandsCHROMIUM path should be 4"); +static_assert(offsetof(PathCommandsCHROMIUM, numCommands) == 8, + "offset of PathCommandsCHROMIUM numCommands should be 8"); +static_assert(offsetof(PathCommandsCHROMIUM, commands_shm_id) == 12, + "offset of PathCommandsCHROMIUM commands_shm_id should be 12"); +static_assert( + offsetof(PathCommandsCHROMIUM, commands_shm_offset) == 16, + "offset of PathCommandsCHROMIUM commands_shm_offset should be 16"); +static_assert(offsetof(PathCommandsCHROMIUM, numCoords) == 20, + "offset of PathCommandsCHROMIUM numCoords should be 20"); +static_assert(offsetof(PathCommandsCHROMIUM, coordType) == 24, + "offset of PathCommandsCHROMIUM coordType should be 24"); +static_assert(offsetof(PathCommandsCHROMIUM, coords_shm_id) == 28, + "offset of PathCommandsCHROMIUM coords_shm_id should be 28"); +static_assert(offsetof(PathCommandsCHROMIUM, coords_shm_offset) == 32, + "offset of PathCommandsCHROMIUM coords_shm_offset should be 32"); + +struct PathParameterfCHROMIUM { + typedef PathParameterfCHROMIUM ValueType; + static const CommandId kCmdId = kPathParameterfCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _path, GLenum _pname, GLfloat _value) { + SetHeader(); + path = _path; + pname = _pname; + value = _value; + } + + void* Set(void* cmd, GLuint _path, GLenum _pname, GLfloat _value) { + static_cast<ValueType*>(cmd)->Init(_path, _pname, _value); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t path; + uint32_t pname; + float value; +}; + +static_assert(sizeof(PathParameterfCHROMIUM) == 16, + "size of PathParameterfCHROMIUM should be 16"); +static_assert(offsetof(PathParameterfCHROMIUM, header) == 0, + "offset of PathParameterfCHROMIUM header should be 0"); +static_assert(offsetof(PathParameterfCHROMIUM, path) == 4, + "offset of PathParameterfCHROMIUM path should be 4"); +static_assert(offsetof(PathParameterfCHROMIUM, pname) == 8, + "offset of PathParameterfCHROMIUM pname should be 8"); +static_assert(offsetof(PathParameterfCHROMIUM, value) == 12, + "offset of PathParameterfCHROMIUM value should be 12"); + +struct PathParameteriCHROMIUM { + typedef PathParameteriCHROMIUM ValueType; + static const CommandId kCmdId = kPathParameteriCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _path, GLenum _pname, GLint _value) { + SetHeader(); + path = _path; + pname = _pname; + value = _value; + } + + void* Set(void* cmd, GLuint _path, GLenum _pname, GLint _value) { + static_cast<ValueType*>(cmd)->Init(_path, _pname, _value); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t path; + uint32_t pname; + int32_t value; +}; + +static_assert(sizeof(PathParameteriCHROMIUM) == 16, + "size of PathParameteriCHROMIUM should be 16"); +static_assert(offsetof(PathParameteriCHROMIUM, header) == 0, + "offset of PathParameteriCHROMIUM header should be 0"); +static_assert(offsetof(PathParameteriCHROMIUM, path) == 4, + "offset of PathParameteriCHROMIUM path should be 4"); +static_assert(offsetof(PathParameteriCHROMIUM, pname) == 8, + "offset of PathParameteriCHROMIUM pname should be 8"); +static_assert(offsetof(PathParameteriCHROMIUM, value) == 12, + "offset of PathParameteriCHROMIUM value should be 12"); + +struct PathStencilFuncCHROMIUM { + typedef PathStencilFuncCHROMIUM ValueType; + static const CommandId kCmdId = kPathStencilFuncCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLenum _func, GLint _ref, GLuint _mask) { + SetHeader(); + func = _func; + ref = _ref; + mask = _mask; + } + + void* Set(void* cmd, GLenum _func, GLint _ref, GLuint _mask) { + static_cast<ValueType*>(cmd)->Init(_func, _ref, _mask); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t func; + int32_t ref; + uint32_t mask; +}; + +static_assert(sizeof(PathStencilFuncCHROMIUM) == 16, + "size of PathStencilFuncCHROMIUM should be 16"); +static_assert(offsetof(PathStencilFuncCHROMIUM, header) == 0, + "offset of PathStencilFuncCHROMIUM header should be 0"); +static_assert(offsetof(PathStencilFuncCHROMIUM, func) == 4, + "offset of PathStencilFuncCHROMIUM func should be 4"); +static_assert(offsetof(PathStencilFuncCHROMIUM, ref) == 8, + "offset of PathStencilFuncCHROMIUM ref should be 8"); +static_assert(offsetof(PathStencilFuncCHROMIUM, mask) == 12, + "offset of PathStencilFuncCHROMIUM mask should be 12"); + +struct StencilFillPathCHROMIUM { + typedef StencilFillPathCHROMIUM ValueType; + static const CommandId kCmdId = kStencilFillPathCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _path, GLenum _fillMode, GLuint _mask) { + SetHeader(); + path = _path; + fillMode = _fillMode; + mask = _mask; + } + + void* Set(void* cmd, GLuint _path, GLenum _fillMode, GLuint _mask) { + static_cast<ValueType*>(cmd)->Init(_path, _fillMode, _mask); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t path; + uint32_t fillMode; + uint32_t mask; +}; + +static_assert(sizeof(StencilFillPathCHROMIUM) == 16, + "size of StencilFillPathCHROMIUM should be 16"); +static_assert(offsetof(StencilFillPathCHROMIUM, header) == 0, + "offset of StencilFillPathCHROMIUM header should be 0"); +static_assert(offsetof(StencilFillPathCHROMIUM, path) == 4, + "offset of StencilFillPathCHROMIUM path should be 4"); +static_assert(offsetof(StencilFillPathCHROMIUM, fillMode) == 8, + "offset of StencilFillPathCHROMIUM fillMode should be 8"); +static_assert(offsetof(StencilFillPathCHROMIUM, mask) == 12, + "offset of StencilFillPathCHROMIUM mask should be 12"); + +struct StencilStrokePathCHROMIUM { + typedef StencilStrokePathCHROMIUM ValueType; + static const CommandId kCmdId = kStencilStrokePathCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _path, GLint _reference, GLuint _mask) { + SetHeader(); + path = _path; + reference = _reference; + mask = _mask; + } + + void* Set(void* cmd, GLuint _path, GLint _reference, GLuint _mask) { + static_cast<ValueType*>(cmd)->Init(_path, _reference, _mask); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t path; + int32_t reference; + uint32_t mask; +}; + +static_assert(sizeof(StencilStrokePathCHROMIUM) == 16, + "size of StencilStrokePathCHROMIUM should be 16"); +static_assert(offsetof(StencilStrokePathCHROMIUM, header) == 0, + "offset of StencilStrokePathCHROMIUM header should be 0"); +static_assert(offsetof(StencilStrokePathCHROMIUM, path) == 4, + "offset of StencilStrokePathCHROMIUM path should be 4"); +static_assert(offsetof(StencilStrokePathCHROMIUM, reference) == 8, + "offset of StencilStrokePathCHROMIUM reference should be 8"); +static_assert(offsetof(StencilStrokePathCHROMIUM, mask) == 12, + "offset of StencilStrokePathCHROMIUM mask should be 12"); + +struct CoverFillPathCHROMIUM { + typedef CoverFillPathCHROMIUM ValueType; + static const CommandId kCmdId = kCoverFillPathCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _path, GLenum _coverMode) { + SetHeader(); + path = _path; + coverMode = _coverMode; + } + + void* Set(void* cmd, GLuint _path, GLenum _coverMode) { + static_cast<ValueType*>(cmd)->Init(_path, _coverMode); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t path; + uint32_t coverMode; +}; + +static_assert(sizeof(CoverFillPathCHROMIUM) == 12, + "size of CoverFillPathCHROMIUM should be 12"); +static_assert(offsetof(CoverFillPathCHROMIUM, header) == 0, + "offset of CoverFillPathCHROMIUM header should be 0"); +static_assert(offsetof(CoverFillPathCHROMIUM, path) == 4, + "offset of CoverFillPathCHROMIUM path should be 4"); +static_assert(offsetof(CoverFillPathCHROMIUM, coverMode) == 8, + "offset of CoverFillPathCHROMIUM coverMode should be 8"); + +struct CoverStrokePathCHROMIUM { + typedef CoverStrokePathCHROMIUM ValueType; + static const CommandId kCmdId = kCoverStrokePathCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _path, GLenum _coverMode) { + SetHeader(); + path = _path; + coverMode = _coverMode; + } + + void* Set(void* cmd, GLuint _path, GLenum _coverMode) { + static_cast<ValueType*>(cmd)->Init(_path, _coverMode); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t path; + uint32_t coverMode; +}; + +static_assert(sizeof(CoverStrokePathCHROMIUM) == 12, + "size of CoverStrokePathCHROMIUM should be 12"); +static_assert(offsetof(CoverStrokePathCHROMIUM, header) == 0, + "offset of CoverStrokePathCHROMIUM header should be 0"); +static_assert(offsetof(CoverStrokePathCHROMIUM, path) == 4, + "offset of CoverStrokePathCHROMIUM path should be 4"); +static_assert(offsetof(CoverStrokePathCHROMIUM, coverMode) == 8, + "offset of CoverStrokePathCHROMIUM coverMode should be 8"); + +struct StencilThenCoverFillPathCHROMIUM { + typedef StencilThenCoverFillPathCHROMIUM ValueType; + static const CommandId kCmdId = kStencilThenCoverFillPathCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _path, GLenum _fillMode, GLuint _mask, GLenum _coverMode) { + SetHeader(); + path = _path; + fillMode = _fillMode; + mask = _mask; + coverMode = _coverMode; + } + + void* Set(void* cmd, + GLuint _path, + GLenum _fillMode, + GLuint _mask, + GLenum _coverMode) { + static_cast<ValueType*>(cmd)->Init(_path, _fillMode, _mask, _coverMode); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t path; + uint32_t fillMode; + uint32_t mask; + uint32_t coverMode; +}; + +static_assert(sizeof(StencilThenCoverFillPathCHROMIUM) == 20, + "size of StencilThenCoverFillPathCHROMIUM should be 20"); +static_assert(offsetof(StencilThenCoverFillPathCHROMIUM, header) == 0, + "offset of StencilThenCoverFillPathCHROMIUM header should be 0"); +static_assert(offsetof(StencilThenCoverFillPathCHROMIUM, path) == 4, + "offset of StencilThenCoverFillPathCHROMIUM path should be 4"); +static_assert( + offsetof(StencilThenCoverFillPathCHROMIUM, fillMode) == 8, + "offset of StencilThenCoverFillPathCHROMIUM fillMode should be 8"); +static_assert(offsetof(StencilThenCoverFillPathCHROMIUM, mask) == 12, + "offset of StencilThenCoverFillPathCHROMIUM mask should be 12"); +static_assert( + offsetof(StencilThenCoverFillPathCHROMIUM, coverMode) == 16, + "offset of StencilThenCoverFillPathCHROMIUM coverMode should be 16"); + +struct StencilThenCoverStrokePathCHROMIUM { + typedef StencilThenCoverStrokePathCHROMIUM ValueType; + static const CommandId kCmdId = kStencilThenCoverStrokePathCHROMIUM; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize() { + return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { header.SetCmd<ValueType>(); } + + void Init(GLuint _path, GLint _reference, GLuint _mask, GLenum _coverMode) { + SetHeader(); + path = _path; + reference = _reference; + mask = _mask; + coverMode = _coverMode; + } + + void* Set(void* cmd, + GLuint _path, + GLint _reference, + GLuint _mask, + GLenum _coverMode) { + static_cast<ValueType*>(cmd)->Init(_path, _reference, _mask, _coverMode); + return NextCmdAddress<ValueType>(cmd); + } + + gpu::CommandHeader header; + uint32_t path; + int32_t reference; + uint32_t mask; + uint32_t coverMode; +}; + +static_assert(sizeof(StencilThenCoverStrokePathCHROMIUM) == 20, + "size of StencilThenCoverStrokePathCHROMIUM should be 20"); +static_assert( + offsetof(StencilThenCoverStrokePathCHROMIUM, header) == 0, + "offset of StencilThenCoverStrokePathCHROMIUM header should be 0"); +static_assert(offsetof(StencilThenCoverStrokePathCHROMIUM, path) == 4, + "offset of StencilThenCoverStrokePathCHROMIUM path should be 4"); +static_assert( + offsetof(StencilThenCoverStrokePathCHROMIUM, reference) == 8, + "offset of StencilThenCoverStrokePathCHROMIUM reference should be 8"); +static_assert(offsetof(StencilThenCoverStrokePathCHROMIUM, mask) == 12, + "offset of StencilThenCoverStrokePathCHROMIUM mask should be 12"); +static_assert( + offsetof(StencilThenCoverStrokePathCHROMIUM, coverMode) == 16, + "offset of StencilThenCoverStrokePathCHROMIUM coverMode should be 16"); + struct BlendBarrierKHR { typedef BlendBarrierKHR ValueType; static const CommandId kCmdId = kBlendBarrierKHR; diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index cb4145a6..b6b81be 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -4887,6 +4887,195 @@ TEST_F(GLES2FormatTest, MatrixLoadIdentityCHROMIUM) { CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } +TEST_F(GLES2FormatTest, GenPathsCHROMIUM) { + cmds::GenPathsCHROMIUM& cmd = *GetBufferAs<cmds::GenPathsCHROMIUM>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLsizei>(12)); + EXPECT_EQ(static_cast<uint32_t>(cmds::GenPathsCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.first_client_id); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.range); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, DeletePathsCHROMIUM) { + cmds::DeletePathsCHROMIUM& cmd = *GetBufferAs<cmds::DeletePathsCHROMIUM>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLsizei>(12)); + EXPECT_EQ(static_cast<uint32_t>(cmds::DeletePathsCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.first_client_id); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.range); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, IsPathCHROMIUM) { + cmds::IsPathCHROMIUM& cmd = *GetBufferAs<cmds::IsPathCHROMIUM>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<uint32_t>(12), + static_cast<uint32_t>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::IsPathCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.path); + EXPECT_EQ(static_cast<uint32_t>(12), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.result_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, PathCommandsCHROMIUM) { + cmds::PathCommandsCHROMIUM& cmd = *GetBufferAs<cmds::PathCommandsCHROMIUM>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLsizei>(12), + static_cast<uint32_t>(13), static_cast<uint32_t>(14), + static_cast<GLsizei>(15), static_cast<GLenum>(16), + static_cast<uint32_t>(17), static_cast<uint32_t>(18)); + EXPECT_EQ(static_cast<uint32_t>(cmds::PathCommandsCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.path); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.numCommands); + EXPECT_EQ(static_cast<uint32_t>(13), cmd.commands_shm_id); + EXPECT_EQ(static_cast<uint32_t>(14), cmd.commands_shm_offset); + EXPECT_EQ(static_cast<GLsizei>(15), cmd.numCoords); + EXPECT_EQ(static_cast<GLenum>(16), cmd.coordType); + EXPECT_EQ(static_cast<uint32_t>(17), cmd.coords_shm_id); + EXPECT_EQ(static_cast<uint32_t>(18), cmd.coords_shm_offset); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, PathParameterfCHROMIUM) { + cmds::PathParameterfCHROMIUM& cmd = + *GetBufferAs<cmds::PathParameterfCHROMIUM>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), + static_cast<GLenum>(12), static_cast<GLfloat>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::PathParameterfCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.path); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<GLfloat>(13), cmd.value); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, PathParameteriCHROMIUM) { + cmds::PathParameteriCHROMIUM& cmd = + *GetBufferAs<cmds::PathParameteriCHROMIUM>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), + static_cast<GLenum>(12), static_cast<GLint>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::PathParameteriCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.path); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<GLint>(13), cmd.value); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, PathStencilFuncCHROMIUM) { + cmds::PathStencilFuncCHROMIUM& cmd = + *GetBufferAs<cmds::PathStencilFuncCHROMIUM>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11), + static_cast<GLint>(12), static_cast<GLuint>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::PathStencilFuncCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLenum>(11), cmd.func); + EXPECT_EQ(static_cast<GLint>(12), cmd.ref); + EXPECT_EQ(static_cast<GLuint>(13), cmd.mask); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, StencilFillPathCHROMIUM) { + cmds::StencilFillPathCHROMIUM& cmd = + *GetBufferAs<cmds::StencilFillPathCHROMIUM>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), + static_cast<GLenum>(12), static_cast<GLuint>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::StencilFillPathCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.path); + EXPECT_EQ(static_cast<GLenum>(12), cmd.fillMode); + EXPECT_EQ(static_cast<GLuint>(13), cmd.mask); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, StencilStrokePathCHROMIUM) { + cmds::StencilStrokePathCHROMIUM& cmd = + *GetBufferAs<cmds::StencilStrokePathCHROMIUM>(); + void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11), + static_cast<GLint>(12), static_cast<GLuint>(13)); + EXPECT_EQ(static_cast<uint32_t>(cmds::StencilStrokePathCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.path); + EXPECT_EQ(static_cast<GLint>(12), cmd.reference); + EXPECT_EQ(static_cast<GLuint>(13), cmd.mask); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, CoverFillPathCHROMIUM) { + cmds::CoverFillPathCHROMIUM& cmd = + *GetBufferAs<cmds::CoverFillPathCHROMIUM>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLenum>(12)); + EXPECT_EQ(static_cast<uint32_t>(cmds::CoverFillPathCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.path); + EXPECT_EQ(static_cast<GLenum>(12), cmd.coverMode); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, CoverStrokePathCHROMIUM) { + cmds::CoverStrokePathCHROMIUM& cmd = + *GetBufferAs<cmds::CoverStrokePathCHROMIUM>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLenum>(12)); + EXPECT_EQ(static_cast<uint32_t>(cmds::CoverStrokePathCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.path); + EXPECT_EQ(static_cast<GLenum>(12), cmd.coverMode); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, StencilThenCoverFillPathCHROMIUM) { + cmds::StencilThenCoverFillPathCHROMIUM& cmd = + *GetBufferAs<cmds::StencilThenCoverFillPathCHROMIUM>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLenum>(12), + static_cast<GLuint>(13), static_cast<GLenum>(14)); + EXPECT_EQ( + static_cast<uint32_t>(cmds::StencilThenCoverFillPathCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.path); + EXPECT_EQ(static_cast<GLenum>(12), cmd.fillMode); + EXPECT_EQ(static_cast<GLuint>(13), cmd.mask); + EXPECT_EQ(static_cast<GLenum>(14), cmd.coverMode); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + +TEST_F(GLES2FormatTest, StencilThenCoverStrokePathCHROMIUM) { + cmds::StencilThenCoverStrokePathCHROMIUM& cmd = + *GetBufferAs<cmds::StencilThenCoverStrokePathCHROMIUM>(); + void* next_cmd = + cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLint>(12), + static_cast<GLuint>(13), static_cast<GLenum>(14)); + EXPECT_EQ( + static_cast<uint32_t>(cmds::StencilThenCoverStrokePathCHROMIUM::kCmdId), + cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.path); + EXPECT_EQ(static_cast<GLint>(12), cmd.reference); + EXPECT_EQ(static_cast<GLuint>(13), cmd.mask); + EXPECT_EQ(static_cast<GLenum>(14), cmd.coverMode); + CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); +} + TEST_F(GLES2FormatTest, BlendBarrierKHR) { cmds::BlendBarrierKHR& cmd = *GetBufferAs<cmds::BlendBarrierKHR>(); void* next_cmd = cmd.Set(&cmd); diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 4a3a3d6..4661ac8 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -302,7 +302,20 @@ OP(SwapInterval) /* 543 */ \ OP(MatrixLoadfCHROMIUMImmediate) /* 544 */ \ OP(MatrixLoadIdentityCHROMIUM) /* 545 */ \ - OP(BlendBarrierKHR) /* 546 */ + OP(GenPathsCHROMIUM) /* 546 */ \ + OP(DeletePathsCHROMIUM) /* 547 */ \ + OP(IsPathCHROMIUM) /* 548 */ \ + OP(PathCommandsCHROMIUM) /* 549 */ \ + OP(PathParameterfCHROMIUM) /* 550 */ \ + OP(PathParameteriCHROMIUM) /* 551 */ \ + OP(PathStencilFuncCHROMIUM) /* 552 */ \ + OP(StencilFillPathCHROMIUM) /* 553 */ \ + OP(StencilStrokePathCHROMIUM) /* 554 */ \ + OP(CoverFillPathCHROMIUM) /* 555 */ \ + OP(CoverStrokePathCHROMIUM) /* 556 */ \ + OP(StencilThenCoverFillPathCHROMIUM) /* 557 */ \ + OP(StencilThenCoverStrokePathCHROMIUM) /* 558 */ \ + OP(BlendBarrierKHR) /* 559 */ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this. diff --git a/gpu/command_buffer/common/gles2_cmd_utils.cc b/gpu/command_buffer/common/gles2_cmd_utils.cc index 7a33ab1..1471456 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils.cc +++ b/gpu/command_buffer/common/gles2_cmd_utils.cc @@ -702,6 +702,23 @@ size_t GLES2Util::GetGLTypeSizeForTexturesAndBuffers(uint32 type) { } } +size_t GLES2Util::GetGLTypeSizeForPathCoordType(uint32 type) { + switch (type) { + case GL_BYTE: + return sizeof(GLbyte); // NOLINT + case GL_UNSIGNED_BYTE: + return sizeof(GLubyte); // NOLINT + case GL_SHORT: + return sizeof(GLshort); // NOLINT + case GL_UNSIGNED_SHORT: + return sizeof(GLushort); // NOLINT + case GL_FLOAT: + return sizeof(GLfloat); // NOLINT + default: + return 0; + } +} + uint32 GLES2Util::GLErrorToErrorBit(uint32 error) { switch (error) { case GL_INVALID_ENUM: diff --git a/gpu/command_buffer/common/gles2_cmd_utils.h b/gpu/command_buffer/common/gles2_cmd_utils.h index 12b1551..4946205 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils.h +++ b/gpu/command_buffer/common/gles2_cmd_utils.h @@ -127,6 +127,8 @@ class GLES2_UTILS_EXPORT GLES2Util { static size_t GetGLTypeSizeForTexturesAndBuffers(uint32_t type); + static size_t GetGLTypeSizeForPathCoordType(uint32_t type); + static uint32_t GLErrorToErrorBit(uint32_t gl_error); static uint32_t GLErrorBitToGLError(uint32_t error_bit); diff --git a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h index 6e3d161..0099155 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h @@ -46,6 +46,10 @@ static std::string GetStringInternalFormatParameter(uint32_t value); static std::string GetStringInvalidateFrameBufferTarget(uint32_t value); static std::string GetStringMapBufferAccess(uint32_t value); static std::string GetStringMatrixMode(uint32_t value); +static std::string GetStringPathCoordType(uint32_t value); +static std::string GetStringPathCoverMode(uint32_t value); +static std::string GetStringPathFillMode(uint32_t value); +static std::string GetStringPathParameter(uint32_t value); static std::string GetStringPixelStore(uint32_t value); static std::string GetStringPixelType(uint32_t value); static std::string GetStringProgramParameter(uint32_t value); diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index 3dd31ca..6b061d4 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h @@ -141,6 +141,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_SHADER_BINARY_VIV", }, { + 0x90A7, + "GL_MITER_REVERT_CHROMIUM", + }, + { 0x9130, "GL_SGX_PROGRAM_BINARY_IMG", }, @@ -581,6 +585,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL", }, { + 0x90a4, + "GL_ROUND_CHROMIUM", + }, + { 0x8A48, "GL_TEXTURE_SRGB_DECODE_EXT", }, @@ -589,6 +597,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_CONTEXT_LOST", }, { + 0x90a3, + "GL_SQUARE_CHROMIUM", + }, + { 0x02000000, "GL_MULTISAMPLE_BUFFER_BIT1_QCOM", }, @@ -749,6 +761,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_RENDERBUFFER", }, { + 0x90B7, + "GL_PATH_STENCIL_FUNC_CHROMIUM", + }, + { 0x8A3A, "GL_UNIFORM_BLOCK_INDEX", }, @@ -761,10 +777,22 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_DITHER", }, { + 0x90B9, + "GL_PATH_STENCIL_VALUE_MASK_CHROMIUM", + }, + { + 0x90B8, + "GL_PATH_STENCIL_REF_CHROMIUM", + }, + { 0x93D3, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR", }, { + 0x1D00, + "GL_FLAT_CHROMIUM", + }, + { 0x9144, "GL_MAX_DEBUG_LOGGED_MESSAGES_KHR", }, @@ -981,6 +1009,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_UNSIGNED_INT_24_8_OES", }, { + 0x0A, + "GL_QUADRATIC_CURVE_TO_CHROMIUM", + }, + { 0x92D4, "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT", }, @@ -1085,6 +1117,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_SAMPLE_COVERAGE", }, { + 0x0C, + "GL_CUBIC_CURVE_TO_CHROMIUM", + }, + { 0x928F, "GL_DST_ATOP_NV", }, @@ -1629,6 +1665,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_BGRA_EXT", }, { + 0x908B, + "GL_CONVEX_HULL_CHROMIUM", + }, + { 0x8ED7, "GL_COVERAGE_AUTOMATIC_NV", }, @@ -1889,6 +1929,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT", }, { + 0x04, + "GL_LINE_TO_CHROMIUM", + }, + { 0x0BE2, "GL_BLEND", }, @@ -1949,10 +1993,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_LINEARLIGHT_NV", }, { + 0x00, + "GL_CLOSE_PATH_CHROMIUM", + }, + { 0x8DCF, "GL_INT_SAMPLER_2D_ARRAY", }, { + 0x02, + "GL_MOVE_TO_CHROMIUM", + }, + { 0x886A, "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED", }, @@ -1961,10 +2013,22 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_SRGB8_NV", }, { + 0x9079, + "GL_PATH_JOIN_STYLE_CHROMIUM", + }, + { 0x0C01, "GL_DRAW_BUFFER_EXT", }, { + 0x9075, + "GL_PATH_STROKE_WIDTH_CHROMIUM", + }, + { + 0x9076, + "GL_PATH_END_CAPS_CHROMIUM", + }, + { 0x886C, "GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT", }, @@ -2477,8 +2541,8 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_TEXTURE10", }, { - 0x0BA7, - "GL_PATH_PROJECTION_MATRIX_CHROMIUM", + 0x78F1, + "GL_MAP_CHROMIUM", }, { 0x84CF, @@ -3057,6 +3121,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_TEXTURE4", }, { + 0x1A, + "GL_CONIC_CURVE_TO_CHROMIUM", + }, + { 0x821C, "GL_MINOR_VERSION", }, @@ -3261,6 +3329,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_UNSIGNED_INT_VEC3", }, { + 0x90A6, + "GL_BEVEL_CHROMIUM", + }, + { 0x1701, "GL_PATH_PROJECTION_CHROMIUM", }, @@ -3393,6 +3465,14 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_BUFFER_MAP_OFFSET", }, { + 0x9089, + "GL_COUNT_DOWN_CHROMIUM", + }, + { + 0x9088, + "GL_COUNT_UP_CHROMIUM", + }, + { 0x00004000, "GL_COLOR_BUFFER_BIT", }, @@ -3473,6 +3553,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_FENCE_STATUS_NV", }, { + 0x908D, + "GL_BOUNDING_BOX_CHROMIUM", + }, + { 0x88E6, "GL_STATIC_COPY", }, @@ -3589,6 +3673,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_UNIFORM_BUFFER_SIZE", }, { + 0x0BA7, + "GL_PATH_PROJECTION_MATRIX_CHROMIUM", + }, + { 0x0DE1, "GL_TEXTURE_2D", }, @@ -3677,6 +3765,10 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_R8UI", }, { + 0x90A4, + "GL_ROUND_CHROMIUM", + }, + { 0x150A, "GL_INVERT", }, @@ -4141,10 +4233,18 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_VERTEX_ATTRIB_ARRAY_SIZE", }, { + 0x9086, + "GL_PATH_STROKE_BOUND_CHROMIUM", + }, + { 0x8DB9, "GL_FRAMEBUFFER_SRGB_EXT", }, { + 0x907a, + "GL_PATH_MITER_LIMIT_CHROMIUM", + }, + { 0x9307, "GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT", }, @@ -4373,10 +4473,6 @@ static const GLES2Util::EnumToString enum_to_string_table[] = { "GL_WRITEONLY_RENDERING_QCOM", }, { - 0x78F1, - "GL_MAP_CHROMIUM", - }, - { 0x8824, "GL_MAX_DRAW_BUFFERS_EXT", }, @@ -5034,6 +5130,49 @@ std::string GLES2Util::GetStringMatrixMode(uint32_t value) { arraysize(string_table), value); } +std::string GLES2Util::GetStringPathCoordType(uint32_t value) { + static const EnumToString string_table[] = { + {GL_BYTE, "GL_BYTE"}, + {GL_UNSIGNED_BYTE, "GL_UNSIGNED_BYTE"}, + {GL_SHORT, "GL_SHORT"}, + {GL_UNSIGNED_SHORT, "GL_UNSIGNED_SHORT"}, + {GL_FLOAT, "GL_FLOAT"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringPathCoverMode(uint32_t value) { + static const EnumToString string_table[] = { + {GL_CONVEX_HULL_CHROMIUM, "GL_CONVEX_HULL_CHROMIUM"}, + {GL_BOUNDING_BOX_CHROMIUM, "GL_BOUNDING_BOX_CHROMIUM"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringPathFillMode(uint32_t value) { + static const EnumToString string_table[] = { + {GL_INVERT, "GL_INVERT"}, + {GL_COUNT_UP_CHROMIUM, "GL_COUNT_UP_CHROMIUM"}, + {GL_COUNT_DOWN_CHROMIUM, "GL_COUNT_DOWN_CHROMIUM"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + +std::string GLES2Util::GetStringPathParameter(uint32_t value) { + static const EnumToString string_table[] = { + {GL_PATH_STROKE_WIDTH_CHROMIUM, "GL_PATH_STROKE_WIDTH_CHROMIUM"}, + {GL_PATH_END_CAPS_CHROMIUM, "GL_PATH_END_CAPS_CHROMIUM"}, + {GL_PATH_JOIN_STYLE_CHROMIUM, "GL_PATH_JOIN_STYLE_CHROMIUM"}, + {GL_PATH_MITER_LIMIT_CHROMIUM, "GL_PATH_MITER_LIMIT_CHROMIUM"}, + {GL_PATH_STROKE_BOUND_CHROMIUM, "GL_PATH_STROKE_BOUND_CHROMIUM"}, + }; + return GLES2Util::GetQualifiedEnumString(string_table, + arraysize(string_table), value); +} + std::string GLES2Util::GetStringPixelStore(uint32_t value) { static const EnumToString string_table[] = { {GL_PACK_ALIGNMENT, "GL_PACK_ALIGNMENT"}, diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn index 14f2402..62fce76 100644 --- a/gpu/command_buffer/service/BUILD.gn +++ b/gpu/command_buffer/service/BUILD.gn @@ -100,6 +100,8 @@ source_set("service_sources") { "mailbox_manager_sync.h", "memory_program_cache.cc", "memory_program_cache.h", + "path_manager.cc", + "path_manager.h", "program_cache.cc", "program_cache.h", "program_manager.cc", diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc index 4a82c56..1cc8f24 100644 --- a/gpu/command_buffer/service/context_group.cc +++ b/gpu/command_buffer/service/context_group.cc @@ -16,6 +16,7 @@ #include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/mailbox_manager_impl.h" #include "gpu/command_buffer/service/memory_tracking.h" +#include "gpu/command_buffer/service/path_manager.h" #include "gpu/command_buffer/service/program_manager.h" #include "gpu/command_buffer/service/renderbuffer_manager.h" #include "gpu/command_buffer/service/shader_manager.h" @@ -294,6 +295,8 @@ bool ContextGroup::Initialize( feature_info_->workarounds().max_vertex_uniform_vectors)); } + path_manager_.reset(new PathManager()); + program_manager_.reset(new ProgramManager( program_cache_, max_varying_vectors_)); @@ -365,6 +368,11 @@ void ContextGroup::Destroy(GLES2Decoder* decoder, bool have_context) { texture_manager_.reset(); } + if (path_manager_ != NULL) { + path_manager_->Destroy(have_context); + path_manager_.reset(); + } + if (program_manager_ != NULL) { program_manager_->Destroy(have_context); program_manager_.reset(); diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h index 466f918..32dbbf3 100644 --- a/gpu/command_buffer/service/context_group.h +++ b/gpu/command_buffer/service/context_group.h @@ -32,6 +32,7 @@ class GLES2Decoder; class FramebufferManager; class MailboxManager; class RenderbufferManager; +class PathManager; class ProgramManager; class ShaderManager; class TextureManager; @@ -153,6 +154,8 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { return texture_manager_.get(); } + PathManager* path_manager() const { return path_manager_.get(); } + ProgramManager* program_manager() const { return program_manager_.get(); } @@ -291,6 +294,8 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> { scoped_ptr<TextureManager> texture_manager_; + scoped_ptr<PathManager> path_manager_; + scoped_ptr<ProgramManager> program_manager_; scoped_ptr<ShaderManager> shader_manager_; diff --git a/gpu/command_buffer/service/context_state_autogen.h b/gpu/command_buffer/service/context_state_autogen.h index e2b65bf..7ca2faa 100644 --- a/gpu/command_buffer/service/context_state_autogen.h +++ b/gpu/command_buffer/service/context_state_autogen.h @@ -74,6 +74,9 @@ GLenum hint_fragment_shader_derivative; GLfloat line_width; GLfloat modelview_matrix[16]; GLfloat projection_matrix[16]; +GLenum stencil_path_func; +GLint stencil_path_ref; +GLuint stencil_path_mask; GLint pack_alignment; GLint unpack_alignment; GLfloat polygon_offset_factor; diff --git a/gpu/command_buffer/service/context_state_impl_autogen.h b/gpu/command_buffer/service/context_state_impl_autogen.h index fa5462f..2dde530 100644 --- a/gpu/command_buffer/service/context_state_impl_autogen.h +++ b/gpu/command_buffer/service/context_state_impl_autogen.h @@ -104,6 +104,9 @@ void ContextState::Initialize() { projection_matrix[13] = 0.0f; projection_matrix[14] = 0.0f; projection_matrix[15] = 1.0f; + stencil_path_func = GL_ALWAYS; + stencil_path_ref = 0; + stencil_path_mask = 0xFFFFFFFFU; pack_alignment = 4; unpack_alignment = 4; polygon_offset_factor = 0.0f; @@ -276,6 +279,12 @@ void ContextState::InitState(const ContextState* prev_state) const { glMatrixLoadfEXT(GL_PATH_PROJECTION_CHROMIUM, projection_matrix); } } + if (feature_info_->feature_flags().chromium_path_rendering) + if ((stencil_path_func != prev_state->stencil_path_func) || + (stencil_path_ref != prev_state->stencil_path_ref) || + (stencil_path_mask != prev_state->stencil_path_mask)) + glPathStencilFuncNV(stencil_path_func, stencil_path_ref, + stencil_path_mask); if (prev_state->pack_alignment != pack_alignment) { glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment); } @@ -355,6 +364,9 @@ void ContextState::InitState(const ContextState* prev_state) const { if (feature_info_->feature_flags().chromium_path_rendering) { glMatrixLoadfEXT(GL_PATH_PROJECTION_CHROMIUM, projection_matrix); } + if (feature_info_->feature_flags().chromium_path_rendering) + glPathStencilFuncNV(stencil_path_func, stencil_path_ref, + stencil_path_mask); glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment); glPixelStorei(GL_UNPACK_ALIGNMENT, unpack_alignment); glPolygonOffset(polygon_offset_factor, polygon_offset_units); @@ -547,6 +559,24 @@ bool ContextState::GetStateAsGLint(GLenum pname, } } return true; + case GL_PATH_STENCIL_FUNC_CHROMIUM: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_path_func); + } + return true; + case GL_PATH_STENCIL_REF_CHROMIUM: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_path_ref); + } + return true; + case GL_PATH_STENCIL_VALUE_MASK_CHROMIUM: + *num_written = 1; + if (params) { + params[0] = static_cast<GLint>(stencil_path_mask); + } + return true; case GL_PACK_ALIGNMENT: *num_written = 1; if (params) { @@ -897,6 +927,24 @@ bool ContextState::GetStateAsGLfloat(GLenum pname, memcpy(params, projection_matrix, sizeof(GLfloat) * 16); } return true; + case GL_PATH_STENCIL_FUNC_CHROMIUM: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_path_func); + } + return true; + case GL_PATH_STENCIL_REF_CHROMIUM: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_path_ref); + } + return true; + case GL_PATH_STENCIL_VALUE_MASK_CHROMIUM: + *num_written = 1; + if (params) { + params[0] = static_cast<GLfloat>(stencil_path_mask); + } + return true; case GL_PACK_ALIGNMENT: *num_written = 1; if (params) { diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index 0ce9980..8caf05c 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc @@ -209,6 +209,9 @@ void FeatureInfo::InitializeBasicState(const base::CommandLine& command_line) { enable_unsafe_es3_apis_switch_ = command_line.HasSwitch(switches::kEnableUnsafeES3APIs); + enable_gl_path_rendering_switch_ = + command_line.HasSwitch(switches::kEnableGLPathRendering); + unsafe_es3_apis_enabled_ = false; } @@ -1004,14 +1007,18 @@ void FeatureInfo::InitializeFeatures() { } } - if (extensions.Contains("GL_NV_path_rendering")) { - if (extensions.Contains("GL_EXT_direct_state_access") || - gl_version_info_->is_es3) { - AddExtensionString("GL_CHROMIUM_path_rendering"); - feature_flags_.chromium_path_rendering = true; - validators_.g_l_state.AddValue(GL_PATH_MODELVIEW_MATRIX_CHROMIUM); - validators_.g_l_state.AddValue(GL_PATH_PROJECTION_MATRIX_CHROMIUM); - } + if (enable_gl_path_rendering_switch_ && + !workarounds_.disable_gl_path_rendering && + extensions.Contains("GL_NV_path_rendering") && + (extensions.Contains("GL_EXT_direct_state_access") || + gl_version_info_->is_es3)) { + AddExtensionString("GL_CHROMIUM_path_rendering"); + feature_flags_.chromium_path_rendering = true; + validators_.g_l_state.AddValue(GL_PATH_MODELVIEW_MATRIX_CHROMIUM); + validators_.g_l_state.AddValue(GL_PATH_PROJECTION_MATRIX_CHROMIUM); + validators_.g_l_state.AddValue(GL_PATH_STENCIL_FUNC_CHROMIUM); + validators_.g_l_state.AddValue(GL_PATH_STENCIL_REF_CHROMIUM); + validators_.g_l_state.AddValue(GL_PATH_STENCIL_VALUE_MASK_CHROMIUM); } if ((gl_version_info_->is_es3 || gl_version_info_->is_desktop_core_profile || diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h index 1ebff2a..aa9c0ba 100644 --- a/gpu/command_buffer/service/feature_info.h +++ b/gpu/command_buffer/service/feature_info.h @@ -164,6 +164,9 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> { bool unsafe_es3_apis_enabled_; + // Whether the command line switch kEnableGLPathRendering is passed in. + bool enable_gl_path_rendering_switch_; + scoped_ptr<gfx::GLVersionInfo> gl_version_info_; DISALLOW_COPY_AND_ASSIGN(FeatureInfo); diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc index fdff175..8321e68 100644 --- a/gpu/command_buffer/service/feature_info_unittest.cc +++ b/gpu/command_buffer/service/feature_info_unittest.cc @@ -8,6 +8,7 @@ #include "base/memory/scoped_ptr.h" #include "base/strings/string_number_conversions.h" #include "gpu/command_buffer/service/gpu_service_test.h" +#include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/test_helper.h" #include "gpu/command_buffer/service/texture_manager.h" #include "gpu/config/gpu_driver_bug_workaround_type.h" @@ -77,6 +78,18 @@ class FeatureInfoTest info_->Initialize(); } + void SetupInitExpectationsWithGLVersionAndCommandLine( + const char* extensions, + const char* renderer, + const char* version, + const base::CommandLine& command_line) { + GpuServiceTest::SetUpWithGLVersion(version, extensions); + TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion( + gl_.get(), extensions, renderer, version); + info_ = new FeatureInfo(command_line); + info_->Initialize(); + } + void SetupWithCommandLine(const base::CommandLine& command_line) { GpuServiceTest::SetUp(); info_ = new FeatureInfo(command_line); @@ -1191,31 +1204,49 @@ TEST_P(FeatureInfoTest, BlendEquationAdvancedDisabled) { EXPECT_FALSE(info_->feature_flags().blend_equation_advanced_coherent); } -TEST_P(FeatureInfoTest, InitializeCHROMIUM_path_rendering) { +TEST_P(FeatureInfoTest, InitializeCHROMIUM_path_rendering_no_cmdline_switch) { SetupInitExpectationsWithGLVersion( "GL_ARB_compatibility GL_NV_path_rendering GL_EXT_direct_state_access", "", "4.3"); + EXPECT_FALSE(info_->feature_flags().chromium_path_rendering); + EXPECT_THAT(info_->extensions(), + Not(HasSubstr("GL_CHROMIUM_path_rendering"))); +} + +TEST_P(FeatureInfoTest, InitializeCHROMIUM_path_rendering) { + base::CommandLine command_line(0, NULL); + command_line.AppendSwitch(switches::kEnableGLPathRendering); + SetupInitExpectationsWithGLVersionAndCommandLine( + "GL_ARB_compatibility GL_NV_path_rendering GL_EXT_direct_state_access", + "", "4.3", command_line); EXPECT_TRUE(info_->feature_flags().chromium_path_rendering); EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_path_rendering")); } TEST_P(FeatureInfoTest, InitializeCHROMIUM_path_rendering2) { - SetupInitExpectationsWithGLVersion( - "GL_NV_path_rendering", "", "OpenGL ES 3.1"); + base::CommandLine command_line(0, NULL); + command_line.AppendSwitch(switches::kEnableGLPathRendering); + SetupInitExpectationsWithGLVersionAndCommandLine( + "GL_NV_path_rendering", "", "OpenGL ES 3.1", command_line); EXPECT_TRUE(info_->feature_flags().chromium_path_rendering); EXPECT_THAT(info_->extensions(), HasSubstr("GL_CHROMIUM_path_rendering")); } TEST_P(FeatureInfoTest, InitializeNoCHROMIUM_path_rendering) { - SetupInitExpectationsWithGLVersion("GL_ARB_compatibility", "", "4.3"); + base::CommandLine command_line(0, NULL); + command_line.AppendSwitch(switches::kEnableGLPathRendering); + SetupInitExpectationsWithGLVersionAndCommandLine("GL_ARB_compatibility", "", + "4.3", command_line); EXPECT_FALSE(info_->feature_flags().chromium_path_rendering); EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_CHROMIUM_path_rendering"))); } TEST_P(FeatureInfoTest, InitializeNoCHROMIUM_path_rendering2) { - SetupInitExpectationsWithGLVersion( - "GL_ARB_compatibility GL_NV_path_rendering", "", "4.3"); + base::CommandLine command_line(0, NULL); + command_line.AppendSwitch(switches::kEnableGLPathRendering); + SetupInitExpectationsWithGLVersionAndCommandLine( + "GL_ARB_compatibility GL_NV_path_rendering", "", "4.3", command_line); EXPECT_FALSE(info_->feature_flags().chromium_path_rendering); EXPECT_THAT(info_->extensions(), Not(HasSubstr("GL_CHROMIUM_path_rendering"))); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 4e35d55..3f70846 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -47,6 +47,7 @@ #include "gpu/command_buffer/service/logger.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/memory_tracking.h" +#include "gpu/command_buffer/service/path_manager.h" #include "gpu/command_buffer/service/program_manager.h" #include "gpu/command_buffer/service/query_manager.h" #include "gpu/command_buffer/service/renderbuffer_manager.h" @@ -791,6 +792,8 @@ class GLES2DecoderImpl : public GLES2Decoder, void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids); bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); + bool GenPathsCHROMIUMHelper(GLuint first_client_id, GLsizei range); + bool DeletePathsCHROMIUMHelper(GLuint first_client_id, GLsizei range); // Helper for async upload token completion notification callback. base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token, @@ -823,6 +826,8 @@ class GLES2DecoderImpl : public GLES2Decoder, return group_->valuebuffer_manager(); } + PathManager* path_manager() { return group_->path_manager(); } + ProgramManager* program_manager() { return group_->program_manager(); } @@ -1563,6 +1568,7 @@ class GLES2DecoderImpl : public GLES2Decoder, bool DoIsShader(GLuint client_id); bool DoIsTexture(GLuint client_id); bool DoIsVertexArrayOES(GLuint client_id); + bool DoIsPathCHROMIUM(GLuint client_id); // Wrapper for glLinkProgram void DoLinkProgram(GLuint program); @@ -3350,6 +3356,42 @@ bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) { return true; } +bool GLES2DecoderImpl::GenPathsCHROMIUMHelper(GLuint first_client_id, + GLsizei range) { + GLuint last_client_id; + if (!SafeAddUint32(first_client_id, range - 1, &last_client_id)) + return false; + + if (path_manager()->HasPathsInRange(first_client_id, last_client_id)) + return false; + + GLuint first_service_id = glGenPathsNV(range); + if (first_service_id == 0) { + // We have to fail the connection here, because client has already + // succeeded in allocating the ids. This happens if we allocate + // the whole path id space (two allocations of 0x7FFFFFFF paths, for + // example). + return false; + } + // GenPathsNV does not wrap. + DCHECK(first_service_id + range - 1 >= first_service_id); + + path_manager()->CreatePathRange(first_client_id, last_client_id, + first_service_id); + + return true; +} + +bool GLES2DecoderImpl::DeletePathsCHROMIUMHelper(GLuint first_client_id, + GLsizei range) { + GLuint last_client_id; + if (!SafeAddUint32(first_client_id, range - 1, &last_client_id)) + return false; + + path_manager()->RemovePaths(first_client_id, last_client_id); + return true; +} + void GLES2DecoderImpl::DeleteBuffersHelper( GLsizei n, const GLuint* client_ids) { for (GLsizei ii = 0; ii < n; ++ii) { @@ -11748,6 +11790,12 @@ bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) { return vao && vao->IsValid() && !vao->IsDeleted(); } +bool GLES2DecoderImpl::DoIsPathCHROMIUM(GLuint client_id) { + GLuint service_id = 0; + return path_manager()->GetPath(client_id, &service_id) && + glIsPathNV(service_id) == GL_TRUE; +} + #if defined(OS_MACOSX) void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) { TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find( @@ -13833,6 +13881,455 @@ void GLES2DecoderImpl::OnOutOfMemoryError() { } } +error::Error GLES2DecoderImpl::HandleGenPathsCHROMIUM( + uint32 immediate_data_size, + const void* cmd_data) { + static const char kFunctionName[] = "glGenPathsCHROMIUM"; + const gles2::cmds::GenPathsCHROMIUM& c = + *static_cast<const gles2::cmds::GenPathsCHROMIUM*>(cmd_data); + if (!features().chromium_path_rendering) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "function not available"); + return error::kNoError; + } + + GLsizei range = static_cast<GLsizei>(c.range); + if (range < 0) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "range < 0"); + return error::kNoError; + } + + GLuint first_client_id = static_cast<GLuint>(c.first_client_id); + if (first_client_id == 0) + return error::kInvalidArguments; + + if (range == 0) + return error::kNoError; + + if (!GenPathsCHROMIUMHelper(first_client_id, range)) + return error::kInvalidArguments; + + return error::kNoError; +} +error::Error GLES2DecoderImpl::HandleDeletePathsCHROMIUM( + uint32_t immediate_data_size, + const void* cmd_data) { + static const char kFunctionName[] = "glDeletePathsCHROMIUM"; + const gles2::cmds::DeletePathsCHROMIUM& c = + *static_cast<const gles2::cmds::DeletePathsCHROMIUM*>(cmd_data); + if (!features().chromium_path_rendering) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "function not available"); + return error::kNoError; + } + + GLsizei range = static_cast<GLsizei>(c.range); + if (range < 0) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "range < 0"); + return error::kNoError; + } + + if (range == 0) + return error::kNoError; + + GLuint first_client_id = c.first_client_id; + // first_client_id can be 0, because non-existing path ids are skipped. + + if (!DeletePathsCHROMIUMHelper(first_client_id, range)) + return error::kInvalidArguments; + + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandlePathCommandsCHROMIUM( + uint32 immediate_data_size, + const void* cmd_data) { + static const char kFunctionName[] = "glPathCommandsCHROMIUM"; + const gles2::cmds::PathCommandsCHROMIUM& c = + *static_cast<const gles2::cmds::PathCommandsCHROMIUM*>(cmd_data); + if (!features().chromium_path_rendering) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "function not available"); + return error::kNoError; + } + + GLuint service_id = 0; + if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "invalid path name"); + return error::kNoError; + } + + GLsizei num_commands = static_cast<GLsizei>(c.numCommands); + if (num_commands < 0) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "numCommands < 0"); + return error::kNoError; + } + + GLsizei num_coords = static_cast<uint32>(c.numCoords); + if (num_coords < 0) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "numCoords < 0"); + return error::kNoError; + } + + GLenum coord_type = static_cast<uint32>(c.coordType); + if (!validators_->path_coord_type.IsValid(static_cast<GLint>(coord_type))) { + LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, kFunctionName, "invalid coordType"); + return error::kNoError; + } + + const GLubyte* commands = NULL; + base::CheckedNumeric<GLsizei> num_coords_expected = 0; + + if (num_commands > 0) { + uint32 commands_shm_id = static_cast<uint32>(c.commands_shm_id); + uint32 commands_shm_offset = static_cast<uint32>(c.commands_shm_offset); + if (commands_shm_id != 0 || commands_shm_offset != 0) + commands = GetSharedMemoryAs<const GLubyte*>( + commands_shm_id, commands_shm_offset, num_commands); + + if (!commands) + return error::kOutOfBounds; + + for (GLsizei i = 0; i < num_commands; ++i) { + switch (commands[i]) { + case GL_CLOSE_PATH_CHROMIUM: + // Close has no coords. + break; + case GL_MOVE_TO_CHROMIUM: + // Fallthrough. + case GL_LINE_TO_CHROMIUM: + num_coords_expected += 2; + break; + case GL_QUADRATIC_CURVE_TO_CHROMIUM: + num_coords_expected += 4; + break; + case GL_CUBIC_CURVE_TO_CHROMIUM: + num_coords_expected += 6; + break; + case GL_CONIC_CURVE_TO_CHROMIUM: + num_coords_expected += 5; + break; + default: + LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, kFunctionName, "invalid command"); + return error::kNoError; + } + } + } + + if (!num_coords_expected.IsValid() || + num_coords != num_coords_expected.ValueOrDie()) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "numCoords does not match commands"); + return error::kNoError; + } + + const void* coords = NULL; + + if (num_coords > 0) { + uint32 coords_size = 0; + uint32 coord_type_size = + GLES2Util::GetGLTypeSizeForPathCoordType(coord_type); + if (!SafeMultiplyUint32(num_coords, coord_type_size, &coords_size)) + return error::kOutOfBounds; + + uint32 coords_shm_id = static_cast<uint32>(c.coords_shm_id); + uint32 coords_shm_offset = static_cast<uint32>(c.coords_shm_offset); + if (coords_shm_id != 0 || coords_shm_offset != 0) + coords = GetSharedMemoryAs<const void*>(coords_shm_id, coords_shm_offset, + coords_size); + + if (!coords) + return error::kOutOfBounds; + } + + glPathCommandsNV(service_id, num_commands, commands, num_coords, coord_type, + coords); + + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandlePathParameterfCHROMIUM( + uint32 immediate_data_size, + const void* cmd_data) { + static const char kFunctionName[] = "glPathParameterfCHROMIUM"; + const gles2::cmds::PathParameterfCHROMIUM& c = + *static_cast<const gles2::cmds::PathParameterfCHROMIUM*>(cmd_data); + if (!features().chromium_path_rendering) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "function not available"); + return error::kNoError; + } + GLuint service_id = 0; + if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "invalid path name"); + return error::kNoError; + } + + GLenum pname = static_cast<GLenum>(c.pname); + GLfloat value = static_cast<GLfloat>(c.value); + bool hasValueError = false; + + switch (pname) { + case GL_PATH_STROKE_WIDTH_CHROMIUM: + case GL_PATH_MITER_LIMIT_CHROMIUM: + hasValueError = std::isnan(value) || !std::isfinite(value) || value < 0; + break; + case GL_PATH_STROKE_BOUND_CHROMIUM: + value = std::max(std::min(1.0f, value), 0.0f); + break; + case GL_PATH_END_CAPS_CHROMIUM: + hasValueError = !validators_->path_parameter_cap_values.IsValid( + static_cast<GLint>(value)); + break; + case GL_PATH_JOIN_STYLE_CHROMIUM: + hasValueError = !validators_->path_parameter_join_values.IsValid( + static_cast<GLint>(value)); + break; + default: + DCHECK(!validators_->path_parameter.IsValid(pname)); + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, pname, "pname"); + return error::kNoError; + } + DCHECK(validators_->path_parameter.IsValid(pname)); + + if (hasValueError) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "value not correct"); + return error::kNoError; + } + + glPathParameterfNV(service_id, pname, value); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandlePathParameteriCHROMIUM( + uint32 immediate_data_size, + const void* cmd_data) { + static const char kFunctionName[] = "glPathParameteriCHROMIUM"; + const gles2::cmds::PathParameteriCHROMIUM& c = + *static_cast<const gles2::cmds::PathParameteriCHROMIUM*>(cmd_data); + if (!features().chromium_path_rendering) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "function not available"); + return error::kNoError; + } + GLuint service_id = 0; + if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "invalid path name"); + return error::kNoError; + } + + GLenum pname = static_cast<GLenum>(c.pname); + GLint value = static_cast<GLint>(c.value); + bool hasValueError = false; + + switch (pname) { + case GL_PATH_STROKE_WIDTH_CHROMIUM: + case GL_PATH_MITER_LIMIT_CHROMIUM: + hasValueError = value < 0; + break; + case GL_PATH_STROKE_BOUND_CHROMIUM: + value = std::max(std::min(1, value), 0); + break; + case GL_PATH_END_CAPS_CHROMIUM: + hasValueError = !validators_->path_parameter_cap_values.IsValid(value); + break; + case GL_PATH_JOIN_STYLE_CHROMIUM: + hasValueError = !validators_->path_parameter_join_values.IsValid(value); + break; + default: + DCHECK(!validators_->path_parameter.IsValid(pname)); + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, pname, "pname"); + return error::kNoError; + } + DCHECK(validators_->path_parameter.IsValid(pname)); + + if (hasValueError) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, "value not correct"); + return error::kNoError; + } + + glPathParameteriNV(service_id, pname, value); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleStencilFillPathCHROMIUM( + uint32 immediate_data_size, + const void* cmd_data) { + static const char kFunctionName[] = "glStencilFillPathCHROMIUM"; + const gles2::cmds::StencilFillPathCHROMIUM& c = + *static_cast<const gles2::cmds::StencilFillPathCHROMIUM*>(cmd_data); + if (!features().chromium_path_rendering) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "function not available"); + return error::kNoError; + } + GLenum fill_mode = static_cast<GLenum>(c.fillMode); + if (!validators_->path_fill_mode.IsValid(fill_mode)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, fill_mode, "fillMode"); + return error::kNoError; + } + GLuint mask = static_cast<GLuint>(c.mask); + if ((fill_mode == GL_COUNT_UP_CHROMIUM || + fill_mode == GL_COUNT_DOWN_CHROMIUM) && + GLES2Util::IsNPOT(mask + 1)) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, + "mask + 1 is not power of two"); + return error::kNoError; + } + GLuint service_id = 0; + if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { + // "If /path/ does not name an existing path object, the command does + // nothing (and no error is generated)." + // This holds for other rendering functions, too. + return error::kNoError; + } + ApplyDirtyState(); + glStencilFillPathNV(service_id, fill_mode, mask); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleStencilStrokePathCHROMIUM( + uint32 immediate_data_size, + const void* cmd_data) { + static const char kFunctionName[] = "glStencilStrokePathCHROMIUM"; + const gles2::cmds::StencilStrokePathCHROMIUM& c = + *static_cast<const gles2::cmds::StencilStrokePathCHROMIUM*>(cmd_data); + if (!features().chromium_path_rendering) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "function not available"); + return error::kNoError; + } + GLuint service_id = 0; + if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) { + return error::kNoError; + } + GLint reference = static_cast<GLint>(c.reference); + GLuint mask = static_cast<GLuint>(c.mask); + ApplyDirtyState(); + glStencilStrokePathNV(service_id, reference, mask); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleCoverFillPathCHROMIUM( + uint32 immediate_data_size, + const void* cmd_data) { + static const char kFunctionName[] = "glCoverFillPathCHROMIUM"; + const gles2::cmds::CoverFillPathCHROMIUM& c = + *static_cast<const gles2::cmds::CoverFillPathCHROMIUM*>(cmd_data); + if (!features().chromium_path_rendering) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "function not available"); + return error::kNoError; + } + GLenum cover_mode = static_cast<GLenum>(c.coverMode); + if (!validators_->path_cover_mode.IsValid(cover_mode)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, cover_mode, "coverMode"); + return error::kNoError; + } + GLuint service_id = 0; + if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) + return error::kNoError; + + ApplyDirtyState(); + glCoverFillPathNV(service_id, cover_mode); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleCoverStrokePathCHROMIUM( + uint32 immediate_data_size, + const void* cmd_data) { + static const char kFunctionName[] = "glCoverStrokePathCHROMIUM"; + const gles2::cmds::CoverStrokePathCHROMIUM& c = + *static_cast<const gles2::cmds::CoverStrokePathCHROMIUM*>(cmd_data); + if (!features().chromium_path_rendering) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "function not available"); + return error::kNoError; + } + GLenum cover_mode = static_cast<GLenum>(c.coverMode); + if (!validators_->path_cover_mode.IsValid(cover_mode)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, cover_mode, "coverMode"); + return error::kNoError; + } + GLuint service_id = 0; + if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) + return error::kNoError; + + ApplyDirtyState(); + glCoverStrokePathNV(service_id, cover_mode); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleStencilThenCoverFillPathCHROMIUM( + uint32 immediate_data_size, + const void* cmd_data) { + static const char kFunctionName[] = "glStencilThenCoverFillPathCHROMIUM"; + const gles2::cmds::StencilThenCoverFillPathCHROMIUM& c = + *static_cast<const gles2::cmds::StencilThenCoverFillPathCHROMIUM*>( + cmd_data); + if (!features().chromium_path_rendering) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "function not available"); + return error::kNoError; + } + GLenum fill_mode = static_cast<GLenum>(c.fillMode); + if (!validators_->path_fill_mode.IsValid(fill_mode)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, fill_mode, "fillMode"); + return error::kNoError; + } + GLuint mask = static_cast<GLuint>(c.mask); + if ((fill_mode == GL_COUNT_UP_CHROMIUM || + fill_mode == GL_COUNT_DOWN_CHROMIUM) && + GLES2Util::IsNPOT(mask + 1)) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, kFunctionName, + "mask + 1 is not power of two"); + return error::kNoError; + } + GLenum cover_mode = static_cast<GLenum>(c.coverMode); + if (!validators_->path_cover_mode.IsValid(cover_mode)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, cover_mode, "coverMode"); + return error::kNoError; + } + GLuint service_id = 0; + if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) + return error::kNoError; + + ApplyDirtyState(); + glStencilThenCoverFillPathNV(service_id, fill_mode, mask, cover_mode); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleStencilThenCoverStrokePathCHROMIUM( + uint32 immediate_data_size, + const void* cmd_data) { + static const char kFunctionName[] = "glStencilThenCoverStrokePathCHROMIUM"; + const gles2::cmds::StencilThenCoverStrokePathCHROMIUM& c = + *static_cast<const gles2::cmds::StencilThenCoverStrokePathCHROMIUM*>( + cmd_data); + if (!features().chromium_path_rendering) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, kFunctionName, + "function not available"); + return error::kNoError; + } + GLenum cover_mode = static_cast<GLenum>(c.coverMode); + if (!validators_->path_cover_mode.IsValid(cover_mode)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM(kFunctionName, cover_mode, "coverMode"); + return error::kNoError; + } + GLuint service_id = 0; + if (!path_manager()->GetPath(static_cast<GLuint>(c.path), &service_id)) + return error::kNoError; + + GLint reference = static_cast<GLint>(c.reference); + GLuint mask = static_cast<GLuint>(c.mask); + ApplyDirtyState(); + glStencilThenCoverStrokePathNV(service_id, reference, mask, cover_mode); + return error::kNoError; +} + // Include the auto-generated part of this file. We split this because it means // we can easily edit the non-auto generated parts right here in this file // instead of having to edit some template or the code generator. diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 1314d0d..615d287 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -4946,6 +4946,58 @@ error::Error GLES2DecoderImpl::HandleMatrixLoadIdentityCHROMIUM( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleIsPathCHROMIUM( + uint32_t immediate_data_size, + const void* cmd_data) { + const gles2::cmds::IsPathCHROMIUM& c = + *static_cast<const gles2::cmds::IsPathCHROMIUM*>(cmd_data); + (void)c; + if (!features().chromium_path_rendering) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glIsPathCHROMIUM", + "function not available"); + return error::kNoError; + } + + GLuint path = c.path; + typedef cmds::IsPathCHROMIUM::Result Result; + Result* result_dst = GetSharedMemoryAs<Result*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result_dst)); + if (!result_dst) { + return error::kOutOfBounds; + } + *result_dst = DoIsPathCHROMIUM(path); + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandlePathStencilFuncCHROMIUM( + uint32_t immediate_data_size, + const void* cmd_data) { + const gles2::cmds::PathStencilFuncCHROMIUM& c = + *static_cast<const gles2::cmds::PathStencilFuncCHROMIUM*>(cmd_data); + (void)c; + if (!features().chromium_path_rendering) { + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glPathStencilFuncCHROMIUM", + "function not available"); + return error::kNoError; + } + + GLenum func = static_cast<GLenum>(c.func); + GLint ref = static_cast<GLint>(c.ref); + GLuint mask = static_cast<GLuint>(c.mask); + if (!validators_->cmp_function.IsValid(func)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM("glPathStencilFuncCHROMIUM", func, "func"); + return error::kNoError; + } + if (state_.stencil_path_func != func || state_.stencil_path_ref != ref || + state_.stencil_path_mask != mask) { + state_.stencil_path_func = func; + state_.stencil_path_ref = ref; + state_.stencil_path_mask = mask; + glPathStencilFuncNV(func, ref, mask); + } + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleBlendBarrierKHR( uint32_t immediate_data_size, const void* cmd_data) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h index 1620423..dd11716 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_0_autogen.h @@ -71,6 +71,11 @@ void GLES2DecoderTestBase::SetupInitStateExpectations() { .Times(1) .RetiresOnSaturation(); } + if (group_->feature_info()->feature_flags().chromium_path_rendering) { + EXPECT_CALL(*gl_, PathStencilFuncNV(GL_ALWAYS, 0, 0xFFFFFFFFU)) + .Times(1) + .RetiresOnSaturation(); + } EXPECT_CALL(*gl_, PixelStorei(GL_PACK_ALIGNMENT, 4)) .Times(1) .RetiresOnSaturation(); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_4_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_4_autogen.h new file mode 100644 index 0000000..9abba52 --- /dev/null +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_4_autogen.h @@ -0,0 +1,15 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is auto-generated from +// gpu/command_buffer/build_gles2_cmd_buffer.py +// It's formatted by clang-format using chromium coding style: +// clang-format -i -style=chromium filename +// DO NOT EDIT! + +// It is included by gles2_cmd_decoder_unittest_4.cc +#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_4_AUTOGEN_H_ +#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_4_AUTOGEN_H_ + +#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_4_AUTOGEN_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc index f87a4bd..916f2aa 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc @@ -4,21 +4,134 @@ #include "gpu/command_buffer/service/gles2_cmd_decoder.h" +#include "base/command_line.h" #include "gpu/command_buffer/common/gles2_cmd_format.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h" +#include "gpu/command_buffer/service/gpu_switches.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_mock.h" using ::gfx::MockGLInterface; using ::testing::_; +using ::testing::Return; namespace gpu { namespace gles2 { +// Class to use to test that functions which need feature flags or +// extensions always return INVALID_OPERATION if the feature flags is not +// enabled or extension is not present. +class GLES2DecoderTestDisabledExtensions : public GLES2DecoderTest { + public: + GLES2DecoderTestDisabledExtensions() {} +}; +INSTANTIATE_TEST_CASE_P(Service, + GLES2DecoderTestDisabledExtensions, + ::testing::Bool()); + +TEST_P(GLES2DecoderTestDisabledExtensions, CHROMIUMPathRenderingDisabled) { + const GLuint kClientPathId = 0; + { + cmds::MatrixLoadfCHROMIUMImmediate& cmd = + *GetImmediateAs<cmds::MatrixLoadfCHROMIUMImmediate>(); + GLfloat temp[16] = { + 0, + }; + cmd.Init(GL_PATH_MODELVIEW_CHROMIUM, temp); + EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } + { + cmds::MatrixLoadIdentityCHROMIUM cmd; + cmd.Init(GL_PATH_PROJECTION_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } + { + cmds::GenPathsCHROMIUM cmd; + cmd.Init(0, 0); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } + { + cmds::DeletePathsCHROMIUM cmd; + cmd.Init(0, 0); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } + { + cmds::IsPathCHROMIUM cmd; + cmd.Init(kClientPathId, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } + { + cmds::PathCommandsCHROMIUM cmd; + cmd.Init(kClientPathId, 0, 0, 0, 0, GL_FLOAT, 0, 0); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } + { + cmds::PathParameterfCHROMIUM cmd; + cmd.Init(kClientPathId, GL_PATH_STROKE_WIDTH_CHROMIUM, 1.0f); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } + { + cmds::PathParameteriCHROMIUM cmd; + cmd.Init(kClientPathId, GL_PATH_STROKE_WIDTH_CHROMIUM, 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } + { + cmds::PathStencilFuncCHROMIUM cmd; + cmd.Init(GL_NEVER, 2, 3); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } + { + cmds::StencilFillPathCHROMIUM cmd; + cmd.Init(kClientPathId, GL_COUNT_UP_CHROMIUM, 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } + { + cmds::StencilStrokePathCHROMIUM cmd; + cmd.Init(kClientPathId, 1, 2); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } + { + cmds::CoverFillPathCHROMIUM cmd; + cmd.Init(kClientPathId, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } + { + cmds::CoverStrokePathCHROMIUM cmd; + cmd.Init(kClientPathId, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } + { + cmds::StencilThenCoverFillPathCHROMIUM cmd; + cmd.Init(kClientPathId, GL_COUNT_UP_CHROMIUM, 1, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } + { + cmds::StencilThenCoverStrokePathCHROMIUM cmd; + cmd.Init(kClientPathId, 1, 2, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } +} + class GLES2DecoderTestWithCHROMIUMPathRendering : public GLES2DecoderTest { public: - GLES2DecoderTestWithCHROMIUMPathRendering() {} + GLES2DecoderTestWithCHROMIUMPathRendering() : client_path_id_(125) {} + void SetUp() override { InitState init; init.gl_version = "opengl es 3.1"; @@ -28,8 +141,24 @@ class GLES2DecoderTestWithCHROMIUMPathRendering : public GLES2DecoderTest { init.request_depth = true; init.bind_generates_resource = true; init.extensions = "GL_NV_path_rendering"; - InitDecoder(init); + base::CommandLine command_line(0, NULL); + command_line.AppendSwitch(switches::kEnableGLPathRendering); + InitDecoderWithCommandLine(init, &command_line); + + EXPECT_CALL(*gl_, GenPathsNV(1)) + .WillOnce(Return(kServicePathId)) + .RetiresOnSaturation(); + cmds::GenPathsCHROMIUM cmd; + cmd.Init(client_path_id_, 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); } + + protected: + template <typename TypeParam> + void TestPathCommandsCHROMIUMCoordTypes(); + + GLuint client_path_id_; + static const GLuint kServicePathId = 311; }; INSTANTIATE_TEST_CASE_P(Service, @@ -56,6 +185,814 @@ INSTANTIATE_TEST_CASE_P(Service, GLES2DecoderTestWithBlendEquationAdvanced, ::testing::Bool()); +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, GenDeletePaths) { + static GLuint kFirstClientID = client_path_id_ + 88; + static GLsizei kPathCount = 58; + static GLuint kFirstCreatedServiceID = 8000; + + // GenPaths range 0 causes no calls. + cmds::GenPathsCHROMIUM gen_cmd; + gen_cmd.Init(kFirstClientID, 0); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // DeletePaths range 0 causes no calls. + cmds::DeletePathsCHROMIUM delete_cmd; + delete_cmd.Init(kFirstClientID, 0); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // DeletePaths client 0 causes no calls and no errors. + delete_cmd.Init(0, 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // DeletePaths with a big range should not cause any deletes. + delete_cmd.Init(client_path_id_ + 1, + std::numeric_limits<GLsizei>::max() - client_path_id_ - 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + delete_cmd.Init(std::numeric_limits<GLsizei>::max() + 1, + std::numeric_limits<GLsizei>::max()); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Normal Gen and Delete should cause the normal calls. + EXPECT_CALL(*gl_, GenPathsNV(kPathCount)) + .WillOnce(Return(kFirstCreatedServiceID)) + .RetiresOnSaturation(); + + gen_cmd.Init(kFirstClientID, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID, kPathCount)) + .RetiresOnSaturation(); + + delete_cmd.Init(kFirstClientID, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, GenDeleteRanges) { + static GLuint kFirstClientID = client_path_id_ + 77; + static GLsizei kPathCount = 5800; + static GLuint kFirstCreatedServiceID = 8000; + + // Create a range of path names, delete one in middle and then + // the rest. Expect 3 DeletePath calls. + EXPECT_CALL(*gl_, GenPathsNV(kPathCount)) + .WillOnce(Return(kFirstCreatedServiceID)) + .RetiresOnSaturation(); + cmds::GenPathsCHROMIUM gen_cmd; + gen_cmd.Init(kFirstClientID, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID + (kPathCount / 2), 1)) + .RetiresOnSaturation(); + + cmds::DeletePathsCHROMIUM delete_cmd; + delete_cmd.Init(kFirstClientID + (kPathCount / 2), 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID, (kPathCount / 2))) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID + (kPathCount / 2) + 1, + (kPathCount / 2) - 1)).RetiresOnSaturation(); + + delete_cmd.Init(kFirstClientID, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, GenDeleteManyPaths) { + static GLuint kFirstClientID = client_path_id_ + 1; + static GLsizei kPathCount = std::numeric_limits<GLsizei>::max(); + static GLuint kFirstCreatedServiceID = 8000; + + EXPECT_CALL(*gl_, GenPathsNV(kPathCount)) + .WillOnce(Return(kFirstCreatedServiceID)) + .RetiresOnSaturation(); + + // GenPaths with big range. + cmds::GenPathsCHROMIUM gen_cmd; + gen_cmd.Init(kFirstClientID, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Path range wraps, so we get connection error. + gen_cmd.Init(kFirstClientID + kPathCount, kPathCount); + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID, kPathCount)) + .RetiresOnSaturation(); + + cmds::DeletePathsCHROMIUM delete_cmd; + delete_cmd.Init(kFirstClientID, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Delete every possible path. + // We run into the one created for client_path_id_. + EXPECT_CALL(*gl_, DeletePathsNV(kServicePathId, 1)).RetiresOnSaturation(); + + delete_cmd.Init(1u, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + delete_cmd.Init(static_cast<GLuint>(kPathCount) + 1u, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Allocate every possible path, delete few, allocate them back and + // expect minimum amount of calls. + EXPECT_CALL(*gl_, GenPathsNV(kPathCount)) + .WillOnce(Return(static_cast<GLuint>(1u))) + .WillOnce(Return(static_cast<GLuint>(kPathCount) + 1u)) + .RetiresOnSaturation(); + + gen_cmd.Init(1u, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + gen_cmd.Init(static_cast<GLuint>(kPathCount) + 1u, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + gen_cmd.Init(static_cast<GLuint>(kPathCount) * 2u + 2u, kPathCount); + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*gl_, DeletePathsNV(kFirstClientID, 4)).RetiresOnSaturation(); + + delete_cmd.Init(kFirstClientID, 4); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*gl_, DeletePathsNV(kFirstClientID * 3, 1)).RetiresOnSaturation(); + + delete_cmd.Init(kFirstClientID * 3, 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*gl_, GenPathsNV(1)) + .WillOnce(Return(kFirstClientID)) + .WillOnce(Return(kFirstClientID + 1)) + .WillOnce(Return(kFirstClientID + 2)) + .WillOnce(Return(kFirstClientID + 3)) + .RetiresOnSaturation(); + + for (int i = 0; i < 4; ++i) { + gen_cmd.Init(kFirstClientID + i, 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + } + + EXPECT_CALL(*gl_, GenPathsNV(1)) + .WillOnce(Return(kFirstClientID * 3)) + .RetiresOnSaturation(); + gen_cmd.Init(kFirstClientID * 3, 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*gl_, DeletePathsNV(1u, kPathCount)).RetiresOnSaturation(); + EXPECT_CALL(*gl_, DeletePathsNV(static_cast<GLuint>(kPathCount) + 1u, + kPathCount)).RetiresOnSaturation(); + + delete_cmd.Init(1u, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + delete_cmd.Init(static_cast<GLuint>(kPathCount) + 1u, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Cleanup: return the client_path_id_ as a path. + EXPECT_CALL(*gl_, GenPathsNV(1)) + .WillOnce(Return(static_cast<GLuint>(kServicePathId))) + .RetiresOnSaturation(); + + gen_cmd.Init(client_path_id_, 1); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, + GenPathsCHROMIUMInvalidCalls) { + static GLuint kFirstClientID = client_path_id_ + 88; + static GLsizei kPathCount = 5800; + static GLuint kFirstCreatedServiceID = 8000; + + // Range < 0 is causes gl error. + cmds::GenPathsCHROMIUM gen_cmd; + gen_cmd.Init(kFirstClientID, -1); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + + // Path 0 is invalid client id, connection error. + gen_cmd.Init(0, kPathCount); + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Too big range causes client id to wrap, connection error. + gen_cmd.Init(std::numeric_limits<GLsizei>::max() + 3, + std::numeric_limits<GLsizei>::max()); + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Creating duplicate client_ids cause connection error. + EXPECT_CALL(*gl_, GenPathsNV(kPathCount)) + .WillOnce(Return(kFirstCreatedServiceID)) + .RetiresOnSaturation(); + + gen_cmd.Init(kFirstClientID, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Create duplicate by executing the same cmd. + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Create duplicate by creating a range that contains + // an already existing client path id. + gen_cmd.Init(kFirstClientID - 1, 2); + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Cleanup. + EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID, kPathCount)) + .RetiresOnSaturation(); + cmds::DeletePathsCHROMIUM delete_cmd; + delete_cmd.Init(kFirstClientID, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, + DeletePathsCHROMIUMInvalidCalls) { + static GLuint kFirstClientID = client_path_id_ + 88; + + // Range < 0 is causes gl error. + cmds::DeletePathsCHROMIUM delete_cmd; + delete_cmd.Init(kFirstClientID, -1); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + + // Too big range causes client id to wrap, connection error. + delete_cmd.Init(std::numeric_limits<GLsizei>::max() + 3, + std::numeric_limits<GLsizei>::max()); + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, + PathCommandsCHROMIUMInvalidCalls) { + static const GLsizei kCorrectCoordCount = 19; + static const GLsizei kCorrectCommandCount = 6; + static const GLenum kInvalidCoordType = GL_NONE; + + GLfloat* coords = GetSharedMemoryAs<GLfloat*>(); + unsigned commands_offset = sizeof(GLfloat) * kCorrectCoordCount; + GLubyte* commands = GetSharedMemoryAsWithOffset<GLubyte*>(commands_offset); + for (int i = 0; i < kCorrectCoordCount; ++i) { + coords[i] = 5.0f * i; + } + commands[0] = GL_MOVE_TO_CHROMIUM; + commands[1] = GL_CLOSE_PATH_CHROMIUM; + commands[2] = GL_LINE_TO_CHROMIUM; + commands[3] = GL_QUADRATIC_CURVE_TO_CHROMIUM; + commands[4] = GL_CUBIC_CURVE_TO_CHROMIUM; + commands[5] = GL_CONIC_CURVE_TO_CHROMIUM; + + EXPECT_CALL(*gl_, PathCommandsNV(kServicePathId, kCorrectCommandCount, + commands, kCorrectCoordCount, GL_FLOAT, + coords)).RetiresOnSaturation(); + + cmds::PathCommandsCHROMIUM cmd; + + // Reference call -- this succeeds. + cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, + shared_memory_offset_ + commands_offset, kCorrectCoordCount, + GL_FLOAT, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*gl_, PathCommandsNV(_, _, _, _, _, _)).Times(0); + + // Invalid client id fails. + cmd.Init(client_path_id_ - 1, kCorrectCommandCount, shared_memory_id_, + shared_memory_offset_, kCorrectCoordCount, GL_FLOAT, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + + // The numCommands < 0. + cmd.Init(client_path_id_, -1, shared_memory_id_, shared_memory_offset_, + kCorrectCoordCount, GL_FLOAT, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + + // The numCoords < 0. + cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, + shared_memory_offset_, -1, GL_FLOAT, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + + // Invalid coordType fails. + cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, + shared_memory_offset_, kCorrectCoordCount, kInvalidCoordType, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); + + // Big command counts. + cmd.Init(client_path_id_, std::numeric_limits<GLsizei>::max(), + shared_memory_id_, shared_memory_offset_ + commands_offset, + kCorrectCoordCount, GL_FLOAT, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Invalid SHM cases. + cmd.Init(client_path_id_, kCorrectCommandCount, kInvalidSharedMemoryId, + shared_memory_offset_ + commands_offset, kCorrectCoordCount, + GL_FLOAT, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, + kInvalidSharedMemoryOffset, kCorrectCoordCount, GL_FLOAT, + shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, + shared_memory_offset_ + commands_offset, kCorrectCoordCount, + GL_FLOAT, kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, + shared_memory_offset_ + commands_offset, kCorrectCoordCount, + GL_FLOAT, shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // NULL shm command id with non-zero command count. + cmd.Init(client_path_id_, kCorrectCommandCount, 0, 0, kCorrectCoordCount, + GL_FLOAT, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // NULL shm coord id with non-zero coord count. + cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, + shared_memory_offset_ + commands_offset, kCorrectCoordCount, + GL_FLOAT, 0, 0); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // The coordCount not matching what is in commands. + // Expects kCorrectCoordCount+2 coords. + commands[1] = GL_MOVE_TO_CHROMIUM; + cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, + shared_memory_offset_ + commands_offset, kCorrectCoordCount, + GL_FLOAT, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + + // The coordCount not matching what is in commands. + // Expects kCorrectCoordCount-2 coords. + commands[0] = GL_CLOSE_PATH_CHROMIUM; + commands[1] = GL_CLOSE_PATH_CHROMIUM; + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + + // NULL shm coord ids. Currently causes gl error, though client should not let + // this through. + cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, + shared_memory_offset_ + commands_offset, kCorrectCoordCount, + GL_FLOAT, 0, 0); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, + PathCommandsCHROMIUMEmptyCommands) { + EXPECT_CALL(*gl_, PathCommandsNV(kServicePathId, 0, NULL, 0, GL_FLOAT, NULL)) + .RetiresOnSaturation(); + cmds::PathCommandsCHROMIUM cmd; + cmd.Init(client_path_id_, 0, 0, 0, 0, GL_FLOAT, 0, 0); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, + PathCommandsCHROMIUMInvalidCommands) { + EXPECT_CALL(*gl_, PathCommandsNV(_, _, _, _, _, _)).Times(0); + + cmds::PathCommandsCHROMIUM cmd; + + { + const GLsizei kCoordCount = 2; + const GLsizei kCommandCount = 2; + GLfloat* coords = GetSharedMemoryAs<GLfloat*>(); + unsigned commands_offset = sizeof(GLfloat) * kCoordCount; + GLubyte* commands = GetSharedMemoryAsWithOffset<GLubyte*>(commands_offset); + + coords[0] = 5.0f; + coords[1] = 5.0f; + commands[0] = 0x3; // Token MOVE_TO_RELATIVE in NV_path_rendering. + commands[1] = GL_CLOSE_PATH_CHROMIUM; + + cmd.Init(client_path_id_ - 1, kCommandCount, shared_memory_id_, + shared_memory_offset_, kCoordCount, GL_FLOAT, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } + { + const GLsizei kCoordCount = 8; + const GLsizei kCommandCount = 4; + GLfloat* coords = GetSharedMemoryAs<GLfloat*>(); + unsigned commands_offset = sizeof(GLfloat) * kCoordCount; + GLubyte* commands = GetSharedMemoryAsWithOffset<GLubyte*>(commands_offset); + + for (int i = 0; i < kCoordCount; ++i) { + coords[i] = 5.0f * i; + } + commands[0] = GL_MOVE_TO_CHROMIUM; + commands[1] = GL_MOVE_TO_CHROMIUM; + commands[2] = 'M'; // Synonym to MOVE_TO in NV_path_rendering. + commands[3] = GL_MOVE_TO_CHROMIUM; + + cmd.Init(client_path_id_ - 1, kCommandCount, shared_memory_id_, + shared_memory_offset_, kCoordCount, GL_FLOAT, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + } +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, PathParameterXCHROMIUM) { + static GLuint kFirstClientID = client_path_id_ + 88; + static GLsizei kPathCount = 2; + static GLuint kFirstCreatedServiceID = 8000; + + // Create a paths so that we do not modify client_path_id_ + EXPECT_CALL(*gl_, GenPathsNV(kPathCount)) + .WillOnce(Return(kFirstCreatedServiceID)) + .RetiresOnSaturation(); + cmds::GenPathsCHROMIUM gen_cmd; + gen_cmd.Init(kFirstClientID, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + cmds::PathParameterfCHROMIUM fcmd; + cmds::PathParameteriCHROMIUM icmd; + const struct { + GLenum pname; + GLfloat value; + GLfloat expected_value; + } kTestcases[] = { + {GL_PATH_STROKE_WIDTH_CHROMIUM, 1.0f, 1.0f}, + {GL_PATH_STROKE_WIDTH_CHROMIUM, 0.0f, 0.0f}, + {GL_PATH_MITER_LIMIT_CHROMIUM, 500.0f, 500.0f}, + {GL_PATH_STROKE_BOUND_CHROMIUM, .80f, .80f}, + {GL_PATH_STROKE_BOUND_CHROMIUM, 1.80f, 1.0f}, + {GL_PATH_STROKE_BOUND_CHROMIUM, -1.0f, 0.0f}, + {GL_PATH_END_CAPS_CHROMIUM, GL_FLAT_CHROMIUM, GL_FLAT_CHROMIUM}, + {GL_PATH_END_CAPS_CHROMIUM, GL_SQUARE_CHROMIUM, GL_SQUARE_CHROMIUM}, + {GL_PATH_JOIN_STYLE_CHROMIUM, + GL_MITER_REVERT_CHROMIUM, + GL_MITER_REVERT_CHROMIUM}, + }; + + for (auto& testcase : kTestcases) { + EXPECT_CALL(*gl_, PathParameterfNV(kFirstCreatedServiceID, testcase.pname, + testcase.expected_value)) + .Times(1) + .RetiresOnSaturation(); + fcmd.Init(kFirstClientID, testcase.pname, testcase.value); + EXPECT_EQ(error::kNoError, ExecuteCmd(fcmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*gl_, + PathParameteriNV(kFirstCreatedServiceID + 1, testcase.pname, + static_cast<GLint>(testcase.expected_value))) + .Times(1) + .RetiresOnSaturation(); + icmd.Init(kFirstClientID + 1, testcase.pname, + static_cast<GLint>(testcase.value)); + EXPECT_EQ(error::kNoError, ExecuteCmd(icmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + } + + // Cleanup. + EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID, kPathCount)) + .RetiresOnSaturation(); + + cmds::DeletePathsCHROMIUM delete_cmd; + delete_cmd.Init(kFirstClientID, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, + PathParameterXCHROMIUMInvalidArgs) { + static GLuint kFirstClientID = client_path_id_ + 88; + static GLsizei kPathCount = 2; + static GLuint kFirstCreatedServiceID = 8000; + + // Create a paths so that we do not modify client_path_id_ + EXPECT_CALL(*gl_, GenPathsNV(kPathCount)) + .WillOnce(Return(kFirstCreatedServiceID)) + .RetiresOnSaturation(); + cmds::GenPathsCHROMIUM gen_cmd; + gen_cmd.Init(kFirstClientID, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + cmds::PathParameterfCHROMIUM fcmd; + cmds::PathParameteriCHROMIUM icmd; + const struct { + GLenum pname; + GLfloat value; + bool try_int_version; + GLint error; + } kTestcases[] = { + {GL_PATH_STROKE_WIDTH_CHROMIUM, -1.0f, true, GL_INVALID_VALUE}, + {GL_PATH_MITER_LIMIT_CHROMIUM, + std::numeric_limits<float>::infinity(), + false, + GL_INVALID_VALUE}, + {GL_PATH_MITER_LIMIT_CHROMIUM, + std::numeric_limits<float>::quiet_NaN(), + false, + GL_INVALID_VALUE}, + {GL_PATH_END_CAPS_CHROMIUM, 0x4, true, GL_INVALID_VALUE}, + {GL_PATH_END_CAPS_CHROMIUM, + GL_MITER_REVERT_CHROMIUM, + true, + GL_INVALID_VALUE}, + {GL_PATH_JOIN_STYLE_CHROMIUM, GL_FLAT_CHROMIUM, true, GL_INVALID_VALUE}, + {GL_PATH_MODELVIEW_CHROMIUM, GL_FLAT_CHROMIUM, true, GL_INVALID_ENUM}, + }; + + EXPECT_CALL(*gl_, PathParameterfNV(_, _, _)).Times(0); + EXPECT_CALL(*gl_, PathParameteriNV(_, _, _)).Times(0); + + for (auto& testcase : kTestcases) { + fcmd.Init(kFirstClientID, testcase.pname, testcase.value); + EXPECT_EQ(error::kNoError, ExecuteCmd(fcmd)); + EXPECT_EQ(testcase.error, GetGLError()); + if (!testcase.try_int_version) + continue; + + icmd.Init(kFirstClientID + 1, testcase.pname, + static_cast<GLint>(testcase.value)); + EXPECT_EQ(error::kNoError, ExecuteCmd(icmd)); + EXPECT_EQ(testcase.error, GetGLError()); + } + + // Cleanup. + EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID, kPathCount)) + .RetiresOnSaturation(); + + cmds::DeletePathsCHROMIUM delete_cmd; + delete_cmd.Init(kFirstClientID, kPathCount); + EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, StencilFillPathCHROMIUM) { + SetupExpectationsForApplyingDefaultDirtyState(); + + cmds::StencilFillPathCHROMIUM cmd; + cmds::StencilThenCoverFillPathCHROMIUM tcmd; + + static const GLenum kFillModes[] = { + GL_INVERT, GL_COUNT_UP_CHROMIUM, GL_COUNT_DOWN_CHROMIUM}; + static const GLuint kMask = 0x7F; + + for (auto& fill_mode : kFillModes) { + EXPECT_CALL(*gl_, StencilFillPathNV(kServicePathId, fill_mode, kMask)) + .RetiresOnSaturation(); + cmd.Init(client_path_id_, fill_mode, kMask); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*gl_, StencilThenCoverFillPathNV(kServicePathId, fill_mode, + kMask, GL_BOUNDING_BOX_NV)) + .RetiresOnSaturation(); + tcmd.Init(client_path_id_, fill_mode, kMask, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + } + + // Non-existent path: no error, no call. + cmd.Init(client_path_id_ - 1, GL_INVERT, 0x80); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + tcmd.Init(client_path_id_ - 1, GL_INVERT, 0x80, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, + StencilFillPathCHROMIUMInvalidArgs) { + EXPECT_CALL(*gl_, StencilFillPathNV(_, _, _)).Times(0); + EXPECT_CALL(*gl_, StencilThenCoverFillPathNV(_, _, _, GL_BOUNDING_BOX_NV)) + .Times(0); + + cmds::StencilFillPathCHROMIUM cmd; + cmds::StencilThenCoverFillPathCHROMIUM tcmd; + + cmd.Init(client_path_id_, GL_INVERT - 1, 0x80); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); + + tcmd.Init(client_path_id_, GL_INVERT - 1, 0x80, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); + EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); + + // The /mask/+1 is not power of two -> invalid value. + cmd.Init(client_path_id_, GL_COUNT_UP_CHROMIUM, 0x80); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + + tcmd.Init(client_path_id_, GL_COUNT_UP_CHROMIUM, 0x80, + GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + + cmd.Init(client_path_id_, GL_COUNT_DOWN_CHROMIUM, 5); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); + + tcmd.Init(client_path_id_, GL_COUNT_DOWN_CHROMIUM, 5, + GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, StencilStrokePathCHROMIUM) { + SetupExpectationsForApplyingDefaultDirtyState(); + + EXPECT_CALL(*gl_, StencilStrokePathNV(kServicePathId, 1, 0x80)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, StencilThenCoverStrokePathNV(kServicePathId, 1, 0x80, + GL_BOUNDING_BOX_NV)) + .RetiresOnSaturation(); + + cmds::StencilStrokePathCHROMIUM cmd; + cmds::StencilThenCoverStrokePathCHROMIUM tcmd; + + cmd.Init(client_path_id_, 1, 0x80); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + tcmd.Init(client_path_id_, 1, 0x80, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*gl_, StencilThenCoverStrokePathNV(kServicePathId, 1, 0x80, + GL_CONVEX_HULL_NV)) + .RetiresOnSaturation(); + + tcmd.Init(client_path_id_, 1, 0x80, GL_CONVEX_HULL_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Non-existent path: no error, no call. + cmd.Init(client_path_id_ - 1, 1, 0x80); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + tcmd.Init(client_path_id_ - 1, 1, 0x80, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, CoverFillPathCHROMIUM) { + SetupExpectationsForApplyingDefaultDirtyState(); + + EXPECT_CALL(*gl_, CoverFillPathNV(kServicePathId, GL_BOUNDING_BOX_NV)) + .RetiresOnSaturation(); + cmds::CoverFillPathCHROMIUM cmd; + cmd.Init(client_path_id_, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*gl_, CoverFillPathNV(kServicePathId, GL_CONVEX_HULL_NV)) + .RetiresOnSaturation(); + cmd.Init(client_path_id_, GL_CONVEX_HULL_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Non-existent path: no error, no call. + cmd.Init(client_path_id_ - 1, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, CoverStrokePathCHROMIUM) { + SetupExpectationsForApplyingDefaultDirtyState(); + EXPECT_CALL(*gl_, CoverStrokePathNV(kServicePathId, GL_BOUNDING_BOX_NV)) + .RetiresOnSaturation(); + cmds::CoverStrokePathCHROMIUM cmd; + cmd.Init(client_path_id_, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + EXPECT_CALL(*gl_, CoverStrokePathNV(kServicePathId, GL_CONVEX_HULL_NV)) + .RetiresOnSaturation(); + cmd.Init(client_path_id_, GL_CONVEX_HULL_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Non-existent path: no error, no call. + cmd.Init(client_path_id_ - 1, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +namespace { +template <typename T> +struct gl_type_enum {}; +template <> +struct gl_type_enum<GLbyte> { + enum { kGLType = GL_BYTE }; +}; +template <> +struct gl_type_enum<GLubyte> { + enum { kGLType = GL_UNSIGNED_BYTE }; +}; +template <> +struct gl_type_enum<GLshort> { + enum { kGLType = GL_SHORT }; +}; +template <> +struct gl_type_enum<GLushort> { + enum { kGLType = GL_UNSIGNED_SHORT }; +}; +template <> +struct gl_type_enum<GLfloat> { + enum { kGLType = GL_FLOAT }; +}; +} + +template <typename TypeParam> +void GLES2DecoderTestWithCHROMIUMPathRendering:: + TestPathCommandsCHROMIUMCoordTypes() { + static const GLsizei kCorrectCoordCount = 19; + static const GLsizei kCorrectCommandCount = 6; + + TypeParam* coords = GetSharedMemoryAs<TypeParam*>(); + unsigned commands_offset = sizeof(TypeParam) * kCorrectCoordCount; + GLubyte* commands = GetSharedMemoryAsWithOffset<GLubyte*>(commands_offset); + for (int i = 0; i < kCorrectCoordCount; ++i) { + coords[i] = static_cast<TypeParam>(5 * i); + } + commands[0] = GL_MOVE_TO_CHROMIUM; + commands[1] = GL_CLOSE_PATH_CHROMIUM; + commands[2] = GL_LINE_TO_CHROMIUM; + commands[3] = GL_QUADRATIC_CURVE_TO_CHROMIUM; + commands[4] = GL_CUBIC_CURVE_TO_CHROMIUM; + commands[5] = GL_CONIC_CURVE_TO_CHROMIUM; + + EXPECT_CALL(*gl_, PathCommandsNV(kServicePathId, kCorrectCommandCount, + commands, kCorrectCoordCount, + gl_type_enum<TypeParam>::kGLType, coords)) + .RetiresOnSaturation(); + + cmds::PathCommandsCHROMIUM cmd; + + cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, + shared_memory_offset_ + commands_offset, kCorrectCoordCount, + gl_type_enum<TypeParam>::kGLType, shared_memory_id_, + shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, + PathCommandsCHROMIUMCoordTypes) { + // Not using a typed test case, because the base class is already parametrized + // test case and uses GetParam. + TestPathCommandsCHROMIUMCoordTypes<GLbyte>(); + TestPathCommandsCHROMIUMCoordTypes<GLubyte>(); + TestPathCommandsCHROMIUMCoordTypes<GLshort>(); + TestPathCommandsCHROMIUMCoordTypes<GLushort>(); + TestPathCommandsCHROMIUMCoordTypes<GLfloat>(); +} + #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions_autogen.h" } // namespace gles2 diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions_autogen.h index 57db672..5c22b6c 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions_autogen.h @@ -44,6 +44,55 @@ TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); EXPECT_EQ(GL_NO_ERROR, GetGLError()); } +// TODO(gman): GenPathsCHROMIUM + +// TODO(gman): DeletePathsCHROMIUM + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, IsPathCHROMIUMValidArgs) { + EXPECT_CALL(*gl_, IsPathNV(kServicePathId)); + SpecializedSetup<cmds::IsPathCHROMIUM, 0>(true); + cmds::IsPathCHROMIUM cmd; + cmd.Init(client_path_id_, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, + IsPathCHROMIUMInvalidArgsBadSharedMemoryId) { + EXPECT_CALL(*gl_, IsPathNV(kServicePathId)).Times(0); + SpecializedSetup<cmds::IsPathCHROMIUM, 0>(false); + cmds::IsPathCHROMIUM cmd; + cmd.Init(client_path_id_, kInvalidSharedMemoryId, shared_memory_offset_); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); + cmd.Init(client_path_id_, shared_memory_id_, kInvalidSharedMemoryOffset); + EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); +} +// TODO(gman): PathCommandsCHROMIUM + +// TODO(gman): PathParameterfCHROMIUM + +// TODO(gman): PathParameteriCHROMIUM + +TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, + PathStencilFuncCHROMIUMValidArgs) { + EXPECT_CALL(*gl_, PathStencilFuncNV(GL_NEVER, 2, 3)); + SpecializedSetup<cmds::PathStencilFuncCHROMIUM, 0>(true); + cmds::PathStencilFuncCHROMIUM cmd; + cmd.Init(GL_NEVER, 2, 3); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} +// TODO(gman): StencilFillPathCHROMIUM + +// TODO(gman): StencilStrokePathCHROMIUM + +// TODO(gman): CoverFillPathCHROMIUM + +// TODO(gman): CoverStrokePathCHROMIUM + +// TODO(gman): StencilThenCoverFillPathCHROMIUM + +// TODO(gman): StencilThenCoverStrokePathCHROMIUM TEST_P(GLES2DecoderTestWithBlendEquationAdvanced, BlendBarrierKHRValidArgs) { EXPECT_CALL(*gl_, BlendBarrierKHR()); diff --git a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h index ec96c6b..ccaeb59 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h @@ -46,6 +46,12 @@ ValueValidator<GLenum> internal_format_parameter; ValueValidator<GLenum> invalidate_frame_buffer_target; ValueValidator<GLenum> map_buffer_access; ValueValidator<GLenum> matrix_mode; +ValueValidator<GLenum> path_coord_type; +ValueValidator<GLenum> path_cover_mode; +ValueValidator<GLenum> path_fill_mode; +ValueValidator<GLenum> path_parameter; +ValueValidator<GLint> path_parameter_cap_values; +ValueValidator<GLint> path_parameter_join_values; ValueValidator<GLenum> pixel_store; ValueValidator<GLint> pixel_store_alignment; ValueValidator<GLenum> pixel_type; diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h index 1c4cf97..5e23712 100644 --- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h @@ -474,6 +474,45 @@ static const GLenum valid_matrix_mode_table[] = { GL_PATH_MODELVIEW_CHROMIUM, }; +static const GLenum valid_path_coord_type_table[] = { + GL_BYTE, + GL_UNSIGNED_BYTE, + GL_SHORT, + GL_UNSIGNED_SHORT, + GL_FLOAT, +}; + +static const GLenum valid_path_cover_mode_table[] = { + GL_CONVEX_HULL_CHROMIUM, + GL_BOUNDING_BOX_CHROMIUM, +}; + +static const GLenum valid_path_fill_mode_table[] = { + GL_INVERT, + GL_COUNT_UP_CHROMIUM, + GL_COUNT_DOWN_CHROMIUM, +}; + +static const GLenum valid_path_parameter_table[] = { + GL_PATH_STROKE_WIDTH_CHROMIUM, + GL_PATH_END_CAPS_CHROMIUM, + GL_PATH_JOIN_STYLE_CHROMIUM, + GL_PATH_MITER_LIMIT_CHROMIUM, + GL_PATH_STROKE_BOUND_CHROMIUM, +}; + +static const GLint valid_path_parameter_cap_values_table[] = { + GL_FLAT, + GL_SQUARE_CHROMIUM, + GL_ROUND_CHROMIUM, +}; + +static const GLint valid_path_parameter_join_values_table[] = { + GL_MITER_REVERT_CHROMIUM, + GL_BEVEL_CHROMIUM, + GL_ROUND_CHROMIUM, +}; + static const GLenum valid_pixel_store_table[] = { GL_PACK_ALIGNMENT, GL_UNPACK_ALIGNMENT, @@ -1148,6 +1187,20 @@ Validators::Validators() map_buffer_access(valid_map_buffer_access_table, arraysize(valid_map_buffer_access_table)), matrix_mode(valid_matrix_mode_table, arraysize(valid_matrix_mode_table)), + path_coord_type(valid_path_coord_type_table, + arraysize(valid_path_coord_type_table)), + path_cover_mode(valid_path_cover_mode_table, + arraysize(valid_path_cover_mode_table)), + path_fill_mode(valid_path_fill_mode_table, + arraysize(valid_path_fill_mode_table)), + path_parameter(valid_path_parameter_table, + arraysize(valid_path_parameter_table)), + path_parameter_cap_values( + valid_path_parameter_cap_values_table, + arraysize(valid_path_parameter_cap_values_table)), + path_parameter_join_values( + valid_path_parameter_join_values_table, + arraysize(valid_path_parameter_join_values_table)), pixel_store(valid_pixel_store_table, arraysize(valid_pixel_store_table)), pixel_store_alignment(valid_pixel_store_alignment_table, arraysize(valid_pixel_store_alignment_table)), diff --git a/gpu/command_buffer/service/gpu_switches.cc b/gpu/command_buffer/service/gpu_switches.cc index d2ca490..171f543 100644 --- a/gpu/command_buffer/service/gpu_switches.cc +++ b/gpu/command_buffer/service/gpu_switches.cc @@ -71,25 +71,31 @@ const char kGLShaderIntermOutput[] = "gl-shader-interm-output"; // round intermediate values in ANGLE. const char kEmulateShaderPrecision[] = "emulate-shader-precision"; +// Enables using path rendering implementation implemented currently +// in NV_path_rendering OpenGL extension. Requires compatible hardware +// and driver. This is used in GPU rasterization. +const char kEnableGLPathRendering[] = "enable-gl-path-rendering"; + const char* kGpuSwitches[] = { - kCompileShaderAlwaysSucceeds, - kDisableGLErrorLimit, - kDisableGLSLTranslator, - kDisableGpuDriverBugWorkarounds, - kDisableShaderNameHashing, - kEnableGPUCommandLogging, - kEnableGPUDebugging, - kEnableGPUServiceLoggingGPU, - kDisableGpuProgramCache, - kEnforceGLMinimums, - kForceGpuMemAvailableMb, - kGpuDriverBugWorkarounds, - kGpuProgramCacheSizeKb, - kDisableGpuShaderDiskCache, - kEnableShareGroupAsyncTextureUpload, - kEnableSubscribeUniformExtension, - kGLShaderIntermOutput, - kEmulateShaderPrecision, + kCompileShaderAlwaysSucceeds, + kDisableGLErrorLimit, + kDisableGLSLTranslator, + kDisableGpuDriverBugWorkarounds, + kDisableShaderNameHashing, + kEnableGPUCommandLogging, + kEnableGPUDebugging, + kEnableGPUServiceLoggingGPU, + kDisableGpuProgramCache, + kEnforceGLMinimums, + kForceGpuMemAvailableMb, + kGpuDriverBugWorkarounds, + kGpuProgramCacheSizeKb, + kDisableGpuShaderDiskCache, + kEnableShareGroupAsyncTextureUpload, + kEnableSubscribeUniformExtension, + kGLShaderIntermOutput, + kEmulateShaderPrecision, + kEnableGLPathRendering, }; const int kNumGpuSwitches = arraysize(kGpuSwitches); diff --git a/gpu/command_buffer/service/gpu_switches.h b/gpu/command_buffer/service/gpu_switches.h index ac6883a..ac347e4 100644 --- a/gpu/command_buffer/service/gpu_switches.h +++ b/gpu/command_buffer/service/gpu_switches.h @@ -30,6 +30,7 @@ GPU_EXPORT extern const char kEnableSubscribeUniformExtension[]; GPU_EXPORT extern const char kEnableThreadedTextureMailboxes[]; GPU_EXPORT extern const char kGLShaderIntermOutput[]; GPU_EXPORT extern const char kEmulateShaderPrecision[]; +GPU_EXPORT extern const char kEnableGLPathRendering[]; GPU_EXPORT extern const char* kGpuSwitches[]; GPU_EXPORT extern const int kNumGpuSwitches; diff --git a/gpu/command_buffer/service/path_manager.cc b/gpu/command_buffer/service/path_manager.cc new file mode 100644 index 0000000..3e0d257 --- /dev/null +++ b/gpu/command_buffer/service/path_manager.cc @@ -0,0 +1,252 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gpu/command_buffer/service/path_manager.h" + +#include <algorithm> + +#include "base/logging.h" +#include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "ui/gl/gl_bindings.h" + +namespace gpu { +namespace gles2 { + +namespace { +void CallDeletePaths(GLuint first_id, GLuint range) { + while (range > 0) { + GLsizei irange; + if (range > static_cast<GLuint>(std::numeric_limits<GLsizei>::max())) + irange = std::numeric_limits<GLsizei>::max(); + else + irange = static_cast<GLsizei>(range); + + glDeletePathsNV(first_id, irange); + range -= irange; + first_id += irange; + } +} + +template <typename RangeIterator> +static GLuint RangeSize(const RangeIterator& it) { + return it->second.last_client_id - it->first + 1; +} +template <typename RangeIterator> +static GLuint FirstClientId(const RangeIterator& it) { + return it->first; +} +template <typename RangeIterator> +static GLuint FirstServiceId(const RangeIterator& it) { + return it->second.first_service_id; +} +template <typename RangeIterator> +static GLuint LastServiceId(const RangeIterator& it) { + return FirstServiceId(it) + RangeSize(it) - 1; +} +static GLuint LastClientId(PathManager::PathRangeMap::const_iterator& it) { + return it->second.last_client_id; +} +// Note: this one can be assigned to. +static GLuint& LastClientId(PathManager::PathRangeMap::iterator& it) { + return it->second.last_client_id; +} + +template <typename T> +struct IteratorSelector { + typedef typename T::iterator iterator; +}; +template <typename T> +struct IteratorSelector<const T> { + typedef typename T::const_iterator iterator; +}; + +// Returns the range position that contains |client_id| or +// |PathRangeMap::iterator::end()| if |client_id| is not found. +template <typename MapType> +static typename IteratorSelector<MapType>::iterator GetContainingRange( + MapType& path_map, + GLuint client_id) { + auto it = path_map.lower_bound(client_id); + if (it != path_map.end() && FirstClientId(it) == client_id) + return it; + if (it != path_map.begin()) { + --it; + if (LastClientId(it) >= client_id) + return it; + } + return path_map.end(); +} + +// Returns the range position that contains |client_id|. If that is +// not available, returns the range that has smallest +// |first_client_id| that is bigger than |client_id|. Returns +// |PathRangeMap::iterator::end()| if there is no such range. +template <typename MapType> +static typename IteratorSelector<MapType>::iterator GetContainingOrNextRange( + MapType& path_map, + GLuint client_id) { + auto it = path_map.lower_bound(client_id); + if (it != path_map.end() && FirstClientId(it) == client_id) { + return it; + } + if (it != path_map.begin()) { + --it; + if (LastClientId(it) >= client_id) + return it; + ++it; + } + return it; +} + +} // anonymous namespace + +PathManager::PathManager() { +} + +PathManager::~PathManager() { + DCHECK(path_map_.empty()); +} + +void PathManager::Destroy(bool have_context) { + if (have_context) { + for (PathRangeMap::const_iterator it = path_map_.begin(); + it != path_map_.end(); ++it) + CallDeletePaths(FirstServiceId(it), RangeSize(it)); + } + path_map_.clear(); +} + +void PathManager::CreatePathRange(GLuint first_client_id, + GLuint last_client_id, + GLuint first_service_id) { + DCHECK(first_service_id > 0u); + DCHECK(first_client_id > 0u); + DCHECK(!HasPathsInRange(first_client_id, last_client_id)); + DCHECK(CheckConsistency()); + + PathRangeMap::iterator range = + GetContainingRange(path_map_, first_client_id - 1u); + + if (range != path_map_.end() && + LastServiceId(range) == first_service_id - 1u) { + DCHECK_EQ(LastClientId(range), first_client_id - 1u); + LastClientId(range) = last_client_id; + } else { + auto result = path_map_.insert( + std::make_pair(first_client_id, + PathRangeDescription(last_client_id, first_service_id))); + DCHECK(result.second); + range = result.first; + } + + PathRangeMap::iterator next_range = range; + ++next_range; + if (next_range != path_map_.end()) { + if (LastClientId(range) == FirstClientId(next_range) - 1u && + LastServiceId(range) == FirstServiceId(next_range) - 1u) { + LastClientId(range) = LastClientId(next_range); + path_map_.erase(next_range); + } + } + DCHECK(CheckConsistency()); +} + +bool PathManager::HasPathsInRange(GLuint first_client_id, + GLuint last_client_id) const { + PathRangeMap::const_iterator it = + GetContainingOrNextRange(path_map_, first_client_id); + if (it == path_map_.end()) + return false; + + return FirstClientId(it) <= last_client_id; +} + +bool PathManager::GetPath(GLuint client_id, GLuint* service_id) const { + PathRangeMap::const_iterator range = GetContainingRange(path_map_, client_id); + if (range == path_map_.end()) + return false; + + *service_id = FirstServiceId(range) + client_id - FirstClientId(range); + return true; +} + +void PathManager::RemovePaths(GLuint first_client_id, GLuint last_client_id) { + DCHECK(CheckConsistency()); + PathRangeMap::iterator it = + GetContainingOrNextRange(path_map_, first_client_id); + + while (it != path_map_.end() && FirstClientId(it) <= last_client_id) { + GLuint delete_first_client_id = + std::max(first_client_id, FirstClientId(it)); + GLuint delete_last_client_id = std::min(last_client_id, LastClientId(it)); + GLuint delete_first_service_id = + FirstServiceId(it) + delete_first_client_id - FirstClientId(it); + GLuint delete_range = delete_last_client_id - delete_first_client_id + 1u; + + CallDeletePaths(delete_first_service_id, delete_range); + + PathRangeMap::iterator current = it; + ++it; + + GLuint current_last_client_id = LastClientId(current); + + if (FirstClientId(current) < delete_first_client_id) + LastClientId(current) = delete_first_client_id - 1u; + else + path_map_.erase(current); + + if (current_last_client_id > delete_last_client_id) { + path_map_.insert(std::make_pair( + delete_last_client_id + 1u, + PathRangeDescription(current_last_client_id, + delete_first_service_id + delete_range))); + DCHECK(delete_last_client_id == last_client_id); + // This is necessarily the last range to check. Return early due to + // consistency. Iterator increment would skip the inserted range. The + // algorithm would work ok, but it looks weird. + DCHECK(CheckConsistency()); + return; + } + } + DCHECK(CheckConsistency()); +} + +bool PathManager::CheckConsistency() { + GLuint prev_first_client_id = 0u; + GLuint prev_last_client_id = 0u; + GLuint prev_first_service_id = 0u; + for (PathRangeMap::iterator range = path_map_.begin(); + range != path_map_.end(); ++range) { + // Code relies on ranges not starting at 0. Also, the above initialization + // is only + // correct then. + if (FirstClientId(range) == 0u || FirstServiceId(range) == 0u) + return false; + + // Each range is consistent. + if (FirstClientId(range) > LastClientId(range)) + return false; + + if (prev_first_client_id != 0u) { + // No overlapping ranges. (The iteration is sorted). + if (FirstClientId(range) <= prev_last_client_id) + return false; + + // No mergeable ranges. + bool is_mergeable_client = + FirstClientId(range) - 1u == prev_last_client_id; + bool is_mergeable_service = + FirstServiceId(range) - 1u == prev_first_service_id; + if (is_mergeable_client && is_mergeable_service) + return false; + } + prev_first_client_id = FirstClientId(range); + prev_last_client_id = LastClientId(range); + prev_first_service_id = FirstServiceId(range); + } + return true; +} + +} // namespace gles2 +} // namespace gpu diff --git a/gpu/command_buffer/service/path_manager.h b/gpu/command_buffer/service/path_manager.h new file mode 100644 index 0000000..78a53b7 --- /dev/null +++ b/gpu/command_buffer/service/path_manager.h @@ -0,0 +1,68 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_PATH_MANAGER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_PATH_MANAGER_H_ + +#include <map> + +#include "base/basictypes.h" +#include "gpu/command_buffer/service/gl_utils.h" +#include "gpu/gpu_export.h" + +namespace gpu { +namespace gles2 { + +// This class keeps track of paths and their client and service ids +// so we can correctly clear them. +class GPU_EXPORT PathManager { + public: + PathManager(); + ~PathManager(); + + // Must call before destruction. + void Destroy(bool have_context); + + // Creates a path mapping between closed intervals + // [first_client_id, last_client_id] -> [first_service_id, ...]. + void CreatePathRange(GLuint first_client_id, + GLuint last_client_id, + GLuint first_service_id); + + // Returns true if any path exists in the closed interval + // [first_client_id, last_client_id]. + bool HasPathsInRange(GLuint first_client_id, GLuint last_client_id) const; + + // Gets the path id corresponding the client path id. + // Returns false if no such service path id was not found. + bool GetPath(GLuint client_id, GLuint* service_id) const; + + // Removes a closed interval of paths [first_client_id, last_client_id]. + void RemovePaths(GLuint first_client_id, GLuint last_client_id); + + // Mapping between client id and service id. + // Should be used only by the implementation. + struct PathRangeDescription { + PathRangeDescription(GLuint last_client, GLuint first_service) + : last_client_id(last_client), first_service_id(first_service) {} + GLuint last_client_id; + GLuint first_service_id; + typedef GLuint ServiceIdType; + }; + typedef std::map<GLuint, PathRangeDescription> PathRangeMap; + + private: + // Checks for consistency inside the book-keeping structures. Used as + // DCHECK pre/post condition in mutating functions. + bool CheckConsistency(); + + PathRangeMap path_map_; + + DISALLOW_COPY_AND_ASSIGN(PathManager); +}; + +} // namespace gles2 +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_PATH_MANAGER_H_ diff --git a/gpu/command_buffer/service/path_manager_unittest.cc b/gpu/command_buffer/service/path_manager_unittest.cc new file mode 100644 index 0000000..8a20db5 --- /dev/null +++ b/gpu/command_buffer/service/path_manager_unittest.cc @@ -0,0 +1,164 @@ +// Copyright (c) 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gpu/command_buffer/service/path_manager.h" + +#include "base/memory/scoped_ptr.h" +#include "gpu/command_buffer/service/gpu_service_test.h" +#include "gpu/command_buffer/service/mocks.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gl/gl_mock.h" + +namespace gpu { +namespace gles2 { + +class PathManagerTest : public GpuServiceTest { + public: + PathManagerTest() {} + + protected: + void SetUp() override { + SetUpWithGLVersion("3.0", "GL_NV_path_rendering"); + manager_.reset(new PathManager()); + } + + void TearDown() override { + manager_->Destroy(true); + manager_.reset(); + GpuServiceTest::TearDown(); + } + + scoped_ptr<PathManager> manager_; +}; + +TEST_F(PathManagerTest, Basic) { + const GLuint kClient1Id = 1; + const GLuint kService1Id = 11; + const GLuint kClient2Id = 2; + GLuint service_id = 0; + manager_->CreatePathRange(kClient1Id, kClient1Id, kService1Id); + ASSERT_TRUE(manager_->HasPathsInRange(kClient1Id, kClient1Id)); + EXPECT_TRUE(manager_->GetPath(kClient1Id, &service_id)); + EXPECT_EQ(kService1Id, service_id); + + // Check we get nothing for a non-existent path. + service_id = 123u; + ASSERT_FALSE(manager_->HasPathsInRange(kClient2Id, kClient2Id)); + EXPECT_FALSE(manager_->GetPath(kClient2Id, &service_id)); + EXPECT_EQ(123u, service_id); + + // Check trying to remove non-existent paths does not crash. + manager_->RemovePaths(kClient2Id, kClient2Id); + + // Check that it gets deleted when the last reference is released. + EXPECT_CALL(*gl_, DeletePathsNV(kService1Id, 1)) + .Times(1) + .RetiresOnSaturation(); + + // Check we can't get the path after we remove it. + manager_->RemovePaths(kClient1Id, kClient1Id); + ASSERT_FALSE(manager_->HasPathsInRange(kClient1Id, kClient1Id)); + EXPECT_FALSE(manager_->GetPath(kClient1Id, &service_id)); +} + +// Tests that path manager does not merge ranges that contain service ids that +// prevent the merging. Path ranges A and B can be merged if +// * client ids of B start immediately after the last client id of A +// * service ids of B start immediately after the last service id of A +// and similarly for the 'before' case. +TEST_F(PathManagerTest, NonContiguousServiceIds) { + const GLuint kMergeCheckRange = 54; + + const struct { + GLuint first_client_id; + GLuint last_client_id; + GLuint first_service_id; + } kIdRanges[] = {{500, 1000, 900}, {1001, 1155, 1}, {200, 499, 4888}}; + for (auto& range : kIdRanges) { + manager_->CreatePathRange(range.first_client_id, range.last_client_id, + range.first_service_id); + ASSERT_TRUE(manager_->HasPathsInRange(range.first_client_id, + range.first_client_id)); + ASSERT_TRUE( + manager_->HasPathsInRange(range.last_client_id, range.last_client_id)); + ASSERT_TRUE( + manager_->HasPathsInRange(range.first_client_id, range.last_client_id)); + GLuint service_id = 0u; + EXPECT_TRUE(manager_->GetPath(range.first_client_id + 5u, &service_id)); + EXPECT_EQ(range.first_service_id + 5u, service_id); + } + + // Insert a mergeable range last, to check that merges + // work. Otherwise the test could succeed because merges were not + // working. + auto& merge_candidate = kIdRanges[1]; + GLuint merge_candidate_range = + merge_candidate.last_client_id - merge_candidate.first_client_id + 1; + manager_->CreatePathRange( + merge_candidate.last_client_id + 1, + merge_candidate.last_client_id + kMergeCheckRange, + merge_candidate.first_service_id + merge_candidate_range); + + // We detect that ranges were not merged accidentally by detecting individual + // deletes. + for (auto& range : kIdRanges) { + if (&range == &merge_candidate) + continue; + GLsizei range_amount = range.last_client_id - range.first_client_id + 1; + EXPECT_CALL(*gl_, DeletePathsNV(range.first_service_id, range_amount)) + .Times(1) + .RetiresOnSaturation(); + } + + // Just a check that merges work. + EXPECT_CALL(*gl_, DeletePathsNV(merge_candidate.first_service_id, + merge_candidate_range + kMergeCheckRange)) + .Times(1) + .RetiresOnSaturation(); + + // Remove all ids. This should cause the expected amount of DeletePathsNV + // calls. + manager_->RemovePaths(1, std::numeric_limits<GLsizei>::max()); + + for (auto& range : kIdRanges) { + ASSERT_FALSE( + manager_->HasPathsInRange(range.first_client_id, range.last_client_id)); + } +} + +TEST_F(PathManagerTest, DeleteBigRange) { + // Allocates two ranges which in path manager end up merging as one + // big range. The range will be too big to fit in one DeletePaths + // call. Test that the range is deleted correctly with two calls. + const GLuint kFirstClientId1 = 1; + const GLsizei kRange1 = std::numeric_limits<GLsizei>::max() - 3; + const GLuint kLastClientId1 = kFirstClientId1 + kRange1 - 1; + const GLuint kFirstServiceId1 = 77; + const GLuint kLastServiceId1 = kFirstServiceId1 + kRange1 - 1; + + const GLuint kFirstClientId2 = kLastClientId1 + 1; + const GLsizei kRange2 = 15; + const GLuint kLastClientId2 = kFirstClientId2 + kRange2 - 1; + const GLuint kFirstServiceId2 = kLastServiceId1 + 1; + + const GLsizei kFirstDeleteRange = std::numeric_limits<GLsizei>::max(); + const GLsizei kSecondDeleteRange = kRange2 - (kFirstDeleteRange - kRange1); + const GLuint kSecondDeleteFirstServiceId = + kFirstServiceId1 + kFirstDeleteRange; + + EXPECT_CALL(*gl_, DeletePathsNV(kFirstServiceId1, + std::numeric_limits<GLsizei>::max())) + .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, DeletePathsNV(kSecondDeleteFirstServiceId, + kSecondDeleteRange)).RetiresOnSaturation(); + + manager_->CreatePathRange(kFirstClientId1, kLastClientId1, kFirstServiceId1); + manager_->CreatePathRange(kFirstClientId2, kLastClientId2, kFirstServiceId2); + manager_->RemovePaths(0, std::numeric_limits<GLuint>::max()); +} + +} // namespace gles2 + +} // namespace gpu diff --git a/gpu/command_buffer/tests/gl_chromium_path_rendering_unittest.cc b/gpu/command_buffer/tests/gl_chromium_path_rendering_unittest.cc index 0d17b7c..57f5dd0 100644 --- a/gpu/command_buffer/tests/gl_chromium_path_rendering_unittest.cc +++ b/gpu/command_buffer/tests/gl_chromium_path_rendering_unittest.cc @@ -7,11 +7,15 @@ #include <GLES2/gl2extchromium.h> #include <cmath> +#include "base/command_line.h" +#include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/tests/gl_manager.h" #include "gpu/command_buffer/tests/gl_test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#define SHADER(Src) #Src + namespace gpu { class CHROMIUMPathRenderingTest : public testing::Test { @@ -22,7 +26,9 @@ class CHROMIUMPathRenderingTest : public testing::Test { void SetUp() override { GLManager::Options options; options.size = gfx::Size(kResolution, kResolution); - gl_.Initialize(options); + base::CommandLine command_line(*base::CommandLine::ForCurrentProcess()); + command_line.AppendSwitch(switches::kEnableGLPathRendering); + gl_.InitializeWithCommandLine(options, &command_line); } void TearDown() override { gl_.Destroy(); } @@ -37,13 +43,156 @@ class CHROMIUMPathRenderingTest : public testing::Test { EXPECT_EQ(static_cast<GLint>(round(expected[i])), actual[i]); } } + + void SetupStateForTestPattern() { + glViewport(0, 0, kResolution, kResolution); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glStencilMask(0xffffffff); + glClearStencil(0); + glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + static const char* kVertexShaderSource = + SHADER(void main() { gl_Position = vec4(1); }); + static const char* kFragmentShaderSource = + SHADER(precision mediump float; uniform vec4 color; + void main() { gl_FragColor = color; }); + + GLuint program = + GLTestHelper::LoadProgram(kVertexShaderSource, kFragmentShaderSource); + glUseProgram(program); + color_loc_ = glGetUniformLocation(program, "color"); + glDeleteProgram(program); + + // Set up orthogonal projection with near/far plane distance of 2. + static GLfloat matrix[16] = {2.0f / (kResolution - 1), + 0.0f, + 0.0f, + 0.0f, + 0.0f, + 2.0f / (kResolution - 1), + 0.0f, + 0.0f, + 0.0f, + 0.0f, + -1.0f, + 0.0f, + -1.0f, + -1.0f, + 0.0f, + 1.0f}; + glMatrixLoadfCHROMIUM(GL_PATH_PROJECTION_CHROMIUM, matrix); + glMatrixLoadIdentityCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM); + + glEnable(GL_STENCIL_TEST); + + GLTestHelper::CheckGLError("no errors at state setup", __LINE__); + } + + void SetupPathStateForTestPattern(GLuint path) { + static const GLubyte kCommands[] = {GL_MOVE_TO_CHROMIUM, + GL_LINE_TO_CHROMIUM, + GL_QUADRATIC_CURVE_TO_CHROMIUM, + GL_CUBIC_CURVE_TO_CHROMIUM, + GL_CLOSE_PATH_CHROMIUM}; + + static const GLfloat kCoords[] = {50.0f, + 50.0f, + 75.0f, + 75.0f, + 100.0f, + 62.5f, + 50.0f, + 25.5f, + 0.0f, + 62.5f, + 50.0f, + 50.0f, + 25.0f, + 75.0f}; + + glPathCommandsCHROMIUM(path, arraysize(kCommands), kCommands, + arraysize(kCoords), GL_FLOAT, kCoords); + + glPathParameterfCHROMIUM(path, GL_PATH_STROKE_WIDTH_CHROMIUM, 5.0f); + glPathParameterfCHROMIUM(path, GL_PATH_MITER_LIMIT_CHROMIUM, 1.0f); + glPathParameterfCHROMIUM(path, GL_PATH_STROKE_BOUND_CHROMIUM, .02f); + glPathParameteriCHROMIUM(path, GL_PATH_JOIN_STYLE_CHROMIUM, + GL_ROUND_CHROMIUM); + glPathParameteriCHROMIUM(path, GL_PATH_END_CAPS_CHROMIUM, + GL_SQUARE_CHROMIUM); + } + + void VerifyTestPatternFill(float x, float y) { + static const float kFillCoords[] = { + 55.0f, 55.0f, 50.0f, 28.0f, 66.0f, 63.0f}; + static const uint8 kBlue[] = {0, 0, 255, 255}; + + for (size_t i = 0; i < arraysize(kFillCoords); i += 2) { + float fx = kFillCoords[i]; + float fy = kFillCoords[i + 1]; + + EXPECT_TRUE(GLTestHelper::CheckPixels(x + fx, y + fy, 1, 1, 0, kBlue)); + } + } + + void VerifyTestPatternBg(float x, float y) { + const float kBackgroundCoords[] = {80.0f, 80.0f, 20.0f, 20.0f, 90.0f, 1.0f}; + const uint8 kExpectedColor[] = {0, 0, 0, 0}; + + for (size_t i = 0; i < arraysize(kBackgroundCoords); i += 2) { + float bx = kBackgroundCoords[i]; + float by = kBackgroundCoords[i + 1]; + + EXPECT_TRUE( + GLTestHelper::CheckPixels(x + bx, y + by, 1, 1, 0, kExpectedColor)); + } + } + + void VerifyTestPatternStroke(float x, float y) { + // Inside the stroke we should have green. + const uint8 kGreen[] = {0, 255, 0, 255}; + EXPECT_TRUE(GLTestHelper::CheckPixels(x + 50, y + 53, 1, 1, 0, kGreen)); + EXPECT_TRUE(GLTestHelper::CheckPixels(x + 26, y + 76, 1, 1, 0, kGreen)); + + // Outside the path we should have black. + const uint8 black[] = {0, 0, 0, 0}; + EXPECT_TRUE(GLTestHelper::CheckPixels(x + 10, y + 10, 1, 1, 0, black)); + EXPECT_TRUE(GLTestHelper::CheckPixels(x + 80, y + 80, 1, 1, 0, black)); + } + + void TryAllDrawFunctions(GLuint path, GLenum expected_error) { + glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F); + EXPECT_EQ(expected_error, glGetError()); + + glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F); + EXPECT_EQ(expected_error, glGetError()); + + glStencilStrokePathCHROMIUM(path, 0x80, 0x80); + EXPECT_EQ(expected_error, glGetError()); + + glCoverFillPathCHROMIUM(path, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(expected_error, glGetError()); + + glCoverStrokePathCHROMIUM(path, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(expected_error, glGetError()); + + glStencilThenCoverStrokePathCHROMIUM(path, 0x80, 0x80, + GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(expected_error, glGetError()); + + glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F, + GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(expected_error, glGetError()); + } + GLManager gl_; + GLint color_loc_; }; TEST_F(CHROMIUMPathRenderingTest, TestMatrix) { - if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) { + if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) return; - } + static const GLfloat kIdentityMatrix[16] = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; @@ -86,25 +235,388 @@ TEST_F(CHROMIUMPathRenderingTest, TestMatrix) { } TEST_F(CHROMIUMPathRenderingTest, TestMatrixErrors) { - if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) { + if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) return; - } + GLfloat mf[16]; memset(mf, 0, sizeof(mf)); - // This should fail. + glMatrixLoadfCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM, mf); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + + glMatrixLoadIdentityCHROMIUM(GL_PATH_PROJECTION_CHROMIUM); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + + // Test that invalid matrix targets fail. glMatrixLoadfCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM - 1, mf); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); - glMatrixLoadfCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM, mf); + // Test that invalid matrix targets fail. + glMatrixLoadIdentityCHROMIUM(GL_PATH_PROJECTION_CHROMIUM + 1); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); +} + +TEST_F(CHROMIUMPathRenderingTest, TestSimpleCalls) { + if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) + return; + + // This is unspecified in NV_path_rendering. + EXPECT_EQ(0u, glGenPathsCHROMIUM(0)); + + GLuint path = glGenPathsCHROMIUM(1); + EXPECT_NE(path, 0u); + glDeletePathsCHROMIUM(path, 1); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); - // This should fail. - glMatrixLoadIdentityCHROMIUM(GL_PATH_PROJECTION_CHROMIUM + 1); + GLuint first_path = glGenPathsCHROMIUM(5); + EXPECT_NE(first_path, 0u); + glDeletePathsCHROMIUM(first_path, 5); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + + // Test deleting paths that are not actually allocated: + // "unused names in /paths/ are silently ignored". + first_path = glGenPathsCHROMIUM(5); + EXPECT_NE(first_path, 0u); + glDeletePathsCHROMIUM(first_path, 6); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + + GLsizei big_range = 0xffff; + // Setting big_range = std::numeric_limits<GLsizei>::max() should go through + // too, as far as NV_path_rendering is concerned. Current chromium side id + // allocator will use too much memory. + first_path = glGenPathsCHROMIUM(big_range); + EXPECT_NE(first_path, 0u); + glDeletePathsCHROMIUM(first_path, big_range); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + + // Test glIsPathCHROMIUM(). + path = glGenPathsCHROMIUM(1); + EXPECT_FALSE(glIsPathCHROMIUM(path)); + GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM}; + GLfloat coords[] = {50.0f, 50.0f}; + glPathCommandsCHROMIUM(path, arraysize(commands), commands, arraysize(coords), + GL_FLOAT, coords); + EXPECT_TRUE(glIsPathCHROMIUM(path)); + glDeletePathsCHROMIUM(path, 1); + EXPECT_FALSE(glIsPathCHROMIUM(path)); +} + +TEST_F(CHROMIUMPathRenderingTest, TestGenDeleteErrors) { + if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) + return; + + // GenPaths / DeletePaths tests. + // std::numeric_limits<GLuint>::max() is wrong for GLsizei. + GLuint first_path = glGenPathsCHROMIUM(std::numeric_limits<GLuint>::max()); + EXPECT_EQ(first_path, 0u); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); + + first_path = glGenPathsCHROMIUM(-1); + EXPECT_EQ(first_path, 0u); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); + + glDeletePathsCHROMIUM(1, -5); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); + + first_path = glGenPathsCHROMIUM(-1); + EXPECT_EQ(first_path, 0u); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); + + // Test that delete with first_id and range such that first_id + range + // overflows the GLuint. Example: + // Range is 0x7fffffff. First id is X. Last id will be X + 0x7ffffffe. + // X = 0x80000001 would succeed, where as X = 0x80000002 would fail. + // To get 0x80000002, we need to allocate first 0x7fffffff and then + // 3 (0x80000000, 0x80000001 and 0x80000002). + // While not guaranteed by the API, we expect the implementation + // hands us deterministic ids. + first_path = glGenPathsCHROMIUM(std::numeric_limits<GLsizei>::max()); + EXPECT_EQ(first_path, 1u); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + + GLuint additional_paths = glGenPathsCHROMIUM(3); + EXPECT_EQ(additional_paths, + static_cast<GLuint>(std::numeric_limits<GLsizei>::max()) + 1u); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + + // Test that passing a range so big that it would overflow client_id + // + range - 1 check causes an error. + glDeletePathsCHROMIUM(additional_paths + 2u, + std::numeric_limits<GLsizei>::max()); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); + + // Cleanup the above allocations. Also test that passing max value still + // works. + glDeletePathsCHROMIUM(1, std::numeric_limits<GLsizei>::max()); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + glDeletePathsCHROMIUM(std::numeric_limits<GLsizei>::max(), + std::numeric_limits<GLsizei>::max()); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); +} + +TEST_F(CHROMIUMPathRenderingTest, TestPathParameterErrors) { + if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) + return; + + GLuint path = glGenPathsCHROMIUM(1); + // PathParameter*: Wrong value for the pname should fail. + glPathParameteriCHROMIUM(path, GL_PATH_JOIN_STYLE_CHROMIUM, GL_FLAT_CHROMIUM); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); + glPathParameterfCHROMIUM(path, GL_PATH_END_CAPS_CHROMIUM, + GL_MITER_REVERT_CHROMIUM); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); + + // PathParameter*: Wrong floating-point value should fail. + glPathParameterfCHROMIUM(path, GL_PATH_STROKE_WIDTH_CHROMIUM, -0.1f); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); + glPathParameterfCHROMIUM(path, GL_PATH_MITER_LIMIT_CHROMIUM, + std::numeric_limits<float>::quiet_NaN()); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); + glPathParameterfCHROMIUM(path, GL_PATH_MITER_LIMIT_CHROMIUM, + std::numeric_limits<float>::infinity()); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); + + // PathParameter*: Wrong pname should fail. + glPathParameteriCHROMIUM(path, GL_PATH_STROKE_WIDTH_CHROMIUM - 1, 5); EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); + glDeletePathsCHROMIUM(path, 1); +} - glMatrixLoadIdentityCHROMIUM(GL_PATH_PROJECTION_CHROMIUM); +TEST_F(CHROMIUMPathRenderingTest, TestPathObjectState) { + if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) + return; + + glViewport(0, 0, kResolution, kResolution); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glStencilMask(0xffffffff); + glClearStencil(0); + glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + + // Test that trying to draw non-existing paths does not produce errors or + // results. + GLuint non_existing_paths[] = {0, 55, 74744}; + for (auto& p : non_existing_paths) { + EXPECT_FALSE(glIsPathCHROMIUM(p)); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + TryAllDrawFunctions(p, GL_NO_ERROR); + } + + // Path name marked as used but without path object state causes + // a GL error upon any draw command. + GLuint path = glGenPathsCHROMIUM(1); + EXPECT_FALSE(glIsPathCHROMIUM(path)); + TryAllDrawFunctions(path, GL_INVALID_OPERATION); + glDeletePathsCHROMIUM(path, 1); + + // Document a bit of an inconsistency: path name marked as used but without + // path object state causes a GL error upon any draw command (tested above). + // Path name that had path object state, but then was "cleared", still has a + // path object state, even though the state is empty. + path = glGenPathsCHROMIUM(1); + EXPECT_FALSE(glIsPathCHROMIUM(path)); + GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM}; + GLfloat coords[] = {50.0f, 50.0f}; + glPathCommandsCHROMIUM(path, arraysize(commands), commands, arraysize(coords), + GL_FLOAT, coords); + EXPECT_TRUE(glIsPathCHROMIUM(path)); + glPathCommandsCHROMIUM(path, 0, NULL, 0, GL_FLOAT, NULL); + EXPECT_TRUE(glIsPathCHROMIUM(path)); // The surprise. + TryAllDrawFunctions(path, GL_NO_ERROR); + glDeletePathsCHROMIUM(path, 1); + + // Document a bit of an inconsistency: "clearing" a used path name causes + // path to acquire state. + path = glGenPathsCHROMIUM(1); + EXPECT_FALSE(glIsPathCHROMIUM(path)); + glPathCommandsCHROMIUM(path, 0, NULL, 0, GL_FLOAT, NULL); + EXPECT_TRUE(glIsPathCHROMIUM(path)); // The surprise. + glDeletePathsCHROMIUM(path, 1); + + // Make sure nothing got drawn by the drawing commands that should not produce + // anything. + const uint8 black[] = {0, 0, 0, 0}; + EXPECT_TRUE( + GLTestHelper::CheckPixels(0, 0, kResolution, kResolution, 0, black)); +} + +TEST_F(CHROMIUMPathRenderingTest, TestUnnamedPathsErrors) { + if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) + return; + + // Unnamed paths: Trying to create a path object with non-existing path name + // produces error. (Not a error in real NV_path_rendering). + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM}; + GLfloat coords[] = {50.0f, 50.0f}; + glPathCommandsCHROMIUM(555, arraysize(commands), commands, arraysize(coords), + GL_FLOAT, coords); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); + + // PathParameter*: Using non-existing path object produces error. + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + glPathParameterfCHROMIUM(555, GL_PATH_STROKE_WIDTH_CHROMIUM, 5.0f); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); + + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + glPathParameteriCHROMIUM(555, GL_PATH_JOIN_STYLE_CHROMIUM, GL_ROUND_CHROMIUM); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); +} + +TEST_F(CHROMIUMPathRenderingTest, TestPathCommandsErrors) { + if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) + return; + + static const GLenum kInvalidCoordType = GL_NONE; + + GLuint path = glGenPathsCHROMIUM(1); + GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM}; + GLfloat coords[] = {50.0f, 50.0f}; + + glPathCommandsCHROMIUM(path, arraysize(commands), commands, -4, GL_FLOAT, + coords); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); + + glPathCommandsCHROMIUM(path, -1, commands, arraysize(coords), GL_FLOAT, + coords); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); + + glPathCommandsCHROMIUM(path, arraysize(commands), commands, arraysize(coords), + kInvalidCoordType, coords); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); + + // These can not distinquish between the check that should fail them. + // This should fail due to coord count * float size overflow. + glPathCommandsCHROMIUM(path, arraysize(commands), commands, + std::numeric_limits<GLsizei>::max(), GL_FLOAT, coords); + // This should fail due to cmd count + coord count * short size. + glPathCommandsCHROMIUM(path, arraysize(commands), commands, + std::numeric_limits<GLsizei>::max(), GL_SHORT, coords); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), glGetError()); + + glDeletePathsCHROMIUM(path, 1); +} + +TEST_F(CHROMIUMPathRenderingTest, TestPathRenderingInvalidArgs) { + if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) + return; + + GLuint path = glGenPathsCHROMIUM(1); + glPathCommandsCHROMIUM(path, 0, NULL, 0, GL_FLOAT, NULL); + + // Verify that normal calls work. + glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F); EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F, + GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + + // Using invalid fill mode causes INVALID_ENUM. + glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM - 1, 0x7F); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); + glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM - 1, 0x7F, + GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); + + // Using invalid cover mode causes INVALID_ENUM. + glCoverFillPathCHROMIUM(path, GL_CONVEX_HULL_CHROMIUM - 1); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); + glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F, + GL_BOUNDING_BOX_CHROMIUM + 1); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); + + // Using mask+1 not being power of two causes INVALID_VALUE with up/down fill + // mode. + glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x40); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); + glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_DOWN_CHROMIUM, 12, + GL_BOUNDING_BOX_CHROMIUM); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), glGetError()); + + glDeletePathsCHROMIUM(path, 1); +} + +// Tests that drawing with CHROMIUM_path_rendering functions work. +TEST_F(CHROMIUMPathRenderingTest, TestPathRendering) { + if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) + return; + + static const float kBlue[] = {0.0f, 0.0f, 1.0f, 1.0f}; + static const float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f}; + + SetupStateForTestPattern(); + + GLuint path = glGenPathsCHROMIUM(1); + SetupPathStateForTestPattern(path); + + // Do the stencil fill, cover fill, stencil stroke, cover stroke + // in unconventional order: + // 1) stencil the stroke in stencil high bit + // 2) stencil the fill in low bits + // 3) cover the fill + // 4) cover the stroke + // This is done to check that glPathStencilFunc works, eg the mask + // goes through. Stencil func is not tested ATM, for simplicity. + + glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0xFF); + glStencilStrokePathCHROMIUM(path, 0x80, 0x80); + + glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0x7F); + glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F); + + glStencilFunc(GL_LESS, 0, 0x7F); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glUniform4fv(color_loc_, 1, kBlue); + glCoverFillPathCHROMIUM(path, GL_BOUNDING_BOX_CHROMIUM); + + glStencilFunc(GL_EQUAL, 0x80, 0x80); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glUniform4fv(color_loc_, 1, kGreen); + glCoverStrokePathCHROMIUM(path, GL_CONVEX_HULL_CHROMIUM); + + glDeletePathsCHROMIUM(path, 1); + + // Verify the image. + VerifyTestPatternFill(0.0f, 0.0f); + VerifyTestPatternBg(0.0f, 0.0f); + VerifyTestPatternStroke(0.0f, 0.0f); +} + +// Tests that drawing with CHROMIUM_path_rendering +// StencilThenCover{Stroke,Fill}Path functions work. +TEST_F(CHROMIUMPathRenderingTest, TestPathRenderingThenFunctions) { + if (!GLTestHelper::HasExtension("GL_CHROMIUM_path_rendering")) + return; + + static float kBlue[] = {0.0f, 0.0f, 1.0f, 1.0f}; + static float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f}; + + SetupStateForTestPattern(); + + GLuint path = glGenPathsCHROMIUM(1); + SetupPathStateForTestPattern(path); + + glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0xFF); + glStencilFunc(GL_EQUAL, 0x80, 0x80); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glUniform4fv(color_loc_, 1, kGreen); + glStencilThenCoverStrokePathCHROMIUM(path, 0x80, 0x80, + GL_BOUNDING_BOX_CHROMIUM); + + glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0x7F); + glStencilFunc(GL_LESS, 0, 0x7F); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glUniform4fv(color_loc_, 1, kBlue); + glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F, + GL_CONVEX_HULL_CHROMIUM); + + glDeletePathsCHROMIUM(path, 1); + + // Verify the image. + VerifyTestPatternFill(0.0f, 0.0f); + VerifyTestPatternBg(0.0f, 0.0f); + VerifyTestPatternStroke(0.0f, 0.0f); } } // namespace gpu diff --git a/gpu/command_buffer_service.gypi b/gpu/command_buffer_service.gypi index abdedc4..388fcc3 100644 --- a/gpu/command_buffer_service.gypi +++ b/gpu/command_buffer_service.gypi @@ -107,6 +107,8 @@ 'command_buffer/service/mocks.h', 'command_buffer/service/program_cache.cc', 'command_buffer/service/program_cache.h', + 'command_buffer/service/path_manager.cc', + 'command_buffer/service/path_manager.h', 'command_buffer/service/program_manager.cc', 'command_buffer/service/program_manager.h', 'command_buffer/service/query_manager.cc', diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc index d8d301f..92db7bc 100644 --- a/gpu/config/gpu_driver_bug_list_json.cc +++ b/gpu/config/gpu_driver_bug_list_json.cc @@ -19,7 +19,7 @@ const char kGpuDriverBugListJson[] = LONG_STRING_CONST( { "name": "gpu driver bug list", // Please update the version number whenever you change this file. - "version": "8.17", + "version": "8.18", "entries": [ { "id": 1, @@ -1455,6 +1455,19 @@ LONG_STRING_CONST( "features": [ "disable_ns_cgl_surface_api" ] + }, + { + "id": 123, + "cr_bugs": [344330], + "description": "NVIDIA drivers before 337 lack features in NV_path_rendering and related extensions to implement driver level path rendering.", + "driver_version": { + "op": "<", + "value": "337" + }, + "vendor_id": "0x10de", + "features": [ + "disable_gl_path_rendering" + ] } ] } diff --git a/gpu/config/gpu_driver_bug_workaround_type.h b/gpu/config/gpu_driver_bug_workaround_type.h index 5c0127d..70c370d 100644 --- a/gpu/config/gpu_driver_bug_workaround_type.h +++ b/gpu/config/gpu_driver_bug_workaround_type.h @@ -34,6 +34,8 @@ disable_discard_framebuffer) \ GPU_OP(DISABLE_EXT_DRAW_BUFFERS, \ disable_ext_draw_buffers) \ + GPU_OP(DISABLE_GL_PATH_RENDERING, \ + disable_gl_path_rendering) \ GPU_OP(DISABLE_GL_RGB_FORMAT, \ disable_gl_rgb_format) \ GPU_OP(DISABLE_MULTIMONITOR_MULTISAMPLING, \ diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index 82e3f13..5004bc7 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp @@ -251,6 +251,7 @@ 'command_buffer/service/shader_translator_unittest.cc', 'command_buffer/service/test_helper.cc', 'command_buffer/service/test_helper.h', + 'command_buffer/service/path_manager_unittest.cc', 'command_buffer/service/texture_manager_unittest.cc', 'command_buffer/service/transfer_buffer_manager_unittest.cc', 'command_buffer/service/valuebuffer_manager_unittest.cc', diff --git a/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc b/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc index 36ff45b..024c9cc 100644 --- a/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc +++ b/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc @@ -146,8 +146,27 @@ GrGLInterface* CreateCommandBufferSkiaGLBinding() { functions->fBindUniformLocation = glBindUniformLocationCHROMIUM; functions->fBlitFramebuffer = glBlitFramebufferCHROMIUM; functions->fGenerateMipmap = glGenerateMipmap; - functions->fMatrixLoadf = glMatrixLoadfCHROMIUM; - functions->fMatrixLoadIdentity = glMatrixLoadIdentityCHROMIUM; + if (false) { + // These are disabled until the full extension is implemented. + // Otherwise the interface fails validation and the context can not + // be created. + functions->fMatrixLoadf = glMatrixLoadfCHROMIUM; + functions->fMatrixLoadIdentity = glMatrixLoadIdentityCHROMIUM; + functions->fPathCommands = glPathCommandsCHROMIUM; + functions->fPathParameteri = glPathParameteriCHROMIUM; + functions->fPathParameterf = glPathParameterfCHROMIUM; + functions->fGenPaths = glGenPathsCHROMIUM; + functions->fIsPath = glIsPathCHROMIUM; + functions->fDeletePaths = glDeletePathsCHROMIUM; + functions->fPathStencilFunc = glPathStencilFuncCHROMIUM; + functions->fStencilFillPath = glStencilFillPathCHROMIUM; + functions->fStencilStrokePath = glStencilStrokePathCHROMIUM; + functions->fCoverFillPath = glCoverFillPathCHROMIUM; + functions->fCoverStrokePath = glCoverStrokePathCHROMIUM; + functions->fStencilThenCoverFillPath = glStencilThenCoverFillPathCHROMIUM; + functions->fStencilThenCoverStrokePath = + glStencilThenCoverStrokePathCHROMIUM; + } return interface; } diff --git a/mojo/gpu/mojo_gles2_impl_autogen.cc b/mojo/gpu/mojo_gles2_impl_autogen.cc index 8b068c7..6351a07 100644 --- a/mojo/gpu/mojo_gles2_impl_autogen.cc +++ b/mojo/gpu/mojo_gles2_impl_autogen.cc @@ -1644,6 +1644,68 @@ void MojoGLES2Impl::MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) { void MojoGLES2Impl::MatrixLoadIdentityCHROMIUM(GLenum matrixMode) { NOTREACHED() << "Unimplemented MatrixLoadIdentityCHROMIUM."; } +GLuint MojoGLES2Impl::GenPathsCHROMIUM(GLsizei range) { + NOTREACHED() << "Unimplemented GenPathsCHROMIUM."; + return 0; +} +void MojoGLES2Impl::DeletePathsCHROMIUM(GLuint path, GLsizei range) { + NOTREACHED() << "Unimplemented DeletePathsCHROMIUM."; +} +GLboolean MojoGLES2Impl::IsPathCHROMIUM(GLuint path) { + NOTREACHED() << "Unimplemented IsPathCHROMIUM."; + return 0; +} +void MojoGLES2Impl::PathCommandsCHROMIUM(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords) { + NOTREACHED() << "Unimplemented PathCommandsCHROMIUM."; +} +void MojoGLES2Impl::PathParameterfCHROMIUM(GLuint path, + GLenum pname, + GLfloat value) { + NOTREACHED() << "Unimplemented PathParameterfCHROMIUM."; +} +void MojoGLES2Impl::PathParameteriCHROMIUM(GLuint path, + GLenum pname, + GLint value) { + NOTREACHED() << "Unimplemented PathParameteriCHROMIUM."; +} +void MojoGLES2Impl::PathStencilFuncCHROMIUM(GLenum func, + GLint ref, + GLuint mask) { + NOTREACHED() << "Unimplemented PathStencilFuncCHROMIUM."; +} +void MojoGLES2Impl::StencilFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask) { + NOTREACHED() << "Unimplemented StencilFillPathCHROMIUM."; +} +void MojoGLES2Impl::StencilStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask) { + NOTREACHED() << "Unimplemented StencilStrokePathCHROMIUM."; +} +void MojoGLES2Impl::CoverFillPathCHROMIUM(GLuint path, GLenum coverMode) { + NOTREACHED() << "Unimplemented CoverFillPathCHROMIUM."; +} +void MojoGLES2Impl::CoverStrokePathCHROMIUM(GLuint path, GLenum coverMode) { + NOTREACHED() << "Unimplemented CoverStrokePathCHROMIUM."; +} +void MojoGLES2Impl::StencilThenCoverFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) { + NOTREACHED() << "Unimplemented StencilThenCoverFillPathCHROMIUM."; +} +void MojoGLES2Impl::StencilThenCoverStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) { + NOTREACHED() << "Unimplemented StencilThenCoverStrokePathCHROMIUM."; +} GLenum MojoGLES2Impl::GetGraphicsResetStatusKHR() { NOTREACHED() << "Unimplemented GetGraphicsResetStatusKHR."; return 0; diff --git a/mojo/gpu/mojo_gles2_impl_autogen.h b/mojo/gpu/mojo_gles2_impl_autogen.h index 32d9e2a..c71536c 100644 --- a/mojo/gpu/mojo_gles2_impl_autogen.h +++ b/mojo/gpu/mojo_gles2_impl_autogen.h @@ -786,6 +786,36 @@ class MojoGLES2Impl : public gpu::gles2::GLES2Interface { void SwapInterval(GLint interval) override; void MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat* m) override; void MatrixLoadIdentityCHROMIUM(GLenum matrixMode) override; + GLuint GenPathsCHROMIUM(GLsizei range) override; + void DeletePathsCHROMIUM(GLuint path, GLsizei range) override; + GLboolean IsPathCHROMIUM(GLuint path) override; + void PathCommandsCHROMIUM(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords) override; + void PathParameterfCHROMIUM(GLuint path, + GLenum pname, + GLfloat value) override; + void PathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value) override; + void PathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask) override; + void StencilFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask) override; + void StencilStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask) override; + void CoverFillPathCHROMIUM(GLuint path, GLenum coverMode) override; + void CoverStrokePathCHROMIUM(GLuint path, GLenum coverMode) override; + void StencilThenCoverFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) override; + void StencilThenCoverStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) override; GLenum GetGraphicsResetStatusKHR() override; void BlendBarrierKHR() override; diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py index 2667b24..a3c4824 100755 --- a/ui/gl/generate_bindings.py +++ b/ui/gl/generate_bindings.py @@ -36,9 +36,13 @@ array instead of the names array. Each version has the following keys: extensions: Extra Extensions for which the function is bound. Only needed in some cases where the extension cannot be parsed from the headers. - + is_optional: True if the GetProcAddress can return NULL for the + function. This may happen for example when functions + are added to a new version of an extension, but the + extension string is not modified. By default, the function gets its name from the first name in its names or versions array. This can be overridden by supplying a 'known_as' key. + """ GL_FUNCTIONS = [ { 'return_type': 'void', @@ -235,6 +239,12 @@ GL_FUNCTIONS = [ 'arguments': 'GLenum target, GLint level, GLint xoffset, GLint yoffset, ' 'GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height', }, +{ 'return_type': 'void', + 'names': ['glCoverFillPathNV'], + 'arguments': 'GLuint path, GLenum coverMode' }, +{ 'return_type': 'void', + 'names': ['glCoverStrokePathNV'], + 'arguments': 'GLuint name, GLenum coverMode' }, { 'return_type': 'GLuint', 'names': ['glCreateProgram'], 'arguments': 'void', }, @@ -260,6 +270,9 @@ GL_FUNCTIONS = [ 'names': ['glDeleteFramebuffersEXT', 'glDeleteFramebuffers'], 'arguments': 'GLsizei n, const GLuint* framebuffers', }, { 'return_type': 'void', + 'names': ['glDeletePathsNV'], + 'arguments': 'GLuint path, GLsizei range' }, +{ 'return_type': 'void', 'names': ['glDeleteProgram'], 'arguments': 'GLuint program', }, { 'return_type': 'void', @@ -438,6 +451,9 @@ GL_FUNCTIONS = [ { 'return_type': 'void', 'names': ['glGenFramebuffersEXT', 'glGenFramebuffers'], 'arguments': 'GLsizei n, GLuint* framebuffers', }, +{ 'return_type': 'GLuint', + 'names': ['glGenPathsNV'], + 'arguments': 'GLsizei range' }, { 'return_type': 'void', 'versions': [{ 'name': 'glGenQueries' }, { 'name': 'glGenQueriesARB', }, @@ -705,6 +721,9 @@ GL_FUNCTIONS = [ 'names': ['glIsFramebufferEXT', 'glIsFramebuffer'], 'arguments': 'GLuint framebuffer', }, { 'return_type': 'GLboolean', + 'names': ['glIsPathNV'], + 'arguments': 'GLuint path' }, +{ 'return_type': 'GLboolean', 'names': ['glIsProgram'], 'arguments': 'GLuint program', }, { 'return_type': 'GLboolean', @@ -771,6 +790,19 @@ GL_FUNCTIONS = [ 'GL_NV_path_rendering'] },], 'arguments': 'GLenum matrixMode' }, { 'return_type': 'void', + 'names': ['glPathCommandsNV'], + 'arguments': 'GLuint path, GLsizei numCommands, const GLubyte* commands, ' + 'GLsizei numCoords, GLenum coordType, const GLvoid* coords' }, +{ 'return_type': 'void', + 'names': ['glPathParameterfNV'], + 'arguments': 'GLuint path, GLenum pname, GLfloat value' }, +{ 'return_type': 'void', + 'names': ['glPathParameteriNV'], + 'arguments': 'GLuint path, GLenum pname, GLint value' }, +{ 'return_type': 'void', + 'names': ['glPathStencilFuncNV'], + 'arguments': 'GLenum func, GLint ref, GLuint mask' }, +{ 'return_type': 'void', 'versions': [{ 'name': 'glPauseTransformFeedback' }], 'arguments': 'void', }, { 'return_type': 'void', @@ -889,6 +921,9 @@ GL_FUNCTIONS = [ }); """, }, { 'return_type': 'void', + 'names': ['glStencilFillPathNV'], + 'arguments': 'GLuint path, GLenum fillMode, GLuint mask' }, +{ 'return_type': 'void', 'names': ['glStencilFunc'], 'arguments': 'GLenum func, GLint ref, GLuint mask', }, { 'return_type': 'void', @@ -906,6 +941,17 @@ GL_FUNCTIONS = [ { 'return_type': 'void', 'names': ['glStencilOpSeparate'], 'arguments': 'GLenum face, GLenum fail, GLenum zfail, GLenum zpass', }, +{ 'return_type': 'void', + 'names': ['glStencilStrokePathNV'], + 'arguments': 'GLuint path, GLint reference, GLuint mask' }, +{ 'return_type': 'void', + 'names': ['glStencilThenCoverFillPathNV'], + 'arguments': 'GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode', + 'is_optional': True, }, +{ 'return_type': 'void', + 'names': ['glStencilThenCoverStrokePathNV'], + 'arguments': 'GLuint path, GLint reference, GLuint mask, GLenum coverMode', + 'is_optional': True, }, { 'return_type': 'GLboolean', 'known_as': 'glTestFenceAPPLE', 'versions': [{ 'name': 'glTestFenceAPPLE', @@ -1905,7 +1951,8 @@ namespace gfx { file.write(' else if (%s) {\n ' % (cond)) WriteFuncBinding(file, known_as, version['name']) - file.write('DCHECK(fn.%sFn);\n' % known_as) + if not 'is_optional' in func or not func['is_optional']: + file.write('DCHECK(fn.%sFn);\n' % known_as) file.write('}\n') i += 1 first_version = False diff --git a/ui/gl/gl_bindings.h b/ui/gl/gl_bindings.h index 878e776..983ba7f 100644 --- a/ui/gl/gl_bindings.h +++ b/ui/gl/gl_bindings.h @@ -224,12 +224,36 @@ #endif #ifndef GL_CHROMIUM_path_rendering +#define GL_CHROMIUM_path_rendering 1 // These match the corresponding values in NV_path_rendering // extension, eg tokens with CHROMIUM replaced with NV. #define GL_PATH_MODELVIEW_MATRIX_CHROMIUM 0x0BA6 #define GL_PATH_PROJECTION_MATRIX_CHROMIUM 0x0BA7 #define GL_PATH_MODELVIEW_CHROMIUM 0x1700 #define GL_PATH_PROJECTION_CHROMIUM 0x1701 +#define GL_FLAT_CHROMIUM 0x1D00 +#define GL_CLOSE_PATH_CHROMIUM 0x00 +#define GL_MOVE_TO_CHROMIUM 0x02 +#define GL_LINE_TO_CHROMIUM 0x04 +#define GL_QUADRATIC_CURVE_TO_CHROMIUM 0x0A +#define GL_CUBIC_CURVE_TO_CHROMIUM 0x0C +#define GL_CONIC_CURVE_TO_CHROMIUM 0x1A +#define GL_PATH_STROKE_WIDTH_CHROMIUM 0x9075 +#define GL_PATH_END_CAPS_CHROMIUM 0x9076 +#define GL_PATH_JOIN_STYLE_CHROMIUM 0x9079 +#define GL_PATH_MITER_LIMIT_CHROMIUM 0x907a +#define GL_PATH_STROKE_BOUND_CHROMIUM 0x9086 +#define GL_COUNT_UP_CHROMIUM 0x9088 +#define GL_COUNT_DOWN_CHROMIUM 0x9089 +#define GL_CONVEX_HULL_CHROMIUM 0x908B +#define GL_BOUNDING_BOX_CHROMIUM 0x908D +#define GL_SQUARE_CHROMIUM 0x90a3 +#define GL_ROUND_CHROMIUM 0x90a4 +#define GL_BEVEL_CHROMIUM 0x90a6 +#define GL_MITER_REVERT_CHROMIUM 0x90a7 +#define GL_PATH_STENCIL_FUNC_CHROMIUM 0x90B7 +#define GL_PATH_STENCIL_REF_CHROMIUM 0x90B8 +#define GL_PATH_STENCIL_VALUE_MASK_CHROMIUM 0x90B9 #endif #ifndef GL_KHR_blend_equation_advanced diff --git a/ui/gl/gl_bindings_api_autogen_gl.h b/ui/gl/gl_bindings_api_autogen_gl.h index 81160fc..d75fdad 100644 --- a/ui/gl/gl_bindings_api_autogen_gl.h +++ b/ui/gl/gl_bindings_api_autogen_gl.h @@ -182,6 +182,8 @@ void glCopyTexSubImage3DFn(GLenum target, GLint y, GLsizei width, GLsizei height) override; +void glCoverFillPathNVFn(GLuint path, GLenum coverMode) override; +void glCoverStrokePathNVFn(GLuint name, GLenum coverMode) override; GLuint glCreateProgramFn(void) override; GLuint glCreateShaderFn(GLenum type) override; void glCullFaceFn(GLenum mode) override; @@ -189,6 +191,7 @@ void glDeleteBuffersARBFn(GLsizei n, const GLuint* buffers) override; void glDeleteFencesAPPLEFn(GLsizei n, const GLuint* fences) override; void glDeleteFencesNVFn(GLsizei n, const GLuint* fences) override; void glDeleteFramebuffersEXTFn(GLsizei n, const GLuint* framebuffers) override; +void glDeletePathsNVFn(GLuint path, GLsizei range) override; void glDeleteProgramFn(GLuint program) override; void glDeleteQueriesFn(GLsizei n, const GLuint* ids) override; void glDeleteRenderbuffersEXTFn(GLsizei n, @@ -279,6 +282,7 @@ void glGenerateMipmapEXTFn(GLenum target) override; void glGenFencesAPPLEFn(GLsizei n, GLuint* fences) override; void glGenFencesNVFn(GLsizei n, GLuint* fences) override; void glGenFramebuffersEXTFn(GLsizei n, GLuint* framebuffers) override; +GLuint glGenPathsNVFn(GLsizei range) override; void glGenQueriesFn(GLsizei n, GLuint* ids) override; void glGenRenderbuffersEXTFn(GLsizei n, GLuint* renderbuffers) override; void glGenSamplersFn(GLsizei n, GLuint* samplers) override; @@ -446,6 +450,7 @@ GLboolean glIsEnabledFn(GLenum cap) override; GLboolean glIsFenceAPPLEFn(GLuint fence) override; GLboolean glIsFenceNVFn(GLuint fence) override; GLboolean glIsFramebufferEXTFn(GLuint framebuffer) override; +GLboolean glIsPathNVFn(GLuint path) override; GLboolean glIsProgramFn(GLuint program) override; GLboolean glIsQueryFn(GLuint query) override; GLboolean glIsRenderbufferEXTFn(GLuint renderbuffer) override; @@ -464,6 +469,15 @@ void* glMapBufferRangeFn(GLenum target, GLbitfield access) override; void glMatrixLoadfEXTFn(GLenum matrixMode, const GLfloat* m) override; void glMatrixLoadIdentityEXTFn(GLenum matrixMode) override; +void glPathCommandsNVFn(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords) override; +void glPathParameterfNVFn(GLuint path, GLenum pname, GLfloat value) override; +void glPathParameteriNVFn(GLuint path, GLenum pname, GLint value) override; +void glPathStencilFuncNVFn(GLenum func, GLint ref, GLuint mask) override; void glPauseTransformFeedbackFn(void) override; void glPixelStoreiFn(GLenum pname, GLint param) override; void glPointParameteriFn(GLenum pname, GLint param) override; @@ -533,6 +547,7 @@ void glShaderSourceFn(GLuint shader, GLsizei count, const char* const* str, const GLint* length) override; +void glStencilFillPathNVFn(GLuint path, GLenum fillMode, GLuint mask) override; void glStencilFuncFn(GLenum func, GLint ref, GLuint mask) override; void glStencilFuncSeparateFn(GLenum face, GLenum func, @@ -545,6 +560,17 @@ void glStencilOpSeparateFn(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) override; +void glStencilStrokePathNVFn(GLuint path, + GLint reference, + GLuint mask) override; +void glStencilThenCoverFillPathNVFn(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) override; +void glStencilThenCoverStrokePathNVFn(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) override; GLboolean glTestFenceAPPLEFn(GLuint fence) override; GLboolean glTestFenceNVFn(GLuint fence) override; void glTexImage2DFn(GLenum target, diff --git a/ui/gl/gl_bindings_autogen_gl.cc b/ui/gl/gl_bindings_autogen_gl.cc index 391fe6f..c80729b 100644 --- a/ui/gl/gl_bindings_autogen_gl.cc +++ b/ui/gl/gl_bindings_autogen_gl.cc @@ -94,6 +94,8 @@ void DriverGL::InitializeStaticBindings() { fn.glCopyTexSubImage2DFn = reinterpret_cast<glCopyTexSubImage2DProc>( GetGLProcAddress("glCopyTexSubImage2D")); fn.glCopyTexSubImage3DFn = 0; + fn.glCoverFillPathNVFn = 0; + fn.glCoverStrokePathNVFn = 0; fn.glCreateProgramFn = reinterpret_cast<glCreateProgramProc>( GetGLProcAddress("glCreateProgram")); fn.glCreateShaderFn = @@ -105,6 +107,7 @@ void DriverGL::InitializeStaticBindings() { fn.glDeleteFencesAPPLEFn = 0; fn.glDeleteFencesNVFn = 0; fn.glDeleteFramebuffersEXTFn = 0; + fn.glDeletePathsNVFn = 0; fn.glDeleteProgramFn = reinterpret_cast<glDeleteProgramProc>( GetGLProcAddress("glDeleteProgram")); fn.glDeleteQueriesFn = 0; @@ -168,6 +171,7 @@ void DriverGL::InitializeStaticBindings() { fn.glGenFencesAPPLEFn = 0; fn.glGenFencesNVFn = 0; fn.glGenFramebuffersEXTFn = 0; + fn.glGenPathsNVFn = 0; fn.glGenQueriesFn = 0; fn.glGenRenderbuffersEXTFn = 0; fn.glGenSamplersFn = 0; @@ -265,6 +269,7 @@ void DriverGL::InitializeStaticBindings() { fn.glIsFenceAPPLEFn = 0; fn.glIsFenceNVFn = 0; fn.glIsFramebufferEXTFn = 0; + fn.glIsPathNVFn = 0; fn.glIsProgramFn = reinterpret_cast<glIsProgramProc>(GetGLProcAddress("glIsProgram")); fn.glIsQueryFn = 0; @@ -285,6 +290,10 @@ void DriverGL::InitializeStaticBindings() { fn.glMapBufferRangeFn = 0; fn.glMatrixLoadfEXTFn = 0; fn.glMatrixLoadIdentityEXTFn = 0; + fn.glPathCommandsNVFn = 0; + fn.glPathParameterfNVFn = 0; + fn.glPathParameteriNVFn = 0; + fn.glPathStencilFuncNVFn = 0; fn.glPauseTransformFeedbackFn = 0; fn.glPixelStoreiFn = reinterpret_cast<glPixelStoreiProc>(GetGLProcAddress("glPixelStorei")); @@ -319,6 +328,7 @@ void DriverGL::InitializeStaticBindings() { fn.glShaderBinaryFn = 0; fn.glShaderSourceFn = reinterpret_cast<glShaderSourceProc>(GetGLProcAddress("glShaderSource")); + fn.glStencilFillPathNVFn = 0; fn.glStencilFuncFn = reinterpret_cast<glStencilFuncProc>(GetGLProcAddress("glStencilFunc")); fn.glStencilFuncSeparateFn = reinterpret_cast<glStencilFuncSeparateProc>( @@ -331,6 +341,9 @@ void DriverGL::InitializeStaticBindings() { reinterpret_cast<glStencilOpProc>(GetGLProcAddress("glStencilOp")); fn.glStencilOpSeparateFn = reinterpret_cast<glStencilOpSeparateProc>( GetGLProcAddress("glStencilOpSeparate")); + fn.glStencilStrokePathNVFn = 0; + fn.glStencilThenCoverFillPathNVFn = 0; + fn.glStencilThenCoverStrokePathNVFn = 0; fn.glTestFenceAPPLEFn = 0; fn.glTestFenceNVFn = 0; fn.glTexImage2DFn = @@ -764,6 +777,20 @@ void DriverGL::InitializeDynamicBindings(GLContext* context) { DCHECK(fn.glCopyTexSubImage3DFn); } + debug_fn.glCoverFillPathNVFn = 0; + if (ext.b_GL_NV_path_rendering) { + fn.glCoverFillPathNVFn = reinterpret_cast<glCoverFillPathNVProc>( + GetGLProcAddress("glCoverFillPathNV")); + DCHECK(fn.glCoverFillPathNVFn); + } + + debug_fn.glCoverStrokePathNVFn = 0; + if (ext.b_GL_NV_path_rendering) { + fn.glCoverStrokePathNVFn = reinterpret_cast<glCoverStrokePathNVProc>( + GetGLProcAddress("glCoverStrokePathNV")); + DCHECK(fn.glCoverStrokePathNVFn); + } + debug_fn.glDeleteFencesAPPLEFn = 0; if (ext.b_GL_APPLE_fence) { fn.glDeleteFencesAPPLEFn = reinterpret_cast<glDeleteFencesAPPLEProc>( @@ -791,6 +818,13 @@ void DriverGL::InitializeDynamicBindings(GLContext* context) { DCHECK(fn.glDeleteFramebuffersEXTFn); } + debug_fn.glDeletePathsNVFn = 0; + if (ext.b_GL_NV_path_rendering) { + fn.glDeletePathsNVFn = reinterpret_cast<glDeletePathsNVProc>( + GetGLProcAddress("glDeletePathsNV")); + DCHECK(fn.glDeletePathsNVFn); + } + debug_fn.glDeleteQueriesFn = 0; if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) { fn.glDeleteQueriesFn = reinterpret_cast<glDeleteQueriesProc>( @@ -1097,6 +1131,13 @@ void DriverGL::InitializeDynamicBindings(GLContext* context) { DCHECK(fn.glGenFramebuffersEXTFn); } + debug_fn.glGenPathsNVFn = 0; + if (ext.b_GL_NV_path_rendering) { + fn.glGenPathsNVFn = + reinterpret_cast<glGenPathsNVProc>(GetGLProcAddress("glGenPathsNV")); + DCHECK(fn.glGenPathsNVFn); + } + debug_fn.glGenQueriesFn = 0; if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) { fn.glGenQueriesFn = @@ -1491,6 +1532,13 @@ void DriverGL::InitializeDynamicBindings(GLContext* context) { DCHECK(fn.glIsFramebufferEXTFn); } + debug_fn.glIsPathNVFn = 0; + if (ext.b_GL_NV_path_rendering) { + fn.glIsPathNVFn = + reinterpret_cast<glIsPathNVProc>(GetGLProcAddress("glIsPathNV")); + DCHECK(fn.glIsPathNVFn); + } + debug_fn.glIsQueryFn = 0; if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) { fn.glIsQueryFn = @@ -1594,6 +1642,34 @@ void DriverGL::InitializeDynamicBindings(GLContext* context) { DCHECK(fn.glMatrixLoadIdentityEXTFn); } + debug_fn.glPathCommandsNVFn = 0; + if (ext.b_GL_NV_path_rendering) { + fn.glPathCommandsNVFn = reinterpret_cast<glPathCommandsNVProc>( + GetGLProcAddress("glPathCommandsNV")); + DCHECK(fn.glPathCommandsNVFn); + } + + debug_fn.glPathParameterfNVFn = 0; + if (ext.b_GL_NV_path_rendering) { + fn.glPathParameterfNVFn = reinterpret_cast<glPathParameterfNVProc>( + GetGLProcAddress("glPathParameterfNV")); + DCHECK(fn.glPathParameterfNVFn); + } + + debug_fn.glPathParameteriNVFn = 0; + if (ext.b_GL_NV_path_rendering) { + fn.glPathParameteriNVFn = reinterpret_cast<glPathParameteriNVProc>( + GetGLProcAddress("glPathParameteriNV")); + DCHECK(fn.glPathParameteriNVFn); + } + + debug_fn.glPathStencilFuncNVFn = 0; + if (ext.b_GL_NV_path_rendering) { + fn.glPathStencilFuncNVFn = reinterpret_cast<glPathStencilFuncNVProc>( + GetGLProcAddress("glPathStencilFuncNV")); + DCHECK(fn.glPathStencilFuncNVFn); + } + debug_fn.glPauseTransformFeedbackFn = 0; if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(4u, 0u)) { fn.glPauseTransformFeedbackFn = @@ -1772,6 +1848,34 @@ void DriverGL::InitializeDynamicBindings(GLContext* context) { DCHECK(fn.glShaderBinaryFn); } + debug_fn.glStencilFillPathNVFn = 0; + if (ext.b_GL_NV_path_rendering) { + fn.glStencilFillPathNVFn = reinterpret_cast<glStencilFillPathNVProc>( + GetGLProcAddress("glStencilFillPathNV")); + DCHECK(fn.glStencilFillPathNVFn); + } + + debug_fn.glStencilStrokePathNVFn = 0; + if (ext.b_GL_NV_path_rendering) { + fn.glStencilStrokePathNVFn = reinterpret_cast<glStencilStrokePathNVProc>( + GetGLProcAddress("glStencilStrokePathNV")); + DCHECK(fn.glStencilStrokePathNVFn); + } + + debug_fn.glStencilThenCoverFillPathNVFn = 0; + if (ext.b_GL_NV_path_rendering) { + fn.glStencilThenCoverFillPathNVFn = + reinterpret_cast<glStencilThenCoverFillPathNVProc>( + GetGLProcAddress("glStencilThenCoverFillPathNV")); + } + + debug_fn.glStencilThenCoverStrokePathNVFn = 0; + if (ext.b_GL_NV_path_rendering) { + fn.glStencilThenCoverStrokePathNVFn = + reinterpret_cast<glStencilThenCoverStrokePathNVProc>( + GetGLProcAddress("glStencilThenCoverStrokePathNV")); + } + debug_fn.glTestFenceAPPLEFn = 0; if (ext.b_GL_APPLE_fence) { fn.glTestFenceAPPLEFn = reinterpret_cast<glTestFenceAPPLEProc>( @@ -2508,6 +2612,22 @@ static void GL_BINDING_CALL Debug_glCopyTexSubImage3D(GLenum target, zoffset, x, y, width, height); } +static void GL_BINDING_CALL +Debug_glCoverFillPathNV(GLuint path, GLenum coverMode) { + GL_SERVICE_LOG("glCoverFillPathNV" + << "(" << path << ", " << GLEnums::GetStringEnum(coverMode) + << ")"); + g_driver_gl.debug_fn.glCoverFillPathNVFn(path, coverMode); +} + +static void GL_BINDING_CALL +Debug_glCoverStrokePathNV(GLuint name, GLenum coverMode) { + GL_SERVICE_LOG("glCoverStrokePathNV" + << "(" << name << ", " << GLEnums::GetStringEnum(coverMode) + << ")"); + g_driver_gl.debug_fn.glCoverStrokePathNVFn(name, coverMode); +} + static GLuint GL_BINDING_CALL Debug_glCreateProgram(void) { GL_SERVICE_LOG("glCreateProgram" << "(" @@ -2563,6 +2683,12 @@ Debug_glDeleteFramebuffersEXT(GLsizei n, const GLuint* framebuffers) { g_driver_gl.debug_fn.glDeleteFramebuffersEXTFn(n, framebuffers); } +static void GL_BINDING_CALL Debug_glDeletePathsNV(GLuint path, GLsizei range) { + GL_SERVICE_LOG("glDeletePathsNV" + << "(" << path << ", " << range << ")"); + g_driver_gl.debug_fn.glDeletePathsNVFn(path, range); +} + static void GL_BINDING_CALL Debug_glDeleteProgram(GLuint program) { GL_SERVICE_LOG("glDeleteProgram" << "(" << program << ")"); @@ -2956,6 +3082,14 @@ Debug_glGenFramebuffersEXT(GLsizei n, GLuint* framebuffers) { g_driver_gl.debug_fn.glGenFramebuffersEXTFn(n, framebuffers); } +static GLuint GL_BINDING_CALL Debug_glGenPathsNV(GLsizei range) { + GL_SERVICE_LOG("glGenPathsNV" + << "(" << range << ")"); + GLuint result = g_driver_gl.debug_fn.glGenPathsNVFn(range); + GL_SERVICE_LOG("GL_RESULT: " << result); + return result; +} + static void GL_BINDING_CALL Debug_glGenQueries(GLsizei n, GLuint* ids) { GL_SERVICE_LOG("glGenQueries" << "(" << n << ", " << static_cast<const void*>(ids) << ")"); @@ -3638,6 +3772,14 @@ static GLboolean GL_BINDING_CALL Debug_glIsFramebufferEXT(GLuint framebuffer) { return result; } +static GLboolean GL_BINDING_CALL Debug_glIsPathNV(GLuint path) { + GL_SERVICE_LOG("glIsPathNV" + << "(" << path << ")"); + GLboolean result = g_driver_gl.debug_fn.glIsPathNVFn(path); + GL_SERVICE_LOG("GL_RESULT: " << result); + return result; +} + static GLboolean GL_BINDING_CALL Debug_glIsProgram(GLuint program) { GL_SERVICE_LOG("glIsProgram" << "(" << program << ")"); @@ -3759,6 +3901,45 @@ static void GL_BINDING_CALL Debug_glMatrixLoadIdentityEXT(GLenum matrixMode) { g_driver_gl.debug_fn.glMatrixLoadIdentityEXTFn(matrixMode); } +static void GL_BINDING_CALL Debug_glPathCommandsNV(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords) { + GL_SERVICE_LOG("glPathCommandsNV" + << "(" << path << ", " << numCommands << ", " + << static_cast<const void*>(commands) << ", " << numCoords + << ", " << GLEnums::GetStringEnum(coordType) << ", " + << static_cast<const void*>(coords) << ")"); + g_driver_gl.debug_fn.glPathCommandsNVFn(path, numCommands, commands, + numCoords, coordType, coords); +} + +static void GL_BINDING_CALL +Debug_glPathParameterfNV(GLuint path, GLenum pname, GLfloat value) { + GL_SERVICE_LOG("glPathParameterfNV" + << "(" << path << ", " << GLEnums::GetStringEnum(pname) << ", " + << value << ")"); + g_driver_gl.debug_fn.glPathParameterfNVFn(path, pname, value); +} + +static void GL_BINDING_CALL +Debug_glPathParameteriNV(GLuint path, GLenum pname, GLint value) { + GL_SERVICE_LOG("glPathParameteriNV" + << "(" << path << ", " << GLEnums::GetStringEnum(pname) << ", " + << value << ")"); + g_driver_gl.debug_fn.glPathParameteriNVFn(path, pname, value); +} + +static void GL_BINDING_CALL +Debug_glPathStencilFuncNV(GLenum func, GLint ref, GLuint mask) { + GL_SERVICE_LOG("glPathStencilFuncNV" + << "(" << GLEnums::GetStringEnum(func) << ", " << ref << ", " + << mask << ")"); + g_driver_gl.debug_fn.glPathStencilFuncNVFn(func, ref, mask); +} + static void GL_BINDING_CALL Debug_glPauseTransformFeedback(void) { GL_SERVICE_LOG("glPauseTransformFeedback" << "(" @@ -4033,6 +4214,14 @@ static void GL_BINDING_CALL Debug_glShaderSource(GLuint shader, } static void GL_BINDING_CALL +Debug_glStencilFillPathNV(GLuint path, GLenum fillMode, GLuint mask) { + GL_SERVICE_LOG("glStencilFillPathNV" + << "(" << path << ", " << GLEnums::GetStringEnum(fillMode) + << ", " << mask << ")"); + g_driver_gl.debug_fn.glStencilFillPathNVFn(path, fillMode, mask); +} + +static void GL_BINDING_CALL Debug_glStencilFunc(GLenum func, GLint ref, GLuint mask) { GL_SERVICE_LOG("glStencilFunc" << "(" << GLEnums::GetStringEnum(func) << ", " << ref << ", " @@ -4083,6 +4272,38 @@ static void GL_BINDING_CALL Debug_glStencilOpSeparate(GLenum face, g_driver_gl.debug_fn.glStencilOpSeparateFn(face, fail, zfail, zpass); } +static void GL_BINDING_CALL +Debug_glStencilStrokePathNV(GLuint path, GLint reference, GLuint mask) { + GL_SERVICE_LOG("glStencilStrokePathNV" + << "(" << path << ", " << reference << ", " << mask << ")"); + g_driver_gl.debug_fn.glStencilStrokePathNVFn(path, reference, mask); +} + +static void GL_BINDING_CALL +Debug_glStencilThenCoverFillPathNV(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) { + GL_SERVICE_LOG("glStencilThenCoverFillPathNV" + << "(" << path << ", " << GLEnums::GetStringEnum(fillMode) + << ", " << mask << ", " << GLEnums::GetStringEnum(coverMode) + << ")"); + g_driver_gl.debug_fn.glStencilThenCoverFillPathNVFn(path, fillMode, mask, + coverMode); +} + +static void GL_BINDING_CALL +Debug_glStencilThenCoverStrokePathNV(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) { + GL_SERVICE_LOG("glStencilThenCoverStrokePathNV" + << "(" << path << ", " << reference << ", " << mask << ", " + << GLEnums::GetStringEnum(coverMode) << ")"); + g_driver_gl.debug_fn.glStencilThenCoverStrokePathNVFn(path, reference, mask, + coverMode); +} + static GLboolean GL_BINDING_CALL Debug_glTestFenceAPPLE(GLuint fence) { GL_SERVICE_LOG("glTestFenceAPPLE" << "(" << fence << ")"); @@ -4916,6 +5137,14 @@ void DriverGL::InitializeDebugBindings() { debug_fn.glCopyTexSubImage3DFn = fn.glCopyTexSubImage3DFn; fn.glCopyTexSubImage3DFn = Debug_glCopyTexSubImage3D; } + if (!debug_fn.glCoverFillPathNVFn) { + debug_fn.glCoverFillPathNVFn = fn.glCoverFillPathNVFn; + fn.glCoverFillPathNVFn = Debug_glCoverFillPathNV; + } + if (!debug_fn.glCoverStrokePathNVFn) { + debug_fn.glCoverStrokePathNVFn = fn.glCoverStrokePathNVFn; + fn.glCoverStrokePathNVFn = Debug_glCoverStrokePathNV; + } if (!debug_fn.glCreateProgramFn) { debug_fn.glCreateProgramFn = fn.glCreateProgramFn; fn.glCreateProgramFn = Debug_glCreateProgram; @@ -4944,6 +5173,10 @@ void DriverGL::InitializeDebugBindings() { debug_fn.glDeleteFramebuffersEXTFn = fn.glDeleteFramebuffersEXTFn; fn.glDeleteFramebuffersEXTFn = Debug_glDeleteFramebuffersEXT; } + if (!debug_fn.glDeletePathsNVFn) { + debug_fn.glDeletePathsNVFn = fn.glDeletePathsNVFn; + fn.glDeletePathsNVFn = Debug_glDeletePathsNV; + } if (!debug_fn.glDeleteProgramFn) { debug_fn.glDeleteProgramFn = fn.glDeleteProgramFn; fn.glDeleteProgramFn = Debug_glDeleteProgram; @@ -5138,6 +5371,10 @@ void DriverGL::InitializeDebugBindings() { debug_fn.glGenFramebuffersEXTFn = fn.glGenFramebuffersEXTFn; fn.glGenFramebuffersEXTFn = Debug_glGenFramebuffersEXT; } + if (!debug_fn.glGenPathsNVFn) { + debug_fn.glGenPathsNVFn = fn.glGenPathsNVFn; + fn.glGenPathsNVFn = Debug_glGenPathsNV; + } if (!debug_fn.glGenQueriesFn) { debug_fn.glGenQueriesFn = fn.glGenQueriesFn; fn.glGenQueriesFn = Debug_glGenQueries; @@ -5421,6 +5658,10 @@ void DriverGL::InitializeDebugBindings() { debug_fn.glIsFramebufferEXTFn = fn.glIsFramebufferEXTFn; fn.glIsFramebufferEXTFn = Debug_glIsFramebufferEXT; } + if (!debug_fn.glIsPathNVFn) { + debug_fn.glIsPathNVFn = fn.glIsPathNVFn; + fn.glIsPathNVFn = Debug_glIsPathNV; + } if (!debug_fn.glIsProgramFn) { debug_fn.glIsProgramFn = fn.glIsProgramFn; fn.glIsProgramFn = Debug_glIsProgram; @@ -5481,6 +5722,22 @@ void DriverGL::InitializeDebugBindings() { debug_fn.glMatrixLoadIdentityEXTFn = fn.glMatrixLoadIdentityEXTFn; fn.glMatrixLoadIdentityEXTFn = Debug_glMatrixLoadIdentityEXT; } + if (!debug_fn.glPathCommandsNVFn) { + debug_fn.glPathCommandsNVFn = fn.glPathCommandsNVFn; + fn.glPathCommandsNVFn = Debug_glPathCommandsNV; + } + if (!debug_fn.glPathParameterfNVFn) { + debug_fn.glPathParameterfNVFn = fn.glPathParameterfNVFn; + fn.glPathParameterfNVFn = Debug_glPathParameterfNV; + } + if (!debug_fn.glPathParameteriNVFn) { + debug_fn.glPathParameteriNVFn = fn.glPathParameteriNVFn; + fn.glPathParameteriNVFn = Debug_glPathParameteriNV; + } + if (!debug_fn.glPathStencilFuncNVFn) { + debug_fn.glPathStencilFuncNVFn = fn.glPathStencilFuncNVFn; + fn.glPathStencilFuncNVFn = Debug_glPathStencilFuncNV; + } if (!debug_fn.glPauseTransformFeedbackFn) { debug_fn.glPauseTransformFeedbackFn = fn.glPauseTransformFeedbackFn; fn.glPauseTransformFeedbackFn = Debug_glPauseTransformFeedback; @@ -5601,6 +5858,10 @@ void DriverGL::InitializeDebugBindings() { debug_fn.glShaderSourceFn = fn.glShaderSourceFn; fn.glShaderSourceFn = Debug_glShaderSource; } + if (!debug_fn.glStencilFillPathNVFn) { + debug_fn.glStencilFillPathNVFn = fn.glStencilFillPathNVFn; + fn.glStencilFillPathNVFn = Debug_glStencilFillPathNV; + } if (!debug_fn.glStencilFuncFn) { debug_fn.glStencilFuncFn = fn.glStencilFuncFn; fn.glStencilFuncFn = Debug_glStencilFunc; @@ -5625,6 +5886,19 @@ void DriverGL::InitializeDebugBindings() { debug_fn.glStencilOpSeparateFn = fn.glStencilOpSeparateFn; fn.glStencilOpSeparateFn = Debug_glStencilOpSeparate; } + if (!debug_fn.glStencilStrokePathNVFn) { + debug_fn.glStencilStrokePathNVFn = fn.glStencilStrokePathNVFn; + fn.glStencilStrokePathNVFn = Debug_glStencilStrokePathNV; + } + if (!debug_fn.glStencilThenCoverFillPathNVFn) { + debug_fn.glStencilThenCoverFillPathNVFn = fn.glStencilThenCoverFillPathNVFn; + fn.glStencilThenCoverFillPathNVFn = Debug_glStencilThenCoverFillPathNV; + } + if (!debug_fn.glStencilThenCoverStrokePathNVFn) { + debug_fn.glStencilThenCoverStrokePathNVFn = + fn.glStencilThenCoverStrokePathNVFn; + fn.glStencilThenCoverStrokePathNVFn = Debug_glStencilThenCoverStrokePathNV; + } if (!debug_fn.glTestFenceAPPLEFn) { debug_fn.glTestFenceAPPLEFn = fn.glTestFenceAPPLEFn; fn.glTestFenceAPPLEFn = Debug_glTestFenceAPPLE; @@ -6231,6 +6505,14 @@ void GLApiBase::glCopyTexSubImage3DFn(GLenum target, y, width, height); } +void GLApiBase::glCoverFillPathNVFn(GLuint path, GLenum coverMode) { + driver_->fn.glCoverFillPathNVFn(path, coverMode); +} + +void GLApiBase::glCoverStrokePathNVFn(GLuint name, GLenum coverMode) { + driver_->fn.glCoverStrokePathNVFn(name, coverMode); +} + GLuint GLApiBase::glCreateProgramFn(void) { return driver_->fn.glCreateProgramFn(); } @@ -6260,6 +6542,10 @@ void GLApiBase::glDeleteFramebuffersEXTFn(GLsizei n, driver_->fn.glDeleteFramebuffersEXTFn(n, framebuffers); } +void GLApiBase::glDeletePathsNVFn(GLuint path, GLsizei range) { + driver_->fn.glDeletePathsNVFn(path, range); +} + void GLApiBase::glDeleteProgramFn(GLuint program) { driver_->fn.glDeleteProgramFn(program); } @@ -6497,6 +6783,10 @@ void GLApiBase::glGenFramebuffersEXTFn(GLsizei n, GLuint* framebuffers) { driver_->fn.glGenFramebuffersEXTFn(n, framebuffers); } +GLuint GLApiBase::glGenPathsNVFn(GLsizei range) { + return driver_->fn.glGenPathsNVFn(range); +} + void GLApiBase::glGenQueriesFn(GLsizei n, GLuint* ids) { driver_->fn.glGenQueriesFn(n, ids); } @@ -6899,6 +7189,10 @@ GLboolean GLApiBase::glIsFramebufferEXTFn(GLuint framebuffer) { return driver_->fn.glIsFramebufferEXTFn(framebuffer); } +GLboolean GLApiBase::glIsPathNVFn(GLuint path) { + return driver_->fn.glIsPathNVFn(path); +} + GLboolean GLApiBase::glIsProgramFn(GLuint program) { return driver_->fn.glIsProgramFn(program); } @@ -6962,6 +7256,28 @@ void GLApiBase::glMatrixLoadIdentityEXTFn(GLenum matrixMode) { driver_->fn.glMatrixLoadIdentityEXTFn(matrixMode); } +void GLApiBase::glPathCommandsNVFn(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords) { + driver_->fn.glPathCommandsNVFn(path, numCommands, commands, numCoords, + coordType, coords); +} + +void GLApiBase::glPathParameterfNVFn(GLuint path, GLenum pname, GLfloat value) { + driver_->fn.glPathParameterfNVFn(path, pname, value); +} + +void GLApiBase::glPathParameteriNVFn(GLuint path, GLenum pname, GLint value) { + driver_->fn.glPathParameteriNVFn(path, pname, value); +} + +void GLApiBase::glPathStencilFuncNVFn(GLenum func, GLint ref, GLuint mask) { + driver_->fn.glPathStencilFuncNVFn(func, ref, mask); +} + void GLApiBase::glPauseTransformFeedbackFn(void) { driver_->fn.glPauseTransformFeedbackFn(); } @@ -7123,6 +7439,12 @@ void GLApiBase::glShaderSourceFn(GLuint shader, driver_->fn.glShaderSourceFn(shader, count, str, length); } +void GLApiBase::glStencilFillPathNVFn(GLuint path, + GLenum fillMode, + GLuint mask) { + driver_->fn.glStencilFillPathNVFn(path, fillMode, mask); +} + void GLApiBase::glStencilFuncFn(GLenum func, GLint ref, GLuint mask) { driver_->fn.glStencilFuncFn(func, ref, mask); } @@ -7153,6 +7475,27 @@ void GLApiBase::glStencilOpSeparateFn(GLenum face, driver_->fn.glStencilOpSeparateFn(face, fail, zfail, zpass); } +void GLApiBase::glStencilStrokePathNVFn(GLuint path, + GLint reference, + GLuint mask) { + driver_->fn.glStencilStrokePathNVFn(path, reference, mask); +} + +void GLApiBase::glStencilThenCoverFillPathNVFn(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) { + driver_->fn.glStencilThenCoverFillPathNVFn(path, fillMode, mask, coverMode); +} + +void GLApiBase::glStencilThenCoverStrokePathNVFn(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) { + driver_->fn.glStencilThenCoverStrokePathNVFn(path, reference, mask, + coverMode); +} + GLboolean GLApiBase::glTestFenceAPPLEFn(GLuint fence) { return driver_->fn.glTestFenceAPPLEFn(fence); } @@ -7949,6 +8292,16 @@ void TraceGLApi::glCopyTexSubImage3DFn(GLenum target, width, height); } +void TraceGLApi::glCoverFillPathNVFn(GLuint path, GLenum coverMode) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glCoverFillPathNV") + gl_api_->glCoverFillPathNVFn(path, coverMode); +} + +void TraceGLApi::glCoverStrokePathNVFn(GLuint name, GLenum coverMode) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glCoverStrokePathNV") + gl_api_->glCoverStrokePathNVFn(name, coverMode); +} + GLuint TraceGLApi::glCreateProgramFn(void) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glCreateProgram") return gl_api_->glCreateProgramFn(); @@ -7985,6 +8338,11 @@ void TraceGLApi::glDeleteFramebuffersEXTFn(GLsizei n, gl_api_->glDeleteFramebuffersEXTFn(n, framebuffers); } +void TraceGLApi::glDeletePathsNVFn(GLuint path, GLsizei range) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glDeletePathsNV") + gl_api_->glDeletePathsNVFn(path, range); +} + void TraceGLApi::glDeleteProgramFn(GLuint program) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glDeleteProgram") gl_api_->glDeleteProgramFn(program); @@ -8275,6 +8633,11 @@ void TraceGLApi::glGenFramebuffersEXTFn(GLsizei n, GLuint* framebuffers) { gl_api_->glGenFramebuffersEXTFn(n, framebuffers); } +GLuint TraceGLApi::glGenPathsNVFn(GLsizei range) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glGenPathsNV") + return gl_api_->glGenPathsNVFn(range); +} + void TraceGLApi::glGenQueriesFn(GLsizei n, GLuint* ids) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glGenQueries") gl_api_->glGenQueriesFn(n, ids); @@ -8753,6 +9116,11 @@ GLboolean TraceGLApi::glIsFramebufferEXTFn(GLuint framebuffer) { return gl_api_->glIsFramebufferEXTFn(framebuffer); } +GLboolean TraceGLApi::glIsPathNVFn(GLuint path) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glIsPathNV") + return gl_api_->glIsPathNVFn(path); +} + GLboolean TraceGLApi::glIsProgramFn(GLuint program) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glIsProgram") return gl_api_->glIsProgramFn(program); @@ -8831,6 +9199,34 @@ void TraceGLApi::glMatrixLoadIdentityEXTFn(GLenum matrixMode) { gl_api_->glMatrixLoadIdentityEXTFn(matrixMode); } +void TraceGLApi::glPathCommandsNVFn(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glPathCommandsNV") + gl_api_->glPathCommandsNVFn(path, numCommands, commands, numCoords, coordType, + coords); +} + +void TraceGLApi::glPathParameterfNVFn(GLuint path, + GLenum pname, + GLfloat value) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glPathParameterfNV") + gl_api_->glPathParameterfNVFn(path, pname, value); +} + +void TraceGLApi::glPathParameteriNVFn(GLuint path, GLenum pname, GLint value) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glPathParameteriNV") + gl_api_->glPathParameteriNVFn(path, pname, value); +} + +void TraceGLApi::glPathStencilFuncNVFn(GLenum func, GLint ref, GLuint mask) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glPathStencilFuncNV") + gl_api_->glPathStencilFuncNVFn(func, ref, mask); +} + void TraceGLApi::glPauseTransformFeedbackFn(void) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glPauseTransformFeedback") gl_api_->glPauseTransformFeedbackFn(); @@ -9024,6 +9420,13 @@ void TraceGLApi::glShaderSourceFn(GLuint shader, gl_api_->glShaderSourceFn(shader, count, str, length); } +void TraceGLApi::glStencilFillPathNVFn(GLuint path, + GLenum fillMode, + GLuint mask) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glStencilFillPathNV") + gl_api_->glStencilFillPathNVFn(path, fillMode, mask); +} + void TraceGLApi::glStencilFuncFn(GLenum func, GLint ref, GLuint mask) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glStencilFunc") gl_api_->glStencilFuncFn(func, ref, mask); @@ -9060,6 +9463,31 @@ void TraceGLApi::glStencilOpSeparateFn(GLenum face, gl_api_->glStencilOpSeparateFn(face, fail, zfail, zpass); } +void TraceGLApi::glStencilStrokePathNVFn(GLuint path, + GLint reference, + GLuint mask) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glStencilStrokePathNV") + gl_api_->glStencilStrokePathNVFn(path, reference, mask); +} + +void TraceGLApi::glStencilThenCoverFillPathNVFn(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", + "TraceGLAPI::glStencilThenCoverFillPathNV") + gl_api_->glStencilThenCoverFillPathNVFn(path, fillMode, mask, coverMode); +} + +void TraceGLApi::glStencilThenCoverStrokePathNVFn(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", + "TraceGLAPI::glStencilThenCoverStrokePathNV") + gl_api_->glStencilThenCoverStrokePathNVFn(path, reference, mask, coverMode); +} + GLboolean TraceGLApi::glTestFenceAPPLEFn(GLuint fence) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::glTestFenceAPPLE") return gl_api_->glTestFenceAPPLEFn(fence); @@ -9961,6 +10389,19 @@ void NoContextGLApi::glCopyTexSubImage3DFn(GLenum target, << "Trying to call glCopyTexSubImage3D() without current GL context"; } +void NoContextGLApi::glCoverFillPathNVFn(GLuint path, GLenum coverMode) { + NOTREACHED() + << "Trying to call glCoverFillPathNV() without current GL context"; + LOG(ERROR) << "Trying to call glCoverFillPathNV() without current GL context"; +} + +void NoContextGLApi::glCoverStrokePathNVFn(GLuint name, GLenum coverMode) { + NOTREACHED() + << "Trying to call glCoverStrokePathNV() without current GL context"; + LOG(ERROR) + << "Trying to call glCoverStrokePathNV() without current GL context"; +} + GLuint NoContextGLApi::glCreateProgramFn(void) { NOTREACHED() << "Trying to call glCreateProgram() without current GL context"; LOG(ERROR) << "Trying to call glCreateProgram() without current GL context"; @@ -10006,6 +10447,11 @@ void NoContextGLApi::glDeleteFramebuffersEXTFn(GLsizei n, << "Trying to call glDeleteFramebuffersEXT() without current GL context"; } +void NoContextGLApi::glDeletePathsNVFn(GLuint path, GLsizei range) { + NOTREACHED() << "Trying to call glDeletePathsNV() without current GL context"; + LOG(ERROR) << "Trying to call glDeletePathsNV() without current GL context"; +} + void NoContextGLApi::glDeleteProgramFn(GLuint program) { NOTREACHED() << "Trying to call glDeleteProgram() without current GL context"; LOG(ERROR) << "Trying to call glDeleteProgram() without current GL context"; @@ -10334,6 +10780,12 @@ void NoContextGLApi::glGenFramebuffersEXTFn(GLsizei n, GLuint* framebuffers) { << "Trying to call glGenFramebuffersEXT() without current GL context"; } +GLuint NoContextGLApi::glGenPathsNVFn(GLsizei range) { + NOTREACHED() << "Trying to call glGenPathsNV() without current GL context"; + LOG(ERROR) << "Trying to call glGenPathsNV() without current GL context"; + return 0U; +} + void NoContextGLApi::glGenQueriesFn(GLsizei n, GLuint* ids) { NOTREACHED() << "Trying to call glGenQueries() without current GL context"; LOG(ERROR) << "Trying to call glGenQueries() without current GL context"; @@ -10909,6 +11361,12 @@ GLboolean NoContextGLApi::glIsFramebufferEXTFn(GLuint framebuffer) { return GL_FALSE; } +GLboolean NoContextGLApi::glIsPathNVFn(GLuint path) { + NOTREACHED() << "Trying to call glIsPathNV() without current GL context"; + LOG(ERROR) << "Trying to call glIsPathNV() without current GL context"; + return GL_FALSE; +} + GLboolean NoContextGLApi::glIsProgramFn(GLuint program) { NOTREACHED() << "Trying to call glIsProgram() without current GL context"; LOG(ERROR) << "Trying to call glIsProgram() without current GL context"; @@ -11008,6 +11466,44 @@ void NoContextGLApi::glMatrixLoadIdentityEXTFn(GLenum matrixMode) { << "Trying to call glMatrixLoadIdentityEXT() without current GL context"; } +void NoContextGLApi::glPathCommandsNVFn(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords) { + NOTREACHED() + << "Trying to call glPathCommandsNV() without current GL context"; + LOG(ERROR) << "Trying to call glPathCommandsNV() without current GL context"; +} + +void NoContextGLApi::glPathParameterfNVFn(GLuint path, + GLenum pname, + GLfloat value) { + NOTREACHED() + << "Trying to call glPathParameterfNV() without current GL context"; + LOG(ERROR) + << "Trying to call glPathParameterfNV() without current GL context"; +} + +void NoContextGLApi::glPathParameteriNVFn(GLuint path, + GLenum pname, + GLint value) { + NOTREACHED() + << "Trying to call glPathParameteriNV() without current GL context"; + LOG(ERROR) + << "Trying to call glPathParameteriNV() without current GL context"; +} + +void NoContextGLApi::glPathStencilFuncNVFn(GLenum func, + GLint ref, + GLuint mask) { + NOTREACHED() + << "Trying to call glPathStencilFuncNV() without current GL context"; + LOG(ERROR) + << "Trying to call glPathStencilFuncNV() without current GL context"; +} + void NoContextGLApi::glPauseTransformFeedbackFn(void) { NOTREACHED() << "Trying to call glPauseTransformFeedback() without current GL context"; @@ -11232,6 +11728,15 @@ void NoContextGLApi::glShaderSourceFn(GLuint shader, LOG(ERROR) << "Trying to call glShaderSource() without current GL context"; } +void NoContextGLApi::glStencilFillPathNVFn(GLuint path, + GLenum fillMode, + GLuint mask) { + NOTREACHED() + << "Trying to call glStencilFillPathNV() without current GL context"; + LOG(ERROR) + << "Trying to call glStencilFillPathNV() without current GL context"; +} + void NoContextGLApi::glStencilFuncFn(GLenum func, GLint ref, GLuint mask) { NOTREACHED() << "Trying to call glStencilFunc() without current GL context"; LOG(ERROR) << "Trying to call glStencilFunc() without current GL context"; @@ -11274,6 +11779,35 @@ void NoContextGLApi::glStencilOpSeparateFn(GLenum face, << "Trying to call glStencilOpSeparate() without current GL context"; } +void NoContextGLApi::glStencilStrokePathNVFn(GLuint path, + GLint reference, + GLuint mask) { + NOTREACHED() + << "Trying to call glStencilStrokePathNV() without current GL context"; + LOG(ERROR) + << "Trying to call glStencilStrokePathNV() without current GL context"; +} + +void NoContextGLApi::glStencilThenCoverFillPathNVFn(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) { + NOTREACHED() << "Trying to call glStencilThenCoverFillPathNV() without " + "current GL context"; + LOG(ERROR) << "Trying to call glStencilThenCoverFillPathNV() without current " + "GL context"; +} + +void NoContextGLApi::glStencilThenCoverStrokePathNVFn(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) { + NOTREACHED() << "Trying to call glStencilThenCoverStrokePathNV() without " + "current GL context"; + LOG(ERROR) << "Trying to call glStencilThenCoverStrokePathNV() without " + "current GL context"; +} + GLboolean NoContextGLApi::glTestFenceAPPLEFn(GLuint fence) { NOTREACHED() << "Trying to call glTestFenceAPPLE() without current GL context"; diff --git a/ui/gl/gl_bindings_autogen_gl.h b/ui/gl/gl_bindings_autogen_gl.h index 1689361..3a16380 100644 --- a/ui/gl/gl_bindings_autogen_gl.h +++ b/ui/gl/gl_bindings_autogen_gl.h @@ -198,6 +198,10 @@ typedef void(GL_BINDING_CALL* glCopyTexSubImage3DProc)(GLenum target, GLint y, GLsizei width, GLsizei height); +typedef void(GL_BINDING_CALL* glCoverFillPathNVProc)(GLuint path, + GLenum coverMode); +typedef void(GL_BINDING_CALL* glCoverStrokePathNVProc)(GLuint name, + GLenum coverMode); typedef GLuint(GL_BINDING_CALL* glCreateProgramProc)(void); typedef GLuint(GL_BINDING_CALL* glCreateShaderProc)(GLenum type); typedef void(GL_BINDING_CALL* glCullFaceProc)(GLenum mode); @@ -210,6 +214,7 @@ typedef void(GL_BINDING_CALL* glDeleteFencesNVProc)(GLsizei n, typedef void(GL_BINDING_CALL* glDeleteFramebuffersEXTProc)( GLsizei n, const GLuint* framebuffers); +typedef void(GL_BINDING_CALL* glDeletePathsNVProc)(GLuint path, GLsizei range); typedef void(GL_BINDING_CALL* glDeleteProgramProc)(GLuint program); typedef void(GL_BINDING_CALL* glDeleteQueriesProc)(GLsizei n, const GLuint* ids); @@ -322,6 +327,7 @@ typedef void(GL_BINDING_CALL* glGenFencesAPPLEProc)(GLsizei n, GLuint* fences); typedef void(GL_BINDING_CALL* glGenFencesNVProc)(GLsizei n, GLuint* fences); typedef void(GL_BINDING_CALL* glGenFramebuffersEXTProc)(GLsizei n, GLuint* framebuffers); +typedef GLuint(GL_BINDING_CALL* glGenPathsNVProc)(GLsizei range); typedef void(GL_BINDING_CALL* glGenQueriesProc)(GLsizei n, GLuint* ids); typedef void(GL_BINDING_CALL* glGenRenderbuffersEXTProc)(GLsizei n, GLuint* renderbuffers); @@ -540,6 +546,7 @@ typedef GLboolean(GL_BINDING_CALL* glIsEnabledProc)(GLenum cap); typedef GLboolean(GL_BINDING_CALL* glIsFenceAPPLEProc)(GLuint fence); typedef GLboolean(GL_BINDING_CALL* glIsFenceNVProc)(GLuint fence); typedef GLboolean(GL_BINDING_CALL* glIsFramebufferEXTProc)(GLuint framebuffer); +typedef GLboolean(GL_BINDING_CALL* glIsPathNVProc)(GLuint path); typedef GLboolean(GL_BINDING_CALL* glIsProgramProc)(GLuint program); typedef GLboolean(GL_BINDING_CALL* glIsQueryProc)(GLuint query); typedef GLboolean(GL_BINDING_CALL* glIsRenderbufferEXTProc)( @@ -560,6 +567,21 @@ typedef void*(GL_BINDING_CALL* glMapBufferRangeProc)(GLenum target, typedef void(GL_BINDING_CALL* glMatrixLoadfEXTProc)(GLenum matrixMode, const GLfloat* m); typedef void(GL_BINDING_CALL* glMatrixLoadIdentityEXTProc)(GLenum matrixMode); +typedef void(GL_BINDING_CALL* glPathCommandsNVProc)(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords); +typedef void(GL_BINDING_CALL* glPathParameterfNVProc)(GLuint path, + GLenum pname, + GLfloat value); +typedef void(GL_BINDING_CALL* glPathParameteriNVProc)(GLuint path, + GLenum pname, + GLint value); +typedef void(GL_BINDING_CALL* glPathStencilFuncNVProc)(GLenum func, + GLint ref, + GLuint mask); typedef void(GL_BINDING_CALL* glPauseTransformFeedbackProc)(void); typedef void(GL_BINDING_CALL* glPixelStoreiProc)(GLenum pname, GLint param); typedef void(GL_BINDING_CALL* glPointParameteriProc)(GLenum pname, GLint param); @@ -644,6 +666,9 @@ typedef void(GL_BINDING_CALL* glShaderSourceProc)(GLuint shader, GLsizei count, const char* const* str, const GLint* length); +typedef void(GL_BINDING_CALL* glStencilFillPathNVProc)(GLuint path, + GLenum fillMode, + GLuint mask); typedef void(GL_BINDING_CALL* glStencilFuncProc)(GLenum func, GLint ref, GLuint mask); @@ -661,6 +686,19 @@ typedef void(GL_BINDING_CALL* glStencilOpSeparateProc)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass); +typedef void(GL_BINDING_CALL* glStencilStrokePathNVProc)(GLuint path, + GLint reference, + GLuint mask); +typedef void(GL_BINDING_CALL* glStencilThenCoverFillPathNVProc)( + GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode); +typedef void(GL_BINDING_CALL* glStencilThenCoverStrokePathNVProc)( + GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode); typedef GLboolean(GL_BINDING_CALL* glTestFenceAPPLEProc)(GLuint fence); typedef GLboolean(GL_BINDING_CALL* glTestFenceNVProc)(GLuint fence); typedef void(GL_BINDING_CALL* glTexImage2DProc)(GLenum target, @@ -999,6 +1037,8 @@ struct ProcsGL { glCopyTexImage2DProc glCopyTexImage2DFn; glCopyTexSubImage2DProc glCopyTexSubImage2DFn; glCopyTexSubImage3DProc glCopyTexSubImage3DFn; + glCoverFillPathNVProc glCoverFillPathNVFn; + glCoverStrokePathNVProc glCoverStrokePathNVFn; glCreateProgramProc glCreateProgramFn; glCreateShaderProc glCreateShaderFn; glCullFaceProc glCullFaceFn; @@ -1006,6 +1046,7 @@ struct ProcsGL { glDeleteFencesAPPLEProc glDeleteFencesAPPLEFn; glDeleteFencesNVProc glDeleteFencesNVFn; glDeleteFramebuffersEXTProc glDeleteFramebuffersEXTFn; + glDeletePathsNVProc glDeletePathsNVFn; glDeleteProgramProc glDeleteProgramFn; glDeleteQueriesProc glDeleteQueriesFn; glDeleteRenderbuffersEXTProc glDeleteRenderbuffersEXTFn; @@ -1056,6 +1097,7 @@ struct ProcsGL { glGenFencesAPPLEProc glGenFencesAPPLEFn; glGenFencesNVProc glGenFencesNVFn; glGenFramebuffersEXTProc glGenFramebuffersEXTFn; + glGenPathsNVProc glGenPathsNVFn; glGenQueriesProc glGenQueriesFn; glGenRenderbuffersEXTProc glGenRenderbuffersEXTFn; glGenSamplersProc glGenSamplersFn; @@ -1126,6 +1168,7 @@ struct ProcsGL { glIsFenceAPPLEProc glIsFenceAPPLEFn; glIsFenceNVProc glIsFenceNVFn; glIsFramebufferEXTProc glIsFramebufferEXTFn; + glIsPathNVProc glIsPathNVFn; glIsProgramProc glIsProgramFn; glIsQueryProc glIsQueryFn; glIsRenderbufferEXTProc glIsRenderbufferEXTFn; @@ -1141,6 +1184,10 @@ struct ProcsGL { glMapBufferRangeProc glMapBufferRangeFn; glMatrixLoadfEXTProc glMatrixLoadfEXTFn; glMatrixLoadIdentityEXTProc glMatrixLoadIdentityEXTFn; + glPathCommandsNVProc glPathCommandsNVFn; + glPathParameterfNVProc glPathParameterfNVFn; + glPathParameteriNVProc glPathParameteriNVFn; + glPathStencilFuncNVProc glPathStencilFuncNVFn; glPauseTransformFeedbackProc glPauseTransformFeedbackFn; glPixelStoreiProc glPixelStoreiFn; glPointParameteriProc glPointParameteriFn; @@ -1170,12 +1217,16 @@ struct ProcsGL { glSetFenceNVProc glSetFenceNVFn; glShaderBinaryProc glShaderBinaryFn; glShaderSourceProc glShaderSourceFn; + glStencilFillPathNVProc glStencilFillPathNVFn; glStencilFuncProc glStencilFuncFn; glStencilFuncSeparateProc glStencilFuncSeparateFn; glStencilMaskProc glStencilMaskFn; glStencilMaskSeparateProc glStencilMaskSeparateFn; glStencilOpProc glStencilOpFn; glStencilOpSeparateProc glStencilOpSeparateFn; + glStencilStrokePathNVProc glStencilStrokePathNVFn; + glStencilThenCoverFillPathNVProc glStencilThenCoverFillPathNVFn; + glStencilThenCoverStrokePathNVProc glStencilThenCoverStrokePathNVFn; glTestFenceAPPLEProc glTestFenceAPPLEFn; glTestFenceNVProc glTestFenceNVFn; glTexImage2DProc glTexImage2DFn; @@ -1426,6 +1477,8 @@ class GL_EXPORT GLApi { GLint y, GLsizei width, GLsizei height) = 0; + virtual void glCoverFillPathNVFn(GLuint path, GLenum coverMode) = 0; + virtual void glCoverStrokePathNVFn(GLuint name, GLenum coverMode) = 0; virtual GLuint glCreateProgramFn(void) = 0; virtual GLuint glCreateShaderFn(GLenum type) = 0; virtual void glCullFaceFn(GLenum mode) = 0; @@ -1434,6 +1487,7 @@ class GL_EXPORT GLApi { virtual void glDeleteFencesNVFn(GLsizei n, const GLuint* fences) = 0; virtual void glDeleteFramebuffersEXTFn(GLsizei n, const GLuint* framebuffers) = 0; + virtual void glDeletePathsNVFn(GLuint path, GLsizei range) = 0; virtual void glDeleteProgramFn(GLuint program) = 0; virtual void glDeleteQueriesFn(GLsizei n, const GLuint* ids) = 0; virtual void glDeleteRenderbuffersEXTFn(GLsizei n, @@ -1525,6 +1579,7 @@ class GL_EXPORT GLApi { virtual void glGenFencesAPPLEFn(GLsizei n, GLuint* fences) = 0; virtual void glGenFencesNVFn(GLsizei n, GLuint* fences) = 0; virtual void glGenFramebuffersEXTFn(GLsizei n, GLuint* framebuffers) = 0; + virtual GLuint glGenPathsNVFn(GLsizei range) = 0; virtual void glGenQueriesFn(GLsizei n, GLuint* ids) = 0; virtual void glGenRenderbuffersEXTFn(GLsizei n, GLuint* renderbuffers) = 0; virtual void glGenSamplersFn(GLsizei n, GLuint* samplers) = 0; @@ -1710,6 +1765,7 @@ class GL_EXPORT GLApi { virtual GLboolean glIsFenceAPPLEFn(GLuint fence) = 0; virtual GLboolean glIsFenceNVFn(GLuint fence) = 0; virtual GLboolean glIsFramebufferEXTFn(GLuint framebuffer) = 0; + virtual GLboolean glIsPathNVFn(GLuint path) = 0; virtual GLboolean glIsProgramFn(GLuint program) = 0; virtual GLboolean glIsQueryFn(GLuint query) = 0; virtual GLboolean glIsRenderbufferEXTFn(GLuint renderbuffer) = 0; @@ -1728,6 +1784,17 @@ class GL_EXPORT GLApi { GLbitfield access) = 0; virtual void glMatrixLoadfEXTFn(GLenum matrixMode, const GLfloat* m) = 0; virtual void glMatrixLoadIdentityEXTFn(GLenum matrixMode) = 0; + virtual void glPathCommandsNVFn(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords) = 0; + virtual void glPathParameterfNVFn(GLuint path, + GLenum pname, + GLfloat value) = 0; + virtual void glPathParameteriNVFn(GLuint path, GLenum pname, GLint value) = 0; + virtual void glPathStencilFuncNVFn(GLenum func, GLint ref, GLuint mask) = 0; virtual void glPauseTransformFeedbackFn(void) = 0; virtual void glPixelStoreiFn(GLenum pname, GLint param) = 0; virtual void glPointParameteriFn(GLenum pname, GLint param) = 0; @@ -1801,6 +1868,9 @@ class GL_EXPORT GLApi { GLsizei count, const char* const* str, const GLint* length) = 0; + virtual void glStencilFillPathNVFn(GLuint path, + GLenum fillMode, + GLuint mask) = 0; virtual void glStencilFuncFn(GLenum func, GLint ref, GLuint mask) = 0; virtual void glStencilFuncSeparateFn(GLenum face, GLenum func, @@ -1813,6 +1883,17 @@ class GL_EXPORT GLApi { GLenum fail, GLenum zfail, GLenum zpass) = 0; + virtual void glStencilStrokePathNVFn(GLuint path, + GLint reference, + GLuint mask) = 0; + virtual void glStencilThenCoverFillPathNVFn(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) = 0; + virtual void glStencilThenCoverStrokePathNVFn(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) = 0; virtual GLboolean glTestFenceAPPLEFn(GLuint fence) = 0; virtual GLboolean glTestFenceNVFn(GLuint fence) = 0; virtual void glTexImage2DFn(GLenum target, @@ -2097,6 +2178,8 @@ class GL_EXPORT GLApi { #define glCopyTexImage2D ::gfx::g_current_gl_context->glCopyTexImage2DFn #define glCopyTexSubImage2D ::gfx::g_current_gl_context->glCopyTexSubImage2DFn #define glCopyTexSubImage3D ::gfx::g_current_gl_context->glCopyTexSubImage3DFn +#define glCoverFillPathNV ::gfx::g_current_gl_context->glCoverFillPathNVFn +#define glCoverStrokePathNV ::gfx::g_current_gl_context->glCoverStrokePathNVFn #define glCreateProgram ::gfx::g_current_gl_context->glCreateProgramFn #define glCreateShader ::gfx::g_current_gl_context->glCreateShaderFn #define glCullFace ::gfx::g_current_gl_context->glCullFaceFn @@ -2105,6 +2188,7 @@ class GL_EXPORT GLApi { #define glDeleteFencesNV ::gfx::g_current_gl_context->glDeleteFencesNVFn #define glDeleteFramebuffersEXT \ ::gfx::g_current_gl_context->glDeleteFramebuffersEXTFn +#define glDeletePathsNV ::gfx::g_current_gl_context->glDeletePathsNVFn #define glDeleteProgram ::gfx::g_current_gl_context->glDeleteProgramFn #define glDeleteQueries ::gfx::g_current_gl_context->glDeleteQueriesFn #define glDeleteRenderbuffersEXT \ @@ -2169,6 +2253,7 @@ class GL_EXPORT GLApi { #define glGenFencesAPPLE ::gfx::g_current_gl_context->glGenFencesAPPLEFn #define glGenFencesNV ::gfx::g_current_gl_context->glGenFencesNVFn #define glGenFramebuffersEXT ::gfx::g_current_gl_context->glGenFramebuffersEXTFn +#define glGenPathsNV ::gfx::g_current_gl_context->glGenPathsNVFn #define glGenQueries ::gfx::g_current_gl_context->glGenQueriesFn #define glGenRenderbuffersEXT \ ::gfx::g_current_gl_context->glGenRenderbuffersEXTFn @@ -2263,6 +2348,7 @@ class GL_EXPORT GLApi { #define glIsFenceAPPLE ::gfx::g_current_gl_context->glIsFenceAPPLEFn #define glIsFenceNV ::gfx::g_current_gl_context->glIsFenceNVFn #define glIsFramebufferEXT ::gfx::g_current_gl_context->glIsFramebufferEXTFn +#define glIsPathNV ::gfx::g_current_gl_context->glIsPathNVFn #define glIsProgram ::gfx::g_current_gl_context->glIsProgramFn #define glIsQuery ::gfx::g_current_gl_context->glIsQueryFn #define glIsRenderbufferEXT ::gfx::g_current_gl_context->glIsRenderbufferEXTFn @@ -2280,6 +2366,10 @@ class GL_EXPORT GLApi { #define glMatrixLoadfEXT ::gfx::g_current_gl_context->glMatrixLoadfEXTFn #define glMatrixLoadIdentityEXT \ ::gfx::g_current_gl_context->glMatrixLoadIdentityEXTFn +#define glPathCommandsNV ::gfx::g_current_gl_context->glPathCommandsNVFn +#define glPathParameterfNV ::gfx::g_current_gl_context->glPathParameterfNVFn +#define glPathParameteriNV ::gfx::g_current_gl_context->glPathParameteriNVFn +#define glPathStencilFuncNV ::gfx::g_current_gl_context->glPathStencilFuncNVFn #define glPauseTransformFeedback \ ::gfx::g_current_gl_context->glPauseTransformFeedbackFn #define glPixelStorei ::gfx::g_current_gl_context->glPixelStoreiFn @@ -2316,6 +2406,7 @@ class GL_EXPORT GLApi { #define glSetFenceNV ::gfx::g_current_gl_context->glSetFenceNVFn #define glShaderBinary ::gfx::g_current_gl_context->glShaderBinaryFn #define glShaderSource ::gfx::g_current_gl_context->glShaderSourceFn +#define glStencilFillPathNV ::gfx::g_current_gl_context->glStencilFillPathNVFn #define glStencilFunc ::gfx::g_current_gl_context->glStencilFuncFn #define glStencilFuncSeparate \ ::gfx::g_current_gl_context->glStencilFuncSeparateFn @@ -2324,6 +2415,12 @@ class GL_EXPORT GLApi { ::gfx::g_current_gl_context->glStencilMaskSeparateFn #define glStencilOp ::gfx::g_current_gl_context->glStencilOpFn #define glStencilOpSeparate ::gfx::g_current_gl_context->glStencilOpSeparateFn +#define glStencilStrokePathNV \ + ::gfx::g_current_gl_context->glStencilStrokePathNVFn +#define glStencilThenCoverFillPathNV \ + ::gfx::g_current_gl_context->glStencilThenCoverFillPathNVFn +#define glStencilThenCoverStrokePathNV \ + ::gfx::g_current_gl_context->glStencilThenCoverStrokePathNVFn #define glTestFenceAPPLE ::gfx::g_current_gl_context->glTestFenceAPPLEFn #define glTestFenceNV ::gfx::g_current_gl_context->glTestFenceNVFn #define glTexImage2D ::gfx::g_current_gl_context->glTexImage2DFn diff --git a/ui/gl/gl_bindings_autogen_mock.cc b/ui/gl/gl_bindings_autogen_mock.cc index b5a82ee..23940cd 100644 --- a/ui/gl/gl_bindings_autogen_mock.cc +++ b/ui/gl/gl_bindings_autogen_mock.cc @@ -475,6 +475,18 @@ void GL_BINDING_CALL MockGLInterface::Mock_glCopyTexSubImage3D(GLenum target, width, height); } +void GL_BINDING_CALL +MockGLInterface::Mock_glCoverFillPathNV(GLuint path, GLenum coverMode) { + MakeFunctionUnique("glCoverFillPathNV"); + interface_->CoverFillPathNV(path, coverMode); +} + +void GL_BINDING_CALL +MockGLInterface::Mock_glCoverStrokePathNV(GLuint name, GLenum coverMode) { + MakeFunctionUnique("glCoverStrokePathNV"); + interface_->CoverStrokePathNV(name, coverMode); +} + GLuint GL_BINDING_CALL MockGLInterface::Mock_glCreateProgram(void) { MakeFunctionUnique("glCreateProgram"); return interface_->CreateProgram(); @@ -522,6 +534,12 @@ MockGLInterface::Mock_glDeleteFramebuffersEXT(GLsizei n, interface_->DeleteFramebuffersEXT(n, framebuffers); } +void GL_BINDING_CALL +MockGLInterface::Mock_glDeletePathsNV(GLuint path, GLsizei range) { + MakeFunctionUnique("glDeletePathsNV"); + interface_->DeletePathsNV(path, range); +} + void GL_BINDING_CALL MockGLInterface::Mock_glDeleteProgram(GLuint program) { MakeFunctionUnique("glDeleteProgram"); interface_->DeleteProgram(program); @@ -950,6 +968,11 @@ MockGLInterface::Mock_glGenFramebuffersEXT(GLsizei n, GLuint* framebuffers) { interface_->GenFramebuffersEXT(n, framebuffers); } +GLuint GL_BINDING_CALL MockGLInterface::Mock_glGenPathsNV(GLsizei range) { + MakeFunctionUnique("glGenPathsNV"); + return interface_->GenPathsNV(range); +} + void GL_BINDING_CALL MockGLInterface::Mock_glGenQueries(GLsizei n, GLuint* ids) { MakeFunctionUnique("glGenQueries"); @@ -1627,6 +1650,11 @@ MockGLInterface::Mock_glIsFramebufferEXT(GLuint framebuffer) { return interface_->IsFramebufferEXT(framebuffer); } +GLboolean GL_BINDING_CALL MockGLInterface::Mock_glIsPathNV(GLuint path) { + MakeFunctionUnique("glIsPathNV"); + return interface_->IsPathNV(path); +} + GLboolean GL_BINDING_CALL MockGLInterface::Mock_glIsProgram(GLuint program) { MakeFunctionUnique("glIsProgram"); return interface_->IsProgram(program); @@ -1754,6 +1782,38 @@ MockGLInterface::Mock_glMatrixLoadfEXT(GLenum matrixMode, const GLfloat* m) { interface_->MatrixLoadfEXT(matrixMode, m); } +void GL_BINDING_CALL +MockGLInterface::Mock_glPathCommandsNV(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords) { + MakeFunctionUnique("glPathCommandsNV"); + interface_->PathCommandsNV(path, numCommands, commands, numCoords, coordType, + coords); +} + +void GL_BINDING_CALL MockGLInterface::Mock_glPathParameterfNV(GLuint path, + GLenum pname, + GLfloat value) { + MakeFunctionUnique("glPathParameterfNV"); + interface_->PathParameterfNV(path, pname, value); +} + +void GL_BINDING_CALL MockGLInterface::Mock_glPathParameteriNV(GLuint path, + GLenum pname, + GLint value) { + MakeFunctionUnique("glPathParameteriNV"); + interface_->PathParameteriNV(path, pname, value); +} + +void GL_BINDING_CALL +MockGLInterface::Mock_glPathStencilFuncNV(GLenum func, GLint ref, GLuint mask) { + MakeFunctionUnique("glPathStencilFuncNV"); + interface_->PathStencilFuncNV(func, ref, mask); +} + void GL_BINDING_CALL MockGLInterface::Mock_glPauseTransformFeedback(void) { MakeFunctionUnique("glPauseTransformFeedback"); interface_->PauseTransformFeedback(); @@ -1986,6 +2046,13 @@ MockGLInterface::Mock_glShaderSource(GLuint shader, interface_->ShaderSource(shader, count, str, length); } +void GL_BINDING_CALL MockGLInterface::Mock_glStencilFillPathNV(GLuint path, + GLenum fillMode, + GLuint mask) { + MakeFunctionUnique("glStencilFillPathNV"); + interface_->StencilFillPathNV(path, fillMode, mask); +} + void GL_BINDING_CALL MockGLInterface::Mock_glStencilFunc(GLenum func, GLint ref, GLuint mask) { MakeFunctionUnique("glStencilFunc"); @@ -2025,6 +2092,32 @@ void GL_BINDING_CALL MockGLInterface::Mock_glStencilOpSeparate(GLenum face, interface_->StencilOpSeparate(face, fail, zfail, zpass); } +void GL_BINDING_CALL +MockGLInterface::Mock_glStencilStrokePathNV(GLuint path, + GLint reference, + GLuint mask) { + MakeFunctionUnique("glStencilStrokePathNV"); + interface_->StencilStrokePathNV(path, reference, mask); +} + +void GL_BINDING_CALL +MockGLInterface::Mock_glStencilThenCoverFillPathNV(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) { + MakeFunctionUnique("glStencilThenCoverFillPathNV"); + interface_->StencilThenCoverFillPathNV(path, fillMode, mask, coverMode); +} + +void GL_BINDING_CALL +MockGLInterface::Mock_glStencilThenCoverStrokePathNV(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) { + MakeFunctionUnique("glStencilThenCoverStrokePathNV"); + interface_->StencilThenCoverStrokePathNV(path, reference, mask, coverMode); +} + GLboolean GL_BINDING_CALL MockGLInterface::Mock_glTestFenceAPPLE(GLuint fence) { MakeFunctionUnique("glTestFenceAPPLE"); return interface_->TestFenceAPPLE(fence); @@ -2697,6 +2790,10 @@ void* GL_BINDING_CALL MockGLInterface::GetGLProcAddress(const char* name) { return reinterpret_cast<void*>(Mock_glCopyTexSubImage2D); if (strcmp(name, "glCopyTexSubImage3D") == 0) return reinterpret_cast<void*>(Mock_glCopyTexSubImage3D); + if (strcmp(name, "glCoverFillPathNV") == 0) + return reinterpret_cast<void*>(Mock_glCoverFillPathNV); + if (strcmp(name, "glCoverStrokePathNV") == 0) + return reinterpret_cast<void*>(Mock_glCoverStrokePathNV); if (strcmp(name, "glCreateProgram") == 0) return reinterpret_cast<void*>(Mock_glCreateProgram); if (strcmp(name, "glCreateShader") == 0) @@ -2713,6 +2810,8 @@ void* GL_BINDING_CALL MockGLInterface::GetGLProcAddress(const char* name) { return reinterpret_cast<void*>(Mock_glDeleteFramebuffers); if (strcmp(name, "glDeleteFramebuffersEXT") == 0) return reinterpret_cast<void*>(Mock_glDeleteFramebuffersEXT); + if (strcmp(name, "glDeletePathsNV") == 0) + return reinterpret_cast<void*>(Mock_glDeletePathsNV); if (strcmp(name, "glDeleteProgram") == 0) return reinterpret_cast<void*>(Mock_glDeleteProgram); if (strcmp(name, "glDeleteQueries") == 0) @@ -2837,6 +2936,8 @@ void* GL_BINDING_CALL MockGLInterface::GetGLProcAddress(const char* name) { return reinterpret_cast<void*>(Mock_glGenFramebuffers); if (strcmp(name, "glGenFramebuffersEXT") == 0) return reinterpret_cast<void*>(Mock_glGenFramebuffersEXT); + if (strcmp(name, "glGenPathsNV") == 0) + return reinterpret_cast<void*>(Mock_glGenPathsNV); if (strcmp(name, "glGenQueries") == 0) return reinterpret_cast<void*>(Mock_glGenQueries); if (strcmp(name, "glGenQueriesARB") == 0) @@ -3020,6 +3121,8 @@ void* GL_BINDING_CALL MockGLInterface::GetGLProcAddress(const char* name) { return reinterpret_cast<void*>(Mock_glIsFramebuffer); if (strcmp(name, "glIsFramebufferEXT") == 0) return reinterpret_cast<void*>(Mock_glIsFramebufferEXT); + if (strcmp(name, "glIsPathNV") == 0) + return reinterpret_cast<void*>(Mock_glIsPathNV); if (strcmp(name, "glIsProgram") == 0) return reinterpret_cast<void*>(Mock_glIsProgram); if (strcmp(name, "glIsQuery") == 0) @@ -3064,6 +3167,14 @@ void* GL_BINDING_CALL MockGLInterface::GetGLProcAddress(const char* name) { return reinterpret_cast<void*>(Mock_glMatrixLoadIdentityEXT); if (strcmp(name, "glMatrixLoadfEXT") == 0) return reinterpret_cast<void*>(Mock_glMatrixLoadfEXT); + if (strcmp(name, "glPathCommandsNV") == 0) + return reinterpret_cast<void*>(Mock_glPathCommandsNV); + if (strcmp(name, "glPathParameterfNV") == 0) + return reinterpret_cast<void*>(Mock_glPathParameterfNV); + if (strcmp(name, "glPathParameteriNV") == 0) + return reinterpret_cast<void*>(Mock_glPathParameteriNV); + if (strcmp(name, "glPathStencilFuncNV") == 0) + return reinterpret_cast<void*>(Mock_glPathStencilFuncNV); if (strcmp(name, "glPauseTransformFeedback") == 0) return reinterpret_cast<void*>(Mock_glPauseTransformFeedback); if (strcmp(name, "glPixelStorei") == 0) @@ -3126,6 +3237,8 @@ void* GL_BINDING_CALL MockGLInterface::GetGLProcAddress(const char* name) { return reinterpret_cast<void*>(Mock_glShaderBinary); if (strcmp(name, "glShaderSource") == 0) return reinterpret_cast<void*>(Mock_glShaderSource); + if (strcmp(name, "glStencilFillPathNV") == 0) + return reinterpret_cast<void*>(Mock_glStencilFillPathNV); if (strcmp(name, "glStencilFunc") == 0) return reinterpret_cast<void*>(Mock_glStencilFunc); if (strcmp(name, "glStencilFuncSeparate") == 0) @@ -3138,6 +3251,12 @@ void* GL_BINDING_CALL MockGLInterface::GetGLProcAddress(const char* name) { return reinterpret_cast<void*>(Mock_glStencilOp); if (strcmp(name, "glStencilOpSeparate") == 0) return reinterpret_cast<void*>(Mock_glStencilOpSeparate); + if (strcmp(name, "glStencilStrokePathNV") == 0) + return reinterpret_cast<void*>(Mock_glStencilStrokePathNV); + if (strcmp(name, "glStencilThenCoverFillPathNV") == 0) + return reinterpret_cast<void*>(Mock_glStencilThenCoverFillPathNV); + if (strcmp(name, "glStencilThenCoverStrokePathNV") == 0) + return reinterpret_cast<void*>(Mock_glStencilThenCoverStrokePathNV); if (strcmp(name, "glTestFenceAPPLE") == 0) return reinterpret_cast<void*>(Mock_glTestFenceAPPLE); if (strcmp(name, "glTestFenceNV") == 0) diff --git a/ui/gl/gl_bindings_autogen_mock.h b/ui/gl/gl_bindings_autogen_mock.h index 9dc82a0..5125ea1 100644 --- a/ui/gl/gl_bindings_autogen_mock.h +++ b/ui/gl/gl_bindings_autogen_mock.h @@ -189,6 +189,10 @@ static void GL_BINDING_CALL Mock_glCopyTexSubImage3D(GLenum target, GLint y, GLsizei width, GLsizei height); +static void GL_BINDING_CALL +Mock_glCoverFillPathNV(GLuint path, GLenum coverMode); +static void GL_BINDING_CALL +Mock_glCoverStrokePathNV(GLuint name, GLenum coverMode); static GLuint GL_BINDING_CALL Mock_glCreateProgram(void); static GLuint GL_BINDING_CALL Mock_glCreateShader(GLenum type); static void GL_BINDING_CALL Mock_glCullFace(GLenum mode); @@ -202,6 +206,7 @@ static void GL_BINDING_CALL Mock_glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers); static void GL_BINDING_CALL Mock_glDeleteFramebuffersEXT(GLsizei n, const GLuint* framebuffers); +static void GL_BINDING_CALL Mock_glDeletePathsNV(GLuint path, GLsizei range); static void GL_BINDING_CALL Mock_glDeleteProgram(GLuint program); static void GL_BINDING_CALL Mock_glDeleteQueries(GLsizei n, const GLuint* ids); static void GL_BINDING_CALL @@ -349,6 +354,7 @@ static void GL_BINDING_CALL Mock_glGenFramebuffers(GLsizei n, GLuint* framebuffers); static void GL_BINDING_CALL Mock_glGenFramebuffersEXT(GLsizei n, GLuint* framebuffers); +static GLuint GL_BINDING_CALL Mock_glGenPathsNV(GLsizei range); static void GL_BINDING_CALL Mock_glGenQueries(GLsizei n, GLuint* ids); static void GL_BINDING_CALL Mock_glGenQueriesARB(GLsizei n, GLuint* ids); static void GL_BINDING_CALL Mock_glGenQueriesEXT(GLsizei n, GLuint* ids); @@ -582,6 +588,7 @@ static GLboolean GL_BINDING_CALL Mock_glIsFenceAPPLE(GLuint fence); static GLboolean GL_BINDING_CALL Mock_glIsFenceNV(GLuint fence); static GLboolean GL_BINDING_CALL Mock_glIsFramebuffer(GLuint framebuffer); static GLboolean GL_BINDING_CALL Mock_glIsFramebufferEXT(GLuint framebuffer); +static GLboolean GL_BINDING_CALL Mock_glIsPathNV(GLuint path); static GLboolean GL_BINDING_CALL Mock_glIsProgram(GLuint program); static GLboolean GL_BINDING_CALL Mock_glIsQuery(GLuint query); static GLboolean GL_BINDING_CALL Mock_glIsQueryARB(GLuint query); @@ -611,6 +618,18 @@ static void* GL_BINDING_CALL Mock_glMapBufferRangeEXT(GLenum target, static void GL_BINDING_CALL Mock_glMatrixLoadIdentityEXT(GLenum matrixMode); static void GL_BINDING_CALL Mock_glMatrixLoadfEXT(GLenum matrixMode, const GLfloat* m); +static void GL_BINDING_CALL Mock_glPathCommandsNV(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords); +static void GL_BINDING_CALL +Mock_glPathParameterfNV(GLuint path, GLenum pname, GLfloat value); +static void GL_BINDING_CALL +Mock_glPathParameteriNV(GLuint path, GLenum pname, GLint value); +static void GL_BINDING_CALL +Mock_glPathStencilFuncNV(GLenum func, GLint ref, GLuint mask); static void GL_BINDING_CALL Mock_glPauseTransformFeedback(void); static void GL_BINDING_CALL Mock_glPixelStorei(GLenum pname, GLint param); static void GL_BINDING_CALL Mock_glPointParameteri(GLenum pname, GLint param); @@ -696,6 +715,8 @@ static void GL_BINDING_CALL Mock_glShaderSource(GLuint shader, const char* const* str, const GLint* length); static void GL_BINDING_CALL +Mock_glStencilFillPathNV(GLuint path, GLenum fillMode, GLuint mask); +static void GL_BINDING_CALL Mock_glStencilFunc(GLenum func, GLint ref, GLuint mask); static void GL_BINDING_CALL Mock_glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); @@ -706,6 +727,17 @@ static void GL_BINDING_CALL Mock_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass); static void GL_BINDING_CALL Mock_glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass); +static void GL_BINDING_CALL +Mock_glStencilStrokePathNV(GLuint path, GLint reference, GLuint mask); +static void GL_BINDING_CALL Mock_glStencilThenCoverFillPathNV(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode); +static void GL_BINDING_CALL +Mock_glStencilThenCoverStrokePathNV(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode); static GLboolean GL_BINDING_CALL Mock_glTestFenceAPPLE(GLuint fence); static GLboolean GL_BINDING_CALL Mock_glTestFenceNV(GLuint fence); static void GL_BINDING_CALL Mock_glTexImage2D(GLenum target, diff --git a/ui/gl/gl_enums_implementation_autogen.h b/ui/gl/gl_enums_implementation_autogen.h index 9bd294e..2952663 100644 --- a/ui/gl/gl_enums_implementation_autogen.h +++ b/ui/gl/gl_enums_implementation_autogen.h @@ -98,6 +98,10 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_LINES_ADJACENCY_EXT", }, { + 0x8DCA, + "GL_INT_SAMPLER_2D", + }, + { 0x92CF, "GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT", }, @@ -502,6 +506,10 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_NUM_PROGRAM_BINARY_FORMATS_OES", }, { + 0x8A2D, + "GL_MAX_FRAGMENT_UNIFORM_BLOCKS", + }, + { 0x8A41, "GL_UNIFORM_BLOCK_NAME_LENGTH", }, @@ -530,10 +538,6 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_UNIFORM_BLOCK_DATA_SIZE", }, { - 0x9242, - "GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM", - }, - { 0x821D, "GL_NUM_EXTENSIONS", }, @@ -586,6 +590,10 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL", }, { + 0x90a4, + "GL_ROUND_CHROMIUM", + }, + { 0x8A48, "GL_TEXTURE_SRGB_DECODE_EXT", }, @@ -594,6 +602,10 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_CONTEXT_LOST", }, { + 0x90a3, + "GL_SQUARE_CHROMIUM", + }, + { 0x02000000, "GL_MULTISAMPLE_BUFFER_BIT1_QCOM", }, @@ -754,6 +766,10 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_RENDERBUFFER", }, { + 0x90B7, + "GL_PATH_STENCIL_FUNC_CHROMIUM", + }, + { 0x8A3A, "GL_UNIFORM_BLOCK_INDEX", }, @@ -762,10 +778,22 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_DITHER", }, { + 0x90B9, + "GL_PATH_STENCIL_VALUE_MASK_CHROMIUM", + }, + { + 0x90B8, + "GL_PATH_STENCIL_REF_CHROMIUM", + }, + { 0x93D3, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR", }, { + 0x1D00, + "GL_FLAT_CHROMIUM", + }, + { 0x9144, "GL_MAX_DEBUG_LOGGED_MESSAGES_KHR", }, @@ -1086,6 +1114,10 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_SAMPLE_COVERAGE", }, { + 0x0C, + "GL_CUBIC_CURVE_TO_CHROMIUM", + }, + { 0x928F, "GL_DST_ATOP_NV", }, @@ -1190,6 +1222,10 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE", }, { + 0x8DCC, + "GL_INT_SAMPLER_CUBE", + }, + { 0x0308, "GL_SRC_ALPHA_SATURATE", }, @@ -1322,6 +1358,10 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_SAMPLE_COVERAGE_INVERT", }, { + 0x8A3D, + "GL_UNIFORM_MATRIX_STRIDE", + }, + { 0x8E7D, "GL_MAX_PATCH_VERTICES_EXT", }, @@ -1446,12 +1486,12 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT", }, { - 0x8C85, - "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE", + 0x90A6, + "GL_BEVEL_CHROMIUM", }, { - 0x8D7C, - "GL_RGBA8UI", + 0x90A7, + "GL_MITER_REVERT_CHROMIUM", }, { 0x6007, @@ -1814,6 +1854,10 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_LEQUAL", }, { + 0x8DC6, + "GL_UNSIGNED_INT_VEC2", + }, + { 0x8BD6, "GL_TEXTURE_FORMAT_QCOM", }, @@ -1942,12 +1986,12 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_UNIFORM_BUFFER_SIZE", }, { - 0x8DCC, - "GL_INT_SAMPLER_CUBE", + 0x04, + "GL_LINE_TO_CHROMIUM", }, { - 0x78F1, - "GL_MAP_CHROMIUM", + 0x0BA7, + "GL_PATH_PROJECTION_MATRIX_CHROMIUM", }, { 0x00080000, @@ -1958,10 +2002,18 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_LINEARLIGHT_NV", }, { + 0x00, + "GL_CLOSE_PATH_CHROMIUM", + }, + { 0x8DCF, "GL_INT_SAMPLER_2D_ARRAY", }, { + 0x02, + "GL_MOVE_TO_CHROMIUM", + }, + { 0x886A, "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED", }, @@ -1970,10 +2022,22 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_SRGB8_NV", }, { + 0x9079, + "GL_PATH_JOIN_STYLE_CHROMIUM", + }, + { 0x0C01, "GL_DRAW_BUFFER_EXT", }, { + 0x9075, + "GL_PATH_STROKE_WIDTH_CHROMIUM", + }, + { + 0x9076, + "GL_PATH_END_CAPS_CHROMIUM", + }, + { 0x886C, "GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT", }, @@ -1982,8 +2046,8 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT", }, { - 0x8DCA, - "GL_INT_SAMPLER_2D", + 0x9086, + "GL_PATH_STROKE_BOUND_CHROMIUM", }, { 0x93C7, @@ -2090,8 +2154,8 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_BOOL_VEC3", }, { - 0x8A3D, - "GL_UNIFORM_MATRIX_STRIDE", + 0x907a, + "GL_PATH_MITER_LIMIT_CHROMIUM", }, { 0x8828, @@ -2202,10 +2266,6 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_RG8UI", }, { - 0x9240, - "GL_UNPACK_FLIP_Y_CHROMIUM", - }, - { 0x8DF6, "GL_UNSIGNED_INT_10_10_10_2_OES", }, @@ -2490,8 +2550,8 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_TEXTURE10", }, { - 0x0BA7, - "GL_PATH_PROJECTION_MATRIX_CHROMIUM", + 0x78F1, + "GL_MAP_CHROMIUM", }, { 0x84CF, @@ -3078,6 +3138,10 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_TEXTURE4", }, { + 0x1A, + "GL_CONIC_CURVE_TO_CHROMIUM", + }, + { 0x821C, "GL_MINOR_VERSION", }, @@ -3414,6 +3478,14 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_BUFFER_MAP_OFFSET", }, { + 0x9089, + "GL_COUNT_DOWN_CHROMIUM", + }, + { + 0x9088, + "GL_COUNT_UP_CHROMIUM", + }, + { 0x00004000, "GL_COLOR_BUFFER_BIT", }, @@ -3478,10 +3550,6 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_FLOAT_MAT2x3_NV", }, { - 0x9241, - "GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM", - }, - { 0x00010000, "GL_STENCIL_BUFFER_BIT0_QCOM", }, @@ -3498,6 +3566,10 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_FENCE_STATUS_NV", }, { + 0x908D, + "GL_BOUNDING_BOX_CHROMIUM", + }, + { 0x88E6, "GL_STATIC_COPY", }, @@ -3566,8 +3638,8 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_TEXTURE_BORDER_COLOR_EXT", }, { - 0x8A2D, - "GL_MAX_FRAGMENT_UNIFORM_BLOCKS", + 0x908B, + "GL_CONVEX_HULL_CHROMIUM", }, { 0x8B48, @@ -3698,6 +3770,10 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_R8UI", }, { + 0x90A4, + "GL_ROUND_CHROMIUM", + }, + { 0x150A, "GL_INVERT", }, @@ -3770,6 +3846,10 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_DEPTH_BUFFER_BIT1_QCOM", }, { + 0x8C85, + "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE", + }, + { 0x00008000, "GL_COVERAGE_BUFFER_BIT_NV", }, @@ -3910,8 +3990,8 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_MAX_TEXTURE_IMAGE_UNITS", }, { - 0x8DC6, - "GL_UNSIGNED_INT_VEC2", + 0x0A, + "GL_QUADRATIC_CURVE_TO_CHROMIUM", }, { 0x8905, @@ -4058,6 +4138,10 @@ static const GLEnums::EnumToString enum_to_string_table[] = { "GL_COMPRESSED_SRGB8_ETC2", }, { + 0x8D7C, + "GL_RGBA8UI", + }, + { 0x84D5, "GL_TEXTURE21", }, diff --git a/ui/gl/gl_mock_autogen_gl.h b/ui/gl/gl_mock_autogen_gl.h index 2840661..bd08515 100644 --- a/ui/gl/gl_mock_autogen_gl.h +++ b/ui/gl/gl_mock_autogen_gl.h @@ -168,6 +168,8 @@ MOCK_METHOD9(CopyTexSubImage3D, GLint y, GLsizei width, GLsizei height)); +MOCK_METHOD2(CoverFillPathNV, void(GLuint path, GLenum coverMode)); +MOCK_METHOD2(CoverStrokePathNV, void(GLuint name, GLenum coverMode)); MOCK_METHOD0(CreateProgram, GLuint()); MOCK_METHOD1(CreateShader, GLuint(GLenum type)); MOCK_METHOD1(CullFace, void(GLenum mode)); @@ -176,6 +178,7 @@ MOCK_METHOD2(DeleteFencesAPPLE, void(GLsizei n, const GLuint* fences)); MOCK_METHOD2(DeleteFencesNV, void(GLsizei n, const GLuint* fences)); MOCK_METHOD2(DeleteFramebuffersEXT, void(GLsizei n, const GLuint* framebuffers)); +MOCK_METHOD2(DeletePathsNV, void(GLuint path, GLsizei range)); MOCK_METHOD1(DeleteProgram, void(GLuint program)); MOCK_METHOD2(DeleteQueries, void(GLsizei n, const GLuint* ids)); MOCK_METHOD2(DeleteRenderbuffersEXT, @@ -270,6 +273,7 @@ MOCK_METHOD1(GenerateMipmapEXT, void(GLenum target)); MOCK_METHOD2(GenFencesAPPLE, void(GLsizei n, GLuint* fences)); MOCK_METHOD2(GenFencesNV, void(GLsizei n, GLuint* fences)); MOCK_METHOD2(GenFramebuffersEXT, void(GLsizei n, GLuint* framebuffers)); +MOCK_METHOD1(GenPathsNV, GLuint(GLsizei range)); MOCK_METHOD2(GenQueries, void(GLsizei n, GLuint* ids)); MOCK_METHOD2(GenRenderbuffersEXT, void(GLsizei n, GLuint* renderbuffers)); MOCK_METHOD2(GenSamplers, void(GLsizei n, GLuint* samplers)); @@ -436,6 +440,7 @@ MOCK_METHOD1(IsEnabled, GLboolean(GLenum cap)); MOCK_METHOD1(IsFenceAPPLE, GLboolean(GLuint fence)); MOCK_METHOD1(IsFenceNV, GLboolean(GLuint fence)); MOCK_METHOD1(IsFramebufferEXT, GLboolean(GLuint framebuffer)); +MOCK_METHOD1(IsPathNV, GLboolean(GLuint path)); MOCK_METHOD1(IsProgram, GLboolean(GLuint program)); MOCK_METHOD1(IsQuery, GLboolean(GLuint query)); MOCK_METHOD1(IsRenderbufferEXT, GLboolean(GLuint renderbuffer)); @@ -455,6 +460,16 @@ MOCK_METHOD4(MapBufferRange, GLbitfield access)); MOCK_METHOD2(MatrixLoadfEXT, void(GLenum matrixMode, const GLfloat* m)); MOCK_METHOD1(MatrixLoadIdentityEXT, void(GLenum matrixMode)); +MOCK_METHOD6(PathCommandsNV, + void(GLuint path, + GLsizei numCommands, + const GLubyte* commands, + GLsizei numCoords, + GLenum coordType, + const GLvoid* coords)); +MOCK_METHOD3(PathParameterfNV, void(GLuint path, GLenum pname, GLfloat value)); +MOCK_METHOD3(PathParameteriNV, void(GLuint path, GLenum pname, GLint value)); +MOCK_METHOD3(PathStencilFuncNV, void(GLenum func, GLint ref, GLuint mask)); MOCK_METHOD0(PauseTransformFeedback, void()); MOCK_METHOD2(PixelStorei, void(GLenum pname, GLint param)); MOCK_METHOD2(PointParameteri, void(GLenum pname, GLint param)); @@ -530,6 +545,8 @@ MOCK_METHOD4(ShaderSource, GLsizei count, const char* const* str, const GLint* length)); +MOCK_METHOD3(StencilFillPathNV, + void(GLuint path, GLenum fillMode, GLuint mask)); MOCK_METHOD3(StencilFunc, void(GLenum func, GLint ref, GLuint mask)); MOCK_METHOD4(StencilFuncSeparate, void(GLenum face, GLenum func, GLint ref, GLuint mask)); @@ -538,6 +555,12 @@ MOCK_METHOD2(StencilMaskSeparate, void(GLenum face, GLuint mask)); MOCK_METHOD3(StencilOp, void(GLenum fail, GLenum zfail, GLenum zpass)); MOCK_METHOD4(StencilOpSeparate, void(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)); +MOCK_METHOD3(StencilStrokePathNV, + void(GLuint path, GLint reference, GLuint mask)); +MOCK_METHOD4(StencilThenCoverFillPathNV, + void(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode)); +MOCK_METHOD4(StencilThenCoverStrokePathNV, + void(GLuint path, GLint reference, GLuint mask, GLenum coverMode)); MOCK_METHOD1(TestFenceAPPLE, GLboolean(GLuint fence)); MOCK_METHOD1(TestFenceNV, GLboolean(GLuint fence)); MOCK_METHOD9(TexImage2D, |