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