Title: [87009] trunk
Revision
87009
Author
[email protected]
Date
2011-05-20 21:20:27 -0700 (Fri, 20 May 2011)

Log Message

2011-05-20  Simon Fraser  <[email protected]>

        Reviewed by Dan Bernstein.

        Allow ShadowBlur to do tiling when the context is scaled
        https://bugs.webkit.org/show_bug.cgi?id=61232

        If the GraphicsContext is scaled or rotated by a multiple of 90deg, have ShadowBlur
        use the tiling code path, to avoid blurring large areas on pages like cracked.com
        when the context is scaled.

        * platform/graphics/ShadowBlur.cpp:
        (WebCore::ShadowBlur::drawRectShadow): Call preservesAxisAlignment()
        to decide when to not use tiling.
        (WebCore::ShadowBlur::drawInsetShadow): Ditto.
        (WebCore::ShadowBlur::drawLayerPieces): Round to device pixels when drawing tiles
        to avoid pixel cracks in scaled contexts.
        * platform/graphics/transforms/AffineTransform.h:
        (WebCore::AffineTransform::preservesAxisAlignment): Return true if there is the matrix
        contains a transform that results in axis alignment (no rotation or skew, or rotations
        which are multiples of 90deg).

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (87008 => 87009)


--- trunk/LayoutTests/ChangeLog	2011-05-21 01:15:40 UTC (rev 87008)
+++ trunk/LayoutTests/ChangeLog	2011-05-21 04:20:27 UTC (rev 87009)
@@ -1,3 +1,14 @@
+2011-05-20  Simon Fraser  <[email protected]>
+
+        Reviewed by Dan Bernstein.
+
+        Allow ShadowBlur to do tiling when the context is scaled
+        https://bugs.webkit.org/show_bug.cgi?id=61232
+
+        * fast/box-shadow/scaled-box-shadow.html: Added.
+        * platform/mac/fast/box-shadow/scaled-box-shadow-expected.png: Added.
+        * platform/mac/fast/box-shadow/scaled-box-shadow-expected.txt: Added.
+
 2011-05-20  Alexey Proskuryakov  <[email protected]>
 
         Reviewed by Kent Tamura.

Added: trunk/LayoutTests/fast/box-shadow/scaled-box-shadow.html (0 => 87009)


--- trunk/LayoutTests/fast/box-shadow/scaled-box-shadow.html	                        (rev 0)
+++ trunk/LayoutTests/fast/box-shadow/scaled-box-shadow.html	2011-05-21 04:20:27 UTC (rev 87009)
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style type="text/css" media="screen">
+    .wrapper {
+      width: 280px;
+      height: 280px;
+      -webkit-box-sizing: border-box;
+      padding: 40px;
+      margin: 4px;
+      display: inline-block;
+    }
+    
+    .box {
+      position: relative;
+      width: 100px;
+      height: 100px;
+      display: inline-block;
+      box-shadow: 0 0 23px black;
+      -webkit-transform-origin: top left;
+    }
+  </style>
+</head>
+<body>
+  <!-- You should not see any pixel cracks in the shadows -->
+  <div class="wrapper">
+    <div class="box" style="-webkit-transform: scale(0.63)"></div>
+  </div>
+
+  <div class="wrapper">
+    <div class="box" style="-webkit-transform: scale(0.97)"></div>
+  </div>
+  <br>
+
+  <div class="wrapper">
+    <div class="box" style="-webkit-transform: scale(1.234)"></div>
+  </div>
+
+  <div class="wrapper">
+    <div class="box" style="-webkit-transform: rotate(90deg) scale(1.377); -webkit-transform-origin: center;"></div>
+  </div>
+
+</body>
+</html>

Added: trunk/LayoutTests/platform/mac/fast/box-shadow/scaled-box-shadow-expected.png


(Binary files differ)
Property changes on: trunk/LayoutTests/platform/mac/fast/box-shadow/scaled-box-shadow-expected.png ___________________________________________________________________

Added: svn:mime-type

Added: trunk/LayoutTests/platform/mac/fast/box-shadow/scaled-box-shadow-expected.txt (0 => 87009)


