Title: [132522] trunk/Source/WebCore
Revision
132522
Author
[email protected]
Date
2012-10-25 13:09:01 -0700 (Thu, 25 Oct 2012)

Log Message

do not multiply/demultiply colors when alpha is 255
https://bugs.webkit.org/show_bug.cgi?id=89246

Patch by Arnaud Renevier <[email protected]> on 2012-10-25
Reviewed by Kenneth Rohde Christiansen.

Do not use colorFromPremultipliedARGB in getImageData nor
premultipliedARGBFromColor in putByteArray. Avoiding object creation
and function call make canvas.getImageData about 10% faster and
canvas.putImageData about 30% faster.

Also, we avoid multiplication/demultiplication computation when alpha
is 255. Result is the same, but when there is no transparency,
canvas.getImageData is about 4x faster, and canvas.putImageData is
about 2x faster.

No new tests. No change in behavior.

* platform/graphics/cairo/ImageBufferCairo.cpp:
(WebCore::getImageData):
(WebCore::ImageBuffer::putByteArray):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (132521 => 132522)


--- trunk/Source/WebCore/ChangeLog	2012-10-25 20:05:35 UTC (rev 132521)
+++ trunk/Source/WebCore/ChangeLog	2012-10-25 20:09:01 UTC (rev 132522)
@@ -1,3 +1,26 @@
+2012-10-25  Arnaud Renevier  <[email protected]>
+
+        do not multiply/demultiply colors when alpha is 255
+        https://bugs.webkit.org/show_bug.cgi?id=89246
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        Do not use colorFromPremultipliedARGB in getImageData nor
+        premultipliedARGBFromColor in putByteArray. Avoiding object creation
+        and function call make canvas.getImageData about 10% faster and
+        canvas.putImageData about 30% faster.
+
+        Also, we avoid multiplication/demultiplication computation when alpha
+        is 255. Result is the same, but when there is no transparency,
+        canvas.getImageData is about 4x faster, and canvas.putImageData is
+        about 2x faster.
+
+        No new tests. No change in behavior.
+
+        * platform/graphics/cairo/ImageBufferCairo.cpp:
+        (WebCore::getImageData):
+        (WebCore::ImageBuffer::putByteArray):
+
 2012-10-25  Nate Chapin  <[email protected]>
 
         Add a main resource type to the memory cache

Modified: trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp (132521 => 132522)


--- trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp	2012-10-25 20:05:35 UTC (rev 132521)
+++ trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp	2012-10-25 20:09:01 UTC (rev 132522)
@@ -175,15 +175,26 @@
         for (int x = 0; x < numColumns; x++) {
             int basex = x * 4;
             unsigned* pixel = row + x + originx;
-            Color pixelColor;
-            if (multiplied == Unmultiplied)
-                pixelColor = colorFromPremultipliedARGB(*pixel);
-            else
-                pixelColor = Color(*pixel);
-            destRows[basex]     = pixelColor.red();
-            destRows[basex + 1] = pixelColor.green();
-            destRows[basex + 2] = pixelColor.blue();
-            destRows[basex + 3] = pixelColor.alpha();
+
+            // Avoid calling Color::colorFromPremultipliedARGB() because one
+            // function call per pixel is too expensive.
+            unsigned alpha = (*pixel & 0xFF000000) >> 24;
+            unsigned red = (*pixel & 0x00FF0000) >> 16;
+            unsigned green = (*pixel & 0x0000FF00) >> 8;
+            unsigned blue = (*pixel & 0x000000FF);
+
+            if (multiplied == Unmultiplied) {
+                if (alpha && alpha != 255) {
+                    red = red * 255 / alpha;
+                    green = green * 255 / alpha;
+                    blue = blue * 255 / alpha;
+                }
+            }
+
+            destRows[basex]     = red;
+            destRows[basex + 1] = green;
+            destRows[basex + 2] = blue;
+            destRows[basex + 3] = alpha;
         }
         destRows += destBytesPerRow;
     }
@@ -242,14 +253,23 @@
         for (int x = 0; x < numColumns; x++) {
             int basex = x * 4;
             unsigned* pixel = row + x + destx;
-            Color pixelColor = Color::createUnCheked(srcRows[basex],
-                                                     srcRows[basex + 1],
-                                                     srcRows[basex + 2],
-                                                     srcRows[basex + 3]);
-            if (multiplied == Unmultiplied)
-                *pixel = premultipliedARGBFromColor(pixelColor);
-            else
-                *pixel = pixelColor.rgb();
+
+            // Avoid calling Color::premultipliedARGBFromColor() because one
+            // function call per pixel is too expensive.
+            unsigned red = srcRows[basex];
+            unsigned green = srcRows[basex + 1];
+            unsigned blue = srcRows[basex + 2];
+            unsigned alpha = srcRows[basex + 3];
+
+            if (multiplied == Unmultiplied) {
+                if (alpha && alpha != 255) {
+                    red = (red * alpha + 254) / 255;
+                    green = (green * alpha + 254) / 255;
+                    blue = (blue * alpha + 254) / 255;
+                }
+            }
+
+            *pixel = (alpha << 24) | red  << 16 | green  << 8 | blue;
         }
         srcRows += srcBytesPerRow;
     }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to