Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
display_list_deferred_image_gpu_impeller.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_impeller.h"
6
7#include <utility>
8
9#include "flutter/fml/make_copyable.h"
10
11namespace flutter {
12
14 std::unique_ptr<LayerTree> layer_tree,
16 fml::RefPtr<fml::TaskRunner> raster_task_runner) {
18 DlDeferredImageGPUImpeller::ImageWrapper::Make(
19 std::move(layer_tree), std::move(snapshot_delegate),
20 std::move(raster_task_runner))));
21}
22
24 sk_sp<DisplayList> display_list,
25 const SkISize& size,
27 fml::RefPtr<fml::TaskRunner> raster_task_runner) {
29 DlDeferredImageGPUImpeller::ImageWrapper::Make(
30 std::move(display_list), size, std::move(snapshot_delegate),
31 std::move(raster_task_runner))));
32}
33
34DlDeferredImageGPUImpeller::DlDeferredImageGPUImpeller(
35 std::shared_ptr<ImageWrapper> wrapper)
36 : wrapper_(std::move(wrapper)) {}
37
38// |DlImage|
40
41// |DlImage|
45
46// |DlImage|
47std::shared_ptr<impeller::Texture>
49 if (!wrapper_) {
50 return nullptr;
51 }
52 return wrapper_->texture();
53}
54
55// |DlImage|
57 // Impeller doesn't currently implement opaque alpha types.
58 return false;
59}
60
61// |DlImage|
63 return wrapper_ && wrapper_->isTextureBacked();
64}
65
66// |DlImage|
68 return true;
69}
70
71// |DlImage|
73 if (!wrapper_) {
74 return SkISize::MakeEmpty();
75 }
76 return wrapper_->size();
77}
78
79// |DlImage|
81 auto size = sizeof(DlDeferredImageGPUImpeller);
82 if (wrapper_) {
83 if (wrapper_->texture()) {
84 size += wrapper_->texture()
85 ->GetTextureDescriptor()
86 .GetByteSizeOfBaseMipLevel();
87 } else {
88 size += wrapper_->size().width() * wrapper_->size().height() * 4;
89 }
90 }
91 return size;
92}
93
94std::shared_ptr<DlDeferredImageGPUImpeller::ImageWrapper>
95DlDeferredImageGPUImpeller::ImageWrapper::Make(
96 sk_sp<DisplayList> display_list,
97 const SkISize& size,
99 fml::RefPtr<fml::TaskRunner> raster_task_runner) {
100 auto wrapper = std::shared_ptr<ImageWrapper>(new ImageWrapper(
101 std::move(display_list), size, std::move(snapshot_delegate),
102 std::move(raster_task_runner)));
103 wrapper->SnapshotDisplayList();
104 return wrapper;
105}
106
107std::shared_ptr<DlDeferredImageGPUImpeller::ImageWrapper>
108DlDeferredImageGPUImpeller::ImageWrapper::Make(
109 std::unique_ptr<LayerTree> layer_tree,
111 fml::RefPtr<fml::TaskRunner> raster_task_runner) {
112 auto wrapper = std::shared_ptr<ImageWrapper>(new ImageWrapper(
113 nullptr, layer_tree->frame_size(), std::move(snapshot_delegate),
114 std::move(raster_task_runner)));
115 wrapper->SnapshotDisplayList(std::move(layer_tree));
116 return wrapper;
117}
118
119DlDeferredImageGPUImpeller::ImageWrapper::ImageWrapper(
120 sk_sp<DisplayList> display_list,
121 const SkISize& size,
123 fml::RefPtr<fml::TaskRunner> raster_task_runner)
124 : size_(size),
125 display_list_(std::move(display_list)),
126 snapshot_delegate_(std::move(snapshot_delegate)),
127 raster_task_runner_(std::move(raster_task_runner)) {}
128
129DlDeferredImageGPUImpeller::ImageWrapper::~ImageWrapper() {
131 raster_task_runner_, [id = reinterpret_cast<uintptr_t>(this),
132 texture_registry = std::move(texture_registry_)]() {
133 if (texture_registry) {
134 texture_registry->UnregisterContextListener(id);
135 }
136 });
137}
138
139void DlDeferredImageGPUImpeller::ImageWrapper::OnGrContextCreated() {
140 FML_DCHECK(raster_task_runner_->RunsTasksOnCurrentThread());
141 SnapshotDisplayList();
142}
143
144void DlDeferredImageGPUImpeller::ImageWrapper::OnGrContextDestroyed() {
145 // Impeller textures do not have threading requirements for deletion, and
146 texture_.reset();
147}
148
149bool DlDeferredImageGPUImpeller::ImageWrapper::isTextureBacked() const {
150 return texture_ && texture_->IsValid();
151}
152
153void DlDeferredImageGPUImpeller::ImageWrapper::SnapshotDisplayList(
154 std::unique_ptr<LayerTree> layer_tree) {
156 raster_task_runner_,
157 fml::MakeCopyable([weak_this = weak_from_this(),
158 layer_tree = std::move(layer_tree)]() {
159 TRACE_EVENT0("flutter", "SnapshotDisplayList (impeller)");
160 auto wrapper = weak_this.lock();
161 if (!wrapper) {
162 return;
163 }
164 auto snapshot_delegate = wrapper->snapshot_delegate_;
165 if (!snapshot_delegate) {
166 return;
167 }
168
169 wrapper->texture_registry_ = snapshot_delegate->GetTextureRegistry();
170 wrapper->texture_registry_->RegisterContextListener(
171 reinterpret_cast<uintptr_t>(wrapper.get()), weak_this);
172
173 if (layer_tree) {
174 wrapper->display_list_ = layer_tree->Flatten(
175 SkRect::MakeWH(wrapper->size_.width(), wrapper->size_.height()),
176 wrapper->texture_registry_);
177 }
178 auto snapshot = snapshot_delegate->MakeRasterSnapshot(
179 wrapper->display_list_, wrapper->size_);
180 if (!snapshot) {
181 std::scoped_lock lock(wrapper->error_mutex_);
182 wrapper->error_ = "Failed to create snapshot.";
183 return;
184 }
185 wrapper->texture_ = snapshot->impeller_texture();
186 }));
187}
188
189std::optional<std::string>
190DlDeferredImageGPUImpeller::ImageWrapper::get_error() {
191 std::scoped_lock lock(error_mutex_);
192 return error_;
193}
194
195} // namespace flutter
bool isUIThreadSafe() const override
If the underlying platform image held by this object has no threading requirements for the release of...
bool isOpaque() const override
If the pixel format of this image ignores alpha, this returns true. This method might conservatively ...
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::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....
static sk_sp< DlDeferredImageGPUImpeller > Make(std::unique_ptr< LayerTree > layer_tree, fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > snapshot_delegate, fml::RefPtr< fml::TaskRunner > raster_task_runner)
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:103
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259
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
#define TRACE_EVENT0(category_group, name)