--- trunk/LayoutTests/platform/mac/fast/box-shadow/scaled-box-shadow-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac/fast/box-shadow/scaled-box-shadow-expected.txt	2011-05-21 04:20:27 UTC (rev 87009)
@@ -0,0 +1,29 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x592
+  RenderBlock {HTML} at (0,0) size 800x592
+    RenderBody {BODY} at (8,8) size 784x576
+      RenderBlock {DIV} at (4,4) size 280x280
+        RenderText {#text} at (0,0) size 0x0
+      RenderText {#text} at (288,130) size 4x18
+        text run at (288,130) width 4: " "
+      RenderBlock {DIV} at (296,4) size 280x280
+        RenderText {#text} at (0,0) size 0x0
+      RenderText {#text} at (580,130) size 4x18
+        text run at (580,130) width 4: " "
+      RenderBR {BR} at (0,0) size 0x0
+      RenderBlock {DIV} at (4,292) size 280x280
+        RenderText {#text} at (0,0) size 0x0
+      RenderText {#text} at (288,418) size 4x18
+        text run at (288,418) width 4: " "
+      RenderBlock {DIV} at (296,292) size 280x280
+        RenderText {#text} at (0,0) size 0x0
+      RenderText {#text} at (0,0) size 0x0
+layer at (52,52) size 100x100
+  RenderBlock (relative positioned) {DIV} at (40,40) size 100x100
+layer at (344,52) size 100x100
+  RenderBlock (relative positioned) {DIV} at (40,40) size 100x100
+layer at (52,340) size 100x100
+  RenderBlock (relative positioned) {DIV} at (40,40) size 100x100
+layer at (344,340) size 100x100
+  RenderBlock (relative positioned) {DIV} at (40,40) size 100x100

Modified: trunk/Source/WebCore/ChangeLog (87008 => 87009)


--- trunk/Source/WebCore/ChangeLog	2011-05-21 01:15:40 UTC (rev 87008)
+++ trunk/Source/WebCore/ChangeLog	2011-05-21 04:20:27 UTC (rev 87009)
@@ -1,3 +1,25 @@
+2011-05-20  Simon Fraser  <[email protected]>
+
+        Reviewed by Dan Bernstein.
+
+        Allow ShadowBlur to do tiling when the context is scaled
+        https://bugs.webkit.org/show_bug.cgi?id=61232
+
+        If the GraphicsContext is scaled or rotated by a multiple of 90deg, have ShadowBlur
+        use the tiling code path, to avoid blurring large areas on pages like cracked.com
+        when the context is scaled.
+
+        * platform/graphics/ShadowBlur.cpp:
+        (WebCore::ShadowBlur::drawRectShadow): Call preservesAxisAlignment()
+        to decide when to not use tiling.
+        (WebCore::ShadowBlur::drawInsetShadow): Ditto.
+        (WebCore::ShadowBlur::drawLayerPieces): Round to device pixels when drawing tiles
+        to avoid pixel cracks in scaled contexts.
+        * platform/graphics/transforms/AffineTransform.h:
+        (WebCore::AffineTransform::preservesAxisAlignment): Return true if there is the matrix
+        contains a transform that results in axis alignment (no rotation or skew, or rotations
+        which are multiples of 90deg).
+
 2011-05-20  Alexey Proskuryakov  <[email protected]>
 
         Reviewed by Kent Tamura.

Modified: trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp (87008 => 87009)


--- trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp	2011-05-21 01:15:40 UTC (rev 87008)
+++ trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp	2011-05-21 04:20:27 UTC (rev 87009)
@@ -482,7 +482,7 @@
 
     // drawRectShadowWithTiling does not work with rotations.
     // https://bugs.webkit.org/show_bug.cgi?id=45042
-    if (!graphicsContext->getCTM().isIdentityOrTranslationOrFlipped() || m_type != BlurShadow) {
+    if (!graphicsContext->getCTM().preservesAxisAlignment() || m_type != BlurShadow) {
         drawRectShadowWithoutTiling(graphicsContext, shadowedRect, radii, layerRect);
         return;
     }
@@ -509,7 +509,7 @@
 
     // drawInsetShadowWithTiling does not work with rotations.
     // https://bugs.webkit.org/show_bug.cgi?id=45042
-    if (!graphicsContext->getCTM().isIdentityOrTranslationOrFlipped() || m_type != BlurShadow) {
+    if (!graphicsContext->getCTM().preservesAxisAlignment() || m_type != BlurShadow) {
         drawInsetShadowWithoutTiling(graphicsContext, rect, holeRect, holeRadii, layerRect);
         return;
     }
@@ -762,49 +762,51 @@
 
     // Note that drawing the ImageBuffer is faster than creating a Image and drawing that,
     // because ImageBuffer::draw() knows that it doesn't have to copy the image bits.
+    FloatRect centerRect(shadowBounds.x() + leftSlice, shadowBounds.y() + topSlice, centerWidth, centerHeight);
+    centerRect = graphicsContext->roundToDevicePixels(centerRect);
     
     // Top side.
     FloatRect tileRect = FloatRect(leftSlice, 0, templateSideLength, topSlice);
-    FloatRect destRect = FloatRect(shadowBounds.x() + leftSlice, shadowBounds.y(), centerWidth, topSlice);
+    FloatRect destRect = FloatRect(centerRect.x(), centerRect.y() - topSlice, centerRect.width(), topSlice);
     graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
 
     // Draw the bottom side.
     tileRect.setY(templateSize.height() - bottomSlice);
     tileRect.setHeight(bottomSlice);
-    destRect.setY(shadowBounds.maxY() - bottomSlice);
+    destRect.setY(centerRect.maxY());
     destRect.setHeight(bottomSlice);
     graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
 
     // Left side.
     tileRect = FloatRect(0, topSlice, leftSlice, templateSideLength);
-    destRect = FloatRect(shadowBounds.x(), shadowBounds.y() + topSlice, leftSlice, centerHeight);
+    destRect = FloatRect(centerRect.x() - leftSlice, centerRect.y(), leftSlice, centerRect.height());
     graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
 
     // Right side.
     tileRect.setX(templateSize.width() - rightSlice);
     tileRect.setWidth(rightSlice);
-    destRect.setX(shadowBounds.maxX() - rightSlice);
+    destRect.setX(centerRect.maxX());
     destRect.setWidth(rightSlice);
     graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
 
     // Top left corner.
     tileRect = FloatRect(0, 0, leftSlice, topSlice);
-    destRect = FloatRect(shadowBounds.x(), shadowBounds.y(), leftSlice, topSlice);
+    destRect = FloatRect(centerRect.x() - leftSlice, centerRect.y() - topSlice, leftSlice, topSlice);
     graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
 
     // Top right corner.
     tileRect = FloatRect(templateSize.width() - rightSlice, 0, rightSlice, topSlice);
-    destRect = FloatRect(shadowBounds.maxX() - rightSlice, shadowBounds.y(), rightSlice, topSlice);
+    destRect = FloatRect(centerRect.maxX(), centerRect.y() - topSlice, rightSlice, topSlice);
     graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
 
     // Bottom right corner.
     tileRect = FloatRect(templateSize.width() - rightSlice, templateSize.height() - bottomSlice, rightSlice, bottomSlice);
-    destRect = FloatRect(shadowBounds.maxX() - rightSlice, shadowBounds.maxY() - bottomSlice, rightSlice, bottomSlice);
+    destRect = FloatRect(centerRect.maxX(), centerRect.maxY(), rightSlice, bottomSlice);
     graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
 
     // Bottom left corner.
     tileRect = FloatRect(0, templateSize.height() - bottomSlice, leftSlice, bottomSlice);
-    destRect = FloatRect(shadowBounds.x(), shadowBounds.maxY() - bottomSlice, leftSlice, bottomSlice);
+    destRect = FloatRect(centerRect.x() - leftSlice, centerRect.maxY(), leftSlice, bottomSlice);
     graphicsContext->drawImageBuffer(m_layerImage, ColorSpaceDeviceRGB, destRect, tileRect);
 }
 

Modified: trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.h (87008 => 87009)


--- trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.h	2011-05-21 01:15:40 UTC (rev 87008)
+++ trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.h	2011-05-21 04:20:27 UTC (rev 87009)
@@ -131,6 +131,11 @@
         return m_transform[0] == 1 && m_transform[1] == 0 && m_transform[2] == 0 && (m_transform[3] == 1 || m_transform[3] == -1);
     }
 
+    bool preservesAxisAlignment() const
+    {
+        return (m_transform[1] == 0 && m_transform[2] == 0) || (m_transform[0] == 0 && m_transform[3] == 0);
+    }
+
     bool operator== (const AffineTransform& m2) const
     {
         return (m_transform[0] == m2.m_transform[0]
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to