31#include "third_party/skia/include/codec/SkCodec.h"
32#include "third_party/skia/include/codec/SkCodecAnimation.h"
33#include "third_party/skia/include/codec/SkJpegDecoder.h"
34#include "third_party/skia/include/core/SkData.h"
35#include "third_party/skia/include/core/SkImage.h"
36#include "third_party/skia/include/core/SkImageInfo.h"
37#include "third_party/skia/include/core/SkSize.h"
38#include "third_party/skia/include/encode/SkPngEncoder.h"
54 bool IsValid()
const override {
return true; }
61 return std::make_shared<TestImpellerAllocator>();
90 const std::function<
void()>& failure)
override {
91 tasks_.push_back(PendingTask{task, failure});
95 for (
auto& task : tasks_) {
119 std::function<void()> task;
120 std::function<void()> failure;
122 std::vector<PendingTask> tasks_;
123 std::shared_ptr<const Capabilities> capabilities_;
124 bool did_dispose_ =
false;
135 bool has_gpu_context =
true)
138 gl_context_(has_gpu_context ? gl_surface_.CreateGrContext() : nullptr),
139 weak_gl_context_factory_(
141 ?
std::make_unique<
fml::WeakPtrFactory<GrDirectContext>>(
146 fml::TimeDelta::FromNanoseconds(0),
148 runner_(task_runner),
149 is_gpu_disabled_sync_switch_(
std::make_shared<
fml::SyncSwitch>()),
150 weak_factory_(this) {
151 FML_CHECK(task_runner->RunsTasksOnCurrentThread())
152 <<
"The IO manager must be initialized its primary task runner. The "
153 "test harness may not be set up correctly/safely.";
154 weak_prototype_ = weak_factory_.GetWeakPtr();
160 [&latch,
queue = unref_queue_]() {
169 return weak_prototype_;
174 return weak_gl_context_factory_ ? weak_gl_context_factory_->GetWeakPtr()
186 return is_gpu_disabled_sync_switch_;
191 return impeller_context_;
195 is_gpu_disabled_sync_switch_->SetSwitch(disabled);
202 std::shared_ptr<impeller::Context> impeller_context_;
203 sk_sp<GrDirectContext> gl_context_;
204 std::unique_ptr<fml::WeakPtrFactory<GrDirectContext>>
205 weak_gl_context_factory_;
209 std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch_;
219 auto thread_task_runner = CreateNewThread();
229 TestIOManager manager(runners.GetIOTaskRunner());
231 auto decoder = ImageDecoder::Make(settings, runners, loop->GetTaskRunner(),
232 manager.GetWeakIOManager(),
233 std::make_shared<fml::SyncSwitch>());
234 ASSERT_NE(decoder, nullptr);
243 const SkImageInfo&
GetInfo() {
return info_; }
250 return {std::nullopt, 0, SkCodecAnimation::DisposalMethod::kKeep};
254 return SkISize::Make(info_.width(), info_.height());
260 unsigned int frame_index,
261 std::optional<unsigned int> prior_frame) {
271 auto thread_task_runner = CreateNewThread();
280 thread_task_runner->PostTask([&]() {
285 std::make_shared<fml::SyncSwitch>());
291 fml::MakeRefCounted<ImageDescriptor>(
292 std::move(
data), std::make_unique<UnknownImageGenerator>());
295 const std::string& decode_error) {
300 decoder->Decode(image_descriptor, {.target_width = 0, .target_height = 0},
309 CreateNewThread(
"platform"),
310 CreateNewThread(
"raster"),
311 CreateNewThread(
"ui"),
312 CreateNewThread(
"io")
317 std::unique_ptr<TestIOManager> io_manager;
319 auto release_io_manager = [&]() {
323 auto decode_image = [&]() {
326 settings, runners, loop->GetTaskRunner(),
327 io_manager->GetWeakIOManager(), std::make_shared<fml::SyncSwitch>());
332 ASSERT_GE(
data->size(), 0u);
335 std::shared_ptr<ImageGenerator> generator =
337 ASSERT_TRUE(generator);
339 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
340 std::move(
data), std::move(generator));
343 const std::string& decode_error) {
345 auto skia_image =
image ?
image->asSkiaImage() :
nullptr;
346 ASSERT_TRUE(skia_image && skia_image->skia_image());
347 EXPECT_TRUE(io_manager->did_access_is_gpu_disabled_sync_switch_);
351 EXPECT_FALSE(io_manager->did_access_is_gpu_disabled_sync_switch_);
352 image_decoder->Decode(
354 {.target_width =
static_cast<uint32_t
>(descriptor->width()),
355 .target_height =
static_cast<uint32_t
>(descriptor->height())},
359 auto set_up_io_manager_and_decode = [&]() {
360 io_manager = std::make_unique<TestIOManager>(runners.
GetIOTaskRunner());
369#if !IMPELLER_SUPPORTS_RENDERING
370 GTEST_SKIP() <<
"Impeller only test.";
373 auto no_gpu_access_context =
374 std::make_shared<impeller::TestImpellerContext>();
375 auto gpu_disabled_switch = std::make_shared<fml::SyncSwitch>(
true);
377 auto info = SkImageInfo::Make(10, 10, SkColorType::kRGBA_8888_SkColorType,
378 SkAlphaType::kPremul_SkAlphaType);
383 auto bitmap = std::make_shared<SkBitmap>();
384 bitmap->allocPixels(info, 10 * 4);
387 auto buffer = std::make_shared<impeller::TestImpellerDeviceBuffer>(desc);
389 bool invoked =
false;
390 auto cb = [&invoked](
const sk_sp<DlImage>&
image,
391 const std::string&
message) { invoked =
true; };
394 cb, no_gpu_access_context,
buffer, decoder_info, std::nullopt,
395 gpu_disabled_switch);
397 EXPECT_EQ(no_gpu_access_context->command_buffer_count_, 0ul);
398 EXPECT_FALSE(invoked);
399 EXPECT_EQ(no_gpu_access_context->DidDisposeResources(),
false);
402 no_gpu_access_context,
bitmap);
404 ASSERT_EQ(no_gpu_access_context->command_buffer_count_, 0ul);
405 ASSERT_EQ(result.second,
"");
406 EXPECT_EQ(no_gpu_access_context->DidDisposeResources(),
true);
407 EXPECT_EQ(result.first->asImpellerImage()
408 ->GetImpellerTexture(no_gpu_access_context)
409 ->GetTextureDescriptor()
413 no_gpu_access_context->FlushTasks(
true);
417 ImpellerUploadToSharedNoGpuTaskFlushingFailure) {
418#if !IMPELLER_SUPPORTS_RENDERING
419 GTEST_SKIP() <<
"Impeller only test.";
422 auto no_gpu_access_context =
423 std::make_shared<impeller::TestImpellerContext>();
424 auto gpu_disabled_switch = std::make_shared<fml::SyncSwitch>(
true);
426 auto info = SkImageInfo::Make(10, 10, SkColorType::kRGBA_8888_SkColorType,
427 SkAlphaType::kPremul_SkAlphaType);
432 auto bitmap = std::make_shared<SkBitmap>();
433 bitmap->allocPixels(info, 10 * 4);
436 auto buffer = std::make_shared<impeller::TestImpellerDeviceBuffer>(desc);
438 sk_sp<DlImage>
image;
440 bool invoked =
false;
441 auto cb = [&invoked, &
image, &
message](sk_sp<DlImage> p_image,
442 std::string p_message) {
444 image = std::move(p_image);
445 message = std::move(p_message);
449 cb, no_gpu_access_context,
buffer, decoder_info, std::nullopt,
450 gpu_disabled_switch);
452 EXPECT_EQ(no_gpu_access_context->command_buffer_count_, 0ul);
453 EXPECT_FALSE(invoked);
455 no_gpu_access_context->FlushTasks(
true);
457 EXPECT_TRUE(invoked);
463 auto info = SkImageInfo::Make(10, 10, SkColorType::kRGBA_8888_SkColorType,
464 SkAlphaType::kPremul_SkAlphaType);
466 bitmap.allocPixels(info, 10 * 4);
467 auto data = SkData::MakeWithoutCopy(
bitmap.getPixels(), 10 * 10 * 4);
469 ASSERT_TRUE(
image !=
nullptr);
470 EXPECT_EQ(SkISize::Make(10, 10),
image->dimensions());
471 EXPECT_EQ(
nullptr,
image->colorSpace());
473 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
477#if IMPELLER_SUPPORTS_RENDERING
478 std::shared_ptr<impeller::Capabilities> capabilities =
482 std::shared_ptr<impeller::Allocator>
allocator =
483 std::make_shared<impeller::TestImpellerAllocator>();
484 absl::StatusOr<ImageDecoderImpeller::DecompressResult> decompressed =
486 descriptor.get(), {.target_width = 100, .target_height = 100},
489 ASSERT_TRUE(decompressed.ok());
490 EXPECT_EQ(decompressed->image_info.format,
496 auto info = SkImageInfo::Make(10, 10, SkColorType::kRGBA_F32_SkColorType,
497 SkAlphaType::kUnpremul_SkAlphaType);
499 bitmap.allocPixels(info, 10 * 16);
500 auto data = SkData::MakeWithoutCopy(
bitmap.getPixels(), 10 * 10 * 16);
503 ASSERT_TRUE(
image !=
nullptr);
504 EXPECT_EQ(SkISize::Make(10, 10),
image->dimensions());
505 EXPECT_EQ(
nullptr,
image->colorSpace());
507 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
511#if IMPELLER_SUPPORTS_RENDERING
512 std::shared_ptr<impeller::Capabilities> capabilities =
516 std::shared_ptr<impeller::Allocator>
allocator =
517 std::make_shared<impeller::TestImpellerAllocator>();
518 absl::StatusOr<ImageDecoderImpeller::DecompressResult> decompressed =
520 descriptor.get(), {.target_width = 100, .target_height = 100},
524 ASSERT_TRUE(decompressed.ok());
525 EXPECT_EQ(decompressed->image_info.format,
532 auto image = SkCodecs::DeferredImage(SkJpegDecoder::Decode(
data,
nullptr));
533 ASSERT_TRUE(
image !=
nullptr);
534 ASSERT_EQ(SkISize::Make(100, 100),
image->dimensions());
537 std::shared_ptr<ImageGenerator> generator =
539 ASSERT_TRUE(generator);
541 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(std::move(
data),
542 std::move(generator));
544#if IMPELLER_SUPPORTS_RENDERING
545 std::shared_ptr<impeller::Capabilities> capabilities =
549 std::shared_ptr<impeller::Allocator>
allocator =
550 std::make_shared<impeller::TestImpellerAllocator>();
551 absl::StatusOr<ImageDecoderImpeller::DecompressResult> wide_result =
553 descriptor.get(), {.target_width = 100, .target_height = 100},
557 ASSERT_TRUE(wide_result.ok());
558 ASSERT_EQ(wide_result->image_info.format,
561 const uint32_t* pixel_ptr =
reinterpret_cast<const uint32_t*
>(
562 wide_result->device_buffer->OnGetContents());
563 bool found_deep_red =
false;
564 for (
int i = 0;
i < wide_result->image_info.size.width *
565 wide_result->image_info.size.height;
567 uint32_t pixel = *pixel_ptr++;
571 if (fabsf(red - 1.0931f) < 0.01f && fabsf(green - -0.2268f) < 0.01f &&
572 fabsf(blue - -0.1501f) < 0.01f) {
573 found_deep_red =
true;
577 ASSERT_TRUE(found_deep_red);
579 absl::StatusOr<ImageDecoderImpeller::DecompressResult> narrow_result =
581 descriptor.get(), {.target_width = 100, .target_height = 100},
585 ASSERT_TRUE(narrow_result.ok());
586 ASSERT_EQ(narrow_result->image_info.format,
593 auto image = SkCodecs::DeferredImage(SkJpegDecoder::Decode(
data,
nullptr));
594 ASSERT_TRUE(
image !=
nullptr);
595 ASSERT_EQ(SkISize::Make(600, 200),
image->dimensions());
598 std::shared_ptr<ImageGenerator> generator =
600 ASSERT_TRUE(generator);
602 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(std::move(
data),
603 std::move(generator));
605#if IMPELLER_SUPPORTS_RENDERING
606 std::shared_ptr<impeller::Capabilities> capabilities =
610 std::shared_ptr<impeller::Allocator>
allocator =
611 std::make_shared<impeller::TestImpellerAllocator>();
612 absl::StatusOr<ImageDecoderImpeller::DecompressResult> result =
614 descriptor.get(), {.target_width = 600, .target_height = 200},
618 ASSERT_TRUE(result.ok());
619 ASSERT_EQ(result->image_info.format,
627 CreateNewThread(
"platform"),
628 CreateNewThread(
"raster"),
629 CreateNewThread(
"ui"),
630 CreateNewThread(
"io")
635 std::unique_ptr<IOManager> io_manager;
637 auto release_io_manager = [&]() {
642 SkISize decoded_size = SkISize::MakeEmpty();
643 auto decode_image = [&]() {
646 settings, runners, loop->GetTaskRunner(),
647 io_manager->GetWeakIOManager(), std::make_shared<fml::SyncSwitch>());
652 ASSERT_GE(
data->size(), 0u);
655 std::shared_ptr<ImageGenerator> generator =
657 ASSERT_TRUE(generator);
659 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
660 std::move(
data), std::move(generator));
663 const std::string& decode_error) {
666 auto skia_image =
image ?
image->asSkiaImage() :
nullptr;
667 ASSERT_TRUE(skia_image && skia_image->skia_image());
668 decoded_size = skia_image->skia_image()->dimensions();
672 image_decoder->Decode(
674 {.target_width =
static_cast<uint32_t
>(descriptor->width()),
675 .target_height =
static_cast<uint32_t
>(descriptor->height())},
679 auto set_up_io_manager_and_decode = [&]() {
680 io_manager = std::make_unique<TestIOManager>(runners.
GetIOTaskRunner());
688 ASSERT_EQ(decoded_size.width(), 600);
689 ASSERT_EQ(decoded_size.height(), 200);
695 CreateNewThread(
"platform"),
696 CreateNewThread(
"raster"),
697 CreateNewThread(
"ui"),
698 CreateNewThread(
"io")
703 std::unique_ptr<IOManager> io_manager;
705 auto release_io_manager = [&]() {
710 auto decode_image = [&]() {
713 settings, runners, loop->GetTaskRunner(),
714 io_manager->GetWeakIOManager(), std::make_shared<fml::SyncSwitch>());
719 ASSERT_GE(
data->size(), 0u);
722 std::shared_ptr<ImageGenerator> generator =
724 ASSERT_TRUE(generator);
726 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
727 std::move(
data), std::move(generator));
730 const std::string& decode_error) {
733 auto skia_image =
image ?
image->asSkiaImage() :
nullptr;
734 ASSERT_TRUE(skia_image && skia_image->skia_image());
738 image_decoder->Decode(
740 {.target_width =
static_cast<uint32_t
>(descriptor->width()),
741 .target_height =
static_cast<uint32_t
>(descriptor->height())},
745 auto set_up_io_manager_and_decode = [&]() {
757 const auto image_dimensions =
758 SkJpegDecoder::Decode(
763 ASSERT_FALSE(image_dimensions.isEmpty());
765 ASSERT_NE(image_dimensions.width(), image_dimensions.height());
769 CreateNewThread(
"platform"),
770 CreateNewThread(
"raster"),
771 CreateNewThread(
"ui"),
772 CreateNewThread(
"io")
776 std::unique_ptr<IOManager> io_manager;
777 std::unique_ptr<ImageDecoder> image_decoder;
781 io_manager = std::make_unique<TestIOManager>(runners.GetIOTaskRunner());
787 image_decoder = ImageDecoder::Make(settings, runners, loop->GetTaskRunner(),
788 io_manager->GetWeakIOManager(),
789 std::make_shared<fml::SyncSwitch>());
793 auto decoded_size = [&](uint32_t target_width,
794 uint32_t target_height) -> SkISize {
795 SkISize final_size = SkISize::MakeEmpty();
800 ASSERT_GE(
data->size(), 0u);
803 std::shared_ptr<ImageGenerator> generator =
805 ASSERT_TRUE(generator);
807 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
808 std::move(
data), std::move(generator));
811 [&](
const sk_sp<DlImage>&
image,
const std::string& decode_error) {
813 auto skia_image =
image ?
image->asSkiaImage() :
nullptr;
814 ASSERT_TRUE(skia_image && skia_image->skia_image());
815 final_size = skia_image->skia_image()->dimensions();
819 image_decoder->Decode(
821 {.target_width = target_width, .target_height = target_height},
828 ASSERT_EQ(SkISize::Make(3024, 4032), image_dimensions);
829 ASSERT_EQ(decoded_size(3024, 4032), image_dimensions);
830 ASSERT_EQ(decoded_size(100, 100), SkISize::Make(100, 100));
842 VerifyCodecRepeatCountsForGifAndWebPAreConsistentWithLoopCounts) {
847 ASSERT_TRUE(gif_mapping);
848 ASSERT_TRUE(webp_mapping);
855 ASSERT_TRUE(gif_generator);
856 ASSERT_TRUE(webp_generator);
859 ASSERT_EQ(gif_generator->GetPlayCount(),
static_cast<unsigned int>(2));
860 ASSERT_EQ(webp_generator->GetPlayCount(),
static_cast<unsigned int>(2));
863TEST(ImageDecoderTest, VerifySimpleDecoding) {
865 auto codec = SkJpegDecoder::Decode(
data,
nullptr);
866 ASSERT_TRUE(codec !=
nullptr);
867 auto image = SkCodecs::DeferredImage(std::move(codec));
868 ASSERT_TRUE(
image !=
nullptr);
869 EXPECT_EQ(600,
image->width());
870 EXPECT_EQ(200,
image->height());
873 std::shared_ptr<ImageGenerator> generator =
875 ASSERT_TRUE(generator);
877 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(std::move(
data),
878 std::move(generator));
881 EXPECT_EQ(compressed_image->width(), 6);
882 EXPECT_EQ(compressed_image->height(), 2);
883 EXPECT_EQ(compressed_image->alphaType(), kOpaque_SkAlphaType);
885#if IMPELLER_SUPPORTS_RENDERING
886 std::shared_ptr<impeller::Capabilities> capabilities =
890 std::shared_ptr<impeller::Capabilities> capabilities_no_blit =
896 std::shared_ptr<impeller::Allocator>
allocator =
897 std::make_shared<impeller::TestImpellerAllocator>();
899 descriptor.get(), {.target_width = 6, .target_height = 2}, {1000, 1000},
901 ASSERT_TRUE(result_1.ok());
902 EXPECT_EQ(result_1->image_info.size.width, 75);
903 EXPECT_EQ(result_1->image_info.size.height, 25);
908 descriptor.get(), {.target_width = 6, .target_height = 2}, {10, 10},
910 ASSERT_TRUE(result_2.ok());
911 EXPECT_EQ(result_2->image_info.size.width, 6);
912 EXPECT_EQ(result_2->image_info.size.height, 2);
917 descriptor.get(), {.target_width = 60, .target_height = 20}, {10, 10},
919 ASSERT_TRUE(result_3.ok());
920 EXPECT_EQ(result_3->image_info.size.width, 10);
921 EXPECT_EQ(result_3->image_info.size.height, 10);
925 descriptor.get(), {.target_width = 6, .target_height = 2}, {1000, 1000},
927 ASSERT_TRUE(result_4.ok());
928 EXPECT_EQ(result_4->image_info.size.width, 6);
929 EXPECT_EQ(result_4->image_info.size.height, 2);
933TEST(ImageDecoderTest, ImagesWithTransparencyArePremulAlpha) {
937 std::shared_ptr<ImageGenerator> generator =
939 ASSERT_TRUE(generator);
941 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(std::move(
data),
942 std::move(generator));
945 ASSERT_TRUE(compressed_image);
946 ASSERT_EQ(compressed_image->width(), 250);
947 ASSERT_EQ(compressed_image->height(), 250);
948 ASSERT_EQ(compressed_image->alphaType(), kPremul_SkAlphaType);
951TEST(ImageDecoderTest, VerifySubpixelDecodingPreservesExifOrientation) {
955 std::shared_ptr<ImageGenerator> generator =
957 ASSERT_TRUE(generator);
959 fml::MakeRefCounted<ImageDescriptor>(
data, std::move(generator));
963 ASSERT_EQ(600, descriptor->width());
964 ASSERT_EQ(200, descriptor->height());
966 auto image = SkCodecs::DeferredImage(SkJpegDecoder::Decode(
data,
nullptr));
967 ASSERT_TRUE(
image !=
nullptr);
968 ASSERT_EQ(600,
image->width());
969 ASSERT_EQ(200,
image->height());
973 MultiFrameCodecCanBeCollectedBeforeIOTasksFinish) {
987 auto settings = CreateSettingsForFixture();
989 auto vm_data = vm_ref.GetVMData();
993 ASSERT_TRUE(gif_mapping);
996 std::shared_ptr<ImageGenerator> gif_generator =
998 ASSERT_TRUE(gif_generator);
1001 CreateNewThread(
"platform"),
1002 CreateNewThread(
"raster"),
1003 CreateNewThread(
"ui"),
1004 CreateNewThread(
"io")
1008 std::unique_ptr<TestIOManager> io_manager;
1012 io_manager = std::make_unique<TestIOManager>(runners.GetIOTaskRunner());
1017 io_manager->GetWeakIOManager());
1023 fml::AutoResetWaitableEvent isolate_latch;
1024 fml::RefPtr<MultiFrameCodec> codec;
1025 EXPECT_TRUE(isolate->RunInIsolateScope([&]() -> bool {
1026 Dart_Handle library = Dart_RootLibrary();
1027 if (Dart_IsError(library)) {
1028 isolate_latch.Signal();
1031 Dart_Handle closure =
1032 Dart_GetField(library, Dart_NewStringFromCString(
"frameCallback"));
1033 if (Dart_IsError(closure) || !Dart_IsClosure(closure)) {
1034 isolate_latch.Signal();
1038 codec = fml::MakeRefCounted<MultiFrameCodec>(std::move(gif_generator));
1039 codec->getNextFrame(closure);
1041 isolate_latch.Signal();
1044 isolate_latch.Wait();
1046 EXPECT_FALSE(codec);
1052 PostTaskSync(runners.GetIOTaskRunner(), [&]() { io_manager.reset(); });
1056 auto context = std::make_shared<impeller::TestImpellerContext>();
1059 EXPECT_FALSE(
allocator.allocPixelRef(
nullptr));
static DartVMRef Create(const Settings &settings, fml::RefPtr< const DartSnapshot > vm_snapshot=nullptr, fml::RefPtr< const DartSnapshot > isolate_snapshot=nullptr)
std::function< void(sk_sp< DlImage >, std::string)> ImageResult
static std::unique_ptr< ImageDecoder > Make(const Settings &settings, const TaskRunners &runners, std::shared_ptr< fml::ConcurrentTaskRunner > concurrent_task_runner, const fml::WeakPtr< IOManager > &io_manager, const std::shared_ptr< fml::SyncSwitch > &gpu_disabled_switch)
static absl::StatusOr< DecompressResult > DecompressTexture(ImageDescriptor *descriptor, const ImageDecoder::Options &options, impeller::ISize max_texture_size, bool supports_wide_gamut, const std::shared_ptr< const impeller::Capabilities > &capabilities, const std::shared_ptr< impeller::Allocator > &allocator)
static void UploadTextureToPrivate(ImageResult result, const std::shared_ptr< impeller::Context > &context, const std::shared_ptr< impeller::DeviceBuffer > &buffer, const ImageInfo &image_info, const std::optional< SkImageInfo > &resize_info, const std::shared_ptr< const fml::SyncSwitch > &gpu_disabled_switch)
Create a device private texture from the provided host buffer.
static std::pair< sk_sp< DlImage >, std::string > UploadTextureToStorage(const std::shared_ptr< impeller::Context > &context, std::shared_ptr< SkBitmap > bitmap)
Create a texture from the provided bitmap.
static sk_sp< SkImage > ImageFromCompressedData(ImageDescriptor *descriptor, uint32_t target_width, uint32_t target_height, const fml::tracing::TraceFlow &flow)
static ImageInfo CreateImageInfo(const SkImageInfo &sk_image_info)
The minimal interface necessary for defining a decoder that can be used for both single and multi-fra...
Keeps a priority-ordered registry of image generator builders to be used when decoding images....
std::shared_ptr< ImageGenerator > CreateCompatibleGenerator(const sk_sp< SkData > &buffer)
Walks the list of image generator builders in descending priority order until a compatible ImageGener...
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
fml::RefPtr< fml::TaskRunner > GetIOTaskRunner() const
fml::RefPtr< flutter::SkiaUnrefQueue > GetSkiaUnrefQueue() const override
std::shared_ptr< const fml::SyncSwitch > GetIsGpuDisabledSyncSwitch() override
~TestIOManager() override
void SetGpuDisabled(bool disabled)
fml::WeakPtr< IOManager > GetWeakIOManager() const override
std::shared_ptr< impeller::Context > GetImpellerContext() const override
Retrieve the impeller::Context.
bool did_access_is_gpu_disabled_sync_switch_
TestIOManager(const fml::RefPtr< fml::TaskRunner > &task_runner, bool has_gpu_context=true)
fml::WeakPtr< GrDirectContext > GetResourceContext() const override
An Image generator that pretends it can't recognize the data it was given.
const SkImageInfo & GetInfo()
Returns basic information about the contents of the encoded image. This information can almost always...
unsigned int GetPlayCount() const
The number of times an animated image should play through before playback stops.
const ImageGenerator::FrameInfo GetFrameInfo(unsigned int frame_index)
Get information about a single frame in the context of a multi-frame image, useful for animation and ...
bool GetPixels(const SkImageInfo &info, void *pixels, size_t row_bytes, unsigned int frame_index, std::optional< unsigned int > prior_frame)
Decode the image into a given buffer. This method is currently always used for sub-pixel image decodi...
~UnknownImageGenerator()=default
SkISize GetScaledDimensions(float scale)
Given a scale value, find the closest image size that can be used for efficiently decoding the image....
unsigned int GetFrameCount() const
Get the number of frames that the encoded image stores. This method is always expected to be called b...
static std::shared_ptr< ConcurrentMessageLoop > Create(size_t worker_count=std::thread::hardware_concurrency())
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
virtual void PostTask(const fml::closure &task) override
virtual bool RunsTasksOnCurrentThread()
CapabilitiesBuilder & SetSupportsTextureToTextureBlits(bool value)
std::unique_ptr< Capabilities > Build()
To do anything rendering related with Impeller, you need a context.
std::shared_ptr< CommandQueue > GetCommandQueue() const override
Return the graphics queue for submitting command buffers.
std::shared_ptr< ShaderLibrary > GetShaderLibrary() const override
Returns the library of shaders used to specify the programmable stages of a pipeline.
RuntimeStageBackend GetRuntimeStageBackend() const override
Retrieve the runtime stage for this context type.
std::shared_ptr< PipelineLibrary > GetPipelineLibrary() const override
Returns the library of pipelines used by render or compute commands.
void Shutdown() override
Force all pending asynchronous work to finish. This is achieved by deleting all owned concurrent mess...
std::shared_ptr< Allocator > GetResourceAllocator() const override
Returns the allocator used to create textures and buffers on the device.
bool IsValid() const override
Determines if a context is valid. If the caller ever receives an invalid context, they must discard i...
void DisposeThreadLocalCachedResources() override
const std::shared_ptr< const Capabilities > & GetCapabilities() const override
Get the capabilities of Impeller context. All optionally supported feature of the platform,...
bool FinishQueue() override
Wait until all previously submitted command buffers are processed and displayed by the GPU.
std::string DescribeGpuModel() const override
BackendType GetBackendType() const override
Get the graphics backend of an Impeller context.
size_t command_buffer_count_
std::shared_ptr< CommandBuffer > CreateCommandBuffer() const override
Create a new command buffer. Command buffers can be used to encode graphics, blit,...
void StoreTaskForGPU(const std::function< void()> &task, const std::function< void()> &failure) override
void FlushTasks(bool fail=false)
bool DidDisposeResources() const
std::shared_ptr< SamplerLibrary > GetSamplerLibrary() const override
Returns the library of combined image samplers used in shaders.
FlutterVulkanImage * image
FlutterDesktopBinaryReply callback
#define FML_CHECK(condition)
#define FML_UNREACHABLE()
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
std::shared_ptr< SkBitmap > bitmap
std::shared_ptr< ImpellerAllocator > allocator
std::string GetCurrentTestName()
Gets the name of the currently running test. This is useful in generating logs or assets based on tes...
TEST_F(DisplayListTest, Defaults)
void PostTaskSync(const fml::RefPtr< fml::TaskRunner > &task_runner, const std::function< void()> &function)
std::string GetDefaultKernelFilePath()
Returns the default path to kernel_blob.bin. This file is within the directory returned by GetFixture...
std::unique_ptr< AutoIsolateShutdown > RunDartCodeInIsolate(DartVMRef &vm_ref, const Settings &settings, const TaskRunners &task_runners, std::string entrypoint, const std::vector< std::string > &args, const std::string &kernel_file_path, fml::WeakPtr< IOManager > io_manager, std::unique_ptr< PlatformConfiguration > platform_configuration)
float DecodeBGR10(uint32_t x)
sk_sp< SkData > OpenFixtureAsSkData(const std::string &fixture_name)
Opens a fixture of the given file name and returns a Skia SkData holding its contents.
TEST(NativeAssetsManagerTest, NoAvailableAssets)
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font manager
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
TEST_F(EngineAnimatorTest, AnimatorAcceptsMultipleRenders)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set profile Make the profiler discard new samples once the profiler sample buffer is full When this flag is not the profiler sample buffer is used as a ring buffer
Info about a single frame in the context of a multi-frame image, useful for animation and blending.