diff options
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, |