Diff
Modified: trunk/LayoutTests/ChangeLog (144117 => 144118)
--- trunk/LayoutTests/ChangeLog 2013-02-27 00:13:12 UTC (rev 144117)
+++ trunk/LayoutTests/ChangeLog 2013-02-27 00:19:05 UTC (rev 144118)
@@ -1,3 +1,19 @@
+2013-02-26 Michelangelo De Simone <[email protected]>
+
+ [CSS Shaders] Implement color and luminosity non-separable blend modes
+ https://bugs.webkit.org/show_bug.cgi?id=106226
+
+ Added relevant tests for the "color" and "luminosity" 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-color-expected.html: Added.
+ * css3/filters/custom/custom-filter-nonseparable-blend-mode-color.html: Added.
+ * css3/filters/custom/custom-filter-nonseparable-blend-mode-luminosity-expected.html: Added.
+ * css3/filters/custom/custom-filter-nonseparable-blend-mode-luminosity.html: Added.
+
2013-02-26 Dirk Pranke <[email protected]>
[chromium] Re-enable the fixed version of freetype on linux
Added: trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-color-expected.html (0 => 144118)
--- trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-color-expected.html (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-color-expected.html 2013-02-27 00:19:05 UTC (rev 144118)
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+ <title>Test that blends the source and the backdrop with the color blend mode.</title>
+ <style type="text/css">
+ /* These are exactly the color values we expect. Some platforms may have slightly 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-color.html (0 => 144118)
--- trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-color.html (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-color.html 2013-02-27 00:19:05 UTC (rev 144118)
@@ -0,0 +1,129 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+ <title>Test that blends the source and the backdrop with the color 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') color 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') color 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') color 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') color 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 blended with source with 0.5 alpha
+ The underlaying 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 "color" 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(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
+ 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
+ SetLum(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
+
+ 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
+
+ Lum(Cs) = 0.3 * 0.2 + 0.59 * 0.4 + 0.11 * 0.8
+ Lum(Cs) = 0.06 + 0.236 + 0.088
+ Lum(Cs) = 0.384
+
+ Cr = SetLum(Cs, 0.598)
+ d = 0.598 - Lum(Cs)
+ d = 0.598 - 0.384
+ d = 0.214
+ Cred = 0.2 + 0.214 = 0.414
+ Green = 0.4 + 0.214 = 0.614
+ Cblue = 0.8 + 0.214 = 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-luminosity-expected.html (0 => 144118)
--- trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-luminosity-expected.html (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-luminosity-expected.html 2013-02-27 00:19:05 UTC (rev 144118)
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+ <title>Test that blends the source and the backdrop with the color blend mode.</title>
+ <style type="text/css">
+ /* There are exactly the color values we expect. Some platforms may have slightly different
+ color result. */
+ #solid-solid {
+ background-color: rgb(98, 33, 0);
+ width: 100px;
+ height: 100px;
+ }
+ #alpha-solid {
+ background-color: rgb(184, 172, 184);
+ width: 100px;
+ height: 100px;
+ }
+ #solid-alpha {
+ background-color: rgb(203, 101, 49);
+ width: 100px;
+ height: 100px;
+ }
+ #alpha-alpha {
+ background-color: rgb(213, 182, 175);
+ 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-luminosity.html (0 => 144118)
--- trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-luminosity.html (rev 0)
+++ trunk/LayoutTests/css3/filters/custom/custom-filter-nonseparable-blend-mode-luminosity.html 2013-02-27 00:19:05 UTC (rev 144118)
@@ -0,0 +1,128 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+ <title>Test that blends the source and the backdrop with the luminosity 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') luminosity 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') luminosity 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') luminosity 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') luminosity 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 blended with source with 0.5 alpha
+ The underlaying 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 "luminosity" 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(Cb, Lum(Cs))
+
+ 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(Cs): the luminosity of Cs. Luminosity for color C is generally defined by
+ Lum(C): 0.3 * Cred + 0.59 * Cgreen + 0.11 * Cblue
+ SetLum(Cb, Lum(Cs)): 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
+
+ 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
+
+ Lum(Cs) = 0.3 * 0.1 + 0.59 * 0.2 + 0.11 * 0.4
+ Lum(Cs) = 0.03 + 0.118 + 0.044
+ Lum(Cs) = 0.192
+
+ Cr = SetLum(Cb, 0.192)
+ d = 0.192 - 0.598
+ d = 0.406
+ Cred = 0.9 - 0.406 = 0.494
+ Cgreen = 0.5 - 0.406 = 0.094
+ Cblue = 0.3 - 0.406 = -0.106
+ return ClipColor(0.494, 0.094, -0.106)
+
+ ClipColor(0.494, 0.094, -0.106)
+ l = 0.494 * 0.3 + 0.094 * 0.59 - 0.106 * 0.11 = 0.1482 + 0.05546 - 0.01166 = 0.192
+ n = min(0.494, 0.094, -0.106) = -0.106
+ x = max(0.494, 0.094, -0.106) = 0.494
+ n < 0.0
+ Cred = 0.192 + (((0.494 - 0.192) * 0.192) / (0.192 + 0.106)) =
+ = 0.192 + (0.302 * 0.192) / 0.298 = 0.192 + (0.057984 / 0.298) = 0.192 + 0.19457718 = 0.38657718
+ Cgreen = 0.192 + (((0.094 - 0.192) * 0.192) / (0.192 + 0.106)) =
+ = 0.192 + (-0.098 * 0.192) / 0.298 = 0.192 - (0.018816 / 0.298) = 0.192 - 0.06314094 = 0.12885906
+ Cblue = 0.192 + (((-0.106 - 0.192) * 0.192) / (0.192 + 0.106)) =
+ = 0.192 + (-0.298 * 0.192) / 0.298 = 0.192 - 0.192 = 0.0
+ return (0.38657718, 0.12885906, 0.00)
+
+ This value is equivalent to (98, 33, 0), 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 (144117 => 144118)
--- trunk/LayoutTests/platform/mac/TestExpectations 2013-02-27 00:13:12 UTC (rev 144117)
+++ trunk/LayoutTests/platform/mac/TestExpectations 2013-02-27 00:19:05 UTC (rev 144118)
@@ -949,8 +949,11 @@
css3/filters/composited-during-transition-layertree.html
# --- Custom Filters ---
-# This test is currently skipped on Mac for slight color differences, please see the relevant bug: http://webkit.org/b/107487
+# The following 3 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 ]
# --- Text ---
fast/forms/text-control-intrinsic-widths.html
Modified: trunk/Source/WebCore/ChangeLog (144117 => 144118)
--- trunk/Source/WebCore/ChangeLog 2013-02-27 00:13:12 UTC (rev 144117)
+++ trunk/Source/WebCore/ChangeLog 2013-02-27 00:19:05 UTC (rev 144118)
@@ -1,3 +1,26 @@
+2013-02-26 Michelangelo De Simone <[email protected]>
+
+ [CSS Shaders] Implement color and luminosity non-separable blend modes
+ https://bugs.webkit.org/show_bug.cgi?id=106226
+
+ Added the following GLSL helper functions to the CustomFilterValidatedProgram:
+
+ - css_Lum(C): returns the luminosity for the color C
+ - css_ClipColor(C): clips color C
+ - css_SetLum(C, l): sets the luminosity l on the color C
+
+ The above functions are being used for the "color" and "luminosity" 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-color.html
+ css3/filters/custom/custom-filter-nonseparable-blend-mode-luminosity.html
+
+ * platform/graphics/filters/CustomFilterValidatedProgram.cpp:
+ (WebCore::CustomFilterValidatedProgram::blendFunctionString):
+
2013-02-26 Anders Carlsson <[email protected]>
StorageAreaProxy should hold on to a StorageMap and not a HashMap
Modified: trunk/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp (144117 => 144118)
--- trunk/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp 2013-02-27 00:13:12 UTC (rev 144117)
+++ trunk/Source/WebCore/platform/graphics/filters/CustomFilterValidatedProgram.cpp 2013-02-27 00:19:05 UTC (rev 144118)
@@ -291,6 +291,8 @@
// Cb: is the backdrop color in css_BlendColor() and the backdrop color component in css_BlendComponent()
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;
+ String blendFunctionString;
switch (blendMode) {
case BlendModeNormal:
blendColorExpression = "Cs";
@@ -405,15 +407,46 @@
Co = Cb + (2.0 * Cs - 1.0) * (D - Cb);
);
break;
+ case BlendModeColor:
+ needsLuminosityHelperFunctions = true;
+ blendColorExpression = "css_SetLum(Cs, css_Lum(Cb))";
+ break;
+ case BlendModeLuminosity:
+ needsLuminosityHelperFunctions = true;
+ blendColorExpression = "css_SetLum(Cb, css_Lum(Cs))";
+ break;
case BlendModeHue:
case BlendModeSaturation:
- case BlendModeColor:
- case BlendModeLuminosity:
notImplemented();
return String();
}
- return String::format(SHADER(
+ if (needsLuminosityHelperFunctions) {
+ blendFunctionString.append(SHADER(
+ mediump float css_Lum(mediump vec3 C)
+ {
+ return 0.3 * C.r + 0.59 * C.g + 0.11 * C.b;
+ }
+ mediump vec3 css_ClipColor(mediump vec3 C)
+ {
+ mediump float L = css_Lum(C);
+ mediump float n = min(min(C.r, C.g), C.b);
+ mediump float x = max(max(C.r, C.g), C.b);
+ if (n < 0.0)
+ C = L + (((C - L) * L) / (L - n));
+ if (x > 1.0)
+ C = L + (((C - L) * (1.0 - L) / (x - L)));
+ return C;
+ }
+ mediump vec3 css_SetLum(mediump vec3 C, mediump float l)
+ {
+ C += l - css_Lum(C);
+ return css_ClipColor(C);
+ }
+ ));
+ }
+
+ blendFunctionString.append(String::format(SHADER(
mediump float css_BlendComponent(mediump float Cb, mediump float Cs)
{
mediump float Co;
@@ -424,7 +457,9 @@
{
return %s;
}
- ), blendComponentExpression, blendColorExpression);
+ ), blendComponentExpression, blendColorExpression));
+
+ return blendFunctionString;
}
String CustomFilterValidatedProgram::compositeFunctionString(CompositeOperator compositeOperator)