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/page/Frame.h" 31 #include "core/platform/graphics/GraphicsLayerClient.h" 32 #include "core/rendering/RenderLayer.h" 33 #include "wtf/HashMap.h" 34 35 namespace WebCore { 36 37 class FixedPositionViewportConstraints; 38 class GraphicsLayer; 39 class RenderEmbeddedObject; 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 }; 52 53 // RenderLayerCompositor manages the hierarchy of 54 // composited RenderLayers. It determines which RenderLayers 55 // become compositing, and creates and maintains a hierarchy of 56 // GraphicsLayers based on the RenderLayer painting order. 57 // 58 // There is one RenderLayerCompositor per RenderView. 59 60 class RenderLayerCompositor : public GraphicsLayerClient { 61 WTF_MAKE_FAST_ALLOCATED; 62 public: 63 explicit RenderLayerCompositor(RenderView*); 64 ~RenderLayerCompositor(); 65 66 // Return true if this RenderView is in "compositing mode" (i.e. has one or more 67 // composited RenderLayers) 68 bool inCompositingMode() const { return m_compositing; } 69 // This will make a compositing layer at the root automatically, and hook up to 70 // the native view/window system. 71 void enableCompositingMode(bool enable = true); 72 73 bool inForcedCompositingMode() const { return m_forceCompositingMode; } 74 75 // Returns true if the accelerated compositing is enabled 76 bool hasAcceleratedCompositing() const { return m_hasAcceleratedCompositing; } 77 78 bool canRender3DTransforms() const; 79 80 // Copy the accelerated compositing related flags from Settings 81 void cacheAcceleratedCompositingFlags(); 82 83 // Called when the layer hierarchy needs to be updated (compositing layers have been 84 // created, destroyed or re-parented). 85 void setCompositingLayersNeedRebuild(bool needRebuild = true); 86 bool compositingLayersNeedRebuild() const { return m_compositingLayersNeedRebuild; } 87 88 // Called when something outside WebKit affects the visible rect (e.g. delegated scrolling). Might schedule a layer flush. 89 void didChangeVisibleRect(); 90 91 // Updating properties required for determining if compositing is necessary. 92 void updateCompositingRequirementsState(); 93 void setNeedsUpdateCompositingRequirementsState() { m_needsUpdateCompositingRequirementsState = true; } 94 95 // Rebuild the tree of compositing layers 96 void updateCompositingLayers(CompositingUpdateType, RenderLayer* updateRoot = 0); 97 98 // Update the compositing state of the given layer. Returns true if that state changed. 99 enum CompositingChangeRepaint { CompositingChangeRepaintNow, CompositingChangeWillRepaintLater }; 100 bool updateLayerCompositingState(RenderLayer*, CompositingChangeRepaint = CompositingChangeRepaintNow); 101 102 // Update the geometry for compositing children of compositingAncestor. 103 void updateCompositingDescendantGeometry(RenderLayer* compositingAncestor, RenderLayer*, bool compositedChildrenOnly); 104 105 // Whether layer's backing needs a graphics layer to do clipping by an ancestor (non-stacking-context parent with overflow). 106 bool clippedByAncestor(RenderLayer*) const; 107 // Whether layer's backing needs a graphics layer to clip z-order children of the given layer. 108 bool clipsCompositingDescendants(const RenderLayer*) const; 109 110 // Whether the given layer needs an extra 'contents' layer. 111 bool needsContentsCompositingLayer(const RenderLayer*) const; 112 113 bool supportsFixedRootBackgroundCompositing() const; 114 bool needsFixedRootBackgroundLayer(const RenderLayer*) const; 115 GraphicsLayer* fixedRootBackgroundLayer() const; 116 117 // Return the bounding box required for compositing layer and its childern, relative to ancestorLayer. 118 // If layerBoundingBox is not 0, on return it contains the bounding box of this layer only. 119 IntRect calculateCompositedBounds(const RenderLayer*, const RenderLayer* ancestorLayer) const; 120 121 // Repaint the appropriate layers when the given RenderLayer starts or stops being composited. 122 void repaintOnCompositingChange(RenderLayer*); 123 124 void repaintInCompositedAncestor(RenderLayer*, const LayoutRect&); 125 126 // Notify us that a layer has been added or removed 127 void layerWasAdded(RenderLayer* parent, RenderLayer* child); 128 void layerWillBeRemoved(RenderLayer* parent, RenderLayer* child); 129 130 // Get the nearest ancestor layer that has overflow or clip, but is not a stacking context 131 RenderLayer* enclosingNonStackingClippingLayer(const RenderLayer* layer) const; 132 133 // Repaint parts of all composited layers that intersect the given absolute rectangle (or the entire layer if the pointer is null). 134 void repaintCompositedLayers(const IntRect* = 0); 135 136 // Returns true if the given layer needs it own backing store. 137 bool requiresOwnBackingStore(const RenderLayer*, const RenderLayer* compositingAncestorLayer) const; 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 clearBackingForAllLayers(); 156 157 void layerBecameComposited(const RenderLayer*) { ++m_compositedLayerCount; } 158 void layerBecameNonComposited(const RenderLayer*); 159 160 // Use by RenderVideo to ask if it should try to use accelerated compositing. 161 bool canAccelerateVideoRendering(RenderVideo*) const; 162 163 // Walk the tree looking for layers with 3d transforms. Useful in case you need 164 // to know if there is non-affine content, e.g. for drawing into an image. 165 bool has3DContent() const; 166 167 static RenderLayerCompositor* frameContentsCompositor(RenderPart*); 168 // Return true if the layers changed. 169 static bool parentFrameContentLayers(RenderPart*); 170 171 // Update the geometry of the layers used for clipping and scrolling in frames. 172 void frameViewDidChangeLocation(const IntPoint& contentsOffset); 173 void frameViewDidChangeSize(); 174 void frameViewDidScroll(); 175 void frameViewDidLayout(); 176 void rootFixedBackgroundsChanged(); 177 178 bool scrollingLayerDidChange(RenderLayer*); 179 180 String layerTreeAsText(LayerTreeFlags); 181 182 virtual void didCommitChangesForLayer(const GraphicsLayer*) const OVERRIDE; 183 184 GraphicsLayer* layerForHorizontalScrollbar() const { return m_layerForHorizontalScrollbar.get(); } 185 GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); } 186 GraphicsLayer* layerForScrollCorner() const { return m_layerForScrollCorner.get(); } 187 #if ENABLE(RUBBER_BANDING) 188 GraphicsLayer* layerForOverhangAreas() const { return m_layerForOverhangAreas.get(); } 189 190 GraphicsLayer* updateLayerForTopOverhangArea(bool wantsLayer); 191 GraphicsLayer* updateLayerForBottomOverhangArea(bool wantsLayer); 192 #endif 193 194 void updateViewportConstraintStatus(RenderLayer*); 195 void removeViewportConstrainedLayer(RenderLayer*); 196 197 void addOutOfFlowPositionedLayer(RenderLayer*); 198 void removeOutOfFlowPositionedLayer(RenderLayer*); 199 200 void resetTrackedRepaintRects(); 201 void setTracksRepaints(bool); 202 203 void setShouldReevaluateCompositingAfterLayout() { m_reevaluateCompositingAfterLayout = true; } 204 205 // Returns all reasons (direct, indirectly due to subtree, and indirectly due to overlap) that a layer should be composited. 206 CompositingReasons reasonsForCompositing(const RenderLayer*) const; 207 208 private: 209 class OverlapMap; 210 211 // GraphicsLayerClient implementation 212 virtual void notifyAnimationStarted(const GraphicsLayer*, double) OVERRIDE { } 213 virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&) OVERRIDE; 214 215 virtual bool isTrackingRepaints() const OVERRIDE; 216 217 // Whether the given RL needs a compositing layer. 218 bool needsToBeComposited(const RenderLayer*) const; 219 // Whether the layer could ever be composited. 220 bool canBeComposited(const RenderLayer*) const; 221 222 // Returns all direct reasons that a layer should be composited. 223 CompositingReasons directReasonsForCompositing(const RenderLayer*) const; 224 225 // Returns indirect reasons that a layer should be composited because of something in its subtree. 226 CompositingReasons subtreeReasonsForCompositing(RenderObject*, bool hasCompositedDescendants, bool has3DTransformedDescendants) const; 227 228 // Make or destroy the backing for this layer; returns true if backing changed. 229 bool updateBacking(RenderLayer*, CompositingChangeRepaint shouldRepaint); 230 231 void clearBackingForLayerIncludingDescendants(RenderLayer*); 232 233 // Repaint the given rect (which is layer's coords), and regions of child layers that intersect that rect. 234 void recursiveRepaintLayer(RenderLayer*, const IntRect* = 0); 235 236 void addToOverlapMap(OverlapMap&, RenderLayer*, IntRect& layerBounds, bool& boundsComputed); 237 void addToOverlapMapRecursive(OverlapMap&, RenderLayer*, RenderLayer* ancestorLayer = 0); 238 239 // Returns true if any layer's compositing changed 240 void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer*, OverlapMap*, struct CompositingState&, bool& layersChanged, bool& descendantHas3DTransform); 241 242 // Recurses down the tree, parenting descendant compositing layers and collecting an array of child layers for the current compositing layer. 243 void rebuildCompositingLayerTree(RenderLayer*, Vector<GraphicsLayer*>& childGraphicsLayersOfEnclosingLayer, int depth); 244 245 // Recurses down the tree, updating layer geometry only. 246 void updateLayerTreeGeometry(RenderLayer*, int depth); 247 248 // Hook compositing layers together 249 void setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer); 250 void removeCompositedChildren(RenderLayer*); 251 252 bool layerHas3DContent(const RenderLayer*) const; 253 bool isRunningAcceleratedTransformAnimation(RenderObject*) const; 254 255 bool hasAnyAdditionalCompositedLayers(const RenderLayer* rootLayer) const; 256 257 void ensureRootLayer(); 258 void destroyRootLayer(); 259 260 void attachRootLayer(RootLayerAttachment); 261 void detachRootLayer(); 262 263 bool isMainFrame() const; 264 265 void updateOverflowControlsLayers(); 266 267 void notifyIFramesOfCompositingChange(); 268 269 Page* page() const; 270 271 GraphicsLayerFactory* graphicsLayerFactory() const; 272 ScrollingCoordinator* scrollingCoordinator() const; 273 274 // Whether a running transition or animation enforces the need for a compositing layer. 275 bool requiresCompositingForAnimation(RenderObject*) const; 276 // Whether a (not necessarily running) transition enforces the need for a compositing layer. 277 bool requiresCompositingForTransition(RenderObject*) const; 278 bool requiresCompositingForTransform(RenderObject*) const; 279 bool requiresCompositingForVideo(RenderObject*) const; 280 bool requiresCompositingForCanvas(RenderObject*) const; 281 bool requiresCompositingForPlugin(RenderObject*) const; 282 bool requiresCompositingForFrame(RenderObject*) const; 283 bool requiresCompositingForBackfaceVisibilityHidden(RenderObject*) const; 284 bool requiresCompositingForFilters(RenderObject*) const; 285 bool requiresCompositingForBlending(RenderObject* renderer) const; 286 bool requiresCompositingForScrollableFrame() const; 287 bool requiresCompositingForPosition(RenderObject*, const RenderLayer*, RenderLayer::ViewportConstrainedNotCompositedReason* = 0) const; 288 bool requiresCompositingForOverflowScrolling(const RenderLayer*) const; 289 290 void addViewportConstrainedLayer(RenderLayer*); 291 292 FixedPositionViewportConstraints computeFixedViewportConstraints(RenderLayer*) const; 293 StickyPositionViewportConstraints computeStickyViewportConstraints(RenderLayer*) const; 294 295 bool requiresHorizontalScrollbarLayer() const; 296 bool requiresVerticalScrollbarLayer() const; 297 bool requiresScrollCornerLayer() const; 298 #if ENABLE(RUBBER_BANDING) 299 bool requiresOverhangAreasLayer() const; 300 #endif 301 302 #if !LOG_DISABLED 303 const char* logReasonsForCompositing(const RenderLayer*); 304 void logLayerInfo(const RenderLayer*, int depth); 305 #endif 306 307 private: 308 RenderView* m_renderView; 309 OwnPtr<GraphicsLayer> m_rootContentLayer; 310 311 bool m_hasAcceleratedCompositing; 312 ChromeClient::CompositingTriggerFlags m_compositingTriggers; 313 314 int m_compositedLayerCount; 315 bool m_showRepaintCounter; 316 317 // When true, we have to wait until layout has happened before we can decide whether to enter compositing mode, 318 // because only then do we know the final size of plugins and iframes. 319 mutable bool m_reevaluateCompositingAfterLayout; 320 321 bool m_compositing; 322 bool m_compositingLayersNeedRebuild; 323 bool m_forceCompositingMode; 324 bool m_inPostLayoutUpdate; // true when it's OK to trust layout information (e.g. layer sizes and positions) 325 bool m_needsUpdateCompositingRequirementsState; 326 327 bool m_isTrackingRepaints; // Used for testing. 328 329 RootLayerAttachment m_rootLayerAttachment; 330 331 // Enclosing container layer, which clips for iframe content 332 OwnPtr<GraphicsLayer> m_containerLayer; 333 OwnPtr<GraphicsLayer> m_scrollLayer; 334 335 HashSet<RenderLayer*> m_viewportConstrainedLayers; 336 HashSet<RenderLayer*> m_viewportConstrainedLayersNeedingUpdate; 337 338 // This is used in updateCompositingRequirementsState to avoid full tree 339 // walks while determining if layers have unclipped descendants. 340 HashSet<RenderLayer*> m_outOfFlowPositionedLayers; 341 342 // Enclosing layer for overflow controls and the clipping layer 343 OwnPtr<GraphicsLayer> m_overflowControlsHostLayer; 344 345 // Layers for overflow controls 346 OwnPtr<GraphicsLayer> m_layerForHorizontalScrollbar; 347 OwnPtr<GraphicsLayer> m_layerForVerticalScrollbar; 348 OwnPtr<GraphicsLayer> m_layerForScrollCorner; 349 #if ENABLE(RUBBER_BANDING) 350 OwnPtr<GraphicsLayer> m_layerForOverhangAreas; 351 #endif 352 353 #if !LOG_DISABLED 354 int m_rootLayerUpdateCount; 355 int m_obligateCompositedLayerCount; // count of layer that have to be composited. 356 int m_secondaryCompositedLayerCount; // count of layers that have to be composited because of stacking or overlap. 357 double m_obligatoryBackingStoreBytes; 358 double m_secondaryBackingStoreBytes; 359 #endif 360 }; 361 362 363 } // namespace WebCore 364 365 #endif // RenderLayerCompositor_h 366