Implement hardware accelerated Brightness and contrast filters
authorcmarrin@apple.com <cmarrin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 21 Jan 2012 15:40:03 +0000 (15:40 +0000)
committercmarrin@apple.com <cmarrin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 21 Jan 2012 15:40:03 +0000 (15:40 +0000)
https://bugs.webkit.org/show_bug.cgi?id=75521
https://bugs.webkit.org/show_bug.cgi?id=76719

Reviewed by Simon Fraser.

Source/WebCore:

Implemented hardware accelerated brightness and contrast filters. This also fixes
the bug where grayscale filter was accidentally never getting hardware accelerated.
It also complies with proposed spec changes for the brightness filter to be additive
rather than multiplicative, according to https://bugs.webkit.org/show_bug.cgi?id=76719.
Had to make both fixes in the same patch because I had to change the allowed brightness
values for the hardware version, so I had to change the software version as well.

Tests: css3/filters/effect-brightness-hw.html
       css3/filters/effect-contrast-hw.html

* css/CSSParser.cpp:
(WebCore::CSSParser::parseBuiltinFilterArguments):
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::createFilterOperations):
* platform/graphics/ca/mac/PlatformCALayerMac.mm:
(PlatformCALayer::setFilters):
(PlatformCALayer::filtersCanBeComposited):
* rendering/FilterEffectRenderer.cpp:
(WebCore::FilterEffectRenderer::build):

LayoutTests:

New tests for hardware accelerated brightness and contrast filters. Also
added brightness and contrast values to effect-combined-hw test. And changed
brightness values in effect-brightness.html to reflect new spec.
Also fixed parsing and computed style tests to reflect new brightness spec.

* css3/filters/effect-brightness-expected.png:
* css3/filters/effect-brightness-hw-expected.png: Added.
* css3/filters/effect-brightness-hw-expected.txt: Added.
* css3/filters/effect-brightness-hw.html: Added.
* css3/filters/effect-brightness.html:
* css3/filters/effect-combined-expected.png:
* css3/filters/effect-combined-hw-expected.png:
* css3/filters/effect-combined-hw-expected.txt:
* css3/filters/effect-combined-hw.html:
* css3/filters/effect-combined.html:
* css3/filters/effect-contrast-hw-expected.png: Added.
* css3/filters/effect-contrast-hw-expected.txt: Added.
* css3/filters/effect-contrast-hw.html: Added.
* css3/filters/filter-property-computed-style-expected.txt:
* css3/filters/filter-property-parsing-expected.txt:
* css3/filters/filter-property-parsing-invalid-expected.txt:
* css3/filters/script-tests/filter-property-computed-style.js:
* css3/filters/script-tests/filter-property-parsing-invalid.js:
* css3/filters/script-tests/filter-property-parsing.js:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@105576 268f45cc-cd09-0410-ab3c-d52691b4dbfc

25 files changed:
LayoutTests/ChangeLog
LayoutTests/css3/filters/effect-brightness-expected.png
LayoutTests/css3/filters/effect-brightness-hw-expected.png [new file with mode: 0644]
LayoutTests/css3/filters/effect-brightness-hw-expected.txt [new file with mode: 0644]
LayoutTests/css3/filters/effect-brightness-hw.html [new file with mode: 0644]
LayoutTests/css3/filters/effect-brightness.html
LayoutTests/css3/filters/effect-combined-expected.png
LayoutTests/css3/filters/effect-combined-hw-expected.png
LayoutTests/css3/filters/effect-combined-hw-expected.txt
LayoutTests/css3/filters/effect-combined-hw.html
LayoutTests/css3/filters/effect-combined.html
LayoutTests/css3/filters/effect-contrast-hw-expected.png [new file with mode: 0644]
LayoutTests/css3/filters/effect-contrast-hw-expected.txt [new file with mode: 0644]
LayoutTests/css3/filters/effect-contrast-hw.html [new file with mode: 0644]
LayoutTests/css3/filters/filter-property-computed-style-expected.txt
LayoutTests/css3/filters/filter-property-parsing-expected.txt
LayoutTests/css3/filters/filter-property-parsing-invalid-expected.txt
LayoutTests/css3/filters/script-tests/filter-property-computed-style.js
LayoutTests/css3/filters/script-tests/filter-property-parsing-invalid.js
LayoutTests/css3/filters/script-tests/filter-property-parsing.js
Source/WebCore/ChangeLog
Source/WebCore/css/CSSParser.cpp
Source/WebCore/css/CSSStyleSelector.cpp
Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm
Source/WebCore/rendering/FilterEffectRenderer.cpp

