Title: [137500] trunk
Revision
137500
Author
[email protected]
Date
2012-12-12 12:19:12 -0800 (Wed, 12 Dec 2012)

Log Message

Use CAFilter rather than CIFilter
https://bugs.webkit.org/show_bug.cgi?id=104759

Reviewed by Tim Horton.

Source/WebCore:

In order to get better performance in the simple CSS filter
cases, use CAFilter rather than CIFilter. This involved
defining some platform-specific values inside
PlatformCALayerMac to expose CAFilter.

The great side-effect is that this brings our hardware
output much closer to our software filters. For example,
on a random location in the hue-rotate test.

Software: rgb(255, 148, 16)
Hardware before: rgb(255, 204, 50)
Hardware after: rgb(255, 165, 33)

Still some improvement needed, but better.

Covered by existing tests.

* platform/graphics/ca/mac/PlatformCALayerMac.mm:
(CAColorMatrix): New structure to hold 5x4 matrix representing a color operation.
(PlatformCALayer::setFilters): Use CAFilter objects rather than CIFilter.

LayoutTests:

Update the expected results. They are now much closer to the software case (on Mac).

* css3/filters/composited-reflected-expected.png:
* css3/filters/effect-blur-hw-expected.png:
* css3/filters/effect-brightness-hw-expected.png:
* css3/filters/effect-combined-hw-expected.png:
* css3/filters/effect-contrast-hw-expected.png:
* css3/filters/effect-drop-shadow-hw-expected.png:
* css3/filters/effect-grayscale-hw-expected.png:
* css3/filters/effect-hue-rotate-hw-expected.png:
* css3/filters/effect-invert-hw-expected.png:
* css3/filters/effect-opacity-hw-expected.png:
* css3/filters/effect-saturate-hw-expected.png:
* css3/filters/effect-sepia-hw-expected.png:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (137499 => 137500)


--- trunk/LayoutTests/ChangeLog	2012-12-12 20:14:31 UTC (rev 137499)
+++ trunk/LayoutTests/ChangeLog	2012-12-12 20:19:12 UTC (rev 137500)
@@ -1,3 +1,25 @@
+2012-12-12  Dean Jackson  <[email protected]>
+
+        Use CAFilter rather than CIFilter
+        https://bugs.webkit.org/show_bug.cgi?id=104759
+
+        Reviewed by Tim Horton.
+
+        Update the expected results. They are now much closer to the software case (on Mac).
+
+        * css3/filters/composited-reflected-expected.png:
+        * css3/filters/effect-blur-hw-expected.png:
+        * css3/filters/effect-brightness-hw-expected.png:
+        * css3/filters/effect-combined-hw-expected.png:
+        * css3/filters/effect-contrast-hw-expected.png:
+        * css3/filters/effect-drop-shadow-hw-expected.png:
+        * css3/filters/effect-grayscale-hw-expected.png:
+        * css3/filters/effect-hue-rotate-hw-expected.png:
+        * css3/filters/effect-invert-hw-expected.png:
+        * css3/filters/effect-opacity-hw-expected.png:
+        * css3/filters/effect-saturate-hw-expected.png:
+        * css3/filters/effect-sepia-hw-expected.png:
+
 2012-12-12  Adam Klein  <[email protected]>
 
         Mark the template inert contents test as flaky on cr-win as well.

Modified: trunk/LayoutTests/css3/filters/composited-reflected-expected.png


(Binary files differ)

Modified: trunk/LayoutTests/css3/filters/effect-blur-hw-expected.png


(Binary files differ)

Modified: trunk/LayoutTests/css3/filters/effect-brightness-hw-expected.png


(Binary files differ)

Modified: trunk/LayoutTests/css3/filters/effect-combined-hw-expected.png


(Binary files differ)

Modified: trunk/LayoutTests/css3/filters/effect-contrast-hw-expected.png


(Binary files differ)

Modified: trunk/LayoutTests/css3/filters/effect-drop-shadow-hw-expected.png


(Binary files differ)

Modified: trunk/LayoutTests/css3/filters/effect-grayscale-hw-expected.png


(Binary files differ)

Modified: trunk/LayoutTests/css3/filters/effect-hue-rotate-hw-expected.png


(Binary files differ)

Modified: trunk/LayoutTests/css3/filters/effect-invert-hw-expected.png


(Binary files differ)

Modified: trunk/LayoutTests/css3/filters/effect-opacity-hw-expected.png


(Binary files differ)

Modified: trunk/LayoutTests/css3/filters/effect-saturate-hw-expected.png


(Binary files differ)

