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 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 CompositedLayerMapping_h 27 #define CompositedLayerMapping_h 28 29 #include "core/rendering/RenderLayer.h" 30 #include "core/rendering/compositing/GraphicsLayerUpdater.h" 31 #include "platform/geometry/FloatPoint.h" 32 #include "platform/geometry/FloatPoint3D.h" 33 #include "platform/graphics/GraphicsLayer.h" 34 #include "platform/graphics/GraphicsLayerClient.h" 35 36 namespace WebCore { 37 38 class RenderLayerCompositor; 39 40 // A GraphicsLayerPaintInfo contains all the info needed to paint a partial subtree of RenderLayers into a GraphicsLayer. 41 struct GraphicsLayerPaintInfo { 42 RenderLayer* renderLayer; 43 44 LayoutRect compositedBounds; 45 46 // The clip rect to apply, in the local coordinate space of the squashed layer, when painting it. 47 IntRect localClipRectForSquashedLayer; 48 49 // Offset describing where this squashed RenderLayer paints into the shared GraphicsLayer backing. 50 IntSize offsetFromRenderer; 51 bool offsetFromRendererSet; 52 53 LayoutSize subpixelAccumulation; 54 55 GraphicsLayerPaintingPhase paintingPhase; 56 57 bool isBackgroundLayer; 58 59 GraphicsLayerPaintInfo() : renderLayer(0), offsetFromRendererSet(false), isBackgroundLayer(false) { } 60 61 bool isEquivalentForSquashing(const GraphicsLayerPaintInfo& other) 62 { 63 // FIXME: offsetFromRenderer and compositedBounds should not be checked here, because 64 // they are not yet fixed at the time this function is used. 65 return renderLayer == other.renderLayer 66 && paintingPhase == other.paintingPhase 67 && isBackgroundLayer == other.isBackgroundLayer; 68 } 69 }; 70 71 enum GraphicsLayerUpdateScope { 72 GraphicsLayerUpdateNone, 73 GraphicsLayerUpdateLocal, 74 GraphicsLayerUpdateSubtree, 75 }; 76 77 // CompositedLayerMapping keeps track of how RenderLayers of the render tree correspond to 78 // GraphicsLayers of the composited layer tree. Each instance of CompositedLayerMapping 79 // manages a small cluster of GraphicsLayers and the references to which RenderLayers 80 // and paint phases contribute to each GraphicsLayer. 81 // 82 // Currently (Oct. 2013) there is one CompositedLayerMapping for each RenderLayer, 83 // but this is likely to evolve soon. 84 class CompositedLayerMapping FINAL : public GraphicsLayerClient { 85 WTF_MAKE_NONCOPYABLE(CompositedLayerMapping); WTF_MAKE_FAST_ALLOCATED; 86 public: 87 explicit CompositedLayerMapping(RenderLayer&); 88 virtual ~CompositedLayerMapping(); 89 90 RenderLayer& owningLayer() const { return m_owningLayer; } 91 92 // Returns true if layer configuration changed. 93 bool updateGraphicsLayerConfiguration(GraphicsLayerUpdater::UpdateType); 94 // Update graphics layer position and bounds. 95 96 void updateGraphicsLayerGeometry(GraphicsLayerUpdater::UpdateType, const RenderLayer* compositingContainer, Vector<RenderLayer*>& layersNeedingPaintInvalidation); 97 98 // Update whether layer needs blending. 99 void updateContentsOpaque(); 100 101 GraphicsLayer* mainGraphicsLayer() const { return m_graphicsLayer.get(); } 102 103 // Layer to clip children 104 bool hasClippingLayer() const { return m_childContainmentLayer; } 105 GraphicsLayer* clippingLayer() const { return m_childContainmentLayer.get(); } 106 107 // Layer to get clipped by ancestor 108 bool hasAncestorClippingLayer() const { return m_ancestorClippingLayer; } 109 GraphicsLayer* ancestorClippingLayer() const { return m_ancestorClippingLayer.get(); } 110 111 bool hasContentsLayer() const { return m_foregroundLayer; } 112 GraphicsLayer* foregroundLayer() const { return m_foregroundLayer.get(); } 113 114 GraphicsLayer* backgroundLayer() const { return m_backgroundLayer.get(); } 115 bool backgroundLayerPaintsFixedRootBackground() const { return m_backgroundLayerPaintsFixedRootBackground; } 116 117 bool hasScrollingLayer() const { return m_scrollingLayer; } 118 GraphicsLayer* scrollingLayer() const { return m_scrollingLayer.get(); } 119 GraphicsLayer* scrollingContentsLayer() const { return m_scrollingContentsLayer.get(); } 120 GraphicsLayer* scrollingBlockSelectionLayer() const { return m_scrollingBlockSelectionLayer.get(); } 121 122 bool hasMaskLayer() const { return m_maskLayer; } 123 GraphicsLayer* maskLayer() const { return m_maskLayer.get(); } 124 125 bool hasChildClippingMaskLayer() const { return m_childClippingMaskLayer; } 126 GraphicsLayer* childClippingMaskLayer() const { return m_childClippingMaskLayer.get(); } 127 128 GraphicsLayer* parentForSublayers() const; 129 GraphicsLayer* childForSuperlayers() const; 130 // localRootForOwningLayer does not include the m_squashingContainmentLayer, which is technically not associated with this CLM's owning layer. 131 GraphicsLayer* localRootForOwningLayer() const; 132 133 GraphicsLayer* childTransformLayer() const { return m_childTransformLayer.get(); } 134 135 GraphicsLayer* squashingContainmentLayer() const { return m_squashingContainmentLayer.get(); } 136 GraphicsLayer* squashingLayer() const { return m_squashingLayer.get(); } 137 // Contains the bottommost layer in the hierarchy that can contain the children transform. 138 GraphicsLayer* layerForChildrenTransform() const; 139 140 // Returns true for a composited layer that has no backing store of its own, so 141 // paints into some ancestor layer. 142 bool paintsIntoCompositedAncestor() const { return !(m_requiresOwnBackingStoreForAncestorReasons || m_requiresOwnBackingStoreForIntrinsicReasons); } 143 144 // Updates whether a backing store is needed based on the layer's compositing ancestor's 145 // properties; returns true if the need for a backing store for ancestor reasons changed. 146 bool updateRequiresOwnBackingStoreForAncestorReasons(const RenderLayer* compositingAncestor); 147 148 // Updates whether a backing store is needed for intrinsic reasons (that is, based on the 149 // layer's own properties or compositing reasons); returns true if the intrinsic need for 150 // a backing store changed. 151 bool updateRequiresOwnBackingStoreForIntrinsicReasons(); 152 153 void setSquashingContentsNeedDisplay(); 154 void setContentsNeedDisplay(); 155 // r is in the coordinate space of the layer's render object 156 void setContentsNeedDisplayInRect(const IntRect&); 157 158 // Notification from the renderer that its content changed. 159 void contentChanged(ContentChangeType); 160 161 LayoutRect compositedBounds() const { return m_compositedBounds; } 162 IntRect pixelSnappedCompositedBounds() const; 163 void updateCompositedBounds(GraphicsLayerUpdater::UpdateType); 164 165 void positionOverflowControlsLayers(const IntSize& offsetFromRoot); 166 bool hasUnpositionedOverflowControlsLayers() const; 167 168 // Returns true if the assignment actually changed the assigned squashing layer. 169 bool updateSquashingLayerAssignment(RenderLayer* squashedLayer, const RenderLayer& owningLayer, size_t nextSquashedLayerIndex); 170 void removeRenderLayerFromSquashingGraphicsLayer(const RenderLayer*); 171 172 void finishAccumulatingSquashingLayers(size_t nextSquashedLayerIndex); 173 void updateRenderingContext(); 174 void updateShouldFlattenTransform(); 175 176 // GraphicsLayerClient interface 177 virtual void notifyAnimationStarted(const GraphicsLayer*, double monotonicTime) OVERRIDE; 178 virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& clip) OVERRIDE; 179 virtual bool isTrackingRepaints() const OVERRIDE; 180 181 PassOwnPtr<Vector<FloatRect> > collectTrackedRepaintRects() const; 182 183 #ifndef NDEBUG 184 virtual void verifyNotPainting() OVERRIDE; 185 #endif 186 187 LayoutRect contentsBox() const; 188 189 GraphicsLayer* layerForHorizontalScrollbar() const { return m_layerForHorizontalScrollbar.get(); } 190 GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); } 191 GraphicsLayer* layerForScrollCorner() const { return m_layerForScrollCorner.get(); } 192 193 void updateFilters(const RenderStyle*); 194 bool canCompositeFilters() const { return m_canCompositeFilters; } 195 196 void setBlendMode(blink::WebBlendMode); 197 198 void setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateScope scope) { m_pendingUpdateScope = std::max(static_cast<GraphicsLayerUpdateScope>(m_pendingUpdateScope), scope); } 199 void clearNeedsGraphicsLayerUpdate() { m_pendingUpdateScope = GraphicsLayerUpdateNone; } 200 201 bool shouldUpdateGraphicsLayer(GraphicsLayerUpdater::UpdateType updateType) const { return m_pendingUpdateScope > GraphicsLayerUpdateNone || updateType == GraphicsLayerUpdater::ForceUpdate; } 202 GraphicsLayerUpdater::UpdateType updateTypeForChildren(GraphicsLayerUpdater::UpdateType) const; 203 204 #if ASSERT_ENABLED 205 void assertNeedsToUpdateGraphicsLayerBitsCleared() { ASSERT(m_pendingUpdateScope == GraphicsLayerUpdateNone); } 206 #endif 207 208 virtual String debugName(const GraphicsLayer*) OVERRIDE; 209 210 LayoutSize contentOffsetInCompositingLayer() const; 211 212 LayoutPoint squashingOffsetFromTransformedAncestor() 213 { 214 return m_squashingLayerOffsetFromTransformedAncestor; 215 } 216 217 // If there is a squashed layer painting into this CLM that is an ancestor of the given RenderObject, return it. Otherwise return 0. 218 const GraphicsLayerPaintInfo* containingSquashedLayer(const RenderObject*); 219 220 void updateScrollingBlockSelection(); 221 222 private: 223 static const GraphicsLayerPaintInfo* containingSquashedLayer(const RenderObject*, const Vector<GraphicsLayerPaintInfo>& layers); 224 225 // Helper methods to updateGraphicsLayerGeometry: 226 void computeGraphicsLayerParentLocation(const RenderLayer* compositingContainer, const IntRect& ancestorCompositingBounds, IntPoint& graphicsLayerParentLocation); 227 void updateSquashingLayerGeometry(const LayoutPoint& offsetFromCompositedAncestor, const IntPoint& graphicsLayerParentLocation, const RenderLayer& referenceLayer, Vector<GraphicsLayerPaintInfo>& layers, GraphicsLayer*, LayoutPoint* offsetFromTransformedAncestor, Vector<RenderLayer*>& layersNeedingPaintInvalidation); 228 void updateMainGraphicsLayerGeometry(const IntRect& relativeCompositingBounds, const IntRect& localCompositingBounds, IntPoint& graphicsLayerParentLocation); 229 void updateAncestorClippingLayerGeometry(const RenderLayer* compositingContainer, const IntPoint& snappedOffsetFromCompositedAncestor, IntPoint& graphicsLayerParentLocation); 230 void updateChildContainmentLayerGeometry(const IntRect& clippingBox, const IntRect& localCompositingBounds); 231 void updateChildTransformLayerGeometry(); 232 void updateMaskLayerGeometry(); 233 void updateTransformGeometry(const IntPoint& snappedOffsetFromCompositedAncestor, const IntRect& relativeCompositingBounds); 234 void updateForegroundLayerGeometry(const FloatSize& relativeCompositingBoundsSize, const IntRect& clippingBox); 235 void updateBackgroundLayerGeometry(const FloatSize& relativeCompositingBoundsSize); 236 void updateReflectionLayerGeometry(Vector<RenderLayer*>& layersNeedingPaintInvalidation); 237 void updateScrollingLayerGeometry(const IntRect& localCompositingBounds); 238 void updateChildClippingMaskLayerGeometry(); 239 240 void createPrimaryGraphicsLayer(); 241 void destroyGraphicsLayers(); 242 243 PassOwnPtr<GraphicsLayer> createGraphicsLayer(CompositingReasons); 244 bool toggleScrollbarLayerIfNeeded(OwnPtr<GraphicsLayer>&, bool needsLayer, CompositingReasons); 245 246 RenderLayerModelObject* renderer() const { return m_owningLayer.renderer(); } 247 RenderLayerCompositor* compositor() const { return m_owningLayer.compositor(); } 248 249 void updateInternalHierarchy(); 250 void updatePaintingPhases(); 251 bool updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip); 252 bool updateChildTransformLayer(bool needsChildTransformLayer); 253 bool updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer); 254 bool updateForegroundLayer(bool needsForegroundLayer); 255 bool updateBackgroundLayer(bool needsBackgroundLayer); 256 bool updateMaskLayer(bool needsMaskLayer); 257 bool updateClippingMaskLayers(bool needsChildClippingMaskLayer); 258 bool requiresHorizontalScrollbarLayer() const { return m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->horizontalScrollbar(); } 259 bool requiresVerticalScrollbarLayer() const { return m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->verticalScrollbar(); } 260 bool requiresScrollCornerLayer() const { return m_owningLayer.scrollableArea() && !m_owningLayer.scrollableArea()->scrollCornerAndResizerRect().isEmpty(); } 261 bool updateScrollingLayers(bool scrollingLayers); 262 void updateScrollParent(RenderLayer*); 263 void updateClipParent(RenderLayer*); 264 bool updateSquashingLayers(bool needsSquashingLayers); 265 void updateDrawsContent(); 266 void updateChildrenTransform(); 267 void registerScrollingLayers(); 268 269 // Also sets subpixelAccumulation on the layer. 270 void computeBoundsOfOwningLayer(const RenderLayer* compositedAncestor, IntRect& localCompositingBounds, IntRect& compositingBoundsRelativeToCompositedAncestor, LayoutPoint& offsetFromCompositedAncestor, IntPoint& snappedOffsetFromCompositedAncestor); 271 272 void setBackgroundLayerPaintsFixedRootBackground(bool); 273 274 GraphicsLayerPaintingPhase paintingPhaseForPrimaryLayer() const; 275 276 // Result is transform origin in pixels. 277 FloatPoint3D computeTransformOrigin(const IntRect& borderBox) const; 278 279 void updateOpacity(const RenderStyle*); 280 void updateTransform(const RenderStyle*); 281 void updateLayerBlendMode(const RenderStyle*); 282 void updateIsRootForIsolatedGroup(); 283 // Return the opacity value that this layer should use for compositing. 284 float compositingOpacity(float rendererOpacity) const; 285 286 bool isMainFrameRenderViewLayer() const; 287 288 bool paintsChildren() const; 289 290 // Returns true if this layer has content that needs to be rendered by painting into the backing store. 291 bool containsPaintedContent() const; 292 // Returns true if the RenderLayer just contains an image that we can composite directly. 293 bool isDirectlyCompositedImage() const; 294 void updateImageContents(); 295 296 Color rendererBackgroundColor() const; 297 void updateBackgroundColor(); 298 void updateContentsRect(); 299 void updateAfterWidgetResize(); 300 void updateCompositingReasons(); 301 302 static bool hasVisibleNonCompositingDescendant(RenderLayer* parent); 303 304 void paintsIntoCompositedAncestorChanged(); 305 306 void doPaintTask(GraphicsLayerPaintInfo&, GraphicsContext*, const IntRect& clip); 307 308 // Computes the background clip rect for the given squashed layer, up to any containing layer that is squashed into the 309 // same squashing layer and contains this squashed layer's clipping ancestor. 310 // The clip rect is returned in the coordinate space of the given squashed layer. 311 // If there is no such containing layer, returns the infinite rect. 312 // FIXME: unify this code with the code that sets up m_ancestorClippingLayer. They are doing very similar things. 313 static IntRect localClipRectForSquashedLayer(const RenderLayer& referenceLayer, const GraphicsLayerPaintInfo&, const Vector<GraphicsLayerPaintInfo>& layers); 314 315 RenderLayer& m_owningLayer; 316 317 // The hierarchy of layers that is maintained by the CompositedLayerMapping looks like this: 318 // 319 // + m_ancestorClippingLayer [OPTIONAL] 320 // + m_graphicsLayer 321 // + m_childContainmentLayer [OPTIONAL] <-OR-> m_scrollingLayer [OPTIONAL] <-OR-> m_childTransformLayer 322 // + m_scrollingContentsLayer [Present iff m_scrollingLayer is present] 323 // + m_scrollingBlockSelectionLayer [Present iff m_scrollingLayer is present] 324 // 325 // We need an ancestor clipping layer if our clipping ancestor is not our ancestor in the 326 // clipping tree. Here's what that might look like. 327 // 328 // Let A = the clipping ancestor, 329 // B = the clip descendant, and 330 // SC = the stacking context that is the ancestor of A and B in the stacking tree. 331 // 332 // SC 333 // + A = m_graphicsLayer 334 // | + m_childContainmentLayer 335 // | + ... 336 // ... 337 // | 338 // + B = m_ancestorClippingLayer [+] 339 // + m_graphicsLayer 340 // + ... 341 // 342 // In this case B is clipped by another layer that doesn't happen to be its ancestor: A. 343 // So we create an ancestor clipping layer for B, [+], which ensures that B is clipped 344 // as if it had been A's descendant. 345 OwnPtr<GraphicsLayer> m_ancestorClippingLayer; // Only used if we are clipped by an ancestor which is not a stacking context. 346 OwnPtr<GraphicsLayer> m_graphicsLayer; 347 OwnPtr<GraphicsLayer> m_childContainmentLayer; // Only used if we have clipping on a stacking context with compositing children. 348 OwnPtr<GraphicsLayer> m_childTransformLayer; // Only used if we have perspective and no m_childContainmentLayer. 349 OwnPtr<GraphicsLayer> m_scrollingLayer; // Only used if the layer is using composited scrolling. 350 OwnPtr<GraphicsLayer> m_scrollingContentsLayer; // Only used if the layer is using composited scrolling. 351 OwnPtr<GraphicsLayer> m_scrollingBlockSelectionLayer; // Only used if the layer is using composited scrolling, but has no scrolling contents apart from block selection gaps. 352 353 // This layer is also added to the hierarchy by the RLB, but in a different way than 354 // the layers above. It's added to m_graphicsLayer as its mask layer (naturally) if 355 // we have a mask, and isn't part of the typical hierarchy (it has no children). 356 OwnPtr<GraphicsLayer> m_maskLayer; // Only used if we have a mask. 357 OwnPtr<GraphicsLayer> m_childClippingMaskLayer; // Only used if we have to clip child layers or accelerated contents with border radius or clip-path. 358 359 // There are two other (optional) layers whose painting is managed by the CompositedLayerMapping, 360 // but whose position in the hierarchy is maintained by the RenderLayerCompositor. These 361 // are the foreground and background layers. The foreground layer exists if we have composited 362 // descendants with negative z-order. We need the extra layer in this case because the layer 363 // needs to draw both below (for the background, say) and above (for the normal flow content, say) 364 // the negative z-order descendants and this is impossible with a single layer. The RLC handles 365 // inserting m_foregroundLayer in the correct position in our descendant list for us (right after 366 // the neg z-order dsecendants). 367 // 368 // The background layer is only created if this is the root layer and our background is entirely 369 // fixed. In this case we want to put the background in a separate composited layer so that when 370 // we scroll, we don't have to re-raster the background into position. This layer is also inserted 371 // into the tree by the RLC as it gets a special home. This layer becomes a descendant of the 372 // frame clipping layer. That is: 373 // ... 374 // + frame clipping layer 375 // + m_backgroundLayer 376 // + frame scrolling layer 377 // + root content layer 378 // 379 // With the hierarchy set up like this, the root content layer is able to scroll without affecting 380 // the background layer (or repainting). 381 OwnPtr<GraphicsLayer> m_foregroundLayer; // Only used in cases where we need to draw the foreground separately. 382 OwnPtr<GraphicsLayer> m_backgroundLayer; // Only used in cases where we need to draw the background separately. 383 384 OwnPtr<GraphicsLayer> m_layerForHorizontalScrollbar; 385 OwnPtr<GraphicsLayer> m_layerForVerticalScrollbar; 386 OwnPtr<GraphicsLayer> m_layerForScrollCorner; 387 388 // A squashing CLM has two possible squashing-related structures. 389 // 390 // If m_ancestorClippingLayer is present: 391 // 392 // m_ancestorClippingLayer 393 // + m_graphicsLayer 394 // + m_squashingLayer 395 // 396 // If not: 397 // 398 // m_squashingContainmentLayer 399 // + m_graphicsLayer 400 // + m_squashingLayer 401 OwnPtr<GraphicsLayer> m_squashingContainmentLayer; // Only used if any squashed layers exist and m_squashingContainmentLayer is not present, to contain the squashed layers as siblings to the rest of the GraphicsLayer tree chunk. 402 OwnPtr<GraphicsLayer> m_squashingLayer; // Only used if any squashed layers exist, this is the backing that squashed layers paint into. 403 Vector<GraphicsLayerPaintInfo> m_squashedLayers; 404 LayoutPoint m_squashingLayerOffsetFromTransformedAncestor; 405 406 LayoutRect m_compositedBounds; 407 408 unsigned m_pendingUpdateScope : 2; 409 unsigned m_isMainFrameRenderViewLayer : 1; 410 unsigned m_requiresOwnBackingStoreForIntrinsicReasons : 1; 411 unsigned m_requiresOwnBackingStoreForAncestorReasons : 1; 412 unsigned m_canCompositeFilters : 1; 413 unsigned m_backgroundLayerPaintsFixedRootBackground : 1; 414 unsigned m_scrollingContentsAreEmpty : 1; 415 }; 416 417 } // namespace WebCore 418 419 #endif // CompositedLayerMapping_h 420