1/*
2 * Copyright (C) 2009, 2010, 2011 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 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 RenderLayerBacking_h
27#define RenderLayerBacking_h
28
29#include "FloatPoint.h"
30#include "FloatPoint3D.h"
31#include "GraphicsLayer.h"
32#include "GraphicsLayerClient.h"
33#include "RenderLayer.h"
34#include "ScrollingCoordinator.h"
35
36namespace WebCore {
37
38class KeyframeList;
39class RenderLayerCompositor;
40class TiledBacking;
41class TransformationMatrix;
42
43enum CompositingLayerType {
44    NormalCompositingLayer, // non-tiled layer with backing store
45    TiledCompositingLayer, // tiled layer (always has backing store)
46    MediaCompositingLayer, // layer that contains an image, video, webGL or plugin
47    ContainerCompositingLayer // layer with no backing store
48};
49
50// RenderLayerBacking controls the compositing behavior for a single RenderLayer.
51// It holds the various GraphicsLayers, and makes decisions about intra-layer rendering
52// optimizations.
53//
54// There is one RenderLayerBacking for each RenderLayer that is composited.
55
56class RenderLayerBacking final : public GraphicsLayerClient {
57    WTF_MAKE_NONCOPYABLE(RenderLayerBacking); WTF_MAKE_FAST_ALLOCATED;
58public:
59    explicit RenderLayerBacking(RenderLayer&);
60    ~RenderLayerBacking();
61
62#if PLATFORM(IOS)
63    void layerWillBeDestroyed();
64#endif
65
66    RenderLayer& owningLayer() const { return m_owningLayer; }
67
68    enum UpdateAfterLayoutFlag {
69        CompositingChildrenOnly = 1 << 0,
70        NeedsFullRepaint = 1 << 1,
71        IsUpdateRoot = 1 << 2
72    };
73    typedef unsigned UpdateAfterLayoutFlags;
74    void updateAfterLayout(UpdateAfterLayoutFlags);
75
76    // Returns true if layer configuration changed.
77    bool updateConfiguration();
78
79    // Update graphics layer position and bounds.
80    void updateGeometry();
81
82    // Update state the requires that descendant layers have been updated.
83    void updateAfterDescendents();
84
85    // Update contents and clipping structure.
86    void updateDrawsContent();
87
88    GraphicsLayer* graphicsLayer() const { return m_graphicsLayer.get(); }
89
90    // Layer to clip children
91    bool hasClippingLayer() const { return (m_childContainmentLayer && !m_usingTiledCacheLayer); }
92    GraphicsLayer* clippingLayer() const { return !m_usingTiledCacheLayer ? m_childContainmentLayer.get() : 0; }
93
94    // Layer to get clipped by ancestor
95    bool hasAncestorClippingLayer() const { return m_ancestorClippingLayer != 0; }
96    GraphicsLayer* ancestorClippingLayer() const { return m_ancestorClippingLayer.get(); }
97
98    GraphicsLayer* contentsContainmentLayer() const { return m_contentsContainmentLayer.get(); }
99
100    bool hasContentsLayer() const { return m_foregroundLayer != 0; }
101    GraphicsLayer* foregroundLayer() const { return m_foregroundLayer.get(); }
102
103    GraphicsLayer* backgroundLayer() const { return m_backgroundLayer.get(); }
104    bool backgroundLayerPaintsFixedRootBackground() const { return m_backgroundLayerPaintsFixedRootBackground; }
105
106    bool hasScrollingLayer() const { return m_scrollingLayer != nullptr; }
107    GraphicsLayer* scrollingLayer() const { return m_scrollingLayer.get(); }
108    GraphicsLayer* scrollingContentsLayer() const { return m_scrollingContentsLayer.get(); }
109
110    void detachFromScrollingCoordinator();
111
112    ScrollingNodeID scrollingNodeIDForRole(ScrollingNodeType nodeType) const
113    {
114        switch (nodeType) {
115        case FrameScrollingNode:
116        case OverflowScrollingNode:
117            return m_scrollingNodeID;
118        case FixedNode:
119        case StickyNode:
120            return m_viewportConstrainedNodeID;
121        }
122        return 0;
123    }
124
125    void setScrollingNodeIDForRole(ScrollingNodeID nodeID, ScrollingNodeType nodeType)
126    {
127        switch (nodeType) {
128        case FrameScrollingNode:
129        case OverflowScrollingNode:
130            m_scrollingNodeID = nodeID;
131            break;
132        case FixedNode:
133        case StickyNode:
134            m_viewportConstrainedNodeID = nodeID;
135            break;
136        }
137    }
138
139    ScrollingNodeID scrollingNodeIDForChildren() const { return m_scrollingNodeID ? m_scrollingNodeID : m_viewportConstrainedNodeID; }
140
141    bool hasMaskLayer() const { return m_maskLayer != 0; }
142
143    GraphicsLayer* parentForSublayers() const;
144    GraphicsLayer* childForSuperlayers() const;
145
146    // RenderLayers with backing normally short-circuit paintLayer() because
147    // their content is rendered via callbacks from GraphicsLayer. However, the document
148    // layer is special, because it has a GraphicsLayer to act as a container for the GraphicsLayers
149    // for descendants, but its contents usually render into the window (in which case this returns true).
150    // This returns false for other layers, and when the document layer actually needs to paint into its backing store
151    // for some reason.
152    bool paintsIntoWindow() const;
153
154    // Returns true for a composited layer that has no backing store of its own, so
155    // paints into some ancestor layer.
156    bool paintsIntoCompositedAncestor() const { return !m_requiresOwnBackingStore; }
157
158    void setRequiresOwnBackingStore(bool);
159
160    void setContentsNeedDisplay(GraphicsLayer::ShouldClipToLayer = GraphicsLayer::ClipToLayer);
161    // r is in the coordinate space of the layer's render object
162    void setContentsNeedDisplayInRect(const LayoutRect&, GraphicsLayer::ShouldClipToLayer = GraphicsLayer::ClipToLayer);
163
164    // Notification from the renderer that its content changed.
165    void contentChanged(ContentChangeType);
166
167    // Interface to start, finish, suspend and resume animations and transitions
168    bool startTransition(double, CSSPropertyID, const RenderStyle* fromStyle, const RenderStyle* toStyle);
169    void transitionPaused(double timeOffset, CSSPropertyID);
170    void transitionFinished(CSSPropertyID);
171
172    bool startAnimation(double timeOffset, const Animation* anim, const KeyframeList& keyframes);
173    void animationPaused(double timeOffset, const String& name);
174    void animationFinished(const String& name);
175
176    void suspendAnimations(double time = 0);
177    void resumeAnimations();
178
179    LayoutRect compositedBounds() const;
180    void setCompositedBounds(const LayoutRect&);
181    void updateCompositedBounds();
182
183    void updateAfterWidgetResize();
184    void positionOverflowControlsLayers();
185    bool hasUnpositionedOverflowControlsLayers() const;
186
187    bool usingTiledBacking() const { return m_usingTiledCacheLayer; }
188    TiledBacking* tiledBacking() const;
189    void adjustTiledBackingCoverage();
190    void setTiledBackingHasMargins(bool hasExtendedBackgroundOnLeftAndRight, bool hasExtendedBackgroundOnTopAndBottom);
191
192    void updateDebugIndicators(bool showBorder, bool showRepaintCounter);
193
194    // GraphicsLayerClient interface
195    virtual bool shouldUseTiledBacking(const GraphicsLayer*) const override;
196    virtual void tiledBackingUsageChanged(const GraphicsLayer*, bool /*usingTiledBacking*/) override;
197    virtual void notifyAnimationStarted(const GraphicsLayer*, double startTime) override;
198    virtual void notifyFlushRequired(const GraphicsLayer*) override;
199    virtual void notifyFlushBeforeDisplayRefresh(const GraphicsLayer*) override;
200
201    virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const FloatRect& clip) override;
202
203    virtual float deviceScaleFactor() const override;
204    virtual float contentsScaleMultiplierForNewTiles(const GraphicsLayer*) const override;
205
206    virtual bool paintsOpaquelyAtNonIntegralScales(const GraphicsLayer*) const override;
207
208    virtual float pageScaleFactor() const override;
209    virtual float zoomedOutPageScaleFactor() const override;
210    virtual void didCommitChangesForLayer(const GraphicsLayer*) const override;
211    virtual bool getCurrentTransform(const GraphicsLayer*, TransformationMatrix&) const override;
212
213    virtual bool isTrackingRepaints() const override;
214    virtual bool shouldSkipLayerInDump(const GraphicsLayer*) const override;
215    virtual bool shouldDumpPropertyForLayer(const GraphicsLayer*, const char* propertyName) const override;
216
217    virtual bool shouldAggressivelyRetainTiles(const GraphicsLayer*) const override;
218    virtual bool shouldTemporarilyRetainTileCohorts(const GraphicsLayer*) const override;
219    virtual bool needsPixelAligment() const override { return !m_isMainFrameRenderViewLayer; }
220
221#ifndef NDEBUG
222    virtual void verifyNotPainting();
223#endif
224
225    LayoutRect contentsBox() const;
226
227    // For informative purposes only.
228    CompositingLayerType compositingLayerType() const;
229
230    GraphicsLayer* layerForHorizontalScrollbar() const { return m_layerForHorizontalScrollbar.get(); }
231    GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); }
232    GraphicsLayer* layerForScrollCorner() const { return m_layerForScrollCorner.get(); }
233
234#if ENABLE(CSS_FILTERS)
235    bool canCompositeFilters() const { return m_canCompositeFilters; }
236#endif
237
238    // Return an estimate of the backing store area (in pixels) allocated by this object's GraphicsLayers.
239    double backingStoreMemoryEstimate() const;
240
241    LayoutSize devicePixelFractionFromRenderer() const { return m_devicePixelFractionFromRenderer; }
242
243private:
244    FloatRect backgroundBoxForPainting() const;
245
246    void createPrimaryGraphicsLayer();
247    void destroyGraphicsLayers();
248
249    void willDestroyLayer(const GraphicsLayer*);
250
251    LayoutRect compositedBoundsIncludingMargin() const;
252
253    std::unique_ptr<GraphicsLayer> createGraphicsLayer(const String&);
254
255    RenderLayerModelObject& renderer() const { return m_owningLayer.renderer(); }
256    RenderLayerCompositor& compositor() const { return m_owningLayer.compositor(); }
257
258    void updateInternalHierarchy();
259    bool updateAncestorClippingLayer(bool needsAncestorClip);
260    bool updateDescendantClippingLayer(bool needsDescendantClip);
261    bool updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer);
262    bool updateForegroundLayer(bool needsForegroundLayer);
263    bool updateBackgroundLayer(bool needsBackgroundLayer);
264    void updateMaskLayer(bool needsMaskLayer);
265    bool requiresHorizontalScrollbarLayer() const;
266    bool requiresVerticalScrollbarLayer() const;
267    bool requiresScrollCornerLayer() const;
268    bool updateScrollingLayers(bool scrollingLayers);
269    void updateDrawsContent(bool isSimpleContainer);
270
271    void updateRootLayerConfiguration();
272
273    void setBackgroundLayerPaintsFixedRootBackground(bool);
274
275    GraphicsLayerPaintingPhase paintingPhaseForPrimaryLayer() const;
276
277    LayoutSize contentOffsetInCompostingLayer() const;
278    // Result is transform origin in device pixels.
279    FloatPoint3D computeTransformOriginForPainting(const LayoutRect& borderBox) const;
280
281    void updateOpacity(const RenderStyle&);
282    void updateTransform(const RenderStyle&);
283#if ENABLE(CSS_FILTERS)
284    void updateFilters(const RenderStyle&);
285#endif
286#if ENABLE(CSS_COMPOSITING)
287    void updateBlendMode(const RenderStyle&);
288#endif
289    // Return the opacity value that this layer should use for compositing.
290    float compositingOpacity(float rendererOpacity) const;
291
292    bool isMainFrameRenderViewLayer() const;
293
294    bool paintsBoxDecorations() const;
295    bool paintsChildren() const;
296
297    // Returns true if this compositing layer has no visible content.
298    bool isSimpleContainerCompositingLayer() const;
299    // Returns true if this layer has content that needs to be rendered by painting into the backing store.
300    bool containsPaintedContent(bool isSimpleContainer) const;
301    // Returns true if the RenderLayer just contains an image that we can composite directly.
302    bool isDirectlyCompositedImage() const;
303    void updateImageContents();
304
305    Color rendererBackgroundColor() const;
306    void updateDirectlyCompositedBackgroundColor(bool isSimpleContainer, bool& didUpdateContentsRect);
307    void updateDirectlyCompositedBackgroundImage(bool isSimpleContainer, bool& didUpdateContentsRect);
308    void updateDirectlyCompositedContents(bool isSimpleContainer, bool& didUpdateContentsRect);
309
310    void resetContentsRect();
311
312    bool isPaintDestinationForDescendentLayers() const;
313
314    bool shouldClipCompositedBounds() const;
315
316    bool hasTiledBackingFlatteningLayer() const { return (m_childContainmentLayer && m_usingTiledCacheLayer); }
317    GraphicsLayer* tileCacheFlatteningLayer() const { return m_usingTiledCacheLayer ? m_childContainmentLayer.get() : 0; }
318
319    void paintIntoLayer(const GraphicsLayer*, GraphicsContext*, const IntRect& paintDirtyRect, PaintBehavior, GraphicsLayerPaintingPhase);
320
321    // Helper function for updateGeometry.
322    void adjustAncestorCompositingBoundsForFlowThread(LayoutRect& ancestorCompositingBounds, const RenderLayer* compositingAncestor) const;
323
324    static CSSPropertyID graphicsLayerToCSSProperty(AnimatedPropertyID);
325    static AnimatedPropertyID cssToGraphicsLayerProperty(CSSPropertyID);
326
327    RenderLayer& m_owningLayer;
328
329    std::unique_ptr<GraphicsLayer> m_ancestorClippingLayer; // Only used if we are clipped by an ancestor which is not a stacking context.
330    std::unique_ptr<GraphicsLayer> m_contentsContainmentLayer; // Only used if we have a background layer; takes the transform.
331    std::unique_ptr<GraphicsLayer> m_graphicsLayer;
332    std::unique_ptr<GraphicsLayer> m_foregroundLayer; // Only used in cases where we need to draw the foreground separately.
333    std::unique_ptr<GraphicsLayer> m_backgroundLayer; // Only used in cases where we need to draw the background separately.
334    std::unique_ptr<GraphicsLayer> m_childContainmentLayer; // Only used if we have clipping on a stacking context with compositing children, or if the layer has a tile cache.
335    std::unique_ptr<GraphicsLayer> m_maskLayer; // Only used if we have a mask.
336
337    std::unique_ptr<GraphicsLayer> m_layerForHorizontalScrollbar;
338    std::unique_ptr<GraphicsLayer> m_layerForVerticalScrollbar;
339    std::unique_ptr<GraphicsLayer> m_layerForScrollCorner;
340
341    std::unique_ptr<GraphicsLayer> m_scrollingLayer; // Only used if the layer is using composited scrolling.
342    std::unique_ptr<GraphicsLayer> m_scrollingContentsLayer; // Only used if the layer is using composited scrolling.
343
344    ScrollingNodeID m_viewportConstrainedNodeID;
345    ScrollingNodeID m_scrollingNodeID;
346
347    LayoutRect m_compositedBounds;
348    LayoutSize m_devicePixelFractionFromRenderer;
349
350    bool m_artificiallyInflatedBounds; // bounds had to be made non-zero to make transform-origin work
351    bool m_isMainFrameRenderViewLayer;
352    bool m_usingTiledCacheLayer;
353    bool m_requiresOwnBackingStore;
354#if ENABLE(CSS_FILTERS)
355    bool m_canCompositeFilters;
356#endif
357    bool m_backgroundLayerPaintsFixedRootBackground;
358
359    static bool m_creatingPrimaryGraphicsLayer;
360};
361
362enum CanvasCompositingStrategy {
363    UnacceleratedCanvas,
364    CanvasPaintedToLayer,
365    CanvasAsLayerContents
366};
367CanvasCompositingStrategy canvasCompositingStrategy(const RenderObject&);
368
369} // namespace WebCore
370
371#endif // RenderLayerBacking_h
372