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