Changeset 127217 in webkit


Ignore:
Timestamp:
Aug 30, 2012 5:34:58 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

[CSS Shaders] Implement normal blend mode and source-atop compositing mode
https://bugs.webkit.org/show_bug.cgi?id=93869

Patch by Max Vujovic <mvujovic@adobe.com> on 2012-08-30
Reviewed by Dean Jackson.

Source/WebCore:

Instead of allowing direct texture access in an author's shader via u_texture, CSS
Shaders blends special symbols in the author's shader (css_MixColor and
css_ColorMatrix) with the DOM element texture.

The author specifies the blend mode and composite operator via the CSS mix
function like this:
-webkit-filter: custom(none mix(shader.fs normal source-atop));

This patch implements the normal blend mode and the source-atop composite
operator. The other blend modes and composite operators will come in later
patches.

This patch introduces a new class, CustomFilterValidatedProgram, which validates
the shader using ANGLE. If the shader uses blending and compositing,
CustomFilterValidatedProgram uses ANGLE's SH_CSS_SHADERS_SPEC flag. This allows
the author's shader to compile successfully with special symbols like
"css_MixColor". ANGLE also reserves the "css_" prefix. If the shader doesn't use
blending and compositing, CustomFilterValidatedProgram validates the shader using
ANGLE's SH_WEBGL_SPEC flag.

After validation, CustomFilterValidatedProgram adds blending, compositing, and
texture access shader code to the author's original shaders. The definitions for
css_MixColor and css_ColorMatrix are added before the author's fragment shader
code so that the author code can access them. The blending, compositing, and
texture access code is added after the author code and is thus inaccessible to the
author code. Since ANGLE reserves the "css_" prefix during the validation phase,
no collisions are possible between the author's code and the code that WebKit adds.

The CustomFilterGlobalContext now caches CustomFilterValidatedProgram instead
of CustomFilterCompiledProgram. CustomFilterValidatedProgram owns a
CustomFilterCompiledProgram. This way, we can use the platform-independent
CustomFilterValidatedProgram to validate and rewrite the shaders, regardless of
the platform representation of the program (e.g. CustomFilterCompiledProgram).

Tests: css3/filters/custom/custom-filter-color-matrix.html

css3/filters/custom/custom-filter-composite-source-atop.html

  • GNUmakefile.list.am:
  • Target.pri:
  • WebCore.gyp/WebCore.gyp:
  • WebCore.gypi:
  • WebCore.vcproj/WebCore.vcproj:
  • WebCore.xcodeproj/project.pbxproj:
  • platform/graphics/ANGLEWebKitBridge.cpp:

(WebCore::ANGLEWebKitBridge::ANGLEWebKitBridge):

Add a shader spec parameter, since sometimes we want to validate the shader
against the CSS Shaders spec and other times we want to validate the shader
against the WebGL spec. Note that the CSS Shaders spec is treated as a subset
of the WebGL spec in ANGLE.

(WebCore::ANGLEWebKitBridge::validateShaderSource):

  • platform/graphics/ANGLEWebKitBridge.h:

(ANGLEWebKitBridge):

  • platform/graphics/filters/CustomFilterCompiledProgram.cpp:

(WebCore::CustomFilterCompiledProgram::CustomFilterCompiledProgram):
(WebCore::CustomFilterCompiledProgram::compileShader):
(WebCore::CustomFilterCompiledProgram::initializeParameterLocations):
(WebCore::CustomFilterCompiledProgram::~CustomFilterCompiledProgram):

  • platform/graphics/filters/CustomFilterCompiledProgram.h:

(WebCore):

  • platform/graphics/filters/CustomFilterGlobalContext.cpp:

(WebCore::CustomFilterGlobalContext::~CustomFilterGlobalContext):
(WebCore::CustomFilterGlobalContext::webglShaderValidator):
(WebCore):
(WebCore::CustomFilterGlobalContext::mixShaderValidator):
(WebCore::CustomFilterGlobalContext::createShaderValidator):
(WebCore::CustomFilterGlobalContext::getValidatedProgram):
(WebCore::CustomFilterGlobalContext::removeValidatedProgram):

  • platform/graphics/filters/CustomFilterGlobalContext.h:

(WebCore):
(CustomFilterGlobalContext):

  • platform/graphics/filters/CustomFilterProgramInfo.h:

(WebCore::CustomFilterProgramInfo::mixSettings):

  • platform/graphics/filters/CustomFilterValidatedProgram.cpp: Added.

(WebCore):
(WebCore::CustomFilterValidatedProgram::defaultVertexShaderString):
(WebCore::CustomFilterValidatedProgram::defaultFragmentShaderString):
(WebCore::CustomFilterValidatedProgram::CustomFilterValidatedProgram):
(WebCore::CustomFilterValidatedProgram::compiledProgram):
(WebCore::CustomFilterValidatedProgram::rewriteMixVertexShader):
(WebCore::CustomFilterValidatedProgram::rewriteMixFragmentShader):
(WebCore::CustomFilterValidatedProgram::blendFunctionString):
(WebCore::CustomFilterValidatedProgram::compositeFunctionString):
(WebCore::CustomFilterValidatedProgram::~CustomFilterValidatedProgram):

  • platform/graphics/filters/CustomFilterValidatedProgram.h: Added.

(WebCore):
(CustomFilterValidatedProgram):
(WebCore::CustomFilterValidatedProgram::create):
(WebCore::CustomFilterValidatedProgram::programInfo):
(WebCore::CustomFilterValidatedProgram::isInitialized):
(WebCore::CustomFilterValidatedProgram::detachFromGlobalContext):

  • platform/graphics/filters/FECustomFilter.cpp:

(WebCore::FECustomFilter::FECustomFilter):

Accept a CustomFilterValidatedProgram instead of CustomFilterProgram.

(WebCore::FECustomFilter::create):
(WebCore::FECustomFilter::initializeContext):
(WebCore::FECustomFilter::bindVertexAttribute):
(WebCore::FECustomFilter::bindProgramAndBuffers):

  • platform/graphics/filters/FECustomFilter.h:

(WebCore):
(FECustomFilter):

  • rendering/FilterEffectRenderer.cpp:

(WebCore):
(WebCore::createCustomFilterEffect):
(WebCore::FilterEffectRenderer::build):

Only create an FECustomFilter if the program validates.

  • rendering/FilterEffectRenderer.h:

(WebCore):
(FilterEffectRenderer):

LayoutTests:

We've added two new special built-in symbols in CSS Shaders, css_MixColor and
css_ColorMatrix.

This change adds custom-filter-composite-source-atop.html, a new test that uses css_MixColor
in a shader with the normal blend mode and the source-atop compositing operator.

This change also adds custom-filter-color-matrix.html, a new test that uses css_ColorMatrix
in the shader.

Authors can read and write to these special built-ins in their shader code. WebKit will
premultiply the DOM element texture with css_ColorMatrix. Additionally, WebKit will blend
and composite css_MixColor with the DOM element texture, according to the blend mode and
compositing operator that the author specifies in CSS.

For example, the following line of CSS tells WebKit how to blend and composite the
css_MixColor from shader.fs:
-webkit-filter: custom(none mix(shader.fs normal source-atop));

  • css3/filters/custom/custom-filter-color-matrix-expected.png: Added.
  • css3/filters/custom/custom-filter-color-matrix-expected.txt: Added.
  • css3/filters/custom/custom-filter-color-matrix.html: Added.
  • css3/filters/custom/custom-filter-composite-source-atop-expected.png: Added.
  • css3/filters/custom/custom-filter-composite-source-atop-expected.txt: Added.
  • css3/filters/custom/custom-filter-composite-source-atop.html: Added.
  • css3/filters/custom/custom-filter-shader-cache.html:
  • css3/filters/custom/effect-color-check.html:

Use pass-tex-coord.vs now. Since v_texCoord in not automatically passed in the default
shaders anymore, we have to pass it in our own vertex shader. After we implement more
blending and compositing modes, we will be able to convert most of the tests to use the
CSS mix function. Then, we won't be sampling the DOM element texture directly, so we
won't need a tex coord, so we won't need this shader anymore.

  • css3/filters/custom/effect-custom.html:

The default CSS value for <fragmentShader> needs to be specified explicitly until we
change it from its current default. This will be fixed in:
https://bugs.webkit.org/show_bug.cgi?id=94020

  • css3/filters/custom/effect-custom-transform-parameters.html:

Ditto.

  • css3/filters/custom/filter-fallback-to-software.html:

Ditto.

  • css3/filters/custom/invalid-custom-filter-shader-expected.html:

These tests will not attempt to apply a filter because the programs do not validate.
This means we don't need to trigger FilterEffectRenderer with grayscale(0) in
the reference file anymore.

  • css3/filters/resources/composite.fs: Added.
  • css3/filters/resources/empty-shader.fs: Added.
  • css3/filters/resources/grayscale-color-matrix.fs: Added.
  • css3/filters/resources/pass-tex-coord.vs: Added.
  • platform/chromium/css3/filters/custom/custom-filter-color-matrix-expected.png: Added.
  • platform/chromium/css3/filters/custom/custom-filter-composite-source-atop-expected.png: Added.
  • platform/chromium/TestExpectations:
  • platform/mac-snowleopard/css3/filters/custom/effect-custom-expected.png: Removed.

We should use the generic expectation, because this expectation does not show the
shaders applied.

  • platform/mac-snowleopard/css3/filters/custom/effect-custom-parameters-expected.png: Removed.

Ditto.