index e9632f1..c1a3694 100644 (file)
@@ -1,3 +1,36 @@
+2012-01-20  Chris Marrin  <cmarrin@apple.com>
+
+        Implement hardware accelerated Brightness and contrast filters
+        https://bugs.webkit.org/show_bug.cgi?id=75521
+        https://bugs.webkit.org/show_bug.cgi?id=76719
+
+        Reviewed by Simon Fraser.
+
+        New tests for hardware accelerated brightness and contrast filters. Also
+        added brightness and contrast values to effect-combined-hw test. And changed
+        brightness values in effect-brightness.html to reflect new spec.
+        Also fixed parsing and computed style tests to reflect new brightness spec.
+
+        * css3/filters/effect-brightness-expected.png:
+        * css3/filters/effect-brightness-hw-expected.png: Added.
+        * css3/filters/effect-brightness-hw-expected.txt: Added.
+        * css3/filters/effect-brightness-hw.html: Added.
+        * css3/filters/effect-brightness.html:
+        * css3/filters/effect-combined-expected.png:
+        * css3/filters/effect-combined-hw-expected.png:
+        * css3/filters/effect-combined-hw-expected.txt:
+        * css3/filters/effect-combined-hw.html:
+        * css3/filters/effect-combined.html:
+        * css3/filters/effect-contrast-hw-expected.png: Added.
+        * css3/filters/effect-contrast-hw-expected.txt: Added.
+        * css3/filters/effect-contrast-hw.html: Added.
+        * css3/filters/filter-property-computed-style-expected.txt:
+        * css3/filters/filter-property-parsing-expected.txt:
+        * css3/filters/filter-property-parsing-invalid-expected.txt:
+        * css3/filters/script-tests/filter-property-computed-style.js:
+        * css3/filters/script-tests/filter-property-parsing-invalid.js:
+        * css3/filters/script-tests/filter-property-parsing.js:
+
 2012-01-21  Nikolas Zimmermann  <nzimmermann@rim.com>
 
         <feImage> ignores preserveAspectRatio="none"
