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
- trunk/LayoutTests/ChangeLog
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp
- trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.h
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)
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
