Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit d62aa95

Browse files
authored
[Impeller] Support multi-frame codecs (#36792)
1 parent 03756d2 commit d62aa95

File tree

4 files changed

+51
-19
lines changed

4 files changed

+51
-19
lines changed

lib/ui/painting/image_decoder_impeller.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ std::shared_ptr<SkBitmap> ImageDecoderImpeller::DecompressTexture(
137137
return scaled_bitmap;
138138
}
139139

140-
static sk_sp<DlImage> UploadTexture(
140+
sk_sp<DlImage> ImageDecoderImpeller::UploadTexture(
141141
const std::shared_ptr<impeller::Context>& context,
142142
std::shared_ptr<SkBitmap> bitmap) {
143143
TRACE_EVENT0("impeller", __FUNCTION__);

lib/ui/painting/image_decoder_impeller.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ class ImageDecoderImpeller final : public ImageDecoder {
3737
SkISize target_size,
3838
impeller::ISize max_texture_size);
3939

40+
static sk_sp<DlImage> UploadTexture(
41+
const std::shared_ptr<impeller::Context>& context,
42+
std::shared_ptr<SkBitmap> bitmap);
43+
4044
private:
4145
using FutureContext = std::shared_future<std::shared_ptr<impeller::Context>>;
4246
FutureContext context_;

lib/ui/painting/multi_frame_codec.cc

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
#include "flutter/fml/make_copyable.h"
1010
#include "flutter/lib/ui/painting/image.h"
11+
#if IMPELLER_SUPPORTS_RENDERING
12+
#include "lib/ui/painting/image_decoder_impeller.h"
13+
#endif // IMPELLER_SUPPORTS_RENDERING
1114
#include "third_party/dart/runtime/include/dart_api.h"
1215
#include "third_party/skia/include/core/SkPixelRef.h"
1316
#include "third_party/tonic/logging/dart_invoke.h"
@@ -26,6 +29,7 @@ MultiFrameCodec::State::State(std::shared_ptr<ImageGenerator> generator)
2629
ImageGenerator::kInfinitePlayCount
2730
? -1
2831
: generator_->GetPlayCount() - 1),
32+
is_impeller_enabled_(UIDartState::Current()->IsImpellerEnabled()),
2933
nextFrameIndex_(0) {}
3034

3135
static void InvokeNextFrameCallback(
@@ -77,9 +81,11 @@ static bool CopyToBitmap(SkBitmap* dst,
7781
return true;
7882
}
7983

80-
sk_sp<SkImage> MultiFrameCodec::State::GetNextFrameImage(
84+
sk_sp<DlImage> MultiFrameCodec::State::GetNextFrameImage(
8185
fml::WeakPtr<GrDirectContext> resourceContext,
82-
const std::shared_ptr<const fml::SyncSwitch>& gpu_disable_sync_switch) {
86+
const std::shared_ptr<const fml::SyncSwitch>& gpu_disable_sync_switch,
87+
std::shared_ptr<impeller::Context> impeller_context_,
88+
fml::RefPtr<flutter::SkiaUnrefQueue> unref_queue) {
8389
SkBitmap bitmap = SkBitmap();
8490
SkImageInfo info = generator_->GetInfo().makeColorType(kN32_SkColorType);
8591
if (info.alphaType() == kUnpremul_SkAlphaType) {
@@ -125,30 +131,45 @@ sk_sp<SkImage> MultiFrameCodec::State::GetNextFrameImage(
125131
lastRequiredFrame_ = std::make_unique<SkBitmap>(bitmap);
126132
lastRequiredFrameIndex_ = nextFrameIndex_;
127133
}
128-
sk_sp<SkImage> result;
129134

135+
#if IMPELLER_SUPPORTS_RENDERING
136+
if (is_impeller_enabled_) {
137+
sk_sp<DlImage> result;
138+
// impeller, transfer to DlImageImpeller
139+
gpu_disable_sync_switch->Execute(fml::SyncSwitch::Handlers().SetIfFalse(
140+
[&result, &bitmap, &impeller_context_] {
141+
result = ImageDecoderImpeller::UploadTexture(
142+
impeller_context_, std::make_shared<SkBitmap>(bitmap));
143+
}));
144+
145+
return result;
146+
}
147+
#endif // IMPELLER_SUPPORTS_RENDERING
148+
149+
sk_sp<SkImage> skImage;
130150
gpu_disable_sync_switch->Execute(
131151
fml::SyncSwitch::Handlers()
132-
.SetIfTrue([&result, &bitmap] {
152+
.SetIfTrue([&skImage, &bitmap] {
133153
// Defer decoding until time of draw later on the raster thread. Can
134154
// happen when GL operations are currently forbidden such as in the
135155
// background on iOS.
136-
result = SkImage::MakeFromBitmap(bitmap);
156+
skImage = SkImage::MakeFromBitmap(bitmap);
137157
})
138-
.SetIfFalse([&result, &resourceContext, &bitmap] {
158+
.SetIfFalse([&skImage, &resourceContext, &bitmap] {
139159
if (resourceContext) {
140160
SkPixmap pixmap(bitmap.info(), bitmap.pixelRef()->pixels(),
141161
bitmap.pixelRef()->rowBytes());
142-
result = SkImage::MakeCrossContextFromPixmap(
162+
skImage = SkImage::MakeCrossContextFromPixmap(
143163
resourceContext.get(), pixmap, true);
144164
} else {
145165
// Defer decoding until time of draw later on the raster thread.
146166
// Can happen when GL operations are currently forbidden such as
147167
// in the background on iOS.
148-
result = SkImage::MakeFromBitmap(bitmap);
168+
skImage = SkImage::MakeFromBitmap(bitmap);
149169
}
150170
}));
151-
return result;
171+
172+
return DlImageGPU::Make({skImage, std::move(unref_queue)});
152173
}
153174

154175
void MultiFrameCodec::State::GetNextFrameAndInvokeCallback(
@@ -157,14 +178,16 @@ void MultiFrameCodec::State::GetNextFrameAndInvokeCallback(
157178
fml::WeakPtr<GrDirectContext> resourceContext,
158179
fml::RefPtr<flutter::SkiaUnrefQueue> unref_queue,
159180
const std::shared_ptr<const fml::SyncSwitch>& gpu_disable_sync_switch,
160-
size_t trace_id) {
181+
size_t trace_id,
182+
std::shared_ptr<impeller::Context> impeller_context) {
161183
fml::RefPtr<CanvasImage> image = nullptr;
162184
int duration = 0;
163-
sk_sp<SkImage> skImage =
164-
GetNextFrameImage(std::move(resourceContext), gpu_disable_sync_switch);
165-
if (skImage) {
185+
sk_sp<DlImage> dlImage =
186+
GetNextFrameImage(std::move(resourceContext), gpu_disable_sync_switch,
187+
impeller_context, unref_queue);
188+
if (dlImage) {
166189
image = CanvasImage::Create();
167-
image->set_image(DlImageGPU::Make({skImage, std::move(unref_queue)}));
190+
image->set_image(dlImage);
168191
ImageGenerator::FrameInfo frameInfo =
169192
generator_->GetFrameInfo(nextFrameIndex_);
170193
duration = frameInfo.duration;
@@ -218,7 +241,8 @@ Dart_Handle MultiFrameCodec::getNextFrame(Dart_Handle callback_handle) {
218241
state->GetNextFrameAndInvokeCallback(
219242
std::move(callback), ui_task_runner,
220243
io_manager->GetResourceContext(), io_manager->GetSkiaUnrefQueue(),
221-
io_manager->GetIsGpuDisabledSyncSwitch(), trace_id);
244+
io_manager->GetIsGpuDisabledSyncSwitch(), trace_id,
245+
io_manager->GetImpellerContext());
222246
}));
223247

224248
return Dart_Null();

lib/ui/painting/multi_frame_codec.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class MultiFrameCodec : public Codec {
4444
const std::shared_ptr<ImageGenerator> generator_;
4545
const int frameCount_;
4646
const int repetitionCount_;
47+
bool is_impeller_enabled_ = false;
4748

4849
// The non-const members and functions below here are only read or written
4950
// to on the IO thread. They are not safe to access or write on the UI
@@ -55,17 +56,20 @@ class MultiFrameCodec : public Codec {
5556
// The index of the last decoded required frame.
5657
int lastRequiredFrameIndex_ = -1;
5758

58-
sk_sp<SkImage> GetNextFrameImage(
59+
sk_sp<DlImage> GetNextFrameImage(
5960
fml::WeakPtr<GrDirectContext> resourceContext,
60-
const std::shared_ptr<const fml::SyncSwitch>& gpu_disable_sync_switch);
61+
const std::shared_ptr<const fml::SyncSwitch>& gpu_disable_sync_switch,
62+
std::shared_ptr<impeller::Context> impeller_context_,
63+
fml::RefPtr<flutter::SkiaUnrefQueue> unref_queue);
6164

6265
void GetNextFrameAndInvokeCallback(
6366
std::unique_ptr<DartPersistentValue> callback,
6467
const fml::RefPtr<fml::TaskRunner>& ui_task_runner,
6568
fml::WeakPtr<GrDirectContext> resourceContext,
6669
fml::RefPtr<flutter::SkiaUnrefQueue> unref_queue,
6770
const std::shared_ptr<const fml::SyncSwitch>& gpu_disable_sync_switch,
68-
size_t trace_id);
71+
size_t trace_id,
72+
std::shared_ptr<impeller::Context> impeller_context_);
6973
};
7074

7175
// Shared across the UI and IO task runners.

0 commit comments

Comments
 (0)