Location:
trunk
Files:
13 added
2 deleted
27 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r127216 r127217  
     12012-08-30  Max Vujovic  <mvujovic@adobe.com>
     2
     3        [CSS Shaders] Implement normal blend mode and source-atop compositing mode
     4        https://bugs.webkit.org/show_bug.cgi?id=93869
     5
     6        Reviewed by Dean Jackson.
     7
     8        We've added two new special built-in symbols in CSS Shaders, css_MixColor and
     9        css_ColorMatrix.
     10
     11        This change adds custom-filter-composite-source-atop.html, a new test that uses css_MixColor
     12        in a shader with the normal blend mode and the source-atop compositing operator.
     13
     14        This change also adds custom-filter-color-matrix.html, a new test that uses css_ColorMatrix
     15        in the shader.
     16
     17        Authors can read and write to these special built-ins in their shader code. WebKit will
     18        premultiply the DOM element texture with css_ColorMatrix. Additionally, WebKit will blend
     19        and composite css_MixColor with the DOM element texture, according to the blend mode and
     20        compositing operator that the author specifies in CSS.
     21
     22        For example, the following line of CSS tells WebKit how to blend and composite the
     23        css_MixColor from shader.fs:
     24        -webkit-filter: custom(none mix(shader.fs normal source-atop));
     25
     26        * css3/filters/custom/custom-filter-color-matrix-expected.png: Added.
     27        * css3/filters/custom/custom-filter-color-matrix-expected.txt: Added.
     28        * css3/filters/custom/custom-filter-color-matrix.html: Added.
     29        * css3/filters/custom/custom-filter-composite-source-atop-expected.png: Added.
     30        * css3/filters/custom/custom-filter-composite-source-atop-expected.txt: Added.
     31        * css3/filters/custom/custom-filter-composite-source-atop.html: Added.
     32        * css3/filters/custom/custom-filter-shader-cache.html:
     33        * css3/filters/custom/effect-color-check.html:
     34            Use pass-tex-coord.vs now. Since v_texCoord in not automatically passed in the default
     35            shaders anymore, we have to pass it in our own vertex shader. After we implement more
     36            blending and compositing modes, we will be able to convert most of the tests to use the
     37            CSS mix function. Then, we won't be sampling the DOM element texture directly, so we
     38            won't need a tex coord, so we won't need this shader anymore.
     39        * css3/filters/custom/effect-custom.html:
     40            The default CSS value for <fragmentShader> needs to be specified explicitly until we
     41            change it from its current default. This will be fixed in:
     42            https://bugs.webkit.org/show_bug.cgi?id=94020
     43        * css3/filters/custom/effect-custom-transform-parameters.html:
     44            Ditto.
     45        * css3/filters/custom/filter-fallback-to-software.html:
     46            Ditto.
     47        * css3/filters/custom/invalid-custom-filter-shader-expected.html:
     48            These tests will not attempt to apply a filter because the programs do not validate.
     49            This means we don't need to trigger FilterEffectRenderer with grayscale(0) in
     50            the reference file anymore.
     51        * css3/filters/resources/composite.fs: Added.
     52        * css3/filters/resources/empty-shader.fs: Added.
     53        * css3/filters/resources/grayscale-color-matrix.fs: Added.
     54        * css3/filters/resources/pass-tex-coord.vs: Added.
     55        * platform/chromium/css3/filters/custom/custom-filter-color-matrix-expected.png: Added.
     56        * platform/chromium/css3/filters/custom/custom-filter-composite-source-atop-expected.png: Added.
     57        * platform/chromium/TestExpectations:
     58        * platform/mac-snowleopard/css3/filters/custom/effect-custom-expected.png: Removed.
     59            We should use the generic expectation, because this expectation does not show the
     60            shaders applied.
     61        * platform/mac-snowleopard/css3/filters/custom/effect-custom-parameters-expected.png: Removed.
     62            Ditto.
     63
    1642012-08-30  Jessie Berlin  <jberlin@apple.com>
    265
  • trunk/LayoutTests/css3/filters/custom/custom-filter-shader-cache.html

    r119990 r127217  
    2222            .vertex_shader
    2323            {
    24                 -webkit-filter: custom(url('../resources/vertex-offset.vs'));
     24                -webkit-filter: custom(url('../resources/vertex-offset.vs') mix(url('../resources/empty-shader.fs') normal source-atop));
    2525            }
    2626            .fragment_shader
    2727            {
    28                 -webkit-filter: custom(none url('../resources/color-offset.fs'));
     28                -webkit-filter: custom(url('../resources/pass-tex-coord.vs') url('../resources/color-offset.fs'));
    2929            }
    3030            .both_shaders
  • trunk/LayoutTests/css3/filters/custom/effect-color-check.html

    r119990 r127217  
    2020    </head>
    2121    <body onload="runTest()">
    22         <img style="-webkit-filter: custom(none url('../resources/color-fill.fs'), color 1 0 0 1)" src="../../../compositing/resources/thiswayup.png">
    23         <img style="-webkit-filter: custom(none url('../resources/color-fill.fs'), color 0 1 0 1)" src="../../../compositing/resources/thiswayup.png">
    24         <img style="-webkit-filter: custom(none url('../resources/color-fill.fs'), color 0 0 1 1)" src="../../../compositing/resources/thiswayup.png">
     22        <img style="-webkit-filter: custom(url('../resources/pass-tex-coord.vs') url('../resources/color-fill.fs'), color 1 0 0 1)" src="../../../compositing/resources/thiswayup.png">
     23        <img style="-webkit-filter: custom(url('../resources/pass-tex-coord.vs') url('../resources/color-fill.fs'), color 0 1 0 1)" src="../../../compositing/resources/thiswayup.png">
     24        <img style="-webkit-filter: custom(url('../resources/pass-tex-coord.vs') url('../resources/color-fill.fs'), color 0 0 1 1)" src="../../../compositing/resources/thiswayup.png">
    2525        <!--
    2626            Testing that the color channels are specified correctly. You should see 3 boxes filled with red, green and blue. The arrow should
  • trunk/LayoutTests/css3/filters/custom/effect-custom-transform-parameters.html

    r127173 r127217  
    2626        /* Testing parameters of type transform in vertex-transform-parameter.vs. */
    2727        .filter {
    28             -webkit-filter: custom(url('../resources/vertex-transform-parameter.vs'),
     28            -webkit-filter: custom(url('../resources/vertex-transform-parameter.vs')
     29                                    mix(url('../resources/empty-shader.fs') normal source-atop),
    2930                                    transform translate(10px, 20px)
    3031                                  );
  • trunk/LayoutTests/css3/filters/custom/effect-custom.html

    r119990 r127217  
    2121    <body onload="runTest()">
    2222        <img style="-webkit-filter: custom(url('../resources/vertex-offset.vs') url('../resources/color-offset.fs'))" src="../resources/reference.png">
    23         <img style="-webkit-filter: custom(url('../resources/vertex-offset.vs'), 6 11)" src="../resources/reference.png">
    24         <img style="-webkit-filter: custom(url('../resources/vertex-explode-detached.vs'), 3 3 detached)" src="../resources/reference.png">
     23        <img style="-webkit-filter: custom(url('../resources/vertex-offset.vs') mix(url('../resources/empty-shader.fs') normal source-atop), 6 11)" src="../resources/reference.png">
     24        <img style="-webkit-filter: custom(url('../resources/vertex-explode-detached.vs') mix(url('../resources/empty-shader.fs') normal source-atop), 3 3 detached)" src="../resources/reference.png">
    2525        <img style="-webkit-filter: custom(url('../resources/vertex-explode-detached.vs') url('../resources/color-offset.fs'), 3 3 detached)" src="../resources/reference.png">
    26         <img style="-webkit-filter: custom(none url('../resources/color-offset.fs'))" src="../resources/reference.png">
     26        <img style="-webkit-filter: custom(url('../resources/pass-tex-coord.vs') url('../resources/color-offset.fs'))" src="../resources/reference.png">
    2727        <!--
    2828            Testing that simple custom filters work in software mode. You should see 5 blocks of colored bars with different effects applied, from left to right:
  • trunk/LayoutTests/css3/filters/custom/filter-fallback-to-software.html

    r125629 r127217  
    3131
    3232        .shader {
    33             -webkit-filter: custom(url('../resources/vertex-offset.vs')) drop-shadow(10px 10px 10px blue);
     33            -webkit-filter: custom(url('../resources/vertex-offset.vs') mix(url('../resources/empty-shader.fs') normal source-atop)) drop-shadow(10px 10px 10px blue);
    3434        }
    3535
  • trunk/LayoutTests/css3/filters/custom/invalid-custom-filter-shader-expected.html

    r125128 r127217  
    1515            }
    1616        </script>
    17         <style>
    18             img
    19             {
    20                 /* Note that we use grayscale(0) just to make sure that it triggers the whole FilterEffectRenderer on the images,
    21                 otherwise the result will be slightly different because of the precision errors. Having another filter like grayscale(0)
    22                 will trigger the same precission errors and will act as a similar pass-through filter. */
    23                 -webkit-filter: grayscale(0);
    24             }
    25         </style>
    2617    </head>
    2718    <body onload="notifyDone()">
  • trunk/LayoutTests/css3/filters/resources/pass-tex-coord.vs

    r127216 r127217  
    33attribute vec4 a_position;
    44attribute vec2 a_texCoord;
    5 
    65uniform mat4 u_projectionMatrix;
    7 uniform mat4 transform;
    86varying vec2 v_texCoord;
    97
    108void main()
    119{
    12     gl_Position = u_projectionMatrix * transform * a_position;
    1310    v_texCoord = a_texCoord;
     11    gl_Position = u_projectionMatrix * a_position;
    1412}
  • trunk/LayoutTests/css3/filters/resources/vertex-transform-parameter.vs

    r127046 r127217  
    22
    33attribute vec4 a_position;
    4 attribute vec2 a_texCoord;
    54
    65uniform mat4 u_projectionMatrix;
    76uniform mat4 transform;
    8 varying vec2 v_texCoord;
    97
    108void main()
    119{
    1210    gl_Position = u_projectionMatrix * transform * a_position;
    13     v_texCoord = a_texCoord;
    1411}
  • trunk/LayoutTests/platform/chromium/TestExpectations

    r127200 r127217  
    34923492BUGWK94256 DEBUG : fast/block/inline-children-root-linebox-crash.html = PASS CRASH
    34933493
     3494// Following tests need baselines on Win and Linux
     3495BUGWK94492 WIN LINUX : css3/filters/custom/custom-filter-color-matrix.html = PASS IMAGE IMAGE+TEXT TEXT MISSING
     3496BUGWK94492 WIN LINUX : css3/filters/custom/custom-filter-composite-source-atop.html = PASS IMAGE IMAGE+TEXT TEXT MISSING
     3497
    34943498// Flaky
    34953499BUGWK95246 : http/tests/security/mixedContent/filesystem-url-in-iframe.html = PASS TEXT
  • trunk/Source/WebCore/ChangeLog

    r127206 r127217  
     12012-08-30  Max Vujovic  <mvujovic@adobe.com>
     2
     3        [CSS Shaders] Implement normal blend mode and source-atop compositing mode
     4        https://bugs.webkit.org/show_bug.cgi?id=93869
     5
     6        Reviewed by Dean Jackson.
     7
     8        Instead of allowing direct texture access in an author's shader via u_texture, CSS
     9        Shaders blends special symbols in the author's shader (css_MixColor and
     10        css_ColorMatrix) with the DOM element texture.
     11
     12        The author specifies the blend mode and composite operator via the CSS mix
     13        function like this:
     14        -webkit-filter: custom(none mix(shader.fs normal source-atop));
     15
     16        This patch implements the normal blend mode and the source-atop composite
     17        operator. The other blend modes and composite operators will come in later
     18        patches.
     19
     20        This patch introduces a new class, CustomFilterValidatedProgram, which validates
     21        the shader using ANGLE. If the shader uses blending and compositing,
     22        CustomFilterValidatedProgram uses ANGLE's SH_CSS_SHADERS_SPEC flag. This allows
     23        the author's shader to compile successfully with special symbols like
     24        "css_MixColor". ANGLE also reserves the "css_" prefix. If the shader doesn't use
     25        blending and compositing, CustomFilterValidatedProgram validates the shader using
     26        ANGLE's SH_WEBGL_SPEC flag.
     27
     28        After validation, CustomFilterValidatedProgram adds blending, compositing, and
     29        texture access shader code to the author's original shaders. The definitions for
     30        css_MixColor and css_ColorMatrix are added before the author's fragment shader
     31        code so that the author code can access them. The blending, compositing, and
     32        texture access code is added after the author code and is thus inaccessible to the
     33        author code. Since ANGLE reserves the "css_" prefix during the validation phase,
     34        no collisions are possible between the author's code and the code that WebKit adds.
     35
     36        The CustomFilterGlobalContext now caches CustomFilterValidatedProgram instead
     37        of CustomFilterCompiledProgram. CustomFilterValidatedProgram owns a
     38        CustomFilterCompiledProgram. This way, we can use the platform-independent
     39        CustomFilterValidatedProgram to validate and rewrite the shaders, regardless of
     40        the platform representation of the program (e.g. CustomFilterCompiledProgram).
     41
     42        Tests: css3/filters/custom/custom-filter-color-matrix.html
     43               css3/filters/custom/custom-filter-composite-source-atop.html
     44
     45        * GNUmakefile.list.am:
     46        * Target.pri:
     47        * WebCore.gyp/WebCore.gyp:
     48        * WebCore.gypi:
     49        * WebCore.vcproj/WebCore.vcproj:
     50        * WebCore.xcodeproj/project.pbxproj:
     51        * platform/graphics/ANGLEWebKitBridge.cpp:
     52        (WebCore::ANGLEWebKitBridge::ANGLEWebKitBridge):
     53            Add a shader spec parameter, since sometimes we want to validate the shader
     54            against the CSS Shaders spec and other times we want to validate the shader
     55            against the WebGL spec. Note that the CSS Shaders spec is treated as a subset
     56            of the WebGL spec in ANGLE.
     57        (WebCore::ANGLEWebKitBridge::validateShaderSource):
     58        * platform/graphics/ANGLEWebKitBridge.h:
     59        (ANGLEWebKitBridge):
     60        * platform/graphics/filters/CustomFilterCompiledProgram.cpp:
     61        (WebCore::CustomFilterCompiledProgram::CustomFilterCompiledProgram):
     62        (WebCore::CustomFilterCompiledProgram::compileShader):
     63        (WebCore::CustomFilterCompiledProgram::initializeParameterLocations):
     64        (WebCore::CustomFilterCompiledProgram::~CustomFilterCompiledProgram):
     65        * platform/graphics/filters/CustomFilterCompiledProgram.h:
     66        (WebCore):
     67        * platform/graphics/filters/CustomFilterGlobalContext.cpp:
     68        (WebCore::CustomFilterGlobalContext::~CustomFilterGlobalContext):
     69        (WebCore::CustomFilterGlobalContext::webglShaderValidator):
     70        (WebCore):
     71        (WebCore::CustomFilterGlobalContext::mixShaderValidator):
     72        (WebCore::CustomFilterGlobalContext::createShaderValidator):
     73        (WebCore::CustomFilterGlobalContext::getValidatedProgram):
     74        (WebCore::CustomFilterGlobalContext::removeValidatedProgram):
     75        * platform/graphics/filters/CustomFilterGlobalContext.h:
     76        (WebCore):
     77        (CustomFilterGlobalContext):
     78        * platform/graphics/filters/CustomFilterProgramInfo.h:
     79        (WebCore::CustomFilterProgramInfo::mixSettings):
     80        * platform/graphics/filters/CustomFilterValidatedProgram.cpp: Added.
     81        (WebCore):
     82        (WebCore::CustomFilterValidatedProgram::defaultVertexShaderString):
     83        (WebCore::CustomFilterValidatedProgram::defaultFragmentShaderString):
     84        (WebCore::CustomFilterValidatedProgram::CustomFilterValidatedProgram):
     85        (WebCore::CustomFilterValidatedProgram::compiledProgram):
     86        (WebCore::CustomFilterValidatedProgram::rewriteMixVertexShader):
     87        (WebCore::CustomFilterValidatedProgram::rewriteMixFragmentShader):
     88        (WebCore::CustomFilterValidatedProgram::blendFunctionString):
     89        (WebCore::CustomFilterValidatedProgram::compositeFunctionString):
     90        (WebCore::CustomFilterValidatedProgram::~CustomFilterValidatedProgram):
     91        * platform/graphics/filters/CustomFilterValidatedProgram.h: Added.
     92        (WebCore):
     93        (CustomFilterValidatedProgram):
     94        (WebCore::CustomFilterValidatedProgram::create):
     95        (WebCore::CustomFilterValidatedProgram::programInfo):
     96        (WebCore::CustomFilterValidatedProgram::isInitialized):
     97        (WebCore::CustomFilterValidatedProgram::detachFromGlobalContext):
     98        * platform/graphics/filters/FECustomFilter.cpp:
     99        (WebCore::FECustomFilter::FECustomFilter):
     100            Accept a CustomFilterValidatedProgram instead of CustomFilterProgram.
     101        (WebCore::FECustomFilter::create):
     102        (WebCore::FECustomFilter::initializeContext):
     103        (WebCore::FECustomFilter::bindVertexAttribute):
     104        (WebCore::FECustomFilter::bindProgramAndBuffers):
     105        * platform/graphics/filters/FECustomFilter.h:
     106        (WebCore):
     107        (FECustomFilter):
     108        * rendering/FilterEffectRenderer.cpp:
     109        (WebCore):
     110        (WebCore::createCustomFilterEffect):
     111        (WebCore::FilterEffectRenderer::build):
     112            Only create an FECustomFilter if the program validates.
     113        * rendering/FilterEffectRenderer.h:
     114        (WebCore):
     115        (FilterEffectRenderer):
     116
    11172012-08-30  Julien Chaffraix  <jchaffraix@webkit.org>
    2118
  • trunk/Source/WebCore/GNUmakefile.list.am

    r127165 r127217  
    42434243        Source/WebCore/platform/graphics/filters/CustomFilterCompiledProgram.h \
    42444244        Source/WebCore/platform/graphics/filters/CustomFilterTransformParameter.h \
     4245        Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp \
     4246        Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.h \
    42454247        Source/WebCore/platform/graphics/filters/DistantLightSource.cpp \
    42464248        Source/WebCore/platform/graphics/filters/DistantLightSource.h \
  • trunk/Source/WebCore/Target.pri

    r127132 r127217  
    20462046    platform/graphics/filters/CustomFilterProgram.h \
    20472047    platform/graphics/filters/CustomFilterTransformParameter.h \
     2048    platform/graphics/filters/CustomFilterValidatedProgram.h \
    20482049    platform/graphics/filters/FEBlend.h \
    20492050    platform/graphics/filters/FEColorMatrix.h \
     
    34413442        platform/graphics/filters/CustomFilterCompiledProgram.cpp \
    34423443        platform/graphics/filters/CustomFilterMesh.cpp \
     3444        platform/graphics/filters/CustomFilterValidatedProgram.cpp \
    34433445        platform/graphics/filters/DistantLightSource.cpp \
    34443446        platform/graphics/filters/FEBlend.cpp \
  • trunk/Source/WebCore/WebCore.gyp/WebCore.gyp

    r126907 r127217  
    16421642        ['exclude', 'platform/MIMETypeRegistry\\.cpp$'],
    16431643        ['exclude', 'platform/Theme\\.cpp$'],
    1644         ['exclude', 'platform/graphics/ANGLEWebKitBridge\\.(cpp|h)$'],
    16451644        # *NEON.cpp files need special compile options.
    16461645        # They are moved to the webcore_arm_neon target.
  • trunk/Source/WebCore/WebCore.gypi

    r127170 r127217  
    37123712            'platform/graphics/filters/CustomFilterCompiledProgram.cpp',
    37133713            'platform/graphics/filters/CustomFilterCompiledProgram.h',
     3714            'platform/graphics/filters/CustomFilterValidatedProgram.cpp',
     3715            'platform/graphics/filters/CustomFilterValidatedProgram.h',
    37143716            'platform/graphics/filters/CustomFilterMesh.cpp',
    37153717            'platform/graphics/filters/CustomFilterTransformParameter.h',
  • trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj

    r127191 r127217  
    3192631926                                        </File>
    3192731927                                        <File
     31928                                                RelativePath="..\platform\graphics\filters\CustomFilterValidatedProgram.cpp"
     31929                                                >
     31930                                        </File>
     31931                                        <File
     31932                                                RelativePath="..\platform\graphics\filters\CustomFilterValidatedProgram.h"
     31933                                                >
     31934                                        </File>
     31935                                        <File
    3192831936                                                RelativePath="..\platform\graphics\filters\DistantLightSource.cpp"
    3192931937                                                >
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r127170 r127217  
    37673767                A24BF77B15CC3BAF003191F2 /* WebKitCSSMixFunctionValue.h in Headers */ = {isa = PBXBuildFile; fileRef = A24BF77915CC3BAF003191F2 /* WebKitCSSMixFunctionValue.h */; };
    37683768                A24BF77C15CC3BAF003191F2 /* WebKitCSSMixFunctionValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A24BF77A15CC3BAF003191F2 /* WebKitCSSMixFunctionValue.cpp */; };
     3769                A29532CF15DD5E1700469EBC /* CustomFilterValidatedProgram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A29532CD15DD5E1700469EBC /* CustomFilterValidatedProgram.cpp */; };
     3770                A29532D015DD5E1700469EBC /* CustomFilterValidatedProgram.h in Headers */ = {isa = PBXBuildFile; fileRef = A29532CE15DD5E1700469EBC /* CustomFilterValidatedProgram.h */; };
    37693771                A3BB59F31457A40D00AC56FE /* DocumentEventQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A3BB59F11457A40D00AC56FE /* DocumentEventQueue.cpp */; };
    37703772                A3BB59F41457A40D00AC56FE /* DocumentEventQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = A3BB59F21457A40D00AC56FE /* DocumentEventQueue.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    1098210984                A24BF77915CC3BAF003191F2 /* WebKitCSSMixFunctionValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebKitCSSMixFunctionValue.h; sourceTree = "<group>"; };
    1098310985                A24BF77A15CC3BAF003191F2 /* WebKitCSSMixFunctionValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebKitCSSMixFunctionValue.cpp; sourceTree = "<group>"; };
     10986                A29532CD15DD5E1700469EBC /* CustomFilterValidatedProgram.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CustomFilterValidatedProgram.cpp; path = filters/CustomFilterValidatedProgram.cpp; sourceTree = "<group>"; };
     10987                A29532CE15DD5E1700469EBC /* CustomFilterValidatedProgram.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomFilterValidatedProgram.h; path = filters/CustomFilterValidatedProgram.h; sourceTree = "<group>"; };
    1098410988                A3BB59F11457A40D00AC56FE /* DocumentEventQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentEventQueue.cpp; sourceTree = "<group>"; };
    1098510989                A3BB59F21457A40D00AC56FE /* DocumentEventQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentEventQueue.h; sourceTree = "<group>"; };
     
    1815618160                                50D88CB315BDFDAA001809F4 /* CustomFilterProgramInfo.cpp */,
    1815718161                                50D88CB415BDFDAA001809F4 /* CustomFilterProgramInfo.h */,
     18162                                A29532CD15DD5E1700469EBC /* CustomFilterValidatedProgram.cpp */,
     18163                                A29532CE15DD5E1700469EBC /* CustomFilterValidatedProgram.h */,
    1815818164                                A1E1154313015C3D0054AC8C /* DistantLightSource.cpp */,
    1815918165                                84730D5A1248F0B300D3A9C9 /* DistantLightSource.h */,
     
    2253922545                                503D0CAC14B5B08700F32F57 /* CustomFilterProgramClient.h in Headers */,
    2254022546                                50D88CB615BDFDAA001809F4 /* CustomFilterProgramInfo.h in Headers */,
     22547                                A29532D015DD5E1700469EBC /* CustomFilterValidatedProgram.h in Headers */,
    2254122548                                A8CB413E0E8633FD0032C4F0 /* DashArray.h in Headers */,
    2254222549                                A80E6D0B0A1989CA007FB8C5 /* DashboardRegion.h in Headers */,
     
    2611226119                                503D0CAA14B5B08700F32F57 /* CustomFilterProgram.cpp in Sources */,
    2611326120                                50D88CB515BDFDAA001809F4 /* CustomFilterProgramInfo.cpp in Sources */,
     26121                                A29532CF15DD5E1700469EBC /* CustomFilterValidatedProgram.cpp in Sources */,
    2611426122                                97BC6A201505F081001B74AC /* Database.cpp in Sources */,
    2611526123                                97BC6A231505F081001B74AC /* DatabaseAuthorizer.cpp in Sources */,
  • trunk/Source/WebCore/platform/graphics/ANGLEWebKitBridge.cpp

    r126342 r127217  
    3333namespace WebCore {
    3434
    35 ANGLEWebKitBridge::ANGLEWebKitBridge(ShShaderOutput shaderOutput) :
    36     builtCompilers(false),
    37     m_fragmentCompiler(0),
    38     m_vertexCompiler(0),
    39     m_shaderOutput(shaderOutput)
     35ANGLEWebKitBridge::ANGLEWebKitBridge(ShShaderOutput shaderOutput, ShShaderSpec shaderSpec)
     36    : builtCompilers(false)
     37    , m_fragmentCompiler(0)
     38    , m_vertexCompiler(0)
     39    , m_shaderOutput(shaderOutput)
     40    , m_shaderSpec(shaderSpec)
    4041{
     42    // This is a no-op if it's already initialized.
    4143    ShInitialize();
    4244}
     
    7072{
    7173    if (!builtCompilers) {
    72         m_fragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_WEBGL_SPEC, m_shaderOutput, &m_resources);
    73         m_vertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_WEBGL_SPEC, m_shaderOutput, &m_resources);
     74        m_fragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, m_shaderSpec, m_shaderOutput, &m_resources);
     75        m_vertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, m_shaderSpec, m_shaderOutput, &m_resources);
    7476        if (!m_fragmentCompiler || !m_vertexCompiler) {
    7577            cleanupCompilers();
  • trunk/Source/WebCore/platform/graphics/ANGLEWebKitBridge.h

    r126342 r127217  
    3232#if PLATFORM(QT)
    3333#include "ANGLE/include/GLSLANG/ShaderLang.h"
    34 #elif !PLATFORM(GTK) && !PLATFORM(EFL) && !PLATFORM(BLACKBERRY)
     34#elif !PLATFORM(GTK) && !PLATFORM(EFL) && !PLATFORM(BLACKBERRY) && !PLATFORM(CHROMIUM)
    3535#include "ANGLE/ShaderLang.h"
    3636#else
     
    4848public:
    4949
    50     ANGLEWebKitBridge(ShShaderOutput = SH_GLSL_OUTPUT);
     50    ANGLEWebKitBridge(ShShaderOutput = SH_GLSL_OUTPUT, ShShaderSpec = SH_WEBGL_SPEC);
    5151    ~ANGLEWebKitBridge();
    5252   
     
    5454    void setResources(ShBuiltInResources);
    5555   
    56     bool validateShaderSource(const char* shaderSource, ANGLEShaderType shaderType, String& translatedShaderSource, String& shaderValidationLog, int extraCompileOptions);
     56    bool validateShaderSource(const char* shaderSource, ANGLEShaderType, String& translatedShaderSource, String& shaderValidationLog, int extraCompileOptions = 0);
    5757
    5858private:
     
    6666
    6767    ShShaderOutput m_shaderOutput;
     68    ShShaderSpec m_shaderSpec;
    6869
    6970    ShBuiltInResources m_resources;
  • trunk/Source/WebCore/platform/graphics/filters/CustomFilterCompiledProgram.cpp

    r126968 r127217  
    3434 
    3535#include "CustomFilterGlobalContext.h"
    36 #include "CustomFilterProgramInfo.h"
    37 #include "GraphicsContext3D.h"
    3836
    3937namespace WebCore {
    4038
    41 #define SHADER(Src) (ASCIILiteral(#Src))
    42 
    43 String CustomFilterCompiledProgram::defaultVertexShaderString()
    44 {
    45     DEFINE_STATIC_LOCAL(String, vertexShaderString, SHADER(
    46         precision mediump float;
    47         attribute vec4 a_position;
    48         attribute vec2 a_texCoord;
    49         uniform mat4 u_projectionMatrix;
    50         varying vec2 v_texCoord;
    51         void main()
    52         {
    53             gl_Position = u_projectionMatrix * a_position;
    54             v_texCoord = a_texCoord;
    55         }
    56     ));
    57     return vertexShaderString;
    58 }
    59 
    60 String CustomFilterCompiledProgram::defaultFragmentShaderString()
    61 {
    62     DEFINE_STATIC_LOCAL(String, fragmentShaderString, SHADER(
    63         precision mediump float;
    64         varying vec2 v_texCoord;
    65         uniform sampler2D u_texture;
    66         void main()
    67         {
    68             gl_FragColor = texture2D(u_texture, v_texCoord);
    69         }
    70     ));
    71     return fragmentShaderString;
    72 }
    73 
    74 CustomFilterCompiledProgram::CustomFilterCompiledProgram(CustomFilterGlobalContext* globalContext, const CustomFilterProgramInfo& programInfo)
    75     : m_globalContext(globalContext)
    76     , m_context(globalContext->context())
    77     , m_programInfo(programInfo)
     39CustomFilterCompiledProgram::CustomFilterCompiledProgram(PassRefPtr<GraphicsContext3D> context, const String& validatedVertexShader, const String& validatedFragmentShader)
     40    : m_context(context)
    7841    , m_program(0)
    7942    , m_positionAttribLocation(-1)
     
    8851    , m_samplerSizeLocation(-1)
    8952    , m_contentSamplerLocation(-1)
     53    , m_internalTexCoordAttribLocation(-1)
    9054    , m_isInitialized(false)
    9155{
    9256    m_context->makeContextCurrent();
    93    
    94     Platform3DObject vertexShader = compileShader(GraphicsContext3D::VERTEX_SHADER, programInfo.vertexShaderString());
     57
     58    Platform3DObject vertexShader = compileShader(GraphicsContext3D::VERTEX_SHADER, validatedVertexShader);
    9559    if (!vertexShader)
    9660        return;
    9761   
    98     Platform3DObject fragmentShader = compileShader(GraphicsContext3D::FRAGMENT_SHADER, programInfo.fragmentShaderString());
     62    Platform3DObject fragmentShader = compileShader(GraphicsContext3D::FRAGMENT_SHADER, validatedFragmentShader);
    9963    if (!fragmentShader) {
    10064        m_context->deleteShader(vertexShader);
     
    11579}
    11680
    117 String CustomFilterCompiledProgram::getDefaultShaderString(GC3Denum shaderType)
    118 {
    119     switch (shaderType) {
    120     case GraphicsContext3D::VERTEX_SHADER:
    121         return defaultVertexShaderString();
    122     case GraphicsContext3D::FRAGMENT_SHADER:
    123         return defaultFragmentShaderString();
    124     default:
    125         ASSERT_NOT_REACHED();
    126         return String();
    127     }
    128 }
    129 
    13081Platform3DObject CustomFilterCompiledProgram::compileShader(GC3Denum shaderType, const String& shaderString)
    13182{
     83    ASSERT(!shaderString.isNull());
     84
    13285    Platform3DObject shader = m_context->createShader(shaderType);
    133     if (shaderString.isNull())
    134         m_context->shaderSource(shader, getDefaultShaderString(shaderType));
    135     else
    136         m_context->shaderSource(shader, shaderString);
     86    m_context->shaderSource(shader, shaderString);
    13787    m_context->compileShader(shader);
    13888   
     
    178128    m_meshSizeLocation = m_context->getUniformLocation(m_program, "u_meshSize");
    179129    m_projectionMatrixLocation = m_context->getUniformLocation(m_program, "u_projectionMatrix");
    180     m_samplerLocation = m_context->getUniformLocation(m_program, "u_texture");
    181130    m_samplerSizeLocation = m_context->getUniformLocation(m_program, "u_textureSize");
    182131    m_contentSamplerLocation = m_context->getUniformLocation(m_program, "u_contentTexture");
     132    m_internalTexCoordAttribLocation = m_context->getAttribLocation(m_program, "css_a_texCoord");
     133    m_samplerLocation = m_context->getUniformLocation(m_program, "css_u_texture");
     134    // FIXME: Remove texture access via u_texture and change the tests to use blending and compositing.
     135    // https://bugs.webkit.org/show_bug.cgi?id=93871
     136    if (m_samplerLocation == -1)
     137        m_samplerLocation = m_context->getUniformLocation(m_program, "u_texture");
    183138}
    184139
     
    192147CustomFilterCompiledProgram::~CustomFilterCompiledProgram()
    193148{
    194     if (m_globalContext)
    195         m_globalContext->removeCompiledProgram(this);
    196149    if (m_program) {
    197150        m_context->makeContextCurrent();
  • trunk/Source/WebCore/platform/graphics/filters/CustomFilterCompiledProgram.h

    r124897 r127217  
    3333#if ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
    3434
    35 #include "CustomFilterProgramInfo.h"
    36 #include "GraphicsTypes3D.h"
     35#include "GraphicsContext3D.h"
    3736#include <wtf/RefCounted.h>
    3837#include <wtf/text/WTFString.h>
     
    4140
    4241class CustomFilterGlobalContext;
    43 class GraphicsContext3D;
    4442
    45 // A specific combination of vertex / fragment shader is only going to be compiled once. The CustomFilterGlobalContext is
    46 // caching the compiled programs. CustomFilterGlobalContext has a weak reference to the CustomFilterCompiledProgram, so the
    47 // CustomFilterCompiledProgram destructor needs to notify the CustomFilterGlobalContext to remove the program from the cache.
    48 // FECustomFilter is the reference owner of the CustomFilterCompiledProgram, so a compiled shader is only kept alive as
    49 // long as there is at least one visible layer that applies the shader.
    5043class CustomFilterCompiledProgram: public RefCounted<CustomFilterCompiledProgram> {
    5144public:
    52     static PassRefPtr<CustomFilterCompiledProgram> create(CustomFilterGlobalContext* globalContext, const CustomFilterProgramInfo& programInfo)
     45    static PassRefPtr<CustomFilterCompiledProgram> create(PassRefPtr<GraphicsContext3D> context, const String& validatedVertexShader, const String& validatedFragmentShader)
    5346    {
    54         return adoptRef(new CustomFilterCompiledProgram(globalContext, programInfo));
     47        return adoptRef(new CustomFilterCompiledProgram(context, validatedVertexShader, validatedFragmentShader));
    5548    }
    5649   
    5750    ~CustomFilterCompiledProgram();
    58 
    59     const CustomFilterProgramInfo& programInfo() const { return m_programInfo; }
    6051   
    6152    int positionAttribLocation() const { return m_positionAttribLocation; }
     
    7061    int contentSamplerLocation() const { return m_contentSamplerLocation; }
    7162    int samplerSizeLocation() const { return m_samplerSizeLocation; }
     63    // FIXME: Get rid of the internal tex coord attribute "css_a_texCoord".
     64    // If the author defined "a_texCoord", we should leverage that.
     65    // If not, we should write "a_texCoord" in the shader.
     66    // This requires us to first get the list of attributes from the vertex shader using ANGLE.
     67    // https://bugs.webkit.org/show_bug.cgi?id=94358
     68    int internalTexCoordAttribLocation() const { return m_internalTexCoordAttribLocation; }
    7269
    7370    int uniformLocationByName(const String&);
     
    7673   
    7774    Platform3DObject program() const { return m_program; }
    78 
    79     // 'detachGlobalContext' is called when the CustomFilterGlobalContext is deleted
    80     // and there's no need for the callback anymore.
    81     // Note that CustomFilterGlobalContext doesn't not keep a strong reference to
    82     // the CustomFilterCompiledProgram.
    83     void detachFromGlobalContext() { m_globalContext = 0; }
    8475private:
    85     CustomFilterCompiledProgram(CustomFilterGlobalContext*, const CustomFilterProgramInfo&);
     76    CustomFilterCompiledProgram(PassRefPtr<GraphicsContext3D>, const String& validatedVertexShader, const String& validatedFragmentShader);
    8677   
    8778    Platform3DObject compileShader(GC3Denum shaderType, const String& shaderString);
     
    8980    void initializeParameterLocations();
    9081   
    91     static String defaultVertexShaderString();
    92     static String defaultFragmentShaderString();
    93     String getDefaultShaderString(GC3Denum shaderType);
    94    
    95     CustomFilterGlobalContext* m_globalContext;
    9682    RefPtr<GraphicsContext3D> m_context;
    97     CustomFilterProgramInfo m_programInfo;
    9883    Platform3DObject m_program;
    9984   
     
    10994    int m_samplerSizeLocation;
    11095    int m_contentSamplerLocation;
     96    // FIXME: Get rid of the internal tex coord attribute "css_a_texCoord".
     97    // https://bugs.webkit.org/show_bug.cgi?id=94358
     98    int m_internalTexCoordAttribLocation;
    11199   
    112100    bool m_isInitialized;
  • trunk/Source/WebCore/platform/graphics/filters/CustomFilterGlobalContext.cpp

    r126926 r127217  
    3333#include "CustomFilterGlobalContext.h"
    3434
    35 #include "CustomFilterCompiledProgram.h"
     35#include "CustomFilterValidatedProgram.h"
    3636#include "GraphicsContext3D.h"
    3737
     
    4444CustomFilterGlobalContext::~CustomFilterGlobalContext()
    4545{
    46     for (CustomFilterCompiledProgramsMap::iterator iter = m_programs.begin(); iter != m_programs.end(); ++iter)
     46    for (CustomFilterValidatedProgramsMap::iterator iter = m_programs.begin(); iter != m_programs.end(); ++iter)
    4747        iter->second->detachFromGlobalContext();
     48}
     49
     50ANGLEWebKitBridge* CustomFilterGlobalContext::webglShaderValidator()
     51{
     52    if (!m_webglShaderValidator)
     53        m_webglShaderValidator = createShaderValidator(SH_WEBGL_SPEC);
     54    return m_webglShaderValidator.get();
     55}
     56
     57ANGLEWebKitBridge* CustomFilterGlobalContext::mixShaderValidator()
     58{
     59    if (!m_mixShaderValidator)
     60        m_mixShaderValidator = createShaderValidator(SH_CSS_SHADERS_SPEC);
     61    return m_mixShaderValidator.get();
     62}
     63
     64PassOwnPtr<ANGLEWebKitBridge> CustomFilterGlobalContext::createShaderValidator(ShShaderSpec shaderSpec)
     65{
     66    OwnPtr<ANGLEWebKitBridge> validator = adoptPtr(new ANGLEWebKitBridge(SH_ESSL_OUTPUT, shaderSpec));
     67    ShBuiltInResources resources;
     68    ShInitBuiltInResources(&resources);
     69    validator->setResources(resources);
     70    return validator.release();
    4871}
    4972
     
    6386}
    6487
    65 PassRefPtr<CustomFilterCompiledProgram> CustomFilterGlobalContext::getCompiledProgram(const CustomFilterProgramInfo& programInfo)
     88PassRefPtr<CustomFilterValidatedProgram> CustomFilterGlobalContext::getValidatedProgram(const CustomFilterProgramInfo& programInfo)
    6689{
    6790    // Check that the context is already prepared.
    6891    ASSERT(m_context);
    6992
    70     CustomFilterCompiledProgramsMap::iterator iter = m_programs.find(programInfo);
     93    CustomFilterValidatedProgramsMap::iterator iter = m_programs.find(programInfo);
    7194    if (iter != m_programs.end())
    7295        return iter->second;
    7396
    74     RefPtr<CustomFilterCompiledProgram> compiledProgram = CustomFilterCompiledProgram::create(this, programInfo);
    75     m_programs.set(programInfo, compiledProgram.get());
    76     return compiledProgram.release();
     97    RefPtr<CustomFilterValidatedProgram> validatedProgram = CustomFilterValidatedProgram::create(this, programInfo);
     98    m_programs.set(programInfo, validatedProgram.get());
     99    return validatedProgram.release();
    77100}
    78101
    79 void CustomFilterGlobalContext::removeCompiledProgram(const CustomFilterCompiledProgram* program)
     102void CustomFilterGlobalContext::removeValidatedProgram(const CustomFilterValidatedProgram* program)
    80103{
    81     CustomFilterCompiledProgramsMap::iterator iter = m_programs.find(program->programInfo());
     104    CustomFilterValidatedProgramsMap::iterator iter = m_programs.find(program->programInfo());
    82105    ASSERT(iter != m_programs.end());
    83106    m_programs.remove(iter);
  • trunk/Source/WebCore/platform/graphics/filters/CustomFilterGlobalContext.h

    r124897 r127217  
    3232
    3333#if ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
     34#include "ANGLEWebKitBridge.h"
    3435#include "CustomFilterProgramInfo.h"
    3536#include <wtf/HashMap.h>
     
    3839namespace WebCore {
    3940
    40 class CustomFilterCompiledProgram;
     41class CustomFilterValidatedProgram;
    4142class HostWindow;
    4243class GraphicsContext3D;
    4344
    44 typedef HashMap<CustomFilterProgramInfo, CustomFilterCompiledProgram*> CustomFilterCompiledProgramsMap;
     45typedef HashMap<CustomFilterProgramInfo, CustomFilterValidatedProgram*> CustomFilterValidatedProgramsMap;
    4546
    4647class CustomFilterGlobalContext {
     
    5051   
    5152    GraphicsContext3D* context() const { return m_context.get(); }
     53
     54    // CSS shaders not referenced from the CSS mix function should be validated just like regular WebGL shaders.
     55    // This ANGLE validator uses the SH_WEBGL_SPEC flag.
     56    ANGLEWebKitBridge* webglShaderValidator();
     57
     58    // CSS shaders referenced from the CSS mix function should be validated slightly differently than WebGL shaders.
     59    // This ANGLE validator uses the SH_CSS_SHADERS_SPEC flag.
     60    // Under this flag, most notably:
     61    // - The "gl_FragColor" built-in is not available.
     62    // - Instead, the "css_MixColor" and "css_ColorMatrix" built-ins are available.
     63    // - The "css_" prefix is reserved.
     64    // - In the translated source that ANGLE returns, ANGLE renames the author's "main" function to "css_main".
     65    // The complete details are documented in ANGLE/ShaderLang.h.
     66    ANGLEWebKitBridge* mixShaderValidator();
    5267   
    5368    void prepareContextIfNeeded(HostWindow*);
    5469
    55     PassRefPtr<CustomFilterCompiledProgram> getCompiledProgram(const CustomFilterProgramInfo&);
    56     void removeCompiledProgram(const CustomFilterCompiledProgram*);
     70    PassRefPtr<CustomFilterValidatedProgram> getValidatedProgram(const CustomFilterProgramInfo&);
     71    void removeValidatedProgram(const CustomFilterValidatedProgram*);
    5772private:
     73    static PassOwnPtr<ANGLEWebKitBridge> createShaderValidator(ShShaderSpec);
     74
    5875    RefPtr<GraphicsContext3D> m_context;
    59     CustomFilterCompiledProgramsMap m_programs;
     76    OwnPtr<ANGLEWebKitBridge> m_webglShaderValidator;
     77    OwnPtr<ANGLEWebKitBridge> m_mixShaderValidator;
     78    CustomFilterValidatedProgramsMap m_programs;
    6079};
    6180
  • trunk/Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.h

    r125331 r127217  
    7676    const String& vertexShaderString() const { return m_vertexShaderString; }
    7777    const String& fragmentShaderString() const { return m_fragmentShaderString; }
     78    const CustomFilterProgramMixSettings& mixSettings() const { return m_mixSettings; }
    7879private:
    7980    String m_vertexShaderString;
  • trunk/Source/WebCore/platform/graphics/filters/FECustomFilter.cpp

    r127046 r127217  
    4040#include "CustomFilterProgram.h"
    4141#include "CustomFilterTransformParameter.h"
     42#include "CustomFilterValidatedProgram.h"
    4243#include "DrawingBuffer.h"
    4344#include "GraphicsContext3D.h"
     
    7677}
    7778
    78 FECustomFilter::FECustomFilter(Filter* filter, CustomFilterGlobalContext* customFilterGlobalContext, PassRefPtr<CustomFilterProgram> program, const CustomFilterParameterList& parameters,
     79FECustomFilter::FECustomFilter(Filter* filter, CustomFilterGlobalContext* customFilterGlobalContext, PassRefPtr<CustomFilterValidatedProgram> validatedProgram, const CustomFilterParameterList& parameters,
    7980                               unsigned meshRows, unsigned meshColumns, CustomFilterOperation::MeshBoxType,
    8081                               CustomFilterOperation::MeshType meshType)
    8182    : FilterEffect(filter)
    8283    , m_globalContext(customFilterGlobalContext)
     84    , m_validatedProgram(validatedProgram)
     85    , m_compiledProgram(0) // Don't compile the program unless we need to paint.
    8386    , m_frameBuffer(0)
    8487    , m_depthBuffer(0)
    8588    , m_destTexture(0)
    86     , m_program(program)
    8789    , m_parameters(parameters)
    8890    , m_meshRows(meshRows)
     
    9092    , m_meshType(meshType)
    9193{
    92 }
    93 
    94 PassRefPtr<FECustomFilter> FECustomFilter::create(Filter* filter, CustomFilterGlobalContext* customFilterGlobalContext, PassRefPtr<CustomFilterProgram> program, const CustomFilterParameterList& parameters,
     94    // An FECustomFilter shouldn't have been created unless the program passed validation.
     95    ASSERT(m_validatedProgram->isInitialized());
     96}
     97
     98PassRefPtr<FECustomFilter> FECustomFilter::create(Filter* filter, CustomFilterGlobalContext* customFilterGlobalContext, PassRefPtr<CustomFilterValidatedProgram> validatedProgram, const CustomFilterParameterList& parameters,
    9599                                           unsigned meshRows, unsigned meshColumns, CustomFilterOperation::MeshBoxType meshBoxType,
    96100                                           CustomFilterOperation::MeshType meshType)
    97101{
    98     return adoptRef(new FECustomFilter(filter, customFilterGlobalContext, program, parameters, meshRows, meshColumns, meshBoxType, meshType));
     102    return adoptRef(new FECustomFilter(filter, customFilterGlobalContext, validatedProgram, parameters, meshRows, meshColumns, meshBoxType, meshType));
    99103}
    100104
     
    197201        return false;
    198202    m_context->makeContextCurrent();
    199     m_compiledProgram = m_globalContext->getCompiledProgram(m_program->programInfo());
     203    m_compiledProgram = m_validatedProgram->compiledProgram();
    200204
    201205    // FIXME: Sharing the mesh would just save the time needed to upload it to the GPU, so I assume we could
     
    242246}
    243247
    244 void FECustomFilter::bindVertexAttribute(int attributeLocation, unsigned size, unsigned& offset)
     248void FECustomFilter::bindVertexAttribute(int attributeLocation, unsigned size, unsigned offset)
    245249{
    246250    if (attributeLocation != -1) {
     
    248252        m_context->enableVertexAttribArray(attributeLocation);
    249253    }
    250     offset += size * sizeof(float);
    251254}
    252255
     
    314317void FECustomFilter::bindProgramAndBuffers(Uint8ClampedArray* srcPixelArray)
    315318{
     319    ASSERT(m_compiledProgram->isInitialized());
     320
    316321    m_context->useProgram(m_compiledProgram->program());
    317322   
     
    338343    m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, m_mesh->elementsBufferObject());
    339344
    340     unsigned offset = 0;
    341     bindVertexAttribute(m_compiledProgram->positionAttribLocation(), 4, offset);
    342     bindVertexAttribute(m_compiledProgram->texAttribLocation(), 2, offset);
    343     bindVertexAttribute(m_compiledProgram->meshAttribLocation(), 2, offset);
     345    // FIXME: Ideally, these should be public members of CustomFilterMesh.
     346    // https://bugs.webkit.org/show_bug.cgi?id=94755
     347    static const unsigned PositionAttribSize = 4;
     348    static const unsigned TexAttribSize = 2;
     349    static const unsigned MeshAttribSize = 2;
     350    static const unsigned TriangleAttribSize = 3;
     351
     352    static const unsigned PositionAttribOffset = 0;
     353    static const unsigned TexAttribOffset = PositionAttribOffset + PositionAttribSize * sizeof(float);
     354    static const unsigned MeshAttribOffset = TexAttribOffset + TexAttribSize * sizeof(float);
     355    static const unsigned TriangleAttribOffset = MeshAttribOffset + MeshAttribSize * sizeof(float);
     356
     357    bindVertexAttribute(m_compiledProgram->positionAttribLocation(), PositionAttribSize, PositionAttribOffset);
     358    bindVertexAttribute(m_compiledProgram->texAttribLocation(), TexAttribSize, TexAttribOffset);
     359    // FIXME: Get rid of the internal tex coord attribute "css_a_texCoord".
     360    // https://bugs.webkit.org/show_bug.cgi?id=94358
     361    bindVertexAttribute(m_compiledProgram->internalTexCoordAttribLocation(), TexAttribSize, TexAttribOffset);
     362    bindVertexAttribute(m_compiledProgram->meshAttribLocation(), MeshAttribSize, MeshAttribOffset);
    344363    if (m_meshType == CustomFilterOperation::DETACHED)
    345         bindVertexAttribute(m_compiledProgram->triangleAttribLocation(), 3, offset);
     364        bindVertexAttribute(m_compiledProgram->triangleAttribLocation(), TriangleAttribSize, TriangleAttribOffset);
    346365   
    347366    bindProgramParameters();
  • trunk/Source/WebCore/platform/graphics/filters/FECustomFilter.h

    r127046 r127217  
    5252class CustomFilterProgram;
    5353class CustomFilterTransformParameter;
     54class CustomFilterValidatedProgram;
    5455class DrawingBuffer;
    5556class GraphicsContext3D;
     
    5960class FECustomFilter : public FilterEffect {
    6061public:
    61     static PassRefPtr<FECustomFilter> create(Filter*, CustomFilterGlobalContext*, PassRefPtr<CustomFilterProgram>, const CustomFilterParameterList&,
     62    static PassRefPtr<FECustomFilter> create(Filter*, CustomFilterGlobalContext*, PassRefPtr<CustomFilterValidatedProgram>, const CustomFilterParameterList&,
    6263                   unsigned meshRows, unsigned meshColumns, CustomFilterOperation::MeshBoxType,
    6364                   CustomFilterOperation::MeshType);
     
    6970
    7071private:
    71     FECustomFilter(Filter*, CustomFilterGlobalContext*, PassRefPtr<CustomFilterProgram>, const CustomFilterParameterList&,
     72    FECustomFilter(Filter*, CustomFilterGlobalContext*, PassRefPtr<CustomFilterValidatedProgram>, const CustomFilterParameterList&,
    7273                   unsigned meshRows, unsigned meshColumns, CustomFilterOperation::MeshBoxType,
    7374                   CustomFilterOperation::MeshType);
     
    7980    void deleteRenderBuffers();
    8081    void resizeContext(const IntSize& newContextSize);
    81     void bindVertexAttribute(int attributeLocation, unsigned size, unsigned& offset);
     82    void bindVertexAttribute(int attributeLocation, unsigned size, unsigned offset);
    8283    void bindProgramNumberParameters(int uniformLocation, CustomFilterNumberParameter*);
    8384    void bindProgramTransformParameter(int uniformLocation, CustomFilterTransformParameter*);
     
    9091    RefPtr<GraphicsContext3D> m_context;
    9192    RefPtr<Texture> m_inputTexture;
     93    RefPtr<CustomFilterValidatedProgram> m_validatedProgram;
    9294    RefPtr<CustomFilterCompiledProgram> m_compiledProgram;
    9395    RefPtr<CustomFilterMesh> m_mesh;
  • trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp

    r126927 r127217  
    4747#include "CustomFilterProgram.h"
    4848#include "CustomFilterOperation.h"
     49#include "CustomFilterValidatedProgram.h"
    4950#include "FECustomFilter.h"
    5051#include "RenderView.h"
     
    9091    Settings* settings = document->settings();
    9192    return settings && settings->isCSSCustomFilterEnabled() && settings->webGLEnabled();
     93}
     94
     95static PassRefPtr<FECustomFilter> createCustomFilterEffect(Filter* filter, Document* document, CustomFilterOperation* operation)
     96{
     97    if (!isCSSCustomFilterEnabled(document))
     98        return 0;
     99   
     100    RefPtr<CustomFilterProgram> program = operation->program();
     101    if (!program->isLoaded())
     102        return 0;
     103
     104    CustomFilterGlobalContext* globalContext = document->renderView()->customFilterGlobalContext();
     105    globalContext->prepareContextIfNeeded(document->view()->hostWindow());
     106    RefPtr<CustomFilterValidatedProgram> validatedProgram = globalContext->getValidatedProgram(program->programInfo());
     107    if (!validatedProgram->isInitialized())
     108        return 0;
     109
     110    return FECustomFilter::create(filter, globalContext, validatedProgram, operation->parameters(),
     111                                  operation->meshRows(), operation->meshColumns(),
     112                                  operation->meshBoxType(), operation->meshType());
    92113}
    93114#endif
     
    324345            break;
    325346        }
    326 #if ENABLE(CSS_SHADERS)
     347#if ENABLE(CSS_SHADERS) && ENABLE(WEBGL)
    327348        case FilterOperation::CUSTOM: {
    328 #if ENABLE(WEBGL)
    329             if (!isCSSCustomFilterEnabled(document))
    330                 continue;
    331            
    332349            CustomFilterOperation* customFilterOperation = static_cast<CustomFilterOperation*>(filterOperation);
    333             RefPtr<CustomFilterProgram> program = customFilterOperation->program();
    334             if (program->isLoaded()) {
    335                 CustomFilterGlobalContext* globalContext = document->renderView()->customFilterGlobalContext();
    336                 globalContext->prepareContextIfNeeded(document->view()->hostWindow());
    337                 effect = FECustomFilter::create(this, globalContext, program, customFilterOperation->parameters(),
    338                                                 customFilterOperation->meshRows(), customFilterOperation->meshColumns(),
    339                                                 customFilterOperation->meshBoxType(), customFilterOperation->meshType());
     350            effect = createCustomFilterEffect(this, document, customFilterOperation);
     351            if (effect)
    340352                m_hasCustomShaderFilter = true;
    341             }
    342 #endif
    343353            break;
    344354        }
  • trunk/Source/WebCore/rendering/FilterEffectRenderer.h

    r126986 r127217  
    113113    LayoutRect computeSourceImageRectForDirtyRect(const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect);
    114114
    115 #if ENABLE(CSS_SHADERS)
     115#if ENABLE(CSS_SHADERS) && ENABLE(WEBGL)
    116116    bool hasCustomShaderFilter() const { return m_hasCustomShaderFilter; }
    117117#endif
Note: See TracChangeset for help on using the changeset viewer.