diff options
author | kkinnunen <kkinnunen@nvidia.com> | 2015-11-01 23:57:51 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-11-02 07:58:41 +0000 |
commit | c8b449e1586d545db9f6692efa0aa4f990bc9658 (patch) | |
tree | b3476907ba1385152760ca374e40dad008ebe9da /gpu/GLES2 | |
parent | b907c9c34c99ed5445d2f94a8ef4a2fbc85808f6 (diff) | |
download | chromium_src-c8b449e1586d545db9f6692efa0aa4f990bc9658.zip chromium_src-c8b449e1586d545db9f6692efa0aa4f990bc9658.tar.gz chromium_src-c8b449e1586d545db9f6692efa0aa4f990bc9658.tar.bz2 |
command_buffer: Support textured path rendering for CHROMIUM_path_rendering
Implement support textured path rendering in gpu command buffer for
CHROMIUM_path_rendering.
Add the concept of "fragment input" to the system: a fragment input is a
fragment shader varying in the case the fragment shader of a shader
program is used without the vertex shader. A fragment input can be
referenced by the varying name in the shader code. As the vertex shader
is skipped during path rendering, the fragment inputs will be populated
with the functions added in this commit.
Add following functions to the command buffer:
BindFragmentInputLocationCHROMIUM
ProgramPathFragmentInputGenCHROMIUM
BindFragmentInputLocationCHROMIUM will bind a fragment input to a
location supplied by the caller. The fragment input is identified by the
varying name. The semantics of the call are similar to
BindUniformLocationCHROMIUM, but of course the location bound with
BindFragmentInputLocationCHROMIUM is part of fragment input location
range.
Concretely, BindFragmentInputLocationCHROMIUM is used to obtain a
location to pass to ProgramPathFragmentInputGenCHROMIUM.
ProgramPathFragmentInputGenCHROMIUM sets the "path fragment input
generator" property of the fragment input identified by the location
passed by the caller. This property, together with global path
modelview transform and global path projection transform is used to
generate the value of the fragment input.
Concretely, ProgramPathFragmentInputGenCHROMIUM is used to obtain a
value in the fragment input that is somehow relative to the fragment
position in on the path coverage. When drawing normal vertex-based
primitives, shading is done by setting the vertex position with an
attribute or an uniform, the transform with an attribute or an uniform,
transforming the position with the transform in vertex shader and
interpolating the values for fragment varying. When drawing a path, the
path position is set with projection and modelview matrix, transform is
set with ProgramPathFragmentInputGenCHROMIUM and the system will then
fill the fragment input based on the location of the fragment in the
area covered by the path and the input generator mode (eye space or
model space).
Implement the BindFragmentInputLocationCHROMIUM by the means of program
interface query API, which is part of OpenGL 4.3 and OpenGL ES 3.1.
Alternatively, OpenGL pre 4.3 can have the functionality through
ARB_program_interface_query. glGetProgramInterfaceiv,
glGetProgramResourceiv, glGetProgramResourceName and
glGetProgramResourceLocation are used to query the program for its
fragment inputs after successful link. This list is then used to map
caller-bound locations to actual locations. This is similar to existing
logic for bound uniform and attribute locations. Note: this patch does
not provide getter for fragment input location, so unbound fragment
und locations to actual locations. This is similar to existing
logic for bound uniform and attribute locations. Note: this patch does
not provide getter for fragment input location, so unbound fragment
inputs can not be used by the caller. Providing this would require
implementation of the interface query API, which is too elaborate to be
implemented without proper consumers. Note: as the query API is not
available for the client, the fragment input information is not
serialized between client and the service.
Implement the ProgramPathFragmentInputGenCHROMIUM by means of
NV_path_rendering ProgramPathFragmentInputGenNV. This is part of
NV_path_rendering spec version 1.3.
Changes gpu::gles2::ProgramManager to reference FeatureInfo of the
ContextGroup, because the queries for the fragment input is only done if
path rendering is enabled.
Changes program_manager_unittests to have a common test base class.
Remove some client/service program id constants from test functions that
shadow ProgramManagerWithShader constants. Instead, use the common
constants defined in the test class. Re-organizes the test classes
to be able to use common ProgramManager from the test base
class. Initialize the ProgramManager in SetUp phase. This is done to
be able to provide custom FeatureInfo objects to the ProgramManager.
This is done in order to test the code that is run only if path
rendering is enabled.
Changes NV_path_rendering to be enabled only for ES 3.1 contexts. The
extension spec does not spec the full needed program_interface_query
functionality. Thus the location info is only obtainable from 3.1
contexts.
Sets the driver version needed for the feature as 346. The 346.35 driver
is the version in which glGetProgramInterfaceiv(.._, GL_FRAGMENT_INPUT_NV,
GL_ACTIVE_RESOURCES, ..) works.
BUG=344330
Review URL: https://codereview.chromium.org/527233002
Cr-Commit-Position: refs/heads/master@{#357321}
Diffstat (limited to 'gpu/GLES2')
-rw-r--r-- | gpu/GLES2/extensions/CHROMIUM/CHROMIUM_path_rendering.txt | 260 | ||||
-rw-r--r-- | gpu/GLES2/gl2chromium_autogen.h | 4 | ||||
-rw-r--r-- | gpu/GLES2/gl2extchromium.h | 30 |
3 files changed, 294 insertions, 0 deletions
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_path_rendering.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_path_rendering.txt index 026ac11..a8af396 100644 --- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_path_rendering.txt +++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_path_rendering.txt @@ -73,6 +73,11 @@ New Tokens BOUNDING_BOX_CHROMIUM see above BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM 0x909C + Accepted by the <genMode> parameter of ProgramPathFragmentInputGen: + EYE_LINEAR_CHROMIUM 0x2400 + OBJECT_LINEAR_CHROMIUM 0x2401 + CONSTANT_CHROMIUM 0x8576 + Accepted by the <transformType> parameter of StencilFillPathInstancedCHROMIUM, StencilStrokePathInstancedCHROMIUM, CoverFillPathInstancedCHROMIUM, CoverStrokePathInstancedCHROMIUM, @@ -992,6 +997,261 @@ New Procedures and Functions unless either command would generate an error; for any such error other than OUT_OF_MEMORY, only that error is generated. + void BindFragmentInputLocationCHROMIUM(uint program, int location, + const char* name); + + The call specifes that the fragment shader input varying named + /name/ in program /program/ should be bound to uniform location + /location/ when the program is next linked. If /name/ was bound + previously, its assigned binding is replaced with /location/. The + /name/ must be a null terminated string. The error INVALID_VALUE + is generated if /location/ is equal or greater than + + MAX_VARYING_VECTORS * 4 + + or less than 0. BindFragmentInputLocation has no effect until the + program is linked. In particular, it doesn't modify the bindings of active + uniforms variables in a program that has already been linked. + + The error INVALID_OPERATION is generated if /program/ is not name for a + program object. + + The error INVALID_OPERATION is generated if name starts with the reserved + "gl_" prefix. + + When a program is linked, any active uniforms without a binding specified + through BindFragmentInputLocation will be automatically be bound to + locations by the GL. Such bindings can not be queried. + + BindFragmentInputLocation may be issued before any shader objects are + attached to a program object. Hence it is allowed to bind any name (except + a name starting with "gl_") to an index, including a name that is never used + as a varying in the fragment shader object. Assigned bindings for varying + variables that do not exist or are not active are ignored. + + It is possible for an application to bind more than one fragment + input name to the same location. This is referred to as aliasing. + This will only work if only one of the aliased fragment inputs is + active in the executable program, or if no path through the shader + consumes more than one fragment input of a set of fragment inputs + aliased to the same location. If two statically used fragment + inputs in a program are bound to the name location, link must + fail. + + void ProgramPathFragmentInputGenCHROMIUM(uint program, + int location, + enum genMode, + int components, + const float *coeffs); + + The command controls how a user-defined (non-built-in) fragment input of + a GLSL program object is computed for fragment shading operations that occur + as a result of CoverFillPathCHROMIUM or CoverStrokePathCHROMIUM. + + /program/ names a GLSL program object. If /program/ has not been + successfully linked, the error INVALID_OPERATION is generated. + + The given fragment input generation state is loaded into the fragment + input variable location identified by /location/. This location + is a value bound with BindFragmentInputLocation. + + If the value of location is -1, the ProgramPathFragmentInputGenCHROMIUM + command will silently ignore the command, and the program's path fragment + input generation state will not be changed. + + If any of the following conditions occur, an INVALID_OPERATION error is + generated by the ProgramPathFragmentInputGenCHROMIUM, and no state is + changed: + + * if the size indicated in the /components/ of the + ProgramPathFragmentInputGenCHROMIUM command used does not match the + size of the fragment input scalar or vector declared in the + shader, + + * if the fragment input declared in the shader is not + single-precision floating-point scalar or vector, or + + * if no fragment input variable with a location of /location/ + exists in the program object named by /program/ and location + is not -1, or + + * if the fragment input declared in the shader is a built-in + variables (i.e. prefixed by "gl_"). + + When covering paths, fragment input variables are interpolated at + each shaded fragment based on the corresponding fragment input + generation state specified by ProgramPathFragmentInputGenCHROMIUM for + each respective fragment input. + + The /genMode/, /components/, and /coeffs/ parameters are used to + generate the fragment input variable values. This is described in + subsection FRAGMENT INPUT GENERATION FOR PATH COVER COMMANDS. + + When covering paths, if a fragment input variable has not had its + path fragment input generation state successfully generated, it as + if the values of this variable are always initialized to zero when + the fragment shader is executing. + + FRAGMENT INPUT GENERATION FOR PATH COVER COMMANDS + + The /genMode/, /components/, and /coeffs/ parameters of + ProgramPathFragmentInputGenCHROMIUM control how fragment inputs are computed + for fragment shading operations that occur as a result of + CoverFillPathCHROMIUM and CoverStrokePathCHROMIUM and their StencilThenCover + and instanced variants. + + /genMode/ must be one of NONE, OBJECT_LINEAR_CHROMIUM, EYE_LINEAR_CHROMIUM + or CONSTANT_CHROMIUM; otherwise INVALID_ENUM is generated. + + NONE means that the fragment input is not generated. OBJECT_LINEAR_CHROMIUM + means that the specified input is generated from a linear combination of the + 2D path coordinates (x,y). EYE_LINEAR_CHROMIUM means the specified input is + generated from a linear combination of path's 2D coordinates transformed in + eye space, with (xe, ye, ze, we) calculated as in section 2.12 + ("Fixed-Function Vertex Transformation") of OpenGL 3.2 (unabridged) + Specification (Special Functions). CONSTANT_CHROMIUM means that the + specified input is set to corresponding constant value. + + /components/ must be 0 if /genMode/ is NONE or for other allowed /genMode/ + values must be one of 1, 2, 3, or 4; otherwise INVALID_VALUE is generated. + /components/ determines how many fragment input components, how many + coefficients read from the /coeffs/ array, and the linear equations used to + generate the s, t, r, and q coordinates of the fragment input specified by + /location/. + + In the following equations, coeffs[i] is the /i/th element (base zero) of + the /coeffs/ array; x, y, z, and w are determined by the /genMode/. + + When /genMode/ is EYE_LINEAR_CHROMIUM, xcoeffs[i] is the /i/th element (base + zero) of a /xcoeffs/ array generated by multiplying each respective vector + of four elements of coeffs by the current inverse modelview matrix when + ProgramPathFragmentInputGen is called. + + xcoeffs[0..3] = coeffs[0..3] * MV^-1 + xcoeffs[4..7] = coeffs[4..7] * MV^-1 + xcoeffs[8..11] = coeffs[8..11] * MV^-1 + xcoeffs[12..15] = coeffs[12..12] * MV^-1 + + [[ NOTATION: + + xxx[0..3] is a vector form from xxx[0], xxx[1], xxx[2], and xxx[3] + + MV^-1 is the inverse of the current PATH_MODELVIEW_CHROMIUM matrix when + ProgramPathFragmentInputGenCHROMIUM happens. + + ]] + + If the /components/ is 0, no values from the /coeffs/ array are + accessed and the s, t, r, and q coordinates of a covered fragment's + fragment input for /location/ are computed: + + s = 0 + t = 0 + r = 0 + q = 0 + + If the /components/ is 1 and /genMode/ is OBJECT_LINEAR_CHROMIUM + 3 values from the /coeffs/ array are + accessed and the s, t, r, and q coordinates of a covered fragment's + fragment input for /location/ are computed: + + s = coeffs[0] * x + coeffs[1] * y + coeffs[2] + t = 0 + r = 0 + q = 0 + + Alternatively if the /genMode/ is EYE_LINEAR_CHROMIUM, then 4 values are + accessed and the fragment input for /location/ are + computed: + + s = xcoeffs[0] * xe + xcoeffs[1] * ye + xcoeffs[2] * ze + xcoeffs[3] * we + t = 0 + r = 0 + q = 0 + + Alternatively if the /genMode/ is CONSTANT_CHROMIUM, then: + + s = xcoeffs[0] + t = 0 + r = 0 + q = 0 + + If the /components/ is 2 and /genMode/ is OBJECT_LINEAR_CHROMIUM, + 6 values from the /coeffs/ array are accessed and the + s, t, r, and q coordinates of a covered fragment's fragment input + coordinates are computed: + + s = coeffs[0] * x + coeffs[1] * y + coeffs[2] + t = coeffs[3] * x + coeffs[4] * y + coeffs[5] + r = 0 + q = 0 + + Alternatively if the /genMode/ is EYE_LINEAR_CHROMIUM, then 8 values are + accessed and the fragment input coordinates are computed: + + s = xcoeffs[0] * xe + xcoeffs[1] * ye + xcoeffs[2] * ze + xcoeffs[3] * we + t = xcoeffs[4] * xe + xcoeffs[5] * ye + xcoeffs[6] * ze + xcoeffs[7] * we + r = 0 + q = 0 + + Alternatively if the /genMode/ is CONSTANT_CHROMIUM, then: + + s = xcoeffs[0] + t = xcoeffs[1] + r = 0 + q = 0 + + If the /components/ is 3 and /genMode/ is OBJECT_LINEAR_CHROMIUM 9 values + from the /coeffs/ array are accessed and the s, t, r, and q coordinates of a + covered fragment's fragment input coordinates for /location/ are computed: + + s = coeffs[0] * x + coeffs[1] * y + coeffs[2] + t = coeffs[3] * x + coeffs[4] * y + coeffs[5] + r = coeffs[6] * x + coeffs[7] * y + coeffs[8] + q = 0 + + Alternatively if the /genMode/ is CONSTANT_CHROMIUM, then: + + s = xcoeffs[0] + t = xcoeffs[1] + r = xcoeffs[2] + q = 0 + + Alternatively if the /genMode/ is EYE_LINEAR_CHROMIUM, then 12 values are + accessed and the fragment input coodinates for /location/ are computed: + + s = xcoeffs[0] * xe + xcoeffs[1] * ye + xcoeffs[2] * ze + xcoeffs[3] * we + t = xcoeffs[4] * xe + xcoeffs[5] * ye + xcoeffs[6] * ze + xcoeffs[7] * we + r = xcoeffs[8] * xe + xcoeffs[9] * ye + xcoeffs[10] * ze + xcoeffs[11] * we + q = 0 + + If the /components/ is 4 and /genMode/ is OBJECT_LINEAR_CHROMIUM, + 12 values from the /coeffs/ array are accessed and the + s, t, r, and q coordinates of a covered fragment's fragment input + coordinates for /location/ are computed: + + s = coeffs[0] * x + coeffs[1] * y + coeffs[2] + t = coeffs[3] * x + coeffs[4] * y + coeffs[5] + r = coeffs[6] * x + coeffs[7] * y + coeffs[8] + q = coeffs[9] * x + coeffs[10] * y + coeffs[11] + + Alternatively if the /genMode/ is EYE_LINEAR_CHROMIUM, then 16 values are + accessed and the fragment input coordinates for /location/ are + computed: + + s = xcoeffs[0] * xe + xcoeffs[1] * ye + xcoeffs[2] * ze + xcoeffs[3] * we + t = xcoeffs[4] * xe + xcoeffs[5] * ye + xcoeffs[6] * ze + xcoeffs[7] * we + r = xcoeffs[8] * xe + xcoeffs[9] * ye + xcoeffs[10] * ze + xcoeffs[11] * we + q = xcoeffs[12] * xe + xcoeffs[13] * ye + xcoeffs[14] * ze + xcoeffs[15] * we + + Alternatively if the /genMode/ is CONSTANT_CHROMIUM, then: + + s = xcoeffs[0] + t = xcoeffs[1] + r = xcoeffs[2] + q = xcoeffs[3] + + The initial mode is NONE and the coefficients are all initially zero. PATH COVERING RASTERIZATION DETAILS diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index ee4a8fc..67b07de 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h @@ -367,6 +367,10 @@ GLES2_GET_FUN(StencilThenCoverFillPathInstancedCHROMIUM) #define glStencilThenCoverStrokePathInstancedCHROMIUM \ GLES2_GET_FUN(StencilThenCoverStrokePathInstancedCHROMIUM) +#define glBindFragmentInputLocationCHROMIUM \ + GLES2_GET_FUN(BindFragmentInputLocationCHROMIUM) +#define glProgramPathFragmentInputGenCHROMIUM \ + GLES2_GET_FUN(ProgramPathFragmentInputGenCHROMIUM) #define glGetGraphicsResetStatusKHR GLES2_GET_FUN(GetGraphicsResetStatusKHR) #define glBlendBarrierKHR GLES2_GET_FUN(BlendBarrierKHR) #define glApplyScreenSpaceAntialiasingCHROMIUM \ diff --git a/gpu/GLES2/gl2extchromium.h b/gpu/GLES2/gl2extchromium.h index ccbe6f2..9e15249 100644 --- a/gpu/GLES2/gl2extchromium.h +++ b/gpu/GLES2/gl2extchromium.h @@ -899,6 +899,17 @@ glStencilThenCoverStrokePathInstancedCHROMIUM(GLsizei numPaths, GLenum coverMode, GLenum transformType, const GLfloat* transformValues); +GL_APICALL void GL_APIENTRY +glBindFragmentInputLocationCHROMIUM(GLuint program, + GLint location, + const char* name); +GL_APICALL void GL_APIENTRY +glProgramPathFragmentInputGenCHROMIUM(GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat* coeffs); + #endif typedef void(GL_APIENTRYP PFNGLMATRIXLOADFCHROMIUMPROC)(GLenum matrixMode, @@ -1000,6 +1011,16 @@ typedef void(GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDCHROMIUMPROC)( GLenum coverMode, GLenum transformType, const GLfloat* transformValues); +typedef void(GL_APIENTRYP PFNGLBINDFRAGMENTINPUTLOCATIONCHROMIUMPROC)( + GLuint program, + GLint location, + const char* name); +typedef void(GL_APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENCHROMIUMPROC)( + GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat* coeffs); #ifndef GL_CLOSE_PATH_CHROMIUM #define GL_CLOSE_PATH_CHROMIUM 0x00 @@ -1034,6 +1055,15 @@ typedef void(GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDCHROMIUMPROC)( #ifndef GL_FLAT_CHROMIUM #define GL_FLAT_CHROMIUM 0x1D00 #endif +#ifndef GL_EYE_LINEAR_CHROMIUM +#define GL_EYE_LINEAR_CHROMIUM 0x2400 +#endif +#ifndef GL_OBJECT_LINEAR_CHROMIUM +#define GL_OBJECT_LINEAR_CHROMIUM 0x2401 +#endif +#ifndef GL_CONSTANT_CHROMIUM +#define GL_CONSTANT_CHROMIUM 0x8576 +#endif #ifndef GL_PATH_STROKE_WIDTH_CHROMIUM #define GL_PATH_STROKE_WIDTH_CHROMIUM 0x9075 #endif |