Changeset 154009 in webkit
- Timestamp:
- Aug 13, 2013 10:08:19 AM (11 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r154005 r154009 1 2013-08-13 Allan Sandfeld Jensen <allan.jensen@digia.com> 2 3 REGRESSION(SUBPIXEL_LAYOUT) Composited layers can cause one pixel shifts 4 https://bugs.webkit.org/show_bug.cgi?id=115304 5 6 Reviewed by David Hyatt. 7 8 * fast/sub-pixel/sub-pixel-composited-layers-expected.html: Added. 9 * fast/sub-pixel/sub-pixel-composited-layers.html: Added. 10 1 11 2013-08-13 Christophe Dumez <ch.dumez@sisa.samsung.com> 2 12 -
trunk/Source/WebCore/ChangeLog
r154006 r154009 1 2013-08-13 Allan Sandfeld Jensen <allan.jensen@digia.com> 2 3 REGRESSION(SUBPIXEL_LAYOUT) Composited layers can cause one pixel shifts 4 https://bugs.webkit.org/show_bug.cgi?id=115304 5 6 Reviewed by David Hyatt. 7 8 Accelerated layers can cause blocks at subpixel offsets to shift because 9 accumulated subpixel offsets are lost between each layers. 10 11 To solve this layer bounds are now calculated in LayoutUnits, and their 12 subpixel offset saved so it can be used to ensure correct pixel-snapping 13 during painting. 14 15 Test: fast/sub-pixel/sub-pixel-composited-layers.html 16 17 * WebCore.exp.in: 18 * inspector/InspectorLayerTreeAgent.cpp: 19 (WebCore::InspectorLayerTreeAgent::buildObjectForLayer): 20 * platform/graphics/LayoutPoint.h: 21 (WebCore::LayoutPoint::fraction): 22 * rendering/RenderLayer.cpp: 23 (WebCore::RenderLayer::setupClipPath): 24 (WebCore::RenderLayer::setupFilters): 25 (WebCore::RenderLayer::paintLayerContents): 26 (WebCore::RenderLayer::calculateLayerBounds): 27 * rendering/RenderLayer.h: 28 * rendering/RenderLayerBacking.cpp: 29 (WebCore::RenderLayerBacking::updateCompositedBounds): 30 (WebCore::RenderLayerBacking::updateAfterWidgetResize): 31 (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): 32 (WebCore::RenderLayerBacking::resetContentsRect): 33 (WebCore::RenderLayerBacking::contentOffsetInCompostingLayer): 34 (WebCore::RenderLayerBacking::contentsBox): 35 (WebCore::RenderLayerBacking::backgroundBox): 36 (WebCore::RenderLayerBacking::paintIntoLayer): 37 (WebCore::RenderLayerBacking::paintContents): 38 (WebCore::RenderLayerBacking::compositedBounds): 39 (WebCore::RenderLayerBacking::setCompositedBounds): 40 * rendering/RenderLayerBacking.h: 41 * rendering/RenderLayerCompositor.cpp: 42 (WebCore::RenderLayerCompositor::logLayerInfo): 43 (WebCore::RenderLayerCompositor::calculateCompositedBounds): 44 * rendering/RenderLayerCompositor.h: 45 * rendering/RenderTreeAsText.cpp: 46 (WebCore::operator<<): 47 * rendering/RenderTreeAsText.h: 48 1 49 2013-08-13 peavo@outlook.com <peavo@outlook.com> 2 50 -
trunk/Source/WebCore/WebCore.exp.in
r153907 r154009 1137 1137 __ZN7WebCore9DOMWindow36dispatchAllPendingBeforeUnloadEventsEv 1138 1138 __ZN7WebCore9FloatRectC1ERK6CGRect 1139 __ZN7WebCore9FloatRectC1ERKNS_10LayoutRectE 1139 1140 __ZN7WebCore9FloatRectC1ERKNS_7IntRectE 1140 1141 __ZN7WebCore9FloatSizeC1ERK6CGSize -
trunk/Source/WebCore/inspector/InspectorLayerTreeAgent.cpp
r152103 r154009 181 181 .setBounds(buildObjectForIntRect(renderer->absoluteBoundingBoxRect())) 182 182 .setMemory(backing->backingStoreMemoryEstimate()) 183 .setCompositedBounds(buildObjectForIntRect( backing->compositedBounds()))183 .setCompositedBounds(buildObjectForIntRect(enclosingIntRect(backing->compositedBounds()))) 184 184 .setPaintCount(backing->graphicsLayer()->repaintCount()); 185 185 -
trunk/Source/WebCore/platform/graphics/LayoutPoint.h
r152175 r154009 82 82 return LayoutPoint(m_y, m_x); 83 83 } 84 84 85 LayoutPoint fraction() const 86 { 87 return LayoutPoint(m_x.fraction(), m_y.fraction()); 88 } 89 85 90 operator FloatPoint() const { return FloatPoint(m_x, m_y); } 86 91 -
trunk/Source/WebCore/rendering/RenderLayer.cpp
r153927 r154009 3731 3731 } 3732 3732 3733 bool RenderLayer::setupClipPath(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, const LayoutPoint& offsetFromRoot, IntRect& rootRelativeBounds, bool& rootRelativeBoundsComputed)3733 bool RenderLayer::setupClipPath(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, const LayoutPoint& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed) 3734 3734 { 3735 3735 if (!renderer()->hasClipPath() || context->paintingDisabled()) … … 3774 3774 3775 3775 #if ENABLE(CSS_FILTERS) 3776 PassOwnPtr<FilterEffectRendererHelper> RenderLayer::setupFilters(GraphicsContext* context, LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& offsetFromRoot, IntRect& rootRelativeBounds, bool& rootRelativeBoundsComputed)3776 PassOwnPtr<FilterEffectRendererHelper> RenderLayer::setupFilters(GraphicsContext* context, LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed) 3777 3777 { 3778 3778 if (context->paintingDisabled()) … … 3865 3865 convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); 3866 3866 3867 IntRect rootRelativeBounds;3867 LayoutRect rootRelativeBounds; 3868 3868 bool rootRelativeBoundsComputed = false; 3869 3869 … … 5382 5382 } 5383 5383 5384 IntRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot, CalculateLayerBoundsFlags flags) const5384 LayoutRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot, CalculateLayerBoundsFlags flags) const 5385 5385 { 5386 5386 if (!isSelfPaintingLayer()) 5387 return IntRect();5387 return LayoutRect(); 5388 5388 5389 5389 // FIXME: This could be improved to do a check like hasVisibleNonCompositingDescendantLayers() (bug 92580). 5390 5390 if ((flags & ExcludeHiddenDescendants) && this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant()) 5391 return IntRect();5391 return LayoutRect(); 5392 5392 5393 5393 RenderLayerModelObject* renderer = this->renderer(); … … 5429 5429 convertToLayerCoords(ancestorLayer, ancestorRelOffset); 5430 5430 localClipRect.moveBy(ancestorRelOffset); 5431 return pixelSnappedIntRect(localClipRect);5431 return localClipRect; 5432 5432 } 5433 5433 } … … 5440 5440 if (RenderLayer* reflection = reflectionLayer()) { 5441 5441 if (!reflection->isComposited()) { 5442 IntRect childUnionBounds = reflection->calculateLayerBounds(this, 0, descendantFlags);5442 LayoutRect childUnionBounds = reflection->calculateLayerBounds(this, 0, descendantFlags); 5443 5443 unionBounds.unite(childUnionBounds); 5444 5444 } … … 5456 5456 RenderLayer* curLayer = negZOrderList->at(i); 5457 5457 if (flags & IncludeCompositedDescendants || !curLayer->isComposited()) { 5458 IntRect childUnionBounds = curLayer->calculateLayerBounds(this, 0, descendantFlags);5458 LayoutRect childUnionBounds = curLayer->calculateLayerBounds(this, 0, descendantFlags); 5459 5459 unionBounds.unite(childUnionBounds); 5460 5460 } … … 5467 5467 RenderLayer* curLayer = posZOrderList->at(i); 5468 5468 if (flags & IncludeCompositedDescendants || !curLayer->isComposited()) { 5469 IntRect childUnionBounds = curLayer->calculateLayerBounds(this, 0, descendantFlags);5469 LayoutRect childUnionBounds = curLayer->calculateLayerBounds(this, 0, descendantFlags); 5470 5470 unionBounds.unite(childUnionBounds); 5471 5471 } … … 5481 5481 ASSERT(!curLayer->isOutOfFlowRenderFlowThread()); 5482 5482 if (flags & IncludeCompositedDescendants || !curLayer->isComposited()) { 5483 IntRect curAbsBounds = curLayer->calculateLayerBounds(this, 0, descendantFlags);5483 LayoutRect curAbsBounds = curLayer->calculateLayerBounds(this, 0, descendantFlags); 5484 5484 unionBounds.unite(curAbsBounds); 5485 5485 } … … 5508 5508 unionBounds.moveBy(ancestorRelOffset); 5509 5509 5510 return pixelSnappedIntRect(unionBounds);5510 return unionBounds; 5511 5511 } 5512 5512 -
trunk/Source/WebCore/rendering/RenderLayer.h
r152122 r154009 706 706 707 707 // Can pass offsetFromRoot if known. 708 IntRect calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot = 0, CalculateLayerBoundsFlags = DefaultCalculateLayerBoundsFlags) const;708 LayoutRect calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot = 0, CalculateLayerBoundsFlags = DefaultCalculateLayerBoundsFlags) const; 709 709 710 710 // WARNING: This method returns the offset for the parent as this is what updateLayerPositions expects. … … 941 941 942 942 bool setupFontSubpixelQuantization(GraphicsContext*, bool& didQuantizeFonts); 943 bool setupClipPath(GraphicsContext*, const LayerPaintingInfo&, const LayoutPoint& offsetFromRoot, IntRect& rootRelativeBounds, bool& rootRelativeBoundsComputed);943 bool setupClipPath(GraphicsContext*, const LayerPaintingInfo&, const LayoutPoint& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed); 944 944 #if ENABLE(CSS_FILTERS) 945 PassOwnPtr<FilterEffectRendererHelper> setupFilters(GraphicsContext*, LayerPaintingInfo&, PaintLayerFlags, const LayoutPoint& offsetFromRoot, IntRect& rootRelativeBounds, bool& rootRelativeBoundsComputed);945 PassOwnPtr<FilterEffectRendererHelper> setupFilters(GraphicsContext*, LayerPaintingInfo&, PaintLayerFlags, const LayoutPoint& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed); 946 946 GraphicsContext* applyFilters(FilterEffectRendererHelper*, GraphicsContext* originalContext, LayerPaintingInfo&, LayerFragments&); 947 947 #endif -
trunk/Source/WebCore/rendering/RenderLayerBacking.cpp
r153805 r154009 426 426 void RenderLayerBacking::updateCompositedBounds() 427 427 { 428 IntRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);428 LayoutRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer); 429 429 430 430 // Clip to the size of the document or enclosing overflow-scroll layer. … … 448 448 clippingBounds.move(-delta.x(), -delta.y()); 449 449 450 layerBounds.intersect( pixelSnappedIntRect(clippingBounds));450 layerBounds.intersect(clippingBounds); 451 451 m_boundsConstrainedByClipping = true; 452 452 } else … … 471 471 if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(toRenderPart(renderer()))) { 472 472 innerCompositor->frameViewDidChangeSize(); 473 innerCompositor->frameViewDidChangeLocation( contentsBox().location());473 innerCompositor->frameViewDidChangeLocation(flooredIntPoint(contentsBox().location())); 474 474 } 475 475 } … … 648 648 } 649 649 650 IntRect localCompositingBounds = pixelSnappedIntRect(compositedBounds()); 651 650 LayoutRect localRawCompositingBounds = compositedBounds(); 651 LayoutPoint rawDelta; 652 m_owningLayer->convertToLayerCoords(compAncestor, rawDelta); 653 IntPoint delta = flooredIntPoint(rawDelta); 654 m_subpixelAccumulation = toLayoutSize(rawDelta.fraction()); 655 // Move the bounds by the subpixel accumulation so that it pixel-snaps relative to absolute pixels instead of local coordinates. 656 localRawCompositingBounds.move(m_subpixelAccumulation); 657 658 IntRect localCompositingBounds = pixelSnappedIntRect(localRawCompositingBounds); 652 659 IntRect relativeCompositingBounds(localCompositingBounds); 653 IntPoint delta;654 m_owningLayer->convertToPixelSnappedLayerCoords(compAncestor, delta);655 660 relativeCompositingBounds.moveBy(delta); 656 661 … … 702 707 m_graphicsLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation)); 703 708 m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location())); 704 709 705 710 FloatSize oldSize = m_graphicsLayer->size(); 706 711 if (oldSize != contentsSize) { … … 740 745 741 746 // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds. 742 IntRect layerBounds = IntRect(delta, borderBox.size());747 IntRect layerBounds(delta, borderBox.size()); 743 748 744 749 // Update properties that depend on layer dimensions … … 954 959 void RenderLayerBacking::resetContentsRect() 955 960 { 956 IntRect rect = contentsBox();961 IntRect rect = pixelSnappedIntRect(contentsBox()); 957 962 m_graphicsLayer->setContentsRect(rect); 958 963 m_graphicsLayer->setContentsTileSize(IntSize()); … … 1758 1763 1759 1764 // This is a no-op if the layer doesn't have an inner layer for the image. 1760 m_graphicsLayer->setContentsRect( contentsBox());1765 m_graphicsLayer->setContentsRect(pixelSnappedIntRect(contentsBox())); 1761 1766 m_graphicsLayer->setContentsToImage(image); 1762 1767 bool isSimpleContainer = false; … … 1796 1801 1797 1802 // Return the offset from the top-left of this compositing layer at which the renderer's contents are painted. 1798 IntSize RenderLayerBacking::contentOffsetInCompostingLayer() const1799 { 1800 return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y());1801 } 1802 1803 IntRect RenderLayerBacking::contentsBox() const1803 LayoutSize RenderLayerBacking::contentOffsetInCompostingLayer() const 1804 { 1805 return LayoutSize(-m_compositedBounds.x(), -m_compositedBounds.y()); 1806 } 1807 1808 LayoutRect RenderLayerBacking::contentsBox() const 1804 1809 { 1805 1810 if (!renderer()->isBox()) 1806 return IntRect();1807 1808 IntRect contentsRect;1811 return LayoutRect(); 1812 1813 LayoutRect contentsRect; 1809 1814 #if ENABLE(VIDEO) 1810 1815 if (renderer()->isVideo()) { … … 1813 1818 } else 1814 1819 #endif 1815 contentsRect = pixelSnappedIntRect(toRenderBox(renderer())->contentBoxRect());1820 contentsRect = toRenderBox(renderer())->contentBoxRect(); 1816 1821 1817 1822 contentsRect.move(contentOffsetInCompostingLayer()); … … 1841 1846 return IntRect(); 1842 1847 1843 IntRect pixelSnappedBackgroundBox = pixelSnappedIntRect(backgroundRectForBox(toRenderBox(renderer())));1844 pixelSnappedBackgroundBox.move(contentOffsetInCompostingLayer());1845 return pixelSnapped BackgroundBox;1848 LayoutRect backgroundBox = backgroundRectForBox(toRenderBox(renderer())); 1849 backgroundBox.move(contentOffsetInCompostingLayer()); 1850 return pixelSnappedIntRect(backgroundBox); 1846 1851 } 1847 1852 … … 1989 1994 1990 1995 // FIXME: GraphicsLayers need a way to split for RenderRegions. 1991 RenderLayer::LayerPaintingInfo paintingInfo(m_owningLayer, paintDirtyRect, paintBehavior, LayoutSize());1996 RenderLayer::LayerPaintingInfo paintingInfo(m_owningLayer, paintDirtyRect, paintBehavior, m_subpixelAccumulation); 1992 1997 m_owningLayer->paintLayerContents(context, paintingInfo, paintFlags); 1993 1998 … … 2032 2037 IntRect dirtyRect = clip; 2033 2038 if (!(paintingPhase & GraphicsLayerPaintOverflowContents)) 2034 dirtyRect.intersect( compositedBounds());2039 dirtyRect.intersect(enclosingIntRect(compositedBounds())); 2035 2040 2036 2041 // We have to use the same root as for hit testing, because both methods can compute and cache clipRects. … … 2265 2270 } 2266 2271 2267 IntRect RenderLayerBacking::compositedBounds() const2272 LayoutRect RenderLayerBacking::compositedBounds() const 2268 2273 { 2269 2274 return m_compositedBounds; 2270 2275 } 2271 2276 2272 void RenderLayerBacking::setCompositedBounds(const IntRect& bounds)2277 void RenderLayerBacking::setCompositedBounds(const LayoutRect& bounds) 2273 2278 { 2274 2279 m_compositedBounds = bounds; -
trunk/Source/WebCore/rendering/RenderLayerBacking.h
r152213 r154009 142 142 void resumeAnimations(); 143 143 144 IntRect compositedBounds() const;145 void setCompositedBounds(const IntRect&);144 LayoutRect compositedBounds() const; 145 void setCompositedBounds(const LayoutRect&); 146 146 void updateCompositedBounds(); 147 147 … … 176 176 #endif 177 177 178 IntRect contentsBox() const;178 LayoutRect contentsBox() const; 179 179 IntRect backgroundBox() const; 180 180 … … 230 230 GraphicsLayerPaintingPhase paintingPhaseForPrimaryLayer() const; 231 231 232 IntSize contentOffsetInCompostingLayer() const;232 LayoutSize contentOffsetInCompostingLayer() const; 233 233 // Result is transform origin in pixels. 234 234 FloatPoint3D computeTransformOrigin(const IntRect& borderBox) const; … … 298 298 uint64_t m_scrollLayerID; 299 299 300 IntRect m_compositedBounds; 300 LayoutRect m_compositedBounds; 301 LayoutSize m_subpixelAccumulation; // The accumulated subpixel offset of the compositedBounds compared to absolute coordinates. 301 302 302 303 bool m_artificiallyInflatedBounds; // bounds had to be made non-zero to make transform-origin work -
trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp
r153003 r154009 655 655 StringBuilder logString; 656 656 logString.append(String::format("%*p %dx%d %.2fKB", 12 + depth * 2, layer, 657 backing->compositedBounds().width() , backing->compositedBounds().height(),657 backing->compositedBounds().width().round(), backing->compositedBounds().height().round(), 658 658 backing->backingStoreMemoryEstimate() / 1024)); 659 659 … … 831 831 // The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant 832 832 // RenderLayers that are rendered by the composited RenderLayer. 833 IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer) const833 LayoutRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer) const 834 834 { 835 835 if (!canBeComposited(layer)) 836 return IntRect();836 return LayoutRect(); 837 837 return layer->calculateLayerBounds(ancestorLayer, 0, RenderLayer::DefaultCalculateLayerBoundsFlags | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask); 838 838 } -
trunk/Source/WebCore/rendering/RenderLayerCompositor.h
r150898 r154009 164 164 // Return the bounding box required for compositing layer and its childern, relative to ancestorLayer. 165 165 // If layerBoundingBox is not 0, on return it contains the bounding box of this layer only. 166 IntRect calculateCompositedBounds(const RenderLayer*, const RenderLayer* ancestorLayer) const;166 LayoutRect calculateCompositedBounds(const RenderLayer*, const RenderLayer* ancestorLayer) const; 167 167 168 168 // Repaint the appropriate layers when the given RenderLayer starts or stops being composited. -
trunk/Source/WebCore/rendering/RenderTreeAsText.cpp
r151339 r154009 89 89 } 90 90 91 TextStream& operator<<(TextStream& ts, const LayoutRect& r) 92 { 93 // FIXME: These should be printed as floats. Keeping them ints for consistency with previous test expectations. 94 return ts << pixelSnappedIntRect(r); 95 } 96 91 97 TextStream& operator<<(TextStream& ts, const LayoutPoint& p) 92 98 { 93 // FIXME: These should be printed as floats. Keeping them ints for consistency with p ervious test expectations.99 // FIXME: These should be printed as floats. Keeping them ints for consistency with previous test expectations. 94 100 return ts << "(" << p.x().toInt() << "," << p.y().toInt() << ")"; 95 101 } -
trunk/Source/WebCore/rendering/RenderTreeAsText.h
r133779 r154009 39 39 class IntRect; 40 40 class LayoutPoint; 41 class LayoutRect; 41 42 class RenderObject; 42 43 class TextStream; … … 72 73 TextStream& operator<<(TextStream&, const IntRect&); 73 74 TextStream& operator<<(TextStream&, const LayoutPoint&); 75 TextStream& operator<<(TextStream&, const LayoutRect&); 74 76 TextStream& operator<<(TextStream&, const FloatPoint&); 75 77 TextStream& operator<<(TextStream&, const FloatSize&);
Note: See TracChangeset
for help on using the changeset viewer.