Revert "Reworks the clipping logic" and follow-up.

This change reverts commit
f5bd7257166f313f8bed1ceffa2802e6540b53da and
25907d23a2b4a963c879fb44c18ed05ad388f00e.

The change has been the cause of numerous regressions
(painting and hit-testing clip rects wrongly computed)
and several performance regressions.

Reverting the change so that I can investigate offline
and reland in a smaller bits.

BUG=518215,521452,522829,518219

Review URL: https://codereview.chromium.org/1307203004

git-svn-id: svn://svn.chromium.org/blink/trunk@201739 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent d9dad42c
......@@ -2480,14 +2480,6 @@ void FrameView::updateLifecyclePhasesInternal(LifeCycleUpdateOption phases)
|| (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && lifecycle().state() == DocumentLifecycle::CompositingForSlimmingPaintV2Clean));
}
}
#ifndef NDEBUG
// TODO(jchaffraix): We will want to clear the clip rects in release too
// to reduce our long-term memory consumption. However this requires us
// to migrate all of the clip rects to the state machine and evaluate
// the performance impacts of this.
layoutView()->layer()->clipper().clearClipRectsIncludingDescendants(AbsoluteClipRects);
#endif
}
void FrameView::paintForSlimmingPaintV2()
......
......@@ -28,21 +28,14 @@
#include "platform/geometry/LayoutRect.h"
#include "wtf/FastAllocBase.h"
#include "wtf/PassOwnPtr.h"
namespace blink {
class DeprecatedPaintLayer;
class HitTestLocation;
class ClipRect {
WTF_MAKE_FAST_ALLOCATED(ClipRect);
public:
static PassOwnPtr<ClipRect> create(const ClipRect& other)
{
return adoptPtr(new ClipRect(other));
}
ClipRect()
: m_hasRadius(false)
{ }
......@@ -75,18 +68,7 @@ public:
bool isEmpty() const { return m_rect.isEmpty(); }
bool intersects(const HitTestLocation&) const;
const DeprecatedPaintLayer* rootLayer() const
{
return m_rootLayer;
}
void setRootLayer(const DeprecatedPaintLayer* rootLayer)
{
m_rootLayer = rootLayer;
}
private:
const DeprecatedPaintLayer* m_rootLayer;
LayoutRect m_rect;
bool m_hasRadius;
};
......
......@@ -31,15 +31,20 @@
namespace blink {
class DeprecatedPaintLayer;
class ClipRects {
class ClipRects : public RefCounted<ClipRects> {
WTF_MAKE_FAST_ALLOCATED(ClipRects);
public:
static PassRefPtr<ClipRects> create()
{
return adoptRef(new ClipRects);
}
static PassRefPtr<ClipRects> create(const ClipRects& other)
{
return adoptRef(new ClipRects(other));
}
ClipRects()
: m_rootLayer(nullptr)
, m_fixed(0)
: m_fixed(0)
{
}
......@@ -77,24 +82,12 @@ public:
m_fixedClipRect = other.fixedClipRect();
m_posClipRect = other.posClipRect();
m_fixed = other.fixed();
m_rootLayer = other.m_rootLayer;
return *this;
}
void setRootLayer(const DeprecatedPaintLayer* layer)
{
m_rootLayer = layer;
}
const DeprecatedPaintLayer* rootLayer()
{
return m_rootLayer;
}
private:
ClipRects(const LayoutRect& r)
: m_rootLayer(nullptr)
, m_overflowClipRect(r)
: m_overflowClipRect(r)
, m_fixedClipRect(r)
, m_posClipRect(r)
, m_fixed(0)
......@@ -102,18 +95,13 @@ private:
}
ClipRects(const ClipRects& other)
: m_rootLayer(other.m_rootLayer)
, m_overflowClipRect(other.overflowClipRect())
: m_overflowClipRect(other.overflowClipRect())
, m_fixedClipRect(other.fixedClipRect())
, m_posClipRect(other.posClipRect())
, m_fixed(other.fixed())
{
}
// ClipRects are accumulated relative to this layer. Its clips and the clips
// of its descendents are intersected down to the layer being calculated. It
// also determines the coordinate space of the clips.
const DeprecatedPaintLayer* m_rootLayer;
ClipRect m_overflowClipRect;
ClipRect m_fixedClipRect;
ClipRect m_posClipRect;
......
......@@ -15,14 +15,12 @@ namespace blink {
class DeprecatedPaintLayer;
// TODO: Because this is mostly empty, this should be moved to a better place
enum ClipRectsCacheSlot {
// Relative to the ancestor treated as the root (e.g. transformed layer). Used for hit testing.
RootRelativeClipRects,
RootRelativeClipRectsIgnoringViewportClip,
// Relative to the LayoutView's layer. Used for compositing overlap testing.
// Computed during the compositing update step (see CompositingInputsUpdater::update).
AbsoluteClipRects,
// Relative to painting ancestor. Used for painting.
......@@ -33,6 +31,37 @@ enum ClipRectsCacheSlot {
UncachedClipRects,
};
class ClipRectsCache {
WTF_MAKE_FAST_ALLOCATED(ClipRectsCache);
public:
struct Entry {
Entry()
: root(nullptr)
#if ENABLE(ASSERT)
, scrollbarRelevancy(IgnoreOverlayScrollbarSize)
#endif
{
}
const DeprecatedPaintLayer* root;
RefPtr<ClipRects> clipRects;
#if ENABLE(ASSERT)
OverlayScrollbarSizeRelevancy scrollbarRelevancy;
#endif
};
Entry& get(ClipRectsCacheSlot slot)
{
ASSERT(slot < NumberOfClipRectsCacheSlots);
return m_entries[slot];
}
void clear(ClipRectsCacheSlot slot)
{
ASSERT(slot < NumberOfClipRectsCacheSlots);
m_entries[slot] = Entry();
}
private:
Entry m_entries[NumberOfClipRectsCacheSlots];
};
} // namespace blink
#endif // ClipRectsCache_h
......@@ -26,7 +26,6 @@ CompositingInputsUpdater::~CompositingInputsUpdater()
void CompositingInputsUpdater::update()
{
TRACE_EVENT0("blink", "CompositingInputsUpdater::update");
m_rootLayer->clipper().precalculateAbsoluteClipRects();
updateRecursive(m_rootLayer, DoNotForceUpdate, AncestorInfo());
}
......
......@@ -376,6 +376,8 @@ void DeprecatedPaintLayer::updateTransform(const ComputedStyle* oldStyle, const
// DeprecatedPaintLayers with transforms act as clip rects roots, so clear the cached clip rects here.
m_clipper.clearClipRectsIncludingDescendants();
} else if (hasTransform) {
m_clipper.clearClipRectsIncludingDescendants(AbsoluteClipRects);
}
updateTransformationMatrix();
......@@ -1400,10 +1402,7 @@ void DeprecatedPaintLayer::collectFragments(DeprecatedPaintLayerFragments& fragm
// Calculate clip rects relative to the enclosingPaginationLayer. The purpose of this call is to determine our bounds clipped to intermediate
// layers between us and the pagination context. It's important to minimize the number of fragments we need to create and this helps with that.
// This code uses a non-standard root layer, which can populate our cache with unexpected values.
// Thus we bypass the clip rect cache by ignoring |clipRectsCacheSlot| and passing UncachedClipRects.
// TODO(chadarmstrong): If possible, this code should use the cache (one way would be by computing the root layer relative to |clipRectsCacheSlot|).
ClipRectsContext paginationClipRectsContext(enclosingPaginationLayer(), UncachedClipRects, inOverlayScrollbarSizeRelevancy);
ClipRectsContext paginationClipRectsContext(enclosingPaginationLayer(), clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy);
if (respectOverflowClip == IgnoreOverflowClip)
paginationClipRectsContext.setIgnoreOverflowClip();
LayoutRect layerBoundsInFlowThread;
......@@ -1442,10 +1441,7 @@ void DeprecatedPaintLayer::collectFragments(DeprecatedPaintLayerFragments& fragm
ClipRect ancestorClipRect = dirtyRect;
if (const DeprecatedPaintLayer* paginationParentLayer = enclosingPaginationLayer()->parent()) {
const DeprecatedPaintLayer* ancestorLayer = rootLayerIsInsidePaginationLayer ? paginationParentLayer : rootLayer;
// This code uses a non-standard root layer, which can populate our cache with unexpected values.
// Thus we bypass the clip rect cache by ignoring |clipRectsCacheSlot| and passing UncachedClipRects.
// TODO(chadarmstrong): If possible, this code should use the cache (one way would be by computing the root layer relative to |clipRectsCacheSlot|).
ClipRectsContext clipRectsContext(ancestorLayer, UncachedClipRects, inOverlayScrollbarSizeRelevancy);
ClipRectsContext clipRectsContext(ancestorLayer, clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy);
if (respectOverflowClip == IgnoreOverflowClip)
clipRectsContext.setIgnoreOverflowClip();
ancestorClipRect = enclosingPaginationLayer()->clipper().backgroundClipRect(clipRectsContext);
......
......@@ -45,7 +45,6 @@
#ifndef DeprecatedPaintLayerClipper_h
#define DeprecatedPaintLayerClipper_h
#include "core/layout/ClipRects.h"
#include "core/layout/ClipRectsCache.h"
#include "core/layout/LayoutBox.h"
#include "wtf/Allocator.h"
......@@ -54,25 +53,6 @@ namespace blink {
class DeprecatedPaintLayer;
// This is the state information passed down
// on the stack for calculating clip rects.
struct ClipRectComputationState {
STACK_ALLOCATED();
ClipRectComputationState()
{
currentClipRects.reset(LayoutRect(LayoutRect::infiniteIntRect()));
stackingContextClipRects.reset(LayoutRect(LayoutRect::infiniteIntRect()));
}
// Depending on the value of context.isComputingPaintingRect() can have different meanings
// In painting, this ClipRects is used for statically positioned elements,
// outside painting, it is the only ClipRects, and is used for all elements.
ClipRects currentClipRects;
// During painting this ClipRects is used for positioned elements. It can have
// a rootLayer further up the tree than currentClipRects because its root must be
// beyond the enclosing stacking context. See resetPaintRects.
ClipRects stackingContextClipRects;
};
enum ShouldRespectOverflowClip {
IgnoreOverflowClip,
RespectOverflowClip
......@@ -149,25 +129,33 @@ public:
// Pass offsetFromRoot if known.
void calculateRects(const ClipRectsContext&, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, const LayoutPoint* offsetFromRoot = 0) const;
void calculateClipRects(const ClipRectsContext&, ClipRectComputationState&) const;
DeprecatedPaintLayer* clippingRootForPainting() const;
private:
void calculateClipRects(const ClipRectsContext&, ClipRects&) const;
ClipRects* clipRectsIfCached(const ClipRectsContext&) const;
ClipRects* storeClipRectsInCache(const ClipRectsContext&, ClipRects* parentClipRects, const ClipRects&) const;
void precalculateAbsoluteClipRects();
// cachedClipRects looks buggy: It doesn't check whether context.rootLayer and entry.root match.
// FIXME: Move callers to clipRectsIfCached, which does the proper checks.
ClipRects* cachedClipRects(const ClipRectsContext& context) const
{
return m_cache ? m_cache->get(context.cacheSlot()).clipRects.get() : 0;
}
void getOrCalculateClipRects(const ClipRectsContext&, ClipRects&) const;
private:
void setClipRect(const ClipRectsContext&, const ClipRectComputationState&) const;
void addClipsFromThisObject(const ClipRectsContext&, ClipRects&) const;
void updateClipRectBasedOnPosition(ClipRects*) const;
DeprecatedPaintLayer* clippingRootForPainting() const;
ClipRect uncachedBackgroundClipRect(const ClipRectsContext&) const;
void uncachedCalculateClipRects(const ClipRectsContext&, ClipRects&) const;
ClipRectsCache& cache() const
{
if (!m_cache)
m_cache = adoptPtr(new ClipRectsCache);
return *m_cache;
}
bool shouldRespectOverflowClip(const ClipRectsContext&) const;
// FIXME: Could this be a LayoutBox?
LayoutBoxModelObject& m_layoutObject;
mutable OwnPtr<ClipRect> m_clips[NumberOfClipRectsCacheSlots];
mutable OwnPtr<ClipRectsCache> m_cache;
};
} // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment