Home | History | Annotate | Download | only in rendering
      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)
     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 
     74     bool inForcedCompositingMode() const { return m_forceCompositingMode; }
     75 
     76     // Returns true if the accelerated compositing is enabled
     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);
     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();
     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 
    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 
    182     GraphicsLayer* layerForHorizontalScrollbar() const { return m_layerForHorizontalScrollbar.get(); }
    183     GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); }
    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 
    195     void setNeedsToRecomputeCompositingRequirements() { m_needsToRecomputeCompositingRequirements = true; }
    196 
    197     virtual String debugName(const GraphicsLayer*) OVERRIDE;
    198 
    199 private:
    200     class OverlapMap;
    201 
    202     // GraphicsLayerClient implementation
    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 {
    233         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