Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1713,7 +1713,11 @@ FILE: ../../../flutter/lib/ui/painting/image_descriptor.h
FILE: ../../../flutter/lib/ui/painting/image_dispose_unittests.cc
FILE: ../../../flutter/lib/ui/painting/image_encoding.cc
FILE: ../../../flutter/lib/ui/painting/image_encoding.h
FILE: ../../../flutter/lib/ui/painting/image_encoding_impeller.cc
FILE: ../../../flutter/lib/ui/painting/image_encoding_impeller.h
FILE: ../../../flutter/lib/ui/painting/image_encoding_impl.h
FILE: ../../../flutter/lib/ui/painting/image_encoding_skia.cc
FILE: ../../../flutter/lib/ui/painting/image_encoding_skia.h
FILE: ../../../flutter/lib/ui/painting/image_encoding_unittests.cc
FILE: ../../../flutter/lib/ui/painting/image_filter.cc
FILE: ../../../flutter/lib/ui/painting/image_filter.h
Expand Down
11 changes: 7 additions & 4 deletions impeller/display_list/display_list_image_impeller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@

namespace impeller {

sk_sp<DlImageImpeller> DlImageImpeller::Make(std::shared_ptr<Texture> texture) {
sk_sp<DlImageImpeller> DlImageImpeller::Make(std::shared_ptr<Texture> texture,
OwningContext owning_context) {
if (!texture) {
return nullptr;
}
return sk_sp<DlImageImpeller>(new DlImageImpeller(std::move(texture)));
return sk_sp<DlImageImpeller>(
new DlImageImpeller(std::move(texture), owning_context));
}

sk_sp<DlImageImpeller> DlImageImpeller::MakeFromYUVTextures(
Expand All @@ -33,8 +35,9 @@ sk_sp<DlImageImpeller> DlImageImpeller::MakeFromYUVTextures(
return impeller::DlImageImpeller::Make(snapshot->texture);
}

DlImageImpeller::DlImageImpeller(std::shared_ptr<Texture> texture)
: texture_(std::move(texture)) {}
DlImageImpeller::DlImageImpeller(std::shared_ptr<Texture> texture,
OwningContext owning_context)
: texture_(std::move(texture)), owning_context_(owning_context) {}

// |DlImage|
DlImageImpeller::~DlImageImpeller() = default;
Expand Down
11 changes: 9 additions & 2 deletions impeller/display_list/display_list_image_impeller.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ class AiksContext;

class DlImageImpeller final : public flutter::DlImage {
public:
static sk_sp<DlImageImpeller> Make(std::shared_ptr<Texture> texture);
static sk_sp<DlImageImpeller> Make(
std::shared_ptr<Texture> texture,
OwningContext owning_context = OwningContext::kIO);

static sk_sp<DlImageImpeller> MakeFromYUVTextures(
AiksContext* aiks_context,
Expand Down Expand Up @@ -43,10 +45,15 @@ class DlImageImpeller final : public flutter::DlImage {
// |DlImage|
size_t GetApproximateByteSize() const override;

// |DlImage|
OwningContext owning_context() const override { return owning_context_; }

private:
std::shared_ptr<Texture> texture_;
OwningContext owning_context_;

explicit DlImageImpeller(std::shared_ptr<Texture> texture);
explicit DlImageImpeller(std::shared_ptr<Texture> texture,
OwningContext owning_context = OwningContext::kIO);

FML_DISALLOW_COPY_AND_ASSIGN(DlImageImpeller);
};
Expand Down
4 changes: 4 additions & 0 deletions lib/ui/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ source_set("ui") {
"painting/image_encoding.cc",
"painting/image_encoding.h",
"painting/image_encoding_impl.h",
"painting/image_encoding_skia.cc",
"painting/image_encoding_skia.h",
"painting/image_filter.cc",
"painting/image_filter.h",
"painting/image_generator.cc",
Expand Down Expand Up @@ -167,6 +169,8 @@ source_set("ui") {
"painting/display_list_deferred_image_gpu_impeller.h",
"painting/image_decoder_impeller.cc",
"painting/image_decoder_impeller.h",
"painting/image_encoding_impeller.cc",
"painting/image_encoding_impeller.h",
]

deps += [ "//flutter/impeller" ]
Expand Down
5 changes: 5 additions & 0 deletions lib/ui/painting/display_list_deferred_image_gpu_impeller.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ class DlDeferredImageGPUImpeller final : public DlImage {
// |DlImage|
size_t GetApproximateByteSize() const override;

// |DlImage|
OwningContext owning_context() const override {
return OwningContext::kRaster;
}

private:
class ImageWrapper final : public std::enable_shared_from_this<ImageWrapper>,
public ContextListener {
Expand Down
111 changes: 26 additions & 85 deletions lib/ui/painting/image_encoding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
#include "flutter/fml/make_copyable.h"
#include "flutter/fml/trace_event.h"
#include "flutter/lib/ui/painting/image.h"
#if IMPELLER_SUPPORTS_RENDERING
#include "flutter/lib/ui/painting/image_encoding_impeller.h"
#endif // IMPELLER_SUPPORTS_RENDERING
#include "flutter/lib/ui/painting/image_encoding_skia.h"
#include "third_party/skia/include/core/SkEncodedImageFormat.h"
#include "third_party/tonic/dart_persistent_value.h"
#include "third_party/tonic/logging/dart_invoke.h"
Expand All @@ -22,6 +26,9 @@ using tonic::DartInvoke;
using tonic::DartPersistentValue;
using tonic::ToDart;

namespace impeller {
class Context;
} // namespace impeller
namespace flutter {
namespace {

Expand Down Expand Up @@ -60,84 +67,6 @@ void InvokeDataCallback(std::unique_ptr<DartPersistentValue> callback,
DartInvoke(callback->value(), {dart_data});
}

void ConvertImageToRaster(
const sk_sp<DlImage>& dl_image,
std::function<void(sk_sp<SkImage>)> encode_task,
const fml::RefPtr<fml::TaskRunner>& raster_task_runner,
const fml::RefPtr<fml::TaskRunner>& io_task_runner,
const fml::WeakPtr<GrDirectContext>& resource_context,
const fml::TaskRunnerAffineWeakPtr<SnapshotDelegate>& snapshot_delegate,
const std::shared_ptr<const fml::SyncSwitch>& is_gpu_disabled_sync_switch) {
// If the owning_context is kRaster, we can't access it on this task runner.
if (dl_image->owning_context() != DlImage::OwningContext::kRaster) {
auto image = dl_image->skia_image();

// Check validity of the image.
if (image == nullptr) {
FML_LOG(ERROR) << "Image was null.";
encode_task(nullptr);
return;
}

auto dimensions = image->dimensions();

if (dimensions.isEmpty()) {
FML_LOG(ERROR) << "Image dimensions were empty.";
encode_task(nullptr);
return;
}

SkPixmap pixmap;
if (image->peekPixels(&pixmap)) {
// This is already a raster image.
encode_task(image);
return;
}

if (sk_sp<SkImage> raster_image = image->makeRasterImage()) {
// The image can be converted to a raster image.
encode_task(raster_image);
return;
}
}

// Cross-context images do not support makeRasterImage. Convert these images
// by drawing them into a surface. This must be done on the raster thread
// to prevent concurrent usage of the image on both the IO and raster threads.
raster_task_runner->PostTask([dl_image, encode_task = std::move(encode_task),
resource_context, snapshot_delegate,
io_task_runner, is_gpu_disabled_sync_switch,
raster_task_runner]() {
auto image = dl_image->skia_image();
if (!image || !snapshot_delegate) {
io_task_runner->PostTask(
[encode_task = encode_task]() mutable { encode_task(nullptr); });
return;
}

sk_sp<SkImage> raster_image =
snapshot_delegate->ConvertToRasterImage(image);

io_task_runner->PostTask([image, encode_task = encode_task,
raster_image = std::move(raster_image),
resource_context, is_gpu_disabled_sync_switch,
owning_context = dl_image->owning_context(),
raster_task_runner]() mutable {
if (!raster_image) {
// The rasterizer was unable to render the cross-context image
// (presumably because it does not have a GrContext). In that case,
// convert the image on the IO thread using the resource context.
raster_image = ConvertToRasterUsingResourceContext(
image, resource_context, is_gpu_disabled_sync_switch);
}
encode_task(raster_image);
if (owning_context == DlImage::OwningContext::kRaster) {
raster_task_runner->PostTask([image = std::move(image)]() {});
}
});
});
}

sk_sp<SkData> CopyImageByteData(const sk_sp<SkImage>& raster_image,
SkColorType color_type,
SkAlphaType alpha_type) {
Expand Down Expand Up @@ -221,7 +150,9 @@ void EncodeImageAndInvokeDataCallback(
const fml::RefPtr<fml::TaskRunner>& io_task_runner,
const fml::WeakPtr<GrDirectContext>& resource_context,
const fml::TaskRunnerAffineWeakPtr<SnapshotDelegate>& snapshot_delegate,
const std::shared_ptr<const fml::SyncSwitch>& is_gpu_disabled_sync_switch) {
const std::shared_ptr<const fml::SyncSwitch>& is_gpu_disabled_sync_switch,
const std::shared_ptr<impeller::Context>& impeller_context,
bool is_impeller_enabled) {
auto callback_task = fml::MakeCopyable(
[callback = std::move(callback)](sk_sp<SkData> encoded) mutable {
InvokeDataCallback(std::move(callback), std::move(encoded));
Expand All @@ -239,9 +170,17 @@ void EncodeImageAndInvokeDataCallback(
};

FML_DCHECK(image);
ConvertImageToRaster(image, encode_task, raster_task_runner, io_task_runner,
resource_context, snapshot_delegate,
is_gpu_disabled_sync_switch);
#if IMPELLER_SUPPORTS_RENDERING
if (is_impeller_enabled) {
ConvertImageToRasterImpeller(image, encode_task, raster_task_runner,
io_task_runner, is_gpu_disabled_sync_switch,
impeller_context);
return;
}
#endif // IMPELLER_SUPPORTS_RENDERING
ConvertImageToRasterSkia(image, encode_task, raster_task_runner,
io_task_runner, resource_context, snapshot_delegate,
is_gpu_disabled_sync_switch);
}

} // namespace
Expand Down Expand Up @@ -272,13 +211,15 @@ Dart_Handle EncodeImage(CanvasImage* canvas_image,
raster_task_runner = task_runners.GetRasterTaskRunner(),
io_task_runner = task_runners.GetIOTaskRunner(),
io_manager = UIDartState::Current()->GetIOManager(),
snapshot_delegate =
UIDartState::Current()->GetSnapshotDelegate()]() mutable {
snapshot_delegate = UIDartState::Current()->GetSnapshotDelegate(),
is_impeller_enabled =
UIDartState::Current()->IsImpellerEnabled()]() mutable {
EncodeImageAndInvokeDataCallback(
image, std::move(callback), image_format, ui_task_runner,
raster_task_runner, io_task_runner,
io_manager->GetResourceContext(), snapshot_delegate,
io_manager->GetIsGpuDisabledSyncSwitch());
io_manager->GetIsGpuDisabledSyncSwitch(),
io_manager->GetImpellerContext(), is_impeller_enabled);
}));

return Dart_Null();
Expand Down
Loading