Modified: trunk/LayoutTests/css3/filters/effect-sepia-hw-expected.png


(Binary files differ)

Modified: trunk/Source/WebCore/ChangeLog (137499 => 137500)


--- trunk/Source/WebCore/ChangeLog	2012-12-12 20:14:31 UTC (rev 137499)
+++ trunk/Source/WebCore/ChangeLog	2012-12-12 20:19:12 UTC (rev 137500)
@@ -1,3 +1,31 @@
+2012-12-12  Dean Jackson  <[email protected]>
+
+        Use CAFilter rather than CIFilter
+        https://bugs.webkit.org/show_bug.cgi?id=104759
+
+        Reviewed by Tim Horton.
+
+        In order to get better performance in the simple CSS filter
+        cases, use CAFilter rather than CIFilter. This involved
+        defining some platform-specific values inside
+        PlatformCALayerMac to expose CAFilter.
+
+        The great side-effect is that this brings our hardware
+        output much closer to our software filters. For example,
+        on a random location in the hue-rotate test.
+
+        Software: rgb(255, 148, 16)
+        Hardware before: rgb(255, 204, 50)
+        Hardware after: rgb(255, 165, 33)
+
+        Still some improvement needed, but better.
+
+        Covered by existing tests.
+
+        * platform/graphics/ca/mac/PlatformCALayerMac.mm:
+        (CAColorMatrix): New structure to hold 5x4 matrix representing a color operation.
+        (PlatformCALayer::setFilters): Use CAFilter objects rather than CIFilter.
+
 2012-12-12  No'am Rosenthal  <[email protected]>
 
         [Texmap] Consolidate redundant code for ARB_RECT texture

Modified: trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm (137499 => 137500)


--- trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm	2012-12-12 20:14:31 UTC (rev 137499)
+++ trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm	2012-12-12 20:19:12 UTC (rev 137500)
@@ -111,6 +111,34 @@
 #endif
 @end
 
+@interface CAFilter : NSObject <NSCopying, NSMutableCopying, NSCoding>
+@end
+
+@interface CAFilter (Details)
+@property(copy) NSString *name;
++ (CAFilter *)filterWithType:(NSString *)type;
+@end
+
+extern NSString * const kCAFilterColorMatrix;
+extern NSString * const kCAFilterColorMonochrome;
+extern NSString * const kCAFilterColorHueRotate;
+extern NSString * const kCAFilterColorSaturate;
+extern NSString * const kCAFilterGaussianBlur;
+
+struct CAColorMatrix
+{
+    float m11, m12, m13, m14, m15;
+    float m21, m22, m23, m24, m25;
+    float m31, m32, m33, m34, m35;
+    float m41, m42, m43, m44, m45;
+};
+
+typedef struct CAColorMatrix CAColorMatrix;
+
+@interface NSValue (Details)
++ (NSValue *)valueWithCAColorMatrix:(CAColorMatrix)t;
+@end
+
 static NSString * const platformCALayerPointer = @"WKPlatformCALayer";
 
 bool PlatformCALayer::isValueFunctionSupported()
@@ -690,7 +718,7 @@
         return;
     }
     
-    // Assume filtersCanBeComposited was called and it returned true
+    // Assume filtersCanBeComposited was called and it returned true.
     ASSERT(filtersCanBeComposited(filters));
     
     BEGIN_BLOCK_OBJC_EXCEPTIONS
