Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
picture.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/painting/picture.h"
6
7#include <memory>
8#include <utility>
9
10#include "flutter/fml/make_copyable.h"
11#include "flutter/lib/ui/painting/canvas.h"
12#include "flutter/lib/ui/painting/display_list_deferred_image_gpu_skia.h"
13#include "flutter/lib/ui/ui_dart_state.h"
14#if IMPELLER_SUPPORTS_RENDERING
15#include "flutter/lib/ui/painting/display_list_deferred_image_gpu_impeller.h"
16#endif // IMPELLER_SUPPORTS_RENDERING
17#include "flutter/lib/ui/painting/display_list_image_gpu.h"
24
25namespace flutter {
26
28
30 Dart_Handle dart_handle,
31 sk_sp<DisplayList> display_list) {
32 FML_DCHECK(display_list->isUIThreadSafe());
33 auto canvas_picture = fml::MakeRefCounted<Picture>(std::move(display_list));
34 canvas_picture->AssociateWithDartWrapper(dart_handle);
35}
36
37Picture::Picture(sk_sp<DisplayList> display_list)
38 : display_list_(std::move(display_list)) {}
39
40Picture::~Picture() = default;
41
43 uint32_t height,
44 Dart_Handle raw_image_callback) {
45 if (!display_list_) {
46 return tonic::ToDart("Picture is null");
47 }
48 return RasterizeToImage(display_list_, width, height, raw_image_callback);
49}
50
52 uint32_t height,
53 Dart_Handle raw_image_handle) {
54 FML_DCHECK(display_list_);
55 RasterizeToImageSync(display_list_, width, height, raw_image_handle);
56}
57
59 bool impeller,
60 sk_sp<DisplayList> display_list,
61 uint32_t width,
62 uint32_t height,
64 fml::RefPtr<fml::TaskRunner> raster_task_runner,
65 fml::RefPtr<SkiaUnrefQueue> unref_queue) {
66#if IMPELLER_SUPPORTS_RENDERING
67 if (impeller) {
69 std::move(display_list), SkISize::Make(width, height),
70 std::move(snapshot_delegate), std::move(raster_task_runner));
71 }
72#endif // IMPELLER_SUPPORTS_RENDERING
73
74 const SkImageInfo image_info = SkImageInfo::Make(
77 image_info, std::move(display_list), std::move(snapshot_delegate),
78 raster_task_runner, std::move(unref_queue));
79}
80
81// static
83 uint32_t width,
84 uint32_t height,
85 Dart_Handle raw_image_handle) {
86 auto* dart_state = UIDartState::Current();
87 if (!dart_state) {
88 return;
89 }
90 auto unref_queue = dart_state->GetSkiaUnrefQueue();
91 auto snapshot_delegate = dart_state->GetSnapshotDelegate();
92 auto raster_task_runner = dart_state->GetTaskRunners().GetRasterTaskRunner();
93
95 auto dl_image = CreateDeferredImage(
96 dart_state->IsImpellerEnabled(), std::move(display_list), width, height,
97 std::move(snapshot_delegate), std::move(raster_task_runner),
98 std::move(unref_queue));
99 image->set_image(dl_image);
100 image->AssociateWithDartWrapper(raw_image_handle);
101}
102
104 display_list_.reset();
106}
107
109 if (display_list_) {
110 return display_list_->bytes() + sizeof(Picture);
111 } else {
112 return sizeof(Picture);
113 }
114}
115
117 uint32_t width,
118 uint32_t height,
119 Dart_Handle raw_image_callback) {
121 raw_image_callback);
122}
123
125 std::unique_ptr<LayerTree> layer_tree,
126 Dart_Handle raw_image_callback) {
127 FML_DCHECK(layer_tree != nullptr);
128 auto frame_size = layer_tree->frame_size();
129 return DoRasterizeToImage(nullptr, std::move(layer_tree), frame_size.width(),
130 frame_size.height(), raw_image_callback);
131}
132
134 std::unique_ptr<LayerTree> layer_tree,
135 uint32_t width,
136 uint32_t height,
137 Dart_Handle raw_image_callback) {
138 // Either display_list or layer_tree should be provided.
139 FML_DCHECK((display_list == nullptr) != (layer_tree == nullptr));
140
141 if (Dart_IsNull(raw_image_callback) || !Dart_IsClosure(raw_image_callback)) {
142 return tonic::ToDart("Image callback was invalid");
143 }
144
145 if (width == 0 || height == 0) {
146 return tonic::ToDart("Image dimensions for scene were invalid.");
147 }
148
149 auto* dart_state = UIDartState::Current();
150 auto image_callback = std::make_unique<tonic::DartPersistentValue>(
151 dart_state, raw_image_callback);
152 auto unref_queue = dart_state->GetSkiaUnrefQueue();
153 auto ui_task_runner = dart_state->GetTaskRunners().GetUITaskRunner();
154 auto raster_task_runner = dart_state->GetTaskRunners().GetRasterTaskRunner();
155 auto snapshot_delegate = dart_state->GetSnapshotDelegate();
156
157 // We can't create an image on this task runner because we don't have a
158 // graphics context. Even if we did, it would be slow anyway. Also, this
159 // thread owns the sole reference to the layer tree. So we do it in the
160 // raster thread.
161
162 auto ui_task =
163 // The static leak checker gets confused by the use of fml::MakeCopyable.
164 // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
165 fml::MakeCopyable([image_callback = std::move(image_callback),
166 unref_queue](sk_sp<DlImage> image) mutable {
167 auto dart_state = image_callback->dart_state().lock();
168 if (!dart_state) {
169 // The root isolate could have died in the meantime.
170 return;
171 }
172 tonic::DartState::Scope scope(dart_state);
173
174 if (!image) {
175 tonic::DartInvoke(image_callback->Get(), {Dart_Null()});
176 return;
177 }
178
179 if (!image->isUIThreadSafe()) {
180 // All images with impeller textures should already be safe.
181 FML_DCHECK(image->impeller_texture() == nullptr);
182 image =
183 DlImageGPU::Make({image->skia_image(), std::move(unref_queue)});
184 }
185
186 auto dart_image = CanvasImage::Create();
187 dart_image->set_image(image);
188 auto* raw_dart_image = tonic::ToDart(dart_image);
189
190 // All done!
191 tonic::DartInvoke(image_callback->Get(), {raw_dart_image});
192
193 // image_callback is associated with the Dart isolate and must be
194 // deleted on the UI thread.
195 image_callback.reset();
196 });
197
198 // Kick things off on the raster rask runner.
200 raster_task_runner,
201 fml::MakeCopyable([ui_task_runner, snapshot_delegate, display_list, width,
202 height, ui_task,
203 layer_tree = std::move(layer_tree)]() mutable {
204 auto picture_bounds = SkISize::Make(width, height);
206 if (layer_tree) {
207 FML_DCHECK(picture_bounds == layer_tree->frame_size());
208 auto display_list =
209 layer_tree->Flatten(SkRect::MakeWH(width, height),
210 snapshot_delegate->GetTextureRegistry(),
211 snapshot_delegate->GetGrContext());
212
213 image = snapshot_delegate->MakeRasterSnapshot(display_list,
214 picture_bounds);
215 } else {
216 image = snapshot_delegate->MakeRasterSnapshot(display_list,
217 picture_bounds);
218 }
219
221 ui_task_runner, [ui_task, image]() { ui_task(image); });
222 }));
223
224 return Dart_Null();
225}
226
227} // namespace flutter
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
static fml::RefPtr< CanvasImage > Create()
Definition image.h:28
static sk_sp< DlDeferredImageGPUImpeller > Make(std::unique_ptr< LayerTree > layer_tree, fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > snapshot_delegate, fml::RefPtr< fml::TaskRunner > raster_task_runner)
static sk_sp< DlDeferredImageGPUSkia > Make(const SkImageInfo &image_info, sk_sp< DisplayList > display_list, fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > snapshot_delegate, const fml::RefPtr< fml::TaskRunner > &raster_task_runner, fml::RefPtr< SkiaUnrefQueue > unref_queue)
static sk_sp< DlImageGPU > Make(SkiaGPUObject< SkImage > image)
~Picture() override
sk_sp< DisplayList > display_list() const
Definition picture.h:27
static void CreateAndAssociateWithDartWrapper(Dart_Handle dart_handle, sk_sp< DisplayList > display_list)
Definition picture.cc:29
Dart_Handle toImage(uint32_t width, uint32_t height, Dart_Handle raw_image_callback)
Definition picture.cc:42
static Dart_Handle RasterizeLayerTreeToImage(std::unique_ptr< LayerTree > layer_tree, Dart_Handle raw_image_callback)
Definition picture.cc:124
size_t GetAllocationSize() const
Definition picture.cc:108
void toImageSync(uint32_t width, uint32_t height, Dart_Handle raw_image_handle)
Definition picture.cc:51
static Dart_Handle DoRasterizeToImage(const sk_sp< DisplayList > &display_list, std::unique_ptr< LayerTree > layer_tree, uint32_t width, uint32_t height, Dart_Handle raw_image_callback)
Definition picture.cc:133
static Dart_Handle RasterizeToImage(const sk_sp< DisplayList > &display_list, uint32_t width, uint32_t height, Dart_Handle raw_image_callback)
Definition picture.cc:116
static void RasterizeToImageSync(sk_sp< DisplayList > display_list, uint32_t width, uint32_t height, Dart_Handle raw_image_handle)
Definition picture.cc:82
static UIDartState * Current()
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
DART_EXPORT Dart_Handle Dart_Null(void)
DART_EXPORT bool Dart_IsNull(Dart_Handle object)
DART_EXPORT bool Dart_IsClosure(Dart_Handle object)
#define IMPLEMENT_WRAPPERTYPEINFO(LibraryName, ClassName)
sk_sp< SkImage > image
Definition examples.cpp:29
#define FML_DCHECK(condition)
Definition logging.h:103
static sk_sp< DlImage > CreateDeferredImage(bool impeller, std::unique_ptr< LayerTree > layer_tree, fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > snapshot_delegate, fml::RefPtr< fml::TaskRunner > raster_task_runner, fml::RefPtr< SkiaUnrefQueue > unref_queue)
Definition scene.cc:87
internal::CopyableLambda< T > MakeCopyable(T lambda)
Definition ref_ptr.h:256
Dart_Handle ToDart(const T &object)
Dart_Handle DartInvoke(Dart_Handle closure, std::initializer_list< Dart_Handle > args)
int32_t height
int32_t width
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609