Title: [145114] trunk
Revision
145114
Author
michelang...@webkit.org
Date
2013-03-07 12:00:48 -0800 (Thu, 07 Mar 2013)

Log Message

[CSS Shaders] Implement hue and saturation non-separable blend modes
https://bugs.webkit.org/show_bug.cgi?id=109464

Source/WebCore:

Added the following GLSL helper functions to the CustomFilterValidatedProgram:

    - css_Sat(C): returns the saturation for the color C
    - css_SetSat(C, s): sets the saturation s on the color C
    - css_SetSatHelper(Cmin, Cmid, Cmax, s): helper function for css_SetSat

The above functions are being used for the "hue" and "saturation" non-separable
blend modes, the relevant spec for such modes is at URL:
https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingnonseparable

Reviewed by Dean Jackson.

Tests: css3/filters/custom/custom-filter-nonseparable-blend-mode-hue.html
       css3/filters/custom/custom-filter-nonseparable-blend-mode-saturation.html

* platform/graphics/filters/CustomFilterValidatedProgram.cpp:
(WebCore::CustomFilterValidatedProgram::blendFunctionString):

LayoutTests:

Added relevant tests for the "hue" and "saturation" non-separable blend modes.
These tests are currently skipped on Mac due to a slight color difference; please see relevant bug: http://webkit.org/b/107487.

Reviewed by Dean Jackson.

* css3/filters/custom/custom-filter-nonseparable-blend-mode-hue-expected.html: Added.
* css3/filters/custom/custom-filter-nonseparable-blend-mode-hue.html: Added.
* css3/filters/custom/custom-filter-nonseparable-blend-mode-saturation-expected.html: Added.
* css3/filters/custom/custom-filter-nonseparable-blend-mode-saturation.html: Added.
* platform/mac/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (145113 => 145114)


--- trunk/LayoutTests/ChangeLog	2013-03-07 19:53:34 UTC (rev 145113)
+++ trunk/LayoutTests/ChangeLog	2013-03-07 20:00:48 UTC (rev 145114)
@@ -1,3 +1,19 @@
+2013-03-07  Michelangelo De Simone  <michelang...@webkit.org>
+
+        [CSS Shaders] Implement hue and saturation non-separable blend modes
+        https://bugs.webkit.org/show_bug.cgi?id=109464
+
+        Added relevant tests for the "hue" and "saturation" non-separable blend modes.
+        These tests are currently skipped on Mac due to a slight color difference; please see relevant bug: http://webkit.org/b/107487.
+
+        Reviewed by Dean Jackson.
+
+        * css3/filters/custom/custom-filter-nonseparable-blend-mode-hue-expected.html: Added.
+        * css3/filters/custom/custom-filter-nonseparable-blend-mode-hue.html: Added.
+        * css3/filters/custom/custom-filter-nonseparable-blend-mode-saturation-expected.html: Added.
+        * css3/filters/custom/custom-filter-nonseparable-blend-mode-saturation.html: Added.
+        * platform/mac/TestExpectations:
+
 2013-03-07  Rafael Weinstein  <rafa...@chromium.org>
 
         Unreviewed gardening.

Added: trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-hue-expected.html (0 => 145114)


--- trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-hue-expected.html	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-hue-expected.html	2013-03-07 20:00:48 UTC (rev 145114)
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+    <title>Test that blends the source and the backdrop with the hue blend mode.</title>
+    <style type="text/css">
+        /* These are exactly the color values we expect. Some platforms may have slight different
+           color result. */
+        #solid-solid {
+            background-color: rgb(108, 157, 255);
+            width: 100px;
+            height: 100px;
+        }
+        #alpha-solid {
+            background-color: rgb(167, 192, 242);
+            width: 100px;
+            height: 100px;
+        }
+        #solid-alpha {
+            background-color: rgb(169, 142, 166);
+            width: 100px;
+            height: 100px;
+        }
+        #alpha-alpha {
+            background-color: rgb(205, 192, 204);
+            width: 100px;
+            height: 100px;
+        }
+    </style>
+</head>
+<body>
+    <div id="solid-solid"></div>
+    <div id="alpha-solid"></div>
+    <div id="solid-alpha"></div>
+    <div id="alpha-alpha"></div>
+</body>
+</html>

Added: trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-hue.html (0 => 145114)


--- trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-hue.html	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-hue.html	2013-03-07 20:00:48 UTC (rev 145114)
@@ -0,0 +1,151 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+    <title>Test that blends the source and the backdrop with the hue blend mode.</title>
+    <script>
+        if (window.testRunner) {
+            window.testRunner.overridePreference("WebKitCSSCustomFilterEnabled", "1");
+            window.testRunner.overridePreference("WebKitWebGLEnabled", "1");
+        }
+    </script>
+    <style type="text/css">
+        #solid-solid {
+            background-color: rgb(90%, 50%, 30%);
+            width: 100px;
+            height: 100px;
+            -webkit-filter: custom(none mix(url('../resources/mix-color.fs') hue source-atop), mix_color 0.2 0.4 0.8 1.0);
+        }
+        #alpha-solid {
+            background-color: rgba(90%, 50%, 30%, 0.5);
+            width: 100px;
+            height: 100px;
+            -webkit-filter: custom(none mix(url('../resources/mix-color.fs') hue source-atop), mix_color 0.2 0.4 0.8 1.0);
+        }
+        #solid-alpha {
+            background-color: rgb(90%, 50%, 30%);
+            width: 100px;
+            height: 100px;
+            -webkit-filter: custom(none mix(url('../resources/mix-color.fs') hue source-atop), mix_color 0.2 0.4 0.8 0.5);
+        }
+        #alpha-alpha {
+            background-color: rgba(90%, 50%, 30%, 0.5);
+            width: 100px;
+            height: 100px;
+            -webkit-filter: custom(none mix(url('../resources/mix-color.fs') hue source-atop), mix_color 0.2 0.4 0.8 0.5);
+        }
+    </style>
+</head>
+<body>
+<!--
+    The following proof applies to the first case (#solid-solid) where both the backdrop and the
+    source are solid.
+
+    In this test the following combinations are also tested:
+        Backdrop with 0.5 alpha blended with solid source
+        Solid backdrop blended with source with 0.5 alpha
+        Backdrop with 0.5 alpha blended with source with 0.5 alpha
+    The underlying proof of the above mentioned cases is the same: the colors are premultiplied
+    and then blended together.
+
+    The final color of #solid-solid depends on the "hue" blend mode, which is a non-separable
+    blend mode. This means that colors are blended together as a whole, not component by component.
+
+    The formula for this blend mode is:
+        Cr = B(Cb, Cs) = SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb))
+
+    With:
+        Cr: the resulting color
+        Cb: the backdrop color, which is #solid-solid ("original DOM element color")
+        Cs: the source color, which is mix_color
+        Lum(Cb): the luminosity of Cb. Luminosity for color C is generally defined by
+           Lum(C): 0.3 * Cred + 0.59 * Cgreen + 0.11 * Cblue
+        Sat(Cb): the saturation of Cb. Saturation for color C is generally defined by
+           Sat(C): max(Cred, Cgreen, Cblue) - min(Cred, Cgreen, Cblue)
+       SetSat(Cs, Sat(Cb)): the function that sets the saturation
+       SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb)): the function that sets the luminosity.
+
+    The function that sets the luminosity l on the color C is generally defined by:
+
+        SetLum(C, l)
+            d = l - Lum(C)
+            Cred = Cred + d
+            Cgreen = Cgreen + d
+            Cblue = Cblue + d
+            return ClipColor(C)
+
+    At this point the color C has to be clipped between [0..1]  by the ClipColor function, which is
+    generally defined by:
+
+        ClipColor(C)
+            l = Lum(C)
+            n = min(Cred, Cgreen, Cblue)
+            x = max(Cred, Cgreen, Cblue)
+            if n < 0.0
+                Cred = l + (((Cred - l) * l) / (l - n))
+                Cgreen = l + (((Cgreen - l) * l) / (l - n))
+                Cblue = l + (((Cblue - l) * l) / (l - n))
+            if x > 1.0
+                Cred = l + (((Cred - l) * (1 - l)) / (x - l))
+                Cgreen = l + (((Cgreen - l) * (1 - l)) / (x - l))
+                Cblue = l + (((Cblue - l) * (1 - l)) / (x - l))
+            return C
+
+    The function that sets the saturation s on the color C is generally defined by:
+
+        SetSat(C, s)
+            if(Cmax > Cmin)
+                Cmid = (((Cmid - Cmin) * s) / (Cmax - Cmin))
+                Cmax = s
+            else
+                Cmid = Cmax = 0
+            Cmin = 0
+            return C
+
+    In this test case:
+        Lum(Cb) = 0.3 * 0.9 + 0.59 * 0.5 + 0.11 * 0.3
+        Lum(Cb) = 0.27 + 0.295 + 0.033
+        Lum(Cb) = 0.598
+
+        Sat(Cb) = max(0.9, 0.5, 0.3) - min(0.9, 0.5, 0.3)
+        Sat(Cb) = 0.9 - 0.3
+        Sat(Cb) = 0.6
+
+        For the sake of brevity the result of this computation is called Ct
+        Ct = SetSat(Cs, Sat(Cb))
+            0.8 > 0.2
+                Cmid = (((0.4 - 0.2) * 0.6) / (0.8 - 0.2)) = (0.2 * 0.6) / 0.6 = 0.2
+                Cmax = 0.6
+            Cmin = 0
+            return (0, 0.2, 0.6)
+
+        Cr = SetLum(Ct, Lum(Cb))
+            d = 0.598 - (0.3 * 0.0 + 0.59 * 0.2 + 0.11 * 0.6) = 0.118 + 0.066 = 0.184
+            d = 0.598 - (0.118 + 0.066) = 0.598 - 0.184
+            d = 0.414
+            Cred = 0.0 + 0.414 = 0.414
+            Green = 0.2 + 0.414 = 0.614
+            Cblue = 0.6 + 0.414 = 1.014
+            return ClipColor(0.414, 0.614, 1.014)
+
+        ClipColor(0.414, 0.614, 1.014)
+            l = 0.3 * 0.414 + 0.59 * 0.614 + 0.11 * 1.1014 = 0.1242 + 0.36226 + 0.121154 = 0.607614
+            n = min(0.414, 0.614, 1.014) = 0.414
+            x = max(0.414, 0.614, 1.014) = 1.014
+            x > 1.0
+                Cred = 0.607614 + (((0.414 - 0.607614) * (1 - 0.607614)) / (1.014 - 0.607614)) = 
+                     = 0.607614 + ((-0.193614 * 0.392386) / 0.406386) = 0.607614 - (0.07597142 / 0.406386) = 0.607614 - 0.18694399 = 0.42067001
+                Cgreen = 0.607614 + (((0.614 - 0.607614) * (1 - 0.607614)) / (1.014 - 0.607614)) =
+                       = 0.607614 + ((0.003386 * 0.392386) / 0.406386 = 0.607614 + (0.00132862 / 0.406386) = 0.607614 + 0.00326935 = 0.61088335
+                Cblue = 0.607614 + (((1.014 - 0.607614) * (1 - 0.607614)) / (1.014 - 0.607614) =
+                      = 0.607614 + ((0.406386 * 0.392386) / 0.406386) = 0.607614 + (0.15946018 / 0.406386) = 0.607614 + 0.39238601 = 1.0
+            return (0.42, 0.61, 1.0)
+
+    This value is equivalent to (108, 157, 255), which is the expected color.
+    This is the exact color value, other ports might experience slight differences.
+-->
+    <div id="solid-solid"></div>
+    <div id="alpha-solid"></div>
+    <div id="solid-alpha"></div>
+    <div id="alpha-alpha"></div>
+</body>
+</html>

Added: trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-saturation-expected.html (0 => 145114)


--- trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-saturation-expected.html	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-saturation-expected.html	2013-03-07 20:00:48 UTC (rev 145114)
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+    <title>Test that blends the source and the backdrop with the saturation blend mode.</title>
+    <style type="text/css">
+        /* These are exactly the color values we expect. Some platforms may have slight different
+           color result. */
+        #solid-solid {
+            background-color: rgb(191, 141, 115);
+            width: 100px;
+            height: 100px;
+        }
+        #alpha-solid {
+            background-color: rgb(198, 185, 198);
+            width: 100px;
+            height: 100px;
+        }
+        #solid-alpha {
+            background-color: rgb(230, 128, 76);
+            width: 100px;
+            height: 100px;
+        }
+        #alpha-alpha {
+            background-color: rgb(220, 189, 182);
+            width: 100px;
+            height: 100px;
+        }
+    </style>
+</head>
+<body>
+    <div id="solid-solid"></div>
+    <div id="alpha-solid"></div>
+    <div id="solid-alpha"></div>
+    <div id="alpha-alpha"></div>
+</body>
+</html>

