Changeset 138489 in webkit


Ignore:
Timestamp:
Dec 26, 2012 6:29:21 PM (11 years ago)
Author:
commit-queue@webkit.org
Message:

[Texmap] Instead of having multiple shaders sources with lots of duplication, we should have one shader source with MACRO variants
https://bugs.webkit.org/show_bug.cgi?id=104815

Patch by No'am Rosenthal <Noam Rosenthal> on 2012-12-26
Reviewed by Kenneth Rohde Christiansen.

Created templates for the vertex and fragment shaders, and added some MACROs in
TextureMapperShaderManager to allow GLSL precompiler-based configuration.

The template follows a pattern where the main function in the shader calls
applyFooBarIfNeeded(), while applyFooBar() is implemented. The Macros prepended to the template define whether applyIfNeeded resolves to the real function or to a noop.

In addition, made some small changes to the filter shaders so that they can use the same code as the normal shaders.

Covered by existing pixel/ref tests when run on Qt/EFL/GTK.

  • platform/graphics/texmap/TextureMapperGL.cpp:

(WebCore::TextureMapperGL::drawTexture):
(WebCore::TextureMapperGL::drawSolidColor):
(WebCore::TextureMapperGL::drawTextureWithAntialiasing):
(WebCore::optionsForFilterType):
(WebCore):
(WebCore::getPassesRequiredForFilter):
(WebCore::prepareFilterProgram):
(WebCore::TextureMapperGL::drawFiltered):
(WebCore::BitmapTextureGL::applyFilters):

Always draw using the drawQuad function, and use the new TextureMapperShaderManager::Options mask instead of the old ShaderKey.

  • platform/graphics/texmap/TextureMapperShaderManager.cpp:

(WebCore):
(WebCore::getShaderSpec):
(WebCore::TextureMapperShaderManager::getShaderProgram):

  • platform/graphics/texmap/TextureMapperShaderManager.h:

