• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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.
24  */
25 
26 #ifndef RenderLayerCompositor_h
27 #define RenderLayerCompositor_h
28 
29 #include "core/page/ChromeClient.h"
30 #include "core/rendering/RenderLayer.h"
31 #include "platform/graphics/GraphicsLayerClient.h"
32 #include "wtf/HashMap.h"
33 
34 namespace WebCore {
35 
36 class FixedPositionViewportConstraints;
37 class GraphicsLayer;
38 class RenderEmbeddedObject;
39 class RenderLayerStackingNode;
40 class RenderPart;
41 class RenderVideo;
42 class ScrollingCoordinator;
43 class StickyPositionViewportConstraints;
44 
45 
46 enum CompositingUpdateType {
47     CompositingUpdateAfterStyleChange,
48     CompositingUpdateAfterLayout,
49     CompositingUpdateOnScroll,
50     CompositingUpdateOnCompositedScroll,
51     CompositingUpdateFinishAllDeferredWork
52 };
53 
54 // RenderLayerCompositor manages the hierarchy of
55 // composited RenderLayers. It determines which RenderLayers
56 // become compositing, and creates and maintains a hierarchy of
57 // GraphicsLayers based on the RenderLayer painting order.
58 //
59 // There is one RenderLayerCompositor per RenderView.
60 
61 class RenderLayerCompositor : public GraphicsLayerClient {
62     WTF_MAKE_FAST_ALLOCATED;
63 public:
64     explicit RenderLayerCompositor(RenderView*);
65     ~RenderLayerCompositor();
66 
67     // Return true if this RenderView is in "compositing mode" (i.e. has one or more
68     // composited RenderLayers)
inCompositingMode()69     bool inCompositingMode() const { return m_compositing; }
70     // This will make a compositing layer at the root automatically, and hook up to
71     // the native view/window system.
72     void enableCompositingMode(bool enable = true);
73 
inForcedCompositingMode()74     bool inForcedCompositingMode() const { return m_forceCompositingMode; }
75 
76     // Returns true if the accelerated compositing is enabled
hasAcceleratedCompositing()77     bool hasAcceleratedCompositing() const { return m_hasAcceleratedCompositing; }
78     bool layerSquashingEnabled() const;
79 
80     bool canRender3DTransforms() const;
81 
82     // Copy the accelerated compositing related flags from Settings
83     void cacheAcceleratedCompositingFlags();
84 
85     // Called when the layer hierarchy needs to be updated (compositing layers have been
86     // created, destroyed or re-parented).
87     void setCompositingLayersNeedRebuild(bool needRebuild = true);
compositingLayersNeedRebuild()88     bool compositingLayersNeedRebuild() const { return m_compositingLayersNeedRebuild; }
89 
90     // Called when something outside WebKit affects the visible rect (e.g. delegated scrolling). Might schedule a layer flush.
91     void didChangeVisibleRect();
92 
93     // Updating properties required for determining if compositing is necessary.
94     void updateCompositingRequirementsState();
setNeedsUpdateCompositingRequirementsState()95     void setNeedsUpdateCompositingRequirementsState() { m_needsUpdateCompositingRequirementsState = true; }
96 
97     // Main entry point for a full update. As needed, this function will compute compositing requirements,
98     // rebuild the composited layer tree, and/or update all the properties assocaited with each layer of the
99     // composited layer tree.
100     void updateCompositingLayers(CompositingUpdateType);
101 
102     // Update the compositing state of the given layer. Returns true if that state changed.
103     bool updateLayerCompositingState(RenderLayer*);
104 
105     // Update the geometry for compositing children of compositingAncestor.
106     void updateCompositingDescendantGeometry(RenderLayerStackingNode* compositingAncestor, RenderLayer*, bool compositedChildrenOnly);
107 
108     // Whether layer's compositedLayerMapping needs a GraphicsLayer to do clipping by an ancestor (non-stacking-context parent with overflow).
109     bool clippedByAncestor(const RenderLayer*) const;
110     // Whether layer's compositedLayerMapping needs a GraphicsLayer to clip z-order children of the given RenderLayer.
111     bool clipsCompositingDescendants(const RenderLayer*) const;
112 
113     // Whether the given layer needs an extra 'contents' layer.
114     bool needsContentsCompositingLayer(const RenderLayer*) const;
115 
116     bool supportsFixedRootBackgroundCompositing() const;
117     bool needsFixedRootBackgroundLayer(const RenderLayer*) const;
118     GraphicsLayer* fixedRootBackgroundLayer() const;
119 
120     // Return the bounding box required for compositing layer and its childern, relative to ancestorLayer.
121     // If layerBoundingBox is not 0, on return it contains the bounding box of this layer only.
122     IntRect calculateCompositedBounds(const RenderLayer*, const RenderLayer* ancestorLayer) const;
123 
124     // Repaint the appropriate layers when the given RenderLayer starts or stops being composited.
125     void repaintOnCompositingChange(RenderLayer*);
126 
127     void repaintInCompositedAncestor(RenderLayer*, const LayoutRect&);
128 
129     // Notify us that a layer has been added or removed
130     void layerWasAdded(RenderLayer* parent, RenderLayer* child);
131     void layerWillBeRemoved(RenderLayer* parent, RenderLayer* child);
132 
133     // Get the nearest ancestor layer that has overflow or clip, but is not a stacking context
134     RenderLayer* enclosingNonStackingClippingLayer(const RenderLayer* layer) const;
135 
136     // Repaint parts of all composited layers that intersect the given absolute rectangle (or the entire layer if the pointer is null).
137     void repaintCompositedLayers(const IntRect* = 0);
138 
139     RenderLayer* rootRenderLayer() const;
140     GraphicsLayer* rootGraphicsLayer() const;
141     GraphicsLayer* scrollLayer() const;
142 
143     enum RootLayerAttachment {
144         RootLayerUnattached,
145         RootLayerAttachedViaChromeClient,
146         RootLayerAttachedViaEnclosingFrame
147     };
148 
rootLayerAttachment()149     RootLayerAttachment rootLayerAttachment() const { return m_rootLayerAttachment; }
150     void updateRootLayerAttachment();
151     void updateRootLayerPosition();
152 
153     void setIsInWindow(bool);
154 
155     void clearMappingForAllRenderLayers();
156 
157     // Use by RenderVideo to ask if it should try to use accelerated compositing.
158     bool canAccelerateVideoRendering(RenderVideo*) const;
159 
160     // Walk the tree looking for layers with 3d transforms. Useful in case you need
161     // to know if there is non-affine content, e.g. for drawing into an image.
162     bool has3DContent() const;
163 
164     static RenderLayerCompositor* frameContentsCompositor(RenderPart*);
165     // Return true if the layers changed.
166     static bool parentFrameContentLayers(RenderPart*);
167 
168     // Update the geometry of the layers used for clipping and scrolling in frames.
169     void frameViewDidChangeLocation(const IntPoint& contentsOffset);
170     void frameViewDidChangeSize();
171     void frameViewDidScroll();
172     void frameViewDidLayout();
173     void frameViewScrollbarsExistenceDidChange();
174     void rootFixedBackgroundsChanged();
175 
176     bool scrollingLayerDidChange(RenderLayer*);
177 
178     String layerTreeAsText(LayerTreeFlags);
179 
180     virtual void didCommitChangesForLayer(const GraphicsLayer*) const OVERRIDE;
181 
layerForHorizontalScrollbar()182     GraphicsLayer* layerForHorizontalScrollbar() const { return m_layerForHorizontalScrollbar.get(); }
layerForVerticalScrollbar()183     GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); }
layerForScrollCorner()184     GraphicsLayer* layerForScrollCorner() const { return m_layerForScrollCorner.get(); }
185 
186     void updateViewportConstraintStatus(RenderLayer*);
187     void removeViewportConstrainedLayer(RenderLayer*);
188 
189     void addOutOfFlowPositionedLayer(RenderLayer*);
190     void removeOutOfFlowPositionedLayer(RenderLayer*);
191 
192     void resetTrackedRepaintRects();
193     void setTracksRepaints(bool);
194 
setNeedsToRecomputeCompositingRequirements()195     void setNeedsToRecomputeCompositingRequirements() { m_needsToRecomputeCompositingRequirements = true; }
196 
197     virtual String debugName(const GraphicsLayer*) OVERRIDE;
198 
199 private:
200     class OverlapMap;
201 
202     // GraphicsLayerClient implementation
notifyAnimationStarted(const GraphicsLayer *,double,double)203     virtual void notifyAnimationStarted(const GraphicsLayer*, double, double) OVERRIDE { }
204     virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&) OVERRIDE;
205 
206     virtual bool isTrackingRepaints() const OVERRIDE;
207 
208     // Whether the given RL needs to paint into its own separate backing (and hence would need its own CompositedLayerMapping).
209     bool needsOwnBacking(const RenderLayer*) const;
210     // Whether the layer could ever be composited.
211     bool canBeComposited(const RenderLayer*) const;
212 
213     // Returns all direct reasons that a layer should be composited.
214     CompositingReasons directReasonsForCompositing(const RenderLayer*) const;
215 
216     void updateDirectCompositingReasons(RenderLayer*);
217 
218     // Returns indirect reasons that a layer should be composited because of something in its subtree.
219     CompositingReasons subtreeReasonsForCompositing(RenderObject*, bool hasCompositedDescendants, bool has3DTransformedDescendants) const;
220 
221     // Make or destroy the CompositedLayerMapping for this layer; returns true if the compositedLayerMapping changed.
222     bool allocateOrClearCompositedLayerMapping(RenderLayer*);
223 
224     void clearMappingForRenderLayerIncludingDescendants(RenderLayer*);
225 
226     // Repaint the given rect (which is layer's coords), and regions of child layers that intersect that rect.
227     void recursiveRepaintLayer(RenderLayer*, const IntRect* = 0);
228 
229     void addToOverlapMap(OverlapMap&, RenderLayer*, IntRect& layerBounds, bool& boundsComputed);
230     void addToOverlapMapRecursive(OverlapMap&, RenderLayer*, RenderLayer* ancestorLayer = 0);
231 
232     struct SquashingState {
SquashingStateSquashingState233         SquashingState()
234             : mostRecentMapping(0)
235             , hasMostRecentMapping(false)
236             , nextSquashedLayerIndex(0) { }
237 
238         void updateSquashingStateForNewMapping(CompositedLayerMappingPtr, bool hasNewCompositedLayerMapping, IntPoint newOffsetFromAbsolute);
239 
240         // The most recent composited backing that the layer should squash onto if needed.
241         CompositedLayerMappingPtr mostRecentMapping;
242         bool hasMostRecentMapping;
243 
244         // Offset in absolute coordinates of the compositedLayerMapping's owning layer.
245         IntPoint offsetFromAbsolute;
246 
247         // Counter that tracks what index the next RenderLayer would be if it gets squashed to the current squashing layer.
248         size_t nextSquashedLayerIndex;
249     };
250 
251     // Forces an update for all frames of frame tree recursively. Used only when the mainFrame compositor is ready to
252     // finish all deferred work.
253     static void finishCompositingUpdateForFrameTree(Frame*);
254 
255     // Returns true if any layer's compositing changed
256     void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer*, OverlapMap*, struct CompositingRecursionData&, bool& descendantHas3DTransform, Vector<RenderLayer*>& unclippedDescendants);
257 
258     // Defines which RenderLayers will paint into which composited backings, by allocating and destroying CompositedLayerMappings as needed.
259     void assignLayersToBackings(RenderLayer*, bool& layersChanged);
260     void assignLayersToBackingsInternal(RenderLayer*, SquashingState&, bool& layersChanged);
261 
262     // Recurses down the tree, parenting descendant compositing layers and collecting an array of child layers for the current compositing layer.
263     void rebuildCompositingLayerTree(RenderLayer*, Vector<GraphicsLayer*>& childGraphicsLayersOfEnclosingLayer, int depth);
264 
265     // Recurses down the tree, updating layer geometry only.
266     void updateLayerTreeGeometry(RenderLayer*);
267 
268     // Hook compositing layers together
269     void setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer);
270     void removeCompositedChildren(RenderLayer*);
271 
272     bool layerHas3DContent(const RenderLayer*) const;
273     bool isRunningAcceleratedTransformAnimation(RenderObject*) const;
274 
275     bool hasAnyAdditionalCompositedLayers(const RenderLayer* rootLayer) const;
276 
277     void ensureRootLayer();
278     void destroyRootLayer();
279 
280     void attachRootLayer(RootLayerAttachment);
281     void detachRootLayer();
282 
283     bool isMainFrame() const;
284 
285     void updateOverflowControlsLayers();
286 
287     void notifyIFramesOfCompositingChange();
288 
289     Page* page() const;
290 
291     GraphicsLayerFactory* graphicsLayerFactory() const;
292     ScrollingCoordinator* scrollingCoordinator() const;
293 
294     // Whether a running transition or animation enforces the need for a compositing layer.
295     bool requiresCompositingForAnimation(RenderObject*) const;
296     // Whether a (not necessarily running) transition enforces the need for a compositing layer.
297     bool requiresCompositingForTransition(RenderObject*) const;
298     bool requiresCompositingForTransform(RenderObject*) const;
299     bool requiresCompositingForVideo(RenderObject*) const;
300     bool requiresCompositingForCanvas(RenderObject*) const;
301     bool requiresCompositingForPlugin(RenderObject*) const;
302     bool requiresCompositingForFrame(RenderObject*) const;
303     bool requiresCompositingForBackfaceVisibilityHidden(RenderObject*) const;
304     bool requiresCompositingForFilters(RenderObject*) const;
305     bool requiresCompositingForOverflowScrollingParent(const RenderLayer*) const;
306     bool requiresCompositingForOutOfFlowClipping(const RenderLayer*) const;
307     bool requiresCompositingForScrollableFrame() const;
308     bool requiresCompositingForPosition(RenderObject*, const RenderLayer*, RenderLayer::ViewportConstrainedNotCompositedReason* = 0) const;
309     bool requiresCompositingForOverflowScrolling(const RenderLayer*) const;
310 
311     void addViewportConstrainedLayer(RenderLayer*);
312 
313     FixedPositionViewportConstraints computeFixedViewportConstraints(RenderLayer*) const;
314     StickyPositionViewportConstraints computeStickyViewportConstraints(RenderLayer*) const;
315 
316     bool requiresHorizontalScrollbarLayer() const;
317     bool requiresVerticalScrollbarLayer() const;
318     bool requiresScrollCornerLayer() const;
319 #if USE(RUBBER_BANDING)
320     bool requiresOverhangLayers() const;
321 #endif
322 
323 private:
324     RenderView* m_renderView;
325     OwnPtr<GraphicsLayer> m_rootContentLayer;
326 
327     bool m_hasAcceleratedCompositing;
328     ChromeClient::CompositingTriggerFlags m_compositingTriggers;
329 
330     bool m_showRepaintCounter;
331 
332     // FIXME: This should absolutely not be mutable.
333     mutable bool m_needsToRecomputeCompositingRequirements;
334     bool m_needsToUpdateLayerTreeGeometry;
335 
336     bool m_compositing;
337     bool m_compositingLayersNeedRebuild;
338     bool m_forceCompositingMode;
339     bool m_inPostLayoutUpdate; // true when it's OK to trust layout information (e.g. layer sizes and positions)
340     bool m_needsUpdateCompositingRequirementsState;
341 
342     bool m_isTrackingRepaints; // Used for testing.
343 
344     RootLayerAttachment m_rootLayerAttachment;
345 
346     // Enclosing container layer, which clips for iframe content
347     OwnPtr<GraphicsLayer> m_containerLayer;
348     OwnPtr<GraphicsLayer> m_scrollLayer;
349 
350     HashSet<RenderLayer*> m_viewportConstrainedLayers;
351     HashSet<RenderLayer*> m_viewportConstrainedLayersNeedingUpdate;
352 
353     // This is used in updateCompositingRequirementsState to avoid full tree
354     // walks while determining if layers have unclipped descendants.
355     HashSet<RenderLayer*> m_outOfFlowPositionedLayers;
356 
357     // Enclosing layer for overflow controls and the clipping layer
358     OwnPtr<GraphicsLayer> m_overflowControlsHostLayer;
359 
360     // Layers for overflow controls
361     OwnPtr<GraphicsLayer> m_layerForHorizontalScrollbar;
362     OwnPtr<GraphicsLayer> m_layerForVerticalScrollbar;
363     OwnPtr<GraphicsLayer> m_layerForScrollCorner;
364 #if USE(RUBBER_BANDING)
365     OwnPtr<GraphicsLayer> m_layerForOverhangShadow;
366 #endif
367 };
368 
369 
370 } // namespace WebCore
371 
372 #endif // RenderLayerCompositor_h
373