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