66
77#include < atomic>
88
9+ #include " third_party/skia/include/core/SkColorSpace.h"
10+
911namespace flutter {
1012
1113sk_sp<DlDeferredImageGPU> DlDeferredImageGPU::Make (
12- SkISize size ,
14+ const SkImageInfo& image_info ,
1315 fml::RefPtr<fml::TaskRunner> raster_task_runner,
1416 fml::RefPtr<SkiaUnrefQueue> unref_queue) {
1517 return sk_sp<DlDeferredImageGPU>(new DlDeferredImageGPU (
16- size , std::move (raster_task_runner), std::move (unref_queue)));
18+ image_info , std::move (raster_task_runner), std::move (unref_queue)));
1719}
1820
1921DlDeferredImageGPU::DlDeferredImageGPU (
20- SkISize size ,
22+ const SkImageInfo& image_info ,
2123 fml::RefPtr<fml::TaskRunner> raster_task_runner,
2224 fml::RefPtr<SkiaUnrefQueue> unref_queue)
23- : size_(size ),
25+ : image_info_(image_info ),
2426 raster_task_runner_ (std::move(raster_task_runner)),
2527 unref_queue_(std::move(unref_queue)) {}
2628
@@ -33,13 +35,8 @@ DlDeferredImageGPU::~DlDeferredImageGPU() {
3335 if (!image_wrapper) {
3436 return ;
3537 }
36- auto image = image_wrapper->image ;
37- if (image) {
38- GrBackendTexture texture = image->releaseBackendTexture (true );
39- if (!texture.isValid ()) {
40- return ;
41- }
42-
38+ auto texture = image_wrapper->texture ();
39+ if (texture.isValid ()) {
4340 unref_queue->DeleteTexture (std::move (texture));
4441 }
4542 });
@@ -48,7 +45,7 @@ DlDeferredImageGPU::~DlDeferredImageGPU() {
4845// |DlImage|
4946sk_sp<SkImage> DlDeferredImageGPU::skia_image () const {
5047 auto image_wrapper = std::atomic_load (&image_wrapper_);
51- return image_wrapper ? image_wrapper->image : nullptr ;
48+ return image_wrapper ? image_wrapper->CreateSkiaImage (image_info_) : image_ ;
5249};
5350
5451// |DlImage|
@@ -59,42 +56,45 @@ std::shared_ptr<impeller::Texture> DlDeferredImageGPU::impeller_texture()
5956
6057// |DlImage|
6158bool DlDeferredImageGPU::isTextureBacked () const {
62- if (auto image = skia_image ( )) {
63- return image ->isTextureBacked ();
59+ if (auto image_wrapper = std::atomic_load (&image_wrapper_ )) {
60+ return image_wrapper ->isTextureBacked ();
6461 }
6562 return false ;
6663}
6764
6865// |DlImage|
6966SkISize DlDeferredImageGPU::dimensions () const {
70- return size_ ;
67+ return image_info_. dimensions () ;
7168}
7269
7370// |DlImage|
7471size_t DlDeferredImageGPU::GetApproximateByteSize () const {
7572 // This call is accessed on the UI thread, and image_ may not be available
76- // yet. The image is not mipmapped and it's created using N32 pixels, so this
77- // is safe.
78- if (size_.isEmpty ()) {
79- return sizeof (this );
80- }
81- return sizeof (this ) + size_.width () * size_.height () * 4 ;
73+ // yet. The image is not mipmapped.
74+ return sizeof (this ) + image_info_.computeMinByteSize ();
8275}
8376
84- void DlDeferredImageGPU::set_image (
85- sk_sp<SkImage> image,
77+ void DlDeferredImageGPU::set_texture (
78+ const GrBackendTexture& texture,
79+ sk_sp<GrDirectContext> context,
8680 std::shared_ptr<TextureRegistry> texture_registry) {
8781 FML_DCHECK (raster_task_runner_->RunsTasksOnCurrentThread ());
88- FML_DCHECK (image );
89- FML_DCHECK (image-> dimensions () == size_ );
82+ FML_DCHECK (texture. isValid () );
83+ FML_DCHECK (context );
9084
85+ image_ = nullptr ;
9186 auto image_wrapper = std::make_shared<ImageWrapper>(
92- std::move (image ), raster_task_runner_, unref_queue_);
87+ texture, std::move (context ), raster_task_runner_, unref_queue_);
9388 texture_registry_ = std::move (texture_registry);
9489 texture_registry_->RegisterContextDestroyedListener (image_wrapper);
9590 std::atomic_store (&image_wrapper_, image_wrapper);
9691}
9792
93+ void DlDeferredImageGPU::set_image (sk_sp<SkImage> image) {
94+ FML_DCHECK (image && !image->isTextureBacked ());
95+ image_ = std::move (image);
96+ }
97+
9898void DlDeferredImageGPU::set_error (const std::string& error) {
9999 std::scoped_lock lock (error_mutex_);
100100 error_ = std::move (error);
@@ -106,23 +106,36 @@ std::optional<std::string> DlDeferredImageGPU::get_error() const {
106106}
107107
108108DlDeferredImageGPU::ImageWrapper::ImageWrapper (
109- sk_sp<SkImage> p_image,
110- fml::RefPtr<fml::TaskRunner> p_raster_task_runner,
111- fml::RefPtr<SkiaUnrefQueue> p_unref_queue)
112- : image(std::move(p_image)),
113- raster_task_runner (std::move(p_raster_task_runner)),
114- unref_queue(std::move(p_unref_queue)) {}
109+ const GrBackendTexture& texture,
110+ sk_sp<GrDirectContext> context,
111+ fml::RefPtr<fml::TaskRunner> raster_task_runner,
112+ fml::RefPtr<SkiaUnrefQueue> unref_queue)
113+ : texture_(texture),
114+ context_ (std::move(context)),
115+ raster_task_runner_(std::move(raster_task_runner)),
116+ unref_queue_(std::move(unref_queue)) {}
115117
116118void DlDeferredImageGPU::ImageWrapper::OnGrContextDestroyed () {
117- FML_DCHECK (raster_task_runner->RunsTasksOnCurrentThread ());
118- if (image) {
119- GrBackendTexture texture = image->releaseBackendTexture (true );
120- image.reset ();
121- if (!texture.isValid ()) {
122- return ;
123- }
124- unref_queue->DeleteTexture (std::move (texture));
119+ FML_DCHECK (raster_task_runner_->RunsTasksOnCurrentThread ());
120+
121+ if (texture_.isValid ()) {
122+ unref_queue_->DeleteTexture (std::move (texture_));
125123 }
126124}
127125
126+ sk_sp<SkImage> DlDeferredImageGPU::ImageWrapper::CreateSkiaImage (
127+ const SkImageInfo& image_info) {
128+ FML_DCHECK (raster_task_runner_->RunsTasksOnCurrentThread ());
129+ FML_DCHECK (texture_.isValid ());
130+ FML_DCHECK (context_.get ());
131+
132+ return SkImage::MakeFromTexture (
133+ context_.get (), texture_, kTopLeft_GrSurfaceOrigin ,
134+ kRGBA_8888_SkColorType , kPremul_SkAlphaType , image_info.refColorSpace ());
135+ }
136+
137+ bool DlDeferredImageGPU::ImageWrapper::isTextureBacked () {
138+ return texture_.isValid ();
139+ }
140+
128141} // namespace flutter
0 commit comments