Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp

Issue 2172503002: Fix subpixel accumulation for composited content layers Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add test expectation Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved. 2 * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 #include "wtf/CurrentTime.h" 72 #include "wtf/CurrentTime.h"
73 #include "wtf/text/StringBuilder.h" 73 #include "wtf/text/StringBuilder.h"
74 #include <memory> 74 #include <memory>
75 75
76 namespace blink { 76 namespace blink {
77 77
78 using namespace HTMLNames; 78 using namespace HTMLNames;
79 79
80 static IntRect clipBox(LayoutBox* layoutObject); 80 static IntRect clipBox(LayoutBox* layoutObject);
81 81
82 static IntRect contentsRect(const LayoutObject* layoutObject) 82 static LayoutRect contentsRect(const LayoutObject* layoutObject)
83 { 83 {
84 if (!layoutObject->isBox()) 84 if (!layoutObject->isBox())
85 return IntRect(); 85 return LayoutRect();
86 if (layoutObject->isCanvas()) 86 if (layoutObject->isCanvas())
87 return pixelSnappedIntRect(toLayoutHTMLCanvas(layoutObject)->replacedCon tentRect()); 87 return toLayoutHTMLCanvas(layoutObject)->replacedContentRect();
88 if (layoutObject->isVideo()) 88 if (layoutObject->isVideo())
89 return toLayoutVideo(layoutObject)->videoBox(); 89 return toLayoutVideo(layoutObject)->videoBox();
90 90
91 return pixelSnappedIntRect(toLayoutBox(layoutObject)->contentBoxRect()); 91 if (layoutObject->isLayoutPart()) {
92 const LayoutPart* layoutPart = toLayoutPart(layoutObject);
93 // FrameView are somehow pre-snapped. This is to match behavior of Layou tPart::updateWidgetGeometry().
chrishtr 2016/07/21 18:02:31 PartPainter::paintContents does rounded snapping t
94 if (layoutPart->widget() && layoutPart->widget()->isFrameView()) {
95 LayoutRect contentBoxRect = layoutPart->contentBoxRect();
96 return LayoutRect(contentBoxRect.location(), LayoutSize(roundedIntSi ze(contentBoxRect.size())));
97 }
98 }
99
100 return toLayoutBox(layoutObject)->contentBoxRect();
92 } 101 }
93 102
94 static IntRect backgroundRect(const LayoutObject* layoutObject) 103 static LayoutRect backgroundRect(const LayoutObject* layoutObject)
95 { 104 {
96 if (!layoutObject->isBox()) 105 if (!layoutObject->isBox())
97 return IntRect(); 106 return LayoutRect();
98 107
99 LayoutRect rect; 108 LayoutRect rect;
100 const LayoutBox* box = toLayoutBox(layoutObject); 109 const LayoutBox* box = toLayoutBox(layoutObject);
101 EFillBox clip = box->style()->backgroundClip(); 110 EFillBox clip = box->style()->backgroundClip();
102 switch (clip) { 111 switch (clip) {
103 case BorderFillBox: 112 case BorderFillBox:
104 rect = box->borderBoxRect(); 113 rect = box->borderBoxRect();
105 break; 114 break;
106 case PaddingFillBox: 115 case PaddingFillBox:
107 rect = box->paddingBoxRect(); 116 rect = box->paddingBoxRect();
108 break; 117 break;
109 case ContentFillBox: 118 case ContentFillBox:
110 rect = box->contentBoxRect(); 119 rect = box->contentBoxRect();
111 break; 120 break;
112 case TextFillBox: 121 case TextFillBox:
113 break; 122 break;
114 } 123 }
115 124
116 return pixelSnappedIntRect(rect); 125 return rect;
117 } 126 }
118 127
119 static inline bool isAcceleratedCanvas(const LayoutObject* layoutObject) 128 static inline bool isAcceleratedCanvas(const LayoutObject* layoutObject)
120 { 129 {
121 if (layoutObject->isCanvas()) { 130 if (layoutObject->isCanvas()) {
122 HTMLCanvasElement* canvas = toHTMLCanvasElement(layoutObject->node()); 131 HTMLCanvasElement* canvas = toHTMLCanvasElement(layoutObject->node());
123 if (CanvasRenderingContext* context = canvas->renderingContext()) 132 if (CanvasRenderingContext* context = canvas->renderingContext())
124 return context->isAccelerated(); 133 return context->isAccelerated();
125 } 134 }
126 return false; 135 return false;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 185
177 // Get the scrolling coordinator in a way that works inside CompositedLayerMappi ng's destructor. 186 // Get the scrolling coordinator in a way that works inside CompositedLayerMappi ng's destructor.
178 static ScrollingCoordinator* scrollingCoordinatorFromLayer(PaintLayer& layer) 187 static ScrollingCoordinator* scrollingCoordinatorFromLayer(PaintLayer& layer)
179 { 188 {
180 Page* page = layer.layoutObject()->frame()->page(); 189 Page* page = layer.layoutObject()->frame()->page();
181 return (!page) ? nullptr : page->scrollingCoordinator(); 190 return (!page) ? nullptr : page->scrollingCoordinator();
182 } 191 }
183 192
184 CompositedLayerMapping::CompositedLayerMapping(PaintLayer& layer) 193 CompositedLayerMapping::CompositedLayerMapping(PaintLayer& layer)
185 : m_owningLayer(layer) 194 : m_owningLayer(layer)
186 , m_contentOffsetInCompositingLayerDirty(false)
187 , m_pendingUpdateScope(GraphicsLayerUpdateNone) 195 , m_pendingUpdateScope(GraphicsLayerUpdateNone)
188 , m_isMainFrameLayoutViewLayer(false) 196 , m_isMainFrameLayoutViewLayer(false)
189 , m_backgroundLayerPaintsFixedRootBackground(false) 197 , m_backgroundLayerPaintsFixedRootBackground(false)
190 , m_scrollingContentsAreEmpty(false) 198 , m_scrollingContentsAreEmpty(false)
191 { 199 {
192 if (layer.isRootLayer() && layoutObject()->frame()->isMainFrame()) 200 if (layer.isRootLayer() && layoutObject()->frame()->isMainFrame())
193 m_isMainFrameLayoutViewLayer = true; 201 m_isMainFrameLayoutViewLayer = true;
194 202
195 createPrimaryGraphicsLayer(); 203 createPrimaryGraphicsLayer();
196 } 204 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 // For non-root layers, background is always painted by the primary grap hics layer. 335 // For non-root layers, background is always painted by the primary grap hics layer.
328 m_graphicsLayer->setContentsOpaque(m_owningLayer.backgroundIsKnownToBeOp aqueInRect(compositedBounds())); 336 m_graphicsLayer->setContentsOpaque(m_owningLayer.backgroundIsKnownToBeOp aqueInRect(compositedBounds()));
329 } 337 }
330 } 338 }
331 339
332 void CompositedLayerMapping::updateCompositedBounds() 340 void CompositedLayerMapping::updateCompositedBounds()
333 { 341 {
334 ASSERT(m_owningLayer.compositor()->lifecycle().state() == DocumentLifecycle: :InCompositingUpdate); 342 ASSERT(m_owningLayer.compositor()->lifecycle().state() == DocumentLifecycle: :InCompositingUpdate);
335 // FIXME: if this is really needed for performance, it would be better to st ore it on Layer. 343 // FIXME: if this is really needed for performance, it would be better to st ore it on Layer.
336 m_compositedBounds = m_owningLayer.boundingBoxForCompositing(); 344 m_compositedBounds = m_owningLayer.boundingBoxForCompositing();
337 m_contentOffsetInCompositingLayerDirty = true;
338 } 345 }
339 346
340 void CompositedLayerMapping::updateAfterPartResize() 347 void CompositedLayerMapping::updateAfterPartResize()
341 { 348 {
342 if (layoutObject()->isLayoutPart()) { 349 if (layoutObject()->isLayoutPart()) {
343 if (PaintLayerCompositor* innerCompositor = PaintLayerCompositor::frameC ontentsCompositor(toLayoutPart(layoutObject()))) { 350 if (PaintLayerCompositor* innerCompositor = PaintLayerCompositor::frameC ontentsCompositor(toLayoutPart(layoutObject()))) {
344 innerCompositor->frameViewDidChangeSize(); 351 innerCompositor->frameViewDidChangeSize();
345 // We can floor this point because our frameviews are always aligned to pixel boundaries. 352 // We can floor this point because our frameviews are always aligned to pixel boundaries.
346 ASSERT(m_compositedBounds.location() == flooredIntPoint(m_composited Bounds.location())); 353 ASSERT(m_compositedBounds.location() == flooredIntPoint(m_composited Bounds.location()));
347 innerCompositor->frameViewDidChangeLocation(flooredIntPoint(contents Box().location())); 354 innerCompositor->frameViewDidChangeLocation(roundedIntPoint(contents Box().location()));
chrishtr 2016/07/21 18:02:31 Yet another instance of frame rounding to be refac
348 } 355 }
349 } 356 }
350 } 357 }
351 358
352 void CompositedLayerMapping::updateCompositingReasons() 359 void CompositedLayerMapping::updateCompositingReasons()
353 { 360 {
354 // All other layers owned by this mapping will have the same compositing rea son 361 // All other layers owned by this mapping will have the same compositing rea son
355 // for their lifetime, so they are initialized only when created. 362 // for their lifetime, so they are initialized only when created.
356 m_graphicsLayer->setCompositingReasons(m_owningLayer.getCompositingReasons() ); 363 m_graphicsLayer->setCompositingReasons(m_owningLayer.getCompositingReasons() );
357 m_graphicsLayer->setSquashingDisallowedReasons(m_owningLayer.getSquashingDis allowedReasons()); 364 m_graphicsLayer->setSquashingDisallowedReasons(m_owningLayer.getSquashingDis allowedReasons());
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 IntPoint graphicsLayerParentLocation; 747 IntPoint graphicsLayerParentLocation;
741 computeGraphicsLayerParentLocation(compositingContainer, ancestorCompositing Bounds, graphicsLayerParentLocation); 748 computeGraphicsLayerParentLocation(compositingContainer, ancestorCompositing Bounds, graphicsLayerParentLocation);
742 749
743 // Might update graphicsLayerParentLocation. 750 // Might update graphicsLayerParentLocation.
744 updateAncestorClippingLayerGeometry(compositingContainer, snappedOffsetFromC ompositedAncestor, graphicsLayerParentLocation); 751 updateAncestorClippingLayerGeometry(compositingContainer, snappedOffsetFromC ompositedAncestor, graphicsLayerParentLocation);
745 752
746 FloatSize contentsSize(relativeCompositingBounds.size()); 753 FloatSize contentsSize(relativeCompositingBounds.size());
747 754
748 updateMainGraphicsLayerGeometry(relativeCompositingBounds, localCompositingB ounds, graphicsLayerParentLocation); 755 updateMainGraphicsLayerGeometry(relativeCompositingBounds, localCompositingB ounds, graphicsLayerParentLocation);
749 updateOverflowControlsHostLayerGeometry(compositingStackingContext, composit ingContainer); 756 updateOverflowControlsHostLayerGeometry(compositingStackingContext, composit ingContainer);
750 updateContentsOffsetInCompositingLayer(snappedOffsetFromCompositedAncestor, graphicsLayerParentLocation);
751 updateSquashingLayerGeometry(graphicsLayerParentLocation, compositingContain er, m_squashedLayers, m_squashingLayer.get(), &m_squashingLayerOffsetFromTransfo rmedAncestor, layersNeedingPaintInvalidation); 757 updateSquashingLayerGeometry(graphicsLayerParentLocation, compositingContain er, m_squashedLayers, m_squashingLayer.get(), &m_squashingLayerOffsetFromTransfo rmedAncestor, layersNeedingPaintInvalidation);
752 758
753 // If we have a layer that clips children, position it. 759 // If we have a layer that clips children, position it.
754 IntRect clippingBox; 760 IntRect clippingBox;
755 if (m_childContainmentLayer) 761 if (m_childContainmentLayer)
756 clippingBox = clipBox(toLayoutBox(layoutObject())); 762 clippingBox = clipBox(toLayoutBox(layoutObject()));
757 763
758 updateChildTransformLayerGeometry(); 764 updateChildTransformLayerGeometry();
759 updateChildContainmentLayerGeometry(clippingBox, localCompositingBounds); 765 updateChildContainmentLayerGeometry(clippingBox, localCompositingBounds);
760 766
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 if (m_childClippingMaskLayer && !m_scrollingLayer && !layoutObject()->style( )->clipPath()) { 922 if (m_childClippingMaskLayer && !m_scrollingLayer && !layoutObject()->style( )->clipPath()) {
917 m_childClippingMaskLayer->setSize(m_childContainmentLayer->size()); 923 m_childClippingMaskLayer->setSize(m_childContainmentLayer->size());
918 m_childClippingMaskLayer->setOffsetFromLayoutObject(m_childContainmentLa yer->offsetFromLayoutObject()); 924 m_childClippingMaskLayer->setOffsetFromLayoutObject(m_childContainmentLa yer->offsetFromLayoutObject());
919 } 925 }
920 } 926 }
921 927
922 void CompositedLayerMapping::updateChildTransformLayerGeometry() 928 void CompositedLayerMapping::updateChildTransformLayerGeometry()
923 { 929 {
924 if (!m_childTransformLayer) 930 if (!m_childTransformLayer)
925 return; 931 return;
926 const IntRect borderBox = toLayoutBox(m_owningLayer.layoutObject())->pixelSn appedBorderBoxRect(); 932 LayoutRect borderBox = toLayoutBox(m_owningLayer.layoutObject())->borderBoxR ect();
927 m_childTransformLayer->setSize(FloatSize(borderBox.size())); 933 borderBox.move(contentOffsetInCompositingLayer());
928 m_childTransformLayer->setPosition(FloatPoint(contentOffsetInCompositingLaye r())); 934 IntRect pixelSnappedBorderBox = pixelSnappedIntRect(borderBox);
935
936 m_childTransformLayer->setSize(FloatSize(pixelSnappedBorderBox.size()));
937 m_childTransformLayer->setPosition(FloatPoint(pixelSnappedBorderBox.location ()));
929 } 938 }
930 939
931 void CompositedLayerMapping::updateMaskLayerGeometry() 940 void CompositedLayerMapping::updateMaskLayerGeometry()
932 { 941 {
933 if (!m_maskLayer) 942 if (!m_maskLayer)
934 return; 943 return;
935 944
936 if (m_maskLayer->size() != m_graphicsLayer->size()) { 945 if (m_maskLayer->size() != m_graphicsLayer->size()) {
937 m_maskLayer->setSize(m_graphicsLayer->size()); 946 m_maskLayer->setSize(m_graphicsLayer->size());
938 m_maskLayer->setNeedsDisplay(); 947 m_maskLayer->setNeedsDisplay();
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 paintPhase |= GraphicsLayerPaintOverflowContents; 1193 paintPhase |= GraphicsLayerPaintOverflowContents;
1185 m_foregroundLayer->setPaintingPhase(paintPhase); 1194 m_foregroundLayer->setPaintingPhase(paintPhase);
1186 } 1195 }
1187 } 1196 }
1188 1197
1189 void CompositedLayerMapping::updateContentsRect() 1198 void CompositedLayerMapping::updateContentsRect()
1190 { 1199 {
1191 m_graphicsLayer->setContentsRect(pixelSnappedIntRect(contentsBox())); 1200 m_graphicsLayer->setContentsRect(pixelSnappedIntRect(contentsBox()));
1192 } 1201 }
1193 1202
1194 void CompositedLayerMapping::updateContentsOffsetInCompositingLayer(const IntPoi nt& snappedOffsetFromCompositedAncestor, const IntPoint& graphicsLayerParentLoca tion)
1195 {
1196 // m_graphicsLayer is positioned relative to our compositing ancestor
1197 // PaintLayer, but it's not positioned at the origin of m_owningLayer, it's
1198 // offset by m_contentBounds.location(). This is what
1199 // contentOffsetInCompositingLayer is meant to capture, roughly speaking
1200 // (ignoring rounding and subpixel accumulation).
1201 //
1202 // Our ancestor graphics layers in this CLM (m_graphicsLayer and potentially
1203 // m_ancestorClippingLayer) have pixel snapped, so if we don't adjust this
1204 // offset, we'll see accumulated rounding errors due to that snapping.
1205 //
1206 // In order to ensure that we account for this rounding, we compute
1207 // contentsOffsetInCompositingLayer in a somewhat roundabout way.
1208 //
1209 // our position = (desired position) - (inherited graphics layer offset).
1210 //
1211 // Precisely,
1212 // Offset = snappedOffsetFromCompositedAncestor - offsetDueToAncestorGraphic sLayers (See code below)
1213 // = snappedOffsetFromCompositedAncestor - (m_graphicsLayer->position() + graphicsLayerParentLocation)
1214 // = snappedOffsetFromCompositedAncestor - (relativeCompositingBounds.l ocation() - graphicsLayerParentLocation + graphicsLayerParentLocation) (See upda teMainGraphicsLayerGeometry)
1215 // = snappedOffsetFromCompositedAncestor - relativeCompositingBounds.lo cation()
1216 // = snappedOffsetFromCompositedAncestor - (pixelSnappedIntRect(content Bounds.location()) + snappedOffsetFromCompositedAncestor) (See computeBoundsOfOw ningLayer)
1217 // = -pixelSnappedIntRect(contentBounds.location())
1218 //
1219 // As you can see, we've ended up at the same spot (-contentBounds.location( )),
1220 // but by subtracting off our ancestor graphics layers positions, we can be
1221 // sure we've accounted correctly for any pixel snapping due to ancestor
1222 // graphics layers.
1223 //
1224 // And drawing of composited children takes into account the subpixel
1225 // accumulation of this CLM already (through its own
1226 // graphicsLayerParentLocation it appears).
1227 FloatPoint offsetDueToAncestorGraphicsLayers = m_graphicsLayer->position() + graphicsLayerParentLocation;
1228 m_contentOffsetInCompositingLayer = LayoutSize(snappedOffsetFromCompositedAn cestor - offsetDueToAncestorGraphicsLayers);
1229 m_contentOffsetInCompositingLayerDirty = false;
1230 }
1231
1232 void CompositedLayerMapping::updateDrawsContent() 1203 void CompositedLayerMapping::updateDrawsContent()
1233 { 1204 {
1234 bool inOverlayFullscreenVideo = false; 1205 bool inOverlayFullscreenVideo = false;
1235 if (layoutObject()->isVideo()) { 1206 if (layoutObject()->isVideo()) {
1236 HTMLVideoElement* videoElement = toHTMLVideoElement(layoutObject()->node ()); 1207 HTMLVideoElement* videoElement = toHTMLVideoElement(layoutObject()->node ());
1237 if (videoElement->isFullscreen() && videoElement->usesOverlayFullscreenV ideo()) 1208 if (videoElement->isFullscreen() && videoElement->usesOverlayFullscreenV ideo())
1238 inOverlayFullscreenVideo = true; 1209 inOverlayFullscreenVideo = true;
1239 } 1210 }
1240 bool hasPaintedContent = inOverlayFullscreenVideo ? false : containsPaintedC ontent(); 1211 bool hasPaintedContent = inOverlayFullscreenVideo ? false : containsPaintedC ontent();
1241 m_graphicsLayer->setDrawsContent(hasPaintedContent); 1212 m_graphicsLayer->setDrawsContent(hasPaintedContent);
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after
2007 origin.setY(floatValueForLength(style.transformOriginY(), borderBox.height() )); 1978 origin.setY(floatValueForLength(style.transformOriginY(), borderBox.height() ));
2008 origin.setZ(style.transformOriginZ()); 1979 origin.setZ(style.transformOriginZ());
2009 1980
2010 return origin; 1981 return origin;
2011 } 1982 }
2012 1983
2013 // Return the offset from the top-left of this compositing layer at which the 1984 // Return the offset from the top-left of this compositing layer at which the
2014 // LayoutObject's contents are painted. 1985 // LayoutObject's contents are painted.
2015 LayoutSize CompositedLayerMapping::contentOffsetInCompositingLayer() const 1986 LayoutSize CompositedLayerMapping::contentOffsetInCompositingLayer() const
2016 { 1987 {
2017 ASSERT(!m_contentOffsetInCompositingLayerDirty); 1988 return m_owningLayer.subpixelAccumulation() - LayoutSize(m_graphicsLayer->of fsetFromLayoutObject());
chrishtr 2016/07/21 18:02:31 why subpixelAccumulation - offsetFromLayoutObject?
2018 return m_contentOffsetInCompositingLayer;
2019 } 1989 }
2020 1990
2021 LayoutRect CompositedLayerMapping::contentsBox() const 1991 LayoutRect CompositedLayerMapping::contentsBox() const
2022 { 1992 {
2023 LayoutRect contentsBox = LayoutRect(contentsRect(layoutObject())); 1993 LayoutRect contentsBox = contentsRect(layoutObject());
2024 contentsBox.move(contentOffsetInCompositingLayer()); 1994 contentsBox.move(contentOffsetInCompositingLayer());
2025 return contentsBox; 1995 return contentsBox;
2026 } 1996 }
2027 1997
2028 bool CompositedLayerMapping::needsToReparentOverflowControls() const 1998 bool CompositedLayerMapping::needsToReparentOverflowControls() const
2029 { 1999 {
2030 return m_owningLayer.getScrollableArea() 2000 return m_owningLayer.getScrollableArea()
2031 && m_owningLayer.getScrollableArea()->hasOverlayScrollbars() 2001 && m_owningLayer.getScrollableArea()->hasOverlayScrollbars()
2032 && m_owningLayer.getScrollableArea()->topmostScrollChild(); 2002 && m_owningLayer.getScrollableArea()->topmostScrollChild();
2033 } 2003 }
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after
2675 } else if (graphicsLayer == m_scrollingContentsLayer.get()) { 2645 } else if (graphicsLayer == m_scrollingContentsLayer.get()) {
2676 name = "Scrolling Contents Layer"; 2646 name = "Scrolling Contents Layer";
2677 } else { 2647 } else {
2678 ASSERT_NOT_REACHED(); 2648 ASSERT_NOT_REACHED();
2679 } 2649 }
2680 2650
2681 return name; 2651 return name;
2682 } 2652 }
2683 2653
2684 } // namespace blink 2654 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698