From b7cec681c9cca1190db0f437a187b07c1a8b2767 Mon Sep 17 00:00:00 2001 From: "simon.fraser@apple.com" Date: Mon, 16 Apr 2012 18:32:13 +0000 Subject: [PATCH] Avoid using backing store for compositing layers that just need to clip https://bugs.webkit.org/show_bug.cgi?id=40547 Source/WebCore: Reviewed by Dean Jackson. If a layer becomes composited because it needs to clip composited descendants, or if it has perspective, then it doesn't actually needs its own backing store; its contents can be painted by an ancestor, and we can just have an empty layer that does the clipping or applies the perspective transform. This saves backing store memory on some pages. Tests: compositing/backing/no-backing-for-clip-overlap.html compositing/backing/no-backing-for-clip.html compositing/backing/no-backing-for-perspective.html * rendering/RenderLayer.cpp: (WebCore): (WebCore::RenderLayer::enclosingCompositingLayerForRepaint): (WebCore::RenderLayer::paintLayer): * rendering/RenderLayer.h: (RenderLayer): * rendering/RenderLayerBacking.cpp: (WebCore::RenderLayerBacking::RenderLayerBacking): (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): (WebCore::RenderLayerBacking::containsPaintedContent): (WebCore::RenderLayerBacking::setContentsNeedDisplay): (WebCore::RenderLayerBacking::setContentsNeedDisplayInRect): (WebCore::RenderLayerBacking::paintIntoLayer): * rendering/RenderLayerBacking.h: (RenderLayerBacking): (WebCore::RenderLayerBacking::paintsIntoCompositedAncestor): (WebCore::RenderLayerBacking::setRequiresOwnBackingStore): * rendering/RenderLayerCompositor.cpp: (WebCore::RenderLayerCompositor::layerWillBeRemoved): (WebCore::RenderLayerCompositor::recursiveRepaintLayerRect): (WebCore::RenderLayerCompositor::requiresCompositingLayer): (WebCore::RenderLayerCompositor::requiresOwnBackingStore): (WebCore): * rendering/RenderLayerCompositor.h: * rendering/RenderObject.cpp: (WebCore::RenderObject::containerForRepaint): * rendering/RenderTreeAsText.cpp: (WebCore::write): * rendering/RenderView.cpp: (WebCore::RenderView::paintBoxDecorations): LayoutTests: Reviewed by Dean Jackson. New tests for backing store elimination with clip or perspective. New results for some tests that no longer have backing store on some layers. * compositing/backing/no-backing-for-clip-expected.txt: Added. * compositing/backing/no-backing-for-clip-overlap-expected.txt: Added. * compositing/backing/no-backing-for-clip-overlap.html: Added. * compositing/backing/no-backing-for-clip.html: Added. * compositing/backing/no-backing-for-perspective-expected.txt: Added. * compositing/backing/no-backing-for-perspective.html: Added. * compositing/geometry/preserve-3d-switching-expected.txt: * compositing/visibility/layer-visible-content-expected.png: * compositing/visibility/layer-visible-content-expected.txt: git-svn-id: http://svn.webkit.org/repository/webkit/trunk@114283 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- LayoutTests/ChangeLog | 22 ++++++++ .../backing/no-backing-for-clip-expected.txt | 42 +++++++++++++++ .../no-backing-for-clip-overlap-expected.txt | 48 +++++++++++++++++ .../backing/no-backing-for-clip-overlap.html | 59 +++++++++++++++++++++ .../compositing/backing/no-backing-for-clip.html | 59 +++++++++++++++++++++ .../no-backing-for-perspective-expected.txt | 32 +++++++++++ .../backing/no-backing-for-perspective.html | 57 ++++++++++++++++++++ .../geometry/preserve-3d-switching-expected.txt | 1 - .../visibility/layer-visible-content-expected.png | Bin 10578 -> 3303 bytes .../visibility/layer-visible-content-expected.txt | 1 - Source/WebCore/ChangeLog | 50 +++++++++++++++++ Source/WebCore/rendering/RenderLayer.cpp | 15 +++++- Source/WebCore/rendering/RenderLayer.h | 1 + Source/WebCore/rendering/RenderLayerBacking.cpp | 13 ++++- Source/WebCore/rendering/RenderLayerBacking.h | 7 +++ Source/WebCore/rendering/RenderLayerCompositor.cpp | 48 +++++++++++++---- Source/WebCore/rendering/RenderLayerCompositor.h | 3 ++ Source/WebCore/rendering/RenderObject.cpp | 2 +- Source/WebCore/rendering/RenderTreeAsText.cpp | 2 +- Source/WebCore/rendering/RenderView.cpp | 2 +- 20 files changed, 445 insertions(+), 19 deletions(-) create mode 100644 LayoutTests/compositing/backing/no-backing-for-clip-expected.txt create mode 100644 LayoutTests/compositing/backing/no-backing-for-clip-overlap-expected.txt create mode 100644 LayoutTests/compositing/backing/no-backing-for-clip-overlap.html create mode 100644 LayoutTests/compositing/backing/no-backing-for-clip.html create mode 100644 LayoutTests/compositing/backing/no-backing-for-perspective-expected.txt create mode 100644 LayoutTests/compositing/backing/no-backing-for-perspective.html diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index 94f1213..d7841ec 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,3 +1,25 @@ +2012-04-13 Simon Fraser + + Avoid using backing store for compositing layers that just need to clip + https://bugs.webkit.org/show_bug.cgi?id=40547 + + Reviewed by Dean Jackson. + + New tests for backing store elimination with clip or perspective. + + New results for some tests that no longer have backing store on some + layers. + + * compositing/backing/no-backing-for-clip-expected.txt: Added. + * compositing/backing/no-backing-for-clip-overlap-expected.txt: Added. + * compositing/backing/no-backing-for-clip-overlap.html: Added. + * compositing/backing/no-backing-for-clip.html: Added. + * compositing/backing/no-backing-for-perspective-expected.txt: Added. + * compositing/backing/no-backing-for-perspective.html: Added. + * compositing/geometry/preserve-3d-switching-expected.txt: + * compositing/visibility/layer-visible-content-expected.png: + * compositing/visibility/layer-visible-content-expected.txt: + 2012-04-16 Vincent Scheib [Chromium] Marking css3/filters/huge-region.html and composited version MISSING, CRASH. diff --git a/LayoutTests/compositing/backing/no-backing-for-clip-expected.txt b/LayoutTests/compositing/backing/no-backing-for-clip-expected.txt new file mode 100644 index 0000000..e50aa5c --- /dev/null +++ b/LayoutTests/compositing/backing/no-backing-for-clip-expected.txt @@ -0,0 +1,42 @@ +This layer should not have backing store. +This layer should not have backing store. +(GraphicsLayer + (bounds 800.00 600.00) + (children 1 + (GraphicsLayer + (bounds 800.00 600.00) + (children 1 + (GraphicsLayer + (position 8.00 8.00) + (bounds 342.00 240.00) + (children 1 + (GraphicsLayer + (position 1.00 1.00) + (bounds 340.00 238.00) + (children 1 + (GraphicsLayer + (position 20.00 38.00) + (bounds 320.00 180.00) + (children 1 + (GraphicsLayer + (position 1.00 1.00) + (bounds 340.00 178.00) + (children 1 + (GraphicsLayer + (position 30.00 48.00) + (bounds 100.00 100.00) + (drawsContent 1) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) +) + diff --git a/LayoutTests/compositing/backing/no-backing-for-clip-overlap-expected.txt b/LayoutTests/compositing/backing/no-backing-for-clip-overlap-expected.txt new file mode 100644 index 0000000..b260d0a --- /dev/null +++ b/LayoutTests/compositing/backing/no-backing-for-clip-overlap-expected.txt @@ -0,0 +1,48 @@ +This layer should not have backing store. +This layer should have backing store. +(GraphicsLayer + (bounds 800.00 600.00) + (children 1 + (GraphicsLayer + (bounds 800.00 600.00) + (children 2 + (GraphicsLayer + (position 8.00 8.00) + (bounds 342.00 180.00) + (children 1 + (GraphicsLayer + (position 1.00 1.00) + (bounds 340.00 178.00) + (children 1 + (GraphicsLayer + (position 30.00 48.00) + (bounds 100.00 100.00) + (drawsContent 1) + ) + ) + ) + ) + ) + (GraphicsLayer + (position 8.00 178.00) + (bounds 342.00 180.00) + (drawsContent 1) + (children 1 + (GraphicsLayer + (position 1.00 1.00) + (bounds 340.00 178.00) + (children 1 + (GraphicsLayer + (position 30.00 48.00) + (bounds 100.00 100.00) + (drawsContent 1) + ) + ) + ) + ) + ) + ) + ) + ) +) + diff --git a/LayoutTests/compositing/backing/no-backing-for-clip-overlap.html b/LayoutTests/compositing/backing/no-backing-for-clip-overlap.html new file mode 100644 index 0000000..685de81 --- /dev/null +++ b/LayoutTests/compositing/backing/no-backing-for-clip-overlap.html @@ -0,0 +1,59 @@ + + + + + + + + + + + +
+ This layer should not have backing store. +
+
+
+ This layer should have backing store. +
+
+ +
Layer tree goes here in DRT
+ + + diff --git a/LayoutTests/compositing/backing/no-backing-for-clip.html b/LayoutTests/compositing/backing/no-backing-for-clip.html new file mode 100644 index 0000000..4604802 --- /dev/null +++ b/LayoutTests/compositing/backing/no-backing-for-clip.html @@ -0,0 +1,59 @@ + + + + + + + + + + + +
+ This layer should not have backing store. +
+ This layer should not have backing store. +
+
+
+
+ +
Layer tree goes here in DRT
+ + + diff --git a/LayoutTests/compositing/backing/no-backing-for-perspective-expected.txt b/LayoutTests/compositing/backing/no-backing-for-perspective-expected.txt new file mode 100644 index 0000000..24e7306 --- /dev/null +++ b/LayoutTests/compositing/backing/no-backing-for-perspective-expected.txt @@ -0,0 +1,32 @@ +This layer should not have backing store. +This layer should not have backing store. +(GraphicsLayer + (bounds 800.00 600.00) + (children 1 + (GraphicsLayer + (bounds 800.00 600.00) + (children 1 + (GraphicsLayer + (position 8.00 8.00) + (bounds 342.00 240.00) + (childrenTransform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 -0.00] [0.00 0.00 0.00 1.00]) + (children 1 + (GraphicsLayer + (position 21.00 39.00) + (bounds 342.00 180.00) + (childrenTransform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 -0.00] [0.00 0.00 0.00 1.00]) + (children 1 + (GraphicsLayer + (position 31.00 49.00) + (bounds 100.00 100.00) + (drawsContent 1) + ) + ) + ) + ) + ) + ) + ) + ) +) + diff --git a/LayoutTests/compositing/backing/no-backing-for-perspective.html b/LayoutTests/compositing/backing/no-backing-for-perspective.html new file mode 100644 index 0000000..31e3689 --- /dev/null +++ b/LayoutTests/compositing/backing/no-backing-for-perspective.html @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+ This layer should not have backing store. +
+ This layer should not have backing store. +
+
+
+
+ +
Layer tree goes here in DRT
+ + + diff --git a/LayoutTests/compositing/geometry/preserve-3d-switching-expected.txt b/LayoutTests/compositing/geometry/preserve-3d-switching-expected.txt index 1e4762e..791dda2 100644 --- a/LayoutTests/compositing/geometry/preserve-3d-switching-expected.txt +++ b/LayoutTests/compositing/geometry/preserve-3d-switching-expected.txt @@ -10,7 +10,6 @@ The green box appear angled out from the yellow box and embedded in it. (GraphicsLayer (position 108.00 73.00) (bounds 304.00 304.00) - (drawsContent 1) (childrenTransform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 -0.00] [0.00 0.00 0.00 1.00]) (children 1 (GraphicsLayer diff --git a/LayoutTests/compositing/visibility/layer-visible-content-expected.png b/LayoutTests/compositing/visibility/layer-visible-content-expected.png index b6da2f3b3d70f44913b9f3cbceacc9aed418deab..0fb366eb1a8c9a8938f74c17c781e64cfce3761e 100644 GIT binary patch literal 3303 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRznkB9gCCM47$=SuFxeVs! z78VA^DQO0Y7DgtiDHdr)$>u3(i3aA$re+q#MyVO|_pV`J;HmU<>H=FA&8V66XX=I3Bwm>{UYz~JE408AW`j7$s+DJ-LcqX9CS7)CR~ tXvr{IDvs6&qqX5^Z8%yRV$_B+*^{R7EKfMS8PsrO@O1TaS?83{1OT}0oL~R| literal 10578 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRznkB9gCCM47$=SuFxeVs! z78VA^DQO0Y7DgtiDHdr)$>u3(i3aA$re+q#MyVO|_pV`JP+;(MaSW+oe0$R{&nZxV z#qq<@x3lYu8|SWIZc?hz?hO#!TCx9M-1*bbvsvcF+aJIFM`9lbBNGdUfPzDVgWiY9 z`cf(m4Gb`m1Bwa`d=lp&(qPdqOiWA6w|a~!84VW}j?u&b$~L2!WVB=$EingAHSwX& zZvNwEGvQGJWUOqccL?%JMykhj7#TN}+yPg65QQGBEFPyadl0%BRTUhj^-063La-?e zo|e6Wz$_0{wSk4@#HB)IINw1*R6s#*h0!vFLtwO^WoR6&eMYNfU^`;8oif^Z1NLr5 zTeJcSqs@F!4{EgUGuj~(80{sqaEuNeG>i@%C^(Fcr!b8U9RNq|Mu!eYhYo<_yQ4z~ zqeBOv$-u!dnm=cK&{PHnjvJu00Fa4>(KgFyn+4dLA8oUYwpl<0!f2aiw9PWwW&us) lk4|?Ck~RzR?UWDvNmF^2>pwoJ0$e1?;OXk;vd$@?2>>C7W#a$< diff --git a/LayoutTests/compositing/visibility/layer-visible-content-expected.txt b/LayoutTests/compositing/visibility/layer-visible-content-expected.txt index 97b92e5..7e96af6 100644 --- a/LayoutTests/compositing/visibility/layer-visible-content-expected.txt +++ b/LayoutTests/compositing/visibility/layer-visible-content-expected.txt @@ -6,7 +6,6 @@ (children 2 (GraphicsLayer (bounds 200.00 200.00) - (drawsContent 1) (children 1 (GraphicsLayer (bounds 200.00 200.00) diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 5efbce2..ae49c53 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,53 @@ +2012-04-13 Simon Fraser + + Avoid using backing store for compositing layers that just need to clip + https://bugs.webkit.org/show_bug.cgi?id=40547 + + Reviewed by Dean Jackson. + + If a layer becomes composited because it needs to clip composited + descendants, or if it has perspective, then it doesn't actually + needs its own backing store; its contents can be painted by an + ancestor, and we can just have an empty layer that does the clipping + or applies the perspective transform. + + This saves backing store memory on some pages. + + Tests: compositing/backing/no-backing-for-clip-overlap.html + compositing/backing/no-backing-for-clip.html + compositing/backing/no-backing-for-perspective.html + + * rendering/RenderLayer.cpp: + (WebCore): + (WebCore::RenderLayer::enclosingCompositingLayerForRepaint): + (WebCore::RenderLayer::paintLayer): + * rendering/RenderLayer.h: + (RenderLayer): + * rendering/RenderLayerBacking.cpp: + (WebCore::RenderLayerBacking::RenderLayerBacking): + (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): + (WebCore::RenderLayerBacking::containsPaintedContent): + (WebCore::RenderLayerBacking::setContentsNeedDisplay): + (WebCore::RenderLayerBacking::setContentsNeedDisplayInRect): + (WebCore::RenderLayerBacking::paintIntoLayer): + * rendering/RenderLayerBacking.h: + (RenderLayerBacking): + (WebCore::RenderLayerBacking::paintsIntoCompositedAncestor): + (WebCore::RenderLayerBacking::setRequiresOwnBackingStore): + * rendering/RenderLayerCompositor.cpp: + (WebCore::RenderLayerCompositor::layerWillBeRemoved): + (WebCore::RenderLayerCompositor::recursiveRepaintLayerRect): + (WebCore::RenderLayerCompositor::requiresCompositingLayer): + (WebCore::RenderLayerCompositor::requiresOwnBackingStore): + (WebCore): + * rendering/RenderLayerCompositor.h: + * rendering/RenderObject.cpp: + (WebCore::RenderObject::containerForRepaint): + * rendering/RenderTreeAsText.cpp: + (WebCore::write): + * rendering/RenderView.cpp: + (WebCore::RenderView::paintBoxDecorations): + 2012-04-16 Brady Eidson and https://bugs.webkit.org/show_bug.cgi?id=84050 diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp index 77b7011..4a2d37d 100644 --- a/Source/WebCore/rendering/RenderLayer.cpp +++ b/Source/WebCore/rendering/RenderLayer.cpp @@ -959,6 +959,19 @@ RenderLayer* RenderLayer::enclosingCompositingLayer(bool includeSelf) const return 0; } + +RenderLayer* RenderLayer::enclosingCompositingLayerForRepaint(bool includeSelf) const +{ + if (includeSelf && isComposited() && !backing()->paintsIntoCompositedAncestor()) + return const_cast(this); + + for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) { + if (curr->isComposited() && !curr->backing()->paintsIntoCompositedAncestor()) + return const_cast(curr); + } + + return 0; +} #endif #if ENABLE(CSS_FILTERS) @@ -2857,7 +2870,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* context, // but we need to ensure that we don't cache clip rects computed with the wrong root in this case. if (context->updatingControlTints() || (paintBehavior & PaintBehaviorFlattenCompositingLayers)) paintFlags |= PaintLayerTemporaryClipRects; - else if (!backing()->paintsIntoWindow() && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection)) { + else if (!backing()->paintsIntoWindow() && !backing()->paintsIntoCompositedAncestor() && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection)) { // If this RenderLayer should paint into its backing, that will be done via RenderLayerBacking::paintIntoLayer(). return; } diff --git a/Source/WebCore/rendering/RenderLayer.h b/Source/WebCore/rendering/RenderLayer.h index 90b011a..e67fb2c 100644 --- a/Source/WebCore/rendering/RenderLayer.h +++ b/Source/WebCore/rendering/RenderLayer.h @@ -420,6 +420,7 @@ public: #if USE(ACCELERATED_COMPOSITING) // Enclosing compositing layer; if includeSelf is true, may return this. RenderLayer* enclosingCompositingLayer(bool includeSelf = true) const; + RenderLayer* enclosingCompositingLayerForRepaint(bool includeSelf = true) const; // Ancestor compositing layer, excluding this. RenderLayer* ancestorCompositingLayer() const { return enclosingCompositingLayer(false); } #endif diff --git a/Source/WebCore/rendering/RenderLayerBacking.cpp b/Source/WebCore/rendering/RenderLayerBacking.cpp index 8c79fd3..c98bafd 100644 --- a/Source/WebCore/rendering/RenderLayerBacking.cpp +++ b/Source/WebCore/rendering/RenderLayerBacking.cpp @@ -92,6 +92,7 @@ RenderLayerBacking::RenderLayerBacking(RenderLayer* layer) , m_artificiallyInflatedBounds(false) , m_isMainFrameRenderViewLayer(false) , m_usingTiledCacheLayer(false) + , m_requiresOwnBackingStore(true) #if ENABLE(CSS_FILTERS) , m_canCompositeFilters(false) #endif @@ -563,6 +564,10 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() } m_graphicsLayer->setContentsRect(contentsBox()); + + // If this layer was created just for clipping or to apply perspective, it doesn't need its own backing store. + setRequiresOwnBackingStore(compositor()->requiresOwnBackingStore(m_owningLayer, compAncestor)); + updateDrawsContent(); updateAfterWidgetResize(); } @@ -937,7 +942,7 @@ bool RenderLayerBacking::hasVisibleNonCompositingDescendantLayers() const bool RenderLayerBacking::containsPaintedContent() const { - if (isSimpleContainerCompositingLayer() || paintsIntoWindow() || m_artificiallyInflatedBounds || m_owningLayer->isReflection()) + if (isSimpleContainerCompositingLayer() || paintsIntoWindow() || paintsIntoCompositedAncestor() || m_artificiallyInflatedBounds || m_owningLayer->isReflection()) return false; if (isDirectlyCompositedImage()) @@ -1095,6 +1100,8 @@ bool RenderLayerBacking::paintsIntoWindow() const void RenderLayerBacking::setContentsNeedDisplay() { + ASSERT(!paintsIntoCompositedAncestor()); + if (m_graphicsLayer && m_graphicsLayer->drawsContent()) m_graphicsLayer->setNeedsDisplay(); @@ -1108,6 +1115,8 @@ void RenderLayerBacking::setContentsNeedDisplay() // r is in the coordinate space of the layer's render object void RenderLayerBacking::setContentsNeedDisplayInRect(const IntRect& r) { + ASSERT(!paintsIntoCompositedAncestor()); + if (m_graphicsLayer && m_graphicsLayer->drawsContent()) { IntRect layerDirtyRect = r; layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer()); @@ -1132,7 +1141,7 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase, RenderObject* paintingRoot) { - if (paintsIntoWindow()) { + if (paintsIntoWindow() || paintsIntoCompositedAncestor()) { ASSERT_NOT_REACHED(); return; } diff --git a/Source/WebCore/rendering/RenderLayerBacking.h b/Source/WebCore/rendering/RenderLayerBacking.h index 4244dca..c11336c 100644 --- a/Source/WebCore/rendering/RenderLayerBacking.h +++ b/Source/WebCore/rendering/RenderLayerBacking.h @@ -96,6 +96,12 @@ public: // This returns false for other layers, and when the document layer actually needs to paint into its backing store // for some reason. bool paintsIntoWindow() const; + + // Returns true for a composited layer that has no backing store of its own, so + // paints into some ancestor layer. + bool paintsIntoCompositedAncestor() const { return !m_requiresOwnBackingStore; } + + void setRequiresOwnBackingStore(bool flag) { m_requiresOwnBackingStore = flag; } void setContentsNeedDisplay(); // r is in the coordinate space of the layer's render object @@ -235,6 +241,7 @@ private: bool m_artificiallyInflatedBounds; // bounds had to be made non-zero to make transform-origin work bool m_isMainFrameRenderViewLayer; bool m_usingTiledCacheLayer; + bool m_requiresOwnBackingStore; #if ENABLE(CSS_FILTERS) bool m_canCompositeFilters; #endif diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp index fb47da4..52d3616 100644 --- a/Source/WebCore/rendering/RenderLayerCompositor.cpp +++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp @@ -525,7 +525,7 @@ void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* setCompositingParent(child, 0); - RenderLayer* compLayer = parent->enclosingCompositingLayer(); + RenderLayer* compLayer = parent->enclosingCompositingLayerForRepaint(); if (compLayer) { ASSERT(compLayer->backing()); LayoutRect compBounds = child->backing()->compositedBounds(); @@ -1130,7 +1130,7 @@ void RenderLayerCompositor::repaintCompositedLayersAbsoluteRect(const IntRect& a void RenderLayerCompositor::recursiveRepaintLayerRect(RenderLayer* layer, const IntRect& rect) { // FIXME: This method does not work correctly with transforms. - if (layer->isComposited()) + if (layer->isComposited() && !layer->backing()->paintsIntoCompositedAncestor()) layer->setBackingNeedsRepaintInRect(rect); #if !ASSERT_DISABLED @@ -1325,15 +1325,15 @@ bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) c } // The root layer always has a compositing layer, but it may not have backing. return requiresCompositingForTransform(renderer) - || requiresCompositingForVideo(renderer) - || requiresCompositingForCanvas(renderer) - || requiresCompositingForPlugin(renderer) - || requiresCompositingForFrame(renderer) - || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden) - || clipsCompositingDescendants(layer) - || requiresCompositingForAnimation(renderer) - || requiresCompositingForFilters(renderer) - || requiresCompositingForPosition(renderer, layer); + || requiresCompositingForVideo(renderer) + || requiresCompositingForCanvas(renderer) + || requiresCompositingForPlugin(renderer) + || requiresCompositingForFrame(renderer) + || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden) + || clipsCompositingDescendants(layer) + || requiresCompositingForAnimation(renderer) + || requiresCompositingForFilters(renderer) + || requiresCompositingForPosition(renderer, layer); } bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const @@ -1341,6 +1341,32 @@ bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer(); } +bool RenderLayerCompositor::requiresOwnBackingStore(const RenderLayer* layer, const RenderLayer* compositingAncestorLayer) const +{ + RenderObject* renderer = layer->renderer(); + if (compositingAncestorLayer + && !(compositingAncestorLayer->backing()->graphicsLayer()->drawsContent() + || compositingAncestorLayer->backing()->paintsIntoWindow() + || compositingAncestorLayer->backing()->paintsIntoCompositedAncestor())) + return true; + + return layer->isRootLayer() + || layer->transform() // note: excludes perspective and transformStyle3D. + || requiresCompositingForVideo(renderer) + || requiresCompositingForCanvas(renderer) + || requiresCompositingForPlugin(renderer) + || requiresCompositingForFrame(renderer) + || (canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden) + || requiresCompositingForAnimation(renderer) + || requiresCompositingForFilters(renderer) + || requiresCompositingForPosition(renderer, layer) + || renderer->isTransparent() + || renderer->hasMask() + || renderer->hasReflection() + || renderer->hasFilter() + || layer->mustOverlapCompositedLayers(); +} + // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips, // up to the enclosing compositing ancestor. This is required because compositing layers are parented // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy. diff --git a/Source/WebCore/rendering/RenderLayerCompositor.h b/Source/WebCore/rendering/RenderLayerCompositor.h index a62afd4..cb207f0 100644 --- a/Source/WebCore/rendering/RenderLayerCompositor.h +++ b/Source/WebCore/rendering/RenderLayerCompositor.h @@ -136,6 +136,9 @@ public: // Repaint parts of all composited layers that intersect the given absolute rectangle. void repaintCompositedLayersAbsoluteRect(const IntRect&); + // Returns true if the given layer needs it own backing store. + bool requiresOwnBackingStore(const RenderLayer*, const RenderLayer* compositingAncestorLayer) const; + RenderLayer* rootRenderLayer() const; GraphicsLayer* rootGraphicsLayer() const; GraphicsLayer* scrollLayer() const; diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp index 3bea353..bf9201a 100755 --- a/Source/WebCore/rendering/RenderObject.cpp +++ b/Source/WebCore/rendering/RenderObject.cpp @@ -1243,7 +1243,7 @@ RenderBoxModelObject* RenderObject::containerForRepaint() const #if USE(ACCELERATED_COMPOSITING) if (v->usesCompositing()) { - RenderLayer* compLayer = enclosingLayer()->enclosingCompositingLayer(); + RenderLayer* compLayer = enclosingLayer()->enclosingCompositingLayerForRepaint(); if (compLayer) repaintContainer = compLayer->renderer(); } diff --git a/Source/WebCore/rendering/RenderTreeAsText.cpp b/Source/WebCore/rendering/RenderTreeAsText.cpp index 265b59a..55d68ed 100644 --- a/Source/WebCore/rendering/RenderTreeAsText.cpp +++ b/Source/WebCore/rendering/RenderTreeAsText.cpp @@ -631,7 +631,7 @@ static void write(TextStream& ts, RenderLayer& l, #if USE(ACCELERATED_COMPOSITING) if (behavior & RenderAsTextShowCompositedLayers) { if (l.isComposited()) - ts << " (composited, bounds " << l.backing()->compositedBounds() << ")"; + ts << " (composited, bounds=" << l.backing()->compositedBounds() << ", drawsContent=" << l.backing()->graphicsLayer()->drawsContent() << ", paints into ancestor=" << l.backing()->paintsIntoCompositedAncestor() << ")"; } #else UNUSED_PARAM(behavior); diff --git a/Source/WebCore/rendering/RenderView.cpp b/Source/WebCore/rendering/RenderView.cpp index 8f76afb..7f27098 100644 --- a/Source/WebCore/rendering/RenderView.cpp +++ b/Source/WebCore/rendering/RenderView.cpp @@ -255,7 +255,7 @@ void RenderView::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&) } #if USE(ACCELERATED_COMPOSITING) - if (RenderLayer* compositingLayer = layer->enclosingCompositingLayer()) { + if (RenderLayer* compositingLayer = layer->enclosingCompositingLayerForRepaint()) { if (!compositingLayer->backing()->paintsIntoWindow()) { frameView()->setCannotBlitToWindow(); break; -- 2.7.4