(TextureMapperShaderProgram):
(TextureMapperShaderManager):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r138487 r138489  
     12012-12-26  No'am Rosenthal  <noam@webkit.org>
     2
     3        [Texmap] Instead of having multiple shaders sources with lots of duplication, we should have one shader source with MACRO variants
     4        https://bugs.webkit.org/show_bug.cgi?id=104815
     5
     6        Reviewed by Kenneth Rohde Christiansen.
     7
     8        Created templates for the vertex and fragment shaders, and added some MACROs in
     9        TextureMapperShaderManager to allow GLSL precompiler-based configuration.
     10
     11        The template follows a pattern where the main function in the shader calls
     12        applyFooBarIfNeeded(), while applyFooBar() is implemented. The Macros prepended to the template define whether applyIfNeeded resolves to the real function or to a noop.
     13
     14        In addition, made some small changes to the filter shaders so that they can use the same code as the normal shaders.
     15
     16        Covered by existing pixel/ref tests when run on Qt/EFL/GTK.
     17
     18        * platform/graphics/texmap/TextureMapperGL.cpp:
     19        (WebCore::TextureMapperGL::drawTexture):
     20        (WebCore::TextureMapperGL::drawSolidColor):
     21        (WebCore::TextureMapperGL::drawTextureWithAntialiasing):
     22        (WebCore::optionsForFilterType):
     23        (WebCore):
     24        (WebCore::getPassesRequiredForFilter):
     25        (WebCore::prepareFilterProgram):
     26        (WebCore::TextureMapperGL::drawFiltered):
     27        (WebCore::BitmapTextureGL::applyFilters):
     28            Always draw using the drawQuad function, and use the new TextureMapperShaderManager::Options mask instead of the old ShaderKey.
     29
     30        * platform/graphics/texmap/TextureMapperShaderManager.cpp:
     31        (WebCore):
     32        (WebCore::getShaderSpec):
     33        (WebCore::TextureMapperShaderManager::getShaderProgram):
     34        * platform/graphics/texmap/TextureMapperShaderManager.h:
     35        (TextureMapperShaderProgram):
     36        (TextureMapperShaderManager):
     37
    1382012-12-26  Huang Dongsung  <luxtella@company100.net>
    239
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp

    r138168 r138489  
    8585            return adoptRef(new SharedGLData(context));
    8686        }
    87 
    88 
    8987
    9088        TextureMapperShaderManager textureMapperShaderManager;
     
    414412        return;
    415413
    416     TextureMapperShaderManager::ShaderKey key = TextureMapperShaderManager::Default;
    417     if (masked && useRect)
    418         key = TextureMapperShaderManager::MaskedRect;
    419     else if (masked)
    420         key = TextureMapperShaderManager::Masked;
    421     else if (useRect)
    422         key = TextureMapperShaderManager::Rect;
     414    TextureMapperShaderManager::Options options = TextureMapperShaderManager::Texture;
     415    if (masked)
     416        options |= TextureMapperShaderManager::Mask;
     417    if (flags & ShouldUseARBTextureRect)
     418        options |= TextureMapperShaderManager::Rect;
     419    if (opacity < 1)
     420        options |= TextureMapperShaderManager::Opacity;
    423421
    424422    RefPtr<TextureMapperShaderProgram> program;
    425     program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(key);
     423    program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(options);
    426424    m_context3D->useProgram(program->programID());
    427425
     
    563561    quadToEdgeArray(expandedQuadInScreenSpace, targetQuadEdges);
    564562    quadToEdgeArray(inflateQuad(quadInScreenSpace.boundingBox(),  inflationDistance), targetQuadEdges + 12);
    565 
    566     RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::Antialiased);
     563    TextureMapperShaderManager::Options options = TextureMapperShaderManager::Antialias | TextureMapperShaderManager::Texture;
     564    if (opacity < 1)
     565        options |= TextureMapperShaderManager::Opacity;
     566
     567    RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(options);
    567568    m_context3D->useProgram(program->programID());
    568569    m_context3D->uniform3fv(program->expandedQuadEdgesInScreenSpaceLocation(), 8, targetQuadEdges);
     
    757758#if ENABLE(CSS_FILTERS)
    758759
    759 static TextureMapperShaderManager::ShaderKey keyForFilterType(FilterOperation::OperationType type, unsigned pass)
     760static TextureMapperShaderManager::Options optionsForFilterType(FilterOperation::OperationType type, unsigned pass)
    760761{
    761762    switch (type) {
    762763    case FilterOperation::GRAYSCALE:
    763         return TextureMapperShaderManager::GrayscaleFilter;
     764        return TextureMapperShaderManager::Texture | TextureMapperShaderManager::GrayscaleFilter;
    764765    case FilterOperation::SEPIA:
    765         return TextureMapperShaderManager::SepiaFilter;
     766        return TextureMapperShaderManager::Texture | TextureMapperShaderManager::SepiaFilter;
    766767    case FilterOperation::SATURATE:
    767         return TextureMapperShaderManager::SaturateFilter;
     768        return TextureMapperShaderManager::Texture | TextureMapperShaderManager::SaturateFilter;
    768769    case FilterOperation::HUE_ROTATE:
    769         return TextureMapperShaderManager::HueRotateFilter;
     770        return TextureMapperShaderManager::Texture | TextureMapperShaderManager::HueRotateFilter;
    770771    case FilterOperation::INVERT:
    771         return TextureMapperShaderManager::InvertFilter;
     772        return TextureMapperShaderManager::Texture | TextureMapperShaderManager::InvertFilter;
    772773    case FilterOperation::BRIGHTNESS:
    773         return TextureMapperShaderManager::BrightnessFilter;
     774        return TextureMapperShaderManager::Texture | TextureMapperShaderManager::BrightnessFilter;
    774775    case FilterOperation::CONTRAST:
    775         return TextureMapperShaderManager::ContrastFilter;
     776        return TextureMapperShaderManager::Texture | TextureMapperShaderManager::ContrastFilter;
    776777    case FilterOperation::OPACITY:
    777         return TextureMapperShaderManager::OpacityFilter;
     778        return TextureMapperShaderManager::Texture | TextureMapperShaderManager::OpacityFilter;
    778779    case FilterOperation::BLUR:
    779780        return TextureMapperShaderManager::BlurFilter;
    780781    case FilterOperation::DROP_SHADOW:
    781         return pass ? TextureMapperShaderManager::ShadowFilterPass2 : TextureMapperShaderManager::ShadowFilterPass1;
     782        return TextureMapperShaderManager::AlphaBlur
     783            | (pass ? TextureMapperShaderManager::ContentTexture | TextureMapperShaderManager::SolidColor: 0);
    782784    default:
    783785        ASSERT_NOT_REACHED();
    784         return TextureMapperShaderManager::Invalid;
     786        return 0;
    785787    }
    786788}
     
    853855    case FilterOperation::SATURATE:
    854856    case FilterOperation::HUE_ROTATE:
    855         context->uniform1f(program->amountLocation(), static_cast<const BasicColorMatrixFilterOperation&>(operation).amount());
     857        context->uniform1f(program->filterAmountLocation(), static_cast<const BasicColorMatrixFilterOperation&>(operation).amount());
    856858        break;
    857859    case FilterOperation::INVERT:
     
    859861    case FilterOperation::CONTRAST:
    860862    case FilterOperation::OPACITY:
    861         context->uniform1f(program->amountLocation(), static_cast<const BasicComponentTransferFilterOperation&>(operation).amount());
     863        context->uniform1f(program->filterAmountLocation(), static_cast<const BasicComponentTransferFilterOperation&>(operation).amount());
    862864        break;
    863865    case FilterOperation::BLUR: {
     
    880882        switch (pass) {
    881883        case 0:
    882             // First pass: vertical alpha blur.
     884            // First pass: horizontal alpha blur.
     885            context->uniform2f(program->blurRadiusLocation(), shadow.stdDeviation() / float(size.width()), 0);
    883886            context->uniform2f(program->shadowOffsetLocation(), float(shadow.location().x()) / float(size.width()), float(shadow.location().y()) / float(size.height()));
    884             context->uniform1f(program->blurRadiusLocation(), shadow.stdDeviation() / float(size.width()));
    885887            break;
    886888        case 1:
    887889            // Second pass: we need the shadow color and the content texture for compositing.
    888             context->uniform1f(program->blurRadiusLocation(), shadow.stdDeviation() / float(size.height()));
     890            float r, g, b, a;
     891            shadow.color().getRGBA(r, g, b, a);
     892            context->uniform4f(program->colorLocation(), r, g, b, a);
     893            context->uniform2f(program->blurRadiusLocation(), 0, shadow.stdDeviation() / float(size.height()));
     894            context->uniform2f(program->shadowOffsetLocation(), 0, 0);
    889895            context->activeTexture(GraphicsContext3D::TEXTURE1);
    890896            context->bindTexture(GraphicsContext3D::TEXTURE_2D, contentTexture);
    891897            context->uniform1i(program->contentTextureLocation(), 1);
    892             float r, g, b, a;
    893             shadow.color().getRGBA(r, g, b, a);
    894             context->uniform4f(program->shadowColorLocation(), r, g, b, a);
    895898            break;
    896899        }
     
    961964{
    962965    // For standard filters, we always draw the whole texture without transformations.
    963     TextureMapperShaderManager::ShaderKey key = keyForFilterType(filter.getOperationType(), pass);
    964     RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(key);
     966    TextureMapperShaderManager::Options options = optionsForFilterType(filter.getOperationType(), pass);
     967    RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(options);
    965968    ASSERT(program);
    966969
    967970    prepareFilterProgram(program.get(), filter, pass, sampler.contentSize(), static_cast<const BitmapTextureGL&>(contentTexture).id());
    968 
    969     m_context3D->enableVertexAttribArray(program->vertexLocation());
    970     m_context3D->enableVertexAttribArray(program->texCoordLocation());
    971     m_context3D->activeTexture(GraphicsContext3D::TEXTURE0);
    972     m_context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, static_cast<const BitmapTextureGL&>(sampler).id());
    973     m_context3D->uniform1i(program->samplerLocation(), 0);
    974     const GC3Dfloat targetVertices[] = {-1, -1, 1, -1, 1, 1, -1, 1};
    975     const GC3Dfloat sourceVertices[] = {0, 0, 1, 0, 1, 1, 0, 1};
    976     m_context3D->vertexAttribPointer(program->vertexLocation(), 2, GraphicsContext3D::FLOAT, false, 0, GC3Dintptr(targetVertices));
    977     m_context3D->vertexAttribPointer(program->texCoordLocation(), 2, GraphicsContext3D::FLOAT, false, 0, GC3Dintptr(sourceVertices));
    978     m_context3D->disable(GraphicsContext3D::BLEND);
    979     m_context3D->drawArrays(GraphicsContext3D::TRIANGLE_FAN, 0, 4);
    980     m_context3D->disableVertexAttribArray(program->vertexLocation());
    981     m_context3D->disableVertexAttribArray(program->texCoordLocation());
     971    FloatRect targetRect(IntPoint::zero(), sampler.contentSize());
     972    drawTexturedQuadWithProgram(program.get(), static_cast<const BitmapTextureGL&>(sampler).id(), 0, IntSize(1, 1), targetRect, TransformationMatrix(), 1, 0);
    982973}
    983974
     
    11731164    data().initializeStencil();
    11741165
    1175     RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::Default);
     1166    RefPtr<TextureMapperShaderProgram> program = data().sharedGLData().textureMapperShaderManager.getShaderProgram(TextureMapperShaderManager::SolidColor);
    11761167
    11771168    m_context3D->useProgram(program->programID());
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp

    r138168 r138489  
    2424
    2525#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
    26 
    2726#include "LengthFunctions.h"
    2827#include "Logging.h"
    2928#include "TextureMapperGL.h"
    3029
     30#include <wtf/text/StringBuilder.h>
     31
    3132#define STRINGIFY(...) #__VA_ARGS__
    3233
    3334namespace WebCore {
    34 
    3535
    3636static inline bool compositingLogEnabled()
     
    107107}
    108108
    109 struct ShaderSpec {
     109static const char* vertexShaderSource =
     110    STRINGIFY(
     111        uniform mat4 u_matrix;
     112        uniform float u_flip;
     113        uniform vec2 u_textureSize;
     114        attribute vec4 a_vertex;
     115        varying vec2 v_texCoord;
     116        varying vec2 v_maskTexCoord;
     117
     118        void main(void)
     119        {
     120            vec4 position = a_vertex;
     121            v_texCoord = vec2(position.x, mix(position.y, 1. - position.y, u_flip)) * u_textureSize;
     122            v_maskTexCoord = vec2(position);
     123            gl_Position = u_matrix * a_vertex;
     124        }
     125    );
     126
     127#define GLSL_DIRECTIVE(...) "#"#__VA_ARGS__"\n"
     128#define DEFINE_APPLIER(Name) \
     129    "#ifdef ENABLE_"#Name"\n" \
     130    "#define apply"#Name"IfNeeded apply"#Name"\n"\
     131    "#else\n"\
     132    "#define apply"#Name"IfNeeded noop\n"\
     133    "#endif\n"
     134
     135#define RECT_TEXTURE_DIRECTIVE \
     136    GLSL_DIRECTIVE(ifdef ENABLE_Rect) \
     137        GLSL_DIRECTIVE(define SamplerType sampler2DRect) \
     138        GLSL_DIRECTIVE(define SamplerFunction texture2DRect) \
     139    GLSL_DIRECTIVE(else) \
     140        GLSL_DIRECTIVE(define SamplerType sampler2D) \
     141        GLSL_DIRECTIVE(define SamplerFunction texture2D) \
     142    GLSL_DIRECTIVE(endif)
     143
     144#define ENABLE_APPLIER(Name) "#define ENABLE_"#Name"\n"
     145#define BLUR_CONSTANTS \
     146    GLSL_DIRECTIVE(define GAUSSIAN_KERNEL_HALF_WIDTH 11) \
     147    GLSL_DIRECTIVE(define GAUSSIAN_KERNEL_STEP 0.2)
     148
     149
     150static const char* fragmentTemplate =
     151    DEFINE_APPLIER(Texture)
     152    DEFINE_APPLIER(SolidColor)
     153    DEFINE_APPLIER(Opacity)
     154    DEFINE_APPLIER(Mask)
     155    DEFINE_APPLIER(Antialias)
     156    DEFINE_APPLIER(GrayscaleFilter)
     157    DEFINE_APPLIER(SepiaFilter)
     158    DEFINE_APPLIER(SaturateFilter)
     159    DEFINE_APPLIER(HueRotateFilter)
     160    DEFINE_APPLIER(InvertFilter)
     161    DEFINE_APPLIER(BrightnessFilter)
     162    DEFINE_APPLIER(ContrastFilter)
     163    DEFINE_APPLIER(OpacityFilter)
     164    DEFINE_APPLIER(BlurFilter)
     165    DEFINE_APPLIER(AlphaBlur)
     166    DEFINE_APPLIER(ContentTexture)
     167    RECT_TEXTURE_DIRECTIVE
     168    BLUR_CONSTANTS
     169    STRINGIFY(
     170        precision mediump float;
     171        uniform SamplerType s_sampler;
     172        uniform sampler2D s_mask;
     173        uniform sampler2D s_contentTexture;
     174        uniform float u_opacity;
     175        varying vec2 v_texCoord;
     176        varying vec2 v_maskTexCoord;
     177        uniform vec3 u_expandedQuadEdgesInScreenSpace[8];
     178        uniform float u_filterAmount;
     179        uniform vec2 u_blurRadius;
     180        uniform vec2 u_shadowOffset;
     181        uniform vec4 u_color;
     182        uniform float u_gaussianKernel[GAUSSIAN_KERNEL_HALF_WIDTH];
     183
     184        void noop(inout vec4 dummyParameter) { }
     185
     186        // The data passed in u_expandedQuadEdgesInScreenSpace is merely the
     187        // pre-scaled coeffecients of the line equations describing the four edges
     188        // of the expanded quad in screen space and the rectangular bounding box
     189        // of the expanded quad.
     190        //
     191        float normalizedDistance(vec3 edgeCoefficient)
     192        {
     193            // We are doing a simple distance calculation here according to the formula:
     194            // (A*p.x + B*p.y + C) / sqrt(A^2 + B^2) = distance from line to p
     195            // Note that A, B and C have already been scaled by 1 / sqrt(A^2 + B^2).
     196            return clamp(dot(edgeCoefficient, vec3(gl_FragCoord.xy, 1.)), 0., 1.);
     197        }
     198
     199        float antialiasQuad(vec3 coefficient1, vec3 coefficient2, vec3 coefficient3, vec3 coefficient4)
     200        {
     201            // Now we want to reduce the alpha value of the fragment if it is close to the
     202            // edges of the expanded quad (or rectangular bounding box -- which seems to be
     203            // important for backfacing quads). Note that we are combining the contribution
     204            // from the (top || bottom) and (left || right) edge by simply multiplying. This follows
     205            // the approach described at: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter22.html,
     206            // in this case without using Gaussian weights.
     207            return min(normalizedDistance(coefficient1), normalizedDistance(coefficient2))
     208                * min(normalizedDistance(coefficient3), normalizedDistance(coefficient4));
     209        }
     210
     211        float antialias()
     212        {
     213            float antialiasValueForQuad =
     214                antialiasQuad(u_expandedQuadEdgesInScreenSpace[0],
     215                    u_expandedQuadEdgesInScreenSpace[1],
     216                    u_expandedQuadEdgesInScreenSpace[2],
     217                    u_expandedQuadEdgesInScreenSpace[3]);
     218
     219            float antialiasValueForBoundingRect =
     220                antialiasQuad(u_expandedQuadEdgesInScreenSpace[4],
     221                    u_expandedQuadEdgesInScreenSpace[5],
     222                    u_expandedQuadEdgesInScreenSpace[6],
     223                    u_expandedQuadEdgesInScreenSpace[7]);
     224
     225            return min(antialiasValueForQuad, antialiasValueForBoundingRect);           
     226        }
     227
     228        void applyTexture(inout vec4 color) { color = SamplerFunction(s_sampler, v_texCoord); }
     229        void applyOpacity(inout vec4 color) { color *= u_opacity; }
     230        void applyAntialias(inout vec4 color) { color *= antialias(); }
     231        void applyMask(inout vec4 color) { color *= texture2D(s_mask, v_maskTexCoord).a; }
     232
     233        void applyGrayscaleFilter(inout vec4 color)
     234        {
     235            float amount = 1.0 - u_filterAmount;
     236            color = vec4((0.2126 + 0.7874 * amount) * color.r + (0.7152 - 0.7152 * amount) * color.g + (0.0722 - 0.0722 * amount) * color.b,
     237                (0.2126 - 0.2126 * amount) * color.r + (0.7152 + 0.2848 * amount) * color.g + (0.0722 - 0.0722 * amount) * color.b,
     238                (0.2126 - 0.2126 * amount) * color.r + (0.7152 - 0.7152 * amount) * color.g + (0.0722 + 0.9278 * amount) * color.b,
     239                color.a);
     240        }
     241
     242        void applySepiaFilter(inout vec4 color)
     243        {
     244            float amount = 1.0 - u_filterAmount;
     245            color = vec4((0.393 + 0.607 * amount) * color.r + (0.769 - 0.769 * amount) * color.g + (0.189 - 0.189 * amount) * color.b,
     246                (0.349 - 0.349 * amount) * color.r + (0.686 + 0.314 * amount) * color.g + (0.168 - 0.168 * amount) * color.b,
     247                (0.272 - 0.272 * amount) * color.r + (0.534 - 0.534 * amount) * color.g + (0.131 + 0.869 * amount) * color.b,
     248                color.a);
     249        }
     250
     251        void applySaturateFilter(inout vec4 color)
     252        {
     253            color = vec4((0.213 + 0.787 * u_filterAmount) * color.r + (0.715 - 0.715 * u_filterAmount) * color.g + (0.072 - 0.072 * u_filterAmount) * color.b,
     254                (0.213 - 0.213 * u_filterAmount) * color.r + (0.715 + 0.285 * u_filterAmount) * color.g + (0.072 - 0.072 * u_filterAmount) * color.b,
     255                (0.213 - 0.213 * u_filterAmount) * color.r + (0.715 - 0.715 * u_filterAmount) * color.g + (0.072 + 0.928 * u_filterAmount) * color.b,
     256                color.a);
     257        }
     258
     259        void applyHueRotateFilter(inout vec4 color)
     260        {
     261            float pi = 3.14159265358979323846;
     262            float c = cos(u_filterAmount * pi / 180.0);
     263            float s = sin(u_filterAmount * pi / 180.0);
     264            color = vec4(color.r * (0.213 + c * 0.787 - s * 0.213) + color.g * (0.715 - c * 0.715 - s * 0.715) + color.b * (0.072 - c * 0.072 + s * 0.928),
     265                color.r * (0.213 - c * 0.213 + s * 0.143) + color.g * (0.715 + c * 0.285 + s * 0.140) + color.b * (0.072 - c * 0.072 - s * 0.283),
     266                color.r * (0.213 - c * 0.213 - s * 0.787) +  color.g * (0.715 - c * 0.715 + s * 0.715) + color.b * (0.072 + c * 0.928 + s * 0.072),
     267                color.a);
     268        }
     269
     270        float invert(float n) { return (1.0 - n) * u_filterAmount + n * (1.0 - u_filterAmount); }
     271        void applyInvertFilter(inout vec4 color)
     272        {
     273            color = vec4(invert(color.r), invert(color.g), invert(color.b), color.a);
     274        }
     275
     276        void applyBrightnessFilter(inout vec4 color)
     277        {
     278            color = vec4(color.rgb * (1.0 + u_filterAmount), color.a);
     279        }
     280
     281        float contrast(float n) { return (n - 0.5) * u_filterAmount + 0.5; }
     282        void applyContrastFilter(inout vec4 color)
     283        {
     284            color = vec4(contrast(color.r), contrast(color.g), contrast(color.b), color.a);
     285        }
     286
     287        void applyOpacityFilter(inout vec4 color)
     288        {
     289            color = vec4(color.r, color.g, color.b, color.a * u_filterAmount);
     290        }
     291
     292        vec4 sampleColorAtRadius(float radius)
     293        {
     294            vec2 coord = v_texCoord + radius * u_blurRadius;
     295            return SamplerFunction(s_sampler, coord) * float(coord.x > 0. && coord.y > 0. && coord.x < 1. && coord.y < 1.);
     296        }
     297
     298        float sampleAlphaAtRadius(float radius)
     299        {
     300            vec2 coord = v_texCoord - u_shadowOffset + radius * u_blurRadius;
     301            return SamplerFunction(s_sampler, coord).a * float(coord.x > 0. && coord.y > 0. && coord.x < 1. && coord.y < 1.);
     302        }
     303
     304        void applyBlurFilter(inout vec4 color)
     305        {
     306            vec4 total = sampleColorAtRadius(0.) * u_gaussianKernel[0];
     307            for (int i = 1; i < GAUSSIAN_KERNEL_HALF_WIDTH; i++) {
     308                total += sampleColorAtRadius(float(i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
     309                total += sampleColorAtRadius(float(-1 * i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
     310            }
     311
     312            color = total;
     313        }
     314
     315        void applyAlphaBlur(inout vec4 color)
     316        {
     317            float total = sampleAlphaAtRadius(0.) * u_gaussianKernel[0];
     318            for (int i = 1; i < GAUSSIAN_KERNEL_HALF_WIDTH; i++) {
     319                total += sampleAlphaAtRadius(float(i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
     320                total += sampleAlphaAtRadius(float(-1 * i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
     321            }
     322
     323            color *= total;
     324        }
     325
     326        vec4 sourceOver(vec4 src, vec4 dst) { return src + dst * (1. - dst.a); }
     327
     328        void applyContentTexture(inout vec4 color)
     329        {
     330            vec4 contentColor = texture2D(s_contentTexture, v_texCoord);
     331            color = sourceOver(contentColor, color);
     332        }
     333
     334        void applySolidColor(inout vec4 color)
     335        {
     336            color *= u_color;
     337        }
     338
     339        void main(void)
     340        {
     341            vec4 color = vec4(1., 1., 1., 1.);
     342            applyTextureIfNeeded(color);
     343            applySolidColorIfNeeded(color);
     344            applyAntialiasIfNeeded(color);
     345            applyMaskIfNeeded(color);
     346            applyOpacityIfNeeded(color);
     347            applyGrayscaleFilterIfNeeded(color);
     348            applySepiaFilterIfNeeded(color);
     349            applySaturateFilterIfNeeded(color);
     350            applyHueRotateFilterIfNeeded(color);
     351            applyInvertFilterIfNeeded(color);
     352            applyBrightnessFilterIfNeeded(color);
     353            applyContrastFilterIfNeeded(color);
     354            applyOpacityFilterIfNeeded(color);
     355            applyBlurFilterIfNeeded(color);
     356            applyAlphaBlurIfNeeded(color);
     357            applyContentTextureIfNeeded(color);
     358            gl_FragColor = color;
     359        }
     360    );
     361
     362
     363static void getShaderSpec(TextureMapperShaderManager::Options options, String& vertexSource, String& fragmentSource)
     364{
     365    StringBuilder fragmentBuilder;
     366#define SET_APPLIER_FROM_OPTIONS(Applier) \
     367    if (options & TextureMapperShaderManager::Applier) \
     368        fragmentBuilder.append(ENABLE_APPLIER(Applier));
     369
     370    SET_APPLIER_FROM_OPTIONS(Texture)
     371    SET_APPLIER_FROM_OPTIONS(Rect)
     372    SET_APPLIER_FROM_OPTIONS(SolidColor)
     373    SET_APPLIER_FROM_OPTIONS(Opacity)
     374    SET_APPLIER_FROM_OPTIONS(Mask)
     375    SET_APPLIER_FROM_OPTIONS(Antialias)
     376    SET_APPLIER_FROM_OPTIONS(GrayscaleFilter)
     377    SET_APPLIER_FROM_OPTIONS(SepiaFilter)
     378    SET_APPLIER_FROM_OPTIONS(SaturateFilter)
     379    SET_APPLIER_FROM_OPTIONS(HueRotateFilter)
     380    SET_APPLIER_FROM_OPTIONS(BrightnessFilter)
     381    SET_APPLIER_FROM_OPTIONS(ContrastFilter)
     382    SET_APPLIER_FROM_OPTIONS(InvertFilter)
     383    SET_APPLIER_FROM_OPTIONS(OpacityFilter)
     384    SET_APPLIER_FROM_OPTIONS(BlurFilter)
     385    SET_APPLIER_FROM_OPTIONS(AlphaBlur)
     386    SET_APPLIER_FROM_OPTIONS(ContentTexture)
     387
     388    fragmentBuilder.append(fragmentTemplate);
     389    vertexSource = vertexShaderSource;
     390    fragmentSource = fragmentBuilder.toString();
     391}
     392
     393TextureMapperShaderManager::TextureMapperShaderManager(GraphicsContext3D* context)
     394    : m_context(context)
     395{
     396}
     397
     398TextureMapperShaderManager::~TextureMapperShaderManager()
     399{
     400}
     401
     402PassRefPtr<TextureMapperShaderProgram> TextureMapperShaderManager::getShaderProgram(Options options)
     403{
     404    TextureMapperShaderProgramMap::iterator it = m_programs.find(options);
     405    if (it != m_programs.end())
     406        return it->value;
     407
    110408    String vertexShader;
    111409    String fragmentShader;
    112     ShaderSpec(const char* vertex = 0, const char* fragment = 0)
    113         : vertexShader(vertex ? String(ASCIILiteral(vertex)) : String())
    114         , fragmentShader(fragment ? String(ASCIILiteral(fragment)) : String())
    115     {
    116     }
     410    getShaderSpec(options, vertexShader, fragmentShader);
     411    RefPtr<TextureMapperShaderProgram> program = TextureMapperShaderProgram::create(m_context, vertexShader, fragmentShader);
     412    m_programs.add(options, program);
     413    return program;
     414}
    117415};
    118416
    119 static void getShaderSpec(TextureMapperShaderManager::ShaderKey key, String& vertexSource, String& fragmentSource)
    120 {
    121     static Vector<ShaderSpec> specs = Vector<ShaderSpec>();
    122     static const char* fragmentOpacityAndMask =
    123         STRINGIFY(
    124             precision mediump float;
    125             uniform sampler2D s_sampler;
    126             uniform sampler2D s_mask;
    127             uniform float u_opacity;
    128             varying vec2 v_sourceTexCoord;
    129             varying vec2 v_maskTexCoord;
    130             void main(void)
    131             {
    132                 vec4 color = texture2D(s_sampler, v_sourceTexCoord);
    133                 vec4 maskColor = texture2D(s_mask, v_maskTexCoord);
    134                 float fragmentAlpha = u_opacity * maskColor.a;
    135                 gl_FragColor = vec4(color.rgb * fragmentAlpha, color.a * fragmentAlpha);
    136             }
    137         );
    138 
    139     static const char* fragmentRectOpacityAndMask =
    140         STRINGIFY(
    141             precision mediump float;
    142             uniform sampler2DRect s_sampler;
    143             uniform sampler2DRect s_mask;
    144             uniform float u_opacity;
    145             varying vec2 v_sourceTexCoord;
    146             varying vec2 v_maskTexCoord;
    147             void main(void)
    148             {
    149                 vec4 color = texture2DRect(s_sampler, v_sourceTexCoord);
    150                 vec4 maskColor = texture2DRect(s_mask, v_maskTexCoord);
    151                 float fragmentAlpha = u_opacity * maskColor.a;
    152                 gl_FragColor = vec4(color.rgb * fragmentAlpha, color.a * fragmentAlpha);
    153             }
    154         );
    155 
    156     static const char* vertexOpacityAndMask =
    157         STRINGIFY(
    158             uniform mat4 u_matrix;
    159             uniform float u_flip;
    160             uniform vec2 u_textureSize;
    161             attribute vec4 a_vertex;
    162             varying vec2 v_sourceTexCoord;
    163             varying vec2 v_maskTexCoord;
    164             void main(void)
    165             {
    166                 v_sourceTexCoord = vec2(a_vertex.x, mix(a_vertex.y, 1. - a_vertex.y, u_flip)) * u_textureSize;
    167                 v_maskTexCoord = vec2(a_vertex);
    168                 gl_Position = u_matrix * a_vertex;
    169             }
    170         );
    171 
    172     static const char* fragmentSimple =
    173         STRINGIFY(
    174             precision mediump float;
    175             uniform sampler2D s_sampler;
    176             uniform float u_opacity;
    177             varying vec2 v_sourceTexCoord;
    178             void main(void)
    179             {
    180                 vec4 color = texture2D(s_sampler, v_sourceTexCoord);
    181                 gl_FragColor = vec4(color.rgb * u_opacity, color.a * u_opacity);
    182             }
    183         );
    184 
    185     static const char* fragmentAntialiasingNoMask =
    186         STRINGIFY(
    187             precision mediump float;
    188             uniform sampler2D s_sampler;
    189             varying vec2 v_sourceTexCoord;
    190             uniform float u_opacity;
    191             uniform vec3 u_expandedQuadEdgesInScreenSpace[8];
    192 
    193                 // The data passed in u_expandedQuadEdgesInScreenSpace is merely the
    194                 // pre-scaled coeffecients of the line equations describing the four edges
    195                 // of the expanded quad in screen space and the rectangular bounding box
    196                 // of the expanded quad.
    197                 //
    198             float normalizedDistance(vec3 edgeCoefficient)
    199             {
    200                 // We are doing a simple distance calculation here according to the formula:
    201                 // (A*p.x + B*p.y + C) / sqrt(A^2 + B^2) = distance from line to p
    202                 // Note that A, B and C have already been scaled by 1 / sqrt(A^2 + B^2).
    203                 return clamp(dot(edgeCoefficient, vec3(gl_FragCoord.xy, 1.)), 0., 1.);
    204             }
    205 
    206             float antialiasQuad(vec3 coefficient1, vec3 coefficient2, vec3 coefficient3, vec3 coefficient4)
    207             {
    208                 // Now we want to reduce the alpha value of the fragment if it is close to the
    209                 // edges of the expanded quad (or rectangular bounding box -- which seems to be
    210                 // important for backfacing quads). Note that we are combining the contribution
    211                 // from the (top || bottom) and (left || right) edge by simply multiplying. This follows
    212                 // the approach described at: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter22.html,
    213                 // in this case without using Gaussian weights.
    214                 return min(normalizedDistance(coefficient1), normalizedDistance(coefficient2))
    215                     * min(normalizedDistance(coefficient3), normalizedDistance(coefficient4));
    216             }
    217 
    218             float antialias()
    219             {
    220                 float antialiasValueForQuad =
    221                     antialiasQuad(u_expandedQuadEdgesInScreenSpace[0],
    222                         u_expandedQuadEdgesInScreenSpace[1],
    223                         u_expandedQuadEdgesInScreenSpace[2],
    224                         u_expandedQuadEdgesInScreenSpace[3]);
    225 
    226                 float antialiasValueForBoundingRect =
    227                     antialiasQuad(u_expandedQuadEdgesInScreenSpace[4],
    228                         u_expandedQuadEdgesInScreenSpace[5],
    229                         u_expandedQuadEdgesInScreenSpace[6],
    230                         u_expandedQuadEdgesInScreenSpace[7]);
    231 
    232                 return min(antialiasValueForQuad, antialiasValueForBoundingRect);           
    233             }
    234 
    235             void main()
    236             {
    237                 vec4 sampledColor = texture2D(s_sampler, clamp(v_sourceTexCoord, 0.0, 1.0));
    238                 gl_FragColor = sampledColor * u_opacity * antialias();
    239             }
    240         );
    241 
    242     static const char* fragmentRectSimple =
    243         STRINGIFY(
    244             precision mediump float;
    245             uniform sampler2DRect s_sampler;
    246             uniform float u_opacity;
    247             varying vec2 v_sourceTexCoord;
    248             void main(void)
    249             {
    250                 vec4 color = texture2DRect(s_sampler, v_sourceTexCoord);
    251                 gl_FragColor = vec4(color.rgb * u_opacity, color.a * u_opacity);
    252             }
    253         );
    254 
    255     static const char* vertexSimple =
    256         STRINGIFY(
    257             uniform mat4 u_matrix;
    258             uniform float u_flip;
    259             uniform vec2 u_textureSize;
    260             attribute vec4 a_vertex;
    261             varying vec2 v_sourceTexCoord;
    262             void main(void)
    263             {
    264                 v_sourceTexCoord = vec2(a_vertex.x, mix(a_vertex.y, 1. - a_vertex.y, u_flip)) * u_textureSize;
    265                 gl_Position = u_matrix * a_vertex;
    266             }
    267         );
    268 
    269     static const char* vertexSolidColor =
    270         STRINGIFY(
    271             uniform mat4 u_matrix;
    272             attribute vec4 a_vertex;
    273             void main(void)
    274             {
    275                 gl_Position = u_matrix * a_vertex;
    276             }
    277         );
    278 
    279 
    280     static const char* fragmentSolidColor =
    281         STRINGIFY(
    282             precision mediump float;
    283             uniform vec4 u_color;
    284             void main(void)
    285             {
    286                 gl_FragColor = u_color;
    287             }
    288         );
    289 
    290     static const char* vertexFilter =
    291         STRINGIFY(
    292             attribute vec4 a_vertex;
    293             attribute vec4 a_texCoord;
    294             varying vec2 v_texCoord;
    295             void main(void)
    296             {
    297                 v_texCoord = vec2(a_texCoord);
    298                 gl_Position = a_vertex;
    299             }
    300         );
    301 
    302 #define STANDARD_FILTER(...) \
    303         "precision mediump float;\n"\
    304         "varying vec2 v_texCoord;\n"\
    305         "uniform float u_amount;\n"\
    306         "uniform sampler2D s_sampler;\n"#__VA_ARGS__ \
    307         "void main(void)\n { gl_FragColor = shade(texture2D(s_sampler, v_texCoord)); }"
    308 
    309     static const char* fragmentGrayscaleFilter =
    310         STANDARD_FILTER(
    311             vec4 shade(lowp vec4 color)
    312             {
    313                 float amount = 1.0 - u_amount;
    314                 return vec4((0.2126 + 0.7874 * amount) * color.r + (0.7152 - 0.7152 * amount) * color.g + (0.0722 - 0.0722 * amount) * color.b,
    315                             (0.2126 - 0.2126 * amount) * color.r + (0.7152 + 0.2848 * amount) * color.g + (0.0722 - 0.0722 * amount) * color.b,
    316                             (0.2126 - 0.2126 * amount) * color.r + (0.7152 - 0.7152 * amount) * color.g + (0.0722 + 0.9278 * amount) * color.b,
    317                             color.a);
    318             }
    319         );
    320 
    321     static const char* fragmentSepiaFilter =
    322         STANDARD_FILTER(
    323             vec4 shade(lowp vec4 color)
    324             {
    325                 float amount = 1.0 - u_amount;
    326                 return vec4((0.393 + 0.607 * amount) * color.r + (0.769 - 0.769 * amount) * color.g + (0.189 - 0.189 * amount) * color.b,
    327                             (0.349 - 0.349 * amount) * color.r + (0.686 + 0.314 * amount) * color.g + (0.168 - 0.168 * amount) * color.b,
    328                             (0.272 - 0.272 * amount) * color.r + (0.534 - 0.534 * amount) * color.g + (0.131 + 0.869 * amount) * color.b,
    329                             color.a);
    330             }
    331         );
    332 
    333     static const char* fragmentSaturateFilter =
    334         STANDARD_FILTER(
    335             vec4 shade(lowp vec4 color)
    336             {
    337                 return vec4((0.213 + 0.787 * u_amount) * color.r + (0.715 - 0.715 * u_amount) * color.g + (0.072 - 0.072 * u_amount) * color.b,
    338                             (0.213 - 0.213 * u_amount) * color.r + (0.715 + 0.285 * u_amount) * color.g + (0.072 - 0.072 * u_amount) * color.b,
    339                             (0.213 - 0.213 * u_amount) * color.r + (0.715 - 0.715 * u_amount) * color.g + (0.072 + 0.928 * u_amount) * color.b,
    340                             color.a);
    341             }
    342         );
    343 
    344     static const char* fragmentHueRotateFilter =
    345         STANDARD_FILTER(
    346             vec4 shade(lowp vec4 color)
    347             {
    348                 float pi = 3.14159265358979323846;
    349                 float c = cos(u_amount * pi / 180.0);
    350                 float s = sin(u_amount * pi / 180.0);
    351                 return vec4(color.r * (0.213 + c * 0.787 - s * 0.213) + color.g * (0.715 - c * 0.715 - s * 0.715) + color.b * (0.072 - c * 0.072 + s * 0.928),
    352                             color.r * (0.213 - c * 0.213 + s * 0.143) + color.g * (0.715 + c * 0.285 + s * 0.140) + color.b * (0.072 - c * 0.072 - s * 0.283),
    353                             color.r * (0.213 - c * 0.213 - s * 0.787) +  color.g * (0.715 - c * 0.715 + s * 0.715) + color.b * (0.072 + c * 0.928 + s * 0.072),
    354                             color.a);
    355             }
    356         );
    357 
    358     static const char* fragmentInvertFilter =
    359         STANDARD_FILTER(
    360             float invert(lowp float n) { return (1.0 - n) * u_amount + n * (1.0 - u_amount); }
    361             vec4 shade(lowp vec4 color)
    362             {
    363                 return vec4(invert(color.r), invert(color.g), invert(color.b), color.a);
    364             }
    365         );
    366 
    367     static const char* fragmentBrightnessFilter =
    368         STANDARD_FILTER(
    369             vec4 shade(lowp vec4 color)
    370             {
    371                 return vec4(color.rgb * (1.0 + u_amount), color.a);
    372             }
    373         );
    374 
    375     static const char* fragmentContrastFilter =
    376         STANDARD_FILTER(
    377             float contrast(lowp float n) { return (n - 0.5) * u_amount + 0.5; }
    378             vec4 shade(lowp vec4 color)
    379             {
    380                 return vec4(contrast(color.r), contrast(color.g), contrast(color.b), color.a);
    381             }
    382         );
    383 
    384     static const char* fragmentOpacityFilter =
    385         STANDARD_FILTER(
    386             vec4 shade(lowp vec4 color)
    387             {
    388                 return vec4(color.r, color.g, color.b, color.a * u_amount);
    389             }
    390         );
    391 
    392 #define BLUR_CONSTANTS "#define GAUSSIAN_KERNEL_HALF_WIDTH 11\n#define GAUSSIAN_KERNEL_STEP 0.2\n"
    393 
    394     static const char* fragmentBlurFilter =
    395         BLUR_CONSTANTS
    396         STRINGIFY(
    397             // Create a normal distribution of 21 values between -2 and 2.
    398             precision mediump float;
    399             varying vec2 v_texCoord;
    400             uniform vec2 u_blurRadius;
    401             uniform sampler2D s_sampler;
    402             uniform float u_gaussianKernel[GAUSSIAN_KERNEL_HALF_WIDTH];
    403 
    404             vec4 sampleColor(float radius)
    405             {
    406                 vec2 coord = v_texCoord + radius * u_blurRadius;
    407                 return texture2D(s_sampler, coord) * float(coord.x > 0. && coord.y > 0. && coord.x < 1. && coord.y < 1.);
    408             }
    409 
    410             vec4 blur()
    411             {
    412                 vec4 total = sampleColor(0.) * u_gaussianKernel[0];
    413                 for (int i = 1; i < GAUSSIAN_KERNEL_HALF_WIDTH; i++) {
    414                     total += sampleColor(float(i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
    415                     total += sampleColor(float(-1 * i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
    416                 }
    417 
    418                 return total;
    419             }
    420 
    421             void main(void)
    422             {
    423                 gl_FragColor = blur();
    424             }
    425         );
    426 
    427     static const char* fragmentShadowFilter1 =
    428         BLUR_CONSTANTS
    429         STRINGIFY(
    430             precision mediump float;
    431             varying vec2 v_texCoord;
    432             uniform float u_blurRadius;
    433             uniform vec2 u_shadowOffset;
    434             uniform sampler2D s_sampler;
    435             uniform float u_gaussianKernel[GAUSSIAN_KERNEL_HALF_WIDTH];
    436 
    437             float sampleAlpha(float radius)
    438             {
    439                 vec2 coord = v_texCoord - u_shadowOffset + vec2(radius * u_blurRadius, 0.);
    440                 return texture2D(s_sampler, coord).a * float(coord.x > 0. && coord.y > 0. && coord.x < 1. && coord.y < 1.);
    441             }
    442 
    443             float shadowBlurHorizontal()
    444             {
    445                 float total = sampleAlpha(0.) * u_gaussianKernel[0];
    446                 for (int i = 1; i < GAUSSIAN_KERNEL_HALF_WIDTH; i++) {
    447                     total += sampleAlpha(float(i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
    448                     total += sampleAlpha(float(-1 * i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
    449                 }
    450 
    451                 return total;
    452             }
    453 
    454             void main(void)
    455             {
    456                 gl_FragColor = vec4(1., 1., 1., 1.) * shadowBlurHorizontal();
    457             }
    458         );
    459 
    460     // Second pass: vertical alpha blur and composite with origin.
    461     static const char* fragmentShadowFilter2 =
    462         BLUR_CONSTANTS
    463         STRINGIFY(
    464             precision mediump float;
    465             varying vec2 v_texCoord;
    466             uniform float u_blurRadius;
    467             uniform vec4 u_shadowColor;
    468             uniform sampler2D s_sampler;
    469             uniform sampler2D s_contentTexture;
    470             uniform float u_gaussianKernel[GAUSSIAN_KERNEL_HALF_WIDTH];
    471 
    472             float sampleAlpha(float r)
    473             {
    474                 vec2 coord = v_texCoord + vec2(0., r * u_blurRadius);
    475                 return texture2D(s_sampler, coord).a * float(coord.x > 0. && coord.y > 0. && coord.x < 1. && coord.y < 1.);
    476             }
    477 
    478             float shadowBlurVertical()
    479             {
    480                 float total = sampleAlpha(0.) * u_gaussianKernel[0];
    481                 for (int i = 1; i < GAUSSIAN_KERNEL_HALF_WIDTH; i++) {
    482                     total += sampleAlpha(float(i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
    483                     total += sampleAlpha(float(-1 * i) * GAUSSIAN_KERNEL_STEP) * u_gaussianKernel[i];
    484                 }
    485 
    486                 return total;
    487             }
    488 
    489             vec4 sourceOver(lowp vec4 source, vec4 destination)
    490             {
    491                 // Composite the shadow with the original texture.
    492                 return source + destination * (1. - source.a);
    493             }
    494 
    495             void main(void)
    496             {
    497                 gl_FragColor = sourceOver(texture2D(s_contentTexture, v_texCoord), shadowBlurVertical() * u_shadowColor);
    498             }
    499         );
    500 
    501     if (specs.isEmpty()) {
    502         specs.resize(TextureMapperShaderManager::LastFilter);
    503         specs[TextureMapperShaderManager::Default] = ShaderSpec(vertexSimple, fragmentSimple);
    504         specs[TextureMapperShaderManager::SolidColor] = ShaderSpec(vertexSolidColor, fragmentSolidColor);
    505         specs[TextureMapperShaderManager::Rect] = ShaderSpec(vertexSimple, fragmentRectSimple);
    506         specs[TextureMapperShaderManager::Masked] = ShaderSpec(vertexOpacityAndMask, fragmentOpacityAndMask);
    507         specs[TextureMapperShaderManager::MaskedRect] = ShaderSpec(vertexOpacityAndMask, fragmentRectOpacityAndMask);
    508         specs[TextureMapperShaderManager::Antialiased] = ShaderSpec(vertexSimple, fragmentAntialiasingNoMask);
    509         specs[TextureMapperShaderManager::GrayscaleFilter] = ShaderSpec(vertexFilter, fragmentGrayscaleFilter);
    510         specs[TextureMapperShaderManager::SepiaFilter] = ShaderSpec(vertexFilter, fragmentSepiaFilter);
    511         specs[TextureMapperShaderManager::SaturateFilter] = ShaderSpec(vertexFilter, fragmentSaturateFilter);
    512         specs[TextureMapperShaderManager::HueRotateFilter] = ShaderSpec(vertexFilter, fragmentHueRotateFilter);
    513         specs[TextureMapperShaderManager::BrightnessFilter] = ShaderSpec(vertexFilter, fragmentBrightnessFilter);
    514         specs[TextureMapperShaderManager::ContrastFilter] = ShaderSpec(vertexFilter, fragmentContrastFilter);
    515         specs[TextureMapperShaderManager::InvertFilter] = ShaderSpec(vertexFilter, fragmentInvertFilter);
    516         specs[TextureMapperShaderManager::OpacityFilter] = ShaderSpec(vertexFilter, fragmentOpacityFilter);
    517         specs[TextureMapperShaderManager::BlurFilter] = ShaderSpec(vertexFilter, fragmentBlurFilter);
    518         specs[TextureMapperShaderManager::ShadowFilterPass1] = ShaderSpec(vertexFilter, fragmentShadowFilter1);
    519         specs[TextureMapperShaderManager::ShadowFilterPass2] = ShaderSpec(vertexFilter, fragmentShadowFilter2);
    520     }
    521 
    522     ASSERT(specs.size() > key);
    523     ShaderSpec& spec = specs[key];
    524     vertexSource = spec.vertexShader;
    525     fragmentSource = spec.fragmentShader;
    526 }
    527 
    528 TextureMapperShaderManager::TextureMapperShaderManager(GraphicsContext3D* context)
    529     : m_context(context)
    530 {
    531 }
    532 
    533 TextureMapperShaderManager::~TextureMapperShaderManager()
    534 {
    535 }
    536 
    537 PassRefPtr<TextureMapperShaderProgram> TextureMapperShaderManager::getShaderProgram(ShaderKey key)
    538 {
    539     TextureMapperShaderProgramMap::iterator it = m_programs.find(key);
    540     if (it != m_programs.end())
    541         return it->value;
    542 
    543     String vertexShader;
    544     String fragmentShader;
    545     getShaderSpec(key, vertexShader, fragmentShader);
    546     RefPtr<TextureMapperShaderProgram> program = TextureMapperShaderProgram::create(m_context, vertexShader, fragmentShader);
    547     m_programs.add(key, program);
    548     return program;
    549 }
    550 };
    551 
    552417#endif
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h

    r138168 r138489  
    6060
    6161#if ENABLE(CSS_FILTERS)
    62     TEXMAP_DECLARE_UNIFORM(amount)
     62    TEXMAP_DECLARE_UNIFORM(filterAmount)
    6363    TEXMAP_DECLARE_UNIFORM(gaussianKernel)
    6464    TEXMAP_DECLARE_UNIFORM(blurRadius)
    65     TEXMAP_DECLARE_UNIFORM(shadowColor)
    6665    TEXMAP_DECLARE_UNIFORM(shadowOffset)
    6766    TEXMAP_DECLARE_SAMPLER(contentTexture)
     
    8382class TextureMapperShaderManager {
    8483public:
    85     enum ShaderKey {
    86         Invalid = 0,
    87         Default,
    88         Rect,
    89         Masked,
    90         MaskedRect,
    91         SolidColor,
    92         Antialiased,
    93         GrayscaleFilter,
    94         SepiaFilter,
    95         SaturateFilter,
    96         HueRotateFilter,
    97         BrightnessFilter,
    98         ContrastFilter,
    99         OpacityFilter,
    100         InvertFilter,
    101         BlurFilter,
    102         ShadowFilterPass1,
    103         ShadowFilterPass2,
    104         LastFilter
     84    enum Option {
     85        Texture          = 1L << 0,
     86        Rect             = 1L << 1,
     87        SolidColor       = 1L << 2,
     88        Opacity          = 1L << 3,
     89        Mask             = 1L << 4,
     90        Antialias        = 1L << 5,
     91        GrayscaleFilter  = 1L << 6,
     92        SepiaFilter      = 1L << 7,
     93        SaturateFilter   = 1L << 8,
     94        HueRotateFilter  = 1L << 9,
     95        BrightnessFilter = 1L << 10,
     96        ContrastFilter   = 1L << 11,
     97        InvertFilter     = 1L << 12,
     98        OpacityFilter    = 1L << 13,
     99        BlurFilter       = 1L << 14,
     100        AlphaBlur        = 1L << 15,
     101        ContentTexture   = 1L << 16
    105102    };
     103
     104    typedef unsigned Options;
    106105
    107106    TextureMapperShaderManager() { }
     
    109108    virtual ~TextureMapperShaderManager();
    110109
    111     PassRefPtr<TextureMapperShaderProgram> getShaderProgram(ShaderKey);
     110    PassRefPtr<TextureMapperShaderProgram> getShaderProgram(Options);
    112111
    113112private:
    114     typedef HashMap<ShaderKey, RefPtr<TextureMapperShaderProgram>, DefaultHash<int>::Hash, HashTraits<int> > TextureMapperShaderProgramMap;
     113    typedef HashMap<Options, RefPtr<TextureMapperShaderProgram> > TextureMapperShaderProgramMap;
    115114    TextureMapperShaderProgramMap m_programs;
    116115    RefPtr<GraphicsContext3D> m_context;
Note: See TracChangeset for help on using the changeset viewer.