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