Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (118561 => 118562)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2012-05-25 21:14:47 UTC (rev 118561)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2012-05-25 21:17:33 UTC (rev 118562)
@@ -125,25 +125,6 @@
const int MinimumWidthWhileResizing = 100;
const int MinimumHeightWhileResizing = 40;
-void* ClipRects::operator new(size_t sz, RenderArena* renderArena)
-{
- return renderArena->allocate(sz);
-}
-
-void ClipRects::operator delete(void* ptr, size_t sz)
-{
- // Stash size where destroy can find it.
- *(size_t *)ptr = sz;
-}
-
-void ClipRects::destroy(RenderArena* renderArena)
-{
- delete this;
-
- // Recover the size left there for us by operator delete and free the memory.
- renderArena->free(*(size_t *)this, this);
-}
-
RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
: m_inResizeMode(false)
, m_scrollDimensionsDirty(true)
@@ -180,10 +161,6 @@
, m_posZOrderList(0)
, m_negZOrderList(0)
, m_normalFlowList(0)
- , m_clipRects(0)
-#ifndef NDEBUG
- , m_clipRectsRoot(0)
-#endif
, m_marquee(0)
, m_staticInlinePosition(0)
, m_staticBlockPosition(0)
@@ -252,9 +229,6 @@
clearBacking(true);
#endif
- // Make sure we have no lingering clip rects.
- ASSERT(!m_clipRects);
-
if (m_scrollCorner)
m_scrollCorner->destroy();
if (m_resizer)
@@ -1070,7 +1044,7 @@
}
#endif
-RenderLayer* RenderLayer::clippingRoot() const
+RenderLayer* RenderLayer::clippingRootForPainting() const
{
#if USE(ACCELERATED_COMPOSITING)
if (isComposited())
@@ -2935,7 +2909,7 @@
// Make sure the parent's clip rects have been calculated.
ClipRect clipRect = paintDirtyRect;
if (parent()) {
- clipRect = backgroundClipRect(rootLayer, region, paintFlags & PaintLayerTemporaryClipRects);
+ clipRect = backgroundClipRect(rootLayer, region, (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects);
clipRect.intersect(paintDirtyRect);
// Push the parent coordinate space's clip.
@@ -3044,7 +3018,7 @@
#endif
if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
- calculateRects(rootLayer, region, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect, localPaintFlags & PaintLayerTemporaryClipRects);
+ calculateRects(rootLayer, region, (localPaintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect);
paintOffset = toPoint(layerBounds.location() - renderBoxLocation());
}
@@ -3452,11 +3426,7 @@
{
// The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate.
- bool useTemporaryClipRects = false;
-#if USE(ACCELERATED_COMPOSITING)
- useTemporaryClipRects = compositor()->inCompositingMode();
-#endif
- useTemporaryClipRects |= renderer()->view()->frameView()->containsScrollableAreaWithOverlayScrollbars();
+ bool useTemporaryClipRects = renderer()->view()->frameView()->containsScrollableAreaWithOverlayScrollbars();
LayoutRect hitTestArea = result.rectForPoint(hitTestPoint);
@@ -3464,7 +3434,7 @@
if (transform() && !appliedTransform) {
// Make sure the parent's clip rects have been calculated.
if (parent()) {
- ClipRect clipRect = backgroundClipRect(rootLayer, result.region(), useTemporaryClipRects, IncludeOverlayScrollbarSize);
+ ClipRect clipRect = backgroundClipRect(rootLayer, result.region(), useTemporaryClipRects ? TemporaryClipRects : RootRelativeClipRects, IncludeOverlayScrollbarSize);
// Go ahead and test the enclosing clip now.
if (!clipRect.intersects(hitTestArea))
return 0;
@@ -3525,7 +3495,7 @@
ClipRect bgRect;
ClipRect fgRect;
ClipRect outlineRect;
- calculateRects(rootLayer, result.region(), hitTestRect, layerBounds, bgRect, fgRect, outlineRect, useTemporaryClipRects, IncludeOverlayScrollbarSize);
+ calculateRects(rootLayer, result.region(), useTemporaryClipRects ? TemporaryClipRects : RootRelativeClipRects, hitTestRect, layerBounds, bgRect, fgRect, outlineRect, IncludeOverlayScrollbarSize);
// The following are used for keeping track of the z-depth of the hit point of 3d-transformed
// descendants.
@@ -3796,10 +3766,11 @@
return 0;
}
-void RenderLayer::updateClipRects(const RenderLayer* rootLayer, RenderRegion* region, OverlayScrollbarSizeRelevancy relevancy)
+void RenderLayer::updateClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, OverlayScrollbarSizeRelevancy relevancy)
{
- if (m_clipRects) {
- ASSERT(rootLayer == m_clipRectsRoot);
+ ASSERT(clipRectsType < NumCachedClipRectsTypes);
+ if (m_clipRectsCache && m_clipRectsCache->m_clipRects[clipRectsType]) {
+ ASSERT(rootLayer == m_clipRectsCache->m_clipRectsRoot[clipRectsType]);
return; // We have the correct cached value.
}
@@ -3807,29 +3778,34 @@
// examine the parent. We want to cache clip rects with us as the root.
RenderLayer* parentLayer = rootLayer != this ? parent() : 0;
if (parentLayer)
- parentLayer->updateClipRects(rootLayer, region, relevancy);
+ parentLayer->updateClipRects(rootLayer, region, clipRectsType, relevancy);
ClipRects clipRects;
- calculateClipRects(rootLayer, region, clipRects, true, relevancy);
+ calculateClipRects(rootLayer, region, clipRectsType, clipRects, relevancy);
- if (parentLayer && parentLayer->clipRects() && clipRects == *parentLayer->clipRects())
- m_clipRects = parentLayer->clipRects();
+ if (!m_clipRectsCache)
+ m_clipRectsCache = adoptPtr(new ClipRectsCache);
+
+ if (parentLayer && parentLayer->clipRects(clipRectsType) && clipRects == *parentLayer->clipRects(clipRectsType))
+ m_clipRectsCache->m_clipRects[clipRectsType] = parentLayer->clipRects(clipRectsType);
else
- m_clipRects = new (renderer()->renderArena()) ClipRects(clipRects);
- m_clipRects->ref();
+ m_clipRectsCache->m_clipRects[clipRectsType] = ClipRects::create(clipRects);
+
+ m_clipRectsCache->m_clipRects[clipRectsType]->ref();
#ifndef NDEBUG
- m_clipRectsRoot = rootLayer;
+ m_clipRectsCache->m_clipRectsRoot[clipRectsType] = rootLayer;
#endif
}
-void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRects& clipRects,
- bool useCached, OverlayScrollbarSizeRelevancy relevancy) const
+void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, ClipRects& clipRects, OverlayScrollbarSizeRelevancy relevancy) const
{
if (!parent()) {
// The root layer's clip rect is always infinite.
clipRects.reset(PaintInfo::infiniteRect());
return;
}
+
+ bool useCached = clipRectsType != TemporaryClipRects;
// For transformed layers, the root layer was shifted to be us, so there is no need to
// examine the parent. We want to cache clip rects with us as the root.
@@ -3837,10 +3813,10 @@
// Ensure that our parent's clip has been calculated so that we can examine the values.
if (parentLayer) {
- if (useCached && parentLayer->clipRects())
- clipRects = *parentLayer->clipRects();
+ if (useCached && parentLayer->clipRects(clipRectsType))
+ clipRects = *parentLayer->clipRects(clipRectsType);
else
- parentLayer->calculateClipRects(rootLayer, region, clipRects);
+ parentLayer->calculateClipRects(rootLayer, region, clipRectsType, clipRects);
} else
clipRects.reset(PaintInfo::infiniteRect());
@@ -3888,16 +3864,16 @@
}
}
-void RenderLayer::parentClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRects& clipRects, bool temporaryClipRects, OverlayScrollbarSizeRelevancy relevancy) const
+void RenderLayer::parentClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, ClipRects& clipRects, OverlayScrollbarSizeRelevancy relevancy) const
{
ASSERT(parent());
- if (temporaryClipRects) {
- parent()->calculateClipRects(rootLayer, region, clipRects, false, relevancy);
+ if (clipRectsType == TemporaryClipRects) {
+ parent()->calculateClipRects(rootLayer, region, clipRectsType, clipRects, relevancy);
return;
}
- parent()->updateClipRects(rootLayer, region, relevancy);
- clipRects = *parent()->clipRects();
+ parent()->updateClipRects(rootLayer, region, clipRectsType, relevancy);
+ clipRects = *parent()->clipRects(clipRectsType);
}
static inline ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, EPosition position)
@@ -3911,11 +3887,11 @@
return parentRects.overflowClipRect();
}
-ClipRect RenderLayer::backgroundClipRect(const RenderLayer* rootLayer, RenderRegion* region, bool temporaryClipRects, OverlayScrollbarSizeRelevancy relevancy) const
+ClipRect RenderLayer::backgroundClipRect(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, OverlayScrollbarSizeRelevancy relevancy) const
{
ASSERT(parent());
ClipRects parentRects;
- parentClipRects(rootLayer, region, parentRects, temporaryClipRects, relevancy);
+ parentClipRects(rootLayer, region, clipRectsType, parentRects, relevancy);
ClipRect backgroundClipRect = backgroundClipRectForPosition(parentRects, renderer()->style()->position());
RenderView* view = renderer()->view();
ASSERT(view);
@@ -3927,12 +3903,11 @@
return backgroundClipRect;
}
-void RenderLayer::calculateRects(const RenderLayer* rootLayer, RenderRegion* region, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
- ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, bool temporaryClipRects,
- OverlayScrollbarSizeRelevancy relevancy) const
+void RenderLayer::calculateRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
+ ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, OverlayScrollbarSizeRelevancy relevancy) const
{
if (rootLayer != this && parent()) {
- backgroundRect = backgroundClipRect(rootLayer, region, temporaryClipRects, relevancy);
+ backgroundRect = backgroundClipRect(rootLayer, region, clipRectsType, relevancy);
backgroundRect.intersect(paintDirtyRect);
} else
backgroundRect = paintDirtyRect;
@@ -3985,10 +3960,10 @@
// FIXME: border-radius not accounted for.
// FIXME: Regions not accounted for.
RenderView* renderView = renderer()->view();
- RenderLayer* clippingRootLayer = clippingRoot();
+ RenderLayer* clippingRootLayer = clippingRootForPainting();
LayoutRect layerBounds;
ClipRect backgroundRect, foregroundRect, outlineRect;
- calculateRects(clippingRootLayer, 0, renderView->unscaledDocumentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
+ calculateRects(clippingRootLayer, 0, PaintingClipRects, renderView->unscaledDocumentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(foregroundRect.rect())).enclosingBoundingBox();
}
@@ -3997,10 +3972,10 @@
// FIXME: border-radius not accounted for.
// FIXME: Regions not accounted for.
RenderView* renderView = renderer()->view();
- RenderLayer* clippingRootLayer = clippingRoot();
+ RenderLayer* clippingRootLayer = clippingRootForPainting();
LayoutRect layerBounds;
ClipRect backgroundRect, foregroundRect, outlineRect;
- calculateRects(clippingRootLayer, 0, renderView->documentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
+ calculateRects(clippingRootLayer, 0, PaintingClipRects, renderView->documentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(backgroundRect.rect())).enclosingBoundingBox();
}
@@ -4008,10 +3983,10 @@
{
// FIXME: border-radius not accounted for.
// FIXME: Regions not accounted for.
- RenderLayer* clippingRootLayer = clippingRoot();
+ RenderLayer* clippingRootLayer = clippingRootForPainting();
LayoutRect layerBounds;
ClipRect backgroundRect, foregroundRect, outlineRect;
- calculateRects(clippingRootLayer, 0, PaintInfo::infiniteRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
+ calculateRects(clippingRootLayer, 0, PaintingClipRects, PaintInfo::infiniteRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
LayoutRect clipRect = backgroundRect.rect();
if (clipRect == PaintInfo::infiniteRect())
@@ -4259,25 +4234,25 @@
return pixelSnappedIntRect(unionBounds);
}
-void RenderLayer::clearClipRectsIncludingDescendants()
+void RenderLayer::clearClipRectsIncludingDescendants(ClipRectsType typeToClear)
{
- if (!m_clipRects)
+ // FIXME: it's not clear how this layer not having clip rects guarantees that no descendants have any.
+ if (!m_clipRectsCache)
return;
- clearClipRects();
+ clearClipRects(typeToClear);
for (RenderLayer* l = firstChild(); l; l = l->nextSibling())
- l->clearClipRectsIncludingDescendants();
+ l->clearClipRectsIncludingDescendants(typeToClear);
}
-void RenderLayer::clearClipRects()
+void RenderLayer::clearClipRects(ClipRectsType typeToClear)
{
- if (m_clipRects) {
- m_clipRects->deref(renderer()->renderArena());
- m_clipRects = 0;
-#ifndef NDEBUG
- m_clipRectsRoot = 0;
-#endif
+ if (typeToClear == AllClipRectTypes)
+ m_clipRectsCache = nullptr;
+ else {
+ ASSERT(typeToClear < NumCachedClipRectsTypes);
+ m_clipRectsCache->m_clipRects[typeToClear] = nullptr;
}
}
Modified: trunk/Source/WebCore/rendering/RenderLayer.h (118561 => 118562)
--- trunk/Source/WebCore/rendering/RenderLayer.h 2012-05-25 21:14:47 UTC (rev 118561)
+++ trunk/Source/WebCore/rendering/RenderLayer.h 2012-05-25 21:17:33 UTC (rev 118562)
@@ -129,27 +129,19 @@
class ClipRects {
public:
- ClipRects()
- : m_refCnt(0)
- , m_fixed(false)
+ static PassRefPtr<ClipRects> create()
{
+ return adoptRef(new ClipRects);
}
- ClipRects(const LayoutRect& r)
- : m_overflowClipRect(r)
- , m_fixedClipRect(r)
- , m_posClipRect(r)
- , m_refCnt(0)
- , m_fixed(false)
+ static PassRefPtr<ClipRects> create(const ClipRects& other)
{
+ return adoptRef(new ClipRects(other));
}
- ClipRects(const ClipRects& other)
- : m_overflowClipRect(other.overflowClipRect())
- , m_fixedClipRect(other.fixedClipRect())
- , m_posClipRect(other.posClipRect())
- , m_refCnt(0)
- , m_fixed(other.fixed())
+ ClipRects()
+ : m_refCnt(0)
+ , m_fixed(false)
{
}
@@ -174,16 +166,12 @@
void setFixed(bool fixed) { m_fixed = fixed; }
void ref() { m_refCnt++; }
- void deref(RenderArena* renderArena) { if (--m_refCnt == 0) destroy(renderArena); }
+ void deref()
+ {
+ if (!--m_refCnt)
+ delete this;
+ }
- void destroy(RenderArena*);
-
- // Overloaded new operator.
- void* operator new(size_t, RenderArena*);
-
- // Overridden to prevent the normal delete from being called.
- void operator delete(void*, size_t);
-
bool operator==(const ClipRects& other) const
{
return m_overflowClipRect == other.overflowClipRect() &&
@@ -202,10 +190,24 @@
}
private:
- // The normal operator new is disallowed on all render objects.
- void* operator new(size_t) throw();
+ ClipRects(const LayoutRect& r)
+ : m_overflowClipRect(r)
+ , m_fixedClipRect(r)
+ , m_posClipRect(r)
+ , m_refCnt(0)
+ , m_fixed(false)
+ {
+ }
-private:
+ ClipRects(const ClipRects& other)
+ : m_overflowClipRect(other.overflowClipRect())
+ , m_fixedClipRect(other.fixedClipRect())
+ , m_posClipRect(other.posClipRect())
+ , m_refCnt(0)
+ , m_fixed(other.fixed())
+ {
+ }
+
ClipRect m_overflowClipRect;
ClipRect m_fixedClipRect;
ClipRect m_posClipRect;
@@ -213,6 +215,30 @@
bool m_fixed : 1;
};
+enum ClipRectsType {
+ PaintingClipRects, // Relative to painting ancestor. Used for painting.
+ RootRelativeClipRects, // Relative to the ancestor treated as the root (e.g. transformed layer). Used for hit testing.
+ AbsoluteClipRects, // Relative to the RenderView's layer. Used for compositing overlap testing.
+ NumCachedClipRectsTypes,
+ AllClipRectTypes,
+ TemporaryClipRects
+};
+
+struct ClipRectsCache {
+ ClipRectsCache()
+ {
+#ifndef NDEBUG
+ for (int i = 0; i < NumCachedClipRectsTypes; ++i)
+ m_clipRectsRoot[i] = 0;
+#endif
+ }
+
+ RefPtr<ClipRects> m_clipRects[NumCachedClipRectsTypes];
+#ifndef NDEBUG
+ const RenderLayer* m_clipRectsRoot[NumCachedClipRectsTypes];
+#endif
+};
+
class RenderLayer : public ScrollableArea {
public:
friend class RenderReplica;
@@ -371,8 +397,8 @@
const LayoutSize& relativePositionOffset() const { return m_relativeOffset; }
- void clearClipRectsIncludingDescendants();
- void clearClipRects();
+ void clearClipRectsIncludingDescendants(ClipRectsType typeToClear = AllClipRectTypes);
+ void clearClipRects(ClipRectsType typeToClear = AllClipRectTypes);
void addBlockSelectionGapsBounds(const LayoutRect&);
void clearBlockSelectionGapsBounds();
@@ -423,7 +449,7 @@
RenderLayer* enclosingScrollableLayer() const;
// The layer relative to which clipping rects for this layer are computed.
- RenderLayer* clippingRoot() const;
+ RenderLayer* clippingRootForPainting() const;
#if USE(ACCELERATED_COMPOSITING)
// Enclosing compositing layer; if includeSelf is true, may return this.
@@ -472,17 +498,18 @@
// This method figures out our layerBounds in coordinates relative to
// |rootLayer}. It also computes our background and foreground clip rects
// for painting/event handling.
- void calculateRects(const RenderLayer* rootLayer, RenderRegion*, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
+ void calculateRects(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect,
- bool temporaryClipRects = false, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
+ OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
// Compute and cache clip rects computed with the given layer as the root
- void updateClipRects(const RenderLayer* rootLayer, RenderRegion*, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize);
+ void updateClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize);
// Compute and return the clip rects. If useCached is true, will used previously computed clip rects on ancestors
// (rather than computing them all from scratch up the parent chain).
- void calculateClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRects&, bool useCached = false, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
- ClipRects* clipRects() const { return m_clipRects; }
+ void calculateClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, ClipRects&, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
+ ClipRects* clipRects(ClipRectsType type) const { ASSERT(type < NumCachedClipRectsTypes); return m_clipRectsCache ? m_clipRectsCache->m_clipRects[type].get() : 0; }
+
LayoutRect childrenClipRect() const; // Returns the foreground clip rect of the layer in the document's coordinate space.
LayoutRect selfClipRect() const; // Returns the background clip rect of the layer in the document's coordinate space.
LayoutRect localClipRect() const; // Returns the background clip rect of the layer in the local coordinate space.
@@ -767,8 +794,8 @@
void updateOrRemoveFilterEffect();
#endif
- void parentClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRects&, bool temporaryClipRects = false, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
- ClipRect backgroundClipRect(const RenderLayer* rootLayer, RenderRegion*, bool temporaryClipRects, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
+ void parentClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, ClipRects&, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
+ ClipRect backgroundClipRect(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
LayoutRect paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior);
RenderLayer* enclosingTransformedAncestor() const;
@@ -905,11 +932,8 @@
// overflow layers, but that may change in the future.
Vector<RenderLayer*>* m_normalFlowList;
- ClipRects* m_clipRects; // Cached clip rects used when painting and hit testing.
-#ifndef NDEBUG
- const RenderLayer* m_clipRectsRoot; // Root layer used to compute clip rects.
-#endif
-
+ OwnPtr<ClipRectsCache> m_clipRectsCache;
+
IntPoint m_cachedOverlayScrollbarOffset;
RenderMarquee* m_marquee; // Used by layers with overflow:marquee