Added: trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-saturation.html (0 => 145114)


--- trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-saturation.html	                        (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-saturation.html	2013-03-07 20:00:48 UTC (rev 145114)
@@ -0,0 +1,137 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+    <title>Test that blends the source and the backdrop with the saturation blend mode.</title>
+    <script>
+        if (window.testRunner) {
+            window.testRunner.overridePreference("WebKitCSSCustomFilterEnabled", "1");
+            window.testRunner.overridePreference("WebKitWebGLEnabled", "1");
+        }
+    </script>
+    <style type="text/css">
+        #solid-solid {
+            background-color: rgb(90%, 50%, 30%);
+            width: 100px;
+            height: 100px;
+            -webkit-filter: custom(none mix(url('../resources/mix-color.fs') saturation source-atop), mix_color 0.1 0.2 0.4 1.0);
+        }
+        #alpha-solid {
+            background-color: rgba(90%, 50%, 30%, 0.5);
+            width: 100px;
+            height: 100px;
+            -webkit-filter: custom(none mix(url('../resources/mix-color.fs') saturation source-atop), mix_color 0.2 0.4 0.8 1.0);
+        }
+        #solid-alpha {
+            background-color: rgb(90%, 50%, 30%);
+            width: 100px;
+            height: 100px;
+            -webkit-filter: custom(none mix(url('../resources/mix-color.fs') saturation source-atop), mix_color 0.2 0.4 0.8 0.5);
+        }
+        #alpha-alpha {
+            background-color: rgba(90%, 50%, 30%, 0.5);
+            width: 100px;
+            height: 100px;
+            -webkit-filter: custom(none mix(url('../resources/mix-color.fs') saturation source-atop), mix_color 0.2 0.4 0.8 0.5);
+        }
+    </style>
+</head>
+<body>
+<!--
+    The following proof applies to the first case (#solid-solid) where both the backdrop and the
+    source are solid.
+
+    In this test the following combinations are also tested:
+        Backdrop with 0.5 alpha blended with solid source
+        Solid backdrop blended with source with 0.5 alpha
+        Backdrop with 0.5 alpha blended with source with 0.5 alpha
+    The underlying proof of the above mentioned cases is the same: the colors are premultiplied
+    and then blended together.
+
+    The final color of #solid-solid depends on the "saturation" blend mode, which is a non-separable
+    blend mode. This means that colors are blended together as a whole, not component by component.
+
+    The formula for this blend mode is:
+        Cr = B(Cb, Cs) = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb))
+
+    With:
+        Cr: the resulting color
+        Cb: the backdrop color, which is #solid-solid ("original DOM element color")
+        Cs: the source color, which is mix_color
+        Sat(Cb): the saturation of Cb. Saturation for color C is generally defined by
+           Sat(C): max(Cred, Cgreen, Cblue) - min(Cred, Cgreen, Cblue)
+        Lum(Cs): the luminosity of Cs. Luminosity for color C is generally defined by
+           Lum(C): 0.3 * Cred + 0.59 * Cgreen + 0.11 * Cblue
+        SetSat(Cb, Sat(Cs)): the function that sets the saturation
+        SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb)): the function that sets the luminosity.
+
+    The function that sets the luminosity l on the color C is generally defined by:
+
+        SetLum(C, l)
+            d = l - Lum(C)
+            Cred = Cred + d
+            Cgreen = Cgreen + d
+            Cblue = Cblue + d
+            return ClipColor(C)
+
+    At this point the color C has to be clipped between [0..1]  by the ClipColor function, which is
+    generally defined by:
+
+        ClipColor(C)
+            l = Lum(C)
+            n = min(Cred, Cgreen, Cblue)
+            x = max(Cred, Cgreen, Cblue)
+            if n < 0.0
+                Cred = l + (((Cred - l) * l) / (l - n))
+                Cgreen = l + (((Cgreen - l) * l) / (l - n))
+                Cblue = l + (((Cblue - l) * l) / (l - n))
+            if x > 1.0
+                Cred = l + (((Cred - l) * (1 - l)) / (x - l))
+                Cgreen = l + (((Cgreen - l) * (1 - l)) / (x - l))
+                Cblue = l + (((Cblue - l) * (1 - l)) / (x - l))
+            return C
+
+    The function that sets the saturation s on the color C is generally defined by:
+
+        SetSat(C, s)
+            if(Cmax > Cmin)
+                Cmid = (((Cmid - Cmin) * s) / (Cmax - Cmin))
+                Cmax = s
+            else
+                Cmid = Cmax = 0
+            Cmin = 0
+            return C
+
+    In this test case:
+        Lum(Cb) = 0.3 * 0.9 + 0.59 * 0.5 + 0.11 * 0.3
+        Lum(Cb) = 0.27 + 0.295 + 0.033
+        Lum(Cb) = 0.598
+
+        Sat(Cs) = max(0.1, 0.2, 0.4) - min(0.1, 0.2, 0.4)
+        Sat(Cs) = 0.4 - 0.1
+        Sat(Cs) = 0.3
+
+        For the sake of brevity the result of this computation is called Ct
+        Ct = SetSat(Cb, Sat(Cs))
+            0.9 > 0.3
+                Cmid = (((0.5 - 0.3) * 0.3) / (0.9 - 0.3) = 0.2 * 0.3 / 0.6 = 0.06 / 0.6 = 0.10
+                Cmax = 0.3
+            Cmin = 0
+            return (0.3, 0.10, 0.0)
+
+    Cr = SetLum(Ct, 0.598)
+        d = 0.598 - (0.3 * 0.3 + 0.59 * 0.10 + 0.11 * 0.0) = 0.598 - (0.09 + 0.059) = 0.598 - 0.149
+        d = 0.449
+        Cred = 0.3 + 0.449 = 0.749
+        Cgreen = 0.10 + 0.449 = 0.549
+        Cblue = 0.0 + 0.449 = 0.449
+        return (0.749, 0.549, 0.449)
+
+    This value is equivalent to (191, 140, 115), which is the expected color.
+    This is the exact color value, other ports might experience slight differences.
+-->
+    <div id="solid-solid"></div>
+    <div id="alpha-solid"></div>
+    <div id="solid-alpha"></div>
+    <div id="alpha-alpha"></div>
+</body>
+</html>

Modified: trunk/LayoutTests/platform/mac/TestExpectations (145113 => 145114)


--- trunk/LayoutTests/platform/mac/TestExpectations	2013-03-07 19:53:34 UTC (rev 145113)
+++ trunk/LayoutTests/platform/mac/TestExpectations	2013-03-07 20:00:48 UTC (rev 145114)
@@ -956,11 +956,13 @@
 css3/filters/composited-during-transition-layertree.html
 
 # --- Custom Filters ---
-# The following 3 tests are currently skipped on Mac for slight color differences,
+# The following 5 tests are currently skipped on Mac for slight color differences,
 # please see the relevant bug: http://webkit.org/b/107487
 webkit.org/b/107487 css3/filters/custom/custom-filter-blend-fractional-destination-alpha.html [ Skip ]
 webkit.org/b/107487 css3/filters/custom/custom-filter-nonseparable-blend-mode-color.html [ Skip ]
 webkit.org/b/107487 css3/filters/custom/custom-filter-nonseparable-blend-mode-luminosity.html [ Skip ]
+webkit.org/b/107487 css3/filters/custom/custom-filter-nonseparable-blend-mode-hue.html [ Skip ]
+webkit.org/b/107487 css3/filters/custom/custom-filter-nonseparable-blend-mode-saturation.html [ Skip ]
 
 # --- Text ---
 fast/forms/text-control-intrinsic-widths.html

Modified: trunk/Source/WebCore/ChangeLog (145113 => 145114)


--- trunk/Source/WebCore/ChangeLog	2013-03-07 19:53:34 UTC (rev 145113)
+++ trunk/Source/WebCore/ChangeLog	2013-03-07 20:00:48 UTC (rev 145114)
@@ -1,3 +1,26 @@
+2013-03-07  Michelangelo De Simone  <michelang...@webkit.org>
+
+        [CSS Shaders] Implement hue and saturation non-separable blend modes
+        https://bugs.webkit.org/show_bug.cgi?id=109464
+
+        Added the following GLSL helper functions to the CustomFilterValidatedProgram:
+
+            - css_Sat(C): returns the saturation for the color C
+            - css_SetSat(C, s): sets the saturation s on the color C
+            - css_SetSatHelper(Cmin, Cmid, Cmax, s): helper function for css_SetSat
+
+        The above functions are being used for the "hue" and "saturation" non-separable
+        blend modes, the relevant spec for such modes is at URL:
+        https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingnonseparable
+
+        Reviewed by Dean Jackson.
+
+        Tests: css3/filters/custom/custom-filter-nonseparable-blend-mode-hue.html
+               css3/filters/custom/custom-filter-nonseparable-blend-mode-saturation.html
+
+        * platform/graphics/filters/CustomFilterValidatedProgram.cpp:
+        (WebCore::CustomFilterValidatedProgram::blendFunctionString):
+
 2013-03-07  Andrey Lushnikov  <lushni...@chromium.org>
 
         Web Inspector: [ACE] set correct font

Modified: trunk/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp (145113 => 145114)


--- trunk/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp	2013-03-07 19:53:34 UTC (rev 145113)
+++ trunk/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp	2013-03-07 20:00:48 UTC (rev 145114)
@@ -292,6 +292,7 @@
     const char* blendColorExpression = "vec3(css_BlendComponent(Cb.r, Cs.r), css_BlendComponent(Cb.g, Cs.g), css_BlendComponent(Cb.b, Cs.b))";
     const char* blendComponentExpression = "Co = 0.0;";
     bool needsLuminosityHelperFunctions = false;
+    bool needsSaturationHelperFunctions = false;
     String blendFunctionString;
     switch (blendMode) {
     case BlendModeNormal:
@@ -416,9 +417,17 @@
         blendColorExpression = "css_SetLum(Cb, css_Lum(Cs))";
         break;
     case BlendModeHue:
+        needsLuminosityHelperFunctions = true;
+        needsSaturationHelperFunctions = true;
+        blendColorExpression = "css_SetLum(css_SetSat(Cs, css_Sat(Cb)), css_Lum(Cb))";
+        break;
     case BlendModeSaturation:
-        notImplemented();
-        return String();
+        needsLuminosityHelperFunctions = true;
+        needsSaturationHelperFunctions = true;
+        blendColorExpression = "css_SetLum(css_SetSat(Cb, css_Sat(Cs)), css_Lum(Cb))";
+        break;
+    default:
+        ASSERT_NOT_REACHED();
     }
 
     if (needsLuminosityHelperFunctions) {
@@ -446,6 +455,49 @@
         ));
     }
 
