Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
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#if !SLIMPELLER
6
8
10#include "third_party/skia/include/core/SkColorSpace.h"
11#include "third_party/skia/include/core/SkImage.h"
12#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h"
13
14namespace flutter {
15
16sk_sp<DlDeferredImageGPUSkia> DlDeferredImageGPUSkia::Make(
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) {
22 return sk_sp<DlDeferredImageGPUSkia>(new DlDeferredImageGPUSkia(
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
29sk_sp<DlDeferredImageGPUSkia> DlDeferredImageGPUSkia::MakeFromLayerTree(
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) {
35 return sk_sp<DlDeferredImageGPUSkia>(new DlDeferredImageGPUSkia(
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 : DlImageSkia(nullptr),
46 image_wrapper_(std::move(image_wrapper)),
47 raster_task_runner_(std::move(raster_task_runner)) {}
48
49// |DlImage|
51 fml::TaskRunner::RunNowOrPostTask(raster_task_runner_,
52 [image_wrapper = image_wrapper_]() {
53 if (!image_wrapper) {
54 return;
55 }
56 image_wrapper->Unregister();
57 image_wrapper->DeleteTexture();
58 });
59}
60
61// |DlImageSkia|
62sk_sp<SkImage> DlDeferredImageGPUSkia::skia_image() const {
63 return image_wrapper_ ? image_wrapper_->CreateSkiaImage() : nullptr;
64};
65
66// |DlImage|
68 return image_wrapper_ ? image_wrapper_->image_info().isOpaque() : false;
69}
70
71// |DlImage|
73 return true;
74}
75
76// |DlImage|
78 return image_wrapper_ ? ToDlISize(image_wrapper_->image_info().dimensions())
79 : DlISize();
80}
81
82// |DlImage|
84 return sizeof(*this) +
85 (image_wrapper_ ? image_wrapper_->image_info().computeMinByteSize()
86 : 0);
87}
88
89std::optional<std::string> DlDeferredImageGPUSkia::get_error() const {
90 return image_wrapper_ ? image_wrapper_->get_error() : std::nullopt;
91}
92
93std::shared_ptr<DlDeferredImageGPUSkia::ImageWrapper>
94DlDeferredImageGPUSkia::ImageWrapper::Make(
95 const SkImageInfo& image_info,
96 sk_sp<DisplayList> display_list,
98 fml::RefPtr<fml::TaskRunner> raster_task_runner,
99 fml::RefPtr<SkiaUnrefQueue> unref_queue) {
100 auto wrapper = std::shared_ptr<ImageWrapper>(new ImageWrapper(
101 image_info, std::move(display_list), std::move(snapshot_delegate),
102 std::move(raster_task_runner), std::move(unref_queue)));
103 wrapper->SnapshotDisplayList();
104 return wrapper;
105}
106
107std::shared_ptr<DlDeferredImageGPUSkia::ImageWrapper>
108DlDeferredImageGPUSkia::ImageWrapper::MakeFromLayerTree(
109 const SkImageInfo& image_info,
110 std::unique_ptr<LayerTree> layer_tree,
112 fml::RefPtr<fml::TaskRunner> raster_task_runner,
113 fml::RefPtr<SkiaUnrefQueue> unref_queue) {
114 auto wrapper = std::shared_ptr<ImageWrapper>(
115 new ImageWrapper(image_info, nullptr, std::move(snapshot_delegate),
116 std::move(raster_task_runner), std::move(unref_queue)));
117 wrapper->SnapshotDisplayList(std::move(layer_tree));
118 return wrapper;
119}
120
121DlDeferredImageGPUSkia::ImageWrapper::ImageWrapper(
122 const SkImageInfo& image_info,
123 sk_sp<DisplayList> display_list,
125 fml::RefPtr<fml::TaskRunner> raster_task_runner,
126 fml::RefPtr<SkiaUnrefQueue> unref_queue)
127 : image_info_(image_info),
128 display_list_(std::move(display_list)),
129 snapshot_delegate_(std::move(snapshot_delegate)),
130 raster_task_runner_(std::move(raster_task_runner)),
131 unref_queue_(std::move(unref_queue)) {}
132
133void DlDeferredImageGPUSkia::ImageWrapper::OnGrContextCreated() {
134 FML_DCHECK(raster_task_runner_->RunsTasksOnCurrentThread());
135 SnapshotDisplayList();
136}
137
138void DlDeferredImageGPUSkia::ImageWrapper::OnGrContextDestroyed() {
139 FML_DCHECK(raster_task_runner_->RunsTasksOnCurrentThread());
140 DeleteTexture();
141}
142
143sk_sp<SkImage> DlDeferredImageGPUSkia::ImageWrapper::CreateSkiaImage() const {
144 FML_DCHECK(raster_task_runner_->RunsTasksOnCurrentThread());
145
146 if (texture_.isValid() && context_) {
147 return SkImages::BorrowTextureFrom(
148 context_.get(), texture_, kTopLeft_GrSurfaceOrigin,
149 image_info_.colorType(), image_info_.alphaType(),
150 image_info_.refColorSpace());
151 }
152 return image_;
153}
154
155void DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList(
156 std::unique_ptr<LayerTree> layer_tree) {
158 raster_task_runner_,
159 fml::MakeCopyable([weak_this = weak_from_this(),
160 layer_tree = std::move(layer_tree)]() mutable {
161 auto wrapper = weak_this.lock();
162 if (!wrapper) {
163 return;
164 }
165 auto snapshot_delegate = wrapper->snapshot_delegate_;
166 if (!snapshot_delegate) {
167 return;
168 }
169 if (layer_tree) {
170 auto display_list =
171 layer_tree->Flatten(DlRect::MakeWH(wrapper->image_info_.width(),
172 wrapper->image_info_.height()),
173 snapshot_delegate->GetTextureRegistry(),
174 snapshot_delegate->GetGrContext());
175 wrapper->display_list_ = std::move(display_list);
176 }
177 auto result = snapshot_delegate->MakeSkiaGpuImage(
178 wrapper->display_list_, wrapper->image_info_);
179 if (result->texture.isValid()) {
180 wrapper->texture_ = result->texture;
181 wrapper->context_ = std::move(result->context);
182 wrapper->texture_registry_ =
183 wrapper->snapshot_delegate_->GetTextureRegistry();
184 wrapper->texture_registry_->RegisterContextListener(
185 reinterpret_cast<uintptr_t>(wrapper.get()), weak_this);
186 } else if (result->image) {
187 wrapper->image_ = std::move(result->image);
188 } else {
189 std::scoped_lock lock(wrapper->error_mutex_);
190 wrapper->error_ = result->error;
191 }
192 }));
193}
194
195std::optional<std::string> DlDeferredImageGPUSkia::ImageWrapper::get_error() {
196 std::scoped_lock lock(error_mutex_);
197 return error_;
198}
199
200void DlDeferredImageGPUSkia::ImageWrapper::Unregister() {
201 if (texture_registry_) {
202 texture_registry_->UnregisterContextListener(
203 reinterpret_cast<uintptr_t>(this));
204 }
205}
206
207void DlDeferredImageGPUSkia::ImageWrapper::DeleteTexture() {
208 if (texture_.isValid()) {
209 unref_queue_->DeleteTexture(texture_);
210 texture_ = GrBackendTexture();
211 }
212 image_.reset();
213 context_.reset();
214}
215
216} // namespace flutter
217
218#endif // !SLIMPELLER
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)
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_
#define FML_DCHECK(condition)
Definition logging.h:122
const DlISize & ToDlISize(const SkISize &size)
impeller::ISize32 DlISize
internal::CopyableLambda< T > MakeCopyable(T lambda)
Definition ref_ptr.h:261
static constexpr TRect MakeWH(Type width, Type height)
Definition rect.h:140