29#include "third_party/skia/include/codec/SkCodec.h"
30#include "third_party/skia/include/codec/SkCodecAnimation.h"
31#include "third_party/skia/include/codec/SkJpegDecoder.h"
32#include "third_party/skia/include/core/SkData.h"
33#include "third_party/skia/include/core/SkImage.h"
34#include "third_party/skia/include/core/SkImageInfo.h"
35#include "third_party/skia/include/core/SkSize.h"
36#include "third_party/skia/include/encode/SkPngEncoder.h"
52 bool IsValid()
const override {
return true; }
59 return std::make_shared<TestImpellerAllocator>();
84 const std::function<
void()>& failure)
override {
85 tasks_.push_back(PendingTask{task, failure});
89 for (
auto& task : tasks_) {
113 std::function<void()> task;
114 std::function<void()> failure;
116 std::vector<PendingTask> tasks_;
117 std::shared_ptr<const Capabilities> capabilities_;
118 bool did_dispose_ =
false;
129 bool has_gpu_context =
true)
132 gl_context_(has_gpu_context ? gl_surface_.CreateGrContext() : nullptr),
133 weak_gl_context_factory_(
135 ?
std::make_unique<
fml::WeakPtrFactory<GrDirectContext>>(
140 fml::TimeDelta::FromNanoseconds(0),
142 runner_(task_runner),
143 is_gpu_disabled_sync_switch_(
std::make_shared<
fml::SyncSwitch>()),
144 weak_factory_(this) {
145 FML_CHECK(task_runner->RunsTasksOnCurrentThread())
146 <<
"The IO manager must be initialized its primary task runner. The "
147 "test harness may not be set up correctly/safely.";
148 weak_prototype_ = weak_factory_.GetWeakPtr();
154 [&latch,
queue = unref_queue_]() {
163 return weak_prototype_;
168 return weak_gl_context_factory_ ? weak_gl_context_factory_->GetWeakPtr()
180 return is_gpu_disabled_sync_switch_;
185 return impeller_context_;
189 is_gpu_disabled_sync_switch_->SetSwitch(disabled);
196 std::shared_ptr<impeller::Context> impeller_context_;
197 sk_sp<GrDirectContext> gl_context_;
198 std::unique_ptr<fml::WeakPtrFactory<GrDirectContext>>
199 weak_gl_context_factory_;
203 std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch_;
213 auto thread_task_runner = CreateNewThread();
223 TestIOManager manager(runners.GetIOTaskRunner());
225 auto decoder = ImageDecoder::Make(settings, runners, loop->GetTaskRunner(),
226 manager.GetWeakIOManager(),
227 std::make_shared<fml::SyncSwitch>());
228 ASSERT_NE(decoder, nullptr);
237 const SkImageInfo&
GetInfo() {
return info_; }
244 return {std::nullopt, 0, SkCodecAnimation::DisposalMethod::kKeep};
248 return SkISize::Make(info_.width(), info_.height());
254 unsigned int frame_index,
255 std::optional<unsigned int> prior_frame) {
265 auto thread_task_runner = CreateNewThread();
274 thread_task_runner->PostTask([&]() {
279 std::make_shared<fml::SyncSwitch>());
285 fml::MakeRefCounted<ImageDescriptor>(
286 std::move(
data), std::make_unique<UnknownImageGenerator>());
289 const std::string& decode_error) {
294 decoder->Decode(image_descriptor, {.target_width = 0, .target_height = 0},
303 CreateNewThread(
"platform"),
304 CreateNewThread(
"raster"),
305 CreateNewThread(
"ui"),
306 CreateNewThread(
"io")
311 std::unique_ptr<TestIOManager> io_manager;
313 auto release_io_manager = [&]() {
317 auto decode_image = [&]() {
320 settings, runners, loop->GetTaskRunner(),
321 io_manager->GetWeakIOManager(), std::make_shared<fml::SyncSwitch>());
326 ASSERT_GE(
data->size(), 0u);
329 std::shared_ptr<ImageGenerator> generator =
331 ASSERT_TRUE(generator);
333 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
334 std::move(
data), std::move(generator));
337 const std::string& decode_error) {
340 EXPECT_TRUE(io_manager->did_access_is_gpu_disabled_sync_switch_);
343 EXPECT_FALSE(io_manager->did_access_is_gpu_disabled_sync_switch_);
344 image_decoder->Decode(
346 {.target_width =
static_cast<uint32_t
>(descriptor->width()),
347 .target_height =
static_cast<uint32_t
>(descriptor->height())},
351 auto set_up_io_manager_and_decode = [&]() {
352 io_manager = std::make_unique<TestIOManager>(runners.
GetIOTaskRunner());
361#if !IMPELLER_SUPPORTS_RENDERING
362 GTEST_SKIP() <<
"Impeller only test.";
365 auto no_gpu_access_context =
366 std::make_shared<impeller::TestImpellerContext>();
367 auto gpu_disabled_switch = std::make_shared<fml::SyncSwitch>(
true);
369 auto info = SkImageInfo::Make(10, 10, SkColorType::kRGBA_8888_SkColorType,
370 SkAlphaType::kPremul_SkAlphaType);
375 auto bitmap = std::make_shared<SkBitmap>();
376 bitmap->allocPixels(info, 10 * 4);
379 auto buffer = std::make_shared<impeller::TestImpellerDeviceBuffer>(desc);
381 bool invoked =
false;
382 auto cb = [&invoked](
const sk_sp<DlImage>&
image,
383 const std::string&
message) { invoked =
true; };
386 cb, no_gpu_access_context,
buffer, decoder_info, std::nullopt,
387 gpu_disabled_switch);
389 EXPECT_EQ(no_gpu_access_context->command_buffer_count_, 0ul);
390 EXPECT_FALSE(invoked);
391 EXPECT_EQ(no_gpu_access_context->DidDisposeResources(),
false);
394 no_gpu_access_context,
bitmap);
396 ASSERT_EQ(no_gpu_access_context->command_buffer_count_, 0ul);
397 ASSERT_EQ(result.second,
"");
398 EXPECT_EQ(no_gpu_access_context->DidDisposeResources(),
true);
400 result.first->impeller_texture()->GetTextureDescriptor().storage_mode,
403 no_gpu_access_context->FlushTasks(
true);
407 ImpellerUploadToSharedNoGpuTaskFlushingFailure) {
408#if !IMPELLER_SUPPORTS_RENDERING
409 GTEST_SKIP() <<
"Impeller only test.";
412 auto no_gpu_access_context =
413 std::make_shared<impeller::TestImpellerContext>();
414 auto gpu_disabled_switch = std::make_shared<fml::SyncSwitch>(
true);
416 auto info = SkImageInfo::Make(10, 10, SkColorType::kRGBA_8888_SkColorType,
417 SkAlphaType::kPremul_SkAlphaType);
422 auto bitmap = std::make_shared<SkBitmap>();
423 bitmap->allocPixels(info, 10 * 4);
426 auto buffer = std::make_shared<impeller::TestImpellerDeviceBuffer>(desc);
428 sk_sp<DlImage>
image;
430 bool invoked =
false;
431 auto cb = [&invoked, &
image, &
message](sk_sp<DlImage> p_image,
432 std::string p_message) {
434 image = std::move(p_image);
435 message = std::move(p_message);
439 cb, no_gpu_access_context,
buffer, decoder_info, std::nullopt,
440 gpu_disabled_switch);
442 EXPECT_EQ(no_gpu_access_context->command_buffer_count_, 0ul);
443 EXPECT_FALSE(invoked);
445 no_gpu_access_context->FlushTasks(
true);
447 EXPECT_TRUE(invoked);
453 auto info = SkImageInfo::Make(10, 10, SkColorType::kRGBA_8888_SkColorType,
454 SkAlphaType::kPremul_SkAlphaType);
456 bitmap.allocPixels(info, 10 * 4);
457 auto data = SkData::MakeWithoutCopy(
bitmap.getPixels(), 10 * 10 * 4);
459 ASSERT_TRUE(
image !=
nullptr);
460 EXPECT_EQ(SkISize::Make(10, 10),
image->dimensions());
461 EXPECT_EQ(
nullptr,
image->colorSpace());
463 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
467#if IMPELLER_SUPPORTS_RENDERING
468 std::shared_ptr<impeller::Capabilities> capabilities =
472 std::shared_ptr<impeller::Allocator>
allocator =
473 std::make_shared<impeller::TestImpellerAllocator>();
474 absl::StatusOr<ImageDecoderImpeller::DecompressResult> decompressed =
476 descriptor.get(), {.target_width = 100, .target_height = 100},
479 ASSERT_TRUE(decompressed.ok());
480 EXPECT_EQ(decompressed->image_info.format,
486 auto info = SkImageInfo::Make(10, 10, SkColorType::kRGBA_F32_SkColorType,
487 SkAlphaType::kUnpremul_SkAlphaType);
489 bitmap.allocPixels(info, 10 * 16);
490 auto data = SkData::MakeWithoutCopy(
bitmap.getPixels(), 10 * 10 * 16);
493 ASSERT_TRUE(
image !=
nullptr);
494 EXPECT_EQ(SkISize::Make(10, 10),
image->dimensions());
495 EXPECT_EQ(
nullptr,
image->colorSpace());
497 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
501#if IMPELLER_SUPPORTS_RENDERING
502 std::shared_ptr<impeller::Capabilities> capabilities =
506 std::shared_ptr<impeller::Allocator>
allocator =
507 std::make_shared<impeller::TestImpellerAllocator>();
508 absl::StatusOr<ImageDecoderImpeller::DecompressResult> decompressed =
510 descriptor.get(), {.target_width = 100, .target_height = 100},
514 ASSERT_TRUE(decompressed.ok());
515 EXPECT_EQ(decompressed->image_info.format,
522 auto image = SkCodecs::DeferredImage(SkJpegDecoder::Decode(
data,
nullptr));
523 ASSERT_TRUE(
image !=
nullptr);
524 ASSERT_EQ(SkISize::Make(100, 100),
image->dimensions());
527 std::shared_ptr<ImageGenerator> generator =
529 ASSERT_TRUE(generator);
531 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(std::move(
data),
532 std::move(generator));
534#if IMPELLER_SUPPORTS_RENDERING
535 std::shared_ptr<impeller::Capabilities> capabilities =
539 std::shared_ptr<impeller::Allocator>
allocator =
540 std::make_shared<impeller::TestImpellerAllocator>();
541 absl::StatusOr<ImageDecoderImpeller::DecompressResult> wide_result =
543 descriptor.get(), {.target_width = 100, .target_height = 100},
547 ASSERT_TRUE(wide_result.ok());
548 ASSERT_EQ(wide_result->image_info.format,
551 const uint32_t* pixel_ptr =
reinterpret_cast<const uint32_t*
>(
552 wide_result->device_buffer->OnGetContents());
553 bool found_deep_red =
false;
554 for (
int i = 0;
i < wide_result->image_info.size.width *
555 wide_result->image_info.size.height;
557 uint32_t pixel = *pixel_ptr++;
561 if (fabsf(red - 1.0931f) < 0.01f && fabsf(green - -0.2268f) < 0.01f &&
562 fabsf(blue - -0.1501f) < 0.01f) {
563 found_deep_red =
true;
567 ASSERT_TRUE(found_deep_red);
569 absl::StatusOr<ImageDecoderImpeller::DecompressResult> narrow_result =
571 descriptor.get(), {.target_width = 100, .target_height = 100},
575 ASSERT_TRUE(narrow_result.ok());
576 ASSERT_EQ(narrow_result->image_info.format,
583 auto image = SkCodecs::DeferredImage(SkJpegDecoder::Decode(
data,
nullptr));
584 ASSERT_TRUE(
image !=
nullptr);
585 ASSERT_EQ(SkISize::Make(600, 200),
image->dimensions());
588 std::shared_ptr<ImageGenerator> generator =
590 ASSERT_TRUE(generator);
592 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(std::move(
data),
593 std::move(generator));
595#if IMPELLER_SUPPORTS_RENDERING
596 std::shared_ptr<impeller::Capabilities> capabilities =
600 std::shared_ptr<impeller::Allocator>
allocator =
601 std::make_shared<impeller::TestImpellerAllocator>();
602 absl::StatusOr<ImageDecoderImpeller::DecompressResult> result =
604 descriptor.get(), {.target_width = 600, .target_height = 200},
608 ASSERT_TRUE(result.ok());
609 ASSERT_EQ(result->image_info.format,
617 CreateNewThread(
"platform"),
618 CreateNewThread(
"raster"),
619 CreateNewThread(
"ui"),
620 CreateNewThread(
"io")
625 std::unique_ptr<IOManager> io_manager;
627 auto release_io_manager = [&]() {
632 SkISize decoded_size = SkISize::MakeEmpty();
633 auto decode_image = [&]() {
636 settings, runners, loop->GetTaskRunner(),
637 io_manager->GetWeakIOManager(), std::make_shared<fml::SyncSwitch>());
642 ASSERT_GE(
data->size(), 0u);
645 std::shared_ptr<ImageGenerator> generator =
647 ASSERT_TRUE(generator);
649 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
650 std::move(
data), std::move(generator));
653 const std::string& decode_error) {
656 decoded_size =
image->skia_image()->dimensions();
659 image_decoder->Decode(
661 {.target_width =
static_cast<uint32_t
>(descriptor->width()),
662 .target_height =
static_cast<uint32_t
>(descriptor->height())},
666 auto set_up_io_manager_and_decode = [&]() {
667 io_manager = std::make_unique<TestIOManager>(runners.
GetIOTaskRunner());
675 ASSERT_EQ(decoded_size.width(), 600);
676 ASSERT_EQ(decoded_size.height(), 200);
682 CreateNewThread(
"platform"),
683 CreateNewThread(
"raster"),
684 CreateNewThread(
"ui"),
685 CreateNewThread(
"io")
690 std::unique_ptr<IOManager> io_manager;
692 auto release_io_manager = [&]() {
697 auto decode_image = [&]() {
700 settings, runners, loop->GetTaskRunner(),
701 io_manager->GetWeakIOManager(), std::make_shared<fml::SyncSwitch>());
706 ASSERT_GE(
data->size(), 0u);
709 std::shared_ptr<ImageGenerator> generator =
711 ASSERT_TRUE(generator);
713 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
714 std::move(
data), std::move(generator));
717 const std::string& decode_error) {
722 image_decoder->Decode(
724 {.target_width =
static_cast<uint32_t
>(descriptor->width()),
725 .target_height =
static_cast<uint32_t
>(descriptor->height())},
729 auto set_up_io_manager_and_decode = [&]() {
741 const auto image_dimensions =
742 SkJpegDecoder::Decode(
747 ASSERT_FALSE(image_dimensions.isEmpty());
749 ASSERT_NE(image_dimensions.width(), image_dimensions.height());
753 CreateNewThread(
"platform"),
754 CreateNewThread(
"raster"),
755 CreateNewThread(
"ui"),
756 CreateNewThread(
"io")
760 std::unique_ptr<IOManager> io_manager;
761 std::unique_ptr<ImageDecoder> image_decoder;
765 io_manager = std::make_unique<TestIOManager>(runners.GetIOTaskRunner());
771 image_decoder = ImageDecoder::Make(settings, runners, loop->GetTaskRunner(),
772 io_manager->GetWeakIOManager(),
773 std::make_shared<fml::SyncSwitch>());
777 auto decoded_size = [&](uint32_t target_width,
778 uint32_t target_height) -> SkISize {
779 SkISize final_size = SkISize::MakeEmpty();
784 ASSERT_GE(
data->size(), 0u);
787 std::shared_ptr<ImageGenerator> generator =
789 ASSERT_TRUE(generator);
791 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(
792 std::move(
data), std::move(generator));
795 [&](
const sk_sp<DlImage>&
image,
const std::string& decode_error) {
798 final_size =
image->skia_image()->dimensions();
801 image_decoder->Decode(
803 {.target_width = target_width, .target_height = target_height},
810 ASSERT_EQ(SkISize::Make(3024, 4032), image_dimensions);
811 ASSERT_EQ(decoded_size(3024, 4032), image_dimensions);
812 ASSERT_EQ(decoded_size(100, 100), SkISize::Make(100, 100));
824 VerifyCodecRepeatCountsForGifAndWebPAreConsistentWithLoopCounts) {
829 ASSERT_TRUE(gif_mapping);
830 ASSERT_TRUE(webp_mapping);
837 ASSERT_TRUE(gif_generator);
838 ASSERT_TRUE(webp_generator);
841 ASSERT_EQ(gif_generator->GetPlayCount(),
static_cast<unsigned int>(2));
842 ASSERT_EQ(webp_generator->GetPlayCount(),
static_cast<unsigned int>(2));
845TEST(ImageDecoderTest, VerifySimpleDecoding) {
847 auto codec = SkJpegDecoder::Decode(
data,
nullptr);
848 ASSERT_TRUE(codec !=
nullptr);
849 auto image = SkCodecs::DeferredImage(std::move(codec));
850 ASSERT_TRUE(
image !=
nullptr);
851 EXPECT_EQ(600,
image->width());
852 EXPECT_EQ(200,
image->height());
855 std::shared_ptr<ImageGenerator> generator =
857 ASSERT_TRUE(generator);
859 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(std::move(
data),
860 std::move(generator));
863 EXPECT_EQ(compressed_image->width(), 6);
864 EXPECT_EQ(compressed_image->height(), 2);
865 EXPECT_EQ(compressed_image->alphaType(), kOpaque_SkAlphaType);
867#if IMPELLER_SUPPORTS_RENDERING
868 std::shared_ptr<impeller::Capabilities> capabilities =
872 std::shared_ptr<impeller::Capabilities> capabilities_no_blit =
878 std::shared_ptr<impeller::Allocator>
allocator =
879 std::make_shared<impeller::TestImpellerAllocator>();
881 descriptor.get(), {.target_width = 6, .target_height = 2}, {1000, 1000},
883 ASSERT_TRUE(result_1.ok());
884 EXPECT_EQ(result_1->image_info.size.width, 75);
885 EXPECT_EQ(result_1->image_info.size.height, 25);
890 descriptor.get(), {.target_width = 6, .target_height = 2}, {10, 10},
892 ASSERT_TRUE(result_2.ok());
893 EXPECT_EQ(result_2->image_info.size.width, 6);
894 EXPECT_EQ(result_2->image_info.size.height, 2);
899 descriptor.get(), {.target_width = 60, .target_height = 20}, {10, 10},
901 ASSERT_TRUE(result_3.ok());
902 EXPECT_EQ(result_3->image_info.size.width, 10);
903 EXPECT_EQ(result_3->image_info.size.height, 10);
907 descriptor.get(), {.target_width = 6, .target_height = 2}, {1000, 1000},
909 ASSERT_TRUE(result_4.ok());
910 EXPECT_EQ(result_4->image_info.size.width, 6);
911 EXPECT_EQ(result_4->image_info.size.height, 2);
915TEST(ImageDecoderTest, ImagesWithTransparencyArePremulAlpha) {
919 std::shared_ptr<ImageGenerator> generator =
921 ASSERT_TRUE(generator);
923 auto descriptor = fml::MakeRefCounted<ImageDescriptor>(std::move(
data),
924 std::move(generator));
927 ASSERT_TRUE(compressed_image);
928 ASSERT_EQ(compressed_image->width(), 250);
929 ASSERT_EQ(compressed_image->height(), 250);
930 ASSERT_EQ(compressed_image->alphaType(), kPremul_SkAlphaType);
933TEST(ImageDecoderTest, VerifySubpixelDecodingPreservesExifOrientation) {
937 std::shared_ptr<ImageGenerator> generator =
939 ASSERT_TRUE(generator);
941 fml::MakeRefCounted<ImageDescriptor>(
data, std::move(generator));
945 ASSERT_EQ(600, descriptor->width());
946 ASSERT_EQ(200, descriptor->height());
948 auto image = SkCodecs::DeferredImage(SkJpegDecoder::Decode(
data,
nullptr));
949 ASSERT_TRUE(
image !=
nullptr);
950 ASSERT_EQ(600,
image->width());
951 ASSERT_EQ(200,
image->height());
953 auto decode = [descriptor](uint32_t target_width, uint32_t target_height) {
955 descriptor.get(), target_width, target_height,
960 ASSERT_TRUE(expected_data !=
nullptr);
961 ASSERT_FALSE(expected_data->isEmpty());
963 auto assert_image = [&](
const auto& decoded_image,
964 const std::string& decode_error) {
965 ASSERT_EQ(decoded_image->dimensions(), SkISize::Make(300, 100));
966 sk_sp<SkData> encoded =
967 SkPngEncoder::Encode(
nullptr, decoded_image.get(), {});
968 ASSERT_TRUE(encoded->equals(expected_data.get()));
971 assert_image(decode(300, 100), {});
975 MultiFrameCodecCanBeCollectedBeforeIOTasksFinish) {
989 auto settings = CreateSettingsForFixture();
991 auto vm_data = vm_ref.GetVMData();
995 ASSERT_TRUE(gif_mapping);
998 std::shared_ptr<ImageGenerator> gif_generator =
1000 ASSERT_TRUE(gif_generator);
1003 CreateNewThread(
"platform"),
1004 CreateNewThread(
"raster"),
1005 CreateNewThread(
"ui"),
1006 CreateNewThread(
"io")
1010 std::unique_ptr<TestIOManager> io_manager;
1014 io_manager = std::make_unique<TestIOManager>(runners.GetIOTaskRunner());
1019 io_manager->GetWeakIOManager());
1025 fml::AutoResetWaitableEvent isolate_latch;
1026 fml::RefPtr<MultiFrameCodec> codec;
1027 EXPECT_TRUE(isolate->RunInIsolateScope([&]() -> bool {
1028 Dart_Handle library = Dart_RootLibrary();
1029 if (Dart_IsError(library)) {
1030 isolate_latch.Signal();
1033 Dart_Handle closure =
1034 Dart_GetField(library, Dart_NewStringFromCString(
"frameCallback"));
1035 if (Dart_IsError(closure) || !Dart_IsClosure(closure)) {
1036 isolate_latch.Signal();
1040 codec = fml::MakeRefCounted<MultiFrameCodec>(std::move(gif_generator));
1041 codec->getNextFrame(closure);
1043 isolate_latch.Signal();
1046 isolate_latch.Wait();
1048 EXPECT_FALSE(codec);
1054 PostTaskSync(runners.GetIOTaskRunner(), [&]() { io_manager.reset(); });
1058 auto context = std::make_shared<impeller::TestImpellerContext>();
1061 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,...
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.