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