Changeset 204552 in webkit


Ignore:
Timestamp:
Aug 16, 2016 8:18:21 PM (8 years ago)
Author:
Alan Bujtas
Message:

Subpixel rendering: Cleanup RenderLayerBacking::updateGeometry.
https://bugs.webkit.org/show_bug.cgi?id=156860
<rdar://problem/25432352>

Reviewed by Simon Fraser.

Source/WebCore:

This patch cleans up the subpixel adjustment computation for the graphics layers
in RenderLayerBacking::updateGeometry.
It also fixes subpixel jiggling with clipping layers (both ancestor and child containment layers).

Tests: compositing/hidpi-ancestor-subpixel-clipping.html

compositing/hidpi-sibling-composited-content-offset.html
compositing/hidpi-subpixel-transform-origin.html
fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor.html

  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::beginTransparencyLayers):
(WebCore::RenderLayer::paint):
(WebCore::RenderLayer::clipToRect):
(WebCore::RenderLayer::setupClipPath):
(WebCore::RenderLayer::paintLayerByApplyingTransform):
(WebCore::RenderLayer::paintBackgroundForFragments):
(WebCore::RenderLayer::paintForegroundForFragmentsWithPhase):
(WebCore::RenderLayer::paintOutlineForFragments):
(WebCore::RenderLayer::paintMaskForFragments):
(WebCore::RenderLayer::paintChildClippingMaskForFragments):
(WebCore::RenderLayer::paintOverflowControlsForFragments):
(WebCore::RenderLayer::calculateClipRects):

  • rendering/RenderLayer.h:
  • rendering/RenderLayerBacking.cpp:

(WebCore::subpixelOffsetFromRendererChanged):
(WebCore::subpixelForLayerPainting):
(WebCore::computeOffsetFromRenderer):
(WebCore::snappedGraphicsLayerRect):
(WebCore::computeOffsetFromAncestorGraphicsLayer):
(WebCore::ComputedOffsets::ComputedOffsets): This is a helper class to hold offset values.
(WebCore::ComputedOffsets::fromAncestorGraphicsLayer):
(WebCore::ComputedOffsets::fromParentGraphicsLayer):
(WebCore::ComputedOffsets::fromPrimaryGraphicsLayer):
(WebCore::RenderLayerBacking::computePrimaryGraphicsLayerRect):
(WebCore::RenderLayerBacking::computeParentGraphicsLayerRect):
(WebCore::RenderLayerBacking::updateGeometry):
(WebCore::RenderLayerBacking::updateMaskingLayerGeometry):
(WebCore::RenderLayerBacking::contentOffsetInCompostingLayer):
(WebCore::RenderLayerBacking::setContentsNeedDisplayInRect):
(WebCore::RenderLayerBacking::paintIntoLayer):
(WebCore::RenderLayerBacking::paintContents):
(WebCore::devicePixelFractionGapFromRendererChanged): Deleted.
(WebCore::pixelFractionForLayerPainting): Deleted.
(WebCore::calculateDevicePixelOffsetFromRenderer): Deleted.
(WebCore::RenderLayerBacking::adjustAncestorCompositingBoundsForFlowThread): Deleted.

  • rendering/RenderLayerBacking.h:

LayoutTests:

  • compositing/hidpi-ancestor-subpixel-clipping-expected.html: Added.
  • compositing/hidpi-ancestor-subpixel-clipping.html: Added.
  • compositing/hidpi-sibling-composited-content-offset-expected.html: Added.
  • compositing/hidpi-sibling-composited-content-offset.html: Added.
  • compositing/hidpi-subpixel-transform-origin-expected.html: Added.
  • compositing/hidpi-subpixel-transform-origin.html: Added.
  • fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor-expected.txt: Added.
  • fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor.html: Added.
