Flutter Engine
container_layer.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FLUTTER_FLOW_LAYERS_CONTAINER_LAYER_H_
6 #define FLUTTER_FLOW_LAYERS_CONTAINER_LAYER_H_
7 
8 #include <vector>
9 
10 #include "flutter/flow/layers/layer.h"
11 
12 namespace flutter {
13 
14 class ContainerLayer : public Layer {
15  public:
17 
18  virtual void Add(std::shared_ptr<Layer> layer);
19 
20  void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
21  void Paint(PaintContext& context) const override;
22 #if defined(LEGACY_FUCHSIA_EMBEDDER)
23  void CheckForChildLayerBelow(PrerollContext* context) override;
24  void UpdateScene(std::shared_ptr<SceneUpdateContext> context) override;
25 #endif
26 
27  const std::vector<std::shared_ptr<Layer>>& layers() const { return layers_; }
28 
29  protected:
30  void PrerollChildren(PrerollContext* context,
31  const SkMatrix& child_matrix,
32  SkRect* child_paint_bounds);
33  void PaintChildren(PaintContext& context) const;
34 
35 #if defined(LEGACY_FUCHSIA_EMBEDDER)
36  void UpdateSceneChildren(std::shared_ptr<SceneUpdateContext> context);
37 #endif
38 
39  // Try to prepare the raster cache for a given layer.
40  //
41  // The raster cache would fail if either of the followings is true:
42  // 1. The context has a platform view.
43  // 2. The context does not have a valid raster cache.
44  // 3. The layer's paint bounds does not intersect with the cull rect.
45  //
46  // We make this a static function instead of a member function that directy
47  // uses the "this" pointer as the layer because we sometimes need to raster
48  // cache a child layer and one can't access its child's protected method.
49  static void TryToPrepareRasterCache(PrerollContext* context,
50  Layer* layer,
51  const SkMatrix& matrix);
52 
53  private:
54  std::vector<std::shared_ptr<Layer>> layers_;
55 
56  FML_DISALLOW_COPY_AND_ASSIGN(ContainerLayer);
57 };
58 
59 //------------------------------------------------------------------------------
60 /// Some ContainerLayer objects perform a rendering operation or filter on
61 /// the rendered output of their children. Often that operation is changed
62 /// slightly from frame to frame as part of an animation. During such an
63 /// animation, the children can be cached if they are stable to avoid having
64 /// to render them on every frame. Even if the children are not stable,
65 /// rendering them into the raster cache during a Preroll operation will save
66 /// an extra change of rendering surface during the Paint phase as compared
67 /// to using the SaveLayer that would otherwise be needed with no caching.
68 ///
69 /// Typically the Flutter Widget objects that lead to the creation of these
70 /// layers will try to enforce only a single child Widget by their design.
71 /// Unfortunately, the process of turning Widgets eventually into engine
72 /// layers is not a 1:1 process so this layer might end up with multiple
73 /// child layers even if the Widget only had a single child Widget.
74 ///
75 /// When such a layer goes to cache the output of its children, it will
76 /// need to supply a single layer to the cache mechanism since the raster
77 /// cache uses a layer unique_id() as part of the cache key. If this layer
78 /// ended up with multiple children, then it must first collect them into
79 /// one layer for the cache mechanism. In order to provide a single layer
80 /// for all of the children, this utility class will implicitly collect
81 /// the children into a secondary ContainerLayer called the child container.
82 ///
83 /// A by-product of creating a hidden child container, though, is that the
84 /// child container is created new every time this layer is created with
85 /// different properties, such as during an animation. In that scenario,
86 /// it would be best to cache the single real child of this layer if it
87 /// is unique and if it is stable from frame to frame. To facilitate this
88 /// optimal caching strategy, this class implements two accessor methods
89 /// to be used for different purposes:
90 ///
91 /// When the layer needs to recurse to perform some operation on its children,
92 /// it can call GetChildContainer() to return the hidden container containing
93 /// all of the real children.
94 ///
95 /// When the layer wants to cache the rendered contents of its children, it
96 /// should call GetCacheableChild() for best performance. This method may
97 /// end up returning the same layer as GetChildContainer(), but only if the
98 /// conditions for optimal caching of a single child are not met.
99 ///
101  public:
103 
104  void Add(std::shared_ptr<Layer> layer) override;
105 
106  protected:
107  /**
108  * @brief Returns the ContainerLayer used to hold all of the children of the
109  * MergedContainerLayer. Note that this may not be the best layer to use
110  * for caching the children.
111  *
112  * @see GetCacheableChild()
113  * @return the ContainerLayer child used to hold the children
114  */
115  ContainerLayer* GetChildContainer() const;
116 
117  /**
118  * @brief Returns the best choice for a Layer object that can be used
119  * in RasterCache operations to cache the children.
120  *
121  * The returned Layer must represent all children and try to remain stable
122  * if the MergedContainerLayer is reconstructed in subsequent frames of
123  * the scene.
124  *
125  * @see GetChildContainer()
126  * @return the best candidate Layer for caching the children
127  */
128  Layer* GetCacheableChild() const;
129 
130  private:
132 };
133 
134 } // namespace flutter
135 
136 #endif // FLUTTER_FLOW_LAYERS_CONTAINER_LAYER_H_
const std::vector< std::shared_ptr< Layer > > & layers() const
void PrerollChildren(PrerollContext *context, const SkMatrix &child_matrix, SkRect *child_paint_bounds)
void Paint(PaintContext &context) const override
virtual void Add(std::shared_ptr< Layer > layer)
void Preroll(PrerollContext *context, const SkMatrix &matrix) override
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:27
static void TryToPrepareRasterCache(PrerollContext *context, Layer *layer, const SkMatrix &matrix)
void PaintChildren(PaintContext &context) const