Flutter Engine
The Flutter Engine
display_list_deferred_image_gpu_skia.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#if !SLIMPELLER
6
7#include "flutter/lib/ui/painting/display_list_deferred_image_gpu_skia.h"
8
9#include "flutter/fml/make_copyable.h"
13
14namespace flutter {
15
17 const SkImageInfo& image_info,
18 sk_sp<DisplayList> display_list,
20 const fml::RefPtr<fml::TaskRunner>& raster_task_runner,
21 fml::RefPtr<SkiaUnrefQueue> unref_queue) {
23 ImageWrapper::Make(image_info, std::move(display_list),
24 std::move(snapshot_delegate), raster_task_runner,
25 std::move(unref_queue)),
26 raster_task_runner));
27}
28
30 const SkImageInfo& image_info,
31 std::unique_ptr<LayerTree> layer_tree,
33 const fml::RefPtr<fml::TaskRunner>& raster_task_runner,
34 fml::RefPtr<SkiaUnrefQueue> unref_queue) {
36 ImageWrapper::MakeFromLayerTree(
37 image_info, std::move(layer_tree), std::move(snapshot_delegate),
38 raster_task_runner, std::move(unref_queue)),
39 raster_task_runner));
40}
41
42DlDeferredImageGPUSkia::DlDeferredImageGPUSkia(
43 std::shared_ptr<ImageWrapper> image_wrapper,
44 fml::RefPtr<fml::TaskRunner> raster_task_runner)
45 : image_wrapper_(std::move(image_wrapper)),
46 raster_task_runner_(std::move(raster_task_runner)) {}
47
48// |DlImage|
50 fml::TaskRunner::RunNowOrPostTask(raster_task_runner_,
51 [image_wrapper = image_wrapper_]() {
52 if (!image_wrapper) {
53 return;
54 }
55 image_wrapper->Unregister();
56 image_wrapper->DeleteTexture();
57 });
58}
59
60// |DlImage|
62 return image_wrapper_ ? image_wrapper_->CreateSkiaImage() : nullptr;
63};
64
65// |DlImage|
66std::shared_ptr<impeller::Texture> DlDeferredImageGPUSkia::impeller_texture()
67 const {
68 return nullptr;
69}
70
71// |DlImage|
73 return image_wrapper_ ? image_wrapper_->image_info().isOpaque() : false;
74}
75
76// |DlImage|
78 return image_wrapper_ ? image_wrapper_->isTextureBacked() : false;
79}
80
81// |DlImage|
83 return true;
84}
85
86// |DlImage|
88 return image_wrapper_ ? image_wrapper_->image_info().dimensions()
90}
91
92// |DlImage|
94 return sizeof(*this) +
95 (image_wrapper_ ? image_wrapper_->image_info().computeMinByteSize()
96 : 0);
97}
98
99std::optional<std::string> DlDeferredImageGPUSkia::get_error() const {
100 return image_wrapper_ ? image_wrapper_->get_error() : std::nullopt;
101}
102
103std::shared_ptr<DlDeferredImageGPUSkia::ImageWrapper>
105 const SkImageInfo& image_info,
106 sk_sp<DisplayList> display_list,
108 fml::RefPtr<fml::TaskRunner> raster_task_runner,
109 fml::RefPtr<SkiaUnrefQueue> unref_queue) {
110 auto wrapper = std::shared_ptr<ImageWrapper>(new ImageWrapper(
111 image_info, std::move(display_list), std::move(snapshot_delegate),
112 std::move(raster_task_runner), std::move(unref_queue)));
113 wrapper->SnapshotDisplayList();
114 return wrapper;
115}
116
117std::shared_ptr<DlDeferredImageGPUSkia::ImageWrapper>
118DlDeferredImageGPUSkia::ImageWrapper::MakeFromLayerTree(
119 const SkImageInfo& image_info,
120 std::unique_ptr<LayerTree> layer_tree,
122 fml::RefPtr<fml::TaskRunner> raster_task_runner,
123 fml::RefPtr<SkiaUnrefQueue> unref_queue) {
124 auto wrapper = std::shared_ptr<ImageWrapper>(
125 new ImageWrapper(image_info, nullptr, std::move(snapshot_delegate),
126 std::move(raster_task_runner), std::move(unref_queue)));
127 wrapper->SnapshotDisplayList(std::move(layer_tree));
128 return wrapper;
129}
130
131DlDeferredImageGPUSkia::ImageWrapper::ImageWrapper(
132 const SkImageInfo& image_info,
133 sk_sp<DisplayList> display_list,
135 fml::RefPtr<fml::TaskRunner> raster_task_runner,
136 fml::RefPtr<SkiaUnrefQueue> unref_queue)
137 : image_info_(image_info),
138 display_list_(std::move(display_list)),
139 snapshot_delegate_(std::move(snapshot_delegate)),
140 raster_task_runner_(std::move(raster_task_runner)),
141 unref_queue_(std::move(unref_queue)) {}
142
143void DlDeferredImageGPUSkia::ImageWrapper::OnGrContextCreated() {
144 FML_DCHECK(raster_task_runner_->RunsTasksOnCurrentThread());
145 SnapshotDisplayList();
146}
147
148void DlDeferredImageGPUSkia::ImageWrapper::OnGrContextDestroyed() {
149 FML_DCHECK(raster_task_runner_->RunsTasksOnCurrentThread());
150 DeleteTexture();
151}
152
153sk_sp<SkImage> DlDeferredImageGPUSkia::ImageWrapper::CreateSkiaImage() const {
154 FML_DCHECK(raster_task_runner_->RunsTasksOnCurrentThread());
155
156 if (texture_.isValid() && context_) {
158 context_.get(), texture_, kTopLeft_GrSurfaceOrigin,
159 image_info_.colorType(), image_info_.alphaType(),
160 image_info_.refColorSpace());
161 }
162 return image_;
163}
164
165bool DlDeferredImageGPUSkia::ImageWrapper::isTextureBacked() const {
166 return texture_.isValid();
167}
168
169void DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList(
170 std::unique_ptr<LayerTree> layer_tree) {
172 raster_task_runner_,
173 fml::MakeCopyable([weak_this = weak_from_this(),
174 layer_tree = std::move(layer_tree)]() mutable {
175 auto wrapper = weak_this.lock();
176 if (!wrapper) {
177 return;
178 }
179 auto snapshot_delegate = wrapper->snapshot_delegate_;
180 if (!snapshot_delegate) {
181 return;
182 }
183 if (layer_tree) {
184 auto display_list =
185 layer_tree->Flatten(SkRect::MakeWH(wrapper->image_info_.width(),
186 wrapper->image_info_.height()),
187 snapshot_delegate->GetTextureRegistry(),
188 snapshot_delegate->GetGrContext());
189 wrapper->display_list_ = std::move(display_list);
190 }
191 auto result = snapshot_delegate->MakeSkiaGpuImage(
192 wrapper->display_list_, wrapper->image_info_);
193 if (result->texture.isValid()) {
194 wrapper->texture_ = result->texture;
195 wrapper->context_ = std::move(result->context);
196 wrapper->texture_registry_ =
197 wrapper->snapshot_delegate_->GetTextureRegistry();
198 wrapper->texture_registry_->RegisterContextListener(
199 reinterpret_cast<uintptr_t>(wrapper.get()), weak_this);
200 } else if (result->image) {
201 wrapper->image_ = std::move(result->image);
202 } else {
203 std::scoped_lock lock(wrapper->error_mutex_);
204 wrapper->error_ = result->error;
205 }
206 }));
207}
208
209std::optional<std::string> DlDeferredImageGPUSkia::ImageWrapper::get_error() {
210 std::scoped_lock lock(error_mutex_);
211 return error_;
212}
213
214void DlDeferredImageGPUSkia::ImageWrapper::Unregister() {
215 if (texture_registry_) {
216 texture_registry_->UnregisterContextListener(
217 reinterpret_cast<uintptr_t>(this));
218 }
219}
220
221void DlDeferredImageGPUSkia::ImageWrapper::DeleteTexture() {
222 if (texture_.isValid()) {
223 unref_queue_->DeleteTexture(texture_);
224 texture_ = GrBackendTexture();
225 }
226 image_.reset();
227 context_.reset();
228}
229
230} // namespace flutter
231
232#endif // !SLIMPELLER
@ kTopLeft_GrSurfaceOrigin
Definition: GrTypes.h:148
sk_sp< SkImage > skia_image() const override
If this display list image is meant to be used by the Skia backend, an SkImage instance....
std::optional< std::string > get_error() const override
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)
std::shared_ptr< impeller::Texture > impeller_texture() const override
If this display list image is meant to be used by the Impeller backend, an Impeller texture instance....
bool isOpaque() const override
If the pixel format of this image ignores alpha, this returns true. This method might conservatively ...
static sk_sp< DlDeferredImageGPUSkia > MakeFromLayerTree(const SkImageInfo &image_info, std::unique_ptr< LayerTree > layer_tree, fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > snapshot_delegate, const fml::RefPtr< fml::TaskRunner > &raster_task_runner, fml::RefPtr< SkiaUnrefQueue > unref_queue)
bool isUIThreadSafe() const override
If the underlying platform image held by this object has no threading requirements for the release of...
virtual size_t GetApproximateByteSize() const override
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
Definition: task_runner.cc:55
fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > snapshot_delegate_
if(end==-1)
GAsyncResult * result
#define FML_DCHECK(condition)
Definition: logging.h:103
SK_API sk_sp< SkImage > BorrowTextureFrom(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, SkColorType colorType, SkAlphaType alphaType, sk_sp< SkColorSpace > colorSpace, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
internal::CopyableLambda< T > MakeCopyable(T lambda)
Definition: make_copyable.h:57
Definition: ref_ptr.h:256
Definition: SkSize.h:16
static constexpr SkISize MakeEmpty()
Definition: SkSize.h:22
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609