Home | History | Annotate | Download | only in compositing
      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 "core/rendering/compositing/CompositingReasonFinder.h"
     32 #include "platform/graphics/GraphicsLayerClient.h"
     33 #include "wtf/HashMap.h"
     34 
     35 namespace WebCore {
     36 
     37 class GraphicsLayer;
     38 class RenderPart;
     39 class ScrollingCoordinator;
     40 
     41 enum CompositingUpdateType {
     42     CompositingUpdateNone,
     43     CompositingUpdateAfterGeometryChange,
     44     CompositingUpdateAfterCompositingInputChange,
     45     CompositingUpdateRebuildTree,
     46 };
     47 
     48 enum CompositingStateTransitionType {
     49     NoCompositingStateChange,
     50     AllocateOwnCompositedLayerMapping,
     51     RemoveOwnCompositedLayerMapping,
     52     PutInSquashingLayer,
     53     RemoveFromSquashingLayer
     54 };
     55 
     56 // RenderLayerCompositor manages the hierarchy of
     57 // composited RenderLayers. It determines which RenderLayers
     58 // become compositing, and creates and maintains a hierarchy of
     59 // GraphicsLayers based on the RenderLayer painting order.
     60 //
     61 // There is one RenderLayerCompositor per RenderView.
     62 
     63 class RenderLayerCompositor FINAL : public GraphicsLayerClient {
     64     WTF_MAKE_FAST_ALLOCATED;
     65 public:
     66     explicit RenderLayerCompositor(RenderView&);
     67     virtual ~RenderLayerCompositor();
     68 
     69     void updateIfNeededRecursive();
     70 
     71     // Return true if this RenderView is in "compositing mode" (i.e. has one or more
     72     // composited RenderLayers)
     73     bool inCompositingMode() const;
     74     // FIXME: Replace all callers with inCompositingMdoe and remove this function.
     75     bool staleInCompositingMode() const;
     76     // This will make a compositing layer at the root automatically, and hook up to
     77     // the native view/window system.
     78     void setCompositingModeEnabled(bool);
     79 
     80     // Returns true if the accelerated compositing is enabled
     81     bool hasAcceleratedCompositing() const { return m_hasAcceleratedCompositing; }
     82     bool layerSquashingEnabled() const;
     83 
     84     bool acceleratedCompositingForOverflowScrollEnabled() const;
     85 
     86     bool rootShouldAlwaysComposite() const;
     87 
     88     // Copy the accelerated compositing related flags from Settings
     89     void updateAcceleratedCompositingSettings();
     90 
     91     // Used to indicate that a compositing update will be needed for the next frame that gets drawn.
     92     void setNeedsCompositingUpdate(CompositingUpdateType);
     93 
     94     void didLayout();
     95 
     96     enum UpdateLayerCompositingStateOptions {
     97         Normal,
     98         UseChickenEggHacks, // Use this to trigger temporary chicken-egg hacks. See crbug.com/339892.
     99     };
    100 
    101     // Update the compositing dirty bits, based on the compositing-impacting properties of the layer.
    102     void updateLayerCompositingState(RenderLayer*, UpdateLayerCompositingStateOptions = Normal);
    103 
    104     // Returns whether this layer is clipped by another layer that is not an ancestor of the given layer in the stacking context hierarchy.
    105     bool clippedByNonAncestorInStackingTree(const RenderLayer*) const;
    106     // Whether layer's compositedLayerMapping needs a GraphicsLayer to clip z-order children of the given RenderLayer.
    107     bool clipsCompositingDescendants(const RenderLayer*) const;
    108 
    109     // Whether the given layer needs an extra 'contents' layer.
    110     bool needsContentsCompositingLayer(const RenderLayer*) const;
    111 
    112     bool supportsFixedRootBackgroundCompositing() const;
    113     bool needsFixedRootBackgroundLayer(const RenderLayer*) const;
    114     GraphicsLayer* fixedRootBackgroundLayer() const;
    115     void setNeedsUpdateFixedBackground() { m_needsUpdateFixedBackground = true; }
    116 
    117     // Repaint the appropriate layers when the given RenderLayer starts or stops being composited.
    118     void repaintOnCompositingChange(RenderLayer*);
    119 
    120     void repaintInCompositedAncestor(RenderLayer*, const LayoutRect&);
    121     void repaintCompositedLayers();
    122 
    123     RenderLayer* rootRenderLayer() const;
    124     GraphicsLayer* rootGraphicsLayer() const;
    125     GraphicsLayer* scrollLayer() const;
    126     GraphicsLayer* containerLayer() const;
    127 
    128     // We don't always have a root transform layer. This function lazily allocates one
    129     // and returns it as required.
    130     GraphicsLayer* ensureRootTransformLayer();
    131 
    132     enum RootLayerAttachment {
    133         RootLayerUnattached,
    134         RootLayerAttachedViaChromeClient,
    135         RootLayerAttachedViaEnclosingFrame
    136     };
    137 
    138     RootLayerAttachment rootLayerAttachment() const { return m_rootLayerAttachment; }
    139     void updateRootLayerAttachment();
    140     void updateRootLayerPosition();
    141 
    142     void setIsInWindow(bool);
    143 
    144     static RenderLayerCompositor* frameContentsCompositor(RenderPart*);
    145     // Return true if the layers changed.
    146     static bool parentFrameContentLayers(RenderPart*);
    147 
    148     // Update the geometry of the layers used for clipping and scrolling in frames.
    149     void frameViewDidChangeLocation(const IntPoint& contentsOffset);
    150     void frameViewDidChangeSize();
    151     void frameViewDidScroll();
    152     void frameViewScrollbarsExistenceDidChange();
    153     void rootFixedBackgroundsChanged();
    154 
    155     bool scrollingLayerDidChange(RenderLayer*);
    156 
    157     String layerTreeAsText(LayerTreeFlags);
    158 
    159     GraphicsLayer* layerForHorizontalScrollbar() const { return m_layerForHorizontalScrollbar.get(); }
    160     GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); }
    161     GraphicsLayer* layerForScrollCorner() const { return m_layerForScrollCorner.get(); }
    162 
    163     void resetTrackedRepaintRects();
    164     void setTracksRepaints(bool);
    165 
    166     virtual String debugName(const GraphicsLayer*) OVERRIDE;
    167 
    168     void updateStyleDeterminedCompositingReasons(RenderLayer*);
    169 
    170     // Whether the layer could ever be composited.
    171     bool canBeComposited(const RenderLayer*) const;
    172 
    173     // FIXME: Move allocateOrClearCompositedLayerMapping to CompositingLayerAssigner once we've fixed
    174     // the compositing chicken/egg issues.
    175     bool allocateOrClearCompositedLayerMapping(RenderLayer*, CompositingStateTransitionType compositedLayerUpdate);
    176 
    177     void updateDirectCompositingReasons(RenderLayer*);
    178 
    179     void setOverlayLayer(GraphicsLayer*);
    180 
    181     bool inOverlayFullscreenVideo() const { return m_inOverlayFullscreenVideo; }
    182 
    183 private:
    184     class OverlapMap;
    185 
    186 #if ASSERT_ENABLED
    187     void assertNoUnresolvedDirtyBits();
    188 #endif
    189 
    190     // Make updates to the layer based on viewport-constrained properties such as position:fixed. This can in turn affect
    191     // compositing.
    192     bool updateLayerIfViewportConstrained(RenderLayer*);
    193 
    194     // GraphicsLayerClient implementation
    195     virtual void notifyAnimationStarted(const GraphicsLayer*, double) OVERRIDE { }
    196     virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&) OVERRIDE;
    197 
    198     virtual bool isTrackingRepaints() const OVERRIDE;
    199 
    200     // Whether the given RL needs to paint into its own separate backing (and hence would need its own CompositedLayerMapping).
    201     bool needsOwnBacking(const RenderLayer*) const;
    202 
    203     void updateIfNeeded();
    204 
    205     void recursiveRepaintLayer(RenderLayer*);
    206 
    207     void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer*, OverlapMap&, struct CompositingRecursionData&, bool& descendantHas3DTransform, Vector<RenderLayer*>& unclippedDescendants, IntRect& absoluteDecendantBoundingBox);
    208 
    209     bool hasAnyAdditionalCompositedLayers(const RenderLayer* rootLayer) const;
    210 
    211     void ensureRootLayer();
    212     void destroyRootLayer();
    213 
    214     void attachRootLayer(RootLayerAttachment);
    215     void detachRootLayer();
    216 
    217     void updateOverflowControlsLayers();
    218 
    219     Page* page() const;
    220 
    221     GraphicsLayerFactory* graphicsLayerFactory() const;
    222     ScrollingCoordinator* scrollingCoordinator() const;
    223 
    224     void enableCompositingModeIfNeeded();
    225 
    226     bool requiresHorizontalScrollbarLayer() const;
    227     bool requiresVerticalScrollbarLayer() const;
    228     bool requiresScrollCornerLayer() const;
    229 
    230     void applyUpdateLayerCompositingStateChickenEggHacks(RenderLayer*, CompositingStateTransitionType compositedLayerUpdate);
    231 
    232     DocumentLifecycle& lifecycle() const;
    233 
    234     void applyOverlayFullscreenVideoAdjustment();
    235 
    236     RenderView& m_renderView;
    237     OwnPtr<GraphicsLayer> m_rootContentLayer;
    238     OwnPtr<GraphicsLayer> m_rootTransformLayer;
    239 
    240     CompositingReasonFinder m_compositingReasonFinder;
    241 
    242     CompositingUpdateType m_pendingUpdateType;
    243 
    244     bool m_hasAcceleratedCompositing;
    245     bool m_compositing;
    246 
    247     // The root layer doesn't composite if it's a non-scrollable frame.
    248     // So, after a layout we set this dirty bit to know that we need
    249     // to recompute whether the root layer should composite even if
    250     // none of its descendants composite.
    251     // FIXME: Get rid of all the callers of setCompositingModeEnabled
    252     // except the one in updateIfNeeded, then rename this to
    253     // m_compositingDirty.
    254     bool m_rootShouldAlwaysCompositeDirty;
    255     bool m_needsUpdateFixedBackground;
    256     bool m_isTrackingRepaints; // Used for testing.
    257 
    258     RootLayerAttachment m_rootLayerAttachment;
    259 
    260     // Enclosing container layer, which clips for iframe content
    261     OwnPtr<GraphicsLayer> m_containerLayer;
    262     OwnPtr<GraphicsLayer> m_scrollLayer;
    263 
    264     // Enclosing layer for overflow controls and the clipping layer
    265     OwnPtr<GraphicsLayer> m_overflowControlsHostLayer;
    266 
    267     // Layers for overflow controls
    268     OwnPtr<GraphicsLayer> m_layerForHorizontalScrollbar;
    269     OwnPtr<GraphicsLayer> m_layerForVerticalScrollbar;
    270     OwnPtr<GraphicsLayer> m_layerForScrollCorner;
    271 #if USE(RUBBER_BANDING)
    272     OwnPtr<GraphicsLayer> m_layerForOverhangShadow;
    273 #endif
    274 
    275     bool m_inOverlayFullscreenVideo;
    276 };
    277 
    278 } // namespace WebCore
    279 
    280 #endif // RenderLayerCompositor_h
    281