+    if (needsSaturationHelperFunctions) {
+        blendFunctionString.append(SHADER(
+            mediump float css_Sat(mediump vec3 C)
+            {
+                mediump float cMin = min(min(C.r, C.g), C.b);
+                mediump float cMax = max(max(C.r, C.g), C.b);
+                return cMax - cMin;
+            }
+            void css_SetSatHelper(inout mediump float cMin, inout mediump float cMid, inout mediump float cMax, mediump float s)
+            {
+                if (cMax > cMin) {
+                    cMid = (((cMid - cMin) * s) / (cMax - cMin));
+                    cMax = s;
+                } else
+                    cMid = cMax = 0.0;
+                cMin = 0.0;
+            }
+            mediump vec3 css_SetSat(mediump vec3 C, mediump float s)
+            {
+                if (C.r <= C.g) {
+                    if (C.g <= C.b)
+                        css_SetSatHelper(C.r, C.g, C.b, s);
+                    else {
+                        if (C.r <= C.b)
+                            css_SetSatHelper(C.r, C.b, C.g, s);
+                        else
+                            css_SetSatHelper(C.b, C.r, C.g, s);
+                    }
+                } else {
+                    if (C.r <= C.b)
+                        css_SetSatHelper(C.g, C.r, C.b, s);
+                    else {
+                        if (C.g <= C.b)
+                            css_SetSatHelper(C.g, C.b, C.r, s);
+                        else
+                            css_SetSatHelper(C.b, C.g, C.r, s);
+                    }
+                }
+                return C;
+            }
+        ));
+    }
+
     blendFunctionString.append(String::format(SHADER(
         mediump float css_BlendComponent(mediump float Cb, mediump float Cs)
         {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to