Changeset 164449 in webkit
- Timestamp:
- Feb 20, 2014 3:04:20 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r164437 r164449 1 2014-02-20 Zalan Bujtas <zalan@apple.com> 2 3 Subpixel rendering: Enable compositing RenderLayer painting on device pixel position. 4 https://bugs.webkit.org/show_bug.cgi?id=128509 5 6 Reviewed by Simon Fraser. 7 8 GraphicsLayer is now positioned on device pixel boundary. This enables us to put 9 compositing layers on a subpixel position and animate them with device pixel 10 precision. 11 12 * TestExpectations: 13 * fast/sub-pixel/compositing-layers-on-subpixel-position-expected.html: Added. 14 * fast/sub-pixel/compositing-layers-on-subpixel-position.html: Added. 15 * fast/sub-pixel/simple-clipping-expected.html: Added. 16 * fast/sub-pixel/simple-clipping.html: Added. 17 * platform/mac/compositing/layer-creation/overlap-animation-container-expected.txt: 18 1 19 2014-02-20 Mark Hahnenberg <mhahnenberg@apple.com> 2 20 -
trunk/LayoutTests/TestExpectations
r164437 r164449 103 103 104 104 webkit.org/b/129057 media/controls-styling-strict.html [ Pass Failure ] 105 106 #subpixel failure on non-retina displays. 107 webkit.org/b/129050 fast/sub-pixel/compositing-layers-on-subpixel-position.html [ Failure ] 108 webkit.org/b/129113 fast/multicol/newmulticol/clipping.html [ Failure ] -
trunk/LayoutTests/platform/mac/compositing/layer-creation/overlap-animation-container-expected.txt
r161884 r164449 13 13 ) 14 14 (GraphicsLayer 15 (position 4 7.00 229.00)16 (bounds 14 4.00 454.00)15 (position 46.00 229.00) 16 (bounds 146.00 454.00) 17 17 (drawsContent 1) 18 18 (children 1 19 19 (GraphicsLayer 20 (position 21. 0011.00)20 (position 21.13 11.00) 21 21 (bounds 102.00 102.00) 22 22 (transform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 0.00] [0.00 0.00 -1.00 1.00]) -
trunk/Source/WebCore/ChangeLog
r164441 r164449 1 2014-02-20 Zalan Bujtas <zalan@apple.com> 2 3 Subpixel rendering: Enable compositing RenderLayer painting on device pixel position. 4 https://bugs.webkit.org/show_bug.cgi?id=128509 5 6 Reviewed by Simon Fraser. 7 8 GraphicsLayer is now positioned on device pixel boundary. This enables us to put 9 compositing layers on a subpixel position and animate them with device pixel 10 precision. 11 12 Tests: fast/sub-pixel/compositing-layers-on-subpixel-position.html 13 fast/sub-pixel/simple-clipping.html 14 15 * platform/LayoutUnit.h: 16 (WebCore::ceilToDevicePixel): 17 * platform/graphics/LayoutPoint.h: 18 (WebCore::flooredForPainting): 19 (WebCore::ceiledForPainting): 20 * platform/graphics/LayoutRect.cpp: 21 (WebCore::enclosingRectForPainting): 22 * platform/graphics/LayoutRect.h: 23 * rendering/RenderLayer.cpp: 24 (WebCore::RenderLayer::clipToRect): 25 * rendering/RenderLayerBacking.cpp: 26 (WebCore::clipBox): 27 (WebCore::pixelFractionForLayerPainting): 28 (WebCore::calculateDevicePixelOffsetFromRenderer): 29 (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): 30 (WebCore::RenderLayerBacking::paintIntoLayer): 31 * rendering/RenderLayerBacking.h: 32 1 33 2014-02-20 Bem Jones-Bey <bjonesbe@adobe.com> 2 34 -
trunk/Source/WebCore/platform/LayoutUnit.h
r163278 r164449 946 946 } 947 947 948 inline float ceilToDevicePixel(LayoutUnit value, float pixelSnappingFactor) 949 { 950 return ceilf((value.rawValue() * pixelSnappingFactor) / kEffectiveFixedPointDenominator) / pixelSnappingFactor; 951 } 952 948 953 inline float snapSizeToDevicePixel(LayoutUnit size, LayoutUnit location, float pixelSnappingFactor) 949 954 { -
trunk/Source/WebCore/platform/graphics/LayoutPoint.h
r163973 r164449 186 186 } 187 187 188 inline FloatPoint flooredForPainting(const LayoutPoint& point, float pixelSnappingFactor) 189 { 190 #if ENABLE(SUBPIXEL_LAYOUT) 191 return FloatPoint(floorToDevicePixel(point.x(), pixelSnappingFactor), floorToDevicePixel(point.y(), pixelSnappingFactor)); 192 #else 193 UNUSED_PARAM(pixelSnappingFactor); 194 return FloatPoint(point); 195 #endif 196 } 197 198 inline FloatPoint ceiledForPainting(const LayoutPoint& point, float pixelSnappingFactor) 199 { 200 #if ENABLE(SUBPIXEL_LAYOUT) 201 return FloatPoint(ceilToDevicePixel(point.x(), pixelSnappingFactor), ceilToDevicePixel(point.y(), pixelSnappingFactor)); 202 #else 203 UNUSED_PARAM(pixelSnappingFactor); 204 return FloatPoint(point); 205 #endif 206 } 207 188 208 inline LayoutPoint roundedLayoutPoint(const FloatPoint& p) 189 209 { -
trunk/Source/WebCore/platform/graphics/LayoutRect.cpp
r157971 r164449 148 148 } 149 149 150 FloatRect enclosingRectForPainting(const LayoutRect& rect, float pixelSnappingFactor) 151 { 152 FloatPoint location = flooredForPainting(rect.minXMinYCorner(), pixelSnappingFactor); 153 FloatPoint maxPoint = ceiledForPainting(rect.maxXMaxYCorner(), pixelSnappingFactor); 154 155 return FloatRect(location, maxPoint - location); 156 } 157 150 158 } // namespace WebCore -
trunk/Source/WebCore/platform/graphics/LayoutRect.h
r163265 r164449 215 215 IntRect enclosingIntRect(const LayoutRect&); 216 216 LayoutRect enclosingLayoutRect(const FloatRect&); 217 217 FloatRect enclosingRectForPainting(const LayoutRect&, float pixelSnappingFactor); 218 218 219 219 inline IntRect pixelSnappedIntRect(LayoutUnit left, LayoutUnit top, LayoutUnit width, LayoutUnit height) -
trunk/Source/WebCore/rendering/RenderLayer.cpp
r164441 r164449 3573 3573 if (clipRect.rect() != paintDirtyRect || clipRect.hasRadius()) { 3574 3574 context->save(); 3575 context->clip( pixelSnappedIntRect(clipRect.rect()));3575 context->clip(clipRect.rect()); 3576 3576 } 3577 3577 -
trunk/Source/WebCore/rendering/RenderLayerBacking.cpp
r164415 r164449 643 643 result.intersect(renderer.clipRect(LayoutPoint(), 0)); // FIXME: Incorrect for CSS regions. 644 644 645 return pixelSnappedIntRect(result); 645 return result; 646 } 647 648 static FloatSize pixelFractionForLayerPainting(const LayoutPoint& point, float pixelSnappingFactor) 649 { 650 LayoutUnit x = point.x(); 651 LayoutUnit y = point.y(); 652 x = x >= 0 ? floorToDevicePixel(x, pixelSnappingFactor) : ceilToDevicePixel(x, pixelSnappingFactor); 653 y = y >= 0 ? floorToDevicePixel(y, pixelSnappingFactor) : ceilToDevicePixel(y, pixelSnappingFactor); 654 return point - LayoutPoint(x, y); 655 } 656 657 static void calculateDevicePixelOffsetFromRenderer(const LayoutSize& rendererOffsetFromGraphicsLayer, FloatSize& devicePixelOffsetFromRenderer, 658 LayoutSize& devicePixelFractionFromRenderer, float deviceScaleFactor) 659 { 660 devicePixelFractionFromRenderer = LayoutSize(pixelFractionForLayerPainting(toLayoutPoint(rendererOffsetFromGraphicsLayer), deviceScaleFactor)); 661 devicePixelOffsetFromRenderer = rendererOffsetFromGraphicsLayer - devicePixelFractionFromRenderer; 646 662 } 647 663 … … 690 706 if (compAncestor) { 691 707 ASSERT(compAncestor->backing()); 692 ancestorCompositingBounds = pixelSnappedIntRect(compAncestor->backing()->compositedBounds()); 693 } 694 695 LayoutRect localRawCompositingBounds = compositedBounds(); 696 LayoutPoint rawDelta; 697 m_owningLayer.convertToLayerCoords(compAncestor, rawDelta, RenderLayer::AdjustForColumns); 698 IntPoint delta = flooredIntPoint(rawDelta); 699 m_subpixelAccumulation = toLayoutSize(rawDelta.fraction()); 700 // Move the bounds by the subpixel accumulation so that it pixel-snaps relative to absolute pixels instead of local coordinates. 701 localRawCompositingBounds.move(m_subpixelAccumulation); 702 703 LayoutRect localCompositingBounds = pixelSnappedIntRect(localRawCompositingBounds); 708 ancestorCompositingBounds = compAncestor->backing()->compositedBounds(); 709 } 710 711 /* 712 * GraphicsLayer: device pixel positioned. Floored, enclosing rect. 713 * RenderLayer: subpixel positioned. 714 * Offset from renderer (GraphicsLayer <-> RenderLayer::renderer()): subpixel based offset. 715 * 716 * relativeCompositingBounds 717 * _______________________________________ 718 * |\ GraphicsLayer | 719 * | \ | 720 * | \ offset from renderer: (device pixel + subpixel) 721 * | \ | 722 * | \______________________________ | 723 * | | localCompositingBounds | | 724 * | | | | 725 * | | RenderLayer::renderer() | | 726 * | | | | 727 * 728 * localCompositingBounds: this RenderLayer relative to its renderer(). 729 * relativeCompositingBounds: this RenderLayer relative to its parent compositing layer. 730 * enclosingRelativeCompositingBounds: this RenderLayer relative to its parent but floored to device pixel position. 731 * rendererOffsetFromGraphicsLayer: RenderLayer::renderer()'s offset from its enclosing GraphicsLayer. 732 * devicePixelOffsetFromRenderer: rendererOffsetFromGraphicsLayer's device pixel part. (6.9px -> 6.5px in case of 2x display) 733 * devicePixelFractionFromRenderer: rendererOffsetFromGraphicsLayer's fractional part (6.9px -> 0.4px in case of 2x display) 734 */ 735 float deviceScaleFactor = this->deviceScaleFactor(); 736 LayoutRect localCompositingBounds = compositedBounds(); 704 737 LayoutRect relativeCompositingBounds(localCompositingBounds); 705 relativeCompositingBounds.moveBy(delta); 738 739 LayoutPoint offsetFromParent; 740 m_owningLayer.convertToLayerCoords(compAncestor, offsetFromParent, RenderLayer::AdjustForColumns); 741 relativeCompositingBounds.moveBy(offsetFromParent); 742 743 LayoutRect enclosingRelativeCompositingBounds = LayoutRect(enclosingRectForPainting(relativeCompositingBounds, deviceScaleFactor)); 744 LayoutSize subpixelOffsetAdjustment = enclosingRelativeCompositingBounds.location() - relativeCompositingBounds.location(); 745 LayoutSize rendererOffsetFromGraphicsLayer = toLayoutSize(localCompositingBounds.location()) + subpixelOffsetAdjustment; 746 747 FloatSize devicePixelOffsetFromRenderer; 748 LayoutSize devicePixelFractionFromRenderer; 749 calculateDevicePixelOffsetFromRenderer(rendererOffsetFromGraphicsLayer, devicePixelOffsetFromRenderer, devicePixelFractionFromRenderer, deviceScaleFactor); 750 m_devicePixelFractionFromRenderer = LayoutSize(fabs(devicePixelFractionFromRenderer.width().toFloat()), fabs(devicePixelFractionFromRenderer.height().toFloat())); 706 751 707 752 adjustAncestorCompositingBoundsForFlowThread(ancestorCompositingBounds, compAncestor); … … 742 787 // for a compositing layer, rootLayer is the layer itself. 743 788 RenderLayer::ClipRectsContext clipRectsContext(compAncestor, 0, TemporaryClipRects, IgnoreOverlayScrollbarSize, IgnoreOverflowClip); 744 LayoutRect parentClipRect = pixelSnappedIntRect(m_owningLayer.backgroundClipRect(clipRectsContext).rect()); // FIXME: Incorrect for CSS regions.789 LayoutRect parentClipRect = m_owningLayer.backgroundClipRect(clipRectsContext).rect(); // FIXME: Incorrect for CSS regions. 745 790 ASSERT(parentClipRect != LayoutRect::infiniteRect()); 746 791 m_ancestorClippingLayer->setPosition(FloatPoint(parentClipRect.location() - graphicsLayerParentLocation)); … … 748 793 749 794 // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords. 750 m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - delta);795 m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - offsetFromParent); 751 796 752 797 // The primary layer is then parented in, and positioned relative to this clipping layer. … … 754 799 } 755 800 756 LayoutSize contentsSize = relativeCompositingBounds.size();801 LayoutSize contentsSize = enclosingRelativeCompositingBounds.size(); 757 802 758 803 if (m_contentsContainmentLayer) { 759 804 m_contentsContainmentLayer->setPreserves3D(preserves3D); 760 m_contentsContainmentLayer->setPosition(FloatPoint( relativeCompositingBounds.location() - graphicsLayerParentLocation));805 m_contentsContainmentLayer->setPosition(FloatPoint(enclosingRelativeCompositingBounds.location() - graphicsLayerParentLocation)); 761 806 // Use the same size as m_graphicsLayer so transforms behave correctly. 762 807 m_contentsContainmentLayer->setSize(contentsSize); 763 graphicsLayerParentLocation = relativeCompositingBounds.location();764 } 765 766 m_graphicsLayer->setPosition(FloatPoint( relativeCompositingBounds.location() - graphicsLayerParentLocation));808 graphicsLayerParentLocation = enclosingRelativeCompositingBounds.location(); 809 } 810 811 m_graphicsLayer->setPosition(FloatPoint(enclosingRelativeCompositingBounds.location() - graphicsLayerParentLocation)); 767 812 m_graphicsLayer->setSize(contentsSize); 768 FloatSize offsetFromRenderer = toLayoutSize(localCompositingBounds.location()); 769 if (offsetFromRenderer != m_graphicsLayer->offsetFromRenderer()) { 770 m_graphicsLayer->setOffsetFromRenderer(offsetFromRenderer); 813 if (devicePixelOffsetFromRenderer != m_graphicsLayer->offsetFromRenderer()) { 814 m_graphicsLayer->setOffsetFromRenderer(devicePixelOffsetFromRenderer); 771 815 positionOverflowControlsLayers(); 772 816 } … … 775 819 // For non-root layers, background is always painted by the primary graphics layer. 776 820 ASSERT(!m_backgroundLayer); 777 bool hadSubpixelRounding = relativeCompositingBounds.size() != localRawCompositingBounds.size();821 bool hadSubpixelRounding = !m_devicePixelFractionFromRenderer.isEmpty(); 778 822 m_graphicsLayer->setContentsOpaque(!hadSubpixelRounding && m_owningLayer.backgroundIsKnownToBeOpaqueInRect(localCompositingBounds)); 779 823 } … … 798 842 799 843 // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds. 800 LayoutRect layerBounds( delta, borderBox.size());844 LayoutRect layerBounds(offsetFromParent, borderBox.size()); 801 845 802 846 // Update properties that depend on layer dimensions 803 847 FloatPoint3D transformOrigin = computeTransformOrigin(borderBox); 804 848 // Compute the anchor point, which is in the center of the renderer box unless transform-origin is set. 805 FloatPoint3D anchor( relativeCompositingBounds.width() != 0.0f ? ((layerBounds.x() - relativeCompositingBounds.x()) + transformOrigin.x()) / relativeCompositingBounds.width() : 0.5f,806 relativeCompositingBounds.height() != 0.0f ? ((layerBounds.y() - relativeCompositingBounds.y()) + transformOrigin.y()) / relativeCompositingBounds.height() : 0.5f,807 849 FloatPoint3D anchor(enclosingRelativeCompositingBounds.width() != 0.0f ? ((layerBounds.x() - enclosingRelativeCompositingBounds.x()) + transformOrigin.x()) 850 / enclosingRelativeCompositingBounds.width() : 0.5f, enclosingRelativeCompositingBounds.height() != 0.0f ? ((layerBounds.y() - enclosingRelativeCompositingBounds.y()) 851 + transformOrigin.y()) / enclosingRelativeCompositingBounds.height() : 0.5f, transformOrigin.z()); 808 852 if (m_contentsContainmentLayer) 809 853 m_contentsContainmentLayer->setAnchorPoint(anchor); … … 877 921 ASSERT(m_scrollingContentsLayer); 878 922 RenderBox& renderBox = toRenderBox(renderer()); 879 IntRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(), renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(), renderBox.height() - renderBox.borderTop() - renderBox.borderBottom());880 IntSize scrollOffset = m_owningLayer.scrollOffset();923 LayoutRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(), renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(), renderBox.height() - renderBox.borderTop() - renderBox.borderBottom()); 924 LayoutSize scrollOffset = m_owningLayer.scrollOffset(); 881 925 882 926 m_scrollingLayer->setPosition(FloatPoint(paddingBox.location() - localCompositingBounds.location())); … … 885 929 #if PLATFORM(IOS) 886 930 FloatSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer(); 887 m_scrollingLayer->setOffsetFromRenderer( IntPoint() - paddingBox.location());931 m_scrollingLayer->setOffsetFromRenderer(FloatPoint() - paddingBox.location()); 888 932 bool paddingBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer(); 889 933 … … 915 959 916 960 FloatSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer(); 917 m_scrollingLayer->setOffsetFromRenderer(-to IntSize(paddingBox.location()));961 m_scrollingLayer->setOffsetFromRenderer(-toFloatSize(paddingBox.location())); 918 962 919 963 bool paddingBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer(); … … 923 967 m_scrollingContentsLayer->setNeedsDisplay(); 924 968 925 IntSize scrollingContentsOffset = toIntSize(paddingBox.location() - scrollOffset);969 LayoutSize scrollingContentsOffset = toLayoutSize(paddingBox.location() - scrollOffset); 926 970 if (scrollingContentsOffset != m_scrollingContentsLayer->offsetFromRenderer() || scrollSize != m_scrollingContentsLayer->size()) 927 971 compositor().scrollingLayerDidChange(m_owningLayer); … … 939 983 940 984 // If this layer was created just for clipping or to apply perspective, it doesn't need its own backing store. 941 setRequiresOwnBackingStore(compositor().requiresOwnBackingStore(m_owningLayer, compAncestor, relativeCompositingBounds, ancestorCompositingBounds));985 setRequiresOwnBackingStore(compositor().requiresOwnBackingStore(m_owningLayer, compAncestor, enclosingRelativeCompositingBounds, ancestorCompositingBounds)); 942 986 943 987 bool didUpdateContentsRect = false; … … 2162 2206 2163 2207 // FIXME: GraphicsLayers need a way to split for RenderRegions. 2164 RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, m_ subpixelAccumulation);2208 RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, m_devicePixelFractionFromRenderer); 2165 2209 m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags); 2166 2210 -
trunk/Source/WebCore/rendering/RenderLayerBacking.h
r164415 r164449 312 312 313 313 LayoutRect m_compositedBounds; 314 LayoutSize m_ subpixelAccumulation; // The accumulated subpixel offset of the compositedBounds compared to absolute coordinates.314 LayoutSize m_devicePixelFractionFromRenderer; 315 315 316 316 bool m_artificiallyInflatedBounds; // bounds had to be made non-zero to make transform-origin work
Note: See TracChangeset
for help on using the changeset viewer.