@@ -699,11 +727,11 @@
     
     for (unsigned i = 0; i < filters.size(); ++i) {
         String filterName = String::format("filter_%d", i);
-        
         const FilterOperation* filterOperation = filters.at(i);
-        switch(filterOperation->getOperationType()) {
+        switch (filterOperation->getOperationType()) {
         case FilterOperation::DROP_SHADOW: {
-            // FIXME: For now assume drop shadow is the last filter, put it on the layer
+            // FIXME: For now assume drop shadow is the last filter, put it on the layer.
+            // <rdar://problem/10959969> Handle case where drop-shadow is not the last filter.
             const DropShadowFilterOperation* op = static_cast<const DropShadowFilterOperation*>(filterOperation);
             [m_layer.get() setShadowOffset:CGSizeMake(op->x(), op->y())];
 
@@ -712,94 +740,92 @@
             RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
             RetainPtr<CGColorRef> color(AdoptCF, CGColorCreate(colorSpace.get(), components));
             [m_layer.get() setShadowColor:color.get()];
-            
             [m_layer.get() setShadowRadius:op->stdDeviation()];
             [m_layer.get() setShadowOpacity:1];
             break;
         }
         case FilterOperation::GRAYSCALE: {
             const BasicColorMatrixFilterOperation* op = static_cast<const BasicColorMatrixFilterOperation*>(filterOperation);
-            CIFilter* caFilter = [CIFilter filterWithName:@"CIColorMonochrome"];
-            [caFilter setDefaults];
-            [caFilter setValue:[NSNumber numberWithFloat:op->amount()] forKey:@"inputIntensity"];
-            [caFilter setValue:[CIColor colorWithRed:1 green:1 blue:1] forKey:@"inputColor"];
+            CAFilter *caFilter = [CAFilter filterWithType:kCAFilterColorMonochrome];
+            [caFilter setValue:[NSNumber numberWithFloat:op->amount()] forKey:@"inputAmount"];
             [caFilter setName:filterName];
             [array.get() addObject:caFilter];
             break;
         }
         case FilterOperation::SEPIA: {
             const BasicColorMatrixFilterOperation* op = static_cast<const BasicColorMatrixFilterOperation*>(filterOperation);
-            CIFilter* caFilter = [CIFilter filterWithName:@"CIColorMatrix"];
-            [caFilter setDefaults];
+            CAFilter *caFilter = [CAFilter filterWithType:kCAFilterColorMatrix];
             
             double t = op->amount();
             t = min(max(0.0, t), 1.0);
 
-            // FIXME: Should put these values into constants (https://bugs.webkit.org/show_bug.cgi?id=76008)
-            [caFilter setValue:[CIVector vectorWithX:WebCore::blend(1.0, 0.393, t) Y:WebCore::blend(0.0, 0.769, t) Z:WebCore::blend(0.0, 0.189, t) W:0] forKey:@"inputRVector"];
-            [caFilter setValue:[CIVector vectorWithX:WebCore::blend(0.0, 0.349, t) Y:WebCore::blend(1.0, 0.686, t) Z:WebCore::blend(0.0, 0.168, t) W:0] forKey:@"inputGVector"];
-            [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"];
+            // FIXME: Should put these values into constants (https://bugs.webkit.org/show_bug.cgi?id=76008).
+            CAColorMatrix sepiaMatrix = {
+                static_cast<float>(WebCore::blend(1.0, 0.393, t)), static_cast<float>(WebCore::blend(0.0, 0.769, t)), static_cast<float>(WebCore::blend(0.0, 0.189, t)), 0, 0,
+                static_cast<float>(WebCore::blend(0.0, 0.349, t)), static_cast<float>(WebCore::blend(1.0, 0.686, t)), static_cast<float>(WebCore::blend(0.0, 0.168, t)), 0, 0,
+                static_cast<float>(WebCore::blend(0.0, 0.272, t)), static_cast<float>(WebCore::blend(0.0, 0.534, t)), static_cast<float>(WebCore::blend(1.0, 0.131, t)), 0, 0,
+                0, 0, 0, 1, 0
+            };
+
+            [caFilter setValue:[NSValue valueWithCAColorMatrix:sepiaMatrix] forKey:@"inputColorMatrix"];
             [caFilter setName:filterName];
             [array.get() addObject:caFilter];
             break;
         }
         case FilterOperation::SATURATE: {
             const BasicColorMatrixFilterOperation* op = static_cast<const BasicColorMatrixFilterOperation*>(filterOperation);
-            CIFilter* caFilter = [CIFilter filterWithName:@"CIColorControls"];
-            [caFilter setDefaults];
-            [caFilter setValue:[NSNumber numberWithFloat:op->amount()] forKey:@"inputSaturation"];
+            CAFilter *caFilter = [CAFilter filterWithType:kCAFilterColorSaturate];
+            [caFilter setValue:[NSNumber numberWithFloat:op->amount()] forKey:@"inputAmount"];
             [caFilter setName:filterName];
             [array.get() addObject:caFilter];
             break;
         }
         case FilterOperation::HUE_ROTATE: {
             const BasicColorMatrixFilterOperation* op = static_cast<const BasicColorMatrixFilterOperation*>(filterOperation);
-            CIFilter* caFilter = [CIFilter filterWithName:@"CIHueAdjust"];
-            [caFilter setDefaults];
-            
-            // The CIHueAdjust value is in radians
+            CAFilter *caFilter = [CAFilter filterWithType:kCAFilterColorHueRotate];
             [caFilter setValue:[NSNumber numberWithFloat:deg2rad(op->amount())] forKey:@"inputAngle"];
+            [caFilter setName:@"hueRotate"];
             [caFilter setName:filterName];
             [array.get() addObject:caFilter];
             break;
         }
         case FilterOperation::INVERT: {
             const BasicComponentTransferFilterOperation* op = static_cast<const BasicComponentTransferFilterOperation*>(filterOperation);
-            CIFilter* caFilter = [CIFilter filterWithName:@"CIColorMatrix"];
-            [caFilter setDefaults];
-            
-            double multiplier = 1 - op->amount() * 2;
-            
-            [caFilter setValue:[CIVector vectorWithX:multiplier Y:0 Z:0 W:0] forKey:@"inputRVector"];
-            [caFilter setValue:[CIVector vectorWithX:0 Y:multiplier Z:0 W:0] forKey:@"inputGVector"];
-            [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 *caFilter = [CAFilter filterWithType:kCAFilterColorMatrix];
+
+            float multiplier = 1 - op->amount() * 2;
+
+            CAColorMatrix invertMatrix = {
+                multiplier, 0, 0, 0, static_cast<float>(op->amount()),
+                0, multiplier, 0, 0, static_cast<float>(op->amount()),
+                0, 0, multiplier, 0, static_cast<float>(op->amount()),
+                0, 0, 0, 1, 0
+            };
+
+            [caFilter setValue:[NSValue valueWithCAColorMatrix:invertMatrix] forKey:@"inputColorMatrix"];
             [caFilter setName:filterName];
             [array.get() addObject:caFilter];
             break;
         }
         case FilterOperation::OPACITY: {
             const BasicComponentTransferFilterOperation* op = static_cast<const BasicComponentTransferFilterOperation*>(filterOperation);
-            CIFilter* caFilter = [CIFilter filterWithName:@"CIColorMatrix"];
-            [caFilter setDefaults];
-            
-            [caFilter setValue:[CIVector vectorWithX:1 Y:0 Z:0 W:0] forKey:@"inputRVector"];
-            [caFilter setValue:[CIVector vectorWithX:0 Y:1 Z:0 W:0] forKey:@"inputGVector"];
-            [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 *caFilter = [CAFilter filterWithType:kCAFilterColorMatrix];
+
+            CAColorMatrix opacityMatrix = {
+                1, 0, 0, 0, 0,
+                0, 1, 0, 0, 0,
+                0, 0, 1, 0, 0,
+                0, 0, 0, static_cast<float>(op->amount()), 0
+            };
+
+            [caFilter setValue:[NSValue valueWithCAColorMatrix:opacityMatrix] forKey:@"inputColorMatrix"];
             [caFilter setName:filterName];
             [array.get() addObject:caFilter];
             break;
         }
         case FilterOperation::BLUR: {
-            // FIXME: For now we ignore stdDeviationY
             const BlurFilterOperation* op = static_cast<const BlurFilterOperation*>(filterOperation);
-            CIFilter* caFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
-            [caFilter setDefaults];
+            CAFilter *caFilter = [CAFilter filterWithType:kCAFilterGaussianBlur];
             [caFilter setValue:[NSNumber numberWithFloat:floatValueForLength(op->stdDeviation(), 0)] forKey:@"inputRadius"];
             [caFilter setName:filterName];
             [array.get() addObject:caFilter];
@@ -807,21 +833,38 @@
         }
         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 *caFilter = [CAFilter filterWithType:kCAFilterColorMatrix];
+
+            float intercept = -0.5 * op->amount() + 0.5;
+
+            CAColorMatrix contrastMatrix = {
+                static_cast<float>(op->amount()), 0, 0, 0, intercept,
+                0, static_cast<float>(op->amount()), 0, 0, intercept,
+                0, 0, static_cast<float>(op->amount()), 0, intercept,
+                0, 0, 0, 1, 0
+            };
+
+            [caFilter setValue:[NSValue valueWithCAColorMatrix:contrastMatrix] forKey:@"inputColorMatrix"];
             [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 *caFilter = [CAFilter filterWithType:kCAFilterColorMatrix];
+            
+            CAColorMatrix brightnessMatrix = {
+                1, 0, 0, 0, static_cast<float>(op->amount()),
+                0, 1, 0, 0, static_cast<float>(op->amount()),
+                0, 0, 1, 0, static_cast<float>(op->amount()),
+                0, 0, 0, 1, 0
+            };
+
+            [caFilter setValue:[NSValue valueWithCAColorMatrix:brightnessMatrix] forKey:@"inputColorMatrix"];
             [caFilter setName:filterName];
             [array.get() addObject:caFilter];
             break;
+            break;
         }
         case FilterOperation::PASSTHROUGH:
             break;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to