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 THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITED_LAYER_MAPPING_H_ 27 #define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITED_LAYER_MAPPING_H_ 28 29 #include <memory> 30 #include "base/macros.h" 31 #include "third_party/blink/renderer/core/paint/compositing/graphics_layer_updater.h" 32 #include "third_party/blink/renderer/core/paint/paint_layer.h" 33 #include "third_party/blink/renderer/core/paint/paint_layer_painting_info.h" 34 #include "third_party/blink/renderer/platform/geometry/float_point.h" 35 #include "third_party/blink/renderer/platform/geometry/float_point_3d.h" 36 #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" 37 #include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h" 38 #include "third_party/blink/renderer/platform/graphics/graphics_types.h" 39 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" 40 41 namespace blink { 42 43 class PaintLayerCompositor; 44 45 // A GraphicsLayerPaintInfo contains all the info needed to paint a partial 46 // subtree of Layers into a GraphicsLayer. 47 struct GraphicsLayerPaintInfo { 48 DISALLOW_NEW(); 49 PaintLayer* paint_layer; 50 51 PhysicalRect composited_bounds; 52 53 // The clip rect to apply, in the local coordinate space of the squashed 54 // layer, when painting it. 55 ClipRect local_clip_rect_for_squashed_layer; 56 PaintLayer* local_clip_rect_root; 57 PhysicalOffset offset_from_clip_rect_root; 58 59 // Offset describing where this squashed Layer paints into the shared 60 // GraphicsLayer backing. 61 IntSize offset_from_layout_object; 62 bool offset_from_layout_object_set; 63 GraphicsLayerPaintInfoGraphicsLayerPaintInfo64 GraphicsLayerPaintInfo() 65 : paint_layer(nullptr), offset_from_layout_object_set(false) {} 66 }; 67 68 enum GraphicsLayerUpdateScope { 69 kGraphicsLayerUpdateNone, 70 kGraphicsLayerUpdateLocal, 71 kGraphicsLayerUpdateSubtree, 72 }; 73 74 // CompositedLayerMapping keeps track of how PaintLayers correspond to 75 // GraphicsLayers of the composited layer tree. Each instance of 76 // CompositedLayerMapping manages a small cluster of GraphicsLayers and the 77 // references to which Layers and paint phases contribute to each GraphicsLayer. 78 // 79 // - If a PaintLayer is composited, 80 // - if it paints into its own backings (GraphicsLayers), it owns a 81 // CompositedLayerMapping (PaintLayer::compositedLayerMapping()) to keep 82 // track the backings; 83 // - if it paints into grouped backing (i.e. it's squashed), it has a pointer 84 // (PaintLayer::groupedMapping()) to the CompositedLayerMapping into which 85 // the PaintLayer is squashed; 86 // - Otherwise the PaintLayer doesn't own or directly reference any 87 // CompositedLayerMapping. 88 class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient { 89 USING_FAST_MALLOC(CompositedLayerMapping); 90 91 public: 92 explicit CompositedLayerMapping(PaintLayer&); 93 ~CompositedLayerMapping() override; 94 OwningLayer()95 PaintLayer& OwningLayer() const { return owning_layer_; } 96 97 bool UpdateGraphicsLayerConfiguration( 98 const PaintLayer* compositing_container); 99 void UpdateGraphicsLayerGeometry( 100 const PaintLayer* compositing_container, 101 Vector<PaintLayer*>& layers_needing_paint_invalidation); 102 103 // Update whether layer needs blending. 104 void UpdateContentsOpaque(); 105 106 void UpdateRasterizationPolicy(); 107 MainGraphicsLayer()108 GraphicsLayer* MainGraphicsLayer() const { return graphics_layer_.get(); } 109 ForegroundLayer()110 GraphicsLayer* ForegroundLayer() const { return foreground_layer_.get(); } 111 DecorationOutlineLayer()112 GraphicsLayer* DecorationOutlineLayer() const { 113 return decoration_outline_layer_.get(); 114 } 115 HasScrollingLayer()116 bool HasScrollingLayer() const { return scrolling_layer_.get(); } ScrollingLayer()117 GraphicsLayer* ScrollingLayer() const { return scrolling_layer_.get(); } ScrollingContentsLayer()118 GraphicsLayer* ScrollingContentsLayer() const { 119 return scrolling_contents_layer_.get(); 120 } 121 HasMaskLayer()122 bool HasMaskLayer() const { return mask_layer_.get(); } MaskLayer()123 GraphicsLayer* MaskLayer() const { return mask_layer_.get(); } 124 125 GraphicsLayer* ParentForSublayers() const; 126 GraphicsLayer* ChildForSuperlayers() const; 127 void SetSublayers(const GraphicsLayerVector&); 128 SquashingContainmentLayer()129 GraphicsLayer* SquashingContainmentLayer() const { 130 return squashing_containment_layer_.get(); 131 } SquashingLayer()132 GraphicsLayer* SquashingLayer() const { return squashing_layer_.get(); } SquashingLayerOffsetFromLayoutObject()133 const IntSize& SquashingLayerOffsetFromLayoutObject() const { 134 return squashing_layer_offset_from_layout_object_; 135 } 136 137 void SetSquashingContentsNeedDisplay(); 138 void SetContentsNeedDisplay(); 139 140 // Let all DrawsContent GraphicsLayers check raster invalidations after 141 // a no-change paint. 142 void SetNeedsCheckRasterInvalidation(); 143 144 // Notification from the layoutObject that its content changed. 145 void ContentChanged(ContentChangeType); 146 CompositedBounds()147 PhysicalRect CompositedBounds() const { return composited_bounds_; } 148 149 void PositionOverflowControlsLayers(); 150 151 // Returns true if the assignment actually changed the assigned squashing 152 // layer. 153 bool UpdateSquashingLayerAssignment(PaintLayer* squashed_layer, 154 wtf_size_t next_squashed_layer_index); 155 void RemoveLayerFromSquashingGraphicsLayer(const PaintLayer*); 156 #if DCHECK_IS_ON() 157 bool VerifyLayerInSquashingVector(const PaintLayer*); 158 #endif 159 160 void FinishAccumulatingSquashingLayers( 161 wtf_size_t next_squashed_layer_index, 162 Vector<PaintLayer*>& layers_needing_paint_invalidation); 163 void UpdateElementId(); 164 165 // GraphicsLayerClient interface 166 IntRect ComputeInterestRect( 167 const GraphicsLayer*, 168 const IntRect& previous_interest_rect) const override; 169 LayoutSize SubpixelAccumulation() const final; 170 bool NeedsRepaint(const GraphicsLayer&) const override; 171 void PaintContents(const GraphicsLayer*, 172 GraphicsContext&, 173 GraphicsLayerPaintingPhase, 174 const IntRect& interest_rect) const override; 175 bool ShouldThrottleRendering() const override; 176 bool IsUnderSVGHiddenContainer() const override; 177 bool IsTrackingRasterInvalidations() const override; 178 void GraphicsLayersDidChange() override; 179 bool PaintBlockedByDisplayLockIncludingAncestors( 180 DisplayLockContextLifecycleTarget) const override; 181 void NotifyDisplayLockNeedsGraphicsLayerCollection() override; 182 183 #if DCHECK_IS_ON() 184 void VerifyNotPainting() override; 185 #endif 186 187 PhysicalRect ContentsBox() const; 188 LayerForHorizontalScrollbar()189 GraphicsLayer* LayerForHorizontalScrollbar() const { 190 return layer_for_horizontal_scrollbar_.get(); 191 } LayerForVerticalScrollbar()192 GraphicsLayer* LayerForVerticalScrollbar() const { 193 return layer_for_vertical_scrollbar_.get(); 194 } LayerForScrollCorner()195 GraphicsLayer* LayerForScrollCorner() const { 196 return layer_for_scroll_corner_.get(); 197 } 198 199 // Returns true if the overflow controls cannot be positioned within this 200 // CLM's internal hierarchy without incorrectly stacking under some 201 // scrolling content. If this returns true, these controls must be 202 // repositioned in the graphics layer tree to ensure that they stack above 203 // scrolling content. 204 bool NeedsToReparentOverflowControls() const; 205 206 // Removes the overflow controls host layer from its parent and positions it 207 // so that it can be inserted as a sibling to this CLM without changing 208 // position. 209 GraphicsLayer* DetachLayerForOverflowControls(); 210 211 // We may similarly need to reattach the layer for outlines and decorations. 212 GraphicsLayer* DetachLayerForDecorationOutline(); 213 214 void SetBlendMode(BlendMode); 215 NeedsGraphicsLayerUpdate()216 bool NeedsGraphicsLayerUpdate() { 217 return pending_update_scope_ > kGraphicsLayerUpdateNone; 218 } SetNeedsGraphicsLayerUpdate(GraphicsLayerUpdateScope scope)219 void SetNeedsGraphicsLayerUpdate(GraphicsLayerUpdateScope scope) { 220 pending_update_scope_ = std::max( 221 static_cast<GraphicsLayerUpdateScope>(pending_update_scope_), scope); 222 } ClearNeedsGraphicsLayerUpdate()223 void ClearNeedsGraphicsLayerUpdate() { 224 pending_update_scope_ = kGraphicsLayerUpdateNone; 225 } 226 227 GraphicsLayerUpdater::UpdateType UpdateTypeForChildren( 228 GraphicsLayerUpdater::UpdateType) const; 229 230 #if DCHECK_IS_ON() AssertNeedsToUpdateGraphicsLayerBitsCleared()231 void AssertNeedsToUpdateGraphicsLayerBitsCleared() { 232 DCHECK_EQ(pending_update_scope_, 233 static_cast<unsigned>(kGraphicsLayerUpdateNone)); 234 } 235 #endif 236 237 String DebugName(const GraphicsLayer*) const override; 238 239 const ScrollableArea* GetScrollableAreaForTesting( 240 const GraphicsLayer*) const override; 241 242 PhysicalOffset ContentOffsetInCompositingLayer() const; 243 244 // If there is a squashed layer painting into this CLM that is an ancestor of 245 // the given LayoutObject, return it. Otherwise return nullptr. 246 const GraphicsLayerPaintInfo* ContainingSquashedLayer( 247 const LayoutObject*, 248 unsigned max_squashed_layer_index); 249 250 // Returns whether an adjustment happend. 251 bool AdjustForCompositedScrolling(const GraphicsLayer*, 252 IntSize& offset) const; 253 DrawsBackgroundOntoContentLayer()254 bool DrawsBackgroundOntoContentLayer() const { 255 return draws_background_onto_content_layer_; 256 } 257 258 private: 259 // Returns true for layers with scrollable overflow which have a background 260 // that can be painted into the composited scrolling contents layer (i.e. 261 // the background can scroll with the content). When the background is also 262 // opaque this allows us to composite the scroller even on low DPI as we can 263 // draw with subpixel anti-aliasing. BackgroundPaintsOntoScrollingContentsLayer()264 bool BackgroundPaintsOntoScrollingContentsLayer() const { 265 return GetLayoutObject().GetBackgroundPaintLocation() & 266 kBackgroundPaintInScrollingContents; 267 } 268 269 // Returns true if the background paints onto the main graphics layer. 270 // In some situations, we may paint background on both the main graphics layer 271 // and the scrolling contents layer. BackgroundPaintsOntoGraphicsLayer()272 bool BackgroundPaintsOntoGraphicsLayer() const { 273 return GetLayoutObject().GetBackgroundPaintLocation() & 274 kBackgroundPaintInGraphicsLayer; 275 } 276 277 IntRect RecomputeInterestRect(const GraphicsLayer*) const; 278 static bool InterestRectChangedEnoughToRepaint( 279 const IntRect& previous_interest_rect, 280 const IntRect& new_interest_rect, 281 const IntSize& layer_size); 282 283 static const GraphicsLayerPaintInfo* ContainingSquashedLayer( 284 const LayoutObject*, 285 const Vector<GraphicsLayerPaintInfo>& layers, 286 unsigned max_squashed_layer_index); 287 288 // Paints the scrollbar part associated with the given graphics layer into the 289 // given context. 290 void PaintScrollableArea(const GraphicsLayer*, 291 GraphicsContext&, 292 const IntRect& interest_rect) const; 293 // Returns whether the given layer is part of the scrollable area, if any, 294 // associated with this mapping. 295 bool IsScrollableAreaLayer(const GraphicsLayer*) const; 296 297 // Returns whether the given layer is a repaint needed part of the scrollable 298 // area, if any, associated with this mapping. 299 bool IsScrollableAreaLayerWhichNeedsRepaint(const GraphicsLayer*) const; 300 301 // Helper methods to updateGraphicsLayerGeometry: 302 void ComputeGraphicsLayerParentLocation( 303 const PaintLayer* compositing_container, 304 IntPoint& graphics_layer_parent_location); 305 void UpdateSquashingLayerGeometry( 306 const PaintLayer* compositing_container, 307 const IntPoint& snapped_offset_from_composited_ancestor, 308 Vector<GraphicsLayerPaintInfo>& layers, 309 Vector<PaintLayer*>& layers_needing_paint_invalidation); 310 void UpdateMainGraphicsLayerGeometry(const IntRect& local_compositing_bounds); 311 void UpdateOverflowControlsHostLayerGeometry( 312 const PaintLayer* compositing_container); 313 void UpdateChildTransformLayerGeometry(); 314 void UpdateMaskLayerGeometry(); 315 void UpdateForegroundLayerGeometry(); 316 void UpdateDecorationOutlineLayerGeometry( 317 const IntSize& relative_compositing_bounds_size); 318 void UpdateScrollingLayerGeometry(); 319 320 void CreatePrimaryGraphicsLayer(); 321 322 std::unique_ptr<GraphicsLayer> CreateGraphicsLayer( 323 CompositingReasons, 324 SquashingDisallowedReasons = SquashingDisallowedReason::kNone); 325 bool ToggleScrollbarLayerIfNeeded(std::unique_ptr<GraphicsLayer>&, 326 bool needs_layer, 327 CompositingReasons); 328 GetLayoutObject()329 LayoutBoxModelObject& GetLayoutObject() const { 330 return owning_layer_.GetLayoutObject(); 331 } Compositor()332 PaintLayerCompositor* Compositor() const { 333 return owning_layer_.Compositor(); 334 } 335 336 void UpdateInternalHierarchy(); 337 void UpdatePaintingPhases(); 338 bool UpdateOverflowControlsLayers(bool needs_horizontal_scrollbar_layer, 339 bool needs_vertical_scrollbar_layer, 340 bool needs_scroll_corner_layer); 341 bool UpdateForegroundLayer(bool needs_foreground_layer); 342 bool UpdateDecorationOutlineLayer(bool needs_decoration_outline_layer); 343 bool UpdateMaskLayer(bool needs_mask_layer); 344 bool RequiresHorizontalScrollbarLayer() const; 345 bool RequiresVerticalScrollbarLayer() const; 346 bool RequiresScrollCornerLayer() const; 347 bool UpdateScrollingLayers(bool scrolling_layers); 348 bool UpdateSquashingLayers(bool needs_squashing_layers); 349 void UpdateDrawsContentAndPaintsHitTest(); 350 void UpdateCompositedBounds(); 351 352 // Also sets subpixelAccumulation on the layer. 353 void ComputeBoundsOfOwningLayer( 354 const PaintLayer* composited_ancestor, 355 IntRect& local_compositing_bounds, 356 IntPoint& snapped_offset_from_composited_ancestor); 357 358 GraphicsLayerPaintingPhase PaintingPhaseForPrimaryLayer() const; 359 360 // Result is transform origin in pixels. 361 FloatPoint3D ComputeTransformOrigin(const IntRect& border_box) const; 362 363 void UpdateTransform(const ComputedStyle&); 364 365 bool PaintsChildren() const; 366 367 // Returns true if this layer has content that needs to be displayed by 368 // painting into the backing store. 369 bool ContainsPaintedContent() const; 370 // Returns true if the Layer just contains an image that we can composite 371 // directly. 372 bool IsDirectlyCompositedImage() const; 373 void UpdateImageContents(); 374 375 Color LayoutObjectBackgroundColor() const; 376 void UpdateBackgroundColor(); 377 void UpdateContentsRect(); 378 void UpdateCompositingReasons(); 379 380 static bool HasVisibleNonCompositingDescendant(PaintLayer* parent); 381 382 void DoPaintTask(const GraphicsLayerPaintInfo&, 383 const GraphicsLayer&, 384 PaintLayerFlags, 385 GraphicsContext&, 386 const IntRect& clip) const; 387 388 // Computes the background clip rect for the given squashed layer, up to any 389 // containing layer that is squashed into the same squashing layer and 390 // contains this squashed layer's clipping ancestor. The clip rect is 391 // returned in the coordinate space of the given squashed layer. If there is 392 // no such containing layer, returns the infinite rect. 393 static void LocalClipRectForSquashedLayer( 394 const PaintLayer& reference_layer, 395 const Vector<GraphicsLayerPaintInfo>& layers, 396 GraphicsLayerPaintInfo&); 397 398 // Clear the groupedMapping entry on the layer at the given index, only if 399 // that layer does not appear earlier in the set of layers for this object. 400 bool InvalidateLayerIfNoPrecedingEntry(wtf_size_t); 401 402 PaintLayer& owning_layer_; 403 404 // The hierarchy of layers that is maintained by the CompositedLayerMapping 405 // looks like this: 406 // 407 // + graphics_layer_ 408 // + (scrolling_layer_ + scrolling_contents_layer_) [OPTIONAL] 409 // | + overflow_controls_host_layer_ [OPTIONAL] 410 // | + layer_for_vertical_scrollbar_ [OPTIONAL] 411 // | + layer_for_horizontal_scrollbar_ [OPTIONAL] 412 // | + layer_for_scroll_corner_ [OPTIONAL] 413 // + decoration_outline_layer_ [OPTIONAL] 414 // The overflow controls may need to be repositioned in the graphics layer 415 // tree by the RLC to ensure that they stack above scrolling content. 416 417 std::unique_ptr<GraphicsLayer> graphics_layer_; 418 419 // Only used if the layer is using composited scrolling. 420 std::unique_ptr<GraphicsLayer> scrolling_layer_; 421 422 // Only used if the layer is using composited scrolling. 423 std::unique_ptr<GraphicsLayer> scrolling_contents_layer_; 424 425 // This layer is also added to the hierarchy by the RLB, but in a different 426 // way than the layers above. It's added to graphics_layer_ as its mask layer 427 // (naturally) if we have a mask, and isn't part of the typical hierarchy (it 428 // has no children). 429 // Only used if we have a mask. 430 std::unique_ptr<GraphicsLayer> mask_layer_; 431 432 // There is one other (optional) layer whose painting is managed by the 433 // CompositedLayerMapping, but whose position in the hierarchy is maintained 434 // by the PaintLayerCompositor. This is the foreground layer. The foreground 435 // layer exists if we have composited descendants with negative z-order. We 436 // need the extra layer in this case because the layer needs to draw both 437 // below (for the background, say) and above (for the normal flow content, 438 // say) the negative z-order descendants and this is impossible with a single 439 // layer. The RLC handles inserting foreground_layer_ in the correct position 440 // in our descendant list for us (right after the neg z-order dsecendants). 441 // Only used in cases where we need to draw the foreground separately. 442 std::unique_ptr<GraphicsLayer> foreground_layer_; 443 444 std::unique_ptr<GraphicsLayer> layer_for_horizontal_scrollbar_; 445 std::unique_ptr<GraphicsLayer> layer_for_vertical_scrollbar_; 446 std::unique_ptr<GraphicsLayer> layer_for_scroll_corner_; 447 448 // This layer contains the scrollbar and scroll corner layers and clips them 449 // to the border box bounds of our LayoutObject. It is usually added to 450 // graphics_layer_, but may be reparented by GraphicsLayerTreeBuilder to 451 // ensure that scrollbars appear above scrolling content. 452 std::unique_ptr<GraphicsLayer> overflow_controls_host_layer_; 453 454 // DecorationLayer which paints outline. 455 std::unique_ptr<GraphicsLayer> decoration_outline_layer_; 456 457 // A squashing CLM has the following structure: 458 // squashing_containment_layer_ 459 // + graphics_layer_ 460 // + squashing_layer_ 461 // 462 // Stacking children of a squashed layer receive graphics layers that are 463 // parented to the composited ancestor of the squashed layer (i.e. nearest 464 // enclosing composited layer that is not 465 // squashed). 466 467 // Only used if any squashed layers exist, this contains the squashed layers 468 // as siblings to the rest of the GraphicsLayer tree chunk. 469 std::unique_ptr<GraphicsLayer> squashing_containment_layer_; 470 471 // Only used if any squashed layers exist, this is the backing that squashed 472 // layers paint into. 473 std::unique_ptr<GraphicsLayer> squashing_layer_; 474 Vector<GraphicsLayerPaintInfo> squashed_layers_; 475 IntSize squashing_layer_offset_from_layout_object_; 476 477 PhysicalRect composited_bounds_; 478 479 unsigned pending_update_scope_ : 2; 480 481 unsigned scrolling_contents_are_empty_ : 1; 482 483 bool draws_background_onto_content_layer_; 484 485 friend class CompositedLayerMappingTest; 486 DISALLOW_COPY_AND_ASSIGN(CompositedLayerMapping); 487 }; 488 489 } // namespace blink 490 491 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITED_LAYER_MAPPING_H_ 492