From b59916750a5df673afd169a69f2001d54fce36ea Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 27 Feb 2023 16:45:10 -0800 Subject: [PATCH 01/10] Made toByteData work on wide gamut images (always downscaling to sRGB). --- lib/ui/painting/image_encoding_impeller.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/ui/painting/image_encoding_impeller.cc b/lib/ui/painting/image_encoding_impeller.cc index bfb2365e428a4..f3c715a8f50a6 100644 --- a/lib/ui/painting/image_encoding_impeller.cc +++ b/lib/ui/painting/image_encoding_impeller.cc @@ -15,12 +15,14 @@ std::optional ToSkColorType(impeller::PixelFormat format) { switch (format) { case impeller::PixelFormat::kR8G8B8A8UNormInt: return SkColorType::kRGBA_8888_SkColorType; + case impeller::PixelFormat::kR16G16B16A16Float: + return SkColorType::kRGBA_F16_SkColorType; case impeller::PixelFormat::kB8G8R8A8UNormInt: return SkColorType::kBGRA_8888_SkColorType; - break; + case impeller::PixelFormat::kB10G10R10XR: + return SkColorType::kBGR_101010x_XR_SkColorType; default: return std::nullopt; - break; } } From 22cd9a3c09ed8779e4567990e9ad0c9e814cb1ed Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Tue, 28 Feb 2023 14:38:42 -0800 Subject: [PATCH 02/10] added unit test --- lib/ui/painting/image_encoding.cc | 6 +- lib/ui/painting/image_encoding_impeller.cc | 38 +++-- lib/ui/painting/image_encoding_impeller.h | 21 ++- lib/ui/painting/image_encoding_unittests.cc | 173 ++++++++++++++++++++ 4 files changed, 210 insertions(+), 28 deletions(-) diff --git a/lib/ui/painting/image_encoding.cc b/lib/ui/painting/image_encoding.cc index 578e9d6020c33..ea087a044c227 100644 --- a/lib/ui/painting/image_encoding.cc +++ b/lib/ui/painting/image_encoding.cc @@ -173,9 +173,9 @@ void EncodeImageAndInvokeDataCallback( FML_DCHECK(image); #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); + ImageEncodingImpeller::ConvertImageToRaster( + image, encode_task, raster_task_runner, io_task_runner, + is_gpu_disabled_sync_switch, impeller_context); return; } #endif // IMPELLER_SUPPORTS_RENDERING diff --git a/lib/ui/painting/image_encoding_impeller.cc b/lib/ui/painting/image_encoding_impeller.cc index f3c715a8f50a6..ec429a2cda90f 100644 --- a/lib/ui/painting/image_encoding_impeller.cc +++ b/lib/ui/painting/image_encoding_impeller.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "flutter/lib/ui/painting/image_encoding_impeller.h" + #include "flutter/lib/ui/painting/image.h" #include "impeller/renderer/command_buffer.h" #include "impeller/renderer/context.h" @@ -52,7 +54,23 @@ sk_sp ConvertBufferToSkImage( return raster_image; } -void ConvertDlImageImpellerToSkImage( +void DoConvertImageToRasterImpeller( + const sk_sp& dl_image, + std::function)> encode_task, + const std::shared_ptr& is_gpu_disabled_sync_switch, + const std::shared_ptr& impeller_context) { + is_gpu_disabled_sync_switch->Execute( + fml::SyncSwitch::Handlers() + .SetIfTrue([&encode_task] { encode_task(nullptr); }) + .SetIfFalse([&dl_image, &encode_task, &impeller_context] { + ImageEncodingImpeller::ConvertDlImageToSkImage( + dl_image, std::move(encode_task), impeller_context); + })); +} + +} // namespace + +void ImageEncodingImpeller::ConvertDlImageToSkImage( const sk_sp& dl_image, std::function)> encode_task, const std::shared_ptr& impeller_context) { @@ -113,23 +131,7 @@ void ConvertDlImageImpellerToSkImage( } } -void DoConvertImageToRasterImpeller( - const sk_sp& dl_image, - std::function)> encode_task, - const std::shared_ptr& is_gpu_disabled_sync_switch, - const std::shared_ptr& impeller_context) { - is_gpu_disabled_sync_switch->Execute( - fml::SyncSwitch::Handlers() - .SetIfTrue([&encode_task] { encode_task(nullptr); }) - .SetIfFalse([&dl_image, &encode_task, &impeller_context] { - ConvertDlImageImpellerToSkImage(dl_image, std::move(encode_task), - impeller_context); - })); -} - -} // namespace - -void ConvertImageToRasterImpeller( +void ImageEncodingImpeller::ConvertImageToRaster( const sk_sp& dl_image, std::function)> encode_task, const fml::RefPtr& raster_task_runner, diff --git a/lib/ui/painting/image_encoding_impeller.h b/lib/ui/painting/image_encoding_impeller.h index 459ecf50909c4..f1be24b39e903 100644 --- a/lib/ui/painting/image_encoding_impeller.h +++ b/lib/ui/painting/image_encoding_impeller.h @@ -15,14 +15,21 @@ class Context; namespace flutter { -void ConvertImageToRasterImpeller( - const sk_sp& dl_image, - std::function)> encode_task, - const fml::RefPtr& raster_task_runner, - const fml::RefPtr& io_task_runner, - const std::shared_ptr& is_gpu_disabled_sync_switch, - const std::shared_ptr& impeller_context); +class ImageEncodingImpeller { + public: + static void ConvertDlImageToSkImage( + const sk_sp& dl_image, + std::function)> encode_task, + const std::shared_ptr& impeller_context); + static void ConvertImageToRaster( + const sk_sp& dl_image, + std::function)> encode_task, + const fml::RefPtr& raster_task_runner, + const fml::RefPtr& io_task_runner, + const std::shared_ptr& is_gpu_disabled_sync_switch, + const std::shared_ptr& impeller_context); +}; } // namespace flutter #endif // FLUTTER_LIB_UI_PAINTING_IMAGE_ENCODING_IMPELLER_H_ diff --git a/lib/ui/painting/image_encoding_unittests.cc b/lib/ui/painting/image_encoding_unittests.cc index 1899054a94c1d..652a402b5a5d3 100644 --- a/lib/ui/painting/image_encoding_unittests.cc +++ b/lib/ui/painting/image_encoding_unittests.cc @@ -14,16 +14,151 @@ #include "flutter/testing/testing.h" #include "gmock/gmock.h" +using ::testing::_; +using ::testing::DoAll; +using ::testing::InvokeArgument; +using ::testing::Return; + +#if IMPELLER_SUPPORTS_RENDERING +#include "flutter/lib/ui/painting/image_encoding_impeller.h" +#include "impeller/renderer/allocator.h" +#include "impeller/renderer/command_buffer.h" +#include "impeller/renderer/context.h" +#include "impeller/renderer/render_target.h" +#include "impeller/renderer/texture.h" +#endif // IMPELLER_SUPPORTS_RENDERING + // CREATE_NATIVE_ENTRY is leaky by design // NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) +namespace impeller { +namespace { + +class MockDeviceBuffer : public DeviceBuffer { + public: + MockDeviceBuffer(const DeviceBufferDescriptor& desc) : DeviceBuffer(desc) {} + MOCK_METHOD3(CopyHostBuffer, + bool(const uint8_t* source, Range source_range, size_t offset)); + + MOCK_METHOD1(SetLabel, bool(const std::string& label)); + + MOCK_METHOD2(SetLabel, bool(const std::string& label, Range range)); + + MOCK_CONST_METHOD0(OnGetContents, uint8_t*()); + + MOCK_METHOD3(OnCopyHostBuffer, + bool(const uint8_t* source, Range source_range, size_t offset)); +}; + +class MockAllocator : public Allocator { + public: + MOCK_CONST_METHOD0(GetMaxTextureSizeSupported, ISize()); + MOCK_METHOD1( + OnCreateBuffer, + std::shared_ptr(const DeviceBufferDescriptor& desc)); + MOCK_METHOD1(OnCreateTexture, + std::shared_ptr(const TextureDescriptor& desc)); +}; + +class MockBlitPass : public BlitPass { + public: + MOCK_CONST_METHOD0(IsValid, bool()); + MOCK_CONST_METHOD1( + EncodeCommands, + bool(const std::shared_ptr& transients_allocator)); + MOCK_METHOD1(OnSetLabel, void(std::string label)); + + MOCK_METHOD5(OnCopyTextureToTextureCommand, + bool(std::shared_ptr source, + std::shared_ptr destination, + IRect source_region, + IPoint destination_origin, + std::string label)); + + MOCK_METHOD5(OnCopyTextureToBufferCommand, + bool(std::shared_ptr source, + std::shared_ptr destination, + IRect source_region, + size_t destination_offset, + std::string label)); + + MOCK_METHOD2(OnGenerateMipmapCommand, + bool(std::shared_ptr texture, std::string label)); +}; + +class MockCommandBuffer : public CommandBuffer { + public: + MockCommandBuffer(std::weak_ptr context) + : CommandBuffer(context) {} + MOCK_CONST_METHOD0(IsValid, bool()); + MOCK_CONST_METHOD1(SetLabel, void(const std::string& label)); + MOCK_CONST_METHOD0(OnCreateBlitPass, std::shared_ptr()); + MOCK_METHOD1(OnSubmitCommands, bool(CompletionCallback callback)); + MOCK_CONST_METHOD0(OnCreateComputePass, std::shared_ptr()); + MOCK_METHOD1(OnCreateRenderPass, + std::shared_ptr(RenderTarget render_target)); +}; + +class MockImpellerContext : public Context { + public: + MOCK_CONST_METHOD0(IsValid, bool()); + + MOCK_CONST_METHOD0(GetResourceAllocator, std::shared_ptr()); + + MOCK_CONST_METHOD0(GetShaderLibrary, std::shared_ptr()); + + MOCK_CONST_METHOD0(GetSamplerLibrary, std::shared_ptr()); + + MOCK_CONST_METHOD0(GetPipelineLibrary, std::shared_ptr()); + + MOCK_CONST_METHOD0(CreateCommandBuffer, std::shared_ptr()); + + MOCK_CONST_METHOD0(GetWorkQueue, std::shared_ptr()); + + MOCK_CONST_METHOD0(GetGPUTracer, std::shared_ptr()); + + MOCK_CONST_METHOD0(GetColorAttachmentPixelFormat, PixelFormat()); + + MOCK_CONST_METHOD0(GetDeviceCapabilities, const IDeviceCapabilities&()); +}; + +class MockTexture : public Texture { + public: + MockTexture(const TextureDescriptor& desc) : Texture(desc) {} + MOCK_METHOD1(SetLabel, void(std::string_view label)); + MOCK_METHOD3(SetContents, + bool(const uint8_t* contents, size_t length, size_t slice)); + MOCK_METHOD2(SetContents, + bool(std::shared_ptr mapping, size_t slice)); + MOCK_CONST_METHOD0(IsValid, bool()); + MOCK_CONST_METHOD0(GetSize, ISize()); + MOCK_METHOD3(OnSetContents, + bool(const uint8_t* contents, size_t length, size_t slice)); + MOCK_METHOD2(OnSetContents, + bool(std::shared_ptr mapping, size_t slice)); +}; + +} // namespace +} // namespace impeller + namespace flutter { namespace testing { namespace { fml::AutoResetWaitableEvent message_latch; + +class MockDlImage : public DlImage { + public: + MOCK_CONST_METHOD0(skia_image, sk_sp()); + MOCK_CONST_METHOD0(impeller_texture, std::shared_ptr()); + MOCK_CONST_METHOD0(isOpaque, bool()); + MOCK_CONST_METHOD0(isTextureBacked, bool()); + MOCK_CONST_METHOD0(dimensions, SkISize()); + MOCK_CONST_METHOD0(GetApproximateByteSize, size_t()); }; +} // namespace + class MockSyncSwitch { public: struct Handlers { @@ -166,6 +301,44 @@ TEST_F(ShellTest, EncodeImageAccessesSyncSwitch) { DestroyShell(std::move(shell), task_runners); } +TEST(ImageEncodingImpellerTest, ConvertDlImageToSkImage) { + sk_sp image(new MockDlImage()); + EXPECT_CALL(*image, dimensions) + .WillRepeatedly(Return(SkISize::Make(100, 100))); + impeller::TextureDescriptor desc; + desc.format = impeller::PixelFormat::kR16G16B16A16Float; + auto texture = std::make_shared(desc); + EXPECT_CALL(*image, impeller_texture).WillOnce(Return(texture)); + auto context = std::make_shared(); + auto command_buffer = std::make_shared(context); + auto allocator = std::make_shared(); + auto blit_pass = std::make_shared(); + impeller::DeviceBufferDescriptor device_buffer_desc; + auto device_buffer = + std::make_shared(device_buffer_desc); + EXPECT_CALL(*allocator, OnCreateBuffer).WillOnce(Return(device_buffer)); + EXPECT_CALL(*blit_pass, IsValid).WillRepeatedly(Return(true)); + EXPECT_CALL(*command_buffer, IsValid).WillRepeatedly(Return(true)); + EXPECT_CALL(*command_buffer, OnCreateBlitPass).WillOnce(Return(blit_pass)); + EXPECT_CALL(*command_buffer, OnSubmitCommands(_)) + .WillOnce( + DoAll(InvokeArgument<0>(impeller::CommandBuffer::Status::kCompleted), + Return(true))); + EXPECT_CALL(*context, GetResourceAllocator).WillRepeatedly(Return(allocator)); + EXPECT_CALL(*context, CreateCommandBuffer).WillOnce(Return(command_buffer)); + bool did_call = false; + ImageEncodingImpeller::ConvertDlImageToSkImage( + image, + [&did_call](sk_sp image) { + did_call = true; + EXPECT_TRUE(image); + EXPECT_EQUALS(100, image->width()); + EXPECT_EQUALS(100, image->height()); + }, + context); + EXPECT_TRUE(did_call); +} + } // namespace testing } // namespace flutter From 88ed94b77aab473701b718139a90f4572d186f8a Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Tue, 28 Feb 2023 16:28:01 -0800 Subject: [PATCH 03/10] cleaned up the tests --- impeller/renderer/mocks.h | 122 ++++++++++++++++ lib/ui/painting/image_encoding_unittests.cc | 152 +++----------------- 2 files changed, 145 insertions(+), 129 deletions(-) create mode 100644 impeller/renderer/mocks.h diff --git a/impeller/renderer/mocks.h b/impeller/renderer/mocks.h new file mode 100644 index 0000000000000..1f387ee58e05a --- /dev/null +++ b/impeller/renderer/mocks.h @@ -0,0 +1,122 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include "gmock/gmock.h" +#include "impeller/renderer/allocator.h" +#include "impeller/renderer/command_buffer.h" +#include "impeller/renderer/context.h" +#include "impeller/renderer/render_target.h" +#include "impeller/renderer/texture.h" + +namespace impeller { +namespace testing { + +class MockDeviceBuffer : public DeviceBuffer { + public: + MockDeviceBuffer(const DeviceBufferDescriptor& desc) : DeviceBuffer(desc) {} + MOCK_METHOD3(CopyHostBuffer, + bool(const uint8_t* source, Range source_range, size_t offset)); + + MOCK_METHOD1(SetLabel, bool(const std::string& label)); + + MOCK_METHOD2(SetLabel, bool(const std::string& label, Range range)); + + MOCK_CONST_METHOD0(OnGetContents, uint8_t*()); + + MOCK_METHOD3(OnCopyHostBuffer, + bool(const uint8_t* source, Range source_range, size_t offset)); +}; + +class MockAllocator : public Allocator { + public: + MOCK_CONST_METHOD0(GetMaxTextureSizeSupported, ISize()); + MOCK_METHOD1( + OnCreateBuffer, + std::shared_ptr(const DeviceBufferDescriptor& desc)); + MOCK_METHOD1(OnCreateTexture, + std::shared_ptr(const TextureDescriptor& desc)); +}; + +class MockBlitPass : public BlitPass { + public: + MOCK_CONST_METHOD0(IsValid, bool()); + MOCK_CONST_METHOD1( + EncodeCommands, + bool(const std::shared_ptr& transients_allocator)); + MOCK_METHOD1(OnSetLabel, void(std::string label)); + + MOCK_METHOD5(OnCopyTextureToTextureCommand, + bool(std::shared_ptr source, + std::shared_ptr destination, + IRect source_region, + IPoint destination_origin, + std::string label)); + + MOCK_METHOD5(OnCopyTextureToBufferCommand, + bool(std::shared_ptr source, + std::shared_ptr destination, + IRect source_region, + size_t destination_offset, + std::string label)); + + MOCK_METHOD2(OnGenerateMipmapCommand, + bool(std::shared_ptr texture, std::string label)); +}; + +class MockCommandBuffer : public CommandBuffer { + public: + MockCommandBuffer(std::weak_ptr context) + : CommandBuffer(context) {} + MOCK_CONST_METHOD0(IsValid, bool()); + MOCK_CONST_METHOD1(SetLabel, void(const std::string& label)); + MOCK_CONST_METHOD0(OnCreateBlitPass, std::shared_ptr()); + MOCK_METHOD1(OnSubmitCommands, bool(CompletionCallback callback)); + MOCK_CONST_METHOD0(OnCreateComputePass, std::shared_ptr()); + MOCK_METHOD1(OnCreateRenderPass, + std::shared_ptr(RenderTarget render_target)); +}; + +class MockImpellerContext : public Context { + public: + MOCK_CONST_METHOD0(IsValid, bool()); + + MOCK_CONST_METHOD0(GetResourceAllocator, std::shared_ptr()); + + MOCK_CONST_METHOD0(GetShaderLibrary, std::shared_ptr()); + + MOCK_CONST_METHOD0(GetSamplerLibrary, std::shared_ptr()); + + MOCK_CONST_METHOD0(GetPipelineLibrary, std::shared_ptr()); + + MOCK_CONST_METHOD0(CreateCommandBuffer, std::shared_ptr()); + + MOCK_CONST_METHOD0(GetWorkQueue, std::shared_ptr()); + + MOCK_CONST_METHOD0(GetGPUTracer, std::shared_ptr()); + + MOCK_CONST_METHOD0(GetColorAttachmentPixelFormat, PixelFormat()); + + MOCK_CONST_METHOD0(GetDeviceCapabilities, const IDeviceCapabilities&()); +}; + +class MockTexture : public Texture { + public: + MockTexture(const TextureDescriptor& desc) : Texture(desc) {} + MOCK_METHOD1(SetLabel, void(std::string_view label)); + MOCK_METHOD3(SetContents, + bool(const uint8_t* contents, size_t length, size_t slice)); + MOCK_METHOD2(SetContents, + bool(std::shared_ptr mapping, size_t slice)); + MOCK_CONST_METHOD0(IsValid, bool()); + MOCK_CONST_METHOD0(GetSize, ISize()); + MOCK_METHOD3(OnSetContents, + bool(const uint8_t* contents, size_t length, size_t slice)); + MOCK_METHOD2(OnSetContents, + bool(std::shared_ptr mapping, size_t slice)); +}; + +} // namespace testing +} // namespace impeller diff --git a/lib/ui/painting/image_encoding_unittests.cc b/lib/ui/painting/image_encoding_unittests.cc index 652a402b5a5d3..2255047e73bb9 100644 --- a/lib/ui/painting/image_encoding_unittests.cc +++ b/lib/ui/painting/image_encoding_unittests.cc @@ -13,134 +13,16 @@ #include "flutter/shell/common/thread_host.h" #include "flutter/testing/testing.h" #include "gmock/gmock.h" - -using ::testing::_; -using ::testing::DoAll; -using ::testing::InvokeArgument; -using ::testing::Return; +#include "gtest/gtest.h" #if IMPELLER_SUPPORTS_RENDERING #include "flutter/lib/ui/painting/image_encoding_impeller.h" -#include "impeller/renderer/allocator.h" -#include "impeller/renderer/command_buffer.h" -#include "impeller/renderer/context.h" -#include "impeller/renderer/render_target.h" -#include "impeller/renderer/texture.h" +#include "impeller/renderer/mocks.h" #endif // IMPELLER_SUPPORTS_RENDERING // CREATE_NATIVE_ENTRY is leaky by design // NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) -namespace impeller { -namespace { - -class MockDeviceBuffer : public DeviceBuffer { - public: - MockDeviceBuffer(const DeviceBufferDescriptor& desc) : DeviceBuffer(desc) {} - MOCK_METHOD3(CopyHostBuffer, - bool(const uint8_t* source, Range source_range, size_t offset)); - - MOCK_METHOD1(SetLabel, bool(const std::string& label)); - - MOCK_METHOD2(SetLabel, bool(const std::string& label, Range range)); - - MOCK_CONST_METHOD0(OnGetContents, uint8_t*()); - - MOCK_METHOD3(OnCopyHostBuffer, - bool(const uint8_t* source, Range source_range, size_t offset)); -}; - -class MockAllocator : public Allocator { - public: - MOCK_CONST_METHOD0(GetMaxTextureSizeSupported, ISize()); - MOCK_METHOD1( - OnCreateBuffer, - std::shared_ptr(const DeviceBufferDescriptor& desc)); - MOCK_METHOD1(OnCreateTexture, - std::shared_ptr(const TextureDescriptor& desc)); -}; - -class MockBlitPass : public BlitPass { - public: - MOCK_CONST_METHOD0(IsValid, bool()); - MOCK_CONST_METHOD1( - EncodeCommands, - bool(const std::shared_ptr& transients_allocator)); - MOCK_METHOD1(OnSetLabel, void(std::string label)); - - MOCK_METHOD5(OnCopyTextureToTextureCommand, - bool(std::shared_ptr source, - std::shared_ptr destination, - IRect source_region, - IPoint destination_origin, - std::string label)); - - MOCK_METHOD5(OnCopyTextureToBufferCommand, - bool(std::shared_ptr source, - std::shared_ptr destination, - IRect source_region, - size_t destination_offset, - std::string label)); - - MOCK_METHOD2(OnGenerateMipmapCommand, - bool(std::shared_ptr texture, std::string label)); -}; - -class MockCommandBuffer : public CommandBuffer { - public: - MockCommandBuffer(std::weak_ptr context) - : CommandBuffer(context) {} - MOCK_CONST_METHOD0(IsValid, bool()); - MOCK_CONST_METHOD1(SetLabel, void(const std::string& label)); - MOCK_CONST_METHOD0(OnCreateBlitPass, std::shared_ptr()); - MOCK_METHOD1(OnSubmitCommands, bool(CompletionCallback callback)); - MOCK_CONST_METHOD0(OnCreateComputePass, std::shared_ptr()); - MOCK_METHOD1(OnCreateRenderPass, - std::shared_ptr(RenderTarget render_target)); -}; - -class MockImpellerContext : public Context { - public: - MOCK_CONST_METHOD0(IsValid, bool()); - - MOCK_CONST_METHOD0(GetResourceAllocator, std::shared_ptr()); - - MOCK_CONST_METHOD0(GetShaderLibrary, std::shared_ptr()); - - MOCK_CONST_METHOD0(GetSamplerLibrary, std::shared_ptr()); - - MOCK_CONST_METHOD0(GetPipelineLibrary, std::shared_ptr()); - - MOCK_CONST_METHOD0(CreateCommandBuffer, std::shared_ptr()); - - MOCK_CONST_METHOD0(GetWorkQueue, std::shared_ptr()); - - MOCK_CONST_METHOD0(GetGPUTracer, std::shared_ptr()); - - MOCK_CONST_METHOD0(GetColorAttachmentPixelFormat, PixelFormat()); - - MOCK_CONST_METHOD0(GetDeviceCapabilities, const IDeviceCapabilities&()); -}; - -class MockTexture : public Texture { - public: - MockTexture(const TextureDescriptor& desc) : Texture(desc) {} - MOCK_METHOD1(SetLabel, void(std::string_view label)); - MOCK_METHOD3(SetContents, - bool(const uint8_t* contents, size_t length, size_t slice)); - MOCK_METHOD2(SetContents, - bool(std::shared_ptr mapping, size_t slice)); - MOCK_CONST_METHOD0(IsValid, bool()); - MOCK_CONST_METHOD0(GetSize, ISize()); - MOCK_METHOD3(OnSetContents, - bool(const uint8_t* contents, size_t length, size_t slice)); - MOCK_METHOD2(OnSetContents, - bool(std::shared_ptr mapping, size_t slice)); -}; - -} // namespace -} // namespace impeller - namespace flutter { namespace testing { @@ -301,21 +183,32 @@ TEST_F(ShellTest, EncodeImageAccessesSyncSwitch) { DestroyShell(std::move(shell), task_runners); } +#if IMPELLER_SUPPORTS_RENDERING TEST(ImageEncodingImpellerTest, ConvertDlImageToSkImage) { + using ::impeller::testing::MockAllocator; + using ::impeller::testing::MockBlitPass; + using ::impeller::testing::MockCommandBuffer; + using ::impeller::testing::MockDeviceBuffer; + using ::impeller::testing::MockImpellerContext; + using ::impeller::testing::MockTexture; + using ::testing::_; + using ::testing::DoAll; + using ::testing::InvokeArgument; + using ::testing::Return; + sk_sp image(new MockDlImage()); EXPECT_CALL(*image, dimensions) .WillRepeatedly(Return(SkISize::Make(100, 100))); impeller::TextureDescriptor desc; desc.format = impeller::PixelFormat::kR16G16B16A16Float; - auto texture = std::make_shared(desc); + auto texture = std::make_shared(desc); EXPECT_CALL(*image, impeller_texture).WillOnce(Return(texture)); - auto context = std::make_shared(); - auto command_buffer = std::make_shared(context); - auto allocator = std::make_shared(); - auto blit_pass = std::make_shared(); + auto context = std::make_shared(); + auto command_buffer = std::make_shared(context); + auto allocator = std::make_shared(); + auto blit_pass = std::make_shared(); impeller::DeviceBufferDescriptor device_buffer_desc; - auto device_buffer = - std::make_shared(device_buffer_desc); + auto device_buffer = std::make_shared(device_buffer_desc); EXPECT_CALL(*allocator, OnCreateBuffer).WillOnce(Return(device_buffer)); EXPECT_CALL(*blit_pass, IsValid).WillRepeatedly(Return(true)); EXPECT_CALL(*command_buffer, IsValid).WillRepeatedly(Return(true)); @@ -332,12 +225,13 @@ TEST(ImageEncodingImpellerTest, ConvertDlImageToSkImage) { [&did_call](sk_sp image) { did_call = true; EXPECT_TRUE(image); - EXPECT_EQUALS(100, image->width()); - EXPECT_EQUALS(100, image->height()); + EXPECT_EQ(100, image->width()); + EXPECT_EQ(100, image->height()); }, context); EXPECT_TRUE(did_call); } +#endif // IMPELLER_SUPPORTS_RENDERING } // namespace testing } // namespace flutter From 5ba4db674cde5a02e960a126dc64e9ca6a255854 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Tue, 28 Feb 2023 17:15:58 -0800 Subject: [PATCH 04/10] fixed up after rebase --- lib/ui/painting/image_encoding_unittests.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/ui/painting/image_encoding_unittests.cc b/lib/ui/painting/image_encoding_unittests.cc index 2255047e73bb9..d10cdd6c7c1c0 100644 --- a/lib/ui/painting/image_encoding_unittests.cc +++ b/lib/ui/painting/image_encoding_unittests.cc @@ -208,6 +208,9 @@ TEST(ImageEncodingImpellerTest, ConvertDlImageToSkImage) { auto allocator = std::make_shared(); auto blit_pass = std::make_shared(); impeller::DeviceBufferDescriptor device_buffer_desc; + device_buffer_desc.size = 100 * 100 * 8; + std::vector data; + data.reserve(device_buffer_desc.size); auto device_buffer = std::make_shared(device_buffer_desc); EXPECT_CALL(*allocator, OnCreateBuffer).WillOnce(Return(device_buffer)); EXPECT_CALL(*blit_pass, IsValid).WillRepeatedly(Return(true)); @@ -219,14 +222,17 @@ TEST(ImageEncodingImpellerTest, ConvertDlImageToSkImage) { Return(true))); EXPECT_CALL(*context, GetResourceAllocator).WillRepeatedly(Return(allocator)); EXPECT_CALL(*context, CreateCommandBuffer).WillOnce(Return(command_buffer)); + EXPECT_CALL(*device_buffer, OnGetContents).WillOnce(Return(data.data())); bool did_call = false; ImageEncodingImpeller::ConvertDlImageToSkImage( image, - [&did_call](sk_sp image) { + [&did_call](const sk_sp& image) { did_call = true; - EXPECT_TRUE(image); + ASSERT_TRUE(image); EXPECT_EQ(100, image->width()); EXPECT_EQ(100, image->height()); + EXPECT_EQ(kRGBA_F16_SkColorType, image->colorType()); + EXPECT_EQ(nullptr, image->colorSpace()); }, context); EXPECT_TRUE(did_call); From f15abb5345262facd2580f8420780cc4fee02c95 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Tue, 28 Feb 2023 17:39:46 -0800 Subject: [PATCH 05/10] added test for bgr10_xr --- lib/ui/painting/image_encoding_unittests.cc | 78 +++++++++++++++------ 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/lib/ui/painting/image_encoding_unittests.cc b/lib/ui/painting/image_encoding_unittests.cc index d10cdd6c7c1c0..89661b7ba0cc9 100644 --- a/lib/ui/painting/image_encoding_unittests.cc +++ b/lib/ui/painting/image_encoding_unittests.cc @@ -184,33 +184,26 @@ TEST_F(ShellTest, EncodeImageAccessesSyncSwitch) { } #if IMPELLER_SUPPORTS_RENDERING -TEST(ImageEncodingImpellerTest, ConvertDlImageToSkImage) { - using ::impeller::testing::MockAllocator; - using ::impeller::testing::MockBlitPass; - using ::impeller::testing::MockCommandBuffer; - using ::impeller::testing::MockDeviceBuffer; - using ::impeller::testing::MockImpellerContext; - using ::impeller::testing::MockTexture; - using ::testing::_; - using ::testing::DoAll; - using ::testing::InvokeArgument; - using ::testing::Return; +using ::impeller::testing::MockAllocator; +using ::impeller::testing::MockBlitPass; +using ::impeller::testing::MockCommandBuffer; +using ::impeller::testing::MockDeviceBuffer; +using ::impeller::testing::MockImpellerContext; +using ::impeller::testing::MockTexture; +using ::testing::_; +using ::testing::DoAll; +using ::testing::InvokeArgument; +using ::testing::Return; - sk_sp image(new MockDlImage()); - EXPECT_CALL(*image, dimensions) - .WillRepeatedly(Return(SkISize::Make(100, 100))); - impeller::TextureDescriptor desc; - desc.format = impeller::PixelFormat::kR16G16B16A16Float; - auto texture = std::make_shared(desc); - EXPECT_CALL(*image, impeller_texture).WillOnce(Return(texture)); +namespace { +std::shared_ptr MakeConvertDlImageToSkImageContext( + std::vector& buffer) { auto context = std::make_shared(); auto command_buffer = std::make_shared(context); auto allocator = std::make_shared(); auto blit_pass = std::make_shared(); impeller::DeviceBufferDescriptor device_buffer_desc; - device_buffer_desc.size = 100 * 100 * 8; - std::vector data; - data.reserve(device_buffer_desc.size); + device_buffer_desc.size = buffer.size(); auto device_buffer = std::make_shared(device_buffer_desc); EXPECT_CALL(*allocator, OnCreateBuffer).WillOnce(Return(device_buffer)); EXPECT_CALL(*blit_pass, IsValid).WillRepeatedly(Return(true)); @@ -222,7 +215,22 @@ TEST(ImageEncodingImpellerTest, ConvertDlImageToSkImage) { Return(true))); EXPECT_CALL(*context, GetResourceAllocator).WillRepeatedly(Return(allocator)); EXPECT_CALL(*context, CreateCommandBuffer).WillOnce(Return(command_buffer)); - EXPECT_CALL(*device_buffer, OnGetContents).WillOnce(Return(data.data())); + EXPECT_CALL(*device_buffer, OnGetContents).WillOnce(Return(buffer.data())); + return context; +} +} // namespace + +TEST(ImageEncodingImpellerTest, ConvertDlImageToSkImage16Float) { + sk_sp image(new MockDlImage()); + EXPECT_CALL(*image, dimensions) + .WillRepeatedly(Return(SkISize::Make(100, 100))); + impeller::TextureDescriptor desc; + desc.format = impeller::PixelFormat::kR16G16B16A16Float; + auto texture = std::make_shared(desc); + EXPECT_CALL(*image, impeller_texture).WillOnce(Return(texture)); + std::vector buffer; + buffer.reserve(100 * 100 * 8); + auto context = MakeConvertDlImageToSkImageContext(buffer); bool did_call = false; ImageEncodingImpeller::ConvertDlImageToSkImage( image, @@ -237,6 +245,32 @@ TEST(ImageEncodingImpellerTest, ConvertDlImageToSkImage) { context); EXPECT_TRUE(did_call); } + +TEST(ImageEncodingImpellerTest, ConvertDlImageToSkImage10XR) { + sk_sp image(new MockDlImage()); + EXPECT_CALL(*image, dimensions) + .WillRepeatedly(Return(SkISize::Make(100, 100))); + impeller::TextureDescriptor desc; + desc.format = impeller::PixelFormat::kB10G10R10XR; + auto texture = std::make_shared(desc); + EXPECT_CALL(*image, impeller_texture).WillOnce(Return(texture)); + std::vector buffer; + buffer.reserve(100 * 100 * 4); + auto context = MakeConvertDlImageToSkImageContext(buffer); + bool did_call = false; + ImageEncodingImpeller::ConvertDlImageToSkImage( + image, + [&did_call](const sk_sp& image) { + did_call = true; + ASSERT_TRUE(image); + EXPECT_EQ(100, image->width()); + EXPECT_EQ(100, image->height()); + EXPECT_EQ(kBGR_101010x_XR_SkColorType, image->colorType()); + EXPECT_EQ(nullptr, image->colorSpace()); + }, + context); + EXPECT_TRUE(did_call); +} #endif // IMPELLER_SUPPORTS_RENDERING } // namespace testing From daec67a9c76036c253415a43fb197468b4eafa63 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Tue, 28 Feb 2023 17:41:27 -0800 Subject: [PATCH 06/10] added license update --- ci/licenses_golden/licenses_flutter | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index dda3662bd99e1..2af25bf803392 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1481,6 +1481,7 @@ ORIGIN: ../../../flutter/impeller/renderer/gpu_tracer.cc + ../../../flutter/LICE ORIGIN: ../../../flutter/impeller/renderer/gpu_tracer.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/host_buffer.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/host_buffer.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/renderer/mocks.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/pipeline.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/pipeline.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/pipeline_builder.cc + ../../../flutter/LICENSE @@ -3978,6 +3979,7 @@ FILE: ../../../flutter/impeller/renderer/gpu_tracer.cc FILE: ../../../flutter/impeller/renderer/gpu_tracer.h FILE: ../../../flutter/impeller/renderer/host_buffer.cc FILE: ../../../flutter/impeller/renderer/host_buffer.h +FILE: ../../../flutter/impeller/renderer/mocks.h FILE: ../../../flutter/impeller/renderer/pipeline.cc FILE: ../../../flutter/impeller/renderer/pipeline.h FILE: ../../../flutter/impeller/renderer/pipeline_builder.cc From 5d073e1a365705479e5e6d405bb516ce856ae605 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 1 Mar 2023 09:48:51 -0800 Subject: [PATCH 07/10] added docstrings --- lib/ui/painting/image_encoding_impeller.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/ui/painting/image_encoding_impeller.h b/lib/ui/painting/image_encoding_impeller.h index f1be24b39e903..fafe8fc9992b4 100644 --- a/lib/ui/painting/image_encoding_impeller.h +++ b/lib/ui/painting/image_encoding_impeller.h @@ -17,11 +17,18 @@ namespace flutter { class ImageEncodingImpeller { public: + /// Converts a DlImage to a SkImage. + /// This should be called from the thread that corresponds to + /// `dl_image->owning_context()` when gpu access is guaranteed. + /// See also: `ConvertImageToRaster`. + /// Visible for testing. static void ConvertDlImageToSkImage( const sk_sp& dl_image, std::function)> encode_task, const std::shared_ptr& impeller_context); + /// Converts a DlImage to a SkImage. + /// `encode_task` is executed with the resulting `SkImage`. static void ConvertImageToRaster( const sk_sp& dl_image, std::function)> encode_task, From 37d012183625d9967166c95a11490e918f268e83 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 1 Mar 2023 15:03:45 -0800 Subject: [PATCH 08/10] moved the license listing to excluded --- ci/licenses_golden/excluded_files | 1 + ci/licenses_golden/licenses_flutter | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index 4c2ead5262dad..99c315e385792 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -142,6 +142,7 @@ ../../../flutter/impeller/renderer/compute_unittests.cc ../../../flutter/impeller/renderer/device_buffer_unittests.cc ../../../flutter/impeller/renderer/host_buffer_unittests.cc +../../../flutter/impeller/renderer/mocks.h ../../../flutter/impeller/renderer/pipeline_descriptor_unittests.cc ../../../flutter/impeller/renderer/renderer_dart_unittests.cc ../../../flutter/impeller/renderer/renderer_unittests.cc diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 2af25bf803392..dda3662bd99e1 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1481,7 +1481,6 @@ ORIGIN: ../../../flutter/impeller/renderer/gpu_tracer.cc + ../../../flutter/LICE ORIGIN: ../../../flutter/impeller/renderer/gpu_tracer.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/host_buffer.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/host_buffer.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/renderer/mocks.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/pipeline.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/pipeline.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/pipeline_builder.cc + ../../../flutter/LICENSE @@ -3979,7 +3978,6 @@ FILE: ../../../flutter/impeller/renderer/gpu_tracer.cc FILE: ../../../flutter/impeller/renderer/gpu_tracer.h FILE: ../../../flutter/impeller/renderer/host_buffer.cc FILE: ../../../flutter/impeller/renderer/host_buffer.h -FILE: ../../../flutter/impeller/renderer/mocks.h FILE: ../../../flutter/impeller/renderer/pipeline.cc FILE: ../../../flutter/impeller/renderer/pipeline.h FILE: ../../../flutter/impeller/renderer/pipeline_builder.cc From 5f4a0cba5d85bf8219d8040ee0fb0ca82a0424c9 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 1 Mar 2023 15:50:27 -0800 Subject: [PATCH 09/10] moved impeller/renderer/mocks.h to impeller/renderer/testing/mocks.h --- ci/licenses_golden/excluded_files | 2 +- impeller/renderer/{ => testing}/mocks.h | 0 lib/ui/painting/image_encoding_unittests.cc | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename impeller/renderer/{ => testing}/mocks.h (100%) diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index 99c315e385792..b1fb3c2f65301 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -142,10 +142,10 @@ ../../../flutter/impeller/renderer/compute_unittests.cc ../../../flutter/impeller/renderer/device_buffer_unittests.cc ../../../flutter/impeller/renderer/host_buffer_unittests.cc -../../../flutter/impeller/renderer/mocks.h ../../../flutter/impeller/renderer/pipeline_descriptor_unittests.cc ../../../flutter/impeller/renderer/renderer_dart_unittests.cc ../../../flutter/impeller/renderer/renderer_unittests.cc +../../../flutter/impeller/renderer/testing/mocks.h ../../../flutter/impeller/runtime_stage/runtime_stage_unittests.cc ../../../flutter/impeller/scene/README.md ../../../flutter/impeller/scene/importer/importer_unittests.cc diff --git a/impeller/renderer/mocks.h b/impeller/renderer/testing/mocks.h similarity index 100% rename from impeller/renderer/mocks.h rename to impeller/renderer/testing/mocks.h diff --git a/lib/ui/painting/image_encoding_unittests.cc b/lib/ui/painting/image_encoding_unittests.cc index 89661b7ba0cc9..40e587c523c87 100644 --- a/lib/ui/painting/image_encoding_unittests.cc +++ b/lib/ui/painting/image_encoding_unittests.cc @@ -17,7 +17,7 @@ #if IMPELLER_SUPPORTS_RENDERING #include "flutter/lib/ui/painting/image_encoding_impeller.h" -#include "impeller/renderer/mocks.h" +#include "impeller/renderer/testing/mocks.h" #endif // IMPELLER_SUPPORTS_RENDERING // CREATE_NATIVE_ENTRY is leaky by design From b69c32a85ea0843c6d4a68de96fc1da3bf63309b Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 1 Mar 2023 16:03:06 -0800 Subject: [PATCH 10/10] removed mocks.h from excluded and listed its directory instead --- ci/licenses_golden/excluded_files | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index b1fb3c2f65301..8dd864e9bb249 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -145,7 +145,7 @@ ../../../flutter/impeller/renderer/pipeline_descriptor_unittests.cc ../../../flutter/impeller/renderer/renderer_dart_unittests.cc ../../../flutter/impeller/renderer/renderer_unittests.cc -../../../flutter/impeller/renderer/testing/mocks.h +../../../flutter/impeller/renderer/testing ../../../flutter/impeller/runtime_stage/runtime_stage_unittests.cc ../../../flutter/impeller/scene/README.md ../../../flutter/impeller/scene/importer/importer_unittests.cc