Title: [159463] trunk/Source/WebCore
- Revision
- 159463
- Author
- [email protected]
- Date
- 2013-11-18 15:33:04 -0800 (Mon, 18 Nov 2013)
Log Message
At some scales, opaque compositing layers have garbage pixels around the edges
https://bugs.webkit.org/show_bug.cgi?id=124541
Reviewed by Dean Jackson.
Layers get marked as having opaque contents when their background is
known to paint the entire layer. However, this failed to take into
account two reasons why every pixel may not get painted.
First, subpixel layout can result in non-integral RenderLayer
bounds, which will get rounded up to an integral GraphicsLayer
size. When this happens we may not paint edge pixels.
Second, at non-integral scale factors, graphics context scaling
may cause us to not paint edge pixels.
Fix by only marking PlatformCALayers as having opaque contents
when the contentsScale of the layer is integral.
Not testable, because we can't guarantee to get garbage pixels
in a ref test, and layer dumps show GraphicsLayer's notion of
content opaqueness, not the one we set on the PlatformCALayer.
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::isIntegral):
(WebCore::clampedContentsScaleForScale):
(WebCore::GraphicsLayerCA::updateRootRelativeScale):
(WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers):
(WebCore::GraphicsLayerCA::updateContentsOpaque):
(WebCore::GraphicsLayerCA::getTransformFromAnimationsWithMaxScaleImpact):
Drive-by typo fix.
(WebCore::GraphicsLayerCA::noteChangesForScaleSensitiveProperties):
* platform/graphics/ca/GraphicsLayerCA.h:
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (159462 => 159463)
--- trunk/Source/WebCore/ChangeLog 2013-11-18 23:19:53 UTC (rev 159462)
+++ trunk/Source/WebCore/ChangeLog 2013-11-18 23:33:04 UTC (rev 159463)
@@ -1,3 +1,41 @@
+2013-11-18 Simon Fraser <[email protected]>
+
+ At some scales, opaque compositing layers have garbage pixels around the edges
+ https://bugs.webkit.org/show_bug.cgi?id=124541
+
+ Reviewed by Dean Jackson.
+
+ Layers get marked as having opaque contents when their background is
+ known to paint the entire layer. However, this failed to take into
+ account two reasons why every pixel may not get painted.
+
+ First, subpixel layout can result in non-integral RenderLayer
+ bounds, which will get rounded up to an integral GraphicsLayer
+ size. When this happens we may not paint edge pixels.
+
+ Second, at non-integral scale factors, graphics context scaling
+ may cause us to not paint edge pixels.
+
+ Fix by only marking PlatformCALayers as having opaque contents
+ when the contentsScale of the layer is integral.
+
+ Not testable, because we can't guarantee to get garbage pixels
+ in a ref test, and layer dumps show GraphicsLayer's notion of
+ content opaqueness, not the one we set on the PlatformCALayer.
+
+ * platform/graphics/ca/GraphicsLayerCA.cpp:
+ (WebCore::isIntegral):
+ (WebCore::clampedContentsScaleForScale):
+ (WebCore::GraphicsLayerCA::updateRootRelativeScale):
+ (WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers):
+ (WebCore::GraphicsLayerCA::updateContentsOpaque):
+ (WebCore::GraphicsLayerCA::getTransformFromAnimationsWithMaxScaleImpact):
+ Drive-by typo fix.
+ (WebCore::GraphicsLayerCA::noteChangesForScaleSensitiveProperties):
+ * platform/graphics/ca/GraphicsLayerCA.h:
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
+
2013-11-18 David Hyatt <[email protected]>
Add a quirk to not respect center text-align when positioning
Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp (159462 => 159463)
--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp 2013-11-18 23:19:53 UTC (rev 159462)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp 2013-11-18 23:33:04 UTC (rev 159463)
@@ -70,6 +70,20 @@
// of 250ms. So send a very small value instead.
static const float cAnimationAlmostZeroDuration = 1e-3f;
+static inline bool isIntegral(float value)
+{
+ return static_cast<int>(value) == value;
+}
+
+static float clampedContentsScaleForScale(float scale)
+{
+ // Define some limits as a sanity check for the incoming scale value
+ // those too small to see.
+ const float maxScale = 10.0f;
+ const float minScale = 0.01f;
+ return std::max(minScale, std::min(scale, maxScale));
+}
+
static bool isTransformTypeTransformationMatrix(TransformOperation::OperationType transformType)
{
switch (transformType) {
@@ -1118,7 +1132,7 @@
if (rootRelativeScaleFactor != m_rootRelativeScaleFactor) {
m_rootRelativeScaleFactor = rootRelativeScaleFactor;
- m_uncommittedChanges |= ContentsScaleChanged;
+ m_uncommittedChanges |= ContentsScaleChanged | ContentsOpaqueChanged;
}
}
@@ -1301,8 +1315,9 @@
if (m_uncommittedChanges & ContentsVisibilityChanged)
updateContentsVisibility();
+ // Note that contentsScale can affect whether the layer can be opaque.
if (m_uncommittedChanges & ContentsOpaqueChanged)
- updateContentsOpaque();
+ updateContentsOpaque(pageScaleFactor);
if (m_uncommittedChanges & BackfaceVisibilityChanged)
updateBackfaceVisibility();
@@ -1565,14 +1580,21 @@
}
}
-void GraphicsLayerCA::updateContentsOpaque()
+void GraphicsLayerCA::updateContentsOpaque(float pageScaleFactor)
{
- m_layer->setOpaque(m_contentsOpaque);
+ bool contentsOpaque = m_contentsOpaque;
+ if (contentsOpaque) {
+ float contentsScale = clampedContentsScaleForScale(m_rootRelativeScaleFactor * pageScaleFactor * deviceScaleFactor());
+ if (!isIntegral(contentsScale))
+ contentsOpaque = false;
+ }
+
+ m_layer->setOpaque(contentsOpaque);
if (LayerMap* layerCloneMap = m_layerClones.get()) {
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it)
- it->value->setOpaque(m_contentsOpaque);
+ it->value->setOpaque(contentsOpaque);
}
}
@@ -2303,12 +2325,12 @@
const Vector<TransformationMatrix>& matrices = it->value;
for (size_t i = 0; i < matrices.size(); ++i) {
- TransformationMatrix roootRelativeTransformWithAnimation = parentTransformFromRoot;
+ TransformationMatrix rootRelativeTransformWithAnimation = parentTransformFromRoot;
TransformationMatrix layerTransformWithAnimation = layerTransform(m_position, &matrices[i]);
- roootRelativeTransformWithAnimation.multiply(layerTransformWithAnimation);
+ rootRelativeTransformWithAnimation.multiply(layerTransformWithAnimation);
- float rootRelativeScale = maxScaleFromTransform(roootRelativeTransformWithAnimation);
+ float rootRelativeScale = maxScaleFromTransform(rootRelativeTransformWithAnimation);
if (rootRelativeScale > maxScale) {
maxScale = rootRelativeScale;
maxScaleTransform = matrices[i];
@@ -2813,15 +2835,6 @@
return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayerClones.get() : primaryLayerClones();
}
-static float clampedContentsScaleForScale(float scale)
-{
- // Define some limits as a sanity check for the incoming scale value
- // those too small to see.
- const float maxScale = 10.0f;
- const float minScale = 0.01f;
- return std::max(minScale, std::min(scale, maxScale));
-}
-
void GraphicsLayerCA::updateContentsScale(float pageScaleFactor)
{
float contentsScale = clampedContentsScaleForScale(m_rootRelativeScaleFactor * pageScaleFactor * deviceScaleFactor());
@@ -3272,14 +3285,9 @@
void GraphicsLayerCA::noteChangesForScaleSensitiveProperties()
{
- noteLayerPropertyChanged(GeometryChanged | ContentsScaleChanged);
+ noteLayerPropertyChanged(GeometryChanged | ContentsScaleChanged | ContentsOpaqueChanged);
}
-static inline bool isIntegral(float value)
-{
- return static_cast<int>(value) == value;
-}
-
void GraphicsLayerCA::computePixelAlignment(float pageScaleFactor, const FloatPoint& positionRelativeToBase,
FloatPoint& position, FloatSize& size, FloatPoint3D& anchorPoint, FloatSize& alignmentOffset) const
{
Modified: trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h (159462 => 159463)
--- trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h 2013-11-18 23:19:53 UTC (rev 159462)
+++ trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h 2013-11-18 23:33:04 UTC (rev 159463)
@@ -345,7 +345,7 @@
void updateChildrenTransform();
void updateMasksToBounds();
void updateContentsVisibility();
- void updateContentsOpaque();
+ void updateContentsOpaque(float pageScaleFactor);
void updateBackfaceVisibility();
void updateStructuralLayer();
void updateLayerDrawsContent();
Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (159462 => 159463)
--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2013-11-18 23:19:53 UTC (rev 159462)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2013-11-18 23:33:04 UTC (rev 159463)
@@ -706,7 +706,8 @@
if (!m_isMainFrameRenderViewLayer) {
// For non-root layers, background is always painted by the primary graphics layer.
ASSERT(!m_backgroundLayer);
- m_graphicsLayer->setContentsOpaque(m_owningLayer.backgroundIsKnownToBeOpaqueInRect(localCompositingBounds));
+ bool hadSubpixelRounding = LayoutSize(relativeCompositingBounds.size()) != localRawCompositingBounds.size();
+ m_graphicsLayer->setContentsOpaque(!hadSubpixelRounding && m_owningLayer.backgroundIsKnownToBeOpaqueInRect(localCompositingBounds));
}
// If we have a layer that clips children, position it.
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes