Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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#include "flutter/lib/ui/painting/display_list_deferred_image_gpu_skia.h"
6
7#include "flutter/fml/make_copyable.h"
11
12namespace flutter {
13
15 const SkImageInfo& image_info,
16 sk_sp<DisplayList> display_list,
18 const fml::RefPtr<fml::TaskRunner>& raster_task_runner,
19 fml::RefPtr<SkiaUnrefQueue> unref_queue) {
21 ImageWrapper::Make(image_info, std::move(display_list),
22 std::move(snapshot_delegate), raster_task_runner,
23 std::move(unref_queue)),
24 raster_task_runner));
25}
26
28 const SkImageInfo& image_info,
29 std::unique_ptr<LayerTree> layer_tree,
31 const fml::RefPtr<fml::TaskRunner>& raster_task_runner,
32 fml::RefPtr<SkiaUnrefQueue> unref_queue) {
34 ImageWrapper::MakeFromLayerTree(
35 image_info, std::move(layer_tree), std::move(snapshot_delegate),
36 raster_task_runner, std::move(unref_queue)),
37 raster_task_runner));
38}
39
40DlDeferredImageGPUSkia::DlDeferredImageGPUSkia(
41 std::shared_ptr<ImageWrapper> image_wrapper,
42 fml::RefPtr<fml::TaskRunner> raster_task_runner)
43 : image_wrapper_(std::move(image_wrapper)),
44 raster_task_runner_(std::move(raster_task_runner)) {}
45
46// |DlImage|
48 fml::TaskRunner::RunNowOrPostTask(raster_task_runner_,
49 [image_wrapper = image_wrapper_]() {
50 if (!image_wrapper) {
51 return;
52 }
53 image_wrapper->Unregister();
54 image_wrapper->DeleteTexture();
55 });
56}
57
58// |DlImage|
60 return image_wrapper_ ? image_wrapper_->CreateSkiaImage() : nullptr;
61};
62
63// |DlImage|
64std::shared_ptr<impeller::Texture> DlDeferredImageGPUSkia::impeller_texture()
65 const {
66 return nullptr;
67}
68
69// |DlImage|
71 return image_wrapper_ ? image_wrapper_->image_info().isOpaque() : false;
72}
73
74// |DlImage|
76 return image_wrapper_ ? image_wrapper_->isTextureBacked() : false;
77}
78
79// |DlImage|
81 return true;
82}
83
84// |DlImage|
86 return image_wrapper_ ? image_wrapper_->image_info().dimensions()
88}
89
90// |DlImage|
92 return sizeof(*this) +
93 (image_wrapper_ ? image_wrapper_->image_info().computeMinByteSize()
94 : 0);
95}
96
97std::optional<std::string> DlDeferredImageGPUSkia::get_error() const {
98 return image_wrapper_ ? image_wrapper_->get_error() : std::nullopt;
99}
100
101std::shared_ptr<DlDeferredImageGPUSkia::ImageWrapper>
102DlDeferredImageGPUSkia::ImageWrapper::Make(
103 const SkImageInfo& image_info,
104 sk_sp<DisplayList> display_list,
106 fml::RefPtr<fml::TaskRunner> raster_task_runner,
107 fml::RefPtr<SkiaUnrefQueue> unref_queue) {
108 auto wrapper = std::shared_ptr<ImageWrapper>(new ImageWrapper(
109 image_info, std::move(display_list), std::move(snapshot_delegate),
110 std::move(raster_task_runner), std::move(unref_queue)));
111 wrapper->SnapshotDisplayList();
112 return wrapper;
113}
114
115std::shared_ptr<DlDeferredImageGPUSkia::ImageWrapper>
116DlDeferredImageGPUSkia::ImageWrapper::MakeFromLayerTree(
117 const SkImageInfo& image_info,
118 std::unique_ptr<LayerTree> layer_tree,
120 fml::RefPtr<fml::TaskRunner> raster_task_runner,
121 fml::RefPtr<SkiaUnrefQueue> unref_queue) {
122 auto wrapper = std::shared_ptr<ImageWrapper>(
123 new ImageWrapper(image_info, nullptr, std::move(snapshot_delegate),
124 std::move(raster_task_runner), std::move(unref_queue)));
125 wrapper->SnapshotDisplayList(std::move(layer_tree));
126 return wrapper;
127}
128
129DlDeferredImageGPUSkia::ImageWrapper::ImageWrapper(
130 const SkImageInfo& image_info,
131 sk_sp<DisplayList> display_list,
133 fml::RefPtr<fml::TaskRunner> raster_task_runner,
134 fml::RefPtr<SkiaUnrefQueue> unref_queue)
135 : image_info_(image_info),
136 display_list_(std::move(display_list)),
137 snapshot_delegate_(std::move(snapshot_delegate)),
138 raster_task_runner_(std::move(raster_task_runner)),
139 unref_queue_(std::move(unref_queue)) {}
140
141void DlDeferredImageGPUSkia::ImageWrapper::OnGrContextCreated() {
142 FML_DCHECK(raster_task_runner_->RunsTasksOnCurrentThread());
143 SnapshotDisplayList();
144}
145
146void DlDeferredImageGPUSkia::ImageWrapper::OnGrContextDestroyed() {
147 FML_DCHECK(raster_task_runner_->RunsTasksOnCurrentThread());
148 DeleteTexture();
149}
150
151sk_sp<SkImage> DlDeferredImageGPUSkia::ImageWrapper::CreateSkiaImage() const {
152 FML_DCHECK(raster_task_runner_->RunsTasksOnCurrentThread());
153
154 if (texture_.isValid() && context_) {
156 context_.get(), texture_, kTopLeft_GrSurfaceOrigin,
157 image_info_.colorType(), image_info_.alphaType(),
158 image_info_.refColorSpace());
159 }
160 return image_;
161}
162
163bool DlDeferredImageGPUSkia::ImageWrapper::isTextureBacked() const {
164 return texture_.isValid();
165}
166
167void DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList(
168 std::unique_ptr<LayerTree> layer_tree) {
170 raster_task_runner_,
171 fml::MakeCopyable([weak_this = weak_from_this(),
172 layer_tree = std::move(layer_tree)]() mutable {
173 auto wrapper = weak_this.lock();
174 if (!wrapper) {
175 return;
176 }
177 auto snapshot_delegate = wrapper->snapshot_delegate_;
178 if (!snapshot_delegate) {
179 return;
180 }
181 if (layer_tree) {
182 auto display_list =
183 layer_tree->Flatten(SkRect::MakeWH(wrapper->image_info_.width(),
184 wrapper->image_info_.height()),
185 snapshot_delegate->GetTextureRegistry(),
186 snapshot_delegate->GetGrContext());
187 wrapper->display_list_ = std::move(display_list);
188 }
189 auto result = snapshot_delegate->MakeSkiaGpuImage(
190 wrapper->display_list_, wrapper->image_info_);
191 if (result->texture.isValid()) {
192 wrapper->texture_ = result->texture;
193 wrapper->context_ = std::move(result->context);
194 wrapper->texture_registry_ =
195 wrapper->snapshot_delegate_->GetTextureRegistry();
196 wrapper->texture_registry_->RegisterContextListener(
197 reinterpret_cast<uintptr_t>(wrapper.get()), weak_this);
198 } else if (result->image) {
199 wrapper->image_ = std::move(result->image);
200 } else {
201 std::scoped_lock lock(wrapper->error_mutex_);
202 wrapper->error_ = result->error;
203 }
204 }));
205}
206
207std::optional<std::string> DlDeferredImageGPUSkia::ImageWrapper::get_error() {
208 std::scoped_lock lock(error_mutex_);
209 return error_;
210}
211
212void DlDeferredImageGPUSkia::ImageWrapper::Unregister() {
213 if (texture_registry_) {
214 texture_registry_->UnregisterContextListener(
215 reinterpret_cast<uintptr_t>(this));
216 }
217}
218
219void DlDeferredImageGPUSkia::ImageWrapper::DeleteTexture() {
220 if (texture_.isValid()) {
221 unref_queue_->DeleteTexture(texture_);
222 texture_ = GrBackendTexture();
223 }
224 image_.reset();
225 context_.reset();
226}
227
228} // namespace flutter
@ 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)
fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > snapshot_delegate_
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)
internal::CopyableLambda< T > MakeCopyable(T lambda)
Definition ref_ptr.h:256
static constexpr SkISize MakeEmpty()
Definition SkSize.h:22
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609