Location:
trunk
Files:
8 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r204551 r204552  
     12016-08-16  Zalan Bujtas  <zalan@apple.com>
     2
     3        Subpixel rendering: Cleanup RenderLayerBacking::updateGeometry.
     4        https://bugs.webkit.org/show_bug.cgi?id=156860
     5        <rdar://problem/25432352>
     6
     7        Reviewed by Simon Fraser.
     8
     9        * compositing/hidpi-ancestor-subpixel-clipping-expected.html: Added.
     10        * compositing/hidpi-ancestor-subpixel-clipping.html: Added.
     11        * compositing/hidpi-sibling-composited-content-offset-expected.html: Added.
     12        * compositing/hidpi-sibling-composited-content-offset.html: Added.
     13        * compositing/hidpi-subpixel-transform-origin-expected.html: Added.
     14        * compositing/hidpi-subpixel-transform-origin.html: Added.
     15        * fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor-expected.txt: Added.
     16        * fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor.html: Added.
     17
    1182016-08-16  Commit Queue  <commit-queue@webkit.org>
    219
  • trunk/Source/WebCore/ChangeLog

    r204551 r204552  
     12016-08-16  Zalan Bujtas  <zalan@apple.com>
     2
     3        Subpixel rendering: Cleanup RenderLayerBacking::updateGeometry.
     4        https://bugs.webkit.org/show_bug.cgi?id=156860
     5        <rdar://problem/25432352>
     6
     7        Reviewed by Simon Fraser.
     8
     9        This patch cleans up the subpixel adjustment computation for the graphics layers
     10        in RenderLayerBacking::updateGeometry.
     11        It also fixes subpixel jiggling with clipping layers (both ancestor and child containment layers).
     12
     13        Tests: compositing/hidpi-ancestor-subpixel-clipping.html
     14               compositing/hidpi-sibling-composited-content-offset.html
     15               compositing/hidpi-subpixel-transform-origin.html
     16               fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor.html
     17
     18        * rendering/RenderLayer.cpp:
     19        (WebCore::RenderLayer::beginTransparencyLayers):
     20        (WebCore::RenderLayer::paint):
     21        (WebCore::RenderLayer::clipToRect):
     22        (WebCore::RenderLayer::setupClipPath):
     23        (WebCore::RenderLayer::paintLayerByApplyingTransform):
     24        (WebCore::RenderLayer::paintBackgroundForFragments):
     25        (WebCore::RenderLayer::paintForegroundForFragmentsWithPhase):
     26        (WebCore::RenderLayer::paintOutlineForFragments):
     27        (WebCore::RenderLayer::paintMaskForFragments):
     28        (WebCore::RenderLayer::paintChildClippingMaskForFragments):
     29        (WebCore::RenderLayer::paintOverflowControlsForFragments):
     30        (WebCore::RenderLayer::calculateClipRects):
     31        * rendering/RenderLayer.h:
     32        * rendering/RenderLayerBacking.cpp:
     33        (WebCore::subpixelOffsetFromRendererChanged):
     34        (WebCore::subpixelForLayerPainting):
     35        (WebCore::computeOffsetFromRenderer):
     36        (WebCore::snappedGraphicsLayerRect):
     37        (WebCore::computeOffsetFromAncestorGraphicsLayer):
     38        (WebCore::ComputedOffsets::ComputedOffsets): This is a helper class to hold offset values.
     39        (WebCore::ComputedOffsets::fromAncestorGraphicsLayer):
     40        (WebCore::ComputedOffsets::fromParentGraphicsLayer):
     41        (WebCore::ComputedOffsets::fromPrimaryGraphicsLayer):
     42        (WebCore::RenderLayerBacking::computePrimaryGraphicsLayerRect):
     43        (WebCore::RenderLayerBacking::computeParentGraphicsLayerRect):
     44        (WebCore::RenderLayerBacking::updateGeometry):
     45        (WebCore::RenderLayerBacking::updateMaskingLayerGeometry):
     46        (WebCore::RenderLayerBacking::contentOffsetInCompostingLayer):
     47        (WebCore::RenderLayerBacking::setContentsNeedDisplayInRect):
     48        (WebCore::RenderLayerBacking::paintIntoLayer):
     49        (WebCore::RenderLayerBacking::paintContents):
     50        (WebCore::devicePixelFractionGapFromRendererChanged): Deleted.
     51        (WebCore::pixelFractionForLayerPainting): Deleted.
     52        (WebCore::calculateDevicePixelOffsetFromRenderer): Deleted.
     53        (WebCore::RenderLayerBacking::adjustAncestorCompositingBoundsForFlowThread): Deleted.
     54        * rendering/RenderLayerBacking.h:
     55
    1562016-08-16  Commit Queue  <commit-queue@webkit.org>
    257
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r204543 r204552  
    18121812        context.save();
    18131813        LayoutRect adjustedClipRect = paintingExtent(*this, paintingInfo.rootLayer, dirtyRect, paintingInfo.paintBehavior);
    1814         adjustedClipRect.move(paintingInfo.subpixelAccumulation);
     1814        adjustedClipRect.move(paintingInfo.subpixelOffset);
    18151815        FloatRect pixelSnappedClipRect = snapRectToDevicePixels(adjustedClipRect, renderer().document().deviceScaleFactor());
    18161816        context.clip(pixelSnappedClipRect);
     
    38093809}
    38103810
    3811 void RenderLayer::paint(GraphicsContext& context, const LayoutRect& damageRect, const LayoutSize& subpixelAccumulation, PaintBehavior paintBehavior, RenderObject* subtreePaintRoot, PaintLayerFlags paintFlags)
     3811void RenderLayer::paint(GraphicsContext& context, const LayoutRect& damageRect, const LayoutSize& subpixelOffset, PaintBehavior paintBehavior, RenderObject* subtreePaintRoot, PaintLayerFlags paintFlags)
    38123812{
    38133813    OverlapTestRequestMap overlapTestRequests;
    38143814
    3815     LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, subpixelAccumulation, subtreePaintRoot, &overlapTestRequests);
     3815    LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, subpixelOffset, subtreePaintRoot, &overlapTestRequests);
    38163816    paintLayer(context, paintingInfo, paintFlags);
    38173817
     
    38523852    if (needsClipping) {
    38533853        LayoutRect adjustedClipRect = clipRect.rect();
    3854         adjustedClipRect.move(paintingInfo.subpixelAccumulation);
     3854        adjustedClipRect.move(paintingInfo.subpixelOffset);
    38553855        context.clip(snapRectToDevicePixels(adjustedClipRect, deviceScaleFactor));
    38563856    }
     
    38633863            if (layer->renderer().hasOverflowClip() && layer->renderer().style().hasBorderRadius() && inContainingBlockChain(this, layer)) {
    38643864                LayoutRect adjustedClipRect = LayoutRect(toLayoutPoint(layer->offsetFromAncestor(paintingInfo.rootLayer, AdjustForColumns)), layer->size());
    3865                 adjustedClipRect.move(paintingInfo.subpixelAccumulation);
     3865                adjustedClipRect.move(paintingInfo.subpixelOffset);
    38663866                FloatRoundedRect roundedRect = layer->renderer().style().getRoundedInnerBorderFor(adjustedClipRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor);
    38673867                if (roundedRect.intersectionIsRectangular(paintingInfo.paintDirtyRect))
     
    41354135    if (is<ShapeClipPathOperation>(*style.clipPath()) || (is<BoxClipPathOperation>(*style.clipPath()) && is<RenderBox>(renderer()))) {
    41364136        WindRule windRule;
    4137         LayoutSize paintingOffsetFromRoot = LayoutSize(snapSizeToDevicePixel(offsetFromRoot + paintingInfo.subpixelAccumulation, LayoutPoint(), renderer().document().deviceScaleFactor()));
     4137        LayoutSize paintingOffsetFromRoot = LayoutSize(snapSizeToDevicePixel(offsetFromRoot + paintingInfo.subpixelOffset, LayoutPoint(), renderer().document().deviceScaleFactor()));
    41384138        Path path = computeClipPath(paintingOffsetFromRoot, rootRelativeBounds, windRule);
    41394139        context.save();
     
    44514451    TransformationMatrix transform(renderableTransform(paintingInfo.paintBehavior));
    44524452    // Add the subpixel accumulation to the current layer's offset so that we can always snap the translateRight value to where the renderer() is supposed to be painting.
    4453     LayoutSize offsetForThisLayer = offsetFromParent + paintingInfo.subpixelAccumulation;
     4453    LayoutSize offsetForThisLayer = offsetFromParent + paintingInfo.subpixelOffset;
    44544454    FloatSize devicePixelSnappedOffsetForThisLayer = toFloatSize(roundPointToDevicePixels(toLayoutPoint(offsetForThisLayer), deviceScaleFactor));
    44554455    // We handle accumulated subpixels through nested layers here. Since the context gets translated to device pixels,
     
    44624462
    44634463    // Now do a paint with the root layer shifted to be us.
    4464     LayoutSize adjustedSubpixelAccumulation = offsetForThisLayer - LayoutSize(devicePixelSnappedOffsetForThisLayer);
     4464    LayoutSize adjustedSubpixelOffset = offsetForThisLayer - LayoutSize(devicePixelSnappedOffsetForThisLayer);
    44654465    LayerPaintingInfo transformedPaintingInfo(this, LayoutRect(encloseRectToDevicePixels(transform.inverse().valueOr(AffineTransform()).mapRect(paintingInfo.paintDirtyRect), deviceScaleFactor)),
    4466         paintingInfo.paintBehavior, adjustedSubpixelAccumulation, paintingInfo.subtreePaintRoot, paintingInfo.overlapTestRequests);
     4466        paintingInfo.paintBehavior, adjustedSubpixelOffset, paintingInfo.subtreePaintRoot, paintingInfo.overlapTestRequests);
    44674467    paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags);
    44684468    context.setCTM(oldTransfrom);
     
    47064706        // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
    47074707        PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseBlockBackground, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer());
    4708         renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation));
     4708        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset));
    47094709
    47104710        if (localPaintingInfo.clipToDirtyRect)
     
    47734773        if (phase == PaintPhaseForeground)
    47744774            paintInfo.overlapTestRequests = localPaintingInfo.overlapTestRequests;
    4775         renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation));
     4775        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset));
    47764776       
    47774777        if (shouldClip)
     
    47904790        PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseSelfOutline, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer());
    47914791        clipToRect(context, localPaintingInfo, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius);
    4792         renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation));
     4792        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset));
    47934793        restoreClip(context, localPaintingInfo, fragment.backgroundRect);
    47944794    }
     
    48084808        // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
    48094809        PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseMask, PaintBehaviorNormal, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer());
    4810         renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation));
     4810        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset));
    48114811       
    48124812        if (localPaintingInfo.clipToDirtyRect)
     
    48274827        // Paint the clipped mask.
    48284828        PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseClippingMask, PaintBehaviorNormal, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer());
    4829         renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation));
     4829        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset));
    48304830
    48314831        if (localPaintingInfo.clipToDirtyRect)
     
    48404840            continue;
    48414841        clipToRect(context, localPaintingInfo, fragment.backgroundRect);
    4842         paintOverflowControls(context, roundedIntPoint(toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation)),
     4842        paintOverflowControls(context, roundedIntPoint(toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset)),
    48434843            snappedIntRect(fragment.backgroundRect.rect()), true);
    48444844        restoreClip(context, localPaintingInfo, fragment.backgroundRect);
     
    69826982    context.translate(-adjustedPaintOffset.x(), -adjustedPaintOffset.y());
    69836983
    6984     LayoutSize subpixelAccumulation = moveOffset - toLayoutSize(LayoutPoint(adjustedPaintOffset));
     6984    LayoutSize subpixelOffset = moveOffset - toLayoutSize(LayoutPoint(adjustedPaintOffset));
    69856985    paintDirtyRect.move(moveOffset);
    6986     paint(context, paintDirtyRect, LayoutSize(-subpixelAccumulation.width(), -subpixelAccumulation.height()), paintBehavior, nullptr, paintFlags | PaintLayerTemporaryClipRects);
     6986    paint(context, paintDirtyRect, LayoutSize(-subpixelOffset.width(), -subpixelOffset.height()), paintBehavior, nullptr, paintFlags | PaintLayerTemporaryClipRects);
    69876987    region->restoreRegionObjectsOriginalStyle();
    69886988    context.restore();
     
    70257025            clipToRect(context, paintingInfo, clipRect);
    70267026
    7027         flowThreadLayer->paintNamedFlowThreadInsideRegion(context, flowFragment, paintingInfo.paintDirtyRect, fragment.layerBounds.location() + paintingInfo.subpixelAccumulation,
     7027        flowThreadLayer->paintNamedFlowThreadInsideRegion(context, flowFragment, paintingInfo.paintDirtyRect, fragment.layerBounds.location() + paintingInfo.subpixelOffset,
    70287028            paintingInfo.paintBehavior, paintFlags);
    70297029
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r204047 r204552  
    467467    // front.  The hitTest method looks for mouse events by walking
    468468    // layers that intersect the point from front to back.
    469     void paint(GraphicsContext&, const LayoutRect& damageRect, const LayoutSize& subpixelAccumulation = LayoutSize(), PaintBehavior = PaintBehaviorNormal,
     469    void paint(GraphicsContext&, const LayoutRect& damageRect, const LayoutSize& subpixelOffset = LayoutSize(), PaintBehavior = PaintBehaviorNormal,
    470470        RenderObject* subtreePaintRoot = nullptr, PaintLayerFlags = 0);
    471471    bool hitTest(const HitTestRequest&, HitTestResult&);
     
    679679
    680680    struct LayerPaintingInfo {
    681         LayerPaintingInfo(RenderLayer* inRootLayer, const LayoutRect& inDirtyRect, PaintBehavior inPaintBehavior, const LayoutSize& inSubpixelAccumulation, RenderObject* inSubtreePaintRoot = nullptr, OverlapTestRequestMap* inOverlapTestRequests = nullptr)
     681        LayerPaintingInfo(RenderLayer* inRootLayer, const LayoutRect& inDirtyRect, PaintBehavior inPaintBehavior, const LayoutSize& inSupixelOffset, RenderObject* inSubtreePaintRoot = nullptr, OverlapTestRequestMap* inOverlapTestRequests = nullptr)
    682682            : rootLayer(inRootLayer)
    683683            , subtreePaintRoot(inSubtreePaintRoot)
    684684            , paintDirtyRect(inDirtyRect)
    685             , subpixelAccumulation(inSubpixelAccumulation)
     685            , subpixelOffset(inSupixelOffset)
    686686            , overlapTestRequests(inOverlapTestRequests)
    687687            , paintBehavior(inPaintBehavior)
     
    691691        RenderObject* subtreePaintRoot; // only paint descendants of this object
    692692        LayoutRect paintDirtyRect; // relative to rootLayer;
    693         LayoutSize subpixelAccumulation;
     693        LayoutSize subpixelOffset;
    694694        OverlapTestRequestMap* overlapTestRequests; // May be null.
    695695        PaintBehavior paintBehavior;
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r204466 r204552  
    697697}
    698698
    699 static bool devicePixelFractionGapFromRendererChanged(const LayoutSize& previousDevicePixelFractionFromRenderer, const LayoutSize& currentDevicePixelFractionFromRenderer, float deviceScaleFactor)
    700 {
    701     FloatSize previous = snapSizeToDevicePixel(previousDevicePixelFractionFromRenderer, LayoutPoint(), deviceScaleFactor);
    702     FloatSize current = snapSizeToDevicePixel(currentDevicePixelFractionFromRenderer, LayoutPoint(), deviceScaleFactor);
     699static bool subpixelOffsetFromRendererChanged(const LayoutSize& oldSubpixelOffsetFromRenderer, const LayoutSize& newSubpixelOffsetFromRenderer, float deviceScaleFactor)
     700{
     701    FloatSize previous = snapSizeToDevicePixel(oldSubpixelOffsetFromRenderer, LayoutPoint(), deviceScaleFactor);
     702    FloatSize current = snapSizeToDevicePixel(newSubpixelOffsetFromRenderer, LayoutPoint(), deviceScaleFactor);
    703703    return previous != current;
    704704}
    705 
    706 static FloatSize pixelFractionForLayerPainting(const LayoutPoint& point, float pixelSnappingFactor)
     705   
     706static FloatSize subpixelForLayerPainting(const LayoutPoint& point, float pixelSnappingFactor)
    707707{
    708708    LayoutUnit x = point.x();
     
    713713}
    714714
    715 static void calculateDevicePixelOffsetFromRenderer(const LayoutSize& rendererOffsetFromGraphicsLayer, FloatSize& devicePixelOffsetFromRenderer,
    716     LayoutSize& devicePixelFractionFromRenderer, float deviceScaleFactor)
    717 {
    718     devicePixelFractionFromRenderer = LayoutSize(pixelFractionForLayerPainting(toLayoutPoint(rendererOffsetFromGraphicsLayer), deviceScaleFactor));
    719     devicePixelOffsetFromRenderer = rendererOffsetFromGraphicsLayer - devicePixelFractionFromRenderer;
     715struct OffsetFromRenderer {
     716    // 1.2px - > { m_devicePixelOffset = 1px m_subpixelOffset = 0.2px }
     717    LayoutSize m_devicePixelOffset;
     718    LayoutSize m_subpixelOffset;
     719};
     720
     721static OffsetFromRenderer computeOffsetFromRenderer(const LayoutSize& offset, float deviceScaleFactor)
     722{
     723    OffsetFromRenderer offsetFromRenderer;
     724    offsetFromRenderer.m_subpixelOffset = LayoutSize(subpixelForLayerPainting(toLayoutPoint(offset), deviceScaleFactor));
     725    offsetFromRenderer.m_devicePixelOffset = offset - offsetFromRenderer.m_subpixelOffset;
     726    return offsetFromRenderer;
     727}
     728   
     729struct SnappedRectInfo {
     730    LayoutRect m_snappedRect;
     731    LayoutSize m_snapDelta;
     732};
     733   
     734static SnappedRectInfo snappedGraphicsLayer(const LayoutSize& offset, const LayoutSize& size, float deviceScaleFactor)
     735{
     736    SnappedRectInfo snappedGraphicsLayer;
     737    LayoutRect graphicsLayerRect = LayoutRect(toLayoutPoint(offset), size);
     738    snappedGraphicsLayer.m_snappedRect = LayoutRect(snapRectToDevicePixels(graphicsLayerRect, deviceScaleFactor));
     739    snappedGraphicsLayer.m_snapDelta = snappedGraphicsLayer.m_snappedRect.location() - toLayoutPoint(offset);
     740    return snappedGraphicsLayer;
     741}
     742
     743static LayoutSize computeOffsetFromAncestorGraphicsLayer(RenderLayer* compositedAncestor, const LayoutPoint& location)
     744{
     745    if (!compositedAncestor)
     746        return toLayoutSize(location);
     747
     748    LayoutSize ancestorRenderLayerOffsetFromAncestorGraphicsLayer = -(LayoutSize(compositedAncestor->backing()->graphicsLayer()->offsetFromRenderer())
     749        + compositedAncestor->backing()->subpixelOffsetFromRenderer());
     750    return ancestorRenderLayerOffsetFromAncestorGraphicsLayer + toLayoutSize(location);
     751}
     752
     753class ComputedOffsets {
     754public:
     755    ComputedOffsets(const RenderLayer& renderLayer, const LayoutRect& localRect, const LayoutRect& parentGraphicsLayerRect, const LayoutRect& primaryGraphicsLayerRect)
     756        : m_renderLayer(renderLayer)
     757        , m_location(localRect.location())
     758        , m_parentGraphicsLayerOffset(toLayoutSize(parentGraphicsLayerRect.location()))
     759        , m_primaryGraphicsLayerOffset(toLayoutSize(primaryGraphicsLayerRect.location()))
     760    {
     761    }
     762
     763    LayoutSize fromParentGraphicsLayer()
     764    {
     765        if (!m_fromParentGraphicsLayer)
     766            m_fromParentGraphicsLayer = fromAncestorGraphicsLayer() - m_parentGraphicsLayerOffset;
     767        return m_fromParentGraphicsLayer.value();
     768    }
     769   
     770    LayoutSize fromPrimaryGraphicsLayer()
     771    {
     772        if (!m_fromPrimaryGraphicsLayer)
     773            m_fromPrimaryGraphicsLayer = fromAncestorGraphicsLayer() - m_parentGraphicsLayerOffset - m_primaryGraphicsLayerOffset;
     774        return m_fromPrimaryGraphicsLayer.value();
     775    }
     776   
     777private:
     778    LayoutSize fromAncestorGraphicsLayer()
     779    {
     780        if (!m_fromAncestorGraphicsLayer) {
     781            RenderLayer* compositedAncestor = m_renderLayer.ancestorCompositingLayer();
     782            LayoutPoint localPointInAncestorRenderLayerCoords = m_renderLayer.convertToLayerCoords(compositedAncestor, m_location, RenderLayer::AdjustForColumns);
     783            m_fromAncestorGraphicsLayer = computeOffsetFromAncestorGraphicsLayer(compositedAncestor, localPointInAncestorRenderLayerCoords);
     784        }
     785        return m_fromAncestorGraphicsLayer.value();
     786    }
     787
     788    Optional<LayoutSize> m_fromAncestorGraphicsLayer;
     789    Optional<LayoutSize> m_fromParentGraphicsLayer;
     790    Optional<LayoutSize> m_fromPrimaryGraphicsLayer;
     791   
     792    const RenderLayer& m_renderLayer;
     793    // Location is relative to the renderer.
     794    const LayoutPoint m_location;
     795    const LayoutSize m_parentGraphicsLayerOffset;
     796    const LayoutSize m_primaryGraphicsLayerOffset;
     797};
     798
     799LayoutRect RenderLayerBacking::computePrimaryGraphicsLayerRect(const LayoutRect& parentGraphicsLayerRect) const
     800{
     801    ComputedOffsets compositedBoundsOffset(m_owningLayer, compositedBounds(), parentGraphicsLayerRect, LayoutRect());
     802    return LayoutRect(encloseRectToDevicePixels(LayoutRect(toLayoutPoint(compositedBoundsOffset.fromParentGraphicsLayer()), compositedBounds().size()),
     803        deviceScaleFactor()));
     804}
     805
     806LayoutRect RenderLayerBacking::computeParentGraphicsLayerRect(RenderLayer* compositedAncestor, LayoutSize& ancestorClippingLayerOffset) const
     807{
     808    if (!compositedAncestor || !compositedAncestor->backing())
     809        return renderer().view().documentRect();
     810
     811    auto* ancestorBackingLayer = compositedAncestor->backing();
     812    LayoutRect parentGraphicsLayerRect;
     813    if (m_owningLayer.isInsideFlowThread()) {
     814        /// FIXME: flows/columns need work.
     815        LayoutRect ancestorCompositedBounds = ancestorBackingLayer->compositedBounds();
     816        ancestorCompositedBounds.setLocation(LayoutPoint());
     817        adjustAncestorCompositingBoundsForFlowThread(ancestorCompositedBounds, compositedAncestor);
     818        parentGraphicsLayerRect = ancestorCompositedBounds;
     819    }
     820
     821    if (ancestorBackingLayer->hasClippingLayer()) {
     822        // If the compositing ancestor has a layer to clip children, we parent in that, and therefore position relative to it.
     823        LayoutRect clippingBox = clipBox(downcast<RenderBox>(compositedAncestor->renderer()));
     824        LayoutSize clippingBoxOffset = computeOffsetFromAncestorGraphicsLayer(compositedAncestor, clippingBox.location());
     825        parentGraphicsLayerRect = snappedGraphicsLayer(clippingBoxOffset, clippingBox.size(), deviceScaleFactor()).m_snappedRect;
     826    }
     827
     828#if PLATFORM(IOS)
     829    if (compositedAncestor->hasTouchScrollableOverflow()) {
     830        auto& renderBox = downcast<RenderBox>(compositedAncestor->renderer());
     831        LayoutRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(),
     832            renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(),
     833            renderBox.height() - renderBox.borderTop() - renderBox.borderBottom());
     834        ScrollOffset scrollOffset = compositedAncestor->scrollOffset();
     835        parentGraphicsLayerRect = LayoutRect((paddingBox.location() - toLayoutSize(scrollOffset)), paddingBox.size());
     836    }
     837#else
     838    if (compositedAncestor->needsCompositedScrolling()) {
     839        auto& renderBox = downcast<RenderBox>(compositedAncestor->renderer());
     840        LayoutPoint scrollOrigin(renderBox.borderLeft(), renderBox.borderTop());
     841        parentGraphicsLayerRect = LayoutRect(scrollOrigin - toLayoutSize(compositedAncestor->scrollOffset()), renderBox.borderBoxRect().size());
     842    }
     843#endif
     844
     845    if (m_ancestorClippingLayer) {
     846        // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
     847        // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
     848        // for a compositing layer, rootLayer is the layer itself.
     849        ShouldRespectOverflowClip shouldRespectOverflowClip = compositedAncestor->isolatesCompositedBlending() ? RespectOverflowClip : IgnoreOverflowClip;
     850        RenderLayer::ClipRectsContext clipRectsContext(compositedAncestor, TemporaryClipRects, IgnoreOverlayScrollbarSize, shouldRespectOverflowClip);
     851        LayoutRect parentClipRect = m_owningLayer.backgroundClipRect(clipRectsContext).rect(); // FIXME: Incorrect for CSS regions.
     852        ASSERT(!parentClipRect.isInfinite());
     853        LayoutSize clippingOffset = computeOffsetFromAncestorGraphicsLayer(compositedAncestor, parentClipRect.location());
     854        LayoutRect snappedClippingLayerRect = snappedGraphicsLayer(clippingOffset, parentClipRect.size(), deviceScaleFactor()).m_snappedRect;
     855        // The primary layer is then parented in, and positioned relative to this clipping layer.
     856        ancestorClippingLayerOffset = snappedClippingLayerRect.location() - parentGraphicsLayerRect.location();
     857        parentGraphicsLayerRect = snappedClippingLayerRect;
     858    }
     859    return parentGraphicsLayerRect;
    720860}
    721861
     
    727867
    728868    const RenderStyle& style = renderer().style();
    729 
    730869    // Set transform property, if it is not animating. We have to do this here because the transform
    731870    // is affected by the layer dimensions.
     
    744883    updateBlendMode(style);
    745884#endif
    746 
    747885    m_owningLayer.updateDescendantDependentFlags();
    748886
     
    751889    m_graphicsLayer->setPreserves3D(preserves3D);
    752890    m_graphicsLayer->setBackfaceVisibility(style.backfaceVisibility() == BackfaceVisibilityVisible);
    753     /*
    754     * GraphicsLayer: device pixel positioned, enclosing rect.
    755     * RenderLayer: subpixel positioned.
    756     * Offset from renderer (GraphicsLayer <-> RenderLayer::renderer()): subpixel based offset.
    757     *
    758     *     relativeCompositingBounds
    759     *      _______________________________________
    760     *     |\          GraphicsLayer               |
    761     *     | \                                     |
    762     *     |  \ offset from renderer: (device pixel + subpixel)
    763     *     |   \                                   |
    764     *     |    \______________________________    |
    765     *     |    | localCompositingBounds       |   |
    766     *     |    |                              |   |
    767     *     |    |   RenderLayer::renderer()    |   |
    768     *     |    |                              |   |
    769     *
    770     * localCompositingBounds: this RenderLayer relative to its renderer().
    771     * relativeCompositingBounds: this RenderLayer relative to its parent compositing layer.
    772     * enclosingRelativeCompositingBounds: this RenderLayer relative to its parent, device pixel enclosing.
    773     * rendererOffsetFromGraphicsLayer: RenderLayer::renderer()'s offset from its enclosing GraphicsLayer.
    774     * devicePixelOffsetFromRenderer: rendererOffsetFromGraphicsLayer's device pixel part. (6.9px -> 6.5px in case of 2x display)
    775     * devicePixelFractionFromRenderer: rendererOffsetFromGraphicsLayer's fractional part (6.9px -> 0.4px in case of 2x display)
    776     */
    777     float deviceScaleFactor = this->deviceScaleFactor();
    778     RenderLayer* compAncestor = m_owningLayer.ancestorCompositingLayer();
    779     // We compute everything relative to the enclosing compositing layer.
    780     LayoutRect ancestorCompositingBounds;
    781     if (compAncestor) {
    782         ASSERT(compAncestor->backing());
    783         ancestorCompositingBounds = compAncestor->backing()->compositedBounds();
    784     }
    785     LayoutRect localCompositingBounds = compositedBounds();
    786     LayoutRect relativeCompositingBounds(localCompositingBounds);
    787 
    788     LayoutPoint offsetFromParent = m_owningLayer.convertToLayerCoords(compAncestor, LayoutPoint(), RenderLayer::AdjustForColumns);
    789     // Device pixel fractions get accumulated through ancestor layers. Our painting offset is layout offset + parent's painting offset.
    790     offsetFromParent = offsetFromParent + (compAncestor ? compAncestor->backing()->devicePixelFractionFromRenderer() : LayoutSize());
    791     relativeCompositingBounds.moveBy(offsetFromParent);
    792 
    793     LayoutRect enclosingRelativeCompositingBounds = LayoutRect(encloseRectToDevicePixels(relativeCompositingBounds, deviceScaleFactor));
    794     m_compositedBoundsDeltaFromGraphicsLayer = enclosingRelativeCompositingBounds.location() - relativeCompositingBounds.location();
    795     LayoutSize rendererOffsetFromGraphicsLayer =  toLayoutSize(localCompositingBounds.location()) + m_compositedBoundsDeltaFromGraphicsLayer;
    796 
    797     FloatSize devicePixelOffsetFromRenderer;
    798     LayoutSize devicePixelFractionFromRenderer;
    799     calculateDevicePixelOffsetFromRenderer(rendererOffsetFromGraphicsLayer, devicePixelOffsetFromRenderer, devicePixelFractionFromRenderer, deviceScaleFactor);
    800     LayoutSize oldDevicePixelFractionFromRenderer = m_devicePixelFractionFromRenderer;
    801     m_devicePixelFractionFromRenderer = LayoutSize(-devicePixelFractionFromRenderer.width(), -devicePixelFractionFromRenderer.height());
    802 
    803     adjustAncestorCompositingBoundsForFlowThread(ancestorCompositingBounds, compAncestor);
    804 
    805     LayoutPoint graphicsLayerParentLocation;
    806     if (compAncestor && compAncestor->backing()->hasClippingLayer()) {
    807         // If the compositing ancestor has a layer to clip children, we parent in that, and therefore
    808         // position relative to it.
    809         // FIXME: need to do some pixel snapping here.
    810         LayoutRect clippingBox = clipBox(downcast<RenderBox>(compAncestor->renderer()));
    811         graphicsLayerParentLocation = clippingBox.location();
    812     } else if (compAncestor)
    813         graphicsLayerParentLocation = ancestorCompositingBounds.location();
    814     else
    815         graphicsLayerParentLocation = renderer().view().documentRect().location();
    816 
    817 #if PLATFORM(IOS)
    818     if (compAncestor && compAncestor->hasTouchScrollableOverflow()) {
    819         auto& renderBox = downcast<RenderBox>(compAncestor->renderer());
    820         LayoutRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(),
    821             renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(),
    822             renderBox.height() - renderBox.borderTop() - renderBox.borderBottom());
    823 
    824         ScrollOffset scrollOffset = compAncestor->scrollOffset();
    825         // FIXME: pixel snap the padding box.
    826         graphicsLayerParentLocation = paddingBox.location() - toLayoutSize(scrollOffset);
    827     }
    828 #else
    829     if (compAncestor && compAncestor->needsCompositedScrolling()) {
    830         auto& renderBox = downcast<RenderBox>(compAncestor->renderer());
    831         LayoutPoint scrollOrigin(renderBox.borderLeft(), renderBox.borderTop());
    832         graphicsLayerParentLocation = scrollOrigin - toLayoutSize(compAncestor->scrollOffset());
    833     }
    834 #endif
    835 
    836     if (compAncestor && m_ancestorClippingLayer) {
    837         // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
    838         // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
    839         // for a compositing layer, rootLayer is the layer itself.
    840         ShouldRespectOverflowClip shouldRespectOverflowClip = compAncestor->isolatesCompositedBlending() ? RespectOverflowClip : IgnoreOverflowClip;
    841         RenderLayer::ClipRectsContext clipRectsContext(compAncestor, TemporaryClipRects, IgnoreOverlayScrollbarSize, shouldRespectOverflowClip);
    842         LayoutRect parentClipRect = m_owningLayer.backgroundClipRect(clipRectsContext).rect(); // FIXME: Incorrect for CSS regions.
    843         ASSERT(!parentClipRect.isInfinite());
    844         FloatPoint enclosingClippingLayerPosition = floorPointToDevicePixels(LayoutPoint(parentClipRect.location() - graphicsLayerParentLocation), deviceScaleFactor);
    845         m_ancestorClippingLayer->setPosition(enclosingClippingLayerPosition);
    846         m_ancestorClippingLayer->setSize(parentClipRect.size());
    847 
    848         // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords.
    849         m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - offsetFromParent);
    850 
    851         // The primary layer is then parented in, and positioned relative to this clipping layer.
    852         graphicsLayerParentLocation = parentClipRect.location();
    853     }
    854 
    855     LayoutSize contentsSize = enclosingRelativeCompositingBounds.size();
     891
     892    RenderLayer* compositedAncestor = m_owningLayer.ancestorCompositingLayer();
     893    LayoutSize ancestorClippingLayerOffset;
     894    LayoutRect parentGraphicsLayerRect = computeParentGraphicsLayerRect(compositedAncestor, ancestorClippingLayerOffset);
     895    LayoutRect primaryGraphicsLayerRect = computePrimaryGraphicsLayerRect(parentGraphicsLayerRect);
     896
     897    ComputedOffsets compositedBoundsOffset(m_owningLayer, compositedBounds(), parentGraphicsLayerRect, primaryGraphicsLayerRect);
     898    m_compositedBoundsOffsetFromGraphicsLayer = compositedBoundsOffset.fromPrimaryGraphicsLayer();
     899    m_graphicsLayer->setPosition(primaryGraphicsLayerRect.location());
     900    m_graphicsLayer->setSize(primaryGraphicsLayerRect.size());
     901
     902    ComputedOffsets rendererOffset(m_owningLayer, LayoutRect(), parentGraphicsLayerRect, primaryGraphicsLayerRect);
     903    if (m_ancestorClippingLayer) {
     904        // Clipping layer is parented in the ancestor layer.
     905        m_ancestorClippingLayer->setPosition(toLayoutPoint(ancestorClippingLayerOffset));
     906        m_ancestorClippingLayer->setSize(parentGraphicsLayerRect.size());
     907        m_ancestorClippingLayer->setOffsetFromRenderer(-rendererOffset.fromParentGraphicsLayer());
     908    }
     909
    856910    if (m_contentsContainmentLayer) {
    857911        m_contentsContainmentLayer->setPreserves3D(preserves3D);
    858         FloatPoint enclosingGraphicsParentLocation = floorPointToDevicePixels(graphicsLayerParentLocation, deviceScaleFactor);
    859         m_contentsContainmentLayer->setPosition(FloatPoint(enclosingRelativeCompositingBounds.location() - enclosingGraphicsParentLocation));
     912        m_contentsContainmentLayer->setPosition(primaryGraphicsLayerRect.location());
     913        m_graphicsLayer->setPosition(FloatPoint());
    860914        // Use the same size as m_graphicsLayer so transforms behave correctly.
    861         m_contentsContainmentLayer->setSize(contentsSize);
    862         graphicsLayerParentLocation = enclosingRelativeCompositingBounds.location();
    863     }
    864 
    865     FloatPoint enclosingGraphicsParentLocation = floorPointToDevicePixels(graphicsLayerParentLocation, deviceScaleFactor);
    866     m_graphicsLayer->setPosition(FloatPoint(enclosingRelativeCompositingBounds.location() - enclosingGraphicsParentLocation));
    867     m_graphicsLayer->setSize(contentsSize);
    868     if (devicePixelOffsetFromRenderer != m_graphicsLayer->offsetFromRenderer()) {
    869         m_graphicsLayer->setOffsetFromRenderer(devicePixelOffsetFromRenderer);
     915        m_contentsContainmentLayer->setSize(primaryGraphicsLayerRect.size());
     916    }
     917
     918    // Compute renderer offset from primary graphics layer. Note that primaryGraphicsLayerRect is in parentGraphicsLayer's coordidate system which is not necessarily
     919    // the same as the ancestor graphics layer.
     920    OffsetFromRenderer primaryGraphicsLayerOffsetFromRenderer;
     921    LayoutSize oldSubpixelOffsetFromRenderer = m_subpixelOffsetFromRenderer;
     922    primaryGraphicsLayerOffsetFromRenderer = computeOffsetFromRenderer(-rendererOffset.fromPrimaryGraphicsLayer(), deviceScaleFactor());
     923    m_subpixelOffsetFromRenderer = primaryGraphicsLayerOffsetFromRenderer.m_subpixelOffset;
     924
     925    if (primaryGraphicsLayerOffsetFromRenderer.m_devicePixelOffset != m_graphicsLayer->offsetFromRenderer()) {
     926        m_graphicsLayer->setOffsetFromRenderer(primaryGraphicsLayerOffsetFromRenderer.m_devicePixelOffset);
    870927        positionOverflowControlsLayers();
    871928    }
     
    874931        // For non-root layers, background is always painted by the primary graphics layer.
    875932        ASSERT(!m_backgroundLayer);
    876         bool hadSubpixelRounding = enclosingRelativeCompositingBounds != relativeCompositingBounds;
    877         m_graphicsLayer->setContentsOpaque(!hadSubpixelRounding && m_owningLayer.backgroundIsKnownToBeOpaqueInRect(localCompositingBounds));
     933        // Subpixel offset from graphics layer or size changed.
     934        bool hadSubpixelRounding = !m_subpixelOffsetFromRenderer.isZero() || compositedBounds().size() != primaryGraphicsLayerRect.size();
     935        m_graphicsLayer->setContentsOpaque(!hadSubpixelRounding && m_owningLayer.backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
    878936    }
    879937
     
    881939    LayoutRect clippingBox;
    882940    if (GraphicsLayer* clipLayer = clippingLayer()) {
    883         // FIXME: need to do some pixel snapping here.
    884941        clippingBox = clipBox(downcast<RenderBox>(renderer()));
    885         clipLayer->setPosition(FloatPoint(clippingBox.location() - localCompositingBounds.location()));
    886         clipLayer->setSize(clippingBox.size());
    887         clipLayer->setOffsetFromRenderer(toFloatSize(clippingBox.location()));
     942        // Clipping layer is parented in the primary graphics layer.
     943        LayoutSize clipBoxOffsetFromGraphicsLayer = toLayoutSize(clippingBox.location()) + rendererOffset.fromPrimaryGraphicsLayer();
     944        SnappedRectInfo snappedClippingGraphicsLayer = snappedGraphicsLayer(clipBoxOffsetFromGraphicsLayer, clippingBox.size(), deviceScaleFactor());
     945        clipLayer->setPosition(snappedClippingGraphicsLayer.m_snappedRect.location());
     946        clipLayer->setSize(snappedClippingGraphicsLayer.m_snappedRect.size());
     947        clipLayer->setOffsetFromRenderer(toLayoutSize(clippingBox.location() - snappedClippingGraphicsLayer.m_snapDelta));
    888948
    889949        if (m_childClippingMaskLayer && !m_scrollingLayer) {
     
    900960        // Update properties that depend on layer dimensions.
    901961        FloatPoint3D transformOrigin = computeTransformOriginForPainting(downcast<RenderBox>(renderer()).borderBoxRect());
    902         // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds.
    903         FloatPoint layerOffset = roundPointToDevicePixels(offsetFromParent, deviceScaleFactor);
     962        FloatPoint layerOffset = roundPointToDevicePixels(toLayoutPoint(rendererOffset.fromParentGraphicsLayer()), deviceScaleFactor());
    904963        // Compute the anchor point, which is in the center of the renderer box unless transform-origin is set.
    905         FloatPoint3D anchor(enclosingRelativeCompositingBounds.width() ? ((layerOffset.x() - enclosingRelativeCompositingBounds.x()) + transformOrigin.x())
    906             / enclosingRelativeCompositingBounds.width() : 0.5, enclosingRelativeCompositingBounds.height() ? ((layerOffset.y() - enclosingRelativeCompositingBounds.y())
    907             + transformOrigin.y()) / enclosingRelativeCompositingBounds.height() : 0.5, transformOrigin.z());
     964        FloatPoint3D anchor(
     965            primaryGraphicsLayerRect.width() ? ((layerOffset.x() - primaryGraphicsLayerRect.x()) + transformOrigin.x()) / primaryGraphicsLayerRect.width() : 0.5,
     966            primaryGraphicsLayerRect.height() ? ((layerOffset.y() - primaryGraphicsLayerRect.y())+ transformOrigin.y()) / primaryGraphicsLayerRect.height() : 0.5,
     967            transformOrigin.z());
    908968
    909969        if (m_contentsContainmentLayer)
     
    936996    if (m_foregroundLayer) {
    937997        FloatPoint foregroundPosition;
    938         FloatSize foregroundSize = contentsSize;
     998        FloatSize foregroundSize = primaryGraphicsLayerRect.size();
    939999        FloatSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
    9401000        if (hasClippingLayer()) {
     
    9521012    if (m_backgroundLayer) {
    9531013        FloatPoint backgroundPosition;
    954         FloatSize backgroundSize = contentsSize;
     1014        FloatSize backgroundSize = primaryGraphicsLayerRect.size();
    9551015        if (backgroundLayerPaintsFixedRootBackground()) {
    9561016            const FrameView& frameView = renderer().view().frameView();
     
    9691029        // The reflection layer has the bounds of m_owningLayer.reflectionLayer(),
    9701030        // but the reflected layer is the bounds of this layer, so we need to position it appropriately.
    971         FloatRect layerBounds = compositedBounds();
     1031        FloatRect layerBounds = this->compositedBounds();
    9721032        FloatRect reflectionLayerBounds = reflectionBacking->compositedBounds();
    9731033        reflectionBacking->graphicsLayer()->setReplicatedLayerPosition(FloatPoint(layerBounds.location() - reflectionLayerBounds.location()));
     
    9811041
    9821042        // FIXME: need to do some pixel snapping here.
    983         m_scrollingLayer->setPosition(FloatPoint(paddingBox.location() - localCompositingBounds.location()));
     1043        m_scrollingLayer->setPosition(FloatPoint(paddingBox.location() - compositedBounds().location()));
    9841044
    9851045        m_scrollingLayer->setSize(roundedIntSize(LayoutSize(renderBox.clientWidth(), renderBox.clientHeight())));
     
    10451105
    10461106    // If this layer was created just for clipping or to apply perspective, it doesn't need its own backing store.
    1047     setRequiresOwnBackingStore(compositor().requiresOwnBackingStore(m_owningLayer, compAncestor, enclosingRelativeCompositingBounds, ancestorCompositingBounds));
     1107    LayoutRect ancestorCompositedBounds = compositedAncestor ? compositedAncestor->backing()->compositedBounds() : LayoutRect();
     1108    setRequiresOwnBackingStore(compositor().requiresOwnBackingStore(m_owningLayer, compositedAncestor,
     1109        LayoutRect(toLayoutPoint(compositedBoundsOffset.fromParentGraphicsLayer()), compositedBounds().size()), ancestorCompositedBounds));
    10481110#if ENABLE(FILTERS_LEVEL_2)
    10491111    updateBackdropFiltersGeometry();
     
    10511113    updateAfterWidgetResize();
    10521114
    1053     if (devicePixelFractionGapFromRendererChanged(oldDevicePixelFractionFromRenderer, m_devicePixelFractionFromRenderer, deviceScaleFactor) && canIssueSetNeedsDisplay())
     1115    if (subpixelOffsetFromRendererChanged(oldSubpixelOffsetFromRenderer, m_subpixelOffsetFromRenderer, deviceScaleFactor()) && canIssueSetNeedsDisplay())
    10541116        setContentsNeedDisplay();
    10551117
     
    10931155            LayoutRect boundingBox = m_owningLayer.boundingBox(&m_owningLayer);
    10941156            LayoutRect referenceBoxForClippedInline = LayoutRect(snapRectToDevicePixels(boundingBox, deviceScaleFactor()));
    1095             LayoutSize offset = LayoutSize(snapSizeToDevicePixel(m_devicePixelFractionFromRenderer, LayoutPoint(), deviceScaleFactor()));
     1157            LayoutSize offset = LayoutSize(snapSizeToDevicePixel(-m_subpixelOffsetFromRenderer, LayoutPoint(), deviceScaleFactor()));
    10961158            Path clipPath = m_owningLayer.computeClipPath(offset, referenceBoxForClippedInline, windRule);
    10971159
     
    11081170void RenderLayerBacking::adjustAncestorCompositingBoundsForFlowThread(LayoutRect& ancestorCompositingBounds, const RenderLayer* compositingAncestor) const
    11091171{
    1110     if (!m_owningLayer.isInsideFlowThread())
    1111         return;
    1112 
    11131172    RenderLayer* flowThreadLayer = m_owningLayer.isInsideOutOfFlowThread() ? m_owningLayer.stackingContainer() : nullptr;
    11141173    if (flowThreadLayer && flowThreadLayer->isRenderFlowThread()) {
     
    21032162LayoutSize RenderLayerBacking::contentOffsetInCompostingLayer() const
    21042163{
    2105     return LayoutSize(-m_compositedBounds.x() - m_compositedBoundsDeltaFromGraphicsLayer.width(), -m_compositedBounds.y() - m_compositedBoundsDeltaFromGraphicsLayer.height());
     2164    return LayoutSize(-m_compositedBounds.x() + m_compositedBoundsOffsetFromGraphicsLayer.width(), -m_compositedBounds.y() + m_compositedBoundsOffsetFromGraphicsLayer.height());
    21062165}
    21072166
     
    22512310    if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
    22522311        FloatRect layerDirtyRect = pixelSnappedRectForPainting;
    2253         layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer() + m_devicePixelFractionFromRenderer);
     2312        layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
    22542313        m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
    22552314    }
     
    22572316    if (m_foregroundLayer && m_foregroundLayer->drawsContent()) {
    22582317        FloatRect layerDirtyRect = pixelSnappedRectForPainting;
    2259         layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer() + m_devicePixelFractionFromRenderer);
     2318        layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
    22602319        m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
    22612320    }
     
    22642323    if (m_backgroundLayer && m_backgroundLayer->drawsContent()) {
    22652324        FloatRect layerDirtyRect = pixelSnappedRectForPainting;
    2266         layerDirtyRect.move(-m_backgroundLayer->offsetFromRenderer() + m_devicePixelFractionFromRenderer);
     2325        layerDirtyRect.move(-m_backgroundLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
    22672326        m_backgroundLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
    22682327    }
     
    22702329    if (m_maskLayer && m_maskLayer->drawsContent()) {
    22712330        FloatRect layerDirtyRect = pixelSnappedRectForPainting;
    2272         layerDirtyRect.move(-m_maskLayer->offsetFromRenderer() + m_devicePixelFractionFromRenderer);
     2331        layerDirtyRect.move(-m_maskLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
    22732332        m_maskLayer->setNeedsDisplayInRect(layerDirtyRect, shouldClip);
    22742333    }
     
    22822341    if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent()) {
    22832342        FloatRect layerDirtyRect = pixelSnappedRectForPainting;
    2284         layerDirtyRect.move(-m_scrollingContentsLayer->offsetFromRenderer() + m_devicePixelFractionFromRenderer);
     2343        layerDirtyRect.move(-m_scrollingContentsLayer->offsetFromRenderer() - m_subpixelOffsetFromRenderer);
    22852344#if PLATFORM(IOS)
    22862345        // Account for the fact that RenderLayerBacking::updateGeometry() bakes scrollOffset into offsetFromRenderer on iOS,
     
    23362395
    23372396    // FIXME: GraphicsLayers need a way to split for RenderRegions.
    2338     RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, m_devicePixelFractionFromRenderer);
     2397    RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, -m_subpixelOffsetFromRenderer);
    23392398    m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags);
    23402399
     
    23602419    // The dirtyRect is in the coords of the painting root.
    23612420    FloatRect adjustedClipRect = clip;
    2362     adjustedClipRect.move(-m_devicePixelFractionFromRenderer);
     2421    adjustedClipRect.move(m_subpixelOffsetFromRenderer);
    23632422    IntRect dirtyRect = enclosingIntRect(adjustedClipRect);
    23642423
  • trunk/Source/WebCore/rendering/RenderLayerBacking.h

    r198374 r204552  
    217217    bool needsPixelAligment() const override { return !m_isMainFrameRenderViewLayer; }
    218218
     219    LayoutSize subpixelOffsetFromRenderer() const { return m_subpixelOffsetFromRenderer; }
     220
    219221#if PLATFORM(IOS)
    220222    bool needsIOSDumpRenderTreeMainFrameRenderViewLayerIsAlwaysOpaqueHack(const GraphicsLayer&) const override;
     
    248250    WEBCORE_EXPORT void setIsTrackingDisplayListReplay(bool);
    249251    WEBCORE_EXPORT String replayDisplayListAsText(DisplayList::AsTextFlags) const;
    250 
    251     LayoutSize devicePixelFractionFromRenderer() const { return m_devicePixelFractionFromRenderer; }
    252252
    253253private:
     
    344344
    345345    bool canIssueSetNeedsDisplay() const { return !paintsIntoWindow() && !paintsIntoCompositedAncestor(); }
     346    LayoutRect computeParentGraphicsLayerRect(RenderLayer* compositedAncestor, LayoutSize& ancestorClippingLayerOffset) const;
     347    LayoutRect computePrimaryGraphicsLayerRect(const LayoutRect& parentGraphicsLayerRect) const;
    346348
    347349    RenderLayer& m_owningLayer;
     
    367369
    368370    LayoutRect m_compositedBounds;
    369     LayoutSize m_devicePixelFractionFromRenderer;
    370     LayoutSize m_compositedBoundsDeltaFromGraphicsLayer; // This is the (subpixel) distance between the edge of the graphics layer and the layer bounds.
     371    LayoutSize m_subpixelOffsetFromRenderer; // This is the subpixel distance between the primary graphics layer and the associated renderer's bounds.
     372    LayoutSize m_compositedBoundsOffsetFromGraphicsLayer; // This is the subpixel distance between the primary graphics layer and the render layer bounds.
    371373
    372374    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.