Changeset 132268 in webkit


Ignore:
Timestamp:
Oct 23, 2012 2:34:56 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

[CSS Shaders] Implement overlay, color-dodge, color-burn, hard-light, soft-light blend modes.
https://bugs.webkit.org/show_bug.cgi?id=98504

Patch by Huang Dongsung <luxtella@company100.net> on 2012-10-23
Reviewed by Dean Jackson.

Source/WebCore:

Add expressions for the aforementioned blend modes. The expressions are lifted
directly from the CSS Compositing and Blending spec [1]. WebKit adds these
blending expressions to the author's shader.

[1]: https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingnormal

Test: css3/filters/custom/custom-filter-blend-modes.html

  • platform/graphics/filters/CustomFilterValidatedProgram.cpp:

(WebCore::CustomFilterValidatedProgram::rewriteMixFragmentShader):
(WebCore::CustomFilterValidatedProgram::blendFunctionString):

LayoutTests:

Update the test for the aforementioned blend modes.

  • css3/filters/custom/custom-filter-blend-modes-expected.html:
  • css3/filters/custom/custom-filter-blend-modes.html:
Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r132267 r132268  
     12012-10-23  Huang Dongsung  <luxtella@company100.net>
     2
     3        [CSS Shaders] Implement overlay, color-dodge, color-burn, hard-light, soft-light blend modes.
     4        https://bugs.webkit.org/show_bug.cgi?id=98504
     5
     6        Reviewed by Dean Jackson.
     7
     8        Update the test for the aforementioned blend modes.
     9
     10        * css3/filters/custom/custom-filter-blend-modes-expected.html:
     11        * css3/filters/custom/custom-filter-blend-modes.html:
     12
    1132012-10-23  Huang Dongsung  <luxtella@company100.net>
    214
  • trunk/LayoutTests/css3/filters/custom/custom-filter-blend-modes-expected.html

    r127517 r132268  
    4141        background-color: rgb(255, 138, 127);
    4242    }
     43    .overlay-expected {
     44        background-color: rgb(255, 91, 128);
     45    }
     46    .color-dodge-expected {
     47        background-color: rgb(255, 190, 255);
     48    }
     49    .color-burn-expected {
     50        background-color: rgb(255, 31, 96);
     51    }
     52    .hard-light-expected {
     53        background-color: rgb(0%, 44%, 50%);
     54    }
     55    .soft-light-expected {
     56        background-color: rgb(255, 89, 128);
     57    }
    4358    </style>
    4459</head>
     
    7287        <div class="exclusion-expected"></div>
    7388    </div>
     89    <div class="pair-of-squares">
     90        <div class="overlay-expected"></div>
     91        <div class="overlay-expected"></div>
     92    </div>
     93    <div class="pair-of-squares">
     94        <div class="color-dodge-expected"></div>
     95        <div class="color-dodge-expected"></div>
     96    </div>
     97    <div class="pair-of-squares">
     98        <div class="color-burn-expected"></div>
     99        <div class="color-burn-expected"></div>
     100    </div>
     101    <div class="pair-of-squares">
     102        <div class="hard-light-expected"></div>
     103        <div class="hard-light-expected"></div>
     104    </div>
     105    <div class="pair-of-squares">
     106        <div class="soft-light-expected"></div>
     107        <div class="soft-light-expected"></div>
     108    </div>
    74109    <!--
    75110        If you add more blend modes to this page, be careful not to exceed 600px in
  • trunk/LayoutTests/css3/filters/custom/custom-filter-blend-modes.html

    r127517 r132268  
    148148        background-color: rgb(255, 138, 127);
    149149    }
     150    .overlay {
     151        -webkit-filter: custom(none mix(url('../resources/mix-color.fs') overlay source-atop), mix_color 0.0 0.6 0.5 1.0);
     152    }
     153    .overlay-expected {
     154        /*
     155            Overlay:
     156
     157            Co = HardLight(Cs, Cb)
     158               = if(Cb <= 0.5)
     159                     Multiply(Cs, 2 * Cb)
     160                 else
     161                     Screen(Cs, 2 * Cb - 1)
     162               = if(Cb <= 0.5)
     163                     Cs * (2 * Cb)
     164                 else
     165                     Cs + (2 * Cb - 1) - (Cs * (2 * Cb - 1))
     166
     167            r = 0 + (2 * 1 - 1) - (0 * (2 * 1 - 1)) = 1
     168            g = 0.6 * (2 * 0.3) = 0.36
     169            b = 0.5 * (2 * 0.5) = 0.5
     170
     171            The error in the color calculation requires us to use the 8-bit values for:
     172            background-color: rgb(100%, 36%, 50%);
     173        */
     174        background-color: rgb(255, 91, 128);
     175    }
     176    .color-dodge {
     177        -webkit-filter: custom(none mix(url('../resources/mix-color.fs') color-dodge source-atop), mix_color 0.0 0.6 0.5 1.0);
     178    }
     179    .color-dodge-expected {
     180        /*
     181            ColorDodge:
     182
     183            Co = if(Cs < 1)
     184                     min(1, Cb / (1 - Cs))
     185                 else
     186                     1
     187
     188            r = min(1, 1 / (1 - 0)) = 1
     189            g = min(1, 0.3 / (1 - 0.6)) = 0.75
     190            b = min(1, 0.5 / (1 - 0.5)) = 1
     191
     192            The error in the color calculation requires us to use the 8-bit values for:
     193            background-color: rgb(100%, 75%, 100%);
     194        */
     195        background-color: rgb(255, 190, 255);
     196    }
     197    .color-burn {
     198        -webkit-filter: custom(none mix(url('../resources/mix-color.fs') color-burn source-atop), mix_color 0.8 0.8 0.8 1.0);
     199    }
     200    .color-burn-expected {
     201        /*
     202            ColorBurn:
     203
     204            Co = if(Cs > 0)
     205                     1 - min(1, (1 - Cb) / Cs)
     206                 else
     207                     0
     208
     209             r = 1 - min(1, (1 - 1) / 0.8) = 1
     210             g = 1 - min(1, (1 - 0.3) / 0.8) = 0.125
     211             b = 1 - min(1, (1 - 0.5) / 0.8) = 0.375
     212
     213            The error in the color calculation requires us to use the 8-bit values for:
     214            background-color: rgb(100%, 12.5%, 37.5%);
     215        */
     216        background-color: rgb(255, 31, 96);
     217    }
     218    .hard-light {
     219        -webkit-filter: custom(none mix(url('../resources/mix-color.fs') hard-light source-atop), mix_color 0.0 0.6 0.5 1.0);
     220    }
     221    .hard-light-expected {
     222        /*
     223            HardLight:
     224
     225            Co = if(Cs <= 0.5)
     226                     Multiply(Cb, 2 * Cs)
     227                 else
     228                     Screen(Cb, 2 * Cs -1)
     229               = if(Cs <= 0.5)
     230                     Cb * (2 * Cs)
     231                 else
     232                     Cb + (2 * Cs - 1) - (Cb * (2 * Cs - 1))
     233
     234            r = 1 * (2 * 0) = 0
     235            g = 0.3 + (2 * 0.6 - 1) - (0.3 * (2 * 0.6 - 1)) = 0.44
     236            b = 0.5 * (2 * 0.5) = 0.5
     237        */
     238        background-color: rgb(0%, 44%, 50%);
     239    }
     240    .soft-light {
     241        -webkit-filter: custom(none mix(url('../resources/mix-color.fs') soft-light source-atop), mix_color 0.0 0.6 0.5 1.0);
     242    }
     243    .soft-light-expected {
     244        /*
     245            SoftLight:
     246
     247            Co = if(Cs <= 0.5)
     248                     Cb - (1 - 2 * Cs) * Cb * (1 - Cb)
     249                 else
     250                     Cb + (2 * Cs - 1) * (D(Cb) - Cb)
     251
     252            with
     253
     254            D(Cb) = if(Cb <= 0.25)
     255                        (16 * Cb - 12) * Cb + 4) * Cb
     256                    else
     257                        sqrt(Cb)
     258
     259            D.r = sqrt(1) = 1
     260            D.g = sqrt(0.3) = 0.547722557505166
     261            D.b = sqrt(0.5) = 0.707106781186548
     262            r = 1 - (1 - 2 * 0) * 1 * (1 - 1) = 1
     263            g = 0.3 + (2 * 0.6 - 1) * (D.g - 0.3) = 0.349544511501033
     264            b = 0.5 - (1 - 2 * 0.5) * 0.5 * (1 - 0.5) = 0.5
     265
     266            The error in the color calculation requires us to use the 8-bit values for:
     267            background-color: rgb(100%, 34.954451%, 50%);
     268        */
     269        background-color: rgb(255, 89, 128);
     270    }
    150271    </style>
    151272</head>
     
    178299        <div class="destination exclusion"></div>
    179300        <div class="exclusion-expected"></div>
     301    </div>
     302    <div class="pair-of-squares">
     303        <div class="destination overlay"></div>
     304        <div class="overlay-expected"></div>
     305    </div>
     306    <div class="pair-of-squares">
     307        <div class="destination color-dodge"></div>
     308        <div class="color-dodge-expected"></div>
     309    </div>
     310    <div class="pair-of-squares">
     311        <div class="destination color-burn"></div>
     312        <div class="color-burn-expected"></div>
     313    </div>
     314    <div class="pair-of-squares">
     315        <div class="destination hard-light"></div>
     316        <div class="hard-light-expected"></div>
     317    </div>
     318    <div class="pair-of-squares">
     319        <div class="destination soft-light"></div>
     320        <div class="soft-light-expected"></div>
    180321    </div>
    181322    <!--
  • trunk/Source/WebCore/ChangeLog

    r132267 r132268  
     12012-10-23  Huang Dongsung  <luxtella@company100.net>
     2
     3        [CSS Shaders] Implement overlay, color-dodge, color-burn, hard-light, soft-light blend modes.
     4        https://bugs.webkit.org/show_bug.cgi?id=98504
     5
     6        Reviewed by Dean Jackson.
     7
     8        Add expressions for the aforementioned blend modes. The expressions are lifted
     9        directly from the CSS Compositing and Blending spec [1]. WebKit adds these
     10        blending expressions to the author's shader.
     11
     12        [1]: https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingnormal
     13
     14        Test: css3/filters/custom/custom-filter-blend-modes.html
     15
     16        * platform/graphics/filters/CustomFilterValidatedProgram.cpp:
     17        (WebCore::CustomFilterValidatedProgram::rewriteMixFragmentShader):
     18        (WebCore::CustomFilterValidatedProgram::blendFunctionString):
     19
    1202012-10-23  Huang Dongsung  <luxtella@company100.net>
    221
  • trunk/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp

    r132267 r132268  
    232232            mediump vec4 originalColor = texture2D(css_u_texture, css_v_texCoord);
    233233            mediump vec4 multipliedColor = css_ColorMatrix * originalColor;
    234             mediump vec3 blendedColor = css_Blend(multipliedColor.rgb, css_MixColor.rgb);
     234            mediump vec3 blendedColor = css_BlendColor(multipliedColor.rgb, css_MixColor.rgb);
    235235            gl_FragColor = css_Composite(multipliedColor.rgb, multipliedColor.a, blendedColor.rgb, css_MixColor.a);
    236236        }
     
    243243    // Implemented using the same symbol names as the Compositing and Blending spec:
    244244    // https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingnormal
    245     // Cs: is the source color
    246     // Cb: is the backdrop color
    247     const char* expression = 0;
     245    // Cs: is the source color in css_BlendColor() and the source color component in css_BlendComponent()
     246    // Cb: is the backdrop color in css_BlendColor() and the backdrop color component in css_BlendComponent()
     247    const char* blendColorExpression = "vec3(css_BlendComponent(Cb.r, Cs.r), css_BlendComponent(Cb.g, Cs.g), css_BlendComponent(Cb.b, Cs.b))";
     248    const char* blendComponentExpression = "Co = 0.0;";
    248249    switch (blendMode) {
    249250    case BlendModeNormal:
    250         expression = "Cs";
     251        blendColorExpression = "Cs";
    251252        break;
    252253    case BlendModeMultiply:
    253         expression = "Cs * Cb";
     254        blendColorExpression = "Cs * Cb";
    254255        break;
    255256    case BlendModeScreen:
    256         expression = "Cb + Cs - (Cb * Cs)";
     257        blendColorExpression = "Cb + Cs - (Cb * Cs)";
    257258        break;
    258259    case BlendModeDarken:
    259         expression = "min(Cb, Cs)";
     260        blendColorExpression = "min(Cb, Cs)";
    260261        break;
    261262    case BlendModeLighten:
    262         expression = "max(Cb, Cs)";
     263        blendColorExpression = "max(Cb, Cs)";
    263264        break;
    264265    case BlendModeDifference:
    265         expression = "abs(Cb - Cs)";
     266        blendColorExpression = "abs(Cb - Cs)";
    266267        break;
    267268    case BlendModeExclusion:
    268         expression = "Cb + Cs - 2.0 * Cb * Cs";
     269        blendColorExpression = "Cb + Cs - 2.0 * Cb * Cs";
    269270        break;
    270271    case BlendModeOverlay:
     272        /*
     273            Co = HardLight(Cs, Cb)
     274               = if(Cb <= 0.5)
     275                     Multiply(Cs, 2 x Cb)
     276                 else
     277                     Screen(Cs, 2 x Cb - 1)
     278               = if(Cb <= 0.5)
     279                     Cs x (2 x Cb)
     280                 else
     281                     Cs + (2 x Cb - 1) - (Cs x (2 x Cb - 1))
     282        */
     283        blendComponentExpression = SHADER(
     284            if (Cb <= 0.5)
     285                Co = Cs * (2.0 * Cb);
     286            else
     287                Co = Cs + (2.0 * Cb - 1.0) - (Cs * (2.0 * Cb - 1.0));
     288        );
     289        break;
    271290    case BlendModeColorDodge:
     291        /*
     292            Co = if(Cs < 1)
     293                     min(1, Cb / (1 - Cs))
     294                 else
     295                     1
     296        */
     297        blendComponentExpression = SHADER(
     298            if (Cs < 1.0)
     299                Co = min(1.0, Cb / (1.0 - Cs));
     300            else
     301                Co = 1.0;
     302        );
     303        break;
    272304    case BlendModeColorBurn:
     305        /*
     306            Co = if(Cs > 0)
     307                     1 - min(1, (1 - Cb) / Cs)
     308                 else
     309                     0
     310        */
     311        blendComponentExpression = SHADER(
     312            if (Cs > 0.0)
     313                Co = 1.0 - min(1.0, (1.0 - Cb) / Cs);
     314            else
     315                Co = 0.0;
     316        );
     317        break;
    273318    case BlendModeHardLight:
     319        /*
     320            Co = if(Cs <= 0.5)
     321                     Multiply(Cb, 2 x Cs)
     322                 else
     323                     Screen(Cb, 2 x Cs -1)
     324               = if(Cs <= 0.5)
     325                     Cb x (2 x Cs)
     326                 else
     327                     Cb + (2 x Cs - 1) - (Cb x (2 x Cs - 1))
     328        */
     329        blendComponentExpression = SHADER(
     330            if (Cs <= 0.5)
     331                Co = Cb * (2.0 * Cs);
     332            else
     333                Co = Cb + (2.0 * Cs - 1.0) - (Cb * (2.0 * Cs - 1.0));
     334        );
     335        break;
    274336    case BlendModeSoftLight:
     337        /*
     338            Co = if(Cs <= 0.5)
     339                     Cb - (1 - 2 x Cs) x Cb x (1 - Cb)
     340                 else
     341                     Cb + (2 x Cs - 1) x (D(Cb) - Cb)
     342
     343            with
     344
     345            D(Cb) = if(Cb <= 0.25)
     346                        (16 * Cb - 12) x Cb + 4) x Cb
     347                    else
     348                        sqrt(Cb)
     349        */
     350        blendComponentExpression = SHADER(
     351            mediump float D;
     352            if (Cb <= 0.25)
     353                D = ((16.0 * Cb - 12.0) * Cb + 4.0) * Cb;
     354            else
     355                D = sqrt(Cb);
     356
     357            if (Cs <= 0.5)
     358                Co = Cb - (1.0 - 2.0 * Cs) * Cb * (1.0 - Cb);
     359            else
     360                Co = Cb + (2.0 * Cs - 1.0) * (D - Cb);
     361        );
     362        break;
    275363    case BlendModeHue:
    276364    case BlendModeSaturation:
     
    281369    }
    282370
    283     ASSERT(expression);
    284371    return String::format(SHADER(
    285         mediump vec3 css_Blend(mediump vec3 Cb, mediump vec3 Cs)
     372        mediump float css_BlendComponent(mediump float Cb, mediump float Cs)
     373        {
     374            mediump float Co;
     375            %s
     376            return Co;
     377        }
     378        mediump vec3 css_BlendColor(mediump vec3 Cb, mediump vec3 Cs)
    286379        {
    287380            return %s;
    288381        }
    289     ), expression);
     382    ), blendComponentExpression, blendColorExpression);
    290383}
    291384
Note: See TracChangeset for help on using the changeset viewer.