Flutter Engine
scene_builder.cc
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 #include "flutter/lib/ui/compositing/scene_builder.h"
6 
7 #include "flutter/flow/layers/backdrop_filter_layer.h"
8 #include "flutter/flow/layers/clip_path_layer.h"
9 #include "flutter/flow/layers/clip_rect_layer.h"
10 #include "flutter/flow/layers/clip_rrect_layer.h"
11 #include "flutter/flow/layers/color_filter_layer.h"
12 #include "flutter/flow/layers/container_layer.h"
13 #include "flutter/flow/layers/image_filter_layer.h"
14 #include "flutter/flow/layers/layer.h"
15 #include "flutter/flow/layers/layer_tree.h"
16 #include "flutter/flow/layers/opacity_layer.h"
17 #include "flutter/flow/layers/performance_overlay_layer.h"
18 #include "flutter/flow/layers/physical_shape_layer.h"
19 #include "flutter/flow/layers/picture_layer.h"
20 #include "flutter/flow/layers/platform_view_layer.h"
21 #include "flutter/flow/layers/shader_mask_layer.h"
22 #include "flutter/flow/layers/texture_layer.h"
23 #include "flutter/flow/layers/transform_layer.h"
24 #include "flutter/fml/build_config.h"
25 #include "flutter/lib/ui/painting/matrix.h"
26 #include "flutter/lib/ui/painting/shader.h"
27 #include "third_party/skia/include/core/SkColorFilter.h"
32 
33 #if defined(LEGACY_FUCHSIA_EMBEDDER)
34 #include "flutter/flow/layers/child_scene_layer.h" // nogncheck
35 #endif
36 
37 namespace flutter {
38 
39 static void SceneBuilder_constructor(Dart_NativeArguments args) {
42 }
43 
45 
46 #define FOR_EACH_BINDING(V) \
47  V(SceneBuilder, pushOffset) \
48  V(SceneBuilder, pushTransform) \
49  V(SceneBuilder, pushClipRect) \
50  V(SceneBuilder, pushClipRRect) \
51  V(SceneBuilder, pushClipPath) \
52  V(SceneBuilder, pushOpacity) \
53  V(SceneBuilder, pushColorFilter) \
54  V(SceneBuilder, pushImageFilter) \
55  V(SceneBuilder, pushBackdropFilter) \
56  V(SceneBuilder, pushShaderMask) \
57  V(SceneBuilder, pushPhysicalShape) \
58  V(SceneBuilder, pop) \
59  V(SceneBuilder, addPlatformView) \
60  V(SceneBuilder, addRetained) \
61  V(SceneBuilder, addPicture) \
62  V(SceneBuilder, addTexture) \
63  V(SceneBuilder, addPerformanceOverlay) \
64  V(SceneBuilder, setRasterizerTracingThreshold) \
65  V(SceneBuilder, setCheckerboardOffscreenLayers) \
66  V(SceneBuilder, setCheckerboardRasterCacheImages) \
67  V(SceneBuilder, build)
68 
70 #if defined(LEGACY_FUCHSIA_EMBEDDER)
71 DART_NATIVE_CALLBACK(SceneBuilder, addChildScene)
72 #endif
73 
75  natives->Register({
76  {"SceneBuilder_constructor", SceneBuilder_constructor, 1, true},
78 #if defined(LEGACY_FUCHSIA_EMBEDDER)
79  DART_REGISTER_NATIVE(SceneBuilder, addChildScene)
80 #endif
81  });
82 }
83 
84 SceneBuilder::SceneBuilder() {
85  // Add a ContainerLayer as the root layer, so that AddLayer operations are
86  // always valid.
87  PushLayer(std::make_shared<flutter::ContainerLayer>());
88 }
89 
90 SceneBuilder::~SceneBuilder() = default;
91 
92 void SceneBuilder::pushTransform(Dart_Handle layer_handle,
93  tonic::Float64List& matrix4) {
94  SkMatrix sk_matrix = ToSkMatrix(matrix4);
95  auto layer = std::make_shared<flutter::TransformLayer>(sk_matrix);
96  PushLayer(layer);
97  // matrix4 has to be released before we can return another Dart object
98  matrix4.Release();
99  EngineLayer::MakeRetained(layer_handle, layer);
100 }
101 
102 void SceneBuilder::pushOffset(Dart_Handle layer_handle, double dx, double dy) {
103  SkMatrix sk_matrix = SkMatrix::Translate(dx, dy);
104  auto layer = std::make_shared<flutter::TransformLayer>(sk_matrix);
105  PushLayer(layer);
106  EngineLayer::MakeRetained(layer_handle, layer);
107 }
108 
109 void SceneBuilder::pushClipRect(Dart_Handle layer_handle,
110  double left,
111  double right,
112  double top,
113  double bottom,
114  int clipBehavior) {
115  SkRect clipRect = SkRect::MakeLTRB(left, top, right, bottom);
116  flutter::Clip clip_behavior = static_cast<flutter::Clip>(clipBehavior);
117  auto layer =
118  std::make_shared<flutter::ClipRectLayer>(clipRect, clip_behavior);
119  PushLayer(layer);
120  EngineLayer::MakeRetained(layer_handle, layer);
121 }
122 
123 void SceneBuilder::pushClipRRect(Dart_Handle layer_handle,
124  const RRect& rrect,
125  int clipBehavior) {
126  flutter::Clip clip_behavior = static_cast<flutter::Clip>(clipBehavior);
127  auto layer =
128  std::make_shared<flutter::ClipRRectLayer>(rrect.sk_rrect, clip_behavior);
129  PushLayer(layer);
130  EngineLayer::MakeRetained(layer_handle, layer);
131 }
132 
133 void SceneBuilder::pushClipPath(Dart_Handle layer_handle,
134  const CanvasPath* path,
135  int clipBehavior) {
136  flutter::Clip clip_behavior = static_cast<flutter::Clip>(clipBehavior);
137  FML_DCHECK(clip_behavior != flutter::Clip::none);
138  auto layer =
139  std::make_shared<flutter::ClipPathLayer>(path->path(), clip_behavior);
140  PushLayer(layer);
141  EngineLayer::MakeRetained(layer_handle, layer);
142 }
143 
144 void SceneBuilder::pushOpacity(Dart_Handle layer_handle,
145  int alpha,
146  double dx,
147  double dy) {
148  auto layer =
149  std::make_shared<flutter::OpacityLayer>(alpha, SkPoint::Make(dx, dy));
150  PushLayer(layer);
151  EngineLayer::MakeRetained(layer_handle, layer);
152 }
153 
154 void SceneBuilder::pushColorFilter(Dart_Handle layer_handle,
155  const ColorFilter* color_filter) {
156  auto layer =
157  std::make_shared<flutter::ColorFilterLayer>(color_filter->filter());
158  PushLayer(layer);
159  EngineLayer::MakeRetained(layer_handle, layer);
160 }
161 
162 void SceneBuilder::pushImageFilter(Dart_Handle layer_handle,
163  const ImageFilter* image_filter) {
164  auto layer =
165  std::make_shared<flutter::ImageFilterLayer>(image_filter->filter());
166  PushLayer(layer);
167  EngineLayer::MakeRetained(layer_handle, layer);
168 }
169 
170 void SceneBuilder::pushBackdropFilter(Dart_Handle layer_handle,
171  ImageFilter* filter) {
172  auto layer = std::make_shared<flutter::BackdropFilterLayer>(filter->filter());
173  PushLayer(layer);
174  EngineLayer::MakeRetained(layer_handle, layer);
175 }
176 
177 void SceneBuilder::pushShaderMask(Dart_Handle layer_handle,
178  Shader* shader,
179  double maskRectLeft,
180  double maskRectRight,
181  double maskRectTop,
182  double maskRectBottom,
183  int blendMode) {
184  SkRect rect = SkRect::MakeLTRB(maskRectLeft, maskRectTop, maskRectRight,
185  maskRectBottom);
186  auto layer = std::make_shared<flutter::ShaderMaskLayer>(
187  shader->shader(), rect, static_cast<SkBlendMode>(blendMode));
188  PushLayer(layer);
189  EngineLayer::MakeRetained(layer_handle, layer);
190 }
191 
192 void SceneBuilder::pushPhysicalShape(Dart_Handle layer_handle,
193  const CanvasPath* path,
194  double elevation,
195  int color,
196  int shadow_color,
197  int clipBehavior) {
198  auto layer = std::make_shared<flutter::PhysicalShapeLayer>(
199  static_cast<SkColor>(color), static_cast<SkColor>(shadow_color),
200  static_cast<float>(elevation), path->path(),
201  static_cast<flutter::Clip>(clipBehavior));
202  PushLayer(layer);
203  EngineLayer::MakeRetained(layer_handle, layer);
204 }
205 
207  AddLayer(retainedLayer->Layer());
208 }
209 
211  PopLayer();
212 }
213 
215  double dy,
216  Picture* picture,
217  int hints) {
218  SkPoint offset = SkPoint::Make(dx, dy);
219  SkRect pictureRect = picture->picture()->cullRect();
220  pictureRect.offset(offset.x(), offset.y());
221  auto layer = std::make_unique<flutter::PictureLayer>(
222  offset, UIDartState::CreateGPUObject(picture->picture()), !!(hints & 1),
223  !!(hints & 2));
224  AddLayer(std::move(layer));
225 }
226 
228  double dy,
229  double width,
230  double height,
231  int64_t textureId,
232  bool freeze,
233  int filterQuality) {
234  auto layer = std::make_unique<flutter::TextureLayer>(
235  SkPoint::Make(dx, dy), SkSize::Make(width, height), textureId, freeze,
236  static_cast<SkFilterQuality>(filterQuality));
237  AddLayer(std::move(layer));
238 }
239 
241  double dy,
242  double width,
243  double height,
244  int64_t viewId) {
245  auto layer = std::make_unique<flutter::PlatformViewLayer>(
246  SkPoint::Make(dx, dy), SkSize::Make(width, height), viewId);
247  AddLayer(std::move(layer));
248 }
249 
250 #if defined(LEGACY_FUCHSIA_EMBEDDER)
251 void SceneBuilder::addChildScene(double dx,
252  double dy,
253  double width,
254  double height,
255  SceneHost* sceneHost,
256  bool hitTestable) {
257  auto layer = std::make_unique<flutter::ChildSceneLayer>(
258  sceneHost->id(), SkPoint::Make(dx, dy), SkSize::Make(width, height),
259  hitTestable);
260  AddLayer(std::move(layer));
261 }
262 #endif
263 
264 void SceneBuilder::addPerformanceOverlay(uint64_t enabledOptions,
265  double left,
266  double right,
267  double top,
268  double bottom) {
269  SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
270  auto layer =
271  std::make_unique<flutter::PerformanceOverlayLayer>(enabledOptions);
272  layer->set_paint_bounds(rect);
273  AddLayer(std::move(layer));
274 }
275 
276 void SceneBuilder::setRasterizerTracingThreshold(uint32_t frameInterval) {
277  rasterizer_tracing_threshold_ = frameInterval;
278 }
279 
281  checkerboard_raster_cache_images_ = checkerboard;
282 }
283 
285  checkerboard_offscreen_layers_ = checkerboard;
286 }
287 
288 void SceneBuilder::build(Dart_Handle scene_handle) {
289  FML_DCHECK(layer_stack_.size() >= 1);
290 
291  Scene::create(scene_handle, layer_stack_[0], rasterizer_tracing_threshold_,
292  checkerboard_raster_cache_images_,
293  checkerboard_offscreen_layers_);
294  ClearDartWrapper(); // may delete this object.
295 }
296 
297 void SceneBuilder::AddLayer(std::shared_ptr<Layer> layer) {
298  FML_DCHECK(layer);
299 
300  if (!layer_stack_.empty()) {
301  layer_stack_.back()->Add(std::move(layer));
302  }
303 }
304 
305 void SceneBuilder::PushLayer(std::shared_ptr<ContainerLayer> layer) {
306  AddLayer(layer);
307  layer_stack_.push_back(std::move(layer));
308 }
309 
310 void SceneBuilder::PopLayer() {
311  // We never pop the root layer, so that AddLayer operations are always valid.
312  if (layer_stack_.size() > 1) {
313  layer_stack_.pop_back();
314  }
315 }
316 
317 } // namespace flutter
~SceneBuilder() override
G_BEGIN_DECLS FlValue * args
SkRRect sk_rrect
Definition: rrect.h:16
DEF_SWITCHES_START snapshot asset path
Definition: switches.h:32
void pushClipRRect(Dart_Handle layer_handle, const RRect &rrect, int clipBehavior)
void pushOpacity(Dart_Handle layer_handle, int alpha, double dx=0, double dy=0)
void setCheckerboardRasterCacheImages(bool checkerboard)
static void create(Dart_Handle scene_handle, std::shared_ptr< flutter::Layer > rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers)
Definition: scene.cc:30
#define FML_DCHECK(condition)
Definition: logging.h:86
void pushTransform(Dart_Handle layer_handle, tonic::Float64List &matrix4)
void addPlatformView(double dx, double dy, double width, double height, int64_t viewId)
void DartCallConstructor(Sig func, Dart_NativeArguments args)
Definition: dart_args.h:218
void addRetained(fml::RefPtr< EngineLayer > retainedLayer)
void pushClipRect(Dart_Handle layer_handle, double left, double right, double top, double bottom, int clipBehavior)
void pushOffset(Dart_Handle layer_handle, double dx, double dy)
sk_sp< SkPicture > picture() const
Definition: picture.h:30
void pushPhysicalShape(Dart_Handle layer_handle, const CanvasPath *path, double elevation, int color, int shadowColor, int clipBehavior)
#define DART_NATIVE_CALLBACK(CLASS, METHOD)
void pushShaderMask(Dart_Handle layer_handle, Shader *shader, double maskRectLeft, double maskRectRight, double maskRectTop, double maskRectBottom, int blendMode)
void build(Dart_Handle scene_handle)
static fml::RefPtr< SceneBuilder > create()
Definition: scene_builder.h:35
static void RegisterNatives(tonic::DartLibraryNatives *natives)
zx_koid_t id() const
Definition: scene_host.h:39
sk_sp< SkShader > shader()
Definition: shader.h:22
IMPLEMENT_WRAPPERTYPEINFO(ui, Scene)
void setRasterizerTracingThreshold(uint32_t frameInterval)
const SkPath & path() const
Definition: path.h:111
void pushImageFilter(Dart_Handle layer_handle, const ImageFilter *image_filter)
void pushClipPath(Dart_Handle layer_handle, const CanvasPath *path, int clipBehavior)
int32_t height
void Register(std::initializer_list< Entry > entries)
int32_t width
static void ThrowIfUIOperationsProhibited()
void pushBackdropFilter(Dart_Handle layer_handle, ImageFilter *filter)
void setCheckerboardOffscreenLayers(bool checkerboard)
static void SceneBuilder_constructor(Dart_NativeArguments args)
void addPicture(double dx, double dy, Picture *picture, int hints)
static fml::RefPtr< EngineLayer > MakeRetained(std::shared_ptr< flutter::ContainerLayer > layer)
Definition: engine_layer.h:27
void addPerformanceOverlay(uint64_t enabledOptions, double left, double right, double top, double bottom)
const sk_sp< SkImageFilter > & filter() const
Definition: image_filter.h:29
#define FOR_EACH_BINDING(V)
#define DART_REGISTER_NATIVE(CLASS, METHOD)
Clip
Definition: layer.h:41
void pushColorFilter(Dart_Handle layer_handle, const ColorFilter *color_filter)
void addTexture(double dx, double dy, double width, double height, int64_t textureId, bool freeze, int filterQuality)
SkMatrix ToSkMatrix(const tonic::Float64List &matrix4)
Definition: matrix.cc:20
static flutter::SkiaGPUObject< T > CreateGPUObject(sk_sp< T > object)
Definition: ui_dart_state.h:78
sk_sp< SkColorFilter > filter() const
Definition: color_filter.h:42