2 * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef CompositedLayerMapping_h
27 #define CompositedLayerMapping_h
29 #include "core/rendering/RenderLayer.h"
30 #include "core/rendering/compositing/GraphicsLayerUpdater.h"
31 #include "platform/geometry/FloatPoint.h"
32 #include "platform/geometry/FloatPoint3D.h"
33 #include "platform/graphics/GraphicsLayer.h"
34 #include "platform/graphics/GraphicsLayerClient.h"
38 class RenderLayerCompositor;
40 // A GraphicsLayerPaintInfo contains all the info needed to paint a partial subtree of RenderLayers into a GraphicsLayer.
41 struct GraphicsLayerPaintInfo {
42 RenderLayer* renderLayer;
44 LayoutRect compositedBounds;
46 // The clip rect to apply, in the local coordinate space of the squashed layer, when painting it.
47 IntRect localClipRectForSquashedLayer;
49 // Offset describing where this squashed RenderLayer paints into the shared GraphicsLayer backing.
50 IntSize offsetFromRenderer;
51 bool offsetFromRendererSet;
53 GraphicsLayerPaintInfo() : renderLayer(0), offsetFromRendererSet(false) { }
56 enum GraphicsLayerUpdateScope {
57 GraphicsLayerUpdateNone,
58 GraphicsLayerUpdateLocal,
59 GraphicsLayerUpdateSubtree,
62 // CompositedLayerMapping keeps track of how RenderLayers of the render tree correspond to
63 // GraphicsLayers of the composited layer tree. Each instance of CompositedLayerMapping
64 // manages a small cluster of GraphicsLayers and the references to which RenderLayers
65 // and paint phases contribute to each GraphicsLayer.
67 // Currently (Oct. 2013) there is one CompositedLayerMapping for each RenderLayer,
68 // but this is likely to evolve soon.
69 class CompositedLayerMapping FINAL : public GraphicsLayerClient {
70 WTF_MAKE_NONCOPYABLE(CompositedLayerMapping); WTF_MAKE_FAST_ALLOCATED;
72 explicit CompositedLayerMapping(RenderLayer&);
73 virtual ~CompositedLayerMapping();
75 RenderLayer& owningLayer() const { return m_owningLayer; }
77 bool updateGraphicsLayerConfiguration();
78 void updateGraphicsLayerGeometry(const RenderLayer* compositingContainer, const RenderLayer* compositingStackingContext, Vector<RenderLayer*>& layersNeedingPaintInvalidation);
80 // Update whether layer needs blending.
81 void updateContentsOpaque();
83 GraphicsLayer* mainGraphicsLayer() const { return m_graphicsLayer.get(); }
85 // Layer to clip children
86 bool hasClippingLayer() const { return m_childContainmentLayer; }
87 GraphicsLayer* clippingLayer() const { return m_childContainmentLayer.get(); }
89 // Layer to get clipped by ancestor
90 bool hasAncestorClippingLayer() const { return m_ancestorClippingLayer; }
91 GraphicsLayer* ancestorClippingLayer() const { return m_ancestorClippingLayer.get(); }
93 GraphicsLayer* foregroundLayer() const { return m_foregroundLayer.get(); }
95 GraphicsLayer* backgroundLayer() const { return m_backgroundLayer.get(); }
96 bool backgroundLayerPaintsFixedRootBackground() const { return m_backgroundLayerPaintsFixedRootBackground; }
98 bool hasScrollingLayer() const { return m_scrollingLayer; }
99 GraphicsLayer* scrollingLayer() const { return m_scrollingLayer.get(); }
100 GraphicsLayer* scrollingContentsLayer() const { return m_scrollingContentsLayer.get(); }
101 GraphicsLayer* scrollingBlockSelectionLayer() const { return m_scrollingBlockSelectionLayer.get(); }
103 bool hasMaskLayer() const { return m_maskLayer; }
104 GraphicsLayer* maskLayer() const { return m_maskLayer.get(); }
106 bool hasChildClippingMaskLayer() const { return m_childClippingMaskLayer; }
107 GraphicsLayer* childClippingMaskLayer() const { return m_childClippingMaskLayer.get(); }
109 GraphicsLayer* parentForSublayers() const;
110 GraphicsLayer* childForSuperlayers() const;
112 GraphicsLayer* childTransformLayer() const { return m_childTransformLayer.get(); }
114 GraphicsLayer* squashingContainmentLayer() const { return m_squashingContainmentLayer.get(); }
115 GraphicsLayer* squashingLayer() const { return m_squashingLayer.get(); }
116 // Contains the bottommost layer in the hierarchy that can contain the children transform.
117 GraphicsLayer* layerForChildrenTransform() const;
119 // Returns true for a composited layer that has no backing store of its own, so
120 // paints into some ancestor layer.
121 bool paintsIntoCompositedAncestor() const { return !(m_requiresOwnBackingStoreForAncestorReasons || m_requiresOwnBackingStoreForIntrinsicReasons); }
123 // Updates whether a backing store is needed based on the layer's compositing ancestor's
124 // properties; returns true if the need for a backing store for ancestor reasons changed.
125 bool updateRequiresOwnBackingStoreForAncestorReasons(const RenderLayer* compositingAncestor);
127 // Updates whether a backing store is needed for intrinsic reasons (that is, based on the
128 // layer's own properties or compositing reasons); returns true if the intrinsic need for
129 // a backing store changed.
130 bool updateRequiresOwnBackingStoreForIntrinsicReasons();
132 void setSquashingContentsNeedDisplay();
133 void setContentsNeedDisplay();
134 // r is in the coordinate space of the layer's render object
135 void setContentsNeedDisplayInRect(const LayoutRect&, WebInvalidationDebugAnnotations);
137 // Notification from the renderer that its content changed.
138 void contentChanged(ContentChangeType);
140 LayoutRect compositedBounds() const { return m_compositedBounds; }
141 IntRect pixelSnappedCompositedBounds() const;
143 void positionOverflowControlsLayers(const IntSize& offsetFromRoot);
144 bool hasUnpositionedOverflowControlsLayers() const;
146 // Returns true if the assignment actually changed the assigned squashing layer.
147 bool updateSquashingLayerAssignment(RenderLayer* squashedLayer, const RenderLayer& owningLayer, size_t nextSquashedLayerIndex);
148 void removeRenderLayerFromSquashingGraphicsLayer(const RenderLayer*);
150 void finishAccumulatingSquashingLayers(size_t nextSquashedLayerIndex);
151 void updateRenderingContext();
152 void updateShouldFlattenTransform();
154 // GraphicsLayerClient interface
155 virtual void notifyAnimationStarted(const GraphicsLayer*, double monotonicTime) OVERRIDE;
156 virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& clip) OVERRIDE;
157 virtual bool isTrackingPaintInvalidations() const OVERRIDE;
160 virtual void verifyNotPainting() OVERRIDE;
163 LayoutRect contentsBox() const;
165 GraphicsLayer* layerForHorizontalScrollbar() const { return m_layerForHorizontalScrollbar.get(); }
166 GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); }
167 GraphicsLayer* layerForScrollCorner() const { return m_layerForScrollCorner.get(); }
169 // Returns true if the overflow controls cannot be positioned within this
170 // CLM's internal hierarchy without incorrectly stacking under some
171 // scrolling content. If this returns true, these controls must be
172 // repositioned in the graphics layer tree to ensure that they stack above
173 // scrolling content.
174 bool needsToReparentOverflowControls() const;
176 // Removes the overflow controls host layer from its parent and positions it
177 // so that it can be inserted as a sibling to this CLM without changing
179 GraphicsLayer* detachLayerForOverflowControls(const RenderLayer& enclosingLayer);
181 void updateFilters(const RenderStyle*);
183 void setBlendMode(WebBlendMode);
185 bool needsGraphicsLayerUpdate() { return m_pendingUpdateScope > GraphicsLayerUpdateNone; }
186 void setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateScope scope) { m_pendingUpdateScope = std::max(static_cast<GraphicsLayerUpdateScope>(m_pendingUpdateScope), scope); }
187 void clearNeedsGraphicsLayerUpdate() { m_pendingUpdateScope = GraphicsLayerUpdateNone; }
189 GraphicsLayerUpdater::UpdateType updateTypeForChildren(GraphicsLayerUpdater::UpdateType) const;
192 void assertNeedsToUpdateGraphicsLayerBitsCleared() { ASSERT(m_pendingUpdateScope == GraphicsLayerUpdateNone); }
195 virtual String debugName(const GraphicsLayer*) OVERRIDE;
197 LayoutSize contentOffsetInCompositingLayer() const;
199 LayoutPoint squashingOffsetFromTransformedAncestor()
201 return m_squashingLayerOffsetFromTransformedAncestor;
204 // If there is a squashed layer painting into this CLM that is an ancestor of the given RenderObject, return it. Otherwise return 0.
205 const GraphicsLayerPaintInfo* containingSquashedLayer(const RenderObject*);
207 void updateScrollingBlockSelection();
210 static const GraphicsLayerPaintInfo* containingSquashedLayer(const RenderObject*, const Vector<GraphicsLayerPaintInfo>& layers);
212 // Helper methods to updateGraphicsLayerGeometry:
213 void computeGraphicsLayerParentLocation(const RenderLayer* compositingContainer, const IntRect& ancestorCompositingBounds, IntPoint& graphicsLayerParentLocation);
214 void updateSquashingLayerGeometry(const LayoutPoint& offsetFromCompositedAncestor, const IntPoint& graphicsLayerParentLocation, const RenderLayer& referenceLayer, Vector<GraphicsLayerPaintInfo>& layers, GraphicsLayer*, LayoutPoint* offsetFromTransformedAncestor, Vector<RenderLayer*>& layersNeedingPaintInvalidation);
215 void updateMainGraphicsLayerGeometry(const IntRect& relativeCompositingBounds, const IntRect& localCompositingBounds, const IntPoint& graphicsLayerParentLocation);
216 void updateAncestorClippingLayerGeometry(const RenderLayer* compositingContainer, const IntPoint& snappedOffsetFromCompositedAncestor, IntPoint& graphicsLayerParentLocation);
217 void updateOverflowControlsHostLayerGeometry(const RenderLayer* compositingStackingContext);
218 void updateChildContainmentLayerGeometry(const IntRect& clippingBox, const IntRect& localCompositingBounds);
219 void updateChildTransformLayerGeometry();
220 void updateMaskLayerGeometry();
221 void updateTransformGeometry(const IntPoint& snappedOffsetFromCompositedAncestor, const IntRect& relativeCompositingBounds);
222 void updateForegroundLayerGeometry(const FloatSize& relativeCompositingBoundsSize, const IntRect& clippingBox);
223 void updateBackgroundLayerGeometry(const FloatSize& relativeCompositingBoundsSize);
224 void updateReflectionLayerGeometry(Vector<RenderLayer*>& layersNeedingPaintInvalidation);
225 void updateScrollingLayerGeometry(const IntRect& localCompositingBounds);
226 void updateChildClippingMaskLayerGeometry();
228 void createPrimaryGraphicsLayer();
229 void destroyGraphicsLayers();
231 PassOwnPtr<GraphicsLayer> createGraphicsLayer(CompositingReasons);
232 bool toggleScrollbarLayerIfNeeded(OwnPtr<GraphicsLayer>&, bool needsLayer, CompositingReasons);
234 RenderLayerModelObject* renderer() const { return m_owningLayer.renderer(); }
235 RenderLayerCompositor* compositor() const { return m_owningLayer.compositor(); }
237 void updateInternalHierarchy();
238 void updatePaintingPhases();
239 bool updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip);
240 bool updateChildTransformLayer(bool needsChildTransformLayer);
241 bool updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer, bool needsAncestorClip);
242 bool updateForegroundLayer(bool needsForegroundLayer);
243 bool updateBackgroundLayer(bool needsBackgroundLayer);
244 bool updateMaskLayer(bool needsMaskLayer);
245 bool updateClippingMaskLayers(bool needsChildClippingMaskLayer);
246 bool requiresHorizontalScrollbarLayer() const { return m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->horizontalScrollbar(); }
247 bool requiresVerticalScrollbarLayer() const { return m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->verticalScrollbar(); }
248 bool requiresScrollCornerLayer() const { return m_owningLayer.scrollableArea() && !m_owningLayer.scrollableArea()->scrollCornerAndResizerRect().isEmpty(); }
249 bool updateScrollingLayers(bool scrollingLayers);
250 void updateScrollParent(RenderLayer*);
251 void updateClipParent();
252 bool updateSquashingLayers(bool needsSquashingLayers);
253 void updateDrawsContent();
254 void updateChildrenTransform();
255 void updateCompositedBounds();
256 void registerScrollingLayers();
258 // Also sets subpixelAccumulation on the layer.
259 void computeBoundsOfOwningLayer(const RenderLayer* compositedAncestor, IntRect& localCompositingBounds, IntRect& compositingBoundsRelativeToCompositedAncestor, LayoutPoint& offsetFromCompositedAncestor, IntPoint& snappedOffsetFromCompositedAncestor);
261 void setBackgroundLayerPaintsFixedRootBackground(bool);
263 GraphicsLayerPaintingPhase paintingPhaseForPrimaryLayer() const;
265 // Result is transform origin in pixels.
266 FloatPoint3D computeTransformOrigin(const IntRect& borderBox) const;
268 void updateOpacity(const RenderStyle*);
269 void updateTransform(const RenderStyle*);
270 void updateLayerBlendMode(const RenderStyle*);
271 void updateIsRootForIsolatedGroup();
272 // Return the opacity value that this layer should use for compositing.
273 float compositingOpacity(float rendererOpacity) const;
275 bool paintsChildren() const;
277 // Returns true if this layer has content that needs to be rendered by painting into the backing store.
278 bool containsPaintedContent() const;
279 // Returns true if the RenderLayer just contains an image that we can composite directly.
280 bool isDirectlyCompositedImage() const;
281 void updateImageContents();
283 Color rendererBackgroundColor() const;
284 void updateBackgroundColor();
285 void updateContentsRect();
286 void updateContentsOffsetInCompositingLayer(const IntPoint& snappedOffsetFromCompositedAncestor, const IntPoint& graphicsLayerParentLocation);
287 void updateAfterWidgetResize();
288 void updateCompositingReasons();
290 static bool hasVisibleNonCompositingDescendant(RenderLayer* parent);
292 void doPaintTask(const GraphicsLayerPaintInfo&, const PaintLayerFlags&, GraphicsContext*, const IntRect& clip);
294 // Computes the background clip rect for the given squashed layer, up to any containing layer that is squashed into the
295 // same squashing layer and contains this squashed layer's clipping ancestor.
296 // The clip rect is returned in the coordinate space of the given squashed layer.
297 // If there is no such containing layer, returns the infinite rect.
298 // FIXME: unify this code with the code that sets up m_ancestorClippingLayer. They are doing very similar things.
299 static IntRect localClipRectForSquashedLayer(const RenderLayer& referenceLayer, const GraphicsLayerPaintInfo&, const Vector<GraphicsLayerPaintInfo>& layers);
301 // Return true if |m_owningLayer|'s compositing ancestor is not a descendant (inclusive) of the
302 // clipping container for |m_owningLayer|.
303 bool owningLayerClippedByLayerNotAboveCompositedAncestor();
305 RenderLayer& m_owningLayer;
307 // The hierarchy of layers that is maintained by the CompositedLayerMapping looks like this:
309 // + m_ancestorClippingLayer [OPTIONAL]
311 // + m_childContainmentLayer [OPTIONAL] <-OR-> m_scrollingLayer [OPTIONAL] <-OR-> m_childTransformLayer
312 // | + m_scrollingContentsLayer [Present iff m_scrollingLayer is present]
313 // | + m_scrollingBlockSelectionLayer [Present iff m_scrollingLayer is present]
315 // + m_overflowControlsClippingLayer [OPTIONAL] // *The overflow controls may need to be repositioned in the
316 // + m_overflowControlsHostLayer // graphics layer tree by the RLC to ensure that they stack
317 // + m_layerForVerticalScrollbar // above scrolling content.
318 // + m_layerForHorizontalScrollbar
319 // + m_layerForScrollCorner
321 // We need an ancestor clipping layer if our clipping ancestor is not our ancestor in the
322 // clipping tree. Here's what that might look like.
324 // Let A = the clipping ancestor,
325 // B = the clip descendant, and
326 // SC = the stacking context that is the ancestor of A and B in the stacking tree.
329 // + A = m_graphicsLayer
330 // | + m_childContainmentLayer
334 // + B = m_ancestorClippingLayer [+]
338 // In this case B is clipped by another layer that doesn't happen to be its ancestor: A.
339 // So we create an ancestor clipping layer for B, [+], which ensures that B is clipped
340 // as if it had been A's descendant.
341 OwnPtr<GraphicsLayer> m_ancestorClippingLayer; // Only used if we are clipped by an ancestor which is not a stacking context.
342 OwnPtr<GraphicsLayer> m_graphicsLayer;
343 OwnPtr<GraphicsLayer> m_childContainmentLayer; // Only used if we have clipping on a stacking context with compositing children.
344 OwnPtr<GraphicsLayer> m_childTransformLayer; // Only used if we have perspective and no m_childContainmentLayer.
345 OwnPtr<GraphicsLayer> m_scrollingLayer; // Only used if the layer is using composited scrolling.
346 OwnPtr<GraphicsLayer> m_scrollingContentsLayer; // Only used if the layer is using composited scrolling.
347 OwnPtr<GraphicsLayer> m_scrollingBlockSelectionLayer; // Only used if the layer is using composited scrolling, but has no scrolling contents apart from block selection gaps.
349 // This layer is also added to the hierarchy by the RLB, but in a different way than
350 // the layers above. It's added to m_graphicsLayer as its mask layer (naturally) if
351 // we have a mask, and isn't part of the typical hierarchy (it has no children).
352 OwnPtr<GraphicsLayer> m_maskLayer; // Only used if we have a mask.
353 OwnPtr<GraphicsLayer> m_childClippingMaskLayer; // Only used if we have to clip child layers or accelerated contents with border radius or clip-path.
355 // There are two other (optional) layers whose painting is managed by the CompositedLayerMapping,
356 // but whose position in the hierarchy is maintained by the RenderLayerCompositor. These
357 // are the foreground and background layers. The foreground layer exists if we have composited
358 // descendants with negative z-order. We need the extra layer in this case because the layer
359 // needs to draw both below (for the background, say) and above (for the normal flow content, say)
360 // the negative z-order descendants and this is impossible with a single layer. The RLC handles
361 // inserting m_foregroundLayer in the correct position in our descendant list for us (right after
362 // the neg z-order dsecendants).
364 // The background layer is only created if this is the root layer and our background is entirely
365 // fixed. In this case we want to put the background in a separate composited layer so that when
366 // we scroll, we don't have to re-raster the background into position. This layer is also inserted
367 // into the tree by the RLC as it gets a special home. This layer becomes a descendant of the
368 // frame clipping layer. That is:
370 // + frame clipping layer
371 // + m_backgroundLayer
372 // + frame scrolling layer
373 // + root content layer
375 // With the hierarchy set up like this, the root content layer is able to scroll without affecting
376 // the background layer (or paint invalidation).
377 OwnPtr<GraphicsLayer> m_foregroundLayer; // Only used in cases where we need to draw the foreground separately.
378 OwnPtr<GraphicsLayer> m_backgroundLayer; // Only used in cases where we need to draw the background separately.
380 OwnPtr<GraphicsLayer> m_layerForHorizontalScrollbar;
381 OwnPtr<GraphicsLayer> m_layerForVerticalScrollbar;
382 OwnPtr<GraphicsLayer> m_layerForScrollCorner;
384 // This layer exists to simplify the reparenting of overflow control that is occasionally required
385 // to ensure that scrollbars appear above scrolling content.
386 OwnPtr<GraphicsLayer> m_overflowControlsHostLayer;
388 // The reparented overflow controls sometimes need to be clipped by a non-ancestor. In just the same
389 // way we need an ancestor clipping layer to clip this CLM's internal hierarchy, we add another layer
390 // to clip the overflow controls. It would be possible to make m_overflowControlsHostLayer be
391 // responsible for applying this clip, but that could require repositioning all of the overflow
392 // controls since the this clip may apply an offset. By using a separate layer, the overflow controls
393 // can remain ignorant of the layers above them and still work correctly.
394 OwnPtr<GraphicsLayer> m_overflowControlsClippingLayer;
396 // A squashing CLM has two possible squashing-related structures.
398 // If m_ancestorClippingLayer is present:
400 // m_ancestorClippingLayer
402 // + m_squashingLayer
406 // m_squashingContainmentLayer
408 // + m_squashingLayer
410 // Stacking children of a squashed layer receive graphics layers that are parented to the compositd ancestor of the
411 // squashed layer (i.e. nearest enclosing composited layer that is not squashed).
412 OwnPtr<GraphicsLayer> m_squashingContainmentLayer; // Only used if any squashed layers exist and m_squashingContainmentLayer is not present, to contain the squashed layers as siblings to the rest of the GraphicsLayer tree chunk.
413 OwnPtr<GraphicsLayer> m_squashingLayer; // Only used if any squashed layers exist, this is the backing that squashed layers paint into.
414 Vector<GraphicsLayerPaintInfo> m_squashedLayers;
415 LayoutPoint m_squashingLayerOffsetFromTransformedAncestor;
417 LayoutRect m_compositedBounds;
419 LayoutSize m_contentOffsetInCompositingLayer;
420 unsigned m_contentOffsetInCompositingLayerDirty : 1;
422 unsigned m_pendingUpdateScope : 2;
423 unsigned m_isMainFrameRenderViewLayer : 1;
424 unsigned m_requiresOwnBackingStoreForIntrinsicReasons : 1;
425 unsigned m_requiresOwnBackingStoreForAncestorReasons : 1;
426 unsigned m_backgroundLayerPaintsFixedRootBackground : 1;
427 unsigned m_scrollingContentsAreEmpty : 1;
432 #endif // CompositedLayerMapping_h