Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Unified Diff: third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp

Issue 2425873005: Don't apply clips to children of composited-scrolling elements for overlap testing. (Closed)
Patch Set: none Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp
index d8e1150dc64d8b6bf00742d45fed3309de9003f1..343d31601d4c069357d9a39c60ff0740988c0d92 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositingRequirementsUpdater.cpp
@@ -65,6 +65,11 @@ class OverlapMapContainer {
IntRect m_boundingBox;
};
+struct OverlapMapContainers {
+ OverlapMapContainer clipped;
+ OverlapMapContainer unclipped;
+};
+
class CompositingRequirementsUpdater::OverlapMap {
WTF_MAKE_NONCOPYABLE(OverlapMap);
@@ -76,7 +81,16 @@ class CompositingRequirementsUpdater::OverlapMap {
beginNewOverlapTestingContext();
}
- void add(PaintLayer* layer, const IntRect& bounds) {
+ // Each rect added is marked as clipped or unclipped. clipped rects may
+ // overlap only with other clipped rects, but unclipped rects may overlap
+ // with anything.
+ //
+ // This is used to model composited overflow scrolling, where PaintLayers
+ // within the scroller are not clipped for overlap testing, whereas
+ // PaintLayers not within it are. This is necessary because PaintLayerClipper
+ // is not smart enough to understand not to clip composited overflow clips,
+ // but still clip otherwise.
+ void add(PaintLayer* layer, const IntRect& bounds, bool isClipped) {
DCHECK(!layer->isRootLayer());
if (bounds.isEmpty())
return;
@@ -85,18 +99,26 @@ class CompositingRequirementsUpdater::OverlapMap {
// contribute to overlap as soon as they have been recursively processed
// and popped off the stack.
DCHECK_GE(m_overlapStack.size(), 2ul);
- m_overlapStack[m_overlapStack.size() - 2].add(bounds);
+ if (isClipped)
+ m_overlapStack[m_overlapStack.size() - 2].clipped.add(bounds);
+ else
+ m_overlapStack[m_overlapStack.size() - 2].unclipped.add(bounds);
}
- bool overlapsLayers(const IntRect& bounds) const {
- return m_overlapStack.last().overlapsLayers(bounds);
+ bool overlapsLayers(const IntRect& bounds, bool isClipped) const {
+ bool clippedOverlap = m_overlapStack.last().clipped.overlapsLayers(bounds);
+ if (isClipped)
+ return clippedOverlap;
+ // Unclipped is allowed to overlap clipped, but not vice-versa.
+ return clippedOverlap ||
+ m_overlapStack.last().unclipped.overlapsLayers(bounds);
}
void beginNewOverlapTestingContext() {
// This effectively creates a new "clean slate" for overlap state.
// This is used when we know that a subtree or remaining set of
// siblings does not need to check overlap with things behind it.
- m_overlapStack.append(OverlapMapContainer());
+ m_overlapStack.append(OverlapMapContainers());
}
void finishCurrentOverlapTestingContext() {
@@ -107,12 +129,15 @@ class CompositingRequirementsUpdater::OverlapMap {
//
// FIXME: we may be able to avoid this deep copy by rearranging how
// overlapMap state is managed.
- m_overlapStack[m_overlapStack.size() - 2].unite(m_overlapStack.last());
+ m_overlapStack[m_overlapStack.size() - 2].clipped.unite(
+ m_overlapStack.last().clipped);
+ m_overlapStack[m_overlapStack.size() - 2].unclipped.unite(
+ m_overlapStack.last().unclipped);
m_overlapStack.removeLast();
}
private:
- Vector<OverlapMapContainer> m_overlapStack;
+ Vector<OverlapMapContainers> m_overlapStack;
};
class CompositingRequirementsUpdater::RecursionData {
@@ -233,6 +258,13 @@ void CompositingRequirementsUpdater::updateRecursive(
currentRecursionData.m_compositingAncestor->layoutObject()->isVideo())
directReasons |= CompositingReasonVideoOverlay;
+ bool hasCompositedScrollingAncestor =
+ layer->ancestorScrollingLayer() &&
+ (m_compositingReasonFinder.directReasons(
+ layer->ancestorScrollingLayer()) &
+ CompositingReasonOverflowScrollingTouch);
+
+ // TODO(chrishtr): use |hasCompositedScrollingAncestor| instead.
if (currentRecursionData.m_hasCompositedScrollingAncestor &&
layer->layoutObject()->styleRef().hasViewportConstrainedPosition())
directReasons |= CompositingReasonScrollDependentPosition;
@@ -278,6 +310,7 @@ void CompositingRequirementsUpdater::updateRecursive(
? CompositingReasonAssumedOverlap
: CompositingReasonNone;
+ // TODO(chrishtr): use |hasCompositedScrollingAncestor| instead.
if (currentRecursionData.m_hasCompositedScrollingAncestor) {
Vector<size_t> unclippedDescendantsToRemove;
for (size_t i = 0; i < unclippedDescendants.size(); i++) {
@@ -310,14 +343,16 @@ void CompositingRequirementsUpdater::updateRecursive(
}
}
- const IntRect& absBounds = layer->clippedAbsoluteBoundingBox();
+ const IntRect& absBounds = hasCompositedScrollingAncestor
+ ? layer->unclippedAbsoluteBoundingBox()
+ : layer->clippedAbsoluteBoundingBox();
absoluteDescendantBoundingBox = absBounds;
-
if (currentRecursionData.m_testingOverlap &&
!requiresCompositingOrSquashing(directReasons)) {
- overlapCompositingReason = overlapMap.overlapsLayers(absBounds)
- ? CompositingReasonOverlap
- : CompositingReasonNone;
+ bool overlaps =
+ overlapMap.overlapsLayers(absBounds, !hasCompositedScrollingAncestor);
+ overlapCompositingReason =
+ overlaps ? CompositingReasonOverlap : CompositingReasonNone;
}
reasonsToComposite |= overlapCompositingReason;
@@ -379,7 +414,7 @@ void CompositingRequirementsUpdater::updateRecursive(
// the negative z-index child's bounds to the new overlap context.
overlapMap.beginNewOverlapTestingContext();
overlapMap.add(curNode->layer(),
- curNode->layer()->clippedAbsoluteBoundingBox());
+ curNode->layer()->clippedAbsoluteBoundingBox(), true);
overlapMap.finishCurrentOverlapTestingContext();
}
}
@@ -449,7 +484,7 @@ void CompositingRequirementsUpdater::updateRecursive(
// for overlap.
if (childRecursionData.m_compositingAncestor &&
!childRecursionData.m_compositingAncestor->isRootLayer())
- overlapMap.add(layer, absBounds);
+ overlapMap.add(layer, absBounds, !hasCompositedScrollingAncestor);
// Now check for reasons to become composited that depend on the state of
// descendant layers.
@@ -464,7 +499,8 @@ void CompositingRequirementsUpdater::updateRecursive(
// now, because the code is designed to push overlap information to the
// second-from-top context of the stack.
overlapMap.beginNewOverlapTestingContext();
- overlapMap.add(layer, absoluteDescendantBoundingBox);
+ overlapMap.add(layer, absoluteDescendantBoundingBox,
+ !hasCompositedScrollingAncestor);
willBeCompositedOrSquashed = true;
}

Powered by Google App Engine
This is Rietveld 408576698