index 9ad6a20..629f7ad 100644 (file)
Binary files a/LayoutTests/css3/filters/effect-brightness-expected.png and b/LayoutTests/css3/filters/effect-brightness-expected.png differ
diff --git a/LayoutTests/css3/filters/effect-brightness-hw-expected.png b/LayoutTests/css3/filters/effect-brightness-hw-expected.png
new file mode 100644 (file)
index 0000000..3ca48a6
Binary files /dev/null and b/LayoutTests/css3/filters/effect-brightness-hw-expected.png differ
diff --git a/LayoutTests/css3/filters/effect-brightness-hw-expected.txt b/LayoutTests/css3/filters/effect-brightness-hw-expected.txt
new file mode 100644 (file)
index 0000000..94a1869
--- /dev/null
@@ -0,0 +1,32 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (160,76) size 4x18
+        text run at (160,76) width 4: " "
+      RenderText {#text} at (324,76) size 4x18
+        text run at (324,76) width 4: " "
+      RenderText {#text} at (488,76) size 4x18
+        text run at (488,76) width 4: " "
+      RenderText {#text} at (652,76) size 4x18
+        text run at (652,76) width 4: " "
+      RenderText {#text} at (160,170) size 4x18
+        text run at (160,170) width 4: " "
+      RenderText {#text} at (324,170) size 4x18
+        text run at (324,170) width 4: " "
+      RenderText {#text} at (0,0) size 0x0
+layer at (8,8) size 160x90
+  RenderImage {IMG} at (0,0) size 160x90
+layer at (172,8) size 160x90
+  RenderImage {IMG} at (164,0) size 160x90
+layer at (336,8) size 160x90
+  RenderImage {IMG} at (328,0) size 160x90
+layer at (500,8) size 160x90
+  RenderImage {IMG} at (492,0) size 160x90
+layer at (8,102) size 160x90
+  RenderImage {IMG} at (0,94) size 160x90
+layer at (172,102) size 160x90
+  RenderImage {IMG} at (164,94) size 160x90
+layer at (336,102) size 160x90
+  RenderImage {IMG} at (328,94) size 160x90
diff --git a/LayoutTests/css3/filters/effect-brightness-hw.html b/LayoutTests/css3/filters/effect-brightness-hw.html
new file mode 100644 (file)
index 0000000..d98d13f
--- /dev/null
@@ -0,0 +1,12 @@
+<style>
+img {
+    -webkit-transform:translateZ(0);
+}
+</style>
+<img style="-webkit-filter: brightness(-1)" src="resources/reference.png">
+<img style="-webkit-filter: brightness(-0.6)" src="resources/reference.png">
+<img style="-webkit-filter: brightness(-0.3)" src="resources/reference.png">
+<img style="-webkit-filter: brightness()" src="resources/reference.png">
+<img style="-webkit-filter: brightness(0.3)" src="resources/reference.png">
+<img style="-webkit-filter: brightness(0.6)" src="resources/reference.png">
+<img style="-webkit-filter: brightness(1)" src="resources/reference.png">
index 4e7b6c0..6fd9c10 100644 (file)
@@ -4,10 +4,10 @@ if (window.layoutTestController) {
     window.layoutTestController.overridePreference("WebKitAcceleratedCompositingEnabled", "0");
 }
 </script>
-<img style="-webkit-filter: brightness(0)" src="resources/reference.png">
-<img style="-webkit-filter: brightness(0.5)" src="resources/reference.png">
-<img style="-webkit-filter: brightness(1.0)" src="resources/reference.png">
-<img style="-webkit-filter: brightness(2)" src="resources/reference.png">
-<img style="-webkit-filter: brightness(5)" src="resources/reference.png">
-<img style="-webkit-filter: brightness(10)" src="resources/reference.png">
-<img style="-webkit-filter: brightness(1000)" src="resources/reference.png">
+<img style="-webkit-filter: brightness(-1)" src="resources/reference.png">
+<img style="-webkit-filter: brightness(-0.6)" src="resources/reference.png">
+<img style="-webkit-filter: brightness(-0.3)" src="resources/reference.png">
+<img style="-webkit-filter: brightness()" src="resources/reference.png">
+<img style="-webkit-filter: brightness(0.3)" src="resources/reference.png">
+<img style="-webkit-filter: brightness(0.6)" src="resources/reference.png">
+<img style="-webkit-filter: brightness(1)" src="resources/reference.png">
index 6e2acc9..0157d04 100644 (file)
Binary files a/LayoutTests/css3/filters/effect-combined-expected.png and b/LayoutTests/css3/filters/effect-combined-expected.png differ
index db06fc5..e6faffd 100644 (file)
Binary files a/LayoutTests/css3/filters/effect-combined-hw-expected.png and b/LayoutTests/css3/filters/effect-combined-hw-expected.png differ
index 288df80..7b9616e 100644 (file)
@@ -11,6 +11,8 @@ layer at (0,0) size 800x600
         text run at (548,96) width 4: " "
       RenderText {#text} at (732,96) size 4x18
         text run at (732,96) width 4: " "
+      RenderText {#text} at (180,210) size 4x18
+        text run at (180,210) width 4: " "
       RenderText {#text} at (0,0) size 0x0
 layer at (18,18) size 160x90
   RenderImage {IMG} at (10,10) size 160x90
@@ -22,3 +24,5 @@ layer at (570,18) size 160x90
   RenderImage {IMG} at (562,10) size 160x90
 layer at (18,132) size 160x90
   RenderImage {IMG} at (10,124) size 160x90
+layer at (202,132) size 160x90
+  RenderImage {IMG} at (194,124) size 160x90
index 30f8816..4b803e7 100644 (file)
@@ -9,3 +9,4 @@ img {
 <img style="-webkit-filter: grayscale() blur(3px)" src="resources/reference.png">
 <img style="-webkit-filter: blur(3px) hue-rotate(-90deg) sepia()" src="resources/reference.png">
 <img style="-webkit-filter: blur(3px) opacity(0.5) hue-rotate(-90deg) sepia()" src="resources/reference.png">
+<img style="-webkit-filter: blur(3px) brightness(0.2) contrast(2)" src="resources/reference.png">
index 5c02db5..d60a99d 100644 (file)
@@ -14,4 +14,4 @@ img {
 <img style="-webkit-filter: grayscale() blur(3px)" src="resources/reference.png">
 <img style="-webkit-filter: blur(3px) hue-rotate(-90deg) sepia()" src="resources/reference.png">
 <img style="-webkit-filter: blur(3px) opacity(0.5) hue-rotate(-90deg) sepia()" src="resources/reference.png">
-<img style="-webkit-filter: blur(3px) brightness(2)" src="resources/reference.png">
+<img style="-webkit-filter: blur(3px) brightness(0.2) contrast(2)" src="resources/reference.png">
diff --git a/LayoutTests/css3/filters/effect-contrast-hw-expected.png b/LayoutTests/css3/filters/effect-contrast-hw-expected.png
new file mode 100644 (file)
index 0000000..88dea84
Binary files /dev/null and b/LayoutTests/css3/filters/effect-contrast-hw-expected.png differ
diff --git a/LayoutTests/css3/filters/effect-contrast-hw-expected.txt b/LayoutTests/css3/filters/effect-contrast-hw-expected.txt
new file mode 100644 (file)
index 0000000..f1b9930
--- /dev/null
@@ -0,0 +1,28 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderText {#text} at (160,76) size 4x18
+        text run at (160,76) width 4: " "
+      RenderText {#text} at (324,76) size 4x18
+        text run at (324,76) width 4: " "
+      RenderText {#text} at (488,76) size 4x18
+        text run at (488,76) width 4: " "
+      RenderText {#text} at (652,76) size 4x18
+        text run at (652,76) width 4: " "
+      RenderText {#text} at (160,170) size 4x18
+        text run at (160,170) width 4: " "
+      RenderText {#text} at (0,0) size 0x0
+layer at (8,8) size 160x90
+  RenderImage {IMG} at (0,0) size 160x90
+layer at (172,8) size 160x90
+  RenderImage {IMG} at (164,0) size 160x90
+layer at (336,8) size 160x90
+  RenderImage {IMG} at (328,0) size 160x90
+layer at (500,8) size 160x90
+  RenderImage {IMG} at (492,0) size 160x90
+layer at (8,102) size 160x90
+  RenderImage {IMG} at (0,94) size 160x90
+layer at (172,102) size 160x90
+  RenderImage {IMG} at (164,94) size 160x90
diff --git a/LayoutTests/css3/filters/effect-contrast-hw.html b/LayoutTests/css3/filters/effect-contrast-hw.html
new file mode 100644 (file)
index 0000000..950fcea
--- /dev/null
@@ -0,0 +1,11 @@
+<style>
+img {
+    -webkit-transform:translateZ(0);
+}
+</style>
+<img style="-webkit-filter: contrast(0)" src="resources/reference.png">
+<img style="-webkit-filter: contrast(0.5)" src="resources/reference.png">
+<img style="-webkit-filter: contrast(1.0)" src="resources/reference.png">
+<img style="-webkit-filter: contrast(2)" src="resources/reference.png">
+<img style="-webkit-filter: contrast(5)" src="resources/reference.png">
+<img style="-webkit-filter: contrast(10)" src="resources/reference.png">
index 9aa1669..3e7a3a4 100644 (file)
@@ -238,11 +238,6 @@ PASS filterStyle.length is 1
 PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS
 PASS subRule.cssText is 'brightness(1)'
 
-Value greater than 1 : brightness(2)
-PASS filterStyle.length is 1
-PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS
-PASS subRule.cssText is 'brightness(2)'
-
 Float value converts to integer : brightness(1.0)
 PASS filterStyle.length is 1
 PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS
@@ -256,7 +251,7 @@ PASS subRule.cssText is 'brightness(0)'
 No values : brightness()
 PASS filterStyle.length is 1
 PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS
-PASS subRule.cssText is 'brightness(1)'
+PASS subRule.cssText is 'brightness(0)'
 
 Multiple values : brightness(0.5) brightness(0.25)
 PASS filterStyle.length is 2
@@ -373,7 +368,7 @@ PASS subRule.cssText is 'opacity(0.9)'
 PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_BLUR
 PASS subRule.cssText is 'blur(5px)'
 
-Percentage values : grayscale(50%) sepia(25%) saturate(75%) invert(20%) opacity(90%) brightness(130%) contrast(30%)
+Percentage values : grayscale(50%) sepia(25%) saturate(75%) invert(20%) opacity(90%) brightness(60%) contrast(30%)
 PASS filterStyle.length is 7
 PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_GRAYSCALE
 PASS subRule.cssText is 'grayscale(0.5)'
@@ -386,7 +381,7 @@ PASS subRule.cssText is 'invert(0.2)'
 PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_OPACITY
 PASS subRule.cssText is 'opacity(0.9)'
 PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS
-PASS subRule.cssText is 'brightness(1.3)'
+PASS subRule.cssText is 'brightness(0.6)'
 PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_CONTRAST
 PASS subRule.cssText is 'contrast(0.3)'
 PASS successfullyParsed is true
index 5f82be6..662b8d1 100644 (file)
@@ -578,17 +578,6 @@ PASS filterRule.length is 1
 PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS
 PASS subRule.cssText is 'brightness(50%)'
 
-Percentage value > 1 : brightness(150%)
-PASS cssRule.type is 1
-PASS declaration.length is 1
-PASS declaration.getPropertyValue('-webkit-filter') is 'brightness(150%)'
-PASS jsWrapperClass(filterRule) is 'CSSValueList'
-PASS jsWrapperClass(filterRule.__proto__) is 'CSSValueListPrototype'
-PASS jsWrapperClass(filterRule.constructor) is 'CSSValueListConstructor'
-PASS filterRule.length is 1
-PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS
-PASS subRule.cssText is 'brightness(150%)'
-
 Float value converts to integer : brightness(1.0)
 PASS cssRule.type is 1
 PASS declaration.length is 1
@@ -622,17 +611,6 @@ PASS filterRule.length is 1
 PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS
 PASS subRule.cssText is 'brightness()'
 
-Value greater than one : brightness(2)
-PASS cssRule.type is 1
-PASS declaration.length is 1
-PASS declaration.getPropertyValue('-webkit-filter') is 'brightness(2)'
-PASS jsWrapperClass(filterRule) is 'CSSValueList'
-PASS jsWrapperClass(filterRule.__proto__) is 'CSSValueListPrototype'
-PASS jsWrapperClass(filterRule.constructor) is 'CSSValueListConstructor'
-PASS filterRule.length is 1
-PASS subRule.operationType is WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS
-PASS subRule.cssText is 'brightness(2)'
-
 Multiple values : brightness(0.5) brightness(0.25)
 PASS cssRule.type is 1
 PASS declaration.length is 1
index 0bf4532..5670bee 100644 (file)
@@ -214,12 +214,12 @@ PASS cssRule.type is 1
 PASS declaration.length is 0
 PASS declaration.getPropertyValue('-webkit-filter') is null
 
-Negative parameter : brightness(-0.5)
+Parameter out of bounds (negative) : brightness(-1.1)
 PASS cssRule.type is 1
 PASS declaration.length is 0
 PASS declaration.getPropertyValue('-webkit-filter') is null
 
-Negative percent : brightness(-10%)
+Parameter out of bounds (positive) : brightness(101%)
 PASS cssRule.type is 1
 PASS declaration.length is 0
 PASS declaration.getPropertyValue('-webkit-filter') is null
index d525f50..0c685de 100644 (file)
@@ -231,11 +231,6 @@ testComputedFilterRule("Integer value",
                       ["WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS"],
                       ["brightness(1)"]);
 
-testComputedFilterRule("Value greater than 1",
-                      "brightness(2)", 1,
-                      ["WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS"],
-                      ["brightness(2)"]);
-
 testComputedFilterRule("Float value converts to integer",
                       "brightness(1.0)", 1,
                       ["WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS"],
@@ -249,7 +244,7 @@ testComputedFilterRule("Zero value",
 testComputedFilterRule("No values",
                       "brightness()", 1,
                       ["WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS"],
-                      ["brightness(1)"]);
+                      ["brightness(0)"]);
 
 testComputedFilterRule("Multiple values",
                       "brightness(0.5) brightness(0.25)", 2,
@@ -363,7 +358,7 @@ testComputedFilterRule("Multiple operations",
                ]);
 
 testComputedFilterRule("Percentage values",
-                      "grayscale(50%) sepia(25%) saturate(75%) invert(20%) opacity(90%) brightness(130%) contrast(30%)", 7,
+                      "grayscale(50%) sepia(25%) saturate(75%) invert(20%) opacity(90%) brightness(60%) contrast(30%)", 7,
                       [
                           "WebKitCSSFilterValue.CSS_FILTER_GRAYSCALE",
                           "WebKitCSSFilterValue.CSS_FILTER_SEPIA",
@@ -379,7 +374,7 @@ testComputedFilterRule("Percentage values",
                           "saturate(0.75)",
                           "invert(0.2)",
                           "opacity(0.9)",
-                          "brightness(1.3)",
+                          "brightness(0.6)",
                           "contrast(0.3)"
               ]);
 
index 736dceb..c2b0897 100644 (file)
@@ -68,8 +68,8 @@ testInvalidFilterRule("Length instead of number", "brightness(10px)");
 testInvalidFilterRule("Too many parameters", "brightness(0.5 0.5)");
 testInvalidFilterRule("Too many parameters and commas", "brightness(0.5, 0.5)");
 testInvalidFilterRule("Trailing comma", "brightness(0.5,)");
-testInvalidFilterRule("Negative parameter", "brightness(-0.5)");
-testInvalidFilterRule("Negative percent", "brightness(-10%)");
+testInvalidFilterRule("Parameter out of bounds (negative)", "brightness(-1.1)");
+testInvalidFilterRule("Parameter out of bounds (positive)", "brightness(101%)");
 
 testInvalidFilterRule("Length instead of number", "contrast(10px)");
 testInvalidFilterRule("Too many parameters", "contrast(0.5 0.5)");
index fec3124..f7aad97 100644 (file)
@@ -301,11 +301,6 @@ testFilterRule("Percentage value",
               ["WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS"],
               ["brightness(50%)"]);
 
-testFilterRule("Percentage value > 1",
-              "brightness(150%)", 1, "brightness(150%)",
-              ["WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS"],
-              ["brightness(150%)"]);
-
 testFilterRule("Float value converts to integer",
               "brightness(1.0)", 1, "brightness(1)",
               ["WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS"],
@@ -321,11 +316,6 @@ testFilterRule("No values",
               ["WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS"],
               ["brightness()"]);
 
-testFilterRule("Value greater than one",
-              "brightness(2)", 1, "brightness(2)",
-              ["WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS"],
-              ["brightness(2)"]);
-
 testFilterRule("Multiple values",
               "brightness(0.5) brightness(0.25)", 2, "brightness(0.5) brightness(0.25)",
               ["WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS", "WebKitCSSFilterValue.CSS_FILTER_BRIGHTNESS"],
index aba0d79..0bd568a 100644 (file)
@@ -1,3 +1,31 @@
+2012-01-20  Chris Marrin  <cmarrin@apple.com>
+
+        Implement hardware accelerated Brightness and contrast filters
+        https://bugs.webkit.org/show_bug.cgi?id=75521
+        https://bugs.webkit.org/show_bug.cgi?id=76719
+
+        Reviewed by Simon Fraser.
+
+        Implemented hardware accelerated brightness and contrast filters. This also fixes
+        the bug where grayscale filter was accidentally never getting hardware accelerated.
+        It also complies with proposed spec changes for the brightness filter to be additive 
+        rather than multiplicative, according to https://bugs.webkit.org/show_bug.cgi?id=76719. 
+        Had to make both fixes in the same patch because I had to change the allowed brightness
+        values for the hardware version, so I had to change the software version as well.
+
+        Tests: css3/filters/effect-brightness-hw.html
+               css3/filters/effect-contrast-hw.html
+
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseBuiltinFilterArguments):
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::createFilterOperations):
+        * platform/graphics/ca/mac/PlatformCALayerMac.mm:
+        (PlatformCALayer::setFilters):
+        (PlatformCALayer::filtersCanBeComposited):
+        * rendering/FilterEffectRenderer.cpp:
+        (WebCore::FilterEffectRenderer::build):
+
 2012-01-21  Nikolas Zimmermann  <nzimmermann@rim.com>
 
         <feImage> ignores preserveAspectRatio="none"
index 77b8ffb..47ba1ee 100644 (file)
@@ -6811,7 +6811,6 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParse
     case WebKitCSSFilterValue::SaturateFilterOperation:
     case WebKitCSSFilterValue::InvertFilterOperation:
     case WebKitCSSFilterValue::OpacityFilterOperation:
-    case WebKitCSSFilterValue::BrightnessFilterOperation:
     case WebKitCSSFilterValue::ContrastFilterOperation: {
         // One optional argument, 0-1 or 0%-100%, if missing use 100%.
         if (args->size() > 1)
@@ -6824,9 +6823,8 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParse
                 
             double amount = value->fValue;
             
-            // Saturate, Brightness and Contrast allow values over 100%.
+            // Saturate and Contrast allow values over 100%.
             if (filterType != WebKitCSSFilterValue::SaturateFilterOperation
-                && filterType != WebKitCSSFilterValue::BrightnessFilterOperation
                 && filterType != WebKitCSSFilterValue::ContrastFilterOperation) {
                 double maxAllowed = value->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 100.0 : 1.0;
                 if (amount > maxAllowed)
@@ -6837,6 +6835,26 @@ PassRefPtr<WebKitCSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParse
         }
         break;
     }
+    case WebKitCSSFilterValue::BrightnessFilterOperation: {
+        // One optional argument, -1 to +1 or -100% to +100%, if missing use 0,
+        if (args->size() > 1)
+            return 0;
+
+        if (args->size()) {
+            CSSParserValue* value = args->current();
+            if (!validUnit(value, FNumber | FPercent, true))
+                return 0;
+                
+            double amount = value->fValue;
+            double minAllowed = value->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? -100.0 : -1.0;
+            double maxAllowed = value->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 100.0 : 1.0;
+            if (amount < minAllowed || amount > maxAllowed)
+                return 0;
+
+            filterValue->append(cssValuePool()->createValue(amount, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)));
+        }
+        break;
+    }
     case WebKitCSSFilterValue::HueRotateFilterOperation: {
         // hue-rotate() takes one optional angle.
         if (args->size() > 1)
index abf8932..6e75c1c 100644 (file)
@@ -5396,7 +5396,7 @@ bool CSSStyleSelector::createFilterOperations(CSSValue* inValue, RenderStyle* st
         case WebKitCSSFilterValue::BrightnessFilterOperation:
         case WebKitCSSFilterValue::ContrastFilterOperation:
         case WebKitCSSFilterValue::OpacityFilterOperation: {
-            double amount = 1;
+            double amount = (filterValue->operationType() == WebKitCSSFilterValue::BrightnessFilterOperation) ? 0 : 1;
             if (filterValue->length() == 1) {
                 amount = firstValue->getDoubleValue();
                 if (firstValue->isPercentage())
index 25fa953..421112d 100644 (file)
@@ -720,6 +720,8 @@ void PlatformCALayer::setFilters(const FilterOperations& filters)
     RetainPtr<NSMutableArray> array(AdoptNS, [[NSMutableArray alloc] init]);
     
     for (unsigned i = 0; i < filters.size(); ++i) {
+        String filterName = String::format("filter_%d", i);
+        
         const FilterOperation* filterOperation = filters.at(i);
         switch(filterOperation->getOperationType()) {
         case FilterOperation::DROP_SHADOW: {
@@ -744,7 +746,7 @@ void PlatformCALayer::setFilters(const FilterOperations& filters)
             [caFilter setDefaults];
             [caFilter setValue:[NSNumber numberWithFloat:op->amount()] forKey:@"inputIntensity"];
             [caFilter setValue:[CIColor colorWithRed:1 green:1 blue:1] forKey:@"inputColor"];
-            [caFilter setName:@"grayscaleFilter"];
+            [caFilter setName:filterName];
             [array.get() addObject:caFilter];
             break;
         }
@@ -762,7 +764,7 @@ void PlatformCALayer::setFilters(const FilterOperations& filters)
             [caFilter setValue:[CIVector vectorWithX:WebCore::blend(0.0, 0.272, t) Y:WebCore::blend(0.0, 0.534, t) Z:WebCore::blend(1.0, 0.131, t) W:0] forKey:@"inputBVector"];
             [caFilter setValue:[CIVector vectorWithX:0 Y:0 Z:0 W:1] forKey:@"inputAVector"];
             [caFilter setValue:[CIVector vectorWithX:0 Y:0 Z:0 W:0] forKey:@"inputBiasVector"];
-            [caFilter setName:@"sepiaFilter"];
+            [caFilter setName:filterName];
             [array.get() addObject:caFilter];
             break;
         }
@@ -771,7 +773,7 @@ void PlatformCALayer::setFilters(const FilterOperations& filters)
             CIFilter* caFilter = [CIFilter filterWithName:@"CIColorControls"];
             [caFilter setDefaults];
             [caFilter setValue:[NSNumber numberWithFloat:op->amount()] forKey:@"inputSaturation"];
-            [caFilter setName:@"saturateFilter"];
+            [caFilter setName:filterName];
             [array.get() addObject:caFilter];
             break;
         }
@@ -782,7 +784,7 @@ void PlatformCALayer::setFilters(const FilterOperations& filters)
             
             // The CIHueAdjust value is in radians
             [caFilter setValue:[NSNumber numberWithFloat:op->amount() * M_PI * 2 / 360] forKey:@"inputAngle"];
-            [caFilter setName:@"hueRotateFilter"];
+            [caFilter setName:filterName];
             [array.get() addObject:caFilter];
             break;
         }
@@ -798,7 +800,7 @@ void PlatformCALayer::setFilters(const FilterOperations& filters)
             [caFilter setValue:[CIVector vectorWithX:0 Y:0 Z:multiplier W:0] forKey:@"inputBVector"];
             [caFilter setValue:[CIVector vectorWithX:0 Y:0 Z:0 W:1] forKey:@"inputAVector"];
             [caFilter setValue:[CIVector vectorWithX:op->amount() Y:op->amount() Z:op->amount() W:0] forKey:@"inputBiasVector"];
-            [caFilter setName:@"invertFilter"];
+            [caFilter setName:filterName];
             [array.get() addObject:caFilter];
             break;
         }
@@ -812,7 +814,7 @@ void PlatformCALayer::setFilters(const FilterOperations& filters)
             [caFilter setValue:[CIVector vectorWithX:0 Y:0 Z:1 W:0] forKey:@"inputBVector"];
             [caFilter setValue:[CIVector vectorWithX:0 Y:0 Z:0 W:op->amount()] forKey:@"inputAVector"];
             [caFilter setValue:[CIVector vectorWithX:0 Y:0 Z:0 W:0] forKey:@"inputBiasVector"];
-            [caFilter setName:@"opacityFilter"];
+            [caFilter setName:filterName];
             [array.get() addObject:caFilter];
             break;
         }
@@ -822,7 +824,25 @@ void PlatformCALayer::setFilters(const FilterOperations& filters)
             CIFilter* caFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
             [caFilter setDefaults];
             [caFilter setValue:[NSNumber numberWithFloat:op->stdDeviation().calcFloatValue(0)] forKey:@"inputRadius"];
-            [caFilter setName:@"blurFilter"];
+            [caFilter setName:filterName];
+            [array.get() addObject:caFilter];
+            break;
+        }
+        case FilterOperation::CONTRAST: {
+            const BasicComponentTransferFilterOperation* op = static_cast<const BasicComponentTransferFilterOperation*>(filterOperation);
+            CIFilter* caFilter = [CIFilter filterWithName:@"CIColorControls"];
+            [caFilter setDefaults];
+            [caFilter setValue:[NSNumber numberWithFloat:op->amount()] forKey:@"inputContrast"];
+            [caFilter setName:filterName];
+            [array.get() addObject:caFilter];
+            break;
+        }
+        case FilterOperation::BRIGHTNESS: {
+            const BasicComponentTransferFilterOperation* op = static_cast<const BasicComponentTransferFilterOperation*>(filterOperation);
+            CIFilter* caFilter = [CIFilter filterWithName:@"CIColorControls"];
+            [caFilter setDefaults];
+            [caFilter setValue:[NSNumber numberWithFloat:op->amount()] forKey:@"inputBrightness"];
+            [caFilter setName:filterName];
             [array.get() addObject:caFilter];
             break;
         }
@@ -850,9 +870,6 @@ bool PlatformCALayer::filtersCanBeComposited(const FilterOperations& filters)
         const FilterOperation* filterOperation = filters.at(i);
         switch(filterOperation->getOperationType()) {
         case FilterOperation::REFERENCE:
-        case FilterOperation::GRAYSCALE:
-        case FilterOperation::BRIGHTNESS:
-        case FilterOperation::CONTRAST:
 #if ENABLE(CSS_SHADERS)
         case FilterOperation::CUSTOM:
 #endif
index 43d48d1..cb20bc4 100644 (file)
@@ -216,7 +216,8 @@ void FilterEffectRenderer::build(Document* document, const FilterOperations& ope
             BasicComponentTransferFilterOperation* componentTransferOperation = static_cast<BasicComponentTransferFilterOperation*>(filterOperation);
             ComponentTransferFunction transferFunction;
             transferFunction.type = FECOMPONENTTRANSFER_TYPE_LINEAR;
-            transferFunction.slope = narrowPrecisionToFloat(componentTransferOperation->amount());
+            transferFunction.slope = 1;
+            transferFunction.intercept = narrowPrecisionToFloat(componentTransferOperation->amount());
 
             ComponentTransferFunction nullFunction;
             effect = FEComponentTransfer::create(this, transferFunction, transferFunction, transferFunction, nullFunction);