Changeset 206188 in webkit


Ignore:
Timestamp:
Sep 20, 2016 5:25:07 PM (8 years ago)
Author:
Alan Bujtas
Message:

REGRESSION (r204552): Athlete search on Strava gives bad rendering.
https://bugs.webkit.org/show_bug.cgi?id=162250

Reviewed by Simon Fraser.

Source/WebCore:

Test: fast/layers/blank-content-when-child-layer-is-at-negative-big-number.html

  • platform/graphics/LayoutRect.cpp:

(WebCore::LayoutRect::checkedUnite):

  • platform/graphics/LayoutRect.h:

(WebCore::LayoutRect::isMaxXMaxYRepresentable):
(WebCore::LayoutRect::maxXMaxYCorner): Deleted.

  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::calculateClipRects):

LayoutTests:

While computing the size of a particular layer, we unite the content size and the descendant layers' size.
If a descendant layer is positioned far off, the computed rectangle might not fully cover the original rectangles.
This happens when the 2 rectangles' distance is close to the maximum LayoutUnit value.
It's fairly common technic to put some content offscreen (top: -99999999px;). In order to keep the main content
visible, we need to ensure that the parent layer never gets cut off, while uniting it with the descendant layers.

  • fast/layers/blank-content-when-child-layer-is-at-negative-big-number-expected.html: Added.
  • fast/layers/blank-content-when-child-layer-is-at-negative-big-number.html: Added.
Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r206186 r206188  
     12016-09-20  Zalan Bujtas  <zalan@apple.com>
     2
     3        REGRESSION (r204552): Athlete search on Strava gives bad rendering.
     4        https://bugs.webkit.org/show_bug.cgi?id=162250
     5
     6        Reviewed by Simon Fraser.
     7
     8        While computing the size of a particular layer, we unite the content size and the descendant layers' size.
     9        If a descendant layer is positioned far off, the computed rectangle might not fully cover the original rectangles.
     10        This happens when the 2 rectangles' distance is close to the maximum LayoutUnit value.
     11        It's fairly common technic to put some content offscreen (top: -99999999px;). In order to keep the main content
     12        visible, we need to ensure that the parent layer never gets cut off, while uniting it with the descendant layers.
     13
     14        * fast/layers/blank-content-when-child-layer-is-at-negative-big-number-expected.html: Added.
     15        * fast/layers/blank-content-when-child-layer-is-at-negative-big-number.html: Added.
     16
    1172016-09-20  Jer Noble  <jer.noble@apple.com>
    218
  • trunk/Source/WebCore/ChangeLog

    r206186 r206188  
     12016-09-20  Zalan Bujtas  <zalan@apple.com>
     2
     3        REGRESSION (r204552): Athlete search on Strava gives bad rendering.
     4        https://bugs.webkit.org/show_bug.cgi?id=162250
     5
     6        Reviewed by Simon Fraser.
     7
     8        Test: fast/layers/blank-content-when-child-layer-is-at-negative-big-number.html
     9
     10        * platform/graphics/LayoutRect.cpp:
     11        (WebCore::LayoutRect::checkedUnite):
     12        * platform/graphics/LayoutRect.h:
     13        (WebCore::LayoutRect::isMaxXMaxYRepresentable):
     14        (WebCore::LayoutRect::maxXMaxYCorner): Deleted.
     15        * rendering/RenderLayer.cpp:
     16        (WebCore::RenderLayer::calculateClipRects):
     17
    1182016-09-20  Jer Noble  <jer.noble@apple.com>
    219
  • trunk/Source/WebCore/platform/graphics/LayoutRect.cpp

    r191216 r206188  
    8989}
    9090
     91bool LayoutRect::checkedUnite(const LayoutRect& other)
     92{
     93    if (other.isEmpty())
     94        return true;
     95    if (isEmpty()) {
     96        *this = other;
     97        return true;
     98    }
     99    if (!isMaxXMaxYRepresentable() || !other.isMaxXMaxYRepresentable())
     100        return false;
     101    FloatPoint topLeft = FloatPoint(std::min<float>(x(), other.x()), std::min<float>(y(), other.y()));
     102    FloatPoint bottomRight = FloatPoint(std::max<float>(maxX(), other.maxX()), std::max<float>(maxY(), other.maxY()));
     103    FloatSize size = bottomRight - topLeft;
     104   
     105    if (size.width() >= LayoutUnit::nearlyMax() || size.height() >= LayoutUnit::nearlyMax())
     106        return false;
     107    m_location = LayoutPoint(topLeft);
     108    m_size = LayoutSize(size);
     109    return true;
     110}
     111
    91112void LayoutRect::uniteIfNonZero(const LayoutRect& other)
    92113{
  • trunk/Source/WebCore/platform/graphics/LayoutRect.h

    r191623 r206188  
    127127    LayoutPoint minXMaxYCorner() const { return LayoutPoint(m_location.x(), m_location.y() + m_size.height()); } // typically bottomLeft
    128128    LayoutPoint maxXMaxYCorner() const { return LayoutPoint(m_location.x() + m_size.width(), m_location.y() + m_size.height()); } // typically bottomRight
     129    bool isMaxXMaxYRepresentable() const
     130    {
     131        FloatRect rect = *this;
     132        float maxX = rect.maxX();
     133        float maxY = rect.maxY();
     134        return maxX > LayoutUnit::nearlyMin() && maxX < LayoutUnit::nearlyMax() && maxY > LayoutUnit::nearlyMin() && maxY < LayoutUnit::nearlyMax();
     135    }
    129136   
    130137    bool intersects(const LayoutRect&) const;
     
    140147    WEBCORE_EXPORT void unite(const LayoutRect&);
    141148    void uniteIfNonZero(const LayoutRect&);
     149    bool checkedUnite(const LayoutRect&);
    142150
    143151    void inflateX(LayoutUnit dx)
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r206100 r206188  
    60046004#endif
    60056005
     6006    auto computeLayersUnion = [this, &unionBounds, flags, descendantFlags] (const RenderLayer& childLayer) {
     6007        if (!(flags & IncludeCompositedDescendants) && childLayer.isComposited())
     6008            return;
     6009        LayoutRect childBounds = childLayer.calculateLayerBounds(this, childLayer.offsetFromAncestor(this), descendantFlags);
     6010        // Ignore child layer (and behave as if we had overflow: hidden) when it is positioned off the parent layer so much
     6011        // that we hit the max LayoutUnit value.
     6012        unionBounds.checkedUnite(childBounds);
     6013    };
     6014
    60066015    if (Vector<RenderLayer*>* negZOrderList = this->negZOrderList()) {
    6007         for (auto* curLayer : *negZOrderList) {
    6008             if (flags & IncludeCompositedDescendants || !curLayer->isComposited()) {
    6009                 LayoutRect childUnionBounds = curLayer->calculateLayerBounds(this, curLayer->offsetFromAncestor(this), descendantFlags);
    6010                 unionBounds.unite(childUnionBounds);
    6011             }
    6012         }
     6016        for (auto* childLayer : *negZOrderList)
     6017            computeLayersUnion(*childLayer);
    60136018    }
    60146019
    60156020    if (Vector<RenderLayer*>* posZOrderList = this->posZOrderList()) {
    6016         for (auto* curLayer : *posZOrderList) {
     6021        for (auto* childLayer : *posZOrderList) {
    60176022            // The RenderNamedFlowThread is ignored when we calculate the bounds of the RenderView.
    6018             if ((flags & IncludeCompositedDescendants || !curLayer->isComposited()) && !curLayer->isFlowThreadCollectingGraphicsLayersUnderRegions()) {
    6019                 LayoutRect childUnionBounds = curLayer->calculateLayerBounds(this, curLayer->offsetFromAncestor(this), descendantFlags);
    6020                 unionBounds.unite(childUnionBounds);
    6021             }
     6023            if (childLayer->isFlowThreadCollectingGraphicsLayersUnderRegions())
     6024                continue;
     6025            computeLayersUnion(*childLayer);
    60226026        }
    60236027    }
    60246028
    60256029    if (Vector<RenderLayer*>* normalFlowList = this->normalFlowList()) {
    6026         for (auto* curLayer : *normalFlowList) {
     6030        for (auto* childLayer : *normalFlowList) {
    60276031            // RenderView will always return the size of the document, before reaching this point,
    60286032            // so there's no way we could hit a RenderNamedFlowThread here.
    6029             ASSERT(!curLayer->isFlowThreadCollectingGraphicsLayersUnderRegions());
    6030             if (flags & IncludeCompositedDescendants || !curLayer->isComposited()) {
    6031                 LayoutRect curAbsBounds = curLayer->calculateLayerBounds(this, curLayer->offsetFromAncestor(this), descendantFlags);
    6032                 unionBounds.unite(curAbsBounds);
    6033             }
     6033            ASSERT(!childLayer->isFlowThreadCollectingGraphicsLayersUnderRegions());
     6034            computeLayersUnion(*childLayer);
    60346035        }
    60356036    }
Note: See TracChangeset for help on using the changeset viewer.