• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_SCENE_UPDATE_CONTEXT_H_
6 #define FLUTTER_FLOW_SCENE_UPDATE_CONTEXT_H_
7 
8 #include <memory>
9 #include <set>
10 #include <vector>
11 
12 #include "flutter/flow/compositor_context.h"
13 #include "flutter/flow/raster_cache_key.h"
14 #include "flutter/fml/compiler_specific.h"
15 #include "flutter/fml/logging.h"
16 #include "flutter/fml/macros.h"
17 #include "lib/ui/scenic/cpp/resources.h"
18 #include "third_party/skia/include/core/SkRect.h"
19 #include "third_party/skia/include/core/SkSurface.h"
20 
21 namespace flutter {
22 
23 class Layer;
24 
25 class SceneUpdateContext {
26  public:
27   class SurfaceProducerSurface {
28    public:
29     virtual ~SurfaceProducerSurface() = default;
30 
31     virtual size_t AdvanceAndGetAge() = 0;
32 
33     virtual bool FlushSessionAcquireAndReleaseEvents() = 0;
34 
35     virtual bool IsValid() const = 0;
36 
37     virtual SkISize GetSize() const = 0;
38 
39     virtual void SignalWritesFinished(
40         std::function<void(void)> on_writes_committed) = 0;
41 
42     virtual scenic::Image* GetImage() = 0;
43 
44     virtual sk_sp<SkSurface> GetSkiaSurface() const = 0;
45   };
46 
47   class SurfaceProducer {
48    public:
49     virtual ~SurfaceProducer() = default;
50 
51     // The produced surface owns the entity_node and has a layer_key for
52     // retained rendering. The surface will only be retained if the layer_key
53     // has a non-null layer pointer (layer_key.id()).
54     virtual std::unique_ptr<SurfaceProducerSurface> ProduceSurface(
55         const SkISize& size,
56         const LayerRasterCacheKey& layer_key,
57         std::unique_ptr<scenic::EntityNode> entity_node) = 0;
58 
59     // Query a retained entity node (owned by a retained surface) for retained
60     // rendering.
61     virtual bool HasRetainedNode(const LayerRasterCacheKey& key) const = 0;
62     virtual const scenic::EntityNode& GetRetainedNode(
63         const LayerRasterCacheKey& key) = 0;
64 
65     virtual void SubmitSurface(
66         std::unique_ptr<SurfaceProducerSurface> surface) = 0;
67   };
68 
69   class Entity {
70    public:
71     Entity(SceneUpdateContext& context);
72     virtual ~Entity();
73 
context()74     SceneUpdateContext& context() { return context_; }
entity_node()75     scenic::EntityNode& entity_node() { return entity_node_; }
embedder_node()76     virtual scenic::ContainerNode& embedder_node() { return entity_node_; }
77 
78    private:
79     SceneUpdateContext& context_;
80     Entity* const previous_entity_;
81 
82     scenic::EntityNode entity_node_;
83   };
84 
85   class Transform : public Entity {
86    public:
87     Transform(SceneUpdateContext& context, const SkMatrix& transform);
88     Transform(SceneUpdateContext& context,
89               float scale_x,
90               float scale_y,
91               float scale_z);
92     virtual ~Transform();
93 
94    private:
95     float const previous_scale_x_;
96     float const previous_scale_y_;
97   };
98 
99   class Shape : public Entity {
100    public:
101     Shape(SceneUpdateContext& context);
102     virtual ~Shape() = default;
103 
shape_node()104     scenic::ShapeNode& shape_node() { return shape_node_; }
105 
106    private:
107     scenic::ShapeNode shape_node_;
108   };
109 
110   class Frame : public Shape {
111    public:
112     // When layer is not nullptr, the frame is associated with a layer subtree
113     // rooted with that layer. The frame may then create a surface that will be
114     // retained for that layer.
115     Frame(SceneUpdateContext& context,
116           const SkRRect& rrect,
117           SkColor color,
118           float local_elevation = 0.0f,
119           float parent_elevation = 0.0f,
120           float depth = 0.0f,
121           Layer* layer = nullptr);
122     virtual ~Frame();
123 
124     void AddPaintLayer(Layer* layer);
125 
126    private:
127     const SkRRect& rrect_;
128     SkColor const color_;
129 
130     std::vector<Layer*> paint_layers_;
131     SkRect paint_bounds_;
132     Layer* layer_;
133   };
134 
135   class Clip : public Entity {
136    public:
137     Clip(SceneUpdateContext& context, const SkRect& shape_bounds);
138     ~Clip() = default;
139   };
140 
141   SceneUpdateContext(scenic::Session* session,
142                      SurfaceProducer* surface_producer);
143   ~SceneUpdateContext() = default;
144 
session()145   scenic::Session* session() { return session_; }
146 
top_entity()147   Entity* top_entity() { return top_entity_; }
148 
has_metrics()149   bool has_metrics() const { return !!metrics_; }
set_metrics(fuchsia::ui::gfx::MetricsPtr metrics)150   void set_metrics(fuchsia::ui::gfx::MetricsPtr metrics) {
151     metrics_ = std::move(metrics);
152   }
metrics()153   const fuchsia::ui::gfx::MetricsPtr& metrics() const { return metrics_; }
154 
155   // TODO(chinmaygarde): This method must submit the surfaces as soon as paint
156   // tasks are done. However, given that there is no support currently for
157   // Vulkan semaphores, we need to submit all the surfaces after an explicit
158   // CPU wait. Once Vulkan semaphores are available, this method must return
159   // void and the implementation must submit surfaces on its own as soon as the
160   // specific canvas operations are done.
161   FML_WARN_UNUSED_RESULT
162   std::vector<std::unique_ptr<SurfaceProducerSurface>> ExecutePaintTasks(
163       CompositorContext::ScopedFrame& frame);
164 
ScaleX()165   float ScaleX() const { return metrics_->scale_x * top_scale_x_; }
ScaleY()166   float ScaleY() const { return metrics_->scale_y * top_scale_y_; }
167 
168   // The transformation matrix of the current context. It's used to construct
169   // the LayerRasterCacheKey for a given layer.
Matrix()170   SkMatrix Matrix() const { return SkMatrix::MakeScale(ScaleX(), ScaleY()); }
171 
HasRetainedNode(const LayerRasterCacheKey & key)172   bool HasRetainedNode(const LayerRasterCacheKey& key) const {
173     return surface_producer_->HasRetainedNode(key);
174   }
GetRetainedNode(const LayerRasterCacheKey & key)175   const scenic::EntityNode& GetRetainedNode(const LayerRasterCacheKey& key) {
176     return surface_producer_->GetRetainedNode(key);
177   }
178 
179  private:
180   struct PaintTask {
181     std::unique_ptr<SurfaceProducerSurface> surface;
182     SkScalar left;
183     SkScalar top;
184     SkScalar scale_x;
185     SkScalar scale_y;
186     SkColor background_color;
187     std::vector<Layer*> layers;
188   };
189 
190   // Setup the entity_node as a frame that materialize all the paint_layers. In
191   // most cases, this creates a VulkanSurface (SurfaceProducerSurface) by
192   // calling SetShapeTextureOrColor and GenerageImageIfNeeded. Such surface will
193   // own the associated entity_node. If the layer pointer isn't nullptr, the
194   // surface (and thus the entity_node) will be retained for that layer to
195   // improve the performance.
196   void CreateFrame(scenic::EntityNode entity_node,
197                    scenic::ShapeNode shape_node,
198                    const SkRRect& rrect,
199                    SkColor color,
200                    const SkRect& paint_bounds,
201                    std::vector<Layer*> paint_layers,
202                    Layer* layer);
203   void SetShapeTextureAndColor(scenic::ShapeNode& shape_node,
204                                SkColor color,
205                                SkScalar scale_x,
206                                SkScalar scale_y,
207                                const SkRect& paint_bounds,
208                                std::vector<Layer*> paint_layers,
209                                Layer* layer,
210                                scenic::EntityNode entity_node);
211   void SetShapeColor(scenic::ShapeNode& shape_node, SkColor color);
212   scenic::Image* GenerateImageIfNeeded(SkColor color,
213                                        SkScalar scale_x,
214                                        SkScalar scale_y,
215                                        const SkRect& paint_bounds,
216                                        std::vector<Layer*> paint_layers,
217                                        Layer* layer,
218                                        scenic::EntityNode entity_node);
219 
220   Entity* top_entity_ = nullptr;
221   float top_scale_x_ = 1.f;
222   float top_scale_y_ = 1.f;
223 
224   scenic::Session* const session_;
225   SurfaceProducer* const surface_producer_;
226 
227   fuchsia::ui::gfx::MetricsPtr metrics_;
228 
229   std::vector<PaintTask> paint_tasks_;
230 
231   FML_DISALLOW_COPY_AND_ASSIGN(SceneUpdateContext);
232 };
233 
234 }  // namespace flutter
235 
236 #endif  // FLUTTER_FLOW_SCENE_UPDATE_CONTEXT_H_
237