⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 118562 in webkit


Ignore:
Timestamp:
May 25, 2012, 2:17:33 PM (14 years ago)
Author:
Simon Fraser
Message:

Cache absolute clip rects on RenderLayer for compositing overlap testing
https://bugs.webkit.org/show_bug.cgi?id=87212

Reviewed by Dave Hyatt.

Enhance the cache of ClipRects on RenderLayers to store three
different types of ClipRects, rather than just one.

We need to compute clip rects relative to different layers
for different purposes. For painting, we compute relative to
the compositing layer which is acting as a painting root.
For hit testing, we compute relative to the root, except
for transformed layers. For composting overlap testing, we
compute relative to the root ("absolute"). At other times, we do one-off
computation which we never want to cache ("temporary clip rects").

This change allows us to cache rects for hit testing, and for
compositing overlap testing. This has huge performance benefits
on some pages (bug 84410).

This change also makes ClipRects not arena-allocated, so we
can use RefPtr<ClipRect>.

No testable behavior change.

  • rendering/RenderBoxModelObject.cpp:

(WebCore::RenderBoxModelObject::willBeDestroyed): No need for the
explicit clipRects teardown, since clipRects don't need a live
RenderObject for arena-based destruction.

  • rendering/RenderLayer.cpp: Remove arena-related new and delete.

(WebCore::RenderLayer::RenderLayer): No need to explicitly initialize m_clipRects,
since it's an OwnPtr now.
(WebCore::RenderLayer::~RenderLayer): No explicit clipRect teardown required.
(WebCore::RenderLayer::clippingRootForPainting): Renamed to make its purpose
more obvious.
(WebCore::RenderLayer::paintLayer): Use the TemporaryClipRects type when necessary.
(WebCore::RenderLayer::paintLayerContents): Ditto
(WebCore::RenderLayer::hitTestLayer): No longer need to use temporary clipRects when
hit testing since we cache clip rects for hit testing.
(WebCore::RenderLayer::updateClipRects): Take a ClipRectsType and pass it through.
(WebCore::RenderLayer::calculateClipRects): Ditto
(WebCore::RenderLayer::parentClipRects): Ditto
(WebCore::RenderLayer::backgroundClipRect): Ditto
(WebCore::RenderLayer::calculateRects): Take ClipRectsType, which obviates temporaryClipRects.
(WebCore::RenderLayer::childrenClipRect): Use clippingRootForPainting().
(WebCore::RenderLayer::selfClipRect): Ditto
(WebCore::RenderLayer::localClipRect): Ditto
(WebCore::RenderLayer::clearClipRectsIncludingDescendants): Take a type of clip rect to clear
(include all). Allows us to just clear painting clip rects.
(WebCore::RenderLayer::clearClipRects):

  • rendering/RenderLayer.h:

(WebCore::ClipRects::create): We don't use RefCounted<> in order to use a bit in
the refCount for a flag. Add create() method.
(WebCore::ClipRects::deref): No longer arena-allocated.
(WebCore::ClipRectsCache::ClipRectsCache): Struct that holds a small
array of the 3 types of clipRects (and, in debug, the layer relative
to which they were computed).
(WebCore::RenderLayer::clipRects):

  • rendering/RenderLayerBacking.cpp:

(WebCore::RenderLayerBacking::updateCompositedBounds): Use AbsoluteClipRects; rootLayer
is always the RenderView's layer here.
(WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): Use TemporaryClipRects.
(WebCore::RenderLayerBacking::setRequiresOwnBackingStore): When this variable changes,
we need to invalidate painting clipRects, since it affects the ancestor relative to which
those rects are computed.

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

(WebCore::RenderLayerCompositor::updateBacking): When the composited state
of a layer changes, we have to clear all descendant clip rects, since this
can affect the layers relative to which clip rects are computed.
(WebCore::RenderLayerCompositor::addToOverlapMap): Use AbsoluteClipRects.
(WebCore::RenderLayerCompositor::computeCompositingRequirements): No need
to call updateLayerPosition(), since that should have always happened after
layout. That call cleared clip rects, so removing it is very beneficial.
(WebCore::RenderLayerCompositor::clippedByAncestor): Use TemporaryClipRects.

  • rendering/RenderTreeAsText.cpp:

(WebCore::writeLayers): Use TemporaryClipRects.

Location:
trunk/Source/WebCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r118553 r118562  
     12012-05-25  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Cache absolute clip rects on RenderLayer for compositing overlap testing
     4        https://bugs.webkit.org/show_bug.cgi?id=87212
     5
     6        Reviewed by Dave Hyatt.
     7       
     8        Enhance the cache of ClipRects on RenderLayers to store three
     9        different types of ClipRects, rather than just one.
     10       
     11        We need to compute clip rects relative to different layers
     12        for different purposes. For painting, we compute relative to
     13        the compositing layer which is acting as a painting root.
     14        For hit testing, we compute relative to the root, except
     15        for transformed layers. For composting overlap testing, we
     16        compute relative to the root ("absolute"). At other times, we do one-off
     17        computation which we never want to cache ("temporary clip rects").
     18       
     19        This change allows us to cache rects for hit testing, and for
     20        compositing overlap testing. This has huge performance benefits
     21        on some pages (bug 84410).
     22       
     23        This change also makes ClipRects not arena-allocated, so we
     24        can use RefPtr<ClipRect>.
     25
     26        No testable behavior change.
     27
     28        * rendering/RenderBoxModelObject.cpp:
     29        (WebCore::RenderBoxModelObject::willBeDestroyed): No need for the
     30        explicit clipRects teardown, since clipRects don't need a live
     31        RenderObject for arena-based destruction.
     32
     33        * rendering/RenderLayer.cpp: Remove arena-related new and delete.
     34        (WebCore::RenderLayer::RenderLayer): No need to explicitly initialize m_clipRects,
     35        since it's an OwnPtr now.
     36        (WebCore::RenderLayer::~RenderLayer): No explicit clipRect teardown required.
     37        (WebCore::RenderLayer::clippingRootForPainting): Renamed to make its purpose
     38        more obvious.
     39        (WebCore::RenderLayer::paintLayer): Use the TemporaryClipRects type when necessary.
     40        (WebCore::RenderLayer::paintLayerContents): Ditto
     41        (WebCore::RenderLayer::hitTestLayer): No longer need to use temporary clipRects when
     42        hit testing since we cache clip rects for hit testing.
     43        (WebCore::RenderLayer::updateClipRects): Take a ClipRectsType and pass it through.
     44        (WebCore::RenderLayer::calculateClipRects): Ditto
     45        (WebCore::RenderLayer::parentClipRects): Ditto
     46        (WebCore::RenderLayer::backgroundClipRect): Ditto
     47        (WebCore::RenderLayer::calculateRects): Take ClipRectsType, which obviates temporaryClipRects.
     48        (WebCore::RenderLayer::childrenClipRect): Use clippingRootForPainting().
     49        (WebCore::RenderLayer::selfClipRect): Ditto
     50        (WebCore::RenderLayer::localClipRect): Ditto
     51        (WebCore::RenderLayer::clearClipRectsIncludingDescendants): Take a type of clip rect to clear
     52        (include all). Allows us to just clear painting clip rects.
     53        (WebCore::RenderLayer::clearClipRects):
     54
     55        * rendering/RenderLayer.h:
     56        (WebCore::ClipRects::create): We don't use RefCounted<> in order to use a bit in
     57        the refCount for a flag. Add create() method.
     58        (WebCore::ClipRects::deref): No longer arena-allocated.
     59        (WebCore::ClipRectsCache::ClipRectsCache): Struct that holds a small
     60        array of the 3 types of clipRects (and, in debug, the layer relative
     61        to which they were computed).
     62        (WebCore::RenderLayer::clipRects):
     63
     64        * rendering/RenderLayerBacking.cpp:
     65        (WebCore::RenderLayerBacking::updateCompositedBounds): Use AbsoluteClipRects; rootLayer
     66        is always the RenderView's layer here.
     67        (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): Use TemporaryClipRects.
     68        (WebCore::RenderLayerBacking::setRequiresOwnBackingStore): When this variable changes,
     69        we need to invalidate painting clipRects, since it affects the ancestor relative to which
     70        those rects are computed.
     71
     72        * rendering/RenderLayerBacking.h:
     73        * rendering/RenderLayerCompositor.cpp:
     74        (WebCore::RenderLayerCompositor::updateBacking): When the composited state
     75        of a layer changes, we have to clear all descendant clip rects, since this
     76        can affect the layers relative to which clip rects are computed.
     77        (WebCore::RenderLayerCompositor::addToOverlapMap): Use AbsoluteClipRects.
     78        (WebCore::RenderLayerCompositor::computeCompositingRequirements): No need
     79        to call updateLayerPosition(), since that should have always happened after
     80        layout. That call cleared clip rects, so removing it is very beneficial.
     81        (WebCore::RenderLayerCompositor::clippedByAncestor): Use TemporaryClipRects.
     82
     83        * rendering/RenderTreeAsText.cpp:
     84        (WebCore::writeLayers): Use TemporaryClipRects.
     85
    1862012-05-25  Dean Jackson  <dino@apple.com>
    287
  • trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp

    r118551 r118562  
    346346void RenderBoxModelObject::willBeDestroyed()
    347347{
    348     // This must be done before we destroy the RenderObject.
    349     if (m_layer)
    350         m_layer->clearClipRects();
    351 
    352348    // A continuation of this RenderObject should be destroyed at subclasses.
    353349    ASSERT(!continuation());
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r118338 r118562  
    126126const int MinimumHeightWhileResizing = 40;
    127127
    128 void* ClipRects::operator new(size_t sz, RenderArena* renderArena)
    129 {
    130     return renderArena->allocate(sz);
    131 }
    132 
    133 void ClipRects::operator delete(void* ptr, size_t sz)
    134 {
    135     // Stash size where destroy can find it.
    136     *(size_t *)ptr = sz;
    137 }
    138 
    139 void ClipRects::destroy(RenderArena* renderArena)
    140 {
    141     delete this;
    142    
    143     // Recover the size left there for us by operator delete and free the memory.
    144     renderArena->free(*(size_t *)this, this);
    145 }
    146 
    147128RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
    148129    : m_inResizeMode(false)
     
    181162    , m_negZOrderList(0)
    182163    , m_normalFlowList(0)
    183     , m_clipRects(0)
    184 #ifndef NDEBUG
    185     , m_clipRectsRoot(0)
    186 #endif
    187164    , m_marquee(0)
    188165    , m_staticInlinePosition(0)
     
    252229    clearBacking(true);
    253230#endif
    254    
    255     // Make sure we have no lingering clip rects.
    256     ASSERT(!m_clipRects);
    257231   
    258232    if (m_scrollCorner)
     
    10711045#endif
    10721046   
    1073 RenderLayer* RenderLayer::clippingRoot() const
     1047RenderLayer* RenderLayer::clippingRootForPainting() const
    10741048{
    10751049#if USE(ACCELERATED_COMPOSITING)
     
    29362910        ClipRect clipRect = paintDirtyRect;
    29372911        if (parent()) {
    2938             clipRect = backgroundClipRect(rootLayer, region, paintFlags & PaintLayerTemporaryClipRects);
     2912            clipRect = backgroundClipRect(rootLayer, region, (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects);
    29392913            clipRect.intersect(paintDirtyRect);
    29402914       
     
    30453019   
    30463020    if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
    3047         calculateRects(rootLayer, region, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect, localPaintFlags & PaintLayerTemporaryClipRects);
     3021        calculateRects(rootLayer, region, (localPaintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect);
    30483022        paintOffset = toPoint(layerBounds.location() - renderBoxLocation());
    30493023    }
     
    34533427    // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate.
    34543428
    3455     bool useTemporaryClipRects = false;
    3456 #if USE(ACCELERATED_COMPOSITING)
    3457     useTemporaryClipRects = compositor()->inCompositingMode();
    3458 #endif
    3459     useTemporaryClipRects |= renderer()->view()->frameView()->containsScrollableAreaWithOverlayScrollbars();
     3429    bool useTemporaryClipRects = renderer()->view()->frameView()->containsScrollableAreaWithOverlayScrollbars();
    34603430
    34613431    LayoutRect hitTestArea = result.rectForPoint(hitTestPoint);
     
    34653435        // Make sure the parent's clip rects have been calculated.
    34663436        if (parent()) {
    3467             ClipRect clipRect = backgroundClipRect(rootLayer, result.region(), useTemporaryClipRects, IncludeOverlayScrollbarSize);
     3437            ClipRect clipRect = backgroundClipRect(rootLayer, result.region(), useTemporaryClipRects ? TemporaryClipRects : RootRelativeClipRects, IncludeOverlayScrollbarSize);
    34683438            // Go ahead and test the enclosing clip now.
    34693439            if (!clipRect.intersects(hitTestArea))
     
    35263496    ClipRect fgRect;
    35273497    ClipRect outlineRect;
    3528     calculateRects(rootLayer, result.region(), hitTestRect, layerBounds, bgRect, fgRect, outlineRect, useTemporaryClipRects, IncludeOverlayScrollbarSize);
     3498    calculateRects(rootLayer, result.region(), useTemporaryClipRects ? TemporaryClipRects : RootRelativeClipRects, hitTestRect, layerBounds, bgRect, fgRect, outlineRect, IncludeOverlayScrollbarSize);
    35293499   
    35303500    // The following are used for keeping track of the z-depth of the hit point of 3d-transformed
     
    37973767}
    37983768
    3799 void RenderLayer::updateClipRects(const RenderLayer* rootLayer, RenderRegion* region, OverlayScrollbarSizeRelevancy relevancy)
    3800 {
    3801     if (m_clipRects) {
    3802         ASSERT(rootLayer == m_clipRectsRoot);
     3769void RenderLayer::updateClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, OverlayScrollbarSizeRelevancy relevancy)
     3770{
     3771    ASSERT(clipRectsType < NumCachedClipRectsTypes);
     3772    if (m_clipRectsCache && m_clipRectsCache->m_clipRects[clipRectsType]) {
     3773        ASSERT(rootLayer == m_clipRectsCache->m_clipRectsRoot[clipRectsType]);
    38033774        return; // We have the correct cached value.
    38043775    }
     
    38083779    RenderLayer* parentLayer = rootLayer != this ? parent() : 0;
    38093780    if (parentLayer)
    3810         parentLayer->updateClipRects(rootLayer, region, relevancy);
     3781        parentLayer->updateClipRects(rootLayer, region, clipRectsType, relevancy);
    38113782
    38123783    ClipRects clipRects;
    3813     calculateClipRects(rootLayer, region, clipRects, true, relevancy);
    3814 
    3815     if (parentLayer && parentLayer->clipRects() && clipRects == *parentLayer->clipRects())
    3816         m_clipRects = parentLayer->clipRects();
     3784    calculateClipRects(rootLayer, region, clipRectsType, clipRects, relevancy);
     3785
     3786    if (!m_clipRectsCache)
     3787        m_clipRectsCache = adoptPtr(new ClipRectsCache);
     3788
     3789    if (parentLayer && parentLayer->clipRects(clipRectsType) && clipRects == *parentLayer->clipRects(clipRectsType))
     3790        m_clipRectsCache->m_clipRects[clipRectsType] = parentLayer->clipRects(clipRectsType);
    38173791    else
    3818         m_clipRects = new (renderer()->renderArena()) ClipRects(clipRects);
    3819     m_clipRects->ref();
     3792        m_clipRectsCache->m_clipRects[clipRectsType] = ClipRects::create(clipRects);
     3793
     3794    m_clipRectsCache->m_clipRects[clipRectsType]->ref();
    38203795#ifndef NDEBUG
    3821     m_clipRectsRoot = rootLayer;
    3822 #endif
    3823 }
    3824 
    3825 void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRects& clipRects,
    3826     bool useCached, OverlayScrollbarSizeRelevancy relevancy) const
     3796    m_clipRectsCache->m_clipRectsRoot[clipRectsType] = rootLayer;
     3797#endif
     3798}
     3799
     3800void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, ClipRects& clipRects, OverlayScrollbarSizeRelevancy relevancy) const
    38273801{
    38283802    if (!parent()) {
     
    38313805        return;
    38323806    }
     3807   
     3808    bool useCached = clipRectsType != TemporaryClipRects;
    38333809
    38343810    // For transformed layers, the root layer was shifted to be us, so there is no need to
     
    38383814    // Ensure that our parent's clip has been calculated so that we can examine the values.
    38393815    if (parentLayer) {
    3840         if (useCached && parentLayer->clipRects())
    3841             clipRects = *parentLayer->clipRects();
     3816        if (useCached && parentLayer->clipRects(clipRectsType))
     3817            clipRects = *parentLayer->clipRects(clipRectsType);
    38423818        else
    3843             parentLayer->calculateClipRects(rootLayer, region, clipRects);
     3819            parentLayer->calculateClipRects(rootLayer, region, clipRectsType, clipRects);
    38443820    } else
    38453821        clipRects.reset(PaintInfo::infiniteRect());
     
    38893865}
    38903866
    3891 void RenderLayer::parentClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRects& clipRects, bool temporaryClipRects, OverlayScrollbarSizeRelevancy relevancy) const
     3867void RenderLayer::parentClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, ClipRects& clipRects, OverlayScrollbarSizeRelevancy relevancy) const
    38923868{
    38933869    ASSERT(parent());
    3894     if (temporaryClipRects) {
    3895         parent()->calculateClipRects(rootLayer, region, clipRects, false, relevancy);
    3896         return;
    3897     }
    3898 
    3899     parent()->updateClipRects(rootLayer, region, relevancy);
    3900     clipRects = *parent()->clipRects();
     3870    if (clipRectsType == TemporaryClipRects) {
     3871        parent()->calculateClipRects(rootLayer, region, clipRectsType, clipRects, relevancy);
     3872        return;
     3873    }
     3874
     3875    parent()->updateClipRects(rootLayer, region, clipRectsType, relevancy);
     3876    clipRects = *parent()->clipRects(clipRectsType);
    39013877}
    39023878
     
    39123888}
    39133889
    3914 ClipRect RenderLayer::backgroundClipRect(const RenderLayer* rootLayer, RenderRegion* region, bool temporaryClipRects, OverlayScrollbarSizeRelevancy relevancy) const
     3890ClipRect RenderLayer::backgroundClipRect(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, OverlayScrollbarSizeRelevancy relevancy) const
    39153891{
    39163892    ASSERT(parent());
    39173893    ClipRects parentRects;
    3918     parentClipRects(rootLayer, region, parentRects, temporaryClipRects, relevancy);
     3894    parentClipRects(rootLayer, region, clipRectsType, parentRects, relevancy);
    39193895    ClipRect backgroundClipRect = backgroundClipRectForPosition(parentRects, renderer()->style()->position());
    39203896    RenderView* view = renderer()->view();
     
    39283904}
    39293905
    3930 void RenderLayer::calculateRects(const RenderLayer* rootLayer, RenderRegion* region, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
    3931                                  ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, bool temporaryClipRects,
    3932                                  OverlayScrollbarSizeRelevancy relevancy) const
     3906void RenderLayer::calculateRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
     3907                                 ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, OverlayScrollbarSizeRelevancy relevancy) const
    39333908{
    39343909    if (rootLayer != this && parent()) {
    3935         backgroundRect = backgroundClipRect(rootLayer, region, temporaryClipRects, relevancy);
     3910        backgroundRect = backgroundClipRect(rootLayer, region, clipRectsType, relevancy);
    39363911        backgroundRect.intersect(paintDirtyRect);
    39373912    } else
     
    39863961    // FIXME: Regions not accounted for.
    39873962    RenderView* renderView = renderer()->view();
    3988     RenderLayer* clippingRootLayer = clippingRoot();
     3963    RenderLayer* clippingRootLayer = clippingRootForPainting();
    39893964    LayoutRect layerBounds;
    39903965    ClipRect backgroundRect, foregroundRect, outlineRect;
    3991     calculateRects(clippingRootLayer, 0, renderView->unscaledDocumentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
     3966    calculateRects(clippingRootLayer, 0, PaintingClipRects, renderView->unscaledDocumentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
    39923967    return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(foregroundRect.rect())).enclosingBoundingBox();
    39933968}
     
    39983973    // FIXME: Regions not accounted for.
    39993974    RenderView* renderView = renderer()->view();
    4000     RenderLayer* clippingRootLayer = clippingRoot();
     3975    RenderLayer* clippingRootLayer = clippingRootForPainting();
    40013976    LayoutRect layerBounds;
    40023977    ClipRect backgroundRect, foregroundRect, outlineRect;
    4003     calculateRects(clippingRootLayer, 0, renderView->documentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
     3978    calculateRects(clippingRootLayer, 0, PaintingClipRects, renderView->documentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
    40043979    return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(backgroundRect.rect())).enclosingBoundingBox();
    40053980}
     
    40093984    // FIXME: border-radius not accounted for.
    40103985    // FIXME: Regions not accounted for.
    4011     RenderLayer* clippingRootLayer = clippingRoot();
     3986    RenderLayer* clippingRootLayer = clippingRootForPainting();
    40123987    LayoutRect layerBounds;
    40133988    ClipRect backgroundRect, foregroundRect, outlineRect;
    4014     calculateRects(clippingRootLayer, 0, PaintInfo::infiniteRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
     3989    calculateRects(clippingRootLayer, 0, PaintingClipRects, PaintInfo::infiniteRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
    40153990
    40163991    LayoutRect clipRect = backgroundRect.rect();
     
    42604235}
    42614236
    4262 void RenderLayer::clearClipRectsIncludingDescendants()
    4263 {
    4264     if (!m_clipRects)
    4265         return;
    4266 
    4267     clearClipRects();
     4237void RenderLayer::clearClipRectsIncludingDescendants(ClipRectsType typeToClear)
     4238{
     4239    // FIXME: it's not clear how this layer not having clip rects guarantees that no descendants have any.
     4240    if (!m_clipRectsCache)
     4241        return;
     4242
     4243    clearClipRects(typeToClear);
    42684244   
    42694245    for (RenderLayer* l = firstChild(); l; l = l->nextSibling())
    4270         l->clearClipRectsIncludingDescendants();
    4271 }
    4272 
    4273 void RenderLayer::clearClipRects()
    4274 {
    4275     if (m_clipRects) {
    4276         m_clipRects->deref(renderer()->renderArena());
    4277         m_clipRects = 0;
    4278 #ifndef NDEBUG
    4279         m_clipRectsRoot = 0;
    4280 #endif   
     4246        l->clearClipRectsIncludingDescendants(typeToClear);
     4247}
     4248
     4249void RenderLayer::clearClipRects(ClipRectsType typeToClear)
     4250{
     4251    if (typeToClear == AllClipRectTypes)
     4252        m_clipRectsCache = nullptr;
     4253    else {
     4254        ASSERT(typeToClear < NumCachedClipRectsTypes);
     4255        m_clipRectsCache->m_clipRects[typeToClear] = nullptr;
    42814256    }
    42824257}
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r117497 r118562  
    130130class ClipRects {
    131131public:
     132    static PassRefPtr<ClipRects> create()
     133    {
     134        return adoptRef(new ClipRects);
     135    }
     136
     137    static PassRefPtr<ClipRects> create(const ClipRects& other)
     138    {
     139        return adoptRef(new ClipRects(other));
     140    }
     141
    132142    ClipRects()
    133143        : m_refCnt(0)
     
    136146    }
    137147
     148    void reset(const LayoutRect& r)
     149    {
     150        m_overflowClipRect = r;
     151        m_fixedClipRect = r;
     152        m_posClipRect = r;
     153        m_fixed = false;
     154    }
     155   
     156    const ClipRect& overflowClipRect() const { return m_overflowClipRect; }
     157    void setOverflowClipRect(const ClipRect& r) { m_overflowClipRect = r; }
     158
     159    const ClipRect& fixedClipRect() const { return m_fixedClipRect; }
     160    void setFixedClipRect(const ClipRect&r) { m_fixedClipRect = r; }
     161
     162    const ClipRect& posClipRect() const { return m_posClipRect; }
     163    void setPosClipRect(const ClipRect& r) { m_posClipRect = r; }
     164
     165    bool fixed() const { return m_fixed; }
     166    void setFixed(bool fixed) { m_fixed = fixed; }
     167
     168    void ref() { m_refCnt++; }
     169    void deref()
     170    {
     171        if (!--m_refCnt)
     172            delete this;
     173    }
     174
     175    bool operator==(const ClipRects& other) const
     176    {
     177        return m_overflowClipRect == other.overflowClipRect() &&
     178               m_fixedClipRect == other.fixedClipRect() &&
     179               m_posClipRect == other.posClipRect() &&
     180               m_fixed == other.fixed();
     181    }
     182
     183    ClipRects& operator=(const ClipRects& other)
     184    {
     185        m_overflowClipRect = other.overflowClipRect();
     186        m_fixedClipRect = other.fixedClipRect();
     187        m_posClipRect = other.posClipRect();
     188        m_fixed = other.fixed();
     189        return *this;
     190    }
     191
     192private:
    138193    ClipRects(const LayoutRect& r)
    139194        : m_overflowClipRect(r)
     
    154209    }
    155210
    156     void reset(const LayoutRect& r)
    157     {
    158         m_overflowClipRect = r;
    159         m_fixedClipRect = r;
    160         m_posClipRect = r;
    161         m_fixed = false;
    162     }
    163    
    164     const ClipRect& overflowClipRect() const { return m_overflowClipRect; }
    165     void setOverflowClipRect(const ClipRect& r) { m_overflowClipRect = r; }
    166 
    167     const ClipRect& fixedClipRect() const { return m_fixedClipRect; }
    168     void setFixedClipRect(const ClipRect&r) { m_fixedClipRect = r; }
    169 
    170     const ClipRect& posClipRect() const { return m_posClipRect; }
    171     void setPosClipRect(const ClipRect& r) { m_posClipRect = r; }
    172 
    173     bool fixed() const { return m_fixed; }
    174     void setFixed(bool fixed) { m_fixed = fixed; }
    175 
    176     void ref() { m_refCnt++; }
    177     void deref(RenderArena* renderArena) { if (--m_refCnt == 0) destroy(renderArena); }
    178 
    179     void destroy(RenderArena*);
    180 
    181     // Overloaded new operator.
    182     void* operator new(size_t, RenderArena*);
    183 
    184     // Overridden to prevent the normal delete from being called.
    185     void operator delete(void*, size_t);
    186 
    187     bool operator==(const ClipRects& other) const
    188     {
    189         return m_overflowClipRect == other.overflowClipRect() &&
    190                m_fixedClipRect == other.fixedClipRect() &&
    191                m_posClipRect == other.posClipRect() &&
    192                m_fixed == other.fixed();
    193     }
    194 
    195     ClipRects& operator=(const ClipRects& other)
    196     {
    197         m_overflowClipRect = other.overflowClipRect();
    198         m_fixedClipRect = other.fixedClipRect();
    199         m_posClipRect = other.posClipRect();
    200         m_fixed = other.fixed();
    201         return *this;
    202     }
    203 
    204 private:
    205     // The normal operator new is disallowed on all render objects.
    206     void* operator new(size_t) throw();
    207 
    208 private:
    209211    ClipRect m_overflowClipRect;
    210212    ClipRect m_fixedClipRect;
     
    212214    unsigned m_refCnt : 31;
    213215    bool m_fixed : 1;
     216};
     217
     218enum ClipRectsType {
     219    PaintingClipRects, // Relative to painting ancestor. Used for painting.
     220    RootRelativeClipRects, // Relative to the ancestor treated as the root (e.g. transformed layer). Used for hit testing.
     221    AbsoluteClipRects, // Relative to the RenderView's layer. Used for compositing overlap testing.
     222    NumCachedClipRectsTypes,
     223    AllClipRectTypes,
     224    TemporaryClipRects
     225};
     226
     227struct ClipRectsCache {
     228    ClipRectsCache()
     229    {
     230#ifndef NDEBUG
     231        for (int i = 0; i < NumCachedClipRectsTypes; ++i)
     232            m_clipRectsRoot[i] = 0;
     233#endif
     234    }
     235
     236    RefPtr<ClipRects> m_clipRects[NumCachedClipRectsTypes];
     237#ifndef NDEBUG
     238    const RenderLayer* m_clipRectsRoot[NumCachedClipRectsTypes];
     239#endif
    214240};
    215241
     
    372398    const LayoutSize& relativePositionOffset() const { return m_relativeOffset; }
    373399
    374     void clearClipRectsIncludingDescendants();
    375     void clearClipRects();
     400    void clearClipRectsIncludingDescendants(ClipRectsType typeToClear = AllClipRectTypes);
     401    void clearClipRects(ClipRectsType typeToClear = AllClipRectTypes);
    376402
    377403    void addBlockSelectionGapsBounds(const LayoutRect&);
     
    424450
    425451    // The layer relative to which clipping rects for this layer are computed.
    426     RenderLayer* clippingRoot() const;
     452    RenderLayer* clippingRootForPainting() const;
    427453
    428454#if USE(ACCELERATED_COMPOSITING)
     
    473499    // |rootLayer}.  It also computes our background and foreground clip rects
    474500    // for painting/event handling.
    475     void calculateRects(const RenderLayer* rootLayer, RenderRegion*, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
     501    void calculateRects(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
    476502                        ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect,
    477                         bool temporaryClipRects = false, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
     503                        OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
    478504
    479505    // Compute and cache clip rects computed with the given layer as the root
    480     void updateClipRects(const RenderLayer* rootLayer, RenderRegion*, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize);
     506    void updateClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize);
    481507    // Compute and return the clip rects. If useCached is true, will used previously computed clip rects on ancestors
    482508    // (rather than computing them all from scratch up the parent chain).
    483     void calculateClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRects&, bool useCached = false, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
    484     ClipRects* clipRects() const { return m_clipRects; }
     509    void calculateClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, ClipRects&, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
     510
     511    ClipRects* clipRects(ClipRectsType type) const { ASSERT(type < NumCachedClipRectsTypes); return m_clipRectsCache ? m_clipRectsCache->m_clipRects[type].get() : 0; }
    485512
    486513    LayoutRect childrenClipRect() const; // Returns the foreground clip rect of the layer in the document's coordinate space.
     
    768795#endif
    769796
    770     void parentClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRects&, bool temporaryClipRects = false, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
    771     ClipRect backgroundClipRect(const RenderLayer* rootLayer, RenderRegion*, bool temporaryClipRects, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
     797    void parentClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, ClipRects&, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
     798    ClipRect backgroundClipRect(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
    772799    LayoutRect paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior);
    773800
     
    906933    Vector<RenderLayer*>* m_normalFlowList;
    907934
    908     ClipRects* m_clipRects;      // Cached clip rects used when painting and hit testing.
    909 #ifndef NDEBUG
    910     const RenderLayer* m_clipRectsRoot;   // Root layer used to compute clip rects.
    911 #endif
    912 
     935    OwnPtr<ClipRectsCache> m_clipRectsCache;
     936   
    913937    IntPoint m_cachedOverlayScrollbarOffset;
    914938
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r117162 r118562  
    268268
    269269        if (m_owningLayer != rootLayer)
    270             clippingBounds.intersect(m_owningLayer->backgroundClipRect(rootLayer, 0, true).rect()); // FIXME: Incorrect for CSS regions.
     270            clippingBounds.intersect(m_owningLayer->backgroundClipRect(rootLayer, 0, AbsoluteClipRects).rect()); // FIXME: Incorrect for CSS regions.
    271271
    272272        LayoutPoint delta;
     
    466466        // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
    467467        // for a compositing layer, rootLayer is the layer itself.
    468         IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer->backgroundClipRect(compAncestor, 0, true).rect()); // FIXME: Incorrect for CSS regions.
     468        IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer->backgroundClipRect(compAncestor, 0, TemporaryClipRects).rect()); // FIXME: Incorrect for CSS regions.
    469469        ASSERT(parentClipRect != PaintInfo::infiniteRect());
    470470        m_ancestorClippingLayer->setPosition(FloatPoint() + (parentClipRect.location() - graphicsLayerParentLocation));
     
    11131113}
    11141114
     1115void RenderLayerBacking::setRequiresOwnBackingStore(bool flag)
     1116{
     1117    if (flag == m_requiresOwnBackingStore)
     1118        return;
     1119   
     1120    // This affects the answer to paintsIntoCompositedAncestor(), which in turn affects
     1121    // cached clip rects, so when it changes we have to clear clip rects on descendants.
     1122    m_owningLayer->clearClipRectsIncludingDescendants(PaintingClipRects);
     1123    m_requiresOwnBackingStore = flag;
     1124}
     1125
    11151126void RenderLayerBacking::setContentsNeedDisplay()
    11161127{
  • trunk/Source/WebCore/rendering/RenderLayerBacking.h

    r115165 r118562  
    102102    bool paintsIntoCompositedAncestor() const { return !m_requiresOwnBackingStore; }
    103103
    104     void setRequiresOwnBackingStore(bool flag) { m_requiresOwnBackingStore = flag; }
     104    void setRequiresOwnBackingStore(bool);
    105105
    106106    void setContentsNeedDisplay();
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r118052 r118562  
    538538            innerCompositor->updateRootLayerAttachment();
    539539    }
     540   
     541    if (layerChanged)
     542        layer->clearClipRectsIncludingDescendants(PaintingClipRects);
    540543
    541544    return layerChanged;
     
    638641    }
    639642
    640     IntRect clipRect = pixelSnappedIntRect(layer->backgroundClipRect(rootRenderLayer(), 0, true).rect()); // FIXME: Incorrect for CSS regions.
     643    IntRect clipRect = pixelSnappedIntRect(layer->backgroundClipRect(rootRenderLayer(), 0, AbsoluteClipRects).rect()); // FIXME: Incorrect for CSS regions.
    641644    clipRect.scale(pageScaleFactor());
    642645    clipRect.intersect(layerBounds);
     
    697700void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, OverlapMap* overlapMap, CompositingState& compositingState, bool& layersChanged)
    698701{
    699     layer->updateLayerPosition();
    700702    layer->updateLayerListsIfNeeded();
    701703
     
    15371539        return false;
    15381540
    1539     return layer->backgroundClipRect(computeClipRoot, 0, true).rect() != PaintInfo::infiniteRect(); // FIXME: Incorrect for CSS regions.
     1541    return layer->backgroundClipRect(computeClipRoot, 0, TemporaryClipRects).rect() != PaintInfo::infiniteRect(); // FIXME: Incorrect for CSS regions.
    15401542}
    15411543
  • trunk/Source/WebCore/rendering/RenderTreeAsText.cpp

    r117697 r118562  
    719719    LayoutRect layerBounds;
    720720    ClipRect damageRect, clipRectToApply, outlineRect;
    721     l->calculateRects(rootLayer, 0, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect, true);
     721    l->calculateRects(rootLayer, 0, TemporaryClipRects, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect);
    722722
    723723    // Ensure our lists are up-to-date.
Note: See TracChangeset for help on using the changeset viewer.