From ed6da6af082a2a5a02e5c45ec20485640d9b37a7 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 15 Mar 2024 09:58:35 -0700 Subject: [PATCH 01/25] [Impeller] adds wide gamut golden tests --- display_list/testing/dl_test_surface_metal.cc | 2 +- .../golden_playground_test_mac.cc | 15 +- impeller/golden_tests/golden_tests.cc | 3 +- impeller/golden_tests/metal_screenshotter.h | 2 +- impeller/golden_tests/metal_screenshotter.mm | 16 +- .../backend/metal/playground_impl_mtl.mm | 9 +- impeller/playground/playground.cc | 4 + impeller/playground/playground.h | 3 + impeller/playground/playground_impl.cc | 3 + impeller/playground/playground_test.cc | 2 + impeller/playground/playground_test.h | 6 +- impeller/playground/switches.h | 2 + impeller/renderer/backend/metal/context_mtl.h | 13 +- .../renderer/backend/metal/context_mtl.mm | 20 +- .../runtime_stage/runtime_stage_unittests.cc | 2 + testing/impeller_golden_tests_output.txt | 223 ++++++++++++++++++ 16 files changed, 286 insertions(+), 39 deletions(-) diff --git a/display_list/testing/dl_test_surface_metal.cc b/display_list/testing/dl_test_surface_metal.cc index b7d7f7047bd41..def57908b4671 100644 --- a/display_list/testing/dl_test_surface_metal.cc +++ b/display_list/testing/dl_test_surface_metal.cc @@ -115,7 +115,7 @@ sk_sp DlMetalSurfaceProvider::MakeImpellerImage( void DlMetalSurfaceProvider::InitScreenShotter() const { if (!snapshotter_) { - snapshotter_.reset(new MetalScreenshotter()); + snapshotter_.reset(new MetalScreenshotter(/*enable_wide_gamut=*/false)); auto typographer = impeller::TypographerContextSkia::Make(); aiks_context_.reset(new impeller::AiksContext( snapshotter_->GetPlayground().GetContext(), typographer)); diff --git a/impeller/golden_tests/golden_playground_test_mac.cc b/impeller/golden_tests/golden_playground_test_mac.cc index 75fea0f34072a..e2c13df99ceb9 100644 --- a/impeller/golden_tests/golden_playground_test_mac.cc +++ b/impeller/golden_tests/golden_playground_test_mac.cc @@ -139,8 +139,13 @@ void GoldenPlaygroundTest::SetUp() { setenv("VK_ICD_FILENAMES", icd_path.c_str(), 1); switch (GetParam()) { + case PlaygroundBackend::kMetalWideGamut: + pimpl_->screenshotter = std::make_unique( + /*enable_wide_gamut=*/true); + break; case PlaygroundBackend::kMetal: - pimpl_->screenshotter = std::make_unique(); + pimpl_->screenshotter = std::make_unique( + /*enable_wide_gamut=*/false); break; case PlaygroundBackend::kVulkan: { const std::unique_ptr& playground = @@ -160,14 +165,6 @@ void GoldenPlaygroundTest::SetUp() { break; } } - if (GetParam() == PlaygroundBackend::kMetal) { - pimpl_->screenshotter = std::make_unique(); - } else if (GetParam() == PlaygroundBackend::kVulkan) { - const std::unique_ptr& playground = - GetSharedVulkanPlayground(/*enable_validations=*/true); - pimpl_->screenshotter = - std::make_unique(playground); - } std::string test_name = GetTestName(); if (std::find(kSkipTests.begin(), kSkipTests.end(), test_name) != diff --git a/impeller/golden_tests/golden_tests.cc b/impeller/golden_tests/golden_tests.cc index c519f367a1ddb..40a79cd173703 100644 --- a/impeller/golden_tests/golden_tests.cc +++ b/impeller/golden_tests/golden_tests.cc @@ -50,7 +50,8 @@ bool SaveScreenshot(std::unique_ptr screenshot) { class GoldenTests : public ::testing::Test { public: - GoldenTests() : screenshotter_(new MetalScreenshotter()) {} + GoldenTests() + : screenshotter_(new MetalScreenshotter(/*enable_wide_gamut=*/false)) {} MetalScreenshotter& Screenshotter() { return *screenshotter_; } diff --git a/impeller/golden_tests/metal_screenshotter.h b/impeller/golden_tests/metal_screenshotter.h index 582462a73f425..8104396bd8be5 100644 --- a/impeller/golden_tests/metal_screenshotter.h +++ b/impeller/golden_tests/metal_screenshotter.h @@ -18,7 +18,7 @@ namespace testing { /// playground backend. class MetalScreenshotter : public Screenshotter { public: - MetalScreenshotter(); + explicit MetalScreenshotter(bool enable_wide_gamut); std::unique_ptr MakeScreenshot( AiksContext& aiks_context, diff --git a/impeller/golden_tests/metal_screenshotter.mm b/impeller/golden_tests/metal_screenshotter.mm index 534884078a17f..11aa7d26f738e 100644 --- a/impeller/golden_tests/metal_screenshotter.mm +++ b/impeller/golden_tests/metal_screenshotter.mm @@ -13,10 +13,16 @@ namespace impeller { namespace testing { -MetalScreenshotter::MetalScreenshotter() { +MetalScreenshotter::MetalScreenshotter(bool enable_wide_gamut) { FML_CHECK(::glfwInit() == GLFW_TRUE); - playground_ = - PlaygroundImpl::Create(PlaygroundBackend::kMetal, PlaygroundSwitches{}); + PlaygroundSwitches switches; + if (enable_wide_gamut) { + switches.enable_wide_gamut = true; + playground_ = + PlaygroundImpl::Create(PlaygroundBackend::kMetalWideGamut, switches); + } else { + playground_ = PlaygroundImpl::Create(PlaygroundBackend::kMetal, switches); + } } std::unique_ptr MetalScreenshotter::MakeScreenshot( @@ -33,10 +39,6 @@ id metal_texture = std::static_pointer_cast(texture)->GetMTLTexture(); - if (metal_texture.pixelFormat != MTLPixelFormatBGRA8Unorm) { - return {}; - } - CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB(); CIImage* ciImage = [[CIImage alloc] initWithMTLTexture:metal_texture diff --git a/impeller/playground/backend/metal/playground_impl_mtl.mm b/impeller/playground/backend/metal/playground_impl_mtl.mm index 421d6eba3c46b..00babefd4c047 100644 --- a/impeller/playground/backend/metal/playground_impl_mtl.mm +++ b/impeller/playground/backend/metal/playground_impl_mtl.mm @@ -73,9 +73,12 @@ if (!window) { return; } - auto context = - ContextMTL::Create(ShaderLibraryMappingsForPlayground(), - is_gpu_disabled_sync_switch_, "Playground Library"); + auto context = ContextMTL::Create( + ShaderLibraryMappingsForPlayground(), is_gpu_disabled_sync_switch_, + "Playground Library", + switches.enable_wide_gamut + ? std::optional(PixelFormat::kR16G16B16A16Float) + : std::nullopt); if (!context) { return; } diff --git a/impeller/playground/playground.cc b/impeller/playground/playground.cc index 4ed9e5af7efcb..cc11a98b50fa9 100644 --- a/impeller/playground/playground.cc +++ b/impeller/playground/playground.cc @@ -43,6 +43,8 @@ namespace impeller { std::string PlaygroundBackendToString(PlaygroundBackend backend) { switch (backend) { + case PlaygroundBackend::kMetalWideGamut: + return "MetalWideGamut"; case PlaygroundBackend::kMetal: return "Metal"; case PlaygroundBackend::kOpenGLES: @@ -98,6 +100,8 @@ std::shared_ptr Playground::MakeContext() const { bool Playground::SupportsBackend(PlaygroundBackend backend) { switch (backend) { + case PlaygroundBackend::kMetalWideGamut: + [[fallthrough]]; case PlaygroundBackend::kMetal: #if IMPELLER_ENABLE_METAL return true; diff --git a/impeller/playground/playground.h b/impeller/playground/playground.h index 9c6cde6467d6a..85fc34fe127b8 100644 --- a/impeller/playground/playground.h +++ b/impeller/playground/playground.h @@ -28,6 +28,7 @@ class PlaygroundImpl; enum class PlaygroundBackend { kMetal, + kMetalWideGamut, kOpenGLES, kVulkan, }; @@ -36,6 +37,8 @@ constexpr inline RuntimeStageBackend PlaygroundBackendToRuntimeStageBackend( PlaygroundBackend backend) { switch (backend) { case PlaygroundBackend::kMetal: + [[fallthrough]]; + case PlaygroundBackend::kMetalWideGamut: return RuntimeStageBackend::kMetal; case PlaygroundBackend::kOpenGLES: return RuntimeStageBackend::kOpenGLES; diff --git a/impeller/playground/playground_impl.cc b/impeller/playground/playground_impl.cc index 5abee6e07e24b..c25b469728f2e 100644 --- a/impeller/playground/playground_impl.cc +++ b/impeller/playground/playground_impl.cc @@ -27,6 +27,9 @@ std::unique_ptr PlaygroundImpl::Create( PlaygroundSwitches switches) { switch (backend) { #if IMPELLER_ENABLE_METAL + case PlaygroundBackend::kMetalWideGamut: + switches.enable_wide_gamut = true; + return std::make_unique(switches); case PlaygroundBackend::kMetal: return std::make_unique(switches); #endif // IMPELLER_ENABLE_METAL diff --git a/impeller/playground/playground_test.cc b/impeller/playground/playground_test.cc index 676c3b0412992..eaa9e03c56f12 100644 --- a/impeller/playground/playground_test.cc +++ b/impeller/playground/playground_test.cc @@ -62,6 +62,8 @@ std::string PlaygroundTest::GetWindowTitle() const { stream << "Impeller Playground for '" << flutter::testing::GetCurrentTestName() << "' "; switch (GetBackend()) { + case PlaygroundBackend::kMetalWideGamut: + [[fallthrough]]; case PlaygroundBackend::kMetal: break; case PlaygroundBackend::kOpenGLES: diff --git a/impeller/playground/playground_test.h b/impeller/playground/playground_test.h index cabb7dfd3abd5..8684d833f4b01 100644 --- a/impeller/playground/playground_test.h +++ b/impeller/playground/playground_test.h @@ -60,9 +60,9 @@ class PlaygroundTest : public Playground, ""; \ INSTANTIATE_TEST_SUITE_P( \ Play, playground, \ - ::testing::Values(PlaygroundBackend::kMetal, \ - PlaygroundBackend::kOpenGLES, \ - PlaygroundBackend::kVulkan), \ + ::testing::Values( \ + PlaygroundBackend::kMetal, PlaygroundBackend::kMetalWideGamut, \ + PlaygroundBackend::kOpenGLES, PlaygroundBackend::kVulkan), \ [](const ::testing::TestParamInfo& info) { \ return PlaygroundBackendToString(info.param); \ }); diff --git a/impeller/playground/switches.h b/impeller/playground/switches.h index be49fb0191a9b..6b9df55eb7642 100644 --- a/impeller/playground/switches.h +++ b/impeller/playground/switches.h @@ -33,6 +33,8 @@ struct PlaygroundSwitches { /// bool use_angle = false; + bool enable_wide_gamut = false; + PlaygroundSwitches(); explicit PlaygroundSwitches(const fml::CommandLine& args); diff --git a/impeller/renderer/backend/metal/context_mtl.h b/impeller/renderer/backend/metal/context_mtl.h index 6497871b28b25..dd11641665128 100644 --- a/impeller/renderer/backend/metal/context_mtl.h +++ b/impeller/renderer/backend/metal/context_mtl.h @@ -43,7 +43,8 @@ class ContextMTL final : public Context, static std::shared_ptr Create( const std::vector>& shader_libraries_data, std::shared_ptr is_gpu_disabled_sync_switch, - const std::string& label); + const std::string& label, + std::optional pixel_format_override = std::nullopt); static std::shared_ptr Create( id device, @@ -133,11 +134,11 @@ class ContextMTL final : public Context, std::shared_ptr command_queue_ip_; bool is_valid_ = false; - ContextMTL( - id device, - id command_queue, - NSArray>* shader_libraries, - std::shared_ptr is_gpu_disabled_sync_switch); + ContextMTL(id device, + id command_queue, + NSArray>* shader_libraries, + std::shared_ptr is_gpu_disabled_sync_switch, + std::optional pixel_format_override = std::nullopt); std::shared_ptr CreateCommandBufferInQueue( id queue) const; diff --git a/impeller/renderer/backend/metal/context_mtl.mm b/impeller/renderer/backend/metal/context_mtl.mm index 623f3c8335f4c..6248368687451 100644 --- a/impeller/renderer/backend/metal/context_mtl.mm +++ b/impeller/renderer/backend/metal/context_mtl.mm @@ -75,7 +75,8 @@ static bool DeviceSupportsComputeSubgroups(id device) { id device, id command_queue, NSArray>* shader_libraries, - std::shared_ptr is_gpu_disabled_sync_switch) + std::shared_ptr is_gpu_disabled_sync_switch, + std::optional pixel_format_override) : device_(device), command_queue_(command_queue), is_gpu_disabled_sync_switch_(std::move(is_gpu_disabled_sync_switch)) { @@ -128,7 +129,9 @@ static bool DeviceSupportsComputeSubgroups(id device) { } device_capabilities_ = - InferMetalCapabilities(device_, PixelFormat::kB8G8R8A8UNormInt); + InferMetalCapabilities(device_, pixel_format_override.has_value() + ? pixel_format_override.value() + : PixelFormat::kB8G8R8A8UNormInt); command_queue_ip_ = std::make_shared(); #ifdef IMPELLER_DEBUG gpu_tracer_ = std::make_shared(); @@ -238,17 +241,18 @@ static bool DeviceSupportsComputeSubgroups(id device) { std::shared_ptr ContextMTL::Create( const std::vector>& shader_libraries_data, std::shared_ptr is_gpu_disabled_sync_switch, - const std::string& library_label) { + const std::string& library_label, + std::optional pixel_format_override) { auto device = CreateMetalDevice(); auto command_queue = CreateMetalCommandQueue(device); if (!command_queue) { return nullptr; } - auto context = std::shared_ptr( - new ContextMTL(device, command_queue, - MTLShaderLibraryFromFileData(device, shader_libraries_data, - library_label), - std::move(is_gpu_disabled_sync_switch))); + auto context = std::shared_ptr(new ContextMTL( + device, command_queue, + MTLShaderLibraryFromFileData(device, shader_libraries_data, + library_label), + std::move(is_gpu_disabled_sync_switch), pixel_format_override)); if (!context->IsValid()) { FML_LOG(ERROR) << "Could not create Metal context."; return nullptr; diff --git a/impeller/runtime_stage/runtime_stage_unittests.cc b/impeller/runtime_stage/runtime_stage_unittests.cc index 8315c6af7c455..2c22b88d3f4b4 100644 --- a/impeller/runtime_stage/runtime_stage_unittests.cc +++ b/impeller/runtime_stage/runtime_stage_unittests.cc @@ -61,6 +61,8 @@ TEST_P(RuntimeStageTest, CanReadUniforms) { ASSERT_TRUE(stage->IsValid()); switch (GetBackend()) { + case PlaygroundBackend::kMetalWideGamut: + [[fallthrough]]; case PlaygroundBackend::kMetal: case PlaygroundBackend::kOpenGLES: { ASSERT_EQ(stage->GetUniforms().size(), 17u); diff --git a/testing/impeller_golden_tests_output.txt b/testing/impeller_golden_tests_output.txt index aae87f0f42e8c..38c6c7162396a 100644 --- a/testing/impeller_golden_tests_output.txt +++ b/testing/impeller_golden_tests_output.txt @@ -1,662 +1,885 @@ digest.json impeller_GoldenTests_ConicalGradient.png impeller_Play_AiksTest_BlendModeClear_Metal.png +impeller_Play_AiksTest_BlendModeClear_MetalWideGamut.png impeller_Play_AiksTest_BlendModeClear_OpenGLES.png impeller_Play_AiksTest_BlendModeClear_Vulkan.png impeller_Play_AiksTest_BlendModeColorBurn_Metal.png +impeller_Play_AiksTest_BlendModeColorBurn_MetalWideGamut.png impeller_Play_AiksTest_BlendModeColorBurn_OpenGLES.png impeller_Play_AiksTest_BlendModeColorBurn_Vulkan.png impeller_Play_AiksTest_BlendModeColorDodge_Metal.png +impeller_Play_AiksTest_BlendModeColorDodge_MetalWideGamut.png impeller_Play_AiksTest_BlendModeColorDodge_OpenGLES.png impeller_Play_AiksTest_BlendModeColorDodge_Vulkan.png impeller_Play_AiksTest_BlendModeColor_Metal.png +impeller_Play_AiksTest_BlendModeColor_MetalWideGamut.png impeller_Play_AiksTest_BlendModeColor_OpenGLES.png impeller_Play_AiksTest_BlendModeColor_Vulkan.png impeller_Play_AiksTest_BlendModeDarken_Metal.png +impeller_Play_AiksTest_BlendModeDarken_MetalWideGamut.png impeller_Play_AiksTest_BlendModeDarken_OpenGLES.png impeller_Play_AiksTest_BlendModeDarken_Vulkan.png impeller_Play_AiksTest_BlendModeDestinationATop_Metal.png +impeller_Play_AiksTest_BlendModeDestinationATop_MetalWideGamut.png impeller_Play_AiksTest_BlendModeDestinationATop_OpenGLES.png impeller_Play_AiksTest_BlendModeDestinationATop_Vulkan.png impeller_Play_AiksTest_BlendModeDestinationIn_Metal.png +impeller_Play_AiksTest_BlendModeDestinationIn_MetalWideGamut.png impeller_Play_AiksTest_BlendModeDestinationIn_OpenGLES.png impeller_Play_AiksTest_BlendModeDestinationIn_Vulkan.png impeller_Play_AiksTest_BlendModeDestinationOut_Metal.png +impeller_Play_AiksTest_BlendModeDestinationOut_MetalWideGamut.png impeller_Play_AiksTest_BlendModeDestinationOut_OpenGLES.png impeller_Play_AiksTest_BlendModeDestinationOut_Vulkan.png impeller_Play_AiksTest_BlendModeDestinationOver_Metal.png +impeller_Play_AiksTest_BlendModeDestinationOver_MetalWideGamut.png impeller_Play_AiksTest_BlendModeDestinationOver_OpenGLES.png impeller_Play_AiksTest_BlendModeDestinationOver_Vulkan.png impeller_Play_AiksTest_BlendModeDestination_Metal.png +impeller_Play_AiksTest_BlendModeDestination_MetalWideGamut.png impeller_Play_AiksTest_BlendModeDestination_OpenGLES.png impeller_Play_AiksTest_BlendModeDestination_Vulkan.png impeller_Play_AiksTest_BlendModeDifference_Metal.png +impeller_Play_AiksTest_BlendModeDifference_MetalWideGamut.png impeller_Play_AiksTest_BlendModeDifference_OpenGLES.png impeller_Play_AiksTest_BlendModeDifference_Vulkan.png impeller_Play_AiksTest_BlendModeExclusion_Metal.png +impeller_Play_AiksTest_BlendModeExclusion_MetalWideGamut.png impeller_Play_AiksTest_BlendModeExclusion_OpenGLES.png impeller_Play_AiksTest_BlendModeExclusion_Vulkan.png impeller_Play_AiksTest_BlendModeHardLight_Metal.png +impeller_Play_AiksTest_BlendModeHardLight_MetalWideGamut.png impeller_Play_AiksTest_BlendModeHardLight_OpenGLES.png impeller_Play_AiksTest_BlendModeHardLight_Vulkan.png impeller_Play_AiksTest_BlendModeHue_Metal.png +impeller_Play_AiksTest_BlendModeHue_MetalWideGamut.png impeller_Play_AiksTest_BlendModeHue_OpenGLES.png impeller_Play_AiksTest_BlendModeHue_Vulkan.png impeller_Play_AiksTest_BlendModeLighten_Metal.png +impeller_Play_AiksTest_BlendModeLighten_MetalWideGamut.png impeller_Play_AiksTest_BlendModeLighten_OpenGLES.png impeller_Play_AiksTest_BlendModeLighten_Vulkan.png impeller_Play_AiksTest_BlendModeLuminosity_Metal.png +impeller_Play_AiksTest_BlendModeLuminosity_MetalWideGamut.png impeller_Play_AiksTest_BlendModeLuminosity_OpenGLES.png impeller_Play_AiksTest_BlendModeLuminosity_Vulkan.png impeller_Play_AiksTest_BlendModeModulate_Metal.png +impeller_Play_AiksTest_BlendModeModulate_MetalWideGamut.png impeller_Play_AiksTest_BlendModeModulate_OpenGLES.png impeller_Play_AiksTest_BlendModeModulate_Vulkan.png impeller_Play_AiksTest_BlendModeMultiply_Metal.png +impeller_Play_AiksTest_BlendModeMultiply_MetalWideGamut.png impeller_Play_AiksTest_BlendModeMultiply_OpenGLES.png impeller_Play_AiksTest_BlendModeMultiply_Vulkan.png impeller_Play_AiksTest_BlendModeOverlay_Metal.png +impeller_Play_AiksTest_BlendModeOverlay_MetalWideGamut.png impeller_Play_AiksTest_BlendModeOverlay_OpenGLES.png impeller_Play_AiksTest_BlendModeOverlay_Vulkan.png +impeller_Play_AiksTest_BlendModePlusAlpha_Metal.png +impeller_Play_AiksTest_BlendModePlusAlpha_MetalWideGamut.png +impeller_Play_AiksTest_BlendModePlusAlpha_OpenGLES.png +impeller_Play_AiksTest_BlendModePlusAlpha_Vulkan.png impeller_Play_AiksTest_BlendModePlus_Metal.png +impeller_Play_AiksTest_BlendModePlus_MetalWideGamut.png impeller_Play_AiksTest_BlendModePlus_OpenGLES.png impeller_Play_AiksTest_BlendModePlus_Vulkan.png impeller_Play_AiksTest_BlendModeSaturation_Metal.png +impeller_Play_AiksTest_BlendModeSaturation_MetalWideGamut.png impeller_Play_AiksTest_BlendModeSaturation_OpenGLES.png impeller_Play_AiksTest_BlendModeSaturation_Vulkan.png impeller_Play_AiksTest_BlendModeScreen_Metal.png +impeller_Play_AiksTest_BlendModeScreen_MetalWideGamut.png impeller_Play_AiksTest_BlendModeScreen_OpenGLES.png impeller_Play_AiksTest_BlendModeScreen_Vulkan.png impeller_Play_AiksTest_BlendModeShouldCoverWholeScreen_Metal.png +impeller_Play_AiksTest_BlendModeShouldCoverWholeScreen_MetalWideGamut.png impeller_Play_AiksTest_BlendModeShouldCoverWholeScreen_OpenGLES.png impeller_Play_AiksTest_BlendModeShouldCoverWholeScreen_Vulkan.png impeller_Play_AiksTest_BlendModeSoftLight_Metal.png +impeller_Play_AiksTest_BlendModeSoftLight_MetalWideGamut.png impeller_Play_AiksTest_BlendModeSoftLight_OpenGLES.png impeller_Play_AiksTest_BlendModeSoftLight_Vulkan.png impeller_Play_AiksTest_BlendModeSourceATop_Metal.png +impeller_Play_AiksTest_BlendModeSourceATop_MetalWideGamut.png impeller_Play_AiksTest_BlendModeSourceATop_OpenGLES.png impeller_Play_AiksTest_BlendModeSourceATop_Vulkan.png impeller_Play_AiksTest_BlendModeSourceIn_Metal.png +impeller_Play_AiksTest_BlendModeSourceIn_MetalWideGamut.png impeller_Play_AiksTest_BlendModeSourceIn_OpenGLES.png impeller_Play_AiksTest_BlendModeSourceIn_Vulkan.png impeller_Play_AiksTest_BlendModeSourceOut_Metal.png +impeller_Play_AiksTest_BlendModeSourceOut_MetalWideGamut.png impeller_Play_AiksTest_BlendModeSourceOut_OpenGLES.png impeller_Play_AiksTest_BlendModeSourceOut_Vulkan.png impeller_Play_AiksTest_BlendModeSourceOver_Metal.png +impeller_Play_AiksTest_BlendModeSourceOver_MetalWideGamut.png impeller_Play_AiksTest_BlendModeSourceOver_OpenGLES.png impeller_Play_AiksTest_BlendModeSourceOver_Vulkan.png impeller_Play_AiksTest_BlendModeSource_Metal.png +impeller_Play_AiksTest_BlendModeSource_MetalWideGamut.png impeller_Play_AiksTest_BlendModeSource_OpenGLES.png impeller_Play_AiksTest_BlendModeSource_Vulkan.png impeller_Play_AiksTest_BlendModeXor_Metal.png +impeller_Play_AiksTest_BlendModeXor_MetalWideGamut.png impeller_Play_AiksTest_BlendModeXor_OpenGLES.png impeller_Play_AiksTest_BlendModeXor_Vulkan.png impeller_Play_AiksTest_BlurHasNoEdge_Metal.png +impeller_Play_AiksTest_BlurHasNoEdge_MetalWideGamut.png impeller_Play_AiksTest_BlurHasNoEdge_OpenGLES.png impeller_Play_AiksTest_BlurHasNoEdge_Vulkan.png impeller_Play_AiksTest_BlurredRectangleWithShader_Metal.png +impeller_Play_AiksTest_BlurredRectangleWithShader_MetalWideGamut.png impeller_Play_AiksTest_BlurredRectangleWithShader_OpenGLES.png impeller_Play_AiksTest_BlurredRectangleWithShader_Vulkan.png impeller_Play_AiksTest_CanDrawAnOpenPathThatIsntARect_Metal.png +impeller_Play_AiksTest_CanDrawAnOpenPathThatIsntARect_MetalWideGamut.png impeller_Play_AiksTest_CanDrawAnOpenPathThatIsntARect_OpenGLES.png impeller_Play_AiksTest_CanDrawAnOpenPathThatIsntARect_Vulkan.png impeller_Play_AiksTest_CanDrawAnOpenPath_Metal.png +impeller_Play_AiksTest_CanDrawAnOpenPath_MetalWideGamut.png impeller_Play_AiksTest_CanDrawAnOpenPath_OpenGLES.png impeller_Play_AiksTest_CanDrawAnOpenPath_Vulkan.png impeller_Play_AiksTest_CanDrawMultiContourConvexPath_Metal.png +impeller_Play_AiksTest_CanDrawMultiContourConvexPath_MetalWideGamut.png impeller_Play_AiksTest_CanDrawMultiContourConvexPath_OpenGLES.png impeller_Play_AiksTest_CanDrawMultiContourConvexPath_Vulkan.png impeller_Play_AiksTest_CanDrawPaintMultipleTimesInteractive_Metal.png +impeller_Play_AiksTest_CanDrawPaintMultipleTimesInteractive_MetalWideGamut.png impeller_Play_AiksTest_CanDrawPaintMultipleTimesInteractive_OpenGLES.png impeller_Play_AiksTest_CanDrawPaintMultipleTimesInteractive_Vulkan.png impeller_Play_AiksTest_CanDrawPaintMultipleTimes_Metal.png +impeller_Play_AiksTest_CanDrawPaintMultipleTimes_MetalWideGamut.png impeller_Play_AiksTest_CanDrawPaintMultipleTimes_OpenGLES.png impeller_Play_AiksTest_CanDrawPaintMultipleTimes_Vulkan.png impeller_Play_AiksTest_CanDrawPaintWithAdvancedBlend_Metal.png +impeller_Play_AiksTest_CanDrawPaintWithAdvancedBlend_MetalWideGamut.png impeller_Play_AiksTest_CanDrawPaintWithAdvancedBlend_OpenGLES.png impeller_Play_AiksTest_CanDrawPaintWithAdvancedBlend_Vulkan.png impeller_Play_AiksTest_CanDrawPaint_Metal.png +impeller_Play_AiksTest_CanDrawPaint_MetalWideGamut.png impeller_Play_AiksTest_CanDrawPaint_OpenGLES.png impeller_Play_AiksTest_CanDrawPaint_Vulkan.png impeller_Play_AiksTest_CanDrawPerspectiveTransformWithClips_Metal.png impeller_Play_AiksTest_CanDrawPerspectiveTransformWithClips_OpenGLES.png impeller_Play_AiksTest_CanDrawPerspectiveTransformWithClips_Vulkan.png impeller_Play_AiksTest_CanDrawPointsWithTextureMap_Metal.png +impeller_Play_AiksTest_CanDrawPointsWithTextureMap_MetalWideGamut.png impeller_Play_AiksTest_CanDrawPointsWithTextureMap_OpenGLES.png impeller_Play_AiksTest_CanDrawPointsWithTextureMap_Vulkan.png impeller_Play_AiksTest_CanDrawPoints_Metal.png +impeller_Play_AiksTest_CanDrawPoints_MetalWideGamut.png impeller_Play_AiksTest_CanDrawPoints_OpenGLES.png impeller_Play_AiksTest_CanDrawPoints_Vulkan.png impeller_Play_AiksTest_CanEmptyPictureConvertToImage_Metal.png +impeller_Play_AiksTest_CanEmptyPictureConvertToImage_MetalWideGamut.png impeller_Play_AiksTest_CanEmptyPictureConvertToImage_OpenGLES.png impeller_Play_AiksTest_CanEmptyPictureConvertToImage_Vulkan.png impeller_Play_AiksTest_CanPerformFullScreenMSAA_Metal.png +impeller_Play_AiksTest_CanPerformFullScreenMSAA_MetalWideGamut.png impeller_Play_AiksTest_CanPerformFullScreenMSAA_OpenGLES.png impeller_Play_AiksTest_CanPerformFullScreenMSAA_Vulkan.png impeller_Play_AiksTest_CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated_Metal.png +impeller_Play_AiksTest_CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated_MetalWideGamut.png impeller_Play_AiksTest_CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated_OpenGLES.png impeller_Play_AiksTest_CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated_Vulkan.png impeller_Play_AiksTest_CanPerformSaveLayerWithBounds_Metal.png +impeller_Play_AiksTest_CanPerformSaveLayerWithBounds_MetalWideGamut.png impeller_Play_AiksTest_CanPerformSaveLayerWithBounds_OpenGLES.png impeller_Play_AiksTest_CanPerformSaveLayerWithBounds_Vulkan.png impeller_Play_AiksTest_CanPerformSkew_Metal.png +impeller_Play_AiksTest_CanPerformSkew_MetalWideGamut.png impeller_Play_AiksTest_CanPerformSkew_OpenGLES.png impeller_Play_AiksTest_CanPerformSkew_Vulkan.png impeller_Play_AiksTest_CanPictureConvertToImage_Metal.png +impeller_Play_AiksTest_CanPictureConvertToImage_MetalWideGamut.png impeller_Play_AiksTest_CanPictureConvertToImage_OpenGLES.png impeller_Play_AiksTest_CanPictureConvertToImage_Vulkan.png impeller_Play_AiksTest_CanRenderAdvancedBlendColorFilterWithSaveLayer_Metal.png +impeller_Play_AiksTest_CanRenderAdvancedBlendColorFilterWithSaveLayer_MetalWideGamut.png impeller_Play_AiksTest_CanRenderAdvancedBlendColorFilterWithSaveLayer_OpenGLES.png impeller_Play_AiksTest_CanRenderAdvancedBlendColorFilterWithSaveLayer_Vulkan.png impeller_Play_AiksTest_CanRenderBackdropBlurHugeSigma_Metal.png +impeller_Play_AiksTest_CanRenderBackdropBlurHugeSigma_MetalWideGamut.png impeller_Play_AiksTest_CanRenderBackdropBlurHugeSigma_OpenGLES.png impeller_Play_AiksTest_CanRenderBackdropBlurHugeSigma_Vulkan.png impeller_Play_AiksTest_CanRenderBackdropBlurInteractive_Metal.png +impeller_Play_AiksTest_CanRenderBackdropBlurInteractive_MetalWideGamut.png impeller_Play_AiksTest_CanRenderBackdropBlurInteractive_OpenGLES.png impeller_Play_AiksTest_CanRenderBackdropBlurInteractive_Vulkan.png impeller_Play_AiksTest_CanRenderBackdropBlur_Metal.png +impeller_Play_AiksTest_CanRenderBackdropBlur_MetalWideGamut.png impeller_Play_AiksTest_CanRenderBackdropBlur_OpenGLES.png impeller_Play_AiksTest_CanRenderBackdropBlur_Vulkan.png impeller_Play_AiksTest_CanRenderClippedBlur_Metal.png +impeller_Play_AiksTest_CanRenderClippedBlur_MetalWideGamut.png impeller_Play_AiksTest_CanRenderClippedBlur_OpenGLES.png impeller_Play_AiksTest_CanRenderClippedBlur_Vulkan.png impeller_Play_AiksTest_CanRenderClippedLayers_Metal.png +impeller_Play_AiksTest_CanRenderClippedLayers_MetalWideGamut.png impeller_Play_AiksTest_CanRenderClippedLayers_OpenGLES.png impeller_Play_AiksTest_CanRenderClippedLayers_Vulkan.png impeller_Play_AiksTest_CanRenderClippedRuntimeEffects_Metal.png +impeller_Play_AiksTest_CanRenderClippedRuntimeEffects_MetalWideGamut.png impeller_Play_AiksTest_CanRenderClippedRuntimeEffects_OpenGLES.png impeller_Play_AiksTest_CanRenderClips_Metal.png +impeller_Play_AiksTest_CanRenderClips_MetalWideGamut.png impeller_Play_AiksTest_CanRenderClips_OpenGLES.png impeller_Play_AiksTest_CanRenderClips_Vulkan.png impeller_Play_AiksTest_CanRenderColorFilterWithInvertColorsDrawPaint_Metal.png +impeller_Play_AiksTest_CanRenderColorFilterWithInvertColorsDrawPaint_MetalWideGamut.png impeller_Play_AiksTest_CanRenderColorFilterWithInvertColorsDrawPaint_OpenGLES.png impeller_Play_AiksTest_CanRenderColorFilterWithInvertColorsDrawPaint_Vulkan.png impeller_Play_AiksTest_CanRenderColorFilterWithInvertColors_Metal.png +impeller_Play_AiksTest_CanRenderColorFilterWithInvertColors_MetalWideGamut.png impeller_Play_AiksTest_CanRenderColorFilterWithInvertColors_OpenGLES.png impeller_Play_AiksTest_CanRenderColorFilterWithInvertColors_Vulkan.png impeller_Play_AiksTest_CanRenderColoredRect_Metal.png +impeller_Play_AiksTest_CanRenderColoredRect_MetalWideGamut.png impeller_Play_AiksTest_CanRenderColoredRect_OpenGLES.png impeller_Play_AiksTest_CanRenderColoredRect_Vulkan.png impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringDisabled_Metal.png +impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringDisabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringDisabled_OpenGLES.png impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringDisabled_Vulkan.png impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringEnabled_Metal.png +impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringEnabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringEnabled_OpenGLES.png impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringEnabled_Vulkan.png impeller_Play_AiksTest_CanRenderConicalGradient_Metal.png +impeller_Play_AiksTest_CanRenderConicalGradient_MetalWideGamut.png impeller_Play_AiksTest_CanRenderConicalGradient_OpenGLES.png impeller_Play_AiksTest_CanRenderConicalGradient_Vulkan.png impeller_Play_AiksTest_CanRenderCurvedStrokes_Metal.png +impeller_Play_AiksTest_CanRenderCurvedStrokes_MetalWideGamut.png impeller_Play_AiksTest_CanRenderCurvedStrokes_OpenGLES.png impeller_Play_AiksTest_CanRenderCurvedStrokes_Vulkan.png impeller_Play_AiksTest_CanRenderDestructiveSaveLayer_Metal.png +impeller_Play_AiksTest_CanRenderDestructiveSaveLayer_MetalWideGamut.png impeller_Play_AiksTest_CanRenderDestructiveSaveLayer_OpenGLES.png impeller_Play_AiksTest_CanRenderDestructiveSaveLayer_Vulkan.png impeller_Play_AiksTest_CanRenderDifferenceClips_Metal.png +impeller_Play_AiksTest_CanRenderDifferenceClips_MetalWideGamut.png impeller_Play_AiksTest_CanRenderDifferenceClips_OpenGLES.png impeller_Play_AiksTest_CanRenderDifferenceClips_Vulkan.png impeller_Play_AiksTest_CanRenderDifferencePaths_Metal.png +impeller_Play_AiksTest_CanRenderDifferencePaths_MetalWideGamut.png impeller_Play_AiksTest_CanRenderDifferencePaths_OpenGLES.png impeller_Play_AiksTest_CanRenderDifferencePaths_Vulkan.png impeller_Play_AiksTest_CanRenderDifferentShapesWithSameColorSource_Metal.png +impeller_Play_AiksTest_CanRenderDifferentShapesWithSameColorSource_MetalWideGamut.png impeller_Play_AiksTest_CanRenderDifferentShapesWithSameColorSource_OpenGLES.png impeller_Play_AiksTest_CanRenderDifferentShapesWithSameColorSource_Vulkan.png impeller_Play_AiksTest_CanRenderEmojiTextFrameWithAlpha_Metal.png +impeller_Play_AiksTest_CanRenderEmojiTextFrameWithAlpha_MetalWideGamut.png impeller_Play_AiksTest_CanRenderEmojiTextFrameWithAlpha_OpenGLES.png impeller_Play_AiksTest_CanRenderEmojiTextFrameWithAlpha_Vulkan.png impeller_Play_AiksTest_CanRenderEmojiTextFrameWithBlur_Metal.png +impeller_Play_AiksTest_CanRenderEmojiTextFrameWithBlur_MetalWideGamut.png impeller_Play_AiksTest_CanRenderEmojiTextFrameWithBlur_OpenGLES.png impeller_Play_AiksTest_CanRenderEmojiTextFrameWithBlur_Vulkan.png impeller_Play_AiksTest_CanRenderEmojiTextFrame_Metal.png +impeller_Play_AiksTest_CanRenderEmojiTextFrame_MetalWideGamut.png impeller_Play_AiksTest_CanRenderEmojiTextFrame_OpenGLES.png impeller_Play_AiksTest_CanRenderEmojiTextFrame_Vulkan.png impeller_Play_AiksTest_CanRenderForegroundAdvancedBlendWithMaskBlur_Metal.png +impeller_Play_AiksTest_CanRenderForegroundAdvancedBlendWithMaskBlur_MetalWideGamut.png impeller_Play_AiksTest_CanRenderForegroundAdvancedBlendWithMaskBlur_OpenGLES.png impeller_Play_AiksTest_CanRenderForegroundAdvancedBlendWithMaskBlur_Vulkan.png impeller_Play_AiksTest_CanRenderForegroundBlendWithMaskBlur_Metal.png +impeller_Play_AiksTest_CanRenderForegroundBlendWithMaskBlur_MetalWideGamut.png impeller_Play_AiksTest_CanRenderForegroundBlendWithMaskBlur_OpenGLES.png impeller_Play_AiksTest_CanRenderForegroundBlendWithMaskBlur_Vulkan.png impeller_Play_AiksTest_CanRenderGradientDecalWithBackground_Metal.png +impeller_Play_AiksTest_CanRenderGradientDecalWithBackground_MetalWideGamut.png impeller_Play_AiksTest_CanRenderGradientDecalWithBackground_OpenGLES.png impeller_Play_AiksTest_CanRenderGradientDecalWithBackground_Vulkan.png impeller_Play_AiksTest_CanRenderGroupOpacity_Metal.png +impeller_Play_AiksTest_CanRenderGroupOpacity_MetalWideGamut.png impeller_Play_AiksTest_CanRenderGroupOpacity_OpenGLES.png impeller_Play_AiksTest_CanRenderGroupOpacity_Vulkan.png impeller_Play_AiksTest_CanRenderImageRect_Metal.png +impeller_Play_AiksTest_CanRenderImageRect_MetalWideGamut.png impeller_Play_AiksTest_CanRenderImageRect_OpenGLES.png impeller_Play_AiksTest_CanRenderImageRect_Vulkan.png impeller_Play_AiksTest_CanRenderImage_Metal.png +impeller_Play_AiksTest_CanRenderImage_MetalWideGamut.png impeller_Play_AiksTest_CanRenderImage_OpenGLES.png impeller_Play_AiksTest_CanRenderImage_Vulkan.png impeller_Play_AiksTest_CanRenderInvertedImageWithColorFilter_Metal.png +impeller_Play_AiksTest_CanRenderInvertedImageWithColorFilter_MetalWideGamut.png impeller_Play_AiksTest_CanRenderInvertedImageWithColorFilter_OpenGLES.png impeller_Play_AiksTest_CanRenderInvertedImageWithColorFilter_Vulkan.png impeller_Play_AiksTest_CanRenderItalicizedText_Metal.png +impeller_Play_AiksTest_CanRenderItalicizedText_MetalWideGamut.png impeller_Play_AiksTest_CanRenderItalicizedText_OpenGLES.png impeller_Play_AiksTest_CanRenderItalicizedText_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientClamp_Metal.png +impeller_Play_AiksTest_CanRenderLinearGradientClamp_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientClamp_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientClamp_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientDecalWithColorFilter_Metal.png +impeller_Play_AiksTest_CanRenderLinearGradientDecalWithColorFilter_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientDecalWithColorFilter_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientDecalWithColorFilter_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientDecal_Metal.png +impeller_Play_AiksTest_CanRenderLinearGradientDecal_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientDecal_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientDecal_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsClamp_Metal.png +impeller_Play_AiksTest_CanRenderLinearGradientManyColorsClamp_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsClamp_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsClamp_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsDecal_Metal.png +impeller_Play_AiksTest_CanRenderLinearGradientManyColorsDecal_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsDecal_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsDecal_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsMirror_Metal.png +impeller_Play_AiksTest_CanRenderLinearGradientManyColorsMirror_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsMirror_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsMirror_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsRepeat_Metal.png +impeller_Play_AiksTest_CanRenderLinearGradientManyColorsRepeat_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsRepeat_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsRepeat_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsUnevenStops_Metal.png +impeller_Play_AiksTest_CanRenderLinearGradientManyColorsUnevenStops_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsUnevenStops_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsUnevenStops_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientMaskBlur_Metal.png +impeller_Play_AiksTest_CanRenderLinearGradientMaskBlur_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientMaskBlur_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientMaskBlur_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientMirror_Metal.png +impeller_Play_AiksTest_CanRenderLinearGradientMirror_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientMirror_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientMirror_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientRepeat_Metal.png +impeller_Play_AiksTest_CanRenderLinearGradientRepeat_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientRepeat_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientRepeat_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientWayManyColorsClamp_Metal.png +impeller_Play_AiksTest_CanRenderLinearGradientWayManyColorsClamp_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientWayManyColorsClamp_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientWayManyColorsClamp_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringDisabled_Metal.png +impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringDisabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringDisabled_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringDisabled_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringEnabled_Metal.png +impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringEnabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringEnabled_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringEnabled_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientWithOverlappingStopsClamp_Metal.png +impeller_Play_AiksTest_CanRenderLinearGradientWithOverlappingStopsClamp_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientWithOverlappingStopsClamp_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientWithOverlappingStopsClamp_Vulkan.png impeller_Play_AiksTest_CanRenderMaskBlurHugeSigma_Metal.png +impeller_Play_AiksTest_CanRenderMaskBlurHugeSigma_MetalWideGamut.png impeller_Play_AiksTest_CanRenderMaskBlurHugeSigma_OpenGLES.png impeller_Play_AiksTest_CanRenderMaskBlurHugeSigma_Vulkan.png impeller_Play_AiksTest_CanRenderNestedClips_Metal.png +impeller_Play_AiksTest_CanRenderNestedClips_MetalWideGamut.png impeller_Play_AiksTest_CanRenderNestedClips_OpenGLES.png impeller_Play_AiksTest_CanRenderNestedClips_Vulkan.png impeller_Play_AiksTest_CanRenderOffscreenCheckerboard_Metal.png +impeller_Play_AiksTest_CanRenderOffscreenCheckerboard_MetalWideGamut.png impeller_Play_AiksTest_CanRenderOffscreenCheckerboard_OpenGLES.png impeller_Play_AiksTest_CanRenderOffscreenCheckerboard_Vulkan.png impeller_Play_AiksTest_CanRenderOverlappingMultiContourPath_Metal.png +impeller_Play_AiksTest_CanRenderOverlappingMultiContourPath_MetalWideGamut.png impeller_Play_AiksTest_CanRenderOverlappingMultiContourPath_OpenGLES.png impeller_Play_AiksTest_CanRenderOverlappingMultiContourPath_Vulkan.png impeller_Play_AiksTest_CanRenderRadialGradientManyColors_Metal.png +impeller_Play_AiksTest_CanRenderRadialGradientManyColors_MetalWideGamut.png impeller_Play_AiksTest_CanRenderRadialGradientManyColors_OpenGLES.png impeller_Play_AiksTest_CanRenderRadialGradientManyColors_Vulkan.png impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringDisabled_Metal.png +impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringDisabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringDisabled_OpenGLES.png impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringDisabled_Vulkan.png impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringEnabled_Metal.png +impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringEnabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringEnabled_OpenGLES.png impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringEnabled_Vulkan.png impeller_Play_AiksTest_CanRenderRadialGradient_Metal.png +impeller_Play_AiksTest_CanRenderRadialGradient_MetalWideGamut.png impeller_Play_AiksTest_CanRenderRadialGradient_OpenGLES.png impeller_Play_AiksTest_CanRenderRadialGradient_Vulkan.png impeller_Play_AiksTest_CanRenderRoundedRectWithNonUniformRadii_Metal.png +impeller_Play_AiksTest_CanRenderRoundedRectWithNonUniformRadii_MetalWideGamut.png impeller_Play_AiksTest_CanRenderRoundedRectWithNonUniformRadii_OpenGLES.png impeller_Play_AiksTest_CanRenderRoundedRectWithNonUniformRadii_Vulkan.png impeller_Play_AiksTest_CanRenderSimpleClips_Metal.png +impeller_Play_AiksTest_CanRenderSimpleClips_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSimpleClips_OpenGLES.png impeller_Play_AiksTest_CanRenderSimpleClips_Vulkan.png impeller_Play_AiksTest_CanRenderStrokePathThatEndsAtSharpTurn_Metal.png +impeller_Play_AiksTest_CanRenderStrokePathThatEndsAtSharpTurn_MetalWideGamut.png impeller_Play_AiksTest_CanRenderStrokePathThatEndsAtSharpTurn_OpenGLES.png impeller_Play_AiksTest_CanRenderStrokePathThatEndsAtSharpTurn_Vulkan.png impeller_Play_AiksTest_CanRenderStrokePathWithCubicLine_Metal.png +impeller_Play_AiksTest_CanRenderStrokePathWithCubicLine_MetalWideGamut.png impeller_Play_AiksTest_CanRenderStrokePathWithCubicLine_OpenGLES.png impeller_Play_AiksTest_CanRenderStrokePathWithCubicLine_Vulkan.png impeller_Play_AiksTest_CanRenderStrokes_Metal.png +impeller_Play_AiksTest_CanRenderStrokes_MetalWideGamut.png impeller_Play_AiksTest_CanRenderStrokes_OpenGLES.png impeller_Play_AiksTest_CanRenderStrokes_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientClamp_Metal.png +impeller_Play_AiksTest_CanRenderSweepGradientClamp_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientClamp_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientClamp_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientDecal_Metal.png +impeller_Play_AiksTest_CanRenderSweepGradientDecal_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientDecal_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientDecal_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsClamp_Metal.png +impeller_Play_AiksTest_CanRenderSweepGradientManyColorsClamp_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsClamp_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsClamp_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsDecal_Metal.png +impeller_Play_AiksTest_CanRenderSweepGradientManyColorsDecal_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsDecal_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsDecal_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsMirror_Metal.png +impeller_Play_AiksTest_CanRenderSweepGradientManyColorsMirror_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsMirror_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsMirror_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsRepeat_Metal.png +impeller_Play_AiksTest_CanRenderSweepGradientManyColorsRepeat_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsRepeat_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsRepeat_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientMirror_Metal.png +impeller_Play_AiksTest_CanRenderSweepGradientMirror_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientMirror_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientMirror_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientRepeat_Metal.png +impeller_Play_AiksTest_CanRenderSweepGradientRepeat_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientRepeat_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientRepeat_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringDisabled_Metal.png +impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringDisabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringDisabled_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringDisabled_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringEnabled_Metal.png +impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringEnabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringEnabled_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringEnabled_Vulkan.png impeller_Play_AiksTest_CanRenderTextFrameSTB_Metal.png +impeller_Play_AiksTest_CanRenderTextFrameSTB_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTextFrameSTB_OpenGLES.png impeller_Play_AiksTest_CanRenderTextFrameSTB_Vulkan.png impeller_Play_AiksTest_CanRenderTextFrame_Metal.png +impeller_Play_AiksTest_CanRenderTextFrame_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTextFrame_OpenGLES.png impeller_Play_AiksTest_CanRenderTextFrame_Vulkan.png impeller_Play_AiksTest_CanRenderTextInSaveLayer_Metal.png +impeller_Play_AiksTest_CanRenderTextInSaveLayer_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTextInSaveLayer_OpenGLES.png impeller_Play_AiksTest_CanRenderTextInSaveLayer_Vulkan.png impeller_Play_AiksTest_CanRenderTextOutsideBoundaries_Metal.png +impeller_Play_AiksTest_CanRenderTextOutsideBoundaries_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTextOutsideBoundaries_OpenGLES.png impeller_Play_AiksTest_CanRenderTextOutsideBoundaries_Vulkan.png impeller_Play_AiksTest_CanRenderThickCurvedStrokes_Metal.png +impeller_Play_AiksTest_CanRenderThickCurvedStrokes_MetalWideGamut.png impeller_Play_AiksTest_CanRenderThickCurvedStrokes_OpenGLES.png impeller_Play_AiksTest_CanRenderThickCurvedStrokes_Vulkan.png impeller_Play_AiksTest_CanRenderTiledTextureClampWithTranslate_Metal.png +impeller_Play_AiksTest_CanRenderTiledTextureClampWithTranslate_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTiledTextureClampWithTranslate_OpenGLES.png impeller_Play_AiksTest_CanRenderTiledTextureClampWithTranslate_Vulkan.png impeller_Play_AiksTest_CanRenderTiledTextureClamp_Metal.png +impeller_Play_AiksTest_CanRenderTiledTextureClamp_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTiledTextureClamp_OpenGLES.png impeller_Play_AiksTest_CanRenderTiledTextureClamp_Vulkan.png impeller_Play_AiksTest_CanRenderTiledTextureDecal_Metal.png +impeller_Play_AiksTest_CanRenderTiledTextureDecal_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTiledTextureDecal_OpenGLES.png impeller_Play_AiksTest_CanRenderTiledTextureDecal_Vulkan.png impeller_Play_AiksTest_CanRenderTiledTextureMirror_Metal.png +impeller_Play_AiksTest_CanRenderTiledTextureMirror_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTiledTextureMirror_OpenGLES.png impeller_Play_AiksTest_CanRenderTiledTextureMirror_Vulkan.png impeller_Play_AiksTest_CanRenderTiledTextureRepeat_Metal.png +impeller_Play_AiksTest_CanRenderTiledTextureRepeat_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTiledTextureRepeat_OpenGLES.png impeller_Play_AiksTest_CanRenderTiledTextureRepeat_Vulkan.png impeller_Play_AiksTest_CanRenderTinyOverlappingSubpasses_Metal.png +impeller_Play_AiksTest_CanRenderTinyOverlappingSubpasses_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTinyOverlappingSubpasses_OpenGLES.png impeller_Play_AiksTest_CanRenderTinyOverlappingSubpasses_Vulkan.png impeller_Play_AiksTest_CanRenderWithContiguousClipRestores_Metal.png +impeller_Play_AiksTest_CanRenderWithContiguousClipRestores_MetalWideGamut.png impeller_Play_AiksTest_CanRenderWithContiguousClipRestores_OpenGLES.png impeller_Play_AiksTest_CanRenderWithContiguousClipRestores_Vulkan.png impeller_Play_AiksTest_CanSaveLayerStandalone_Metal.png +impeller_Play_AiksTest_CanSaveLayerStandalone_MetalWideGamut.png impeller_Play_AiksTest_CanSaveLayerStandalone_OpenGLES.png impeller_Play_AiksTest_CanSaveLayerStandalone_Vulkan.png impeller_Play_AiksTest_CaptureContext_Metal.png +impeller_Play_AiksTest_CaptureContext_MetalWideGamut.png impeller_Play_AiksTest_CaptureContext_OpenGLES.png impeller_Play_AiksTest_CaptureContext_Vulkan.png impeller_Play_AiksTest_ClearBlendWithBlur_Metal.png +impeller_Play_AiksTest_ClearBlendWithBlur_MetalWideGamut.png impeller_Play_AiksTest_ClearBlendWithBlur_OpenGLES.png impeller_Play_AiksTest_ClearBlendWithBlur_Vulkan.png impeller_Play_AiksTest_ClearColorOptimizationWhenSubpassIsBiggerThanParentPass_Metal.png +impeller_Play_AiksTest_ClearColorOptimizationWhenSubpassIsBiggerThanParentPass_MetalWideGamut.png impeller_Play_AiksTest_ClearColorOptimizationWhenSubpassIsBiggerThanParentPass_OpenGLES.png impeller_Play_AiksTest_ClearColorOptimizationWhenSubpassIsBiggerThanParentPass_Vulkan.png impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectlyInteractive_Metal.png +impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectlyInteractive_MetalWideGamut.png impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectlyInteractive_OpenGLES.png impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectlyInteractive_Vulkan.png impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectly_Metal.png +impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectly_MetalWideGamut.png impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectly_OpenGLES.png impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectly_Vulkan.png impeller_Play_AiksTest_ClipsUseCurrentTransform_Metal.png +impeller_Play_AiksTest_ClipsUseCurrentTransform_MetalWideGamut.png impeller_Play_AiksTest_ClipsUseCurrentTransform_OpenGLES.png impeller_Play_AiksTest_ClipsUseCurrentTransform_Vulkan.png impeller_Play_AiksTest_CollapsedDrawPaintInSubpassBackdropFilter_Metal.png +impeller_Play_AiksTest_CollapsedDrawPaintInSubpassBackdropFilter_MetalWideGamut.png impeller_Play_AiksTest_CollapsedDrawPaintInSubpassBackdropFilter_OpenGLES.png impeller_Play_AiksTest_CollapsedDrawPaintInSubpassBackdropFilter_Vulkan.png impeller_Play_AiksTest_CollapsedDrawPaintInSubpass_Metal.png +impeller_Play_AiksTest_CollapsedDrawPaintInSubpass_MetalWideGamut.png impeller_Play_AiksTest_CollapsedDrawPaintInSubpass_OpenGLES.png impeller_Play_AiksTest_CollapsedDrawPaintInSubpass_Vulkan.png impeller_Play_AiksTest_ColorMatrixFilterSubpassCollapseOptimization_Metal.png +impeller_Play_AiksTest_ColorMatrixFilterSubpassCollapseOptimization_MetalWideGamut.png impeller_Play_AiksTest_ColorMatrixFilterSubpassCollapseOptimization_OpenGLES.png impeller_Play_AiksTest_ColorMatrixFilterSubpassCollapseOptimization_Vulkan.png impeller_Play_AiksTest_ColorWheel_Metal.png +impeller_Play_AiksTest_ColorWheel_MetalWideGamut.png impeller_Play_AiksTest_ColorWheel_OpenGLES.png impeller_Play_AiksTest_ColorWheel_Vulkan.png impeller_Play_AiksTest_CoordinateConversionsAreCorrect_Metal.png +impeller_Play_AiksTest_CoordinateConversionsAreCorrect_MetalWideGamut.png impeller_Play_AiksTest_CoordinateConversionsAreCorrect_OpenGLES.png impeller_Play_AiksTest_CoordinateConversionsAreCorrect_Vulkan.png impeller_Play_AiksTest_CoverageOriginShouldBeAccountedForInSubpasses_Metal.png +impeller_Play_AiksTest_CoverageOriginShouldBeAccountedForInSubpasses_MetalWideGamut.png impeller_Play_AiksTest_CoverageOriginShouldBeAccountedForInSubpasses_OpenGLES.png impeller_Play_AiksTest_CoverageOriginShouldBeAccountedForInSubpasses_Vulkan.png impeller_Play_AiksTest_DrawAdvancedBlendPartlyOffscreen_Metal.png +impeller_Play_AiksTest_DrawAdvancedBlendPartlyOffscreen_MetalWideGamut.png impeller_Play_AiksTest_DrawAdvancedBlendPartlyOffscreen_OpenGLES.png impeller_Play_AiksTest_DrawAdvancedBlendPartlyOffscreen_Vulkan.png impeller_Play_AiksTest_DrawAtlasAdvancedAndTransform_Metal.png +impeller_Play_AiksTest_DrawAtlasAdvancedAndTransform_MetalWideGamut.png impeller_Play_AiksTest_DrawAtlasAdvancedAndTransform_OpenGLES.png impeller_Play_AiksTest_DrawAtlasAdvancedAndTransform_Vulkan.png impeller_Play_AiksTest_DrawAtlasWithColorAdvancedAndTransform_Metal.png +impeller_Play_AiksTest_DrawAtlasWithColorAdvancedAndTransform_MetalWideGamut.png impeller_Play_AiksTest_DrawAtlasWithColorAdvancedAndTransform_OpenGLES.png impeller_Play_AiksTest_DrawAtlasWithColorAdvancedAndTransform_Vulkan.png impeller_Play_AiksTest_DrawLinesRenderCorrectly_Metal.png +impeller_Play_AiksTest_DrawLinesRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_DrawLinesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_DrawLinesRenderCorrectly_Vulkan.png impeller_Play_AiksTest_DrawPaintTransformsBounds_Metal.png +impeller_Play_AiksTest_DrawPaintTransformsBounds_MetalWideGamut.png impeller_Play_AiksTest_DrawPaintTransformsBounds_OpenGLES.png impeller_Play_AiksTest_DrawPaintTransformsBounds_Vulkan.png impeller_Play_AiksTest_DrawPaintWithAdvancedBlendOverFilter_Metal.png +impeller_Play_AiksTest_DrawPaintWithAdvancedBlendOverFilter_MetalWideGamut.png impeller_Play_AiksTest_DrawPaintWithAdvancedBlendOverFilter_OpenGLES.png impeller_Play_AiksTest_DrawPaintWithAdvancedBlendOverFilter_Vulkan.png impeller_Play_AiksTest_DrawRectStrokesRenderCorrectly_Metal.png +impeller_Play_AiksTest_DrawRectStrokesRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_DrawRectStrokesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_DrawRectStrokesRenderCorrectly_Vulkan.png impeller_Play_AiksTest_DrawRectStrokesWithBevelJoinRenderCorrectly_Metal.png +impeller_Play_AiksTest_DrawRectStrokesWithBevelJoinRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_DrawRectStrokesWithBevelJoinRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_DrawRectStrokesWithBevelJoinRenderCorrectly_Vulkan.png impeller_Play_AiksTest_DrawScaledTextWithPerspectiveNoSaveLayer_Metal.png +impeller_Play_AiksTest_DrawScaledTextWithPerspectiveNoSaveLayer_MetalWideGamut.png impeller_Play_AiksTest_DrawScaledTextWithPerspectiveNoSaveLayer_OpenGLES.png impeller_Play_AiksTest_DrawScaledTextWithPerspectiveNoSaveLayer_Vulkan.png impeller_Play_AiksTest_DrawScaledTextWithPerspectiveSaveLayer_Metal.png +impeller_Play_AiksTest_DrawScaledTextWithPerspectiveSaveLayer_MetalWideGamut.png impeller_Play_AiksTest_DrawScaledTextWithPerspectiveSaveLayer_OpenGLES.png impeller_Play_AiksTest_DrawScaledTextWithPerspectiveSaveLayer_Vulkan.png impeller_Play_AiksTest_EmptySaveLayerIgnoresPaint_Metal.png +impeller_Play_AiksTest_EmptySaveLayerIgnoresPaint_MetalWideGamut.png impeller_Play_AiksTest_EmptySaveLayerIgnoresPaint_OpenGLES.png impeller_Play_AiksTest_EmptySaveLayerIgnoresPaint_Vulkan.png impeller_Play_AiksTest_EmptySaveLayerRendersWithClear_Metal.png +impeller_Play_AiksTest_EmptySaveLayerRendersWithClear_MetalWideGamut.png impeller_Play_AiksTest_EmptySaveLayerRendersWithClear_OpenGLES.png impeller_Play_AiksTest_EmptySaveLayerRendersWithClear_Vulkan.png impeller_Play_AiksTest_FilledCirclesRenderCorrectly_Metal.png +impeller_Play_AiksTest_FilledCirclesRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_FilledCirclesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_FilledCirclesRenderCorrectly_Vulkan.png impeller_Play_AiksTest_FilledEllipsesRenderCorrectly_Metal.png +impeller_Play_AiksTest_FilledEllipsesRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_FilledEllipsesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_FilledEllipsesRenderCorrectly_Vulkan.png impeller_Play_AiksTest_FilledRoundRectPathsRenderCorrectly_Metal.png +impeller_Play_AiksTest_FilledRoundRectPathsRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_FilledRoundRectPathsRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_FilledRoundRectPathsRenderCorrectly_Vulkan.png impeller_Play_AiksTest_FilledRoundRectsRenderCorrectly_Metal.png +impeller_Play_AiksTest_FilledRoundRectsRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_FilledRoundRectsRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_FilledRoundRectsRenderCorrectly_Vulkan.png impeller_Play_AiksTest_ForegroundBlendSubpassCollapseOptimization_Metal.png +impeller_Play_AiksTest_ForegroundBlendSubpassCollapseOptimization_MetalWideGamut.png impeller_Play_AiksTest_ForegroundBlendSubpassCollapseOptimization_OpenGLES.png impeller_Play_AiksTest_ForegroundBlendSubpassCollapseOptimization_Vulkan.png impeller_Play_AiksTest_GaussianBlurAnimatedBackdrop_Metal.png +impeller_Play_AiksTest_GaussianBlurAnimatedBackdrop_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurAnimatedBackdrop_OpenGLES.png impeller_Play_AiksTest_GaussianBlurAnimatedBackdrop_Vulkan.png impeller_Play_AiksTest_GaussianBlurAtPeripheryHorizontal_Metal.png +impeller_Play_AiksTest_GaussianBlurAtPeripheryHorizontal_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurAtPeripheryHorizontal_OpenGLES.png impeller_Play_AiksTest_GaussianBlurAtPeripheryHorizontal_Vulkan.png impeller_Play_AiksTest_GaussianBlurAtPeripheryVertical_Metal.png +impeller_Play_AiksTest_GaussianBlurAtPeripheryVertical_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurAtPeripheryVertical_OpenGLES.png impeller_Play_AiksTest_GaussianBlurAtPeripheryVertical_Vulkan.png impeller_Play_AiksTest_GaussianBlurOneDimension_Metal.png +impeller_Play_AiksTest_GaussianBlurOneDimension_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurOneDimension_OpenGLES.png impeller_Play_AiksTest_GaussianBlurOneDimension_Vulkan.png impeller_Play_AiksTest_GaussianBlurRotatedAndClippedInteractive_Metal.png +impeller_Play_AiksTest_GaussianBlurRotatedAndClippedInteractive_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurRotatedAndClippedInteractive_OpenGLES.png impeller_Play_AiksTest_GaussianBlurRotatedAndClippedInteractive_Vulkan.png impeller_Play_AiksTest_GaussianBlurRotatedAndClipped_Metal.png +impeller_Play_AiksTest_GaussianBlurRotatedAndClipped_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurRotatedAndClipped_OpenGLES.png impeller_Play_AiksTest_GaussianBlurRotatedAndClipped_Vulkan.png impeller_Play_AiksTest_GaussianBlurScaledAndClipped_Metal.png +impeller_Play_AiksTest_GaussianBlurScaledAndClipped_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurScaledAndClipped_OpenGLES.png impeller_Play_AiksTest_GaussianBlurScaledAndClipped_Vulkan.png impeller_Play_AiksTest_GaussianBlurStyleInnerGradient_Metal.png +impeller_Play_AiksTest_GaussianBlurStyleInnerGradient_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurStyleInnerGradient_OpenGLES.png impeller_Play_AiksTest_GaussianBlurStyleInnerGradient_Vulkan.png impeller_Play_AiksTest_GaussianBlurStyleInner_Metal.png +impeller_Play_AiksTest_GaussianBlurStyleInner_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurStyleInner_OpenGLES.png impeller_Play_AiksTest_GaussianBlurStyleInner_Vulkan.png impeller_Play_AiksTest_GaussianBlurStyleOuterGradient_Metal.png +impeller_Play_AiksTest_GaussianBlurStyleOuterGradient_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurStyleOuterGradient_OpenGLES.png impeller_Play_AiksTest_GaussianBlurStyleOuterGradient_Vulkan.png impeller_Play_AiksTest_GaussianBlurStyleOuter_Metal.png +impeller_Play_AiksTest_GaussianBlurStyleOuter_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurStyleOuter_OpenGLES.png impeller_Play_AiksTest_GaussianBlurStyleOuter_Vulkan.png impeller_Play_AiksTest_GaussianBlurStyleSolidGradient_Metal.png +impeller_Play_AiksTest_GaussianBlurStyleSolidGradient_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurStyleSolidGradient_OpenGLES.png impeller_Play_AiksTest_GaussianBlurStyleSolidGradient_Vulkan.png impeller_Play_AiksTest_GaussianBlurStyleSolid_Metal.png +impeller_Play_AiksTest_GaussianBlurStyleSolid_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurStyleSolid_OpenGLES.png impeller_Play_AiksTest_GaussianBlurStyleSolid_Vulkan.png impeller_Play_AiksTest_GaussianBlurWithoutDecalSupport_Metal.png impeller_Play_AiksTest_GradientStrokesRenderCorrectly_Metal.png +impeller_Play_AiksTest_GradientStrokesRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_GradientStrokesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_GradientStrokesRenderCorrectly_Vulkan.png impeller_Play_AiksTest_GuassianBlurUpdatesMipmapContents_Metal.png +impeller_Play_AiksTest_GuassianBlurUpdatesMipmapContents_MetalWideGamut.png impeller_Play_AiksTest_GuassianBlurUpdatesMipmapContents_OpenGLES.png impeller_Play_AiksTest_GuassianBlurUpdatesMipmapContents_Vulkan.png impeller_Play_AiksTest_ImageColorSourceEffectTransform_Metal.png +impeller_Play_AiksTest_ImageColorSourceEffectTransform_MetalWideGamut.png impeller_Play_AiksTest_ImageColorSourceEffectTransform_OpenGLES.png impeller_Play_AiksTest_ImageColorSourceEffectTransform_Vulkan.png impeller_Play_AiksTest_ImageFilteredSaveLayerWithUnboundedContents_Metal.png +impeller_Play_AiksTest_ImageFilteredSaveLayerWithUnboundedContents_MetalWideGamut.png impeller_Play_AiksTest_ImageFilteredSaveLayerWithUnboundedContents_OpenGLES.png impeller_Play_AiksTest_ImageFilteredSaveLayerWithUnboundedContents_Vulkan.png impeller_Play_AiksTest_ImageFilteredUnboundedSaveLayerWithUnboundedContents_Metal.png +impeller_Play_AiksTest_ImageFilteredUnboundedSaveLayerWithUnboundedContents_MetalWideGamut.png impeller_Play_AiksTest_ImageFilteredUnboundedSaveLayerWithUnboundedContents_OpenGLES.png impeller_Play_AiksTest_ImageFilteredUnboundedSaveLayerWithUnboundedContents_Vulkan.png impeller_Play_AiksTest_LinearToSrgbFilterSubpassCollapseOptimization_Metal.png +impeller_Play_AiksTest_LinearToSrgbFilterSubpassCollapseOptimization_MetalWideGamut.png impeller_Play_AiksTest_LinearToSrgbFilterSubpassCollapseOptimization_OpenGLES.png impeller_Play_AiksTest_LinearToSrgbFilterSubpassCollapseOptimization_Vulkan.png impeller_Play_AiksTest_MaskBlurDoesntStretchContents_Metal.png impeller_Play_AiksTest_MaskBlurDoesntStretchContents_OpenGLES.png impeller_Play_AiksTest_MaskBlurDoesntStretchContents_Vulkan.png impeller_Play_AiksTest_MaskBlurTexture_Metal.png +impeller_Play_AiksTest_MaskBlurTexture_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurTexture_OpenGLES.png impeller_Play_AiksTest_MaskBlurTexture_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucentWithBlurImageFilter_Metal.png +impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucentWithBlurImageFilter_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucentWithBlurImageFilter_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucentWithBlurImageFilter_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucent_Metal.png +impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucent_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucent_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucent_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucentZeroSigma_Metal.png +impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucentZeroSigma_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucentZeroSigma_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucentZeroSigma_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucent_Metal.png +impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucent_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucent_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucent_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestOuterOpaqueWithBlurImageFilter_Metal.png +impeller_Play_AiksTest_MaskBlurVariantTestOuterOpaqueWithBlurImageFilter_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestOuterOpaqueWithBlurImageFilter_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestOuterOpaqueWithBlurImageFilter_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestOuterTranslucent_Metal.png +impeller_Play_AiksTest_MaskBlurVariantTestOuterTranslucent_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestOuterTranslucent_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestOuterTranslucent_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestSolidOpaque_Metal.png +impeller_Play_AiksTest_MaskBlurVariantTestSolidOpaque_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestSolidOpaque_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestSolidOpaque_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentExclusionBlend_Metal.png +impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentExclusionBlend_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentExclusionBlend_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentExclusionBlend_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentWithFilters_Metal.png +impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentWithFilters_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentWithFilters_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentWithFilters_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucent_Metal.png +impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucent_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucent_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucent_Vulkan.png impeller_Play_AiksTest_MaskBlurWithZeroSigmaIsSkipped_Metal.png +impeller_Play_AiksTest_MaskBlurWithZeroSigmaIsSkipped_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurWithZeroSigmaIsSkipped_OpenGLES.png impeller_Play_AiksTest_MaskBlurWithZeroSigmaIsSkipped_Vulkan.png impeller_Play_AiksTest_MatrixBackdropFilter_Metal.png +impeller_Play_AiksTest_MatrixBackdropFilter_MetalWideGamut.png impeller_Play_AiksTest_MatrixBackdropFilter_OpenGLES.png impeller_Play_AiksTest_MatrixBackdropFilter_Vulkan.png impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen_Metal.png +impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen_MetalWideGamut.png impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen_OpenGLES.png impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen_Vulkan.png impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen_Metal.png +impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen_MetalWideGamut.png impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen_OpenGLES.png impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen_Vulkan.png impeller_Play_AiksTest_MatrixImageFilterMagnify_Metal.png +impeller_Play_AiksTest_MatrixImageFilterMagnify_MetalWideGamut.png impeller_Play_AiksTest_MatrixImageFilterMagnify_OpenGLES.png impeller_Play_AiksTest_MatrixImageFilterMagnify_Vulkan.png impeller_Play_AiksTest_MatrixSaveLayerFilter_Metal.png +impeller_Play_AiksTest_MatrixSaveLayerFilter_MetalWideGamut.png impeller_Play_AiksTest_MatrixSaveLayerFilter_OpenGLES.png impeller_Play_AiksTest_MatrixSaveLayerFilter_Vulkan.png impeller_Play_AiksTest_PaintBlendModeIsRespected_Metal.png +impeller_Play_AiksTest_PaintBlendModeIsRespected_MetalWideGamut.png impeller_Play_AiksTest_PaintBlendModeIsRespected_OpenGLES.png impeller_Play_AiksTest_PaintBlendModeIsRespected_Vulkan.png impeller_Play_AiksTest_PipelineBlendSingleParameter_Metal.png +impeller_Play_AiksTest_PipelineBlendSingleParameter_MetalWideGamut.png impeller_Play_AiksTest_PipelineBlendSingleParameter_OpenGLES.png impeller_Play_AiksTest_PipelineBlendSingleParameter_Vulkan.png impeller_Play_AiksTest_ReleasesTextureOnTeardown_Metal.png +impeller_Play_AiksTest_ReleasesTextureOnTeardown_MetalWideGamut.png impeller_Play_AiksTest_ReleasesTextureOnTeardown_OpenGLES.png impeller_Play_AiksTest_ReleasesTextureOnTeardown_Vulkan.png impeller_Play_AiksTest_RotateColorFilteredPath_Metal.png +impeller_Play_AiksTest_RotateColorFilteredPath_MetalWideGamut.png impeller_Play_AiksTest_RotateColorFilteredPath_OpenGLES.png impeller_Play_AiksTest_RotateColorFilteredPath_Vulkan.png impeller_Play_AiksTest_SaveLayerDrawsBehindSubsequentEntities_Metal.png +impeller_Play_AiksTest_SaveLayerDrawsBehindSubsequentEntities_MetalWideGamut.png impeller_Play_AiksTest_SaveLayerDrawsBehindSubsequentEntities_OpenGLES.png impeller_Play_AiksTest_SaveLayerDrawsBehindSubsequentEntities_Vulkan.png impeller_Play_AiksTest_SaveLayerFiltersScaleWithTransform_Metal.png +impeller_Play_AiksTest_SaveLayerFiltersScaleWithTransform_MetalWideGamut.png impeller_Play_AiksTest_SaveLayerFiltersScaleWithTransform_OpenGLES.png impeller_Play_AiksTest_SaveLayerFiltersScaleWithTransform_Vulkan.png impeller_Play_AiksTest_SiblingSaveLayerBoundsAreRespected_Metal.png +impeller_Play_AiksTest_SiblingSaveLayerBoundsAreRespected_MetalWideGamut.png impeller_Play_AiksTest_SiblingSaveLayerBoundsAreRespected_OpenGLES.png impeller_Play_AiksTest_SiblingSaveLayerBoundsAreRespected_Vulkan.png impeller_Play_AiksTest_SolidColorCirclesOvalsRRectsMaskBlurCorrectly_Metal.png +impeller_Play_AiksTest_SolidColorCirclesOvalsRRectsMaskBlurCorrectly_MetalWideGamut.png impeller_Play_AiksTest_SolidColorCirclesOvalsRRectsMaskBlurCorrectly_OpenGLES.png impeller_Play_AiksTest_SolidColorCirclesOvalsRRectsMaskBlurCorrectly_Vulkan.png impeller_Play_AiksTest_SolidStrokesRenderCorrectly_Metal.png +impeller_Play_AiksTest_SolidStrokesRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_SolidStrokesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_SolidStrokesRenderCorrectly_Vulkan.png impeller_Play_AiksTest_SrgbToLinearFilterSubpassCollapseOptimization_Metal.png +impeller_Play_AiksTest_SrgbToLinearFilterSubpassCollapseOptimization_MetalWideGamut.png impeller_Play_AiksTest_SrgbToLinearFilterSubpassCollapseOptimization_OpenGLES.png impeller_Play_AiksTest_SrgbToLinearFilterSubpassCollapseOptimization_Vulkan.png impeller_Play_AiksTest_StrokedCirclesRenderCorrectly_Metal.png +impeller_Play_AiksTest_StrokedCirclesRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_StrokedCirclesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_StrokedCirclesRenderCorrectly_Vulkan.png impeller_Play_AiksTest_SubpassWithClearColorOptimization_Metal.png +impeller_Play_AiksTest_SubpassWithClearColorOptimization_MetalWideGamut.png impeller_Play_AiksTest_SubpassWithClearColorOptimization_OpenGLES.png impeller_Play_AiksTest_SubpassWithClearColorOptimization_Vulkan.png impeller_Play_AiksTest_TextForegroundShaderWithTransform_Metal.png +impeller_Play_AiksTest_TextForegroundShaderWithTransform_MetalWideGamut.png impeller_Play_AiksTest_TextForegroundShaderWithTransform_OpenGLES.png impeller_Play_AiksTest_TextForegroundShaderWithTransform_Vulkan.png impeller_Play_AiksTest_TextFrameSubpixelAlignment_Metal.png +impeller_Play_AiksTest_TextFrameSubpixelAlignment_MetalWideGamut.png impeller_Play_AiksTest_TextFrameSubpixelAlignment_OpenGLES.png impeller_Play_AiksTest_TextFrameSubpixelAlignment_Vulkan.png +impeller_Play_AiksTest_TextRotated_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerDrawsCorrectly_Metal.png +impeller_Play_AiksTest_TranslucentSaveLayerDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerImageDrawsCorrectly_Metal.png +impeller_Play_AiksTest_TranslucentSaveLayerImageDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerImageDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerImageDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly_Metal.png +impeller_Play_AiksTest_TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly_Metal.png +impeller_Play_AiksTest_TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly_Metal.png +impeller_Play_AiksTest_TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly_Metal.png +impeller_Play_AiksTest_TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly_Metal.png +impeller_Play_AiksTest_TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly_Metal.png +impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly_Metal.png +impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_VerticesGeometryUVPositionDataWithTranslate_Metal.png +impeller_Play_AiksTest_VerticesGeometryUVPositionDataWithTranslate_MetalWideGamut.png impeller_Play_AiksTest_VerticesGeometryUVPositionDataWithTranslate_OpenGLES.png impeller_Play_AiksTest_VerticesGeometryUVPositionDataWithTranslate_Vulkan.png impeller_Play_AiksTest_VerticesGeometryUVPositionData_Metal.png +impeller_Play_AiksTest_VerticesGeometryUVPositionData_MetalWideGamut.png impeller_Play_AiksTest_VerticesGeometryUVPositionData_OpenGLES.png impeller_Play_AiksTest_VerticesGeometryUVPositionData_Vulkan.png \ No newline at end of file From b51b9a265e490c2208a6e801b8002fc7c95d0728 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 18 Mar 2024 10:27:49 -0700 Subject: [PATCH 02/25] updated golden --- testing/impeller_golden_tests_output.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/testing/impeller_golden_tests_output.txt b/testing/impeller_golden_tests_output.txt index 38c6c7162396a..41b4169a8614e 100644 --- a/testing/impeller_golden_tests_output.txt +++ b/testing/impeller_golden_tests_output.txt @@ -76,10 +76,6 @@ impeller_Play_AiksTest_BlendModeOverlay_Metal.png impeller_Play_AiksTest_BlendModeOverlay_MetalWideGamut.png impeller_Play_AiksTest_BlendModeOverlay_OpenGLES.png impeller_Play_AiksTest_BlendModeOverlay_Vulkan.png -impeller_Play_AiksTest_BlendModePlusAlpha_Metal.png -impeller_Play_AiksTest_BlendModePlusAlpha_MetalWideGamut.png -impeller_Play_AiksTest_BlendModePlusAlpha_OpenGLES.png -impeller_Play_AiksTest_BlendModePlusAlpha_Vulkan.png impeller_Play_AiksTest_BlendModePlus_Metal.png impeller_Play_AiksTest_BlendModePlus_MetalWideGamut.png impeller_Play_AiksTest_BlendModePlus_OpenGLES.png @@ -712,6 +708,7 @@ impeller_Play_AiksTest_LinearToSrgbFilterSubpassCollapseOptimization_MetalWideGa impeller_Play_AiksTest_LinearToSrgbFilterSubpassCollapseOptimization_OpenGLES.png impeller_Play_AiksTest_LinearToSrgbFilterSubpassCollapseOptimization_Vulkan.png impeller_Play_AiksTest_MaskBlurDoesntStretchContents_Metal.png +impeller_Play_AiksTest_MaskBlurDoesntStretchContents_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurDoesntStretchContents_OpenGLES.png impeller_Play_AiksTest_MaskBlurDoesntStretchContents_Vulkan.png impeller_Play_AiksTest_MaskBlurTexture_Metal.png From 55135b887e311ce17d9ccada922afab94284ced1 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Tue, 26 Mar 2024 14:44:31 -0700 Subject: [PATCH 03/25] moved to a magic name --- .../golden_playground_test_mac.cc | 4 - impeller/golden_tests/metal_screenshotter.mm | 9 +- .../playground/compute_playground_test.cc | 2 +- impeller/playground/playground.cc | 9 +- impeller/playground/playground.h | 6 +- impeller/playground/playground_impl.cc | 3 - impeller/playground/playground_test.cc | 10 +- impeller/playground/playground_test.h | 6 +- .../runtime_stage/runtime_stage_unittests.cc | 3 +- testing/impeller_golden_tests_output.txt | 220 ------------------ 10 files changed, 19 insertions(+), 253 deletions(-) diff --git a/impeller/golden_tests/golden_playground_test_mac.cc b/impeller/golden_tests/golden_playground_test_mac.cc index e2c13df99ceb9..51d751d056cd1 100644 --- a/impeller/golden_tests/golden_playground_test_mac.cc +++ b/impeller/golden_tests/golden_playground_test_mac.cc @@ -139,10 +139,6 @@ void GoldenPlaygroundTest::SetUp() { setenv("VK_ICD_FILENAMES", icd_path.c_str(), 1); switch (GetParam()) { - case PlaygroundBackend::kMetalWideGamut: - pimpl_->screenshotter = std::make_unique( - /*enable_wide_gamut=*/true); - break; case PlaygroundBackend::kMetal: pimpl_->screenshotter = std::make_unique( /*enable_wide_gamut=*/false); diff --git a/impeller/golden_tests/metal_screenshotter.mm b/impeller/golden_tests/metal_screenshotter.mm index 11aa7d26f738e..f09cb10e03849 100644 --- a/impeller/golden_tests/metal_screenshotter.mm +++ b/impeller/golden_tests/metal_screenshotter.mm @@ -16,13 +16,8 @@ MetalScreenshotter::MetalScreenshotter(bool enable_wide_gamut) { FML_CHECK(::glfwInit() == GLFW_TRUE); PlaygroundSwitches switches; - if (enable_wide_gamut) { - switches.enable_wide_gamut = true; - playground_ = - PlaygroundImpl::Create(PlaygroundBackend::kMetalWideGamut, switches); - } else { - playground_ = PlaygroundImpl::Create(PlaygroundBackend::kMetal, switches); - } + switches.enable_wide_gamut = enable_wide_gamut; + playground_ = PlaygroundImpl::Create(PlaygroundBackend::kMetal, switches); } std::unique_ptr MetalScreenshotter::MakeScreenshot( diff --git a/impeller/playground/compute_playground_test.cc b/impeller/playground/compute_playground_test.cc index 3df0e62a7260e..1abea913ebea4 100644 --- a/impeller/playground/compute_playground_test.cc +++ b/impeller/playground/compute_playground_test.cc @@ -25,7 +25,7 @@ void ComputePlaygroundTest::SetUp() { return; } - SetupContext(GetParam()); + SetupContext(GetParam(), switches_); SetupWindow(); start_time_ = fml::TimePoint::Now().ToEpochDelta(); diff --git a/impeller/playground/playground.cc b/impeller/playground/playground.cc index cc11a98b50fa9..ae4d7cd4dd3fb 100644 --- a/impeller/playground/playground.cc +++ b/impeller/playground/playground.cc @@ -43,8 +43,6 @@ namespace impeller { std::string PlaygroundBackendToString(PlaygroundBackend backend) { switch (backend) { - case PlaygroundBackend::kMetalWideGamut: - return "MetalWideGamut"; case PlaygroundBackend::kMetal: return "Metal"; case PlaygroundBackend::kOpenGLES: @@ -100,8 +98,6 @@ std::shared_ptr Playground::MakeContext() const { bool Playground::SupportsBackend(PlaygroundBackend backend) { switch (backend) { - case PlaygroundBackend::kMetalWideGamut: - [[fallthrough]]; case PlaygroundBackend::kMetal: #if IMPELLER_ENABLE_METAL return true; @@ -124,10 +120,11 @@ bool Playground::SupportsBackend(PlaygroundBackend backend) { FML_UNREACHABLE(); } -void Playground::SetupContext(PlaygroundBackend backend) { +void Playground::SetupContext(PlaygroundBackend backend, + const PlaygroundSwitches& switches) { FML_CHECK(SupportsBackend(backend)); - impl_ = PlaygroundImpl::Create(backend, switches_); + impl_ = PlaygroundImpl::Create(backend, switches); if (!impl_) { FML_LOG(WARNING) << "PlaygroundImpl::Create failed."; return; diff --git a/impeller/playground/playground.h b/impeller/playground/playground.h index 85fc34fe127b8..b15461272f3d5 100644 --- a/impeller/playground/playground.h +++ b/impeller/playground/playground.h @@ -28,7 +28,6 @@ class PlaygroundImpl; enum class PlaygroundBackend { kMetal, - kMetalWideGamut, kOpenGLES, kVulkan, }; @@ -37,8 +36,6 @@ constexpr inline RuntimeStageBackend PlaygroundBackendToRuntimeStageBackend( PlaygroundBackend backend) { switch (backend) { case PlaygroundBackend::kMetal: - [[fallthrough]]; - case PlaygroundBackend::kMetalWideGamut: return RuntimeStageBackend::kMetal; case PlaygroundBackend::kOpenGLES: return RuntimeStageBackend::kOpenGLES; @@ -60,7 +57,8 @@ class Playground { static bool ShouldOpenNewPlaygrounds(); - void SetupContext(PlaygroundBackend backend); + void SetupContext(PlaygroundBackend backend, + const PlaygroundSwitches& switches); void SetupWindow(); diff --git a/impeller/playground/playground_impl.cc b/impeller/playground/playground_impl.cc index c25b469728f2e..5abee6e07e24b 100644 --- a/impeller/playground/playground_impl.cc +++ b/impeller/playground/playground_impl.cc @@ -27,9 +27,6 @@ std::unique_ptr PlaygroundImpl::Create( PlaygroundSwitches switches) { switch (backend) { #if IMPELLER_ENABLE_METAL - case PlaygroundBackend::kMetalWideGamut: - switches.enable_wide_gamut = true; - return std::make_unique(switches); case PlaygroundBackend::kMetal: return std::make_unique(switches); #endif // IMPELLER_ENABLE_METAL diff --git a/impeller/playground/playground_test.cc b/impeller/playground/playground_test.cc index eaa9e03c56f12..00ee371ce2fbb 100644 --- a/impeller/playground/playground_test.cc +++ b/impeller/playground/playground_test.cc @@ -28,7 +28,13 @@ void PlaygroundTest::SetUp() { ImpellerValidationErrorsSetFatal(true); - SetupContext(GetParam()); + // Test names that end with "WideGamut" will render with wide gamut support. + std::string test_name = flutter::testing::GetCurrentTestName(); + PlaygroundSwitches switches = switches_; + switches.enable_wide_gamut = + test_name.find("WideGamut/") != std::string::npos; + + SetupContext(GetParam(), switches); SetupWindow(); } @@ -62,8 +68,6 @@ std::string PlaygroundTest::GetWindowTitle() const { stream << "Impeller Playground for '" << flutter::testing::GetCurrentTestName() << "' "; switch (GetBackend()) { - case PlaygroundBackend::kMetalWideGamut: - [[fallthrough]]; case PlaygroundBackend::kMetal: break; case PlaygroundBackend::kOpenGLES: diff --git a/impeller/playground/playground_test.h b/impeller/playground/playground_test.h index 8684d833f4b01..cabb7dfd3abd5 100644 --- a/impeller/playground/playground_test.h +++ b/impeller/playground/playground_test.h @@ -60,9 +60,9 @@ class PlaygroundTest : public Playground, ""; \ INSTANTIATE_TEST_SUITE_P( \ Play, playground, \ - ::testing::Values( \ - PlaygroundBackend::kMetal, PlaygroundBackend::kMetalWideGamut, \ - PlaygroundBackend::kOpenGLES, PlaygroundBackend::kVulkan), \ + ::testing::Values(PlaygroundBackend::kMetal, \ + PlaygroundBackend::kOpenGLES, \ + PlaygroundBackend::kVulkan), \ [](const ::testing::TestParamInfo& info) { \ return PlaygroundBackendToString(info.param); \ }); diff --git a/impeller/runtime_stage/runtime_stage_unittests.cc b/impeller/runtime_stage/runtime_stage_unittests.cc index 2c22b88d3f4b4..2dc646d3a640b 100644 --- a/impeller/runtime_stage/runtime_stage_unittests.cc +++ b/impeller/runtime_stage/runtime_stage_unittests.cc @@ -61,9 +61,8 @@ TEST_P(RuntimeStageTest, CanReadUniforms) { ASSERT_TRUE(stage->IsValid()); switch (GetBackend()) { - case PlaygroundBackend::kMetalWideGamut: - [[fallthrough]]; case PlaygroundBackend::kMetal: + [[fallthrough]]; case PlaygroundBackend::kOpenGLES: { ASSERT_EQ(stage->GetUniforms().size(), 17u); { diff --git a/testing/impeller_golden_tests_output.txt b/testing/impeller_golden_tests_output.txt index 41b4169a8614e..aae87f0f42e8c 100644 --- a/testing/impeller_golden_tests_output.txt +++ b/testing/impeller_golden_tests_output.txt @@ -1,882 +1,662 @@ digest.json impeller_GoldenTests_ConicalGradient.png impeller_Play_AiksTest_BlendModeClear_Metal.png -impeller_Play_AiksTest_BlendModeClear_MetalWideGamut.png impeller_Play_AiksTest_BlendModeClear_OpenGLES.png impeller_Play_AiksTest_BlendModeClear_Vulkan.png impeller_Play_AiksTest_BlendModeColorBurn_Metal.png -impeller_Play_AiksTest_BlendModeColorBurn_MetalWideGamut.png impeller_Play_AiksTest_BlendModeColorBurn_OpenGLES.png impeller_Play_AiksTest_BlendModeColorBurn_Vulkan.png impeller_Play_AiksTest_BlendModeColorDodge_Metal.png -impeller_Play_AiksTest_BlendModeColorDodge_MetalWideGamut.png impeller_Play_AiksTest_BlendModeColorDodge_OpenGLES.png impeller_Play_AiksTest_BlendModeColorDodge_Vulkan.png impeller_Play_AiksTest_BlendModeColor_Metal.png -impeller_Play_AiksTest_BlendModeColor_MetalWideGamut.png impeller_Play_AiksTest_BlendModeColor_OpenGLES.png impeller_Play_AiksTest_BlendModeColor_Vulkan.png impeller_Play_AiksTest_BlendModeDarken_Metal.png -impeller_Play_AiksTest_BlendModeDarken_MetalWideGamut.png impeller_Play_AiksTest_BlendModeDarken_OpenGLES.png impeller_Play_AiksTest_BlendModeDarken_Vulkan.png impeller_Play_AiksTest_BlendModeDestinationATop_Metal.png -impeller_Play_AiksTest_BlendModeDestinationATop_MetalWideGamut.png impeller_Play_AiksTest_BlendModeDestinationATop_OpenGLES.png impeller_Play_AiksTest_BlendModeDestinationATop_Vulkan.png impeller_Play_AiksTest_BlendModeDestinationIn_Metal.png -impeller_Play_AiksTest_BlendModeDestinationIn_MetalWideGamut.png impeller_Play_AiksTest_BlendModeDestinationIn_OpenGLES.png impeller_Play_AiksTest_BlendModeDestinationIn_Vulkan.png impeller_Play_AiksTest_BlendModeDestinationOut_Metal.png -impeller_Play_AiksTest_BlendModeDestinationOut_MetalWideGamut.png impeller_Play_AiksTest_BlendModeDestinationOut_OpenGLES.png impeller_Play_AiksTest_BlendModeDestinationOut_Vulkan.png impeller_Play_AiksTest_BlendModeDestinationOver_Metal.png -impeller_Play_AiksTest_BlendModeDestinationOver_MetalWideGamut.png impeller_Play_AiksTest_BlendModeDestinationOver_OpenGLES.png impeller_Play_AiksTest_BlendModeDestinationOver_Vulkan.png impeller_Play_AiksTest_BlendModeDestination_Metal.png -impeller_Play_AiksTest_BlendModeDestination_MetalWideGamut.png impeller_Play_AiksTest_BlendModeDestination_OpenGLES.png impeller_Play_AiksTest_BlendModeDestination_Vulkan.png impeller_Play_AiksTest_BlendModeDifference_Metal.png -impeller_Play_AiksTest_BlendModeDifference_MetalWideGamut.png impeller_Play_AiksTest_BlendModeDifference_OpenGLES.png impeller_Play_AiksTest_BlendModeDifference_Vulkan.png impeller_Play_AiksTest_BlendModeExclusion_Metal.png -impeller_Play_AiksTest_BlendModeExclusion_MetalWideGamut.png impeller_Play_AiksTest_BlendModeExclusion_OpenGLES.png impeller_Play_AiksTest_BlendModeExclusion_Vulkan.png impeller_Play_AiksTest_BlendModeHardLight_Metal.png -impeller_Play_AiksTest_BlendModeHardLight_MetalWideGamut.png impeller_Play_AiksTest_BlendModeHardLight_OpenGLES.png impeller_Play_AiksTest_BlendModeHardLight_Vulkan.png impeller_Play_AiksTest_BlendModeHue_Metal.png -impeller_Play_AiksTest_BlendModeHue_MetalWideGamut.png impeller_Play_AiksTest_BlendModeHue_OpenGLES.png impeller_Play_AiksTest_BlendModeHue_Vulkan.png impeller_Play_AiksTest_BlendModeLighten_Metal.png -impeller_Play_AiksTest_BlendModeLighten_MetalWideGamut.png impeller_Play_AiksTest_BlendModeLighten_OpenGLES.png impeller_Play_AiksTest_BlendModeLighten_Vulkan.png impeller_Play_AiksTest_BlendModeLuminosity_Metal.png -impeller_Play_AiksTest_BlendModeLuminosity_MetalWideGamut.png impeller_Play_AiksTest_BlendModeLuminosity_OpenGLES.png impeller_Play_AiksTest_BlendModeLuminosity_Vulkan.png impeller_Play_AiksTest_BlendModeModulate_Metal.png -impeller_Play_AiksTest_BlendModeModulate_MetalWideGamut.png impeller_Play_AiksTest_BlendModeModulate_OpenGLES.png impeller_Play_AiksTest_BlendModeModulate_Vulkan.png impeller_Play_AiksTest_BlendModeMultiply_Metal.png -impeller_Play_AiksTest_BlendModeMultiply_MetalWideGamut.png impeller_Play_AiksTest_BlendModeMultiply_OpenGLES.png impeller_Play_AiksTest_BlendModeMultiply_Vulkan.png impeller_Play_AiksTest_BlendModeOverlay_Metal.png -impeller_Play_AiksTest_BlendModeOverlay_MetalWideGamut.png impeller_Play_AiksTest_BlendModeOverlay_OpenGLES.png impeller_Play_AiksTest_BlendModeOverlay_Vulkan.png impeller_Play_AiksTest_BlendModePlus_Metal.png -impeller_Play_AiksTest_BlendModePlus_MetalWideGamut.png impeller_Play_AiksTest_BlendModePlus_OpenGLES.png impeller_Play_AiksTest_BlendModePlus_Vulkan.png impeller_Play_AiksTest_BlendModeSaturation_Metal.png -impeller_Play_AiksTest_BlendModeSaturation_MetalWideGamut.png impeller_Play_AiksTest_BlendModeSaturation_OpenGLES.png impeller_Play_AiksTest_BlendModeSaturation_Vulkan.png impeller_Play_AiksTest_BlendModeScreen_Metal.png -impeller_Play_AiksTest_BlendModeScreen_MetalWideGamut.png impeller_Play_AiksTest_BlendModeScreen_OpenGLES.png impeller_Play_AiksTest_BlendModeScreen_Vulkan.png impeller_Play_AiksTest_BlendModeShouldCoverWholeScreen_Metal.png -impeller_Play_AiksTest_BlendModeShouldCoverWholeScreen_MetalWideGamut.png impeller_Play_AiksTest_BlendModeShouldCoverWholeScreen_OpenGLES.png impeller_Play_AiksTest_BlendModeShouldCoverWholeScreen_Vulkan.png impeller_Play_AiksTest_BlendModeSoftLight_Metal.png -impeller_Play_AiksTest_BlendModeSoftLight_MetalWideGamut.png impeller_Play_AiksTest_BlendModeSoftLight_OpenGLES.png impeller_Play_AiksTest_BlendModeSoftLight_Vulkan.png impeller_Play_AiksTest_BlendModeSourceATop_Metal.png -impeller_Play_AiksTest_BlendModeSourceATop_MetalWideGamut.png impeller_Play_AiksTest_BlendModeSourceATop_OpenGLES.png impeller_Play_AiksTest_BlendModeSourceATop_Vulkan.png impeller_Play_AiksTest_BlendModeSourceIn_Metal.png -impeller_Play_AiksTest_BlendModeSourceIn_MetalWideGamut.png impeller_Play_AiksTest_BlendModeSourceIn_OpenGLES.png impeller_Play_AiksTest_BlendModeSourceIn_Vulkan.png impeller_Play_AiksTest_BlendModeSourceOut_Metal.png -impeller_Play_AiksTest_BlendModeSourceOut_MetalWideGamut.png impeller_Play_AiksTest_BlendModeSourceOut_OpenGLES.png impeller_Play_AiksTest_BlendModeSourceOut_Vulkan.png impeller_Play_AiksTest_BlendModeSourceOver_Metal.png -impeller_Play_AiksTest_BlendModeSourceOver_MetalWideGamut.png impeller_Play_AiksTest_BlendModeSourceOver_OpenGLES.png impeller_Play_AiksTest_BlendModeSourceOver_Vulkan.png impeller_Play_AiksTest_BlendModeSource_Metal.png -impeller_Play_AiksTest_BlendModeSource_MetalWideGamut.png impeller_Play_AiksTest_BlendModeSource_OpenGLES.png impeller_Play_AiksTest_BlendModeSource_Vulkan.png impeller_Play_AiksTest_BlendModeXor_Metal.png -impeller_Play_AiksTest_BlendModeXor_MetalWideGamut.png impeller_Play_AiksTest_BlendModeXor_OpenGLES.png impeller_Play_AiksTest_BlendModeXor_Vulkan.png impeller_Play_AiksTest_BlurHasNoEdge_Metal.png -impeller_Play_AiksTest_BlurHasNoEdge_MetalWideGamut.png impeller_Play_AiksTest_BlurHasNoEdge_OpenGLES.png impeller_Play_AiksTest_BlurHasNoEdge_Vulkan.png impeller_Play_AiksTest_BlurredRectangleWithShader_Metal.png -impeller_Play_AiksTest_BlurredRectangleWithShader_MetalWideGamut.png impeller_Play_AiksTest_BlurredRectangleWithShader_OpenGLES.png impeller_Play_AiksTest_BlurredRectangleWithShader_Vulkan.png impeller_Play_AiksTest_CanDrawAnOpenPathThatIsntARect_Metal.png -impeller_Play_AiksTest_CanDrawAnOpenPathThatIsntARect_MetalWideGamut.png impeller_Play_AiksTest_CanDrawAnOpenPathThatIsntARect_OpenGLES.png impeller_Play_AiksTest_CanDrawAnOpenPathThatIsntARect_Vulkan.png impeller_Play_AiksTest_CanDrawAnOpenPath_Metal.png -impeller_Play_AiksTest_CanDrawAnOpenPath_MetalWideGamut.png impeller_Play_AiksTest_CanDrawAnOpenPath_OpenGLES.png impeller_Play_AiksTest_CanDrawAnOpenPath_Vulkan.png impeller_Play_AiksTest_CanDrawMultiContourConvexPath_Metal.png -impeller_Play_AiksTest_CanDrawMultiContourConvexPath_MetalWideGamut.png impeller_Play_AiksTest_CanDrawMultiContourConvexPath_OpenGLES.png impeller_Play_AiksTest_CanDrawMultiContourConvexPath_Vulkan.png impeller_Play_AiksTest_CanDrawPaintMultipleTimesInteractive_Metal.png -impeller_Play_AiksTest_CanDrawPaintMultipleTimesInteractive_MetalWideGamut.png impeller_Play_AiksTest_CanDrawPaintMultipleTimesInteractive_OpenGLES.png impeller_Play_AiksTest_CanDrawPaintMultipleTimesInteractive_Vulkan.png impeller_Play_AiksTest_CanDrawPaintMultipleTimes_Metal.png -impeller_Play_AiksTest_CanDrawPaintMultipleTimes_MetalWideGamut.png impeller_Play_AiksTest_CanDrawPaintMultipleTimes_OpenGLES.png impeller_Play_AiksTest_CanDrawPaintMultipleTimes_Vulkan.png impeller_Play_AiksTest_CanDrawPaintWithAdvancedBlend_Metal.png -impeller_Play_AiksTest_CanDrawPaintWithAdvancedBlend_MetalWideGamut.png impeller_Play_AiksTest_CanDrawPaintWithAdvancedBlend_OpenGLES.png impeller_Play_AiksTest_CanDrawPaintWithAdvancedBlend_Vulkan.png impeller_Play_AiksTest_CanDrawPaint_Metal.png -impeller_Play_AiksTest_CanDrawPaint_MetalWideGamut.png impeller_Play_AiksTest_CanDrawPaint_OpenGLES.png impeller_Play_AiksTest_CanDrawPaint_Vulkan.png impeller_Play_AiksTest_CanDrawPerspectiveTransformWithClips_Metal.png impeller_Play_AiksTest_CanDrawPerspectiveTransformWithClips_OpenGLES.png impeller_Play_AiksTest_CanDrawPerspectiveTransformWithClips_Vulkan.png impeller_Play_AiksTest_CanDrawPointsWithTextureMap_Metal.png -impeller_Play_AiksTest_CanDrawPointsWithTextureMap_MetalWideGamut.png impeller_Play_AiksTest_CanDrawPointsWithTextureMap_OpenGLES.png impeller_Play_AiksTest_CanDrawPointsWithTextureMap_Vulkan.png impeller_Play_AiksTest_CanDrawPoints_Metal.png -impeller_Play_AiksTest_CanDrawPoints_MetalWideGamut.png impeller_Play_AiksTest_CanDrawPoints_OpenGLES.png impeller_Play_AiksTest_CanDrawPoints_Vulkan.png impeller_Play_AiksTest_CanEmptyPictureConvertToImage_Metal.png -impeller_Play_AiksTest_CanEmptyPictureConvertToImage_MetalWideGamut.png impeller_Play_AiksTest_CanEmptyPictureConvertToImage_OpenGLES.png impeller_Play_AiksTest_CanEmptyPictureConvertToImage_Vulkan.png impeller_Play_AiksTest_CanPerformFullScreenMSAA_Metal.png -impeller_Play_AiksTest_CanPerformFullScreenMSAA_MetalWideGamut.png impeller_Play_AiksTest_CanPerformFullScreenMSAA_OpenGLES.png impeller_Play_AiksTest_CanPerformFullScreenMSAA_Vulkan.png impeller_Play_AiksTest_CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated_Metal.png -impeller_Play_AiksTest_CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated_MetalWideGamut.png impeller_Play_AiksTest_CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated_OpenGLES.png impeller_Play_AiksTest_CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated_Vulkan.png impeller_Play_AiksTest_CanPerformSaveLayerWithBounds_Metal.png -impeller_Play_AiksTest_CanPerformSaveLayerWithBounds_MetalWideGamut.png impeller_Play_AiksTest_CanPerformSaveLayerWithBounds_OpenGLES.png impeller_Play_AiksTest_CanPerformSaveLayerWithBounds_Vulkan.png impeller_Play_AiksTest_CanPerformSkew_Metal.png -impeller_Play_AiksTest_CanPerformSkew_MetalWideGamut.png impeller_Play_AiksTest_CanPerformSkew_OpenGLES.png impeller_Play_AiksTest_CanPerformSkew_Vulkan.png impeller_Play_AiksTest_CanPictureConvertToImage_Metal.png -impeller_Play_AiksTest_CanPictureConvertToImage_MetalWideGamut.png impeller_Play_AiksTest_CanPictureConvertToImage_OpenGLES.png impeller_Play_AiksTest_CanPictureConvertToImage_Vulkan.png impeller_Play_AiksTest_CanRenderAdvancedBlendColorFilterWithSaveLayer_Metal.png -impeller_Play_AiksTest_CanRenderAdvancedBlendColorFilterWithSaveLayer_MetalWideGamut.png impeller_Play_AiksTest_CanRenderAdvancedBlendColorFilterWithSaveLayer_OpenGLES.png impeller_Play_AiksTest_CanRenderAdvancedBlendColorFilterWithSaveLayer_Vulkan.png impeller_Play_AiksTest_CanRenderBackdropBlurHugeSigma_Metal.png -impeller_Play_AiksTest_CanRenderBackdropBlurHugeSigma_MetalWideGamut.png impeller_Play_AiksTest_CanRenderBackdropBlurHugeSigma_OpenGLES.png impeller_Play_AiksTest_CanRenderBackdropBlurHugeSigma_Vulkan.png impeller_Play_AiksTest_CanRenderBackdropBlurInteractive_Metal.png -impeller_Play_AiksTest_CanRenderBackdropBlurInteractive_MetalWideGamut.png impeller_Play_AiksTest_CanRenderBackdropBlurInteractive_OpenGLES.png impeller_Play_AiksTest_CanRenderBackdropBlurInteractive_Vulkan.png impeller_Play_AiksTest_CanRenderBackdropBlur_Metal.png -impeller_Play_AiksTest_CanRenderBackdropBlur_MetalWideGamut.png impeller_Play_AiksTest_CanRenderBackdropBlur_OpenGLES.png impeller_Play_AiksTest_CanRenderBackdropBlur_Vulkan.png impeller_Play_AiksTest_CanRenderClippedBlur_Metal.png -impeller_Play_AiksTest_CanRenderClippedBlur_MetalWideGamut.png impeller_Play_AiksTest_CanRenderClippedBlur_OpenGLES.png impeller_Play_AiksTest_CanRenderClippedBlur_Vulkan.png impeller_Play_AiksTest_CanRenderClippedLayers_Metal.png -impeller_Play_AiksTest_CanRenderClippedLayers_MetalWideGamut.png impeller_Play_AiksTest_CanRenderClippedLayers_OpenGLES.png impeller_Play_AiksTest_CanRenderClippedLayers_Vulkan.png impeller_Play_AiksTest_CanRenderClippedRuntimeEffects_Metal.png -impeller_Play_AiksTest_CanRenderClippedRuntimeEffects_MetalWideGamut.png impeller_Play_AiksTest_CanRenderClippedRuntimeEffects_OpenGLES.png impeller_Play_AiksTest_CanRenderClips_Metal.png -impeller_Play_AiksTest_CanRenderClips_MetalWideGamut.png impeller_Play_AiksTest_CanRenderClips_OpenGLES.png impeller_Play_AiksTest_CanRenderClips_Vulkan.png impeller_Play_AiksTest_CanRenderColorFilterWithInvertColorsDrawPaint_Metal.png -impeller_Play_AiksTest_CanRenderColorFilterWithInvertColorsDrawPaint_MetalWideGamut.png impeller_Play_AiksTest_CanRenderColorFilterWithInvertColorsDrawPaint_OpenGLES.png impeller_Play_AiksTest_CanRenderColorFilterWithInvertColorsDrawPaint_Vulkan.png impeller_Play_AiksTest_CanRenderColorFilterWithInvertColors_Metal.png -impeller_Play_AiksTest_CanRenderColorFilterWithInvertColors_MetalWideGamut.png impeller_Play_AiksTest_CanRenderColorFilterWithInvertColors_OpenGLES.png impeller_Play_AiksTest_CanRenderColorFilterWithInvertColors_Vulkan.png impeller_Play_AiksTest_CanRenderColoredRect_Metal.png -impeller_Play_AiksTest_CanRenderColoredRect_MetalWideGamut.png impeller_Play_AiksTest_CanRenderColoredRect_OpenGLES.png impeller_Play_AiksTest_CanRenderColoredRect_Vulkan.png impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringDisabled_Metal.png -impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringDisabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringDisabled_OpenGLES.png impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringDisabled_Vulkan.png impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringEnabled_Metal.png -impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringEnabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringEnabled_OpenGLES.png impeller_Play_AiksTest_CanRenderConicalGradientWithDitheringEnabled_Vulkan.png impeller_Play_AiksTest_CanRenderConicalGradient_Metal.png -impeller_Play_AiksTest_CanRenderConicalGradient_MetalWideGamut.png impeller_Play_AiksTest_CanRenderConicalGradient_OpenGLES.png impeller_Play_AiksTest_CanRenderConicalGradient_Vulkan.png impeller_Play_AiksTest_CanRenderCurvedStrokes_Metal.png -impeller_Play_AiksTest_CanRenderCurvedStrokes_MetalWideGamut.png impeller_Play_AiksTest_CanRenderCurvedStrokes_OpenGLES.png impeller_Play_AiksTest_CanRenderCurvedStrokes_Vulkan.png impeller_Play_AiksTest_CanRenderDestructiveSaveLayer_Metal.png -impeller_Play_AiksTest_CanRenderDestructiveSaveLayer_MetalWideGamut.png impeller_Play_AiksTest_CanRenderDestructiveSaveLayer_OpenGLES.png impeller_Play_AiksTest_CanRenderDestructiveSaveLayer_Vulkan.png impeller_Play_AiksTest_CanRenderDifferenceClips_Metal.png -impeller_Play_AiksTest_CanRenderDifferenceClips_MetalWideGamut.png impeller_Play_AiksTest_CanRenderDifferenceClips_OpenGLES.png impeller_Play_AiksTest_CanRenderDifferenceClips_Vulkan.png impeller_Play_AiksTest_CanRenderDifferencePaths_Metal.png -impeller_Play_AiksTest_CanRenderDifferencePaths_MetalWideGamut.png impeller_Play_AiksTest_CanRenderDifferencePaths_OpenGLES.png impeller_Play_AiksTest_CanRenderDifferencePaths_Vulkan.png impeller_Play_AiksTest_CanRenderDifferentShapesWithSameColorSource_Metal.png -impeller_Play_AiksTest_CanRenderDifferentShapesWithSameColorSource_MetalWideGamut.png impeller_Play_AiksTest_CanRenderDifferentShapesWithSameColorSource_OpenGLES.png impeller_Play_AiksTest_CanRenderDifferentShapesWithSameColorSource_Vulkan.png impeller_Play_AiksTest_CanRenderEmojiTextFrameWithAlpha_Metal.png -impeller_Play_AiksTest_CanRenderEmojiTextFrameWithAlpha_MetalWideGamut.png impeller_Play_AiksTest_CanRenderEmojiTextFrameWithAlpha_OpenGLES.png impeller_Play_AiksTest_CanRenderEmojiTextFrameWithAlpha_Vulkan.png impeller_Play_AiksTest_CanRenderEmojiTextFrameWithBlur_Metal.png -impeller_Play_AiksTest_CanRenderEmojiTextFrameWithBlur_MetalWideGamut.png impeller_Play_AiksTest_CanRenderEmojiTextFrameWithBlur_OpenGLES.png impeller_Play_AiksTest_CanRenderEmojiTextFrameWithBlur_Vulkan.png impeller_Play_AiksTest_CanRenderEmojiTextFrame_Metal.png -impeller_Play_AiksTest_CanRenderEmojiTextFrame_MetalWideGamut.png impeller_Play_AiksTest_CanRenderEmojiTextFrame_OpenGLES.png impeller_Play_AiksTest_CanRenderEmojiTextFrame_Vulkan.png impeller_Play_AiksTest_CanRenderForegroundAdvancedBlendWithMaskBlur_Metal.png -impeller_Play_AiksTest_CanRenderForegroundAdvancedBlendWithMaskBlur_MetalWideGamut.png impeller_Play_AiksTest_CanRenderForegroundAdvancedBlendWithMaskBlur_OpenGLES.png impeller_Play_AiksTest_CanRenderForegroundAdvancedBlendWithMaskBlur_Vulkan.png impeller_Play_AiksTest_CanRenderForegroundBlendWithMaskBlur_Metal.png -impeller_Play_AiksTest_CanRenderForegroundBlendWithMaskBlur_MetalWideGamut.png impeller_Play_AiksTest_CanRenderForegroundBlendWithMaskBlur_OpenGLES.png impeller_Play_AiksTest_CanRenderForegroundBlendWithMaskBlur_Vulkan.png impeller_Play_AiksTest_CanRenderGradientDecalWithBackground_Metal.png -impeller_Play_AiksTest_CanRenderGradientDecalWithBackground_MetalWideGamut.png impeller_Play_AiksTest_CanRenderGradientDecalWithBackground_OpenGLES.png impeller_Play_AiksTest_CanRenderGradientDecalWithBackground_Vulkan.png impeller_Play_AiksTest_CanRenderGroupOpacity_Metal.png -impeller_Play_AiksTest_CanRenderGroupOpacity_MetalWideGamut.png impeller_Play_AiksTest_CanRenderGroupOpacity_OpenGLES.png impeller_Play_AiksTest_CanRenderGroupOpacity_Vulkan.png impeller_Play_AiksTest_CanRenderImageRect_Metal.png -impeller_Play_AiksTest_CanRenderImageRect_MetalWideGamut.png impeller_Play_AiksTest_CanRenderImageRect_OpenGLES.png impeller_Play_AiksTest_CanRenderImageRect_Vulkan.png impeller_Play_AiksTest_CanRenderImage_Metal.png -impeller_Play_AiksTest_CanRenderImage_MetalWideGamut.png impeller_Play_AiksTest_CanRenderImage_OpenGLES.png impeller_Play_AiksTest_CanRenderImage_Vulkan.png impeller_Play_AiksTest_CanRenderInvertedImageWithColorFilter_Metal.png -impeller_Play_AiksTest_CanRenderInvertedImageWithColorFilter_MetalWideGamut.png impeller_Play_AiksTest_CanRenderInvertedImageWithColorFilter_OpenGLES.png impeller_Play_AiksTest_CanRenderInvertedImageWithColorFilter_Vulkan.png impeller_Play_AiksTest_CanRenderItalicizedText_Metal.png -impeller_Play_AiksTest_CanRenderItalicizedText_MetalWideGamut.png impeller_Play_AiksTest_CanRenderItalicizedText_OpenGLES.png impeller_Play_AiksTest_CanRenderItalicizedText_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientClamp_Metal.png -impeller_Play_AiksTest_CanRenderLinearGradientClamp_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientClamp_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientClamp_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientDecalWithColorFilter_Metal.png -impeller_Play_AiksTest_CanRenderLinearGradientDecalWithColorFilter_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientDecalWithColorFilter_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientDecalWithColorFilter_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientDecal_Metal.png -impeller_Play_AiksTest_CanRenderLinearGradientDecal_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientDecal_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientDecal_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsClamp_Metal.png -impeller_Play_AiksTest_CanRenderLinearGradientManyColorsClamp_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsClamp_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsClamp_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsDecal_Metal.png -impeller_Play_AiksTest_CanRenderLinearGradientManyColorsDecal_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsDecal_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsDecal_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsMirror_Metal.png -impeller_Play_AiksTest_CanRenderLinearGradientManyColorsMirror_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsMirror_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsMirror_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsRepeat_Metal.png -impeller_Play_AiksTest_CanRenderLinearGradientManyColorsRepeat_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsRepeat_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsRepeat_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsUnevenStops_Metal.png -impeller_Play_AiksTest_CanRenderLinearGradientManyColorsUnevenStops_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsUnevenStops_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientManyColorsUnevenStops_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientMaskBlur_Metal.png -impeller_Play_AiksTest_CanRenderLinearGradientMaskBlur_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientMaskBlur_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientMaskBlur_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientMirror_Metal.png -impeller_Play_AiksTest_CanRenderLinearGradientMirror_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientMirror_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientMirror_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientRepeat_Metal.png -impeller_Play_AiksTest_CanRenderLinearGradientRepeat_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientRepeat_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientRepeat_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientWayManyColorsClamp_Metal.png -impeller_Play_AiksTest_CanRenderLinearGradientWayManyColorsClamp_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientWayManyColorsClamp_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientWayManyColorsClamp_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringDisabled_Metal.png -impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringDisabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringDisabled_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringDisabled_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringEnabled_Metal.png -impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringEnabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringEnabled_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientWithDitheringEnabled_Vulkan.png impeller_Play_AiksTest_CanRenderLinearGradientWithOverlappingStopsClamp_Metal.png -impeller_Play_AiksTest_CanRenderLinearGradientWithOverlappingStopsClamp_MetalWideGamut.png impeller_Play_AiksTest_CanRenderLinearGradientWithOverlappingStopsClamp_OpenGLES.png impeller_Play_AiksTest_CanRenderLinearGradientWithOverlappingStopsClamp_Vulkan.png impeller_Play_AiksTest_CanRenderMaskBlurHugeSigma_Metal.png -impeller_Play_AiksTest_CanRenderMaskBlurHugeSigma_MetalWideGamut.png impeller_Play_AiksTest_CanRenderMaskBlurHugeSigma_OpenGLES.png impeller_Play_AiksTest_CanRenderMaskBlurHugeSigma_Vulkan.png impeller_Play_AiksTest_CanRenderNestedClips_Metal.png -impeller_Play_AiksTest_CanRenderNestedClips_MetalWideGamut.png impeller_Play_AiksTest_CanRenderNestedClips_OpenGLES.png impeller_Play_AiksTest_CanRenderNestedClips_Vulkan.png impeller_Play_AiksTest_CanRenderOffscreenCheckerboard_Metal.png -impeller_Play_AiksTest_CanRenderOffscreenCheckerboard_MetalWideGamut.png impeller_Play_AiksTest_CanRenderOffscreenCheckerboard_OpenGLES.png impeller_Play_AiksTest_CanRenderOffscreenCheckerboard_Vulkan.png impeller_Play_AiksTest_CanRenderOverlappingMultiContourPath_Metal.png -impeller_Play_AiksTest_CanRenderOverlappingMultiContourPath_MetalWideGamut.png impeller_Play_AiksTest_CanRenderOverlappingMultiContourPath_OpenGLES.png impeller_Play_AiksTest_CanRenderOverlappingMultiContourPath_Vulkan.png impeller_Play_AiksTest_CanRenderRadialGradientManyColors_Metal.png -impeller_Play_AiksTest_CanRenderRadialGradientManyColors_MetalWideGamut.png impeller_Play_AiksTest_CanRenderRadialGradientManyColors_OpenGLES.png impeller_Play_AiksTest_CanRenderRadialGradientManyColors_Vulkan.png impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringDisabled_Metal.png -impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringDisabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringDisabled_OpenGLES.png impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringDisabled_Vulkan.png impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringEnabled_Metal.png -impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringEnabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringEnabled_OpenGLES.png impeller_Play_AiksTest_CanRenderRadialGradientWithDitheringEnabled_Vulkan.png impeller_Play_AiksTest_CanRenderRadialGradient_Metal.png -impeller_Play_AiksTest_CanRenderRadialGradient_MetalWideGamut.png impeller_Play_AiksTest_CanRenderRadialGradient_OpenGLES.png impeller_Play_AiksTest_CanRenderRadialGradient_Vulkan.png impeller_Play_AiksTest_CanRenderRoundedRectWithNonUniformRadii_Metal.png -impeller_Play_AiksTest_CanRenderRoundedRectWithNonUniformRadii_MetalWideGamut.png impeller_Play_AiksTest_CanRenderRoundedRectWithNonUniformRadii_OpenGLES.png impeller_Play_AiksTest_CanRenderRoundedRectWithNonUniformRadii_Vulkan.png impeller_Play_AiksTest_CanRenderSimpleClips_Metal.png -impeller_Play_AiksTest_CanRenderSimpleClips_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSimpleClips_OpenGLES.png impeller_Play_AiksTest_CanRenderSimpleClips_Vulkan.png impeller_Play_AiksTest_CanRenderStrokePathThatEndsAtSharpTurn_Metal.png -impeller_Play_AiksTest_CanRenderStrokePathThatEndsAtSharpTurn_MetalWideGamut.png impeller_Play_AiksTest_CanRenderStrokePathThatEndsAtSharpTurn_OpenGLES.png impeller_Play_AiksTest_CanRenderStrokePathThatEndsAtSharpTurn_Vulkan.png impeller_Play_AiksTest_CanRenderStrokePathWithCubicLine_Metal.png -impeller_Play_AiksTest_CanRenderStrokePathWithCubicLine_MetalWideGamut.png impeller_Play_AiksTest_CanRenderStrokePathWithCubicLine_OpenGLES.png impeller_Play_AiksTest_CanRenderStrokePathWithCubicLine_Vulkan.png impeller_Play_AiksTest_CanRenderStrokes_Metal.png -impeller_Play_AiksTest_CanRenderStrokes_MetalWideGamut.png impeller_Play_AiksTest_CanRenderStrokes_OpenGLES.png impeller_Play_AiksTest_CanRenderStrokes_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientClamp_Metal.png -impeller_Play_AiksTest_CanRenderSweepGradientClamp_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientClamp_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientClamp_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientDecal_Metal.png -impeller_Play_AiksTest_CanRenderSweepGradientDecal_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientDecal_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientDecal_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsClamp_Metal.png -impeller_Play_AiksTest_CanRenderSweepGradientManyColorsClamp_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsClamp_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsClamp_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsDecal_Metal.png -impeller_Play_AiksTest_CanRenderSweepGradientManyColorsDecal_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsDecal_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsDecal_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsMirror_Metal.png -impeller_Play_AiksTest_CanRenderSweepGradientManyColorsMirror_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsMirror_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsMirror_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsRepeat_Metal.png -impeller_Play_AiksTest_CanRenderSweepGradientManyColorsRepeat_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsRepeat_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientManyColorsRepeat_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientMirror_Metal.png -impeller_Play_AiksTest_CanRenderSweepGradientMirror_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientMirror_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientMirror_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientRepeat_Metal.png -impeller_Play_AiksTest_CanRenderSweepGradientRepeat_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientRepeat_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientRepeat_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringDisabled_Metal.png -impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringDisabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringDisabled_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringDisabled_Vulkan.png impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringEnabled_Metal.png -impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringEnabled_MetalWideGamut.png impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringEnabled_OpenGLES.png impeller_Play_AiksTest_CanRenderSweepGradientWithDitheringEnabled_Vulkan.png impeller_Play_AiksTest_CanRenderTextFrameSTB_Metal.png -impeller_Play_AiksTest_CanRenderTextFrameSTB_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTextFrameSTB_OpenGLES.png impeller_Play_AiksTest_CanRenderTextFrameSTB_Vulkan.png impeller_Play_AiksTest_CanRenderTextFrame_Metal.png -impeller_Play_AiksTest_CanRenderTextFrame_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTextFrame_OpenGLES.png impeller_Play_AiksTest_CanRenderTextFrame_Vulkan.png impeller_Play_AiksTest_CanRenderTextInSaveLayer_Metal.png -impeller_Play_AiksTest_CanRenderTextInSaveLayer_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTextInSaveLayer_OpenGLES.png impeller_Play_AiksTest_CanRenderTextInSaveLayer_Vulkan.png impeller_Play_AiksTest_CanRenderTextOutsideBoundaries_Metal.png -impeller_Play_AiksTest_CanRenderTextOutsideBoundaries_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTextOutsideBoundaries_OpenGLES.png impeller_Play_AiksTest_CanRenderTextOutsideBoundaries_Vulkan.png impeller_Play_AiksTest_CanRenderThickCurvedStrokes_Metal.png -impeller_Play_AiksTest_CanRenderThickCurvedStrokes_MetalWideGamut.png impeller_Play_AiksTest_CanRenderThickCurvedStrokes_OpenGLES.png impeller_Play_AiksTest_CanRenderThickCurvedStrokes_Vulkan.png impeller_Play_AiksTest_CanRenderTiledTextureClampWithTranslate_Metal.png -impeller_Play_AiksTest_CanRenderTiledTextureClampWithTranslate_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTiledTextureClampWithTranslate_OpenGLES.png impeller_Play_AiksTest_CanRenderTiledTextureClampWithTranslate_Vulkan.png impeller_Play_AiksTest_CanRenderTiledTextureClamp_Metal.png -impeller_Play_AiksTest_CanRenderTiledTextureClamp_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTiledTextureClamp_OpenGLES.png impeller_Play_AiksTest_CanRenderTiledTextureClamp_Vulkan.png impeller_Play_AiksTest_CanRenderTiledTextureDecal_Metal.png -impeller_Play_AiksTest_CanRenderTiledTextureDecal_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTiledTextureDecal_OpenGLES.png impeller_Play_AiksTest_CanRenderTiledTextureDecal_Vulkan.png impeller_Play_AiksTest_CanRenderTiledTextureMirror_Metal.png -impeller_Play_AiksTest_CanRenderTiledTextureMirror_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTiledTextureMirror_OpenGLES.png impeller_Play_AiksTest_CanRenderTiledTextureMirror_Vulkan.png impeller_Play_AiksTest_CanRenderTiledTextureRepeat_Metal.png -impeller_Play_AiksTest_CanRenderTiledTextureRepeat_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTiledTextureRepeat_OpenGLES.png impeller_Play_AiksTest_CanRenderTiledTextureRepeat_Vulkan.png impeller_Play_AiksTest_CanRenderTinyOverlappingSubpasses_Metal.png -impeller_Play_AiksTest_CanRenderTinyOverlappingSubpasses_MetalWideGamut.png impeller_Play_AiksTest_CanRenderTinyOverlappingSubpasses_OpenGLES.png impeller_Play_AiksTest_CanRenderTinyOverlappingSubpasses_Vulkan.png impeller_Play_AiksTest_CanRenderWithContiguousClipRestores_Metal.png -impeller_Play_AiksTest_CanRenderWithContiguousClipRestores_MetalWideGamut.png impeller_Play_AiksTest_CanRenderWithContiguousClipRestores_OpenGLES.png impeller_Play_AiksTest_CanRenderWithContiguousClipRestores_Vulkan.png impeller_Play_AiksTest_CanSaveLayerStandalone_Metal.png -impeller_Play_AiksTest_CanSaveLayerStandalone_MetalWideGamut.png impeller_Play_AiksTest_CanSaveLayerStandalone_OpenGLES.png impeller_Play_AiksTest_CanSaveLayerStandalone_Vulkan.png impeller_Play_AiksTest_CaptureContext_Metal.png -impeller_Play_AiksTest_CaptureContext_MetalWideGamut.png impeller_Play_AiksTest_CaptureContext_OpenGLES.png impeller_Play_AiksTest_CaptureContext_Vulkan.png impeller_Play_AiksTest_ClearBlendWithBlur_Metal.png -impeller_Play_AiksTest_ClearBlendWithBlur_MetalWideGamut.png impeller_Play_AiksTest_ClearBlendWithBlur_OpenGLES.png impeller_Play_AiksTest_ClearBlendWithBlur_Vulkan.png impeller_Play_AiksTest_ClearColorOptimizationWhenSubpassIsBiggerThanParentPass_Metal.png -impeller_Play_AiksTest_ClearColorOptimizationWhenSubpassIsBiggerThanParentPass_MetalWideGamut.png impeller_Play_AiksTest_ClearColorOptimizationWhenSubpassIsBiggerThanParentPass_OpenGLES.png impeller_Play_AiksTest_ClearColorOptimizationWhenSubpassIsBiggerThanParentPass_Vulkan.png impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectlyInteractive_Metal.png -impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectlyInteractive_MetalWideGamut.png impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectlyInteractive_OpenGLES.png impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectlyInteractive_Vulkan.png impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectly_Metal.png -impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectly_MetalWideGamut.png impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectly_OpenGLES.png impeller_Play_AiksTest_ClippedBlurFilterRendersCorrectly_Vulkan.png impeller_Play_AiksTest_ClipsUseCurrentTransform_Metal.png -impeller_Play_AiksTest_ClipsUseCurrentTransform_MetalWideGamut.png impeller_Play_AiksTest_ClipsUseCurrentTransform_OpenGLES.png impeller_Play_AiksTest_ClipsUseCurrentTransform_Vulkan.png impeller_Play_AiksTest_CollapsedDrawPaintInSubpassBackdropFilter_Metal.png -impeller_Play_AiksTest_CollapsedDrawPaintInSubpassBackdropFilter_MetalWideGamut.png impeller_Play_AiksTest_CollapsedDrawPaintInSubpassBackdropFilter_OpenGLES.png impeller_Play_AiksTest_CollapsedDrawPaintInSubpassBackdropFilter_Vulkan.png impeller_Play_AiksTest_CollapsedDrawPaintInSubpass_Metal.png -impeller_Play_AiksTest_CollapsedDrawPaintInSubpass_MetalWideGamut.png impeller_Play_AiksTest_CollapsedDrawPaintInSubpass_OpenGLES.png impeller_Play_AiksTest_CollapsedDrawPaintInSubpass_Vulkan.png impeller_Play_AiksTest_ColorMatrixFilterSubpassCollapseOptimization_Metal.png -impeller_Play_AiksTest_ColorMatrixFilterSubpassCollapseOptimization_MetalWideGamut.png impeller_Play_AiksTest_ColorMatrixFilterSubpassCollapseOptimization_OpenGLES.png impeller_Play_AiksTest_ColorMatrixFilterSubpassCollapseOptimization_Vulkan.png impeller_Play_AiksTest_ColorWheel_Metal.png -impeller_Play_AiksTest_ColorWheel_MetalWideGamut.png impeller_Play_AiksTest_ColorWheel_OpenGLES.png impeller_Play_AiksTest_ColorWheel_Vulkan.png impeller_Play_AiksTest_CoordinateConversionsAreCorrect_Metal.png -impeller_Play_AiksTest_CoordinateConversionsAreCorrect_MetalWideGamut.png impeller_Play_AiksTest_CoordinateConversionsAreCorrect_OpenGLES.png impeller_Play_AiksTest_CoordinateConversionsAreCorrect_Vulkan.png impeller_Play_AiksTest_CoverageOriginShouldBeAccountedForInSubpasses_Metal.png -impeller_Play_AiksTest_CoverageOriginShouldBeAccountedForInSubpasses_MetalWideGamut.png impeller_Play_AiksTest_CoverageOriginShouldBeAccountedForInSubpasses_OpenGLES.png impeller_Play_AiksTest_CoverageOriginShouldBeAccountedForInSubpasses_Vulkan.png impeller_Play_AiksTest_DrawAdvancedBlendPartlyOffscreen_Metal.png -impeller_Play_AiksTest_DrawAdvancedBlendPartlyOffscreen_MetalWideGamut.png impeller_Play_AiksTest_DrawAdvancedBlendPartlyOffscreen_OpenGLES.png impeller_Play_AiksTest_DrawAdvancedBlendPartlyOffscreen_Vulkan.png impeller_Play_AiksTest_DrawAtlasAdvancedAndTransform_Metal.png -impeller_Play_AiksTest_DrawAtlasAdvancedAndTransform_MetalWideGamut.png impeller_Play_AiksTest_DrawAtlasAdvancedAndTransform_OpenGLES.png impeller_Play_AiksTest_DrawAtlasAdvancedAndTransform_Vulkan.png impeller_Play_AiksTest_DrawAtlasWithColorAdvancedAndTransform_Metal.png -impeller_Play_AiksTest_DrawAtlasWithColorAdvancedAndTransform_MetalWideGamut.png impeller_Play_AiksTest_DrawAtlasWithColorAdvancedAndTransform_OpenGLES.png impeller_Play_AiksTest_DrawAtlasWithColorAdvancedAndTransform_Vulkan.png impeller_Play_AiksTest_DrawLinesRenderCorrectly_Metal.png -impeller_Play_AiksTest_DrawLinesRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_DrawLinesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_DrawLinesRenderCorrectly_Vulkan.png impeller_Play_AiksTest_DrawPaintTransformsBounds_Metal.png -impeller_Play_AiksTest_DrawPaintTransformsBounds_MetalWideGamut.png impeller_Play_AiksTest_DrawPaintTransformsBounds_OpenGLES.png impeller_Play_AiksTest_DrawPaintTransformsBounds_Vulkan.png impeller_Play_AiksTest_DrawPaintWithAdvancedBlendOverFilter_Metal.png -impeller_Play_AiksTest_DrawPaintWithAdvancedBlendOverFilter_MetalWideGamut.png impeller_Play_AiksTest_DrawPaintWithAdvancedBlendOverFilter_OpenGLES.png impeller_Play_AiksTest_DrawPaintWithAdvancedBlendOverFilter_Vulkan.png impeller_Play_AiksTest_DrawRectStrokesRenderCorrectly_Metal.png -impeller_Play_AiksTest_DrawRectStrokesRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_DrawRectStrokesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_DrawRectStrokesRenderCorrectly_Vulkan.png impeller_Play_AiksTest_DrawRectStrokesWithBevelJoinRenderCorrectly_Metal.png -impeller_Play_AiksTest_DrawRectStrokesWithBevelJoinRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_DrawRectStrokesWithBevelJoinRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_DrawRectStrokesWithBevelJoinRenderCorrectly_Vulkan.png impeller_Play_AiksTest_DrawScaledTextWithPerspectiveNoSaveLayer_Metal.png -impeller_Play_AiksTest_DrawScaledTextWithPerspectiveNoSaveLayer_MetalWideGamut.png impeller_Play_AiksTest_DrawScaledTextWithPerspectiveNoSaveLayer_OpenGLES.png impeller_Play_AiksTest_DrawScaledTextWithPerspectiveNoSaveLayer_Vulkan.png impeller_Play_AiksTest_DrawScaledTextWithPerspectiveSaveLayer_Metal.png -impeller_Play_AiksTest_DrawScaledTextWithPerspectiveSaveLayer_MetalWideGamut.png impeller_Play_AiksTest_DrawScaledTextWithPerspectiveSaveLayer_OpenGLES.png impeller_Play_AiksTest_DrawScaledTextWithPerspectiveSaveLayer_Vulkan.png impeller_Play_AiksTest_EmptySaveLayerIgnoresPaint_Metal.png -impeller_Play_AiksTest_EmptySaveLayerIgnoresPaint_MetalWideGamut.png impeller_Play_AiksTest_EmptySaveLayerIgnoresPaint_OpenGLES.png impeller_Play_AiksTest_EmptySaveLayerIgnoresPaint_Vulkan.png impeller_Play_AiksTest_EmptySaveLayerRendersWithClear_Metal.png -impeller_Play_AiksTest_EmptySaveLayerRendersWithClear_MetalWideGamut.png impeller_Play_AiksTest_EmptySaveLayerRendersWithClear_OpenGLES.png impeller_Play_AiksTest_EmptySaveLayerRendersWithClear_Vulkan.png impeller_Play_AiksTest_FilledCirclesRenderCorrectly_Metal.png -impeller_Play_AiksTest_FilledCirclesRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_FilledCirclesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_FilledCirclesRenderCorrectly_Vulkan.png impeller_Play_AiksTest_FilledEllipsesRenderCorrectly_Metal.png -impeller_Play_AiksTest_FilledEllipsesRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_FilledEllipsesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_FilledEllipsesRenderCorrectly_Vulkan.png impeller_Play_AiksTest_FilledRoundRectPathsRenderCorrectly_Metal.png -impeller_Play_AiksTest_FilledRoundRectPathsRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_FilledRoundRectPathsRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_FilledRoundRectPathsRenderCorrectly_Vulkan.png impeller_Play_AiksTest_FilledRoundRectsRenderCorrectly_Metal.png -impeller_Play_AiksTest_FilledRoundRectsRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_FilledRoundRectsRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_FilledRoundRectsRenderCorrectly_Vulkan.png impeller_Play_AiksTest_ForegroundBlendSubpassCollapseOptimization_Metal.png -impeller_Play_AiksTest_ForegroundBlendSubpassCollapseOptimization_MetalWideGamut.png impeller_Play_AiksTest_ForegroundBlendSubpassCollapseOptimization_OpenGLES.png impeller_Play_AiksTest_ForegroundBlendSubpassCollapseOptimization_Vulkan.png impeller_Play_AiksTest_GaussianBlurAnimatedBackdrop_Metal.png -impeller_Play_AiksTest_GaussianBlurAnimatedBackdrop_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurAnimatedBackdrop_OpenGLES.png impeller_Play_AiksTest_GaussianBlurAnimatedBackdrop_Vulkan.png impeller_Play_AiksTest_GaussianBlurAtPeripheryHorizontal_Metal.png -impeller_Play_AiksTest_GaussianBlurAtPeripheryHorizontal_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurAtPeripheryHorizontal_OpenGLES.png impeller_Play_AiksTest_GaussianBlurAtPeripheryHorizontal_Vulkan.png impeller_Play_AiksTest_GaussianBlurAtPeripheryVertical_Metal.png -impeller_Play_AiksTest_GaussianBlurAtPeripheryVertical_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurAtPeripheryVertical_OpenGLES.png impeller_Play_AiksTest_GaussianBlurAtPeripheryVertical_Vulkan.png impeller_Play_AiksTest_GaussianBlurOneDimension_Metal.png -impeller_Play_AiksTest_GaussianBlurOneDimension_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurOneDimension_OpenGLES.png impeller_Play_AiksTest_GaussianBlurOneDimension_Vulkan.png impeller_Play_AiksTest_GaussianBlurRotatedAndClippedInteractive_Metal.png -impeller_Play_AiksTest_GaussianBlurRotatedAndClippedInteractive_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurRotatedAndClippedInteractive_OpenGLES.png impeller_Play_AiksTest_GaussianBlurRotatedAndClippedInteractive_Vulkan.png impeller_Play_AiksTest_GaussianBlurRotatedAndClipped_Metal.png -impeller_Play_AiksTest_GaussianBlurRotatedAndClipped_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurRotatedAndClipped_OpenGLES.png impeller_Play_AiksTest_GaussianBlurRotatedAndClipped_Vulkan.png impeller_Play_AiksTest_GaussianBlurScaledAndClipped_Metal.png -impeller_Play_AiksTest_GaussianBlurScaledAndClipped_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurScaledAndClipped_OpenGLES.png impeller_Play_AiksTest_GaussianBlurScaledAndClipped_Vulkan.png impeller_Play_AiksTest_GaussianBlurStyleInnerGradient_Metal.png -impeller_Play_AiksTest_GaussianBlurStyleInnerGradient_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurStyleInnerGradient_OpenGLES.png impeller_Play_AiksTest_GaussianBlurStyleInnerGradient_Vulkan.png impeller_Play_AiksTest_GaussianBlurStyleInner_Metal.png -impeller_Play_AiksTest_GaussianBlurStyleInner_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurStyleInner_OpenGLES.png impeller_Play_AiksTest_GaussianBlurStyleInner_Vulkan.png impeller_Play_AiksTest_GaussianBlurStyleOuterGradient_Metal.png -impeller_Play_AiksTest_GaussianBlurStyleOuterGradient_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurStyleOuterGradient_OpenGLES.png impeller_Play_AiksTest_GaussianBlurStyleOuterGradient_Vulkan.png impeller_Play_AiksTest_GaussianBlurStyleOuter_Metal.png -impeller_Play_AiksTest_GaussianBlurStyleOuter_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurStyleOuter_OpenGLES.png impeller_Play_AiksTest_GaussianBlurStyleOuter_Vulkan.png impeller_Play_AiksTest_GaussianBlurStyleSolidGradient_Metal.png -impeller_Play_AiksTest_GaussianBlurStyleSolidGradient_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurStyleSolidGradient_OpenGLES.png impeller_Play_AiksTest_GaussianBlurStyleSolidGradient_Vulkan.png impeller_Play_AiksTest_GaussianBlurStyleSolid_Metal.png -impeller_Play_AiksTest_GaussianBlurStyleSolid_MetalWideGamut.png impeller_Play_AiksTest_GaussianBlurStyleSolid_OpenGLES.png impeller_Play_AiksTest_GaussianBlurStyleSolid_Vulkan.png impeller_Play_AiksTest_GaussianBlurWithoutDecalSupport_Metal.png impeller_Play_AiksTest_GradientStrokesRenderCorrectly_Metal.png -impeller_Play_AiksTest_GradientStrokesRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_GradientStrokesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_GradientStrokesRenderCorrectly_Vulkan.png impeller_Play_AiksTest_GuassianBlurUpdatesMipmapContents_Metal.png -impeller_Play_AiksTest_GuassianBlurUpdatesMipmapContents_MetalWideGamut.png impeller_Play_AiksTest_GuassianBlurUpdatesMipmapContents_OpenGLES.png impeller_Play_AiksTest_GuassianBlurUpdatesMipmapContents_Vulkan.png impeller_Play_AiksTest_ImageColorSourceEffectTransform_Metal.png -impeller_Play_AiksTest_ImageColorSourceEffectTransform_MetalWideGamut.png impeller_Play_AiksTest_ImageColorSourceEffectTransform_OpenGLES.png impeller_Play_AiksTest_ImageColorSourceEffectTransform_Vulkan.png impeller_Play_AiksTest_ImageFilteredSaveLayerWithUnboundedContents_Metal.png -impeller_Play_AiksTest_ImageFilteredSaveLayerWithUnboundedContents_MetalWideGamut.png impeller_Play_AiksTest_ImageFilteredSaveLayerWithUnboundedContents_OpenGLES.png impeller_Play_AiksTest_ImageFilteredSaveLayerWithUnboundedContents_Vulkan.png impeller_Play_AiksTest_ImageFilteredUnboundedSaveLayerWithUnboundedContents_Metal.png -impeller_Play_AiksTest_ImageFilteredUnboundedSaveLayerWithUnboundedContents_MetalWideGamut.png impeller_Play_AiksTest_ImageFilteredUnboundedSaveLayerWithUnboundedContents_OpenGLES.png impeller_Play_AiksTest_ImageFilteredUnboundedSaveLayerWithUnboundedContents_Vulkan.png impeller_Play_AiksTest_LinearToSrgbFilterSubpassCollapseOptimization_Metal.png -impeller_Play_AiksTest_LinearToSrgbFilterSubpassCollapseOptimization_MetalWideGamut.png impeller_Play_AiksTest_LinearToSrgbFilterSubpassCollapseOptimization_OpenGLES.png impeller_Play_AiksTest_LinearToSrgbFilterSubpassCollapseOptimization_Vulkan.png impeller_Play_AiksTest_MaskBlurDoesntStretchContents_Metal.png -impeller_Play_AiksTest_MaskBlurDoesntStretchContents_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurDoesntStretchContents_OpenGLES.png impeller_Play_AiksTest_MaskBlurDoesntStretchContents_Vulkan.png impeller_Play_AiksTest_MaskBlurTexture_Metal.png -impeller_Play_AiksTest_MaskBlurTexture_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurTexture_OpenGLES.png impeller_Play_AiksTest_MaskBlurTexture_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucentWithBlurImageFilter_Metal.png -impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucentWithBlurImageFilter_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucentWithBlurImageFilter_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucentWithBlurImageFilter_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucent_Metal.png -impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucent_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucent_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestInnerTranslucent_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucentZeroSigma_Metal.png -impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucentZeroSigma_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucentZeroSigma_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucentZeroSigma_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucent_Metal.png -impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucent_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucent_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestNormalTranslucent_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestOuterOpaqueWithBlurImageFilter_Metal.png -impeller_Play_AiksTest_MaskBlurVariantTestOuterOpaqueWithBlurImageFilter_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestOuterOpaqueWithBlurImageFilter_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestOuterOpaqueWithBlurImageFilter_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestOuterTranslucent_Metal.png -impeller_Play_AiksTest_MaskBlurVariantTestOuterTranslucent_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestOuterTranslucent_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestOuterTranslucent_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestSolidOpaque_Metal.png -impeller_Play_AiksTest_MaskBlurVariantTestSolidOpaque_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestSolidOpaque_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestSolidOpaque_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentExclusionBlend_Metal.png -impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentExclusionBlend_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentExclusionBlend_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentExclusionBlend_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentWithFilters_Metal.png -impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentWithFilters_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentWithFilters_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucentWithFilters_Vulkan.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucent_Metal.png -impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucent_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucent_OpenGLES.png impeller_Play_AiksTest_MaskBlurVariantTestSolidTranslucent_Vulkan.png impeller_Play_AiksTest_MaskBlurWithZeroSigmaIsSkipped_Metal.png -impeller_Play_AiksTest_MaskBlurWithZeroSigmaIsSkipped_MetalWideGamut.png impeller_Play_AiksTest_MaskBlurWithZeroSigmaIsSkipped_OpenGLES.png impeller_Play_AiksTest_MaskBlurWithZeroSigmaIsSkipped_Vulkan.png impeller_Play_AiksTest_MatrixBackdropFilter_Metal.png -impeller_Play_AiksTest_MatrixBackdropFilter_MetalWideGamut.png impeller_Play_AiksTest_MatrixBackdropFilter_OpenGLES.png impeller_Play_AiksTest_MatrixBackdropFilter_Vulkan.png impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen_Metal.png -impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen_MetalWideGamut.png impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen_OpenGLES.png impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen_Vulkan.png impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen_Metal.png -impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen_MetalWideGamut.png impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen_OpenGLES.png impeller_Play_AiksTest_MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen_Vulkan.png impeller_Play_AiksTest_MatrixImageFilterMagnify_Metal.png -impeller_Play_AiksTest_MatrixImageFilterMagnify_MetalWideGamut.png impeller_Play_AiksTest_MatrixImageFilterMagnify_OpenGLES.png impeller_Play_AiksTest_MatrixImageFilterMagnify_Vulkan.png impeller_Play_AiksTest_MatrixSaveLayerFilter_Metal.png -impeller_Play_AiksTest_MatrixSaveLayerFilter_MetalWideGamut.png impeller_Play_AiksTest_MatrixSaveLayerFilter_OpenGLES.png impeller_Play_AiksTest_MatrixSaveLayerFilter_Vulkan.png impeller_Play_AiksTest_PaintBlendModeIsRespected_Metal.png -impeller_Play_AiksTest_PaintBlendModeIsRespected_MetalWideGamut.png impeller_Play_AiksTest_PaintBlendModeIsRespected_OpenGLES.png impeller_Play_AiksTest_PaintBlendModeIsRespected_Vulkan.png impeller_Play_AiksTest_PipelineBlendSingleParameter_Metal.png -impeller_Play_AiksTest_PipelineBlendSingleParameter_MetalWideGamut.png impeller_Play_AiksTest_PipelineBlendSingleParameter_OpenGLES.png impeller_Play_AiksTest_PipelineBlendSingleParameter_Vulkan.png impeller_Play_AiksTest_ReleasesTextureOnTeardown_Metal.png -impeller_Play_AiksTest_ReleasesTextureOnTeardown_MetalWideGamut.png impeller_Play_AiksTest_ReleasesTextureOnTeardown_OpenGLES.png impeller_Play_AiksTest_ReleasesTextureOnTeardown_Vulkan.png impeller_Play_AiksTest_RotateColorFilteredPath_Metal.png -impeller_Play_AiksTest_RotateColorFilteredPath_MetalWideGamut.png impeller_Play_AiksTest_RotateColorFilteredPath_OpenGLES.png impeller_Play_AiksTest_RotateColorFilteredPath_Vulkan.png impeller_Play_AiksTest_SaveLayerDrawsBehindSubsequentEntities_Metal.png -impeller_Play_AiksTest_SaveLayerDrawsBehindSubsequentEntities_MetalWideGamut.png impeller_Play_AiksTest_SaveLayerDrawsBehindSubsequentEntities_OpenGLES.png impeller_Play_AiksTest_SaveLayerDrawsBehindSubsequentEntities_Vulkan.png impeller_Play_AiksTest_SaveLayerFiltersScaleWithTransform_Metal.png -impeller_Play_AiksTest_SaveLayerFiltersScaleWithTransform_MetalWideGamut.png impeller_Play_AiksTest_SaveLayerFiltersScaleWithTransform_OpenGLES.png impeller_Play_AiksTest_SaveLayerFiltersScaleWithTransform_Vulkan.png impeller_Play_AiksTest_SiblingSaveLayerBoundsAreRespected_Metal.png -impeller_Play_AiksTest_SiblingSaveLayerBoundsAreRespected_MetalWideGamut.png impeller_Play_AiksTest_SiblingSaveLayerBoundsAreRespected_OpenGLES.png impeller_Play_AiksTest_SiblingSaveLayerBoundsAreRespected_Vulkan.png impeller_Play_AiksTest_SolidColorCirclesOvalsRRectsMaskBlurCorrectly_Metal.png -impeller_Play_AiksTest_SolidColorCirclesOvalsRRectsMaskBlurCorrectly_MetalWideGamut.png impeller_Play_AiksTest_SolidColorCirclesOvalsRRectsMaskBlurCorrectly_OpenGLES.png impeller_Play_AiksTest_SolidColorCirclesOvalsRRectsMaskBlurCorrectly_Vulkan.png impeller_Play_AiksTest_SolidStrokesRenderCorrectly_Metal.png -impeller_Play_AiksTest_SolidStrokesRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_SolidStrokesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_SolidStrokesRenderCorrectly_Vulkan.png impeller_Play_AiksTest_SrgbToLinearFilterSubpassCollapseOptimization_Metal.png -impeller_Play_AiksTest_SrgbToLinearFilterSubpassCollapseOptimization_MetalWideGamut.png impeller_Play_AiksTest_SrgbToLinearFilterSubpassCollapseOptimization_OpenGLES.png impeller_Play_AiksTest_SrgbToLinearFilterSubpassCollapseOptimization_Vulkan.png impeller_Play_AiksTest_StrokedCirclesRenderCorrectly_Metal.png -impeller_Play_AiksTest_StrokedCirclesRenderCorrectly_MetalWideGamut.png impeller_Play_AiksTest_StrokedCirclesRenderCorrectly_OpenGLES.png impeller_Play_AiksTest_StrokedCirclesRenderCorrectly_Vulkan.png impeller_Play_AiksTest_SubpassWithClearColorOptimization_Metal.png -impeller_Play_AiksTest_SubpassWithClearColorOptimization_MetalWideGamut.png impeller_Play_AiksTest_SubpassWithClearColorOptimization_OpenGLES.png impeller_Play_AiksTest_SubpassWithClearColorOptimization_Vulkan.png impeller_Play_AiksTest_TextForegroundShaderWithTransform_Metal.png -impeller_Play_AiksTest_TextForegroundShaderWithTransform_MetalWideGamut.png impeller_Play_AiksTest_TextForegroundShaderWithTransform_OpenGLES.png impeller_Play_AiksTest_TextForegroundShaderWithTransform_Vulkan.png impeller_Play_AiksTest_TextFrameSubpixelAlignment_Metal.png -impeller_Play_AiksTest_TextFrameSubpixelAlignment_MetalWideGamut.png impeller_Play_AiksTest_TextFrameSubpixelAlignment_OpenGLES.png impeller_Play_AiksTest_TextFrameSubpixelAlignment_Vulkan.png -impeller_Play_AiksTest_TextRotated_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerDrawsCorrectly_Metal.png -impeller_Play_AiksTest_TranslucentSaveLayerDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerImageDrawsCorrectly_Metal.png -impeller_Play_AiksTest_TranslucentSaveLayerImageDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerImageDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerImageDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly_Metal.png -impeller_Play_AiksTest_TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly_Metal.png -impeller_Play_AiksTest_TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly_Metal.png -impeller_Play_AiksTest_TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly_Metal.png -impeller_Play_AiksTest_TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly_Metal.png -impeller_Play_AiksTest_TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly_Metal.png -impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly_Metal.png -impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly_MetalWideGamut.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly_OpenGLES.png impeller_Play_AiksTest_TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly_Vulkan.png impeller_Play_AiksTest_VerticesGeometryUVPositionDataWithTranslate_Metal.png -impeller_Play_AiksTest_VerticesGeometryUVPositionDataWithTranslate_MetalWideGamut.png impeller_Play_AiksTest_VerticesGeometryUVPositionDataWithTranslate_OpenGLES.png impeller_Play_AiksTest_VerticesGeometryUVPositionDataWithTranslate_Vulkan.png impeller_Play_AiksTest_VerticesGeometryUVPositionData_Metal.png -impeller_Play_AiksTest_VerticesGeometryUVPositionData_MetalWideGamut.png impeller_Play_AiksTest_VerticesGeometryUVPositionData_OpenGLES.png impeller_Play_AiksTest_VerticesGeometryUVPositionData_Vulkan.png \ No newline at end of file From 509f20be4233c85e15057e4ebf0aebefb2bf1152 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 15 Mar 2024 09:58:35 -0700 Subject: [PATCH 04/25] [Impeller] fixes alpha blend for plus blend mode added test fixed screenshoter fix dl_test_surface limited the new blend to only wide gamut contexts tidy updated golden --- impeller/aiks/aiks_unittests.cc | 21 +++++++++++++++++++++ impeller/entity/contents/content_context.cc | 10 +++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 7dc1c2a5e31bf..86266b3b27b54 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -1101,6 +1101,27 @@ TEST_P(AiksTest, PaintBlendModeIsRespected) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } +// Bug: https://github.com/flutter/flutter/issues/142549 +TEST_P(AiksTest, BlendModePlusAlpha) { + auto texture = CreateTextureForFixture("airplane.jpg", + /*enable_mipmapping=*/true); + + Canvas canvas; + canvas.Scale(GetContentScale()); + canvas.DrawPaint({.color = Color(0.9, 1.0, 0.9, 1.0)}); + canvas.SaveLayer({}); + Paint paint; + paint.blend_mode = BlendMode::kPlus; + paint.color = Color::Red(); + canvas.DrawRect(Rect::MakeXYWH(100, 100, 400, 400), paint); + paint.color = Color::White(); + canvas.DrawImageRect( + std::make_shared(texture), Rect::MakeSize(texture->GetSize()), + Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100), paint); + canvas.Restore(); + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + TEST_P(AiksTest, ColorWheel) { // Compare with https://fiddle.skia.org/c/@BlendModes diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index f500d1b75c14c..d7e933fe3105c 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -24,6 +24,11 @@ namespace impeller { +bool IsAlphaClampedToOne(PixelFormat pixel_format) { + return !(pixel_format == PixelFormat::kR32G32B32A32Float || + pixel_format == PixelFormat::kR16G16B16A16Float); +} + void ContentContextOptions::ApplyToPipelineDescriptor( PipelineDescriptor& desc) const { auto pipeline_blend = blend_mode; @@ -124,7 +129,10 @@ void ContentContextOptions::ApplyToPipelineDescriptor( color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha; break; case BlendMode::kPlus: - color0.dst_alpha_blend_factor = BlendFactor::kOne; + color0.dst_alpha_blend_factor = + IsAlphaClampedToOne(color_attachment_pixel_format) + ? BlendFactor::kOne + : BlendFactor::kOneMinusSourceAlpha; color0.dst_color_blend_factor = BlendFactor::kOne; color0.src_alpha_blend_factor = BlendFactor::kOne; color0.src_color_blend_factor = BlendFactor::kOne; From 47498e11755ca187fd367903f533cd1f7c8fda09 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Thu, 21 Mar 2024 13:04:05 -0700 Subject: [PATCH 05/25] [Impeller] made plus an advanced blend --- impeller/aiks/aiks_unittests.cc | 36 +++++++++++++++++++ impeller/entity/contents/content_context.cc | 15 ++++---- impeller/entity/contents/content_context.h | 19 ++++++++++ .../contents/filters/blend_filter_contents.cc | 3 ++ .../contents/filters/blend_filter_contents.h | 3 +- .../contents/framebuffer_blend_contents.cc | 3 ++ .../contents/framebuffer_blend_contents.h | 1 + .../shaders/blending/advanced_blend.frag | 13 +++++-- .../entity/shaders/blending/blend_select.glsl | 4 ++- .../shaders/blending/framebuffer_blend.frag | 13 +++++-- impeller/geometry/color.h | 4 +-- 11 files changed, 96 insertions(+), 18 deletions(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 86266b3b27b54..2f0f10d1e4d70 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -1122,6 +1122,42 @@ TEST_P(AiksTest, BlendModePlusAlpha) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } +// Bug: https://github.com/flutter/flutter/issues/142549 +TEST_P(AiksTest, BlendModePlusAlphaHalf) { + Canvas canvas; + canvas.Scale(GetContentScale()); + canvas.DrawPaint({.color = Color(0.9, 1.0, 0.9, 1.0)}); + canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300), + {.color = Color(1, 0, 0, 0.5)}); + canvas.SaveLayer({}); + Paint paint; + paint.blend_mode = BlendMode::kPlus; + paint.color = Color(0, 0, 1, 0.5); + canvas.DrawRect(Rect::MakeXYWH(0, 0, 150, 300), paint); + paint.color = Color(1, 0, 1, 1); + canvas.DrawRect(Rect::MakeXYWH(150, 0, 150, 300), paint); + canvas.Restore(); + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + +TEST_P(AiksTest, BlendModePlusAlphaFoo) { + Canvas canvas; + canvas.Scale(GetContentScale()); + canvas.DrawPaint({.color = Color(0.9, 1.0, 0.9, 1.0)}); + canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300), {.color = Color(1, 0, 0, 1)}); + canvas.SaveLayer({}); + Paint paint; + paint.blend_mode = BlendMode::kPlus; + paint.color = Color(0, 0, 1, 10.0 / 255.0); + for (int i = 0; i < 20; ++i) { + canvas.DrawRect(Rect::MakeXYWH(0, 0, 150, 300), paint); + } + paint.color = Color(0, 0, 1, 200.0 / 255.0); + canvas.DrawRect(Rect::MakeXYWH(150, 0, 150, 300), paint); + canvas.Restore(); + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + TEST_P(AiksTest, ColorWheel) { // Compare with https://fiddle.skia.org/c/@BlendModes diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index d7e933fe3105c..1e0d13751348f 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -128,15 +128,6 @@ void ContentContextOptions::ApplyToPipelineDescriptor( color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha; color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha; break; - case BlendMode::kPlus: - color0.dst_alpha_blend_factor = - IsAlphaClampedToOne(color_attachment_pixel_format) - ? BlendFactor::kOne - : BlendFactor::kOneMinusSourceAlpha; - color0.dst_color_blend_factor = BlendFactor::kOne; - color0.src_alpha_blend_factor = BlendFactor::kOne; - color0.src_color_blend_factor = BlendFactor::kOne; - break; case BlendMode::kModulate: color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha; color0.dst_color_blend_factor = BlendFactor::kSourceColor; @@ -332,6 +323,9 @@ ContentContext::ContentContext( framebuffer_blend_lighten_pipelines_.CreateDefault( *context_, options_trianglestrip, {static_cast(BlendSelectValues::kLighten), supports_decal}); + framebuffer_blend_plus_pipelines_.CreateDefault( + *context_, options_trianglestrip, + {static_cast(BlendSelectValues::kPlus), supports_decal}); framebuffer_blend_luminosity_pipelines_.CreateDefault( *context_, options_trianglestrip, {static_cast(BlendSelectValues::kLuminosity), supports_decal}); @@ -379,6 +373,9 @@ ContentContext::ContentContext( blend_lighten_pipelines_.CreateDefault( *context_, options_trianglestrip, {static_cast(BlendSelectValues::kLighten), supports_decal}); + blend_plus_pipelines_.CreateDefault( + *context_, options_trianglestrip, + {static_cast(BlendSelectValues::kPlus), supports_decal}); blend_luminosity_pipelines_.CreateDefault( *context_, options_trianglestrip, {static_cast(BlendSelectValues::kLuminosity), supports_decal}); diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index c1eed6ea2fada..74f0039a79ef6 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -197,6 +197,8 @@ using BlendHuePipeline = RenderPipelineT; using BlendLightenPipeline = RenderPipelineT; +using BlendPlusPipeline = + RenderPipelineT; using BlendLuminosityPipeline = RenderPipelineT; using BlendMultiplyPipeline = @@ -237,6 +239,9 @@ using FramebufferBlendHuePipeline = using FramebufferBlendLightenPipeline = RenderPipelineT; +using FramebufferBlendPlusPipeline = + RenderPipelineT; using FramebufferBlendLuminosityPipeline = RenderPipelineT; @@ -640,6 +645,11 @@ class ContentContext { return GetPipeline(blend_lighten_pipelines_, opts); } + std::shared_ptr> GetBlendPlusPipeline( + ContentContextOptions opts) const { + return GetPipeline(blend_plus_pipelines_, opts); + } + std::shared_ptr> GetBlendLuminosityPipeline( ContentContextOptions opts) const { return GetPipeline(blend_luminosity_pipelines_, opts); @@ -725,6 +735,12 @@ class ContentContext { return GetPipeline(framebuffer_blend_lighten_pipelines_, opts); } + std::shared_ptr> GetFramebufferBlendPlusPipeline( + ContentContextOptions opts) const { + FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); + return GetPipeline(framebuffer_blend_plus_pipelines_, opts); + } + std::shared_ptr> GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); @@ -989,6 +1005,7 @@ class ContentContext { mutable Variants blend_hardlight_pipelines_; mutable Variants blend_hue_pipelines_; mutable Variants blend_lighten_pipelines_; + mutable Variants blend_plus_pipelines_; mutable Variants blend_luminosity_pipelines_; mutable Variants blend_multiply_pipelines_; mutable Variants blend_overlay_pipelines_; @@ -1014,6 +1031,8 @@ class ContentContext { framebuffer_blend_hue_pipelines_; mutable Variants framebuffer_blend_lighten_pipelines_; + mutable Variants + framebuffer_blend_plus_pipelines_; mutable Variants framebuffer_blend_luminosity_pipelines_; mutable Variants diff --git a/impeller/entity/contents/filters/blend_filter_contents.cc b/impeller/entity/contents/filters/blend_filter_contents.cc index 4aadfa3f5ba8f..7fc97b87b6e39 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/impeller/entity/contents/filters/blend_filter_contents.cc @@ -338,6 +338,9 @@ std::optional BlendFilterContents::CreateForegroundAdvancedBlend( case BlendMode::kColor: pass.SetPipeline(renderer.GetBlendColorPipeline(options)); break; + case BlendMode::kPlus: + pass.SetPipeline(renderer.GetBlendPlusPipeline(options)); + break; case BlendMode::kLuminosity: pass.SetPipeline(renderer.GetBlendLuminosityPipeline(options)); break; diff --git a/impeller/entity/contents/filters/blend_filter_contents.h b/impeller/entity/contents/filters/blend_filter_contents.h index 75f575f5b2aaf..645056a915e30 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.h +++ b/impeller/entity/contents/filters/blend_filter_contents.h @@ -12,7 +12,7 @@ namespace impeller { -constexpr std::array, 15> kPorterDuffCoefficients = {{ +constexpr std::array, 14> kPorterDuffCoefficients = {{ {0, 0, 0, 0, 0}, // Clear {1, 0, 0, 0, 0}, // Source {0, 0, 1, 0, 0}, // Destination @@ -25,7 +25,6 @@ constexpr std::array, 15> kPorterDuffCoefficients = {{ {0, 1, 1, -1, 0}, // SourceATop {1, -1, 0, 1, 0}, // DestinationATop {1, -1, 1, -1, 0}, // Xor - {1, 0, 1, 0, 0}, // Plus {0, 0, 0, 0, 1}, // Modulate {0, 0, 1, 0, -1}, // Screen }}; diff --git a/impeller/entity/contents/framebuffer_blend_contents.cc b/impeller/entity/contents/framebuffer_blend_contents.cc index c4a75ddd03ab4..0854167ebb2bf 100644 --- a/impeller/entity/contents/framebuffer_blend_contents.cc +++ b/impeller/entity/contents/framebuffer_blend_contents.cc @@ -118,6 +118,9 @@ bool FramebufferBlendContents::Render(const ContentContext& renderer, case BlendMode::kColor: pass.SetPipeline(renderer.GetFramebufferBlendColorPipeline(options)); break; + case BlendMode::kPlus: + pass.SetPipeline(renderer.GetFramebufferBlendPlusPipeline(options)); + break; case BlendMode::kLuminosity: pass.SetPipeline(renderer.GetFramebufferBlendLuminosityPipeline(options)); break; diff --git a/impeller/entity/contents/framebuffer_blend_contents.h b/impeller/entity/contents/framebuffer_blend_contents.h index 5335055bd3f61..fd3a70e52f3ea 100644 --- a/impeller/entity/contents/framebuffer_blend_contents.h +++ b/impeller/entity/contents/framebuffer_blend_contents.h @@ -27,6 +27,7 @@ enum class BlendSelectValues { kHue, kSaturation, kColor, + kPlus, kLuminosity, }; diff --git a/impeller/entity/shaders/blending/advanced_blend.frag b/impeller/entity/shaders/blending/advanced_blend.frag index db444f522a092..882213e254fbc 100644 --- a/impeller/entity/shaders/blending/advanced_blend.frag +++ b/impeller/entity/shaders/blending/advanced_blend.frag @@ -51,7 +51,16 @@ void main() { src.a *= blend_info.src_input_alpha; } - f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, int(blend_type)); + int nblend_type = int(blend_type); - frag_color = IPApplyBlendedColor(dst, src, blend_result); + if (nblend_type == /*BlendSelectValues::kPlus*/ 14) { + f16vec4 plus = src + dst; + if (plus.a > 1.0hf) { + plus.a = 1.0hf; + } + frag_color = IPHalfPremultiply(plus); + } else { + f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, nblend_type); + frag_color = IPApplyBlendedColor(dst, src, blend_result); + } } diff --git a/impeller/entity/shaders/blending/blend_select.glsl b/impeller/entity/shaders/blending/blend_select.glsl index 17c45c16fdcf4..c0b90acc77416 100644 --- a/impeller/entity/shaders/blending/blend_select.glsl +++ b/impeller/entity/shaders/blending/blend_select.glsl @@ -20,6 +20,7 @@ // kHue, // kSaturation, // kColor, +// kPlus, // kLuminosity, // Note, this isn't a switch as GLSL ES 1.0 does not support them. f16vec3 AdvancedBlend(f16vec3 dst, f16vec3 src, int blend_type) { @@ -65,7 +66,8 @@ f16vec3 AdvancedBlend(f16vec3 dst, f16vec3 src, int blend_type) { if (blend_type == 13) { return IPBlendColor(dst, src); } - if (blend_type == 14) { + // 14 is `plus`, it's handled in advanced_blend.frag. + if (blend_type == 15) { return IPBlendLuminosity(dst, src); } return f16vec3(0.0hf); diff --git a/impeller/entity/shaders/blending/framebuffer_blend.frag b/impeller/entity/shaders/blending/framebuffer_blend.frag index 6d03856b4a824..19118738967cc 100644 --- a/impeller/entity/shaders/blending/framebuffer_blend.frag +++ b/impeller/entity/shaders/blending/framebuffer_blend.frag @@ -50,7 +50,16 @@ void main() { ))); src.a *= frag_info.src_input_alpha; - f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, int(blend_type)); + int nblend_type = int(blend_type); - frag_color = IPApplyBlendedColor(dst, src, blend_result); + if (nblend_type == /*BlendSelectValues::kPlus*/ 14) { + f16vec4 plus = src + dst; + if (plus.a > 1.0hf) { + plus.a = 1.0hf; + } + frag_color = IPHalfPremultiply(plus); + } else { + f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, nblend_type); + frag_color = IPApplyBlendedColor(dst, src, blend_result); + } } diff --git a/impeller/geometry/color.h b/impeller/geometry/color.h index c90c696066ed6..f1c07c7beb0f8 100644 --- a/impeller/geometry/color.h +++ b/impeller/geometry/color.h @@ -29,7 +29,6 @@ V(SourceATop) \ V(DestinationATop) \ V(Xor) \ - V(Plus) \ V(Modulate) \ V(Screen) \ V(Overlay) \ @@ -45,6 +44,7 @@ V(Hue) \ V(Saturation) \ V(Color) \ + V(Plus) \ V(Luminosity) namespace impeller { @@ -71,7 +71,6 @@ enum class BlendMode : uint8_t { kSourceATop, kDestinationATop, kXor, - kPlus, kModulate, // The following blend modes use equations that are not available for @@ -91,6 +90,7 @@ enum class BlendMode : uint8_t { kHue, kSaturation, kColor, + kPlus, kLuminosity, kLast = kLuminosity, From c2a9d68bc22e6ddf57590863959dc6bb9c94e9d6 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 22 Mar 2024 14:05:42 -0700 Subject: [PATCH 06/25] fixed the blending math (jasons test passes now) --- .../shaders/blending/advanced_blend.frag | 40 +++++++++++-------- .../shaders/blending/framebuffer_blend.frag | 16 ++++---- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/impeller/entity/shaders/blending/advanced_blend.frag b/impeller/entity/shaders/blending/advanced_blend.frag index 882213e254fbc..1d8202c957927 100644 --- a/impeller/entity/shaders/blending/advanced_blend.frag +++ b/impeller/entity/shaders/blending/advanced_blend.frag @@ -36,30 +36,36 @@ f16vec4 Sample(f16sampler2D texture_sampler, vec2 texture_coords) { } void main() { - f16vec4 dst = - IPHalfUnpremultiply(Sample(texture_sampler_dst, // sampler - v_dst_texture_coords // texture coordinates - )); - dst *= blend_info.dst_input_alpha; - f16vec4 src = blend_info.color_factor > 0.0hf - ? blend_info.color - : IPHalfUnpremultiply(Sample( - texture_sampler_src, // sampler - v_src_texture_coords // texture coordinates - )); - if (blend_info.color_factor == 0.0hf) { - src.a *= blend_info.src_input_alpha; - } - + f16vec4 premultiplied_dst = + Sample(texture_sampler_dst, // sampler + v_dst_texture_coords // texture coordinates + ); int nblend_type = int(blend_type); if (nblend_type == /*BlendSelectValues::kPlus*/ 14) { - f16vec4 plus = src + dst; + f16vec4 premultiplied_src = + Sample(texture_sampler_src, // sampler + v_src_texture_coords // texture coordinates + ); + f16vec4 plus = premultiplied_dst + premultiplied_src; if (plus.a > 1.0hf) { plus.a = 1.0hf; } - frag_color = IPHalfPremultiply(plus); + frag_color = plus; } else { + f16vec4 dst = IPHalfUnpremultiply(premultiplied_dst); + dst *= blend_info.dst_input_alpha; + + f16vec4 src = blend_info.color_factor > 0.0hf + ? blend_info.color + : IPHalfUnpremultiply(Sample( + texture_sampler_src, // sampler + v_src_texture_coords // texture coordinates + )); + if (blend_info.color_factor == 0.0hf) { + src.a *= blend_info.src_input_alpha; + } + f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, nblend_type); frag_color = IPApplyBlendedColor(dst, src, blend_result); } diff --git a/impeller/entity/shaders/blending/framebuffer_blend.frag b/impeller/entity/shaders/blending/framebuffer_blend.frag index 19118738967cc..b4beba329c3c6 100644 --- a/impeller/entity/shaders/blending/framebuffer_blend.frag +++ b/impeller/entity/shaders/blending/framebuffer_blend.frag @@ -43,22 +43,24 @@ vec4 Sample(sampler2D texture_sampler, vec2 texture_coords) { } void main() { - f16vec4 dst = IPHalfUnpremultiply(f16vec4(ReadDestination())); - f16vec4 src = IPHalfUnpremultiply( + f16vec4 premultiplied_dst = f16vec4(ReadDestination()); + f16vec4 premultiplied_src = f16vec4(Sample(texture_sampler_src, // sampler v_src_texture_coords // texture coordinates - ))); - src.a *= frag_info.src_input_alpha; - + )); int nblend_type = int(blend_type); if (nblend_type == /*BlendSelectValues::kPlus*/ 14) { - f16vec4 plus = src + dst; + f16vec4 plus = premultiplied_dst + premultiplied_src; if (plus.a > 1.0hf) { plus.a = 1.0hf; } - frag_color = IPHalfPremultiply(plus); + frag_color = plus; } else { + f16vec4 dst = IPHalfUnpremultiply(premultiplied_dst); + f16vec4 src = IPHalfUnpremultiply(premultiplied_src); + src.a *= frag_info.src_input_alpha; + f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, nblend_type); frag_color = IPApplyBlendedColor(dst, src, blend_result); } From d3e714e9a9dd7ae3ab0473163726a358af3d8d7e Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 25 Mar 2024 10:50:57 -0700 Subject: [PATCH 07/25] fixed ColorBlendReturnsExpectedResults test --- impeller/geometry/geometry_unittests.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/impeller/geometry/geometry_unittests.cc b/impeller/geometry/geometry_unittests.cc index aa1e5910b77eb..9b00776e37866 100644 --- a/impeller/geometry/geometry_unittests.cc +++ b/impeller/geometry/geometry_unittests.cc @@ -1470,7 +1470,6 @@ struct ColorBlendTestData { {0.848039, 0.896078, 0.982353, 0.75}, // SourceATop {0.544118, 0.688235, 0.947059, 0.75}, // DestinationATop {0.696078, 0.792157, 0.964706, 0.375}, // Xor - {1, 1, 1, 1}, // Plus {0.392157, 0.584314, 0.929412, 0.5625}, // Modulate {0.878431, 0.916863, 0.985882, 0.9375}, // Screen {0.74902, 0.916863, 0.985882, 0.9375}, // Overlay @@ -1486,6 +1485,7 @@ struct ColorBlendTestData { {0.617208, 0.655639, 0.724659, 0.9375}, // Hue {0.617208, 0.655639, 0.724659, 0.9375}, // Saturation {0.617208, 0.655639, 0.724659, 0.9375}, // Color + {1, 1, 1, 1}, // Plus {0.878431, 0.916863, 0.985882, 0.9375}, // Luminosity }, { @@ -1501,7 +1501,6 @@ struct ColorBlendTestData { {0.245098, 0.74902, 0.379412, 0.75}, // SourceATop {0.343137, 0.639216, 0.746078, 0.75}, // DestinationATop {0.294118, 0.694118, 0.562745, 0.375}, // Xor - {0.441176, 1, 0.844118, 1}, // Plus {0.0768935, 0.469742, 0.182238, 0.5625}, // Modulate {0.424452, 0.828743, 0.79105, 0.9375}, // Screen {0.209919, 0.779839, 0.757001, 0.9375}, // Overlay @@ -1517,6 +1516,7 @@ struct ColorBlendTestData { {0.266235, 0.748588, 0.373686, 0.9375}, // Hue {0.339345, 0.629787, 0.811502, 0.9375}, // Saturation {0.241247, 0.765953, 0.348698, 0.9375}, // Color + {0.441176, 1, 0.844118, 1}, // Plus {0.346988, 0.622282, 0.776792, 0.9375}, // Luminosity }, { @@ -1532,7 +1532,6 @@ struct ColorBlendTestData { {0.0980392, 0.146078, 0.232353, 0.75}, // SourceATop {0.294118, 0.438235, 0.697059, 0.75}, // DestinationATop {0.196078, 0.292157, 0.464706, 0.375}, // Xor - {0.294118, 0.438235, 0.697059, 1}, // Plus {0, 0, 0, 0.5625}, // Modulate {0.313726, 0.467451, 0.743529, 0.9375}, // Screen {0.0784314, 0.218039, 0.701176, 0.9375}, // Overlay @@ -1548,6 +1547,7 @@ struct ColorBlendTestData { {0.417208, 0.455639, 0.524659, 0.9375}, // Hue {0.417208, 0.455639, 0.524659, 0.9375}, // Saturation {0.417208, 0.455639, 0.524659, 0.9375}, // Color + {0.294118, 0.438235, 0.697059, 1}, // Plus {0.0784314, 0.116863, 0.185882, 0.9375}, // Luminosity }, }; From 85e93d77c9b2c3e48d835ece2bc37b4a2b1920c4 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 25 Mar 2024 11:22:09 -0700 Subject: [PATCH 08/25] refactored the geometry tests to not be dependent on order --- impeller/geometry/geometry_unittests.cc | 218 ++++++++++++------------ 1 file changed, 111 insertions(+), 107 deletions(-) diff --git a/impeller/geometry/geometry_unittests.cc b/impeller/geometry/geometry_unittests.cc index 9b00776e37866..941a6070140f1 100644 --- a/impeller/geometry/geometry_unittests.cc +++ b/impeller/geometry/geometry_unittests.cc @@ -6,6 +6,7 @@ #include "impeller/geometry/geometry_asserts.h" #include +#include #include #include @@ -1450,107 +1451,109 @@ struct ColorBlendTestData { Color::LimeGreen().WithAlpha(0.75), Color::Black().WithAlpha(0.75)}; - // THIS RESULT TABLE IS GENERATED! - // - // Uncomment the `GenerateColorBlendResults` test below to print a new table - // after making changes to `Color::Blend`. - static constexpr Color kExpectedResults - [sizeof(kSourceColors)] - [static_cast>(BlendMode::kLast) + 1] = { - { - {0, 0, 0, 0}, // Clear - {1, 1, 1, 0.75}, // Source - {0.392157, 0.584314, 0.929412, 0.75}, // Destination - {0.878431, 0.916863, 0.985882, 0.9375}, // SourceOver - {0.513726, 0.667451, 0.943529, 0.9375}, // DestinationOver - {1, 1, 1, 0.5625}, // SourceIn - {0.392157, 0.584314, 0.929412, 0.5625}, // DestinationIn - {1, 1, 1, 0.1875}, // SourceOut - {0.392157, 0.584314, 0.929412, 0.1875}, // DestinationOut - {0.848039, 0.896078, 0.982353, 0.75}, // SourceATop - {0.544118, 0.688235, 0.947059, 0.75}, // DestinationATop - {0.696078, 0.792157, 0.964706, 0.375}, // Xor - {0.392157, 0.584314, 0.929412, 0.5625}, // Modulate - {0.878431, 0.916863, 0.985882, 0.9375}, // Screen - {0.74902, 0.916863, 0.985882, 0.9375}, // Overlay - {0.513726, 0.667451, 0.943529, 0.9375}, // Darken - {0.878431, 0.916863, 0.985882, 0.9375}, // Lighten - {0.878431, 0.916863, 0.985882, 0.9375}, // ColorDodge - {0.513725, 0.667451, 0.943529, 0.9375}, // ColorBurn - {0.878431, 0.916863, 0.985882, 0.9375}, // HardLight - {0.654166, 0.775505, 0.964318, 0.9375}, // SoftLight - {0.643137, 0.566275, 0.428235, 0.9375}, // Difference - {0.643137, 0.566275, 0.428235, 0.9375}, // Exclusion - {0.513726, 0.667451, 0.943529, 0.9375}, // Multiply - {0.617208, 0.655639, 0.724659, 0.9375}, // Hue - {0.617208, 0.655639, 0.724659, 0.9375}, // Saturation - {0.617208, 0.655639, 0.724659, 0.9375}, // Color - {1, 1, 1, 1}, // Plus - {0.878431, 0.916863, 0.985882, 0.9375}, // Luminosity - }, - { - {0, 0, 0, 0}, // Clear - {0.196078, 0.803922, 0.196078, 0.75}, // Source - {0.392157, 0.584314, 0.929412, 0.75}, // Destination - {0.235294, 0.76, 0.342745, 0.9375}, // SourceOver - {0.352941, 0.628235, 0.782745, 0.9375}, // DestinationOver - {0.196078, 0.803922, 0.196078, 0.5625}, // SourceIn - {0.392157, 0.584314, 0.929412, 0.5625}, // DestinationIn - {0.196078, 0.803922, 0.196078, 0.1875}, // SourceOut - {0.392157, 0.584314, 0.929412, 0.1875}, // DestinationOut - {0.245098, 0.74902, 0.379412, 0.75}, // SourceATop - {0.343137, 0.639216, 0.746078, 0.75}, // DestinationATop - {0.294118, 0.694118, 0.562745, 0.375}, // Xor - {0.0768935, 0.469742, 0.182238, 0.5625}, // Modulate - {0.424452, 0.828743, 0.79105, 0.9375}, // Screen - {0.209919, 0.779839, 0.757001, 0.9375}, // Overlay - {0.235294, 0.628235, 0.342745, 0.9375}, // Darken - {0.352941, 0.76, 0.782745, 0.9375}, // Lighten - {0.41033, 0.877647, 0.825098, 0.9375}, // ColorDodge - {0.117647, 0.567403, 0.609098, 0.9375}, // ColorBurn - {0.209919, 0.779839, 0.443783, 0.9375}, // HardLight - {0.266006, 0.693915, 0.758818, 0.9375}, // SoftLight - {0.235294, 0.409412, 0.665098, 0.9375}, // Difference - {0.378316, 0.546897, 0.681707, 0.9375}, // Exclusion - {0.163783, 0.559493, 0.334441, 0.9375}, // Multiply - {0.266235, 0.748588, 0.373686, 0.9375}, // Hue - {0.339345, 0.629787, 0.811502, 0.9375}, // Saturation - {0.241247, 0.765953, 0.348698, 0.9375}, // Color - {0.441176, 1, 0.844118, 1}, // Plus - {0.346988, 0.622282, 0.776792, 0.9375}, // Luminosity - }, - { - {0, 0, 0, 0}, // Clear - {0, 0, 0, 0.75}, // Source - {0.392157, 0.584314, 0.929412, 0.75}, // Destination - {0.0784314, 0.116863, 0.185882, 0.9375}, // SourceOver - {0.313726, 0.467451, 0.743529, 0.9375}, // DestinationOver - {0, 0, 0, 0.5625}, // SourceIn - {0.392157, 0.584314, 0.929412, 0.5625}, // DestinationIn - {0, 0, 0, 0.1875}, // SourceOut - {0.392157, 0.584314, 0.929412, 0.1875}, // DestinationOut - {0.0980392, 0.146078, 0.232353, 0.75}, // SourceATop - {0.294118, 0.438235, 0.697059, 0.75}, // DestinationATop - {0.196078, 0.292157, 0.464706, 0.375}, // Xor - {0, 0, 0, 0.5625}, // Modulate - {0.313726, 0.467451, 0.743529, 0.9375}, // Screen - {0.0784314, 0.218039, 0.701176, 0.9375}, // Overlay - {0.0784314, 0.116863, 0.185882, 0.9375}, // Darken - {0.313726, 0.467451, 0.743529, 0.9375}, // Lighten - {0.313726, 0.467451, 0.743529, 0.9375}, // ColorDodge - {0.0784314, 0.116863, 0.185882, 0.9375}, // ColorBurn - {0.0784314, 0.116863, 0.185882, 0.9375}, // HardLight - {0.170704, 0.321716, 0.704166, 0.9375}, // SoftLight - {0.313726, 0.467451, 0.743529, 0.9375}, // Difference - {0.313726, 0.467451, 0.743529, 0.9375}, // Exclusion - {0.0784314, 0.116863, 0.185882, 0.9375}, // Multiply - {0.417208, 0.455639, 0.524659, 0.9375}, // Hue - {0.417208, 0.455639, 0.524659, 0.9375}, // Saturation - {0.417208, 0.455639, 0.524659, 0.9375}, // Color - {0.294118, 0.438235, 0.697059, 1}, // Plus - {0.0784314, 0.116863, 0.185882, 0.9375}, // Luminosity - }, - }; + static const std::map + kExpectedResults[sizeof(kSourceColors)]; +}; + +// THIS RESULT TABLE IS GENERATED! +// +// Uncomment the `GenerateColorBlendResults` test below to print a new table +// after making changes to `Color::Blend`. +const std::map ColorBlendTestData::kExpectedResults[sizeof( + ColorBlendTestData::kSourceColors)] = { + { + {BlendMode::kClear, {0, 0, 0, 0}}, + {BlendMode::kSource, {1, 1, 1, 0.75}}, + {BlendMode::kDestination, {0.392157, 0.584314, 0.929412, 0.75}}, + {BlendMode::kSourceOver, {0.878431, 0.916863, 0.985882, 0.9375}}, + {BlendMode::kDestinationOver, {0.513726, 0.667451, 0.943529, 0.9375}}, + {BlendMode::kSourceIn, {1, 1, 1, 0.5625}}, + {BlendMode::kDestinationIn, {0.392157, 0.584314, 0.929412, 0.5625}}, + {BlendMode::kSourceOut, {1, 1, 1, 0.1875}}, + {BlendMode::kDestinationOut, {0.392157, 0.584314, 0.929412, 0.1875}}, + {BlendMode::kSourceATop, {0.848039, 0.896078, 0.982353, 0.75}}, + {BlendMode::kDestinationATop, {0.544118, 0.688235, 0.947059, 0.75}}, + {BlendMode::kXor, {0.696078, 0.792157, 0.964706, 0.375}}, + {BlendMode::kModulate, {0.392157, 0.584314, 0.929412, 0.5625}}, + {BlendMode::kScreen, {0.878431, 0.916863, 0.985882, 0.9375}}, + {BlendMode::kOverlay, {0.74902, 0.916863, 0.985882, 0.9375}}, + {BlendMode::kDarken, {0.513726, 0.667451, 0.943529, 0.9375}}, + {BlendMode::kLighten, {0.878431, 0.916863, 0.985882, 0.9375}}, + {BlendMode::kColorDodge, {0.878431, 0.916863, 0.985882, 0.9375}}, + {BlendMode::kColorBurn, {0.513725, 0.667451, 0.943529, 0.9375}}, + {BlendMode::kHardLight, {0.878431, 0.916863, 0.985882, 0.9375}}, + {BlendMode::kSoftLight, {0.654166, 0.775505, 0.964318, 0.9375}}, + {BlendMode::kDifference, {0.643137, 0.566275, 0.428235, 0.9375}}, + {BlendMode::kExclusion, {0.643137, 0.566275, 0.428235, 0.9375}}, + {BlendMode::kMultiply, {0.513726, 0.667451, 0.943529, 0.9375}}, + {BlendMode::kHue, {0.617208, 0.655639, 0.724659, 0.9375}}, + {BlendMode::kSaturation, {0.617208, 0.655639, 0.724659, 0.9375}}, + {BlendMode::kColor, {0.617208, 0.655639, 0.724659, 0.9375}}, + {BlendMode::kPlus, {1, 1, 1, 1}}, + {BlendMode::kLuminosity, {0.878431, 0.916863, 0.985882, 0.9375}}, + }, + { + {BlendMode::kClear, {0, 0, 0, 0}}, + {BlendMode::kSource, {0.196078, 0.803922, 0.196078, 0.75}}, + {BlendMode::kDestination, {0.392157, 0.584314, 0.929412, 0.75}}, + {BlendMode::kSourceOver, {0.235294, 0.76, 0.342745, 0.9375}}, + {BlendMode::kDestinationOver, {0.352941, 0.628235, 0.782745, 0.9375}}, + {BlendMode::kSourceIn, {0.196078, 0.803922, 0.196078, 0.5625}}, + {BlendMode::kDestinationIn, {0.392157, 0.584314, 0.929412, 0.5625}}, + {BlendMode::kSourceOut, {0.196078, 0.803922, 0.196078, 0.1875}}, + {BlendMode::kDestinationOut, {0.392157, 0.584314, 0.929412, 0.1875}}, + {BlendMode::kSourceATop, {0.245098, 0.74902, 0.379412, 0.75}}, + {BlendMode::kDestinationATop, {0.343137, 0.639216, 0.746078, 0.75}}, + {BlendMode::kXor, {0.294118, 0.694118, 0.562745, 0.375}}, + {BlendMode::kModulate, {0.0768935, 0.469742, 0.182238, 0.5625}}, + {BlendMode::kScreen, {0.424452, 0.828743, 0.79105, 0.9375}}, + {BlendMode::kOverlay, {0.209919, 0.779839, 0.757001, 0.9375}}, + {BlendMode::kDarken, {0.235294, 0.628235, 0.342745, 0.9375}}, + {BlendMode::kLighten, {0.352941, 0.76, 0.782745, 0.9375}}, + {BlendMode::kColorDodge, {0.41033, 0.877647, 0.825098, 0.9375}}, + {BlendMode::kColorBurn, {0.117647, 0.567403, 0.609098, 0.9375}}, + {BlendMode::kHardLight, {0.209919, 0.779839, 0.443783, 0.9375}}, + {BlendMode::kSoftLight, {0.266006, 0.693915, 0.758818, 0.9375}}, + {BlendMode::kDifference, {0.235294, 0.409412, 0.665098, 0.9375}}, + {BlendMode::kExclusion, {0.378316, 0.546897, 0.681707, 0.9375}}, + {BlendMode::kMultiply, {0.163783, 0.559493, 0.334441, 0.9375}}, + {BlendMode::kHue, {0.266235, 0.748588, 0.373686, 0.9375}}, + {BlendMode::kSaturation, {0.339345, 0.629787, 0.811502, 0.9375}}, + {BlendMode::kColor, {0.241247, 0.765953, 0.348698, 0.9375}}, + {BlendMode::kPlus, {0.441176, 1, 0.844118, 1}}, + {BlendMode::kLuminosity, {0.346988, 0.622282, 0.776792, 0.9375}}, + }, + { + {BlendMode::kClear, {0, 0, 0, 0}}, + {BlendMode::kSource, {0, 0, 0, 0.75}}, + {BlendMode::kDestination, {0.392157, 0.584314, 0.929412, 0.75}}, + {BlendMode::kSourceOver, {0.0784314, 0.116863, 0.185882, 0.9375}}, + {BlendMode::kDestinationOver, {0.313726, 0.467451, 0.743529, 0.9375}}, + {BlendMode::kSourceIn, {0, 0, 0, 0.5625}}, + {BlendMode::kDestinationIn, {0.392157, 0.584314, 0.929412, 0.5625}}, + {BlendMode::kSourceOut, {0, 0, 0, 0.1875}}, + {BlendMode::kDestinationOut, {0.392157, 0.584314, 0.929412, 0.1875}}, + {BlendMode::kSourceATop, {0.0980392, 0.146078, 0.232353, 0.75}}, + {BlendMode::kDestinationATop, {0.294118, 0.438235, 0.697059, 0.75}}, + {BlendMode::kXor, {0.196078, 0.292157, 0.464706, 0.375}}, + {BlendMode::kModulate, {0, 0, 0, 0.5625}}, + {BlendMode::kScreen, {0.313726, 0.467451, 0.743529, 0.9375}}, + {BlendMode::kOverlay, {0.0784314, 0.218039, 0.701176, 0.9375}}, + {BlendMode::kDarken, {0.0784314, 0.116863, 0.185882, 0.9375}}, + {BlendMode::kLighten, {0.313726, 0.467451, 0.743529, 0.9375}}, + {BlendMode::kColorDodge, {0.313726, 0.467451, 0.743529, 0.9375}}, + {BlendMode::kColorBurn, {0.0784314, 0.116863, 0.185882, 0.9375}}, + {BlendMode::kHardLight, {0.0784314, 0.116863, 0.185882, 0.9375}}, + {BlendMode::kSoftLight, {0.170704, 0.321716, 0.704166, 0.9375}}, + {BlendMode::kDifference, {0.313726, 0.467451, 0.743529, 0.9375}}, + {BlendMode::kExclusion, {0.313726, 0.467451, 0.743529, 0.9375}}, + {BlendMode::kMultiply, {0.0784314, 0.116863, 0.185882, 0.9375}}, + {BlendMode::kHue, {0.417208, 0.455639, 0.524659, 0.9375}}, + {BlendMode::kSaturation, {0.417208, 0.455639, 0.524659, 0.9375}}, + {BlendMode::kColor, {0.417208, 0.455639, 0.524659, 0.9375}}, + {BlendMode::kPlus, {0.294118, 0.438235, 0.697059, 1}}, + {BlendMode::kLuminosity, {0.0784314, 0.116863, 0.185882, 0.9375}}, + }, }; /// To print a new ColorBlendTestData::kExpectedResults table, uncomment this @@ -1567,8 +1570,10 @@ TEST(GeometryTest, GenerateColorBlendResults) { blend_i < static_cast(BlendMode::kLast) + 1; blend_i++) { auto blend = static_cast(blend_i); Color c = ColorBlendTestData::kDestinationColor.Blend(source, blend); + o << "{ BlendMode::k" << BlendModeToString(blend) << ", "; o << "{" << c.red << "," << c.green << "," << c.blue << "," << c.alpha - << "}, // " << BlendModeToString(blend) << std::endl; + << "}"; + o << "}," << std::endl; } o << "},"; } @@ -1576,20 +1581,19 @@ TEST(GeometryTest, GenerateColorBlendResults) { } */ -#define _BLEND_MODE_RESULT_CHECK(blend_mode) \ - blend_i = static_cast(BlendMode::k##blend_mode); \ - expected = ColorBlendTestData::kExpectedResults[source_i][blend_i]; \ +#define _BLEND_MODE_RESULT_CHECK(blend_mode) \ + expected = ColorBlendTestData::kExpectedResults[source_i] \ + .find(BlendMode::k##blend_mode) \ + ->second; \ EXPECT_COLOR_NEAR(dst.Blend(src, BlendMode::k##blend_mode), expected); TEST(GeometryTest, ColorBlendReturnsExpectedResults) { - using BlendT = std::underlying_type_t; Color dst = ColorBlendTestData::kDestinationColor; for (size_t source_i = 0; source_i < sizeof(ColorBlendTestData::kSourceColors) / sizeof(Color); source_i++) { Color src = ColorBlendTestData::kSourceColors[source_i]; - size_t blend_i; Color expected; IMPELLER_FOR_EACH_BLEND_MODE(_BLEND_MODE_RESULT_CHECK) } From dacb1e4d74623fea5105bf73332da6dfad6d4e36 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 25 Mar 2024 11:38:11 -0700 Subject: [PATCH 09/25] removed single plus test, renamed the overlapping one --- impeller/aiks/aiks_unittests.cc | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 2f0f10d1e4d70..c0c45f239575f 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -1123,24 +1123,7 @@ TEST_P(AiksTest, BlendModePlusAlpha) { } // Bug: https://github.com/flutter/flutter/issues/142549 -TEST_P(AiksTest, BlendModePlusAlphaHalf) { - Canvas canvas; - canvas.Scale(GetContentScale()); - canvas.DrawPaint({.color = Color(0.9, 1.0, 0.9, 1.0)}); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300), - {.color = Color(1, 0, 0, 0.5)}); - canvas.SaveLayer({}); - Paint paint; - paint.blend_mode = BlendMode::kPlus; - paint.color = Color(0, 0, 1, 0.5); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 150, 300), paint); - paint.color = Color(1, 0, 1, 1); - canvas.DrawRect(Rect::MakeXYWH(150, 0, 150, 300), paint); - canvas.Restore(); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, BlendModePlusAlphaFoo) { +TEST_P(AiksTest, BlendModePlusAlphaOverlapping) { Canvas canvas; canvas.Scale(GetContentScale()); canvas.DrawPaint({.color = Color(0.9, 1.0, 0.9, 1.0)}); From 418c811232ec29b051c17bb41ddae8a671b9532f Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 25 Mar 2024 14:39:32 -0700 Subject: [PATCH 10/25] fixed Play/AiksTest.PaintBlendModeIsRespected/OpenGLES --- impeller/entity/contents/filters/blend_filter_contents.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/impeller/entity/contents/filters/blend_filter_contents.cc b/impeller/entity/contents/filters/blend_filter_contents.cc index 7fc97b87b6e39..a99de51a43348 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/impeller/entity/contents/filters/blend_filter_contents.cc @@ -586,6 +586,7 @@ void BlendFilterContents::SetBlendMode(BlendMode blend_mode) { BLEND_CASE(Hue) BLEND_CASE(Saturation) BLEND_CASE(Color) + BLEND_CASE(Plus) BLEND_CASE(Luminosity) default: FML_UNREACHABLE(); From c3aa8cc2c4d6b5ce63ab22ebf5113e15884c659e Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Tue, 26 Mar 2024 15:00:16 -0700 Subject: [PATCH 11/25] moved the test to the new magic name, removed the blending test --- impeller/aiks/aiks_unittests.cc | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index c0c45f239575f..43accfb20a2b1 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -1102,7 +1102,7 @@ TEST_P(AiksTest, PaintBlendModeIsRespected) { } // Bug: https://github.com/flutter/flutter/issues/142549 -TEST_P(AiksTest, BlendModePlusAlpha) { +TEST_P(AiksTest, BlendModePlusAlphaWideGamut) { auto texture = CreateTextureForFixture("airplane.jpg", /*enable_mipmapping=*/true); @@ -1122,25 +1122,6 @@ TEST_P(AiksTest, BlendModePlusAlpha) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } -// Bug: https://github.com/flutter/flutter/issues/142549 -TEST_P(AiksTest, BlendModePlusAlphaOverlapping) { - Canvas canvas; - canvas.Scale(GetContentScale()); - canvas.DrawPaint({.color = Color(0.9, 1.0, 0.9, 1.0)}); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300), {.color = Color(1, 0, 0, 1)}); - canvas.SaveLayer({}); - Paint paint; - paint.blend_mode = BlendMode::kPlus; - paint.color = Color(0, 0, 1, 10.0 / 255.0); - for (int i = 0; i < 20; ++i) { - canvas.DrawRect(Rect::MakeXYWH(0, 0, 150, 300), paint); - } - paint.color = Color(0, 0, 1, 200.0 / 255.0); - canvas.DrawRect(Rect::MakeXYWH(150, 0, 150, 300), paint); - canvas.Restore(); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - TEST_P(AiksTest, ColorWheel) { // Compare with https://fiddle.skia.org/c/@BlendModes From 5b5e6caf46cb8ea80ceb8d2480302207ee22e99c Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Tue, 26 Mar 2024 15:10:11 -0700 Subject: [PATCH 12/25] gave golden image tests the magic name feature --- impeller/golden_tests/golden_playground_test_mac.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/impeller/golden_tests/golden_playground_test_mac.cc b/impeller/golden_tests/golden_playground_test_mac.cc index 51d751d056cd1..833a62bfbf0a1 100644 --- a/impeller/golden_tests/golden_playground_test_mac.cc +++ b/impeller/golden_tests/golden_playground_test_mac.cc @@ -138,10 +138,12 @@ void GoldenPlaygroundTest::SetUp() { std::filesystem::path icd_path = target_path / "vk_swiftshader_icd.json"; setenv("VK_ICD_FILENAMES", icd_path.c_str(), 1); + std::string test_name = GetTestName(); + bool enable_wide_gamut = test_name.find("WideGamut_") != std::string::npos; switch (GetParam()) { case PlaygroundBackend::kMetal: - pimpl_->screenshotter = std::make_unique( - /*enable_wide_gamut=*/false); + pimpl_->screenshotter = + std::make_unique(enable_wide_gamut); break; case PlaygroundBackend::kVulkan: { const std::unique_ptr& playground = @@ -162,7 +164,6 @@ void GoldenPlaygroundTest::SetUp() { } } - std::string test_name = GetTestName(); if (std::find(kSkipTests.begin(), kSkipTests.end(), test_name) != kSkipTests.end()) { GTEST_SKIP_( From 7953bd79d4193ff22caaabaab175cd28b0b83fb2 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Tue, 26 Mar 2024 15:33:12 -0700 Subject: [PATCH 13/25] resurrected the old blend --- impeller/entity/contents/content_context.cc | 13 +++++++++++-- impeller/entity/contents/content_context.h | 14 +++++++------- .../contents/filters/blend_filter_contents.cc | 6 +++--- .../contents/filters/blend_filter_contents.h | 3 ++- .../entity/contents/framebuffer_blend_contents.cc | 5 +++-- .../entity/contents/framebuffer_blend_contents.h | 2 +- .../entity/shaders/blending/advanced_blend.frag | 2 +- impeller/entity/shaders/blending/blend_select.glsl | 2 +- .../entity/shaders/blending/framebuffer_blend.frag | 2 +- impeller/geometry/color.cc | 2 ++ impeller/geometry/color.h | 6 ++++-- impeller/geometry/geometry_unittests.cc | 9 ++++++--- 12 files changed, 42 insertions(+), 24 deletions(-) diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 1e0d13751348f..79822bf439921 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -134,6 +134,14 @@ void ContentContextOptions::ApplyToPipelineDescriptor( color0.src_alpha_blend_factor = BlendFactor::kZero; color0.src_color_blend_factor = BlendFactor::kZero; break; + case BlendMode::kPlus: + // The kPlusAdvanced should be used instead. + FML_DCHECK(IsAlphaClampedToOne(color_attachment_pixel_format)); + color0.dst_alpha_blend_factor = BlendFactor::kOne; + color0.dst_color_blend_factor = BlendFactor::kOne; + color0.src_alpha_blend_factor = BlendFactor::kOne; + color0.src_color_blend_factor = BlendFactor::kOne; + break; default: FML_UNREACHABLE(); } @@ -325,7 +333,8 @@ ContentContext::ContentContext( {static_cast(BlendSelectValues::kLighten), supports_decal}); framebuffer_blend_plus_pipelines_.CreateDefault( *context_, options_trianglestrip, - {static_cast(BlendSelectValues::kPlus), supports_decal}); + {static_cast(BlendSelectValues::kPlusAdvanced), + supports_decal}); framebuffer_blend_luminosity_pipelines_.CreateDefault( *context_, options_trianglestrip, {static_cast(BlendSelectValues::kLuminosity), supports_decal}); @@ -375,7 +384,7 @@ ContentContext::ContentContext( {static_cast(BlendSelectValues::kLighten), supports_decal}); blend_plus_pipelines_.CreateDefault( *context_, options_trianglestrip, - {static_cast(BlendSelectValues::kPlus), supports_decal}); + {static_cast(BlendSelectValues::kPlusAdvanced), supports_decal}); blend_luminosity_pipelines_.CreateDefault( *context_, options_trianglestrip, {static_cast(BlendSelectValues::kLuminosity), supports_decal}); diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 74f0039a79ef6..7b624548c8fdd 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -197,7 +197,7 @@ using BlendHuePipeline = RenderPipelineT; using BlendLightenPipeline = RenderPipelineT; -using BlendPlusPipeline = +using BlendPlusAdvancedPipeline = RenderPipelineT; using BlendLuminosityPipeline = RenderPipelineT; @@ -239,7 +239,7 @@ using FramebufferBlendHuePipeline = using FramebufferBlendLightenPipeline = RenderPipelineT; -using FramebufferBlendPlusPipeline = +using FramebufferBlendPlusAdvancedPipeline = RenderPipelineT; using FramebufferBlendLuminosityPipeline = @@ -645,7 +645,7 @@ class ContentContext { return GetPipeline(blend_lighten_pipelines_, opts); } - std::shared_ptr> GetBlendPlusPipeline( + std::shared_ptr> GetBlendPlusAdvancedPipeline( ContentContextOptions opts) const { return GetPipeline(blend_plus_pipelines_, opts); } @@ -735,8 +735,8 @@ class ContentContext { return GetPipeline(framebuffer_blend_lighten_pipelines_, opts); } - std::shared_ptr> GetFramebufferBlendPlusPipeline( - ContentContextOptions opts) const { + std::shared_ptr> + GetFramebufferBlendPlusAdvancedPipeline(ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_plus_pipelines_, opts); } @@ -1005,7 +1005,7 @@ class ContentContext { mutable Variants blend_hardlight_pipelines_; mutable Variants blend_hue_pipelines_; mutable Variants blend_lighten_pipelines_; - mutable Variants blend_plus_pipelines_; + mutable Variants blend_plus_pipelines_; mutable Variants blend_luminosity_pipelines_; mutable Variants blend_multiply_pipelines_; mutable Variants blend_overlay_pipelines_; @@ -1031,7 +1031,7 @@ class ContentContext { framebuffer_blend_hue_pipelines_; mutable Variants framebuffer_blend_lighten_pipelines_; - mutable Variants + mutable Variants framebuffer_blend_plus_pipelines_; mutable Variants framebuffer_blend_luminosity_pipelines_; diff --git a/impeller/entity/contents/filters/blend_filter_contents.cc b/impeller/entity/contents/filters/blend_filter_contents.cc index a99de51a43348..21c15e93a66de 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/impeller/entity/contents/filters/blend_filter_contents.cc @@ -338,8 +338,8 @@ std::optional BlendFilterContents::CreateForegroundAdvancedBlend( case BlendMode::kColor: pass.SetPipeline(renderer.GetBlendColorPipeline(options)); break; - case BlendMode::kPlus: - pass.SetPipeline(renderer.GetBlendPlusPipeline(options)); + case BlendMode::kPlusAdvanced: + pass.SetPipeline(renderer.GetBlendPlusAdvancedPipeline(options)); break; case BlendMode::kLuminosity: pass.SetPipeline(renderer.GetBlendLuminosityPipeline(options)); @@ -586,7 +586,7 @@ void BlendFilterContents::SetBlendMode(BlendMode blend_mode) { BLEND_CASE(Hue) BLEND_CASE(Saturation) BLEND_CASE(Color) - BLEND_CASE(Plus) + BLEND_CASE(PlusAdvanced) BLEND_CASE(Luminosity) default: FML_UNREACHABLE(); diff --git a/impeller/entity/contents/filters/blend_filter_contents.h b/impeller/entity/contents/filters/blend_filter_contents.h index 645056a915e30..75f575f5b2aaf 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.h +++ b/impeller/entity/contents/filters/blend_filter_contents.h @@ -12,7 +12,7 @@ namespace impeller { -constexpr std::array, 14> kPorterDuffCoefficients = {{ +constexpr std::array, 15> kPorterDuffCoefficients = {{ {0, 0, 0, 0, 0}, // Clear {1, 0, 0, 0, 0}, // Source {0, 0, 1, 0, 0}, // Destination @@ -25,6 +25,7 @@ constexpr std::array, 14> kPorterDuffCoefficients = {{ {0, 1, 1, -1, 0}, // SourceATop {1, -1, 0, 1, 0}, // DestinationATop {1, -1, 1, -1, 0}, // Xor + {1, 0, 1, 0, 0}, // Plus {0, 0, 0, 0, 1}, // Modulate {0, 0, 1, 0, -1}, // Screen }}; diff --git a/impeller/entity/contents/framebuffer_blend_contents.cc b/impeller/entity/contents/framebuffer_blend_contents.cc index 0854167ebb2bf..cee9b5a904e4c 100644 --- a/impeller/entity/contents/framebuffer_blend_contents.cc +++ b/impeller/entity/contents/framebuffer_blend_contents.cc @@ -118,8 +118,9 @@ bool FramebufferBlendContents::Render(const ContentContext& renderer, case BlendMode::kColor: pass.SetPipeline(renderer.GetFramebufferBlendColorPipeline(options)); break; - case BlendMode::kPlus: - pass.SetPipeline(renderer.GetFramebufferBlendPlusPipeline(options)); + case BlendMode::kPlusAdvanced: + pass.SetPipeline( + renderer.GetFramebufferBlendPlusAdvancedPipeline(options)); break; case BlendMode::kLuminosity: pass.SetPipeline(renderer.GetFramebufferBlendLuminosityPipeline(options)); diff --git a/impeller/entity/contents/framebuffer_blend_contents.h b/impeller/entity/contents/framebuffer_blend_contents.h index fd3a70e52f3ea..c8deee6450b25 100644 --- a/impeller/entity/contents/framebuffer_blend_contents.h +++ b/impeller/entity/contents/framebuffer_blend_contents.h @@ -27,7 +27,7 @@ enum class BlendSelectValues { kHue, kSaturation, kColor, - kPlus, + kPlusAdvanced, kLuminosity, }; diff --git a/impeller/entity/shaders/blending/advanced_blend.frag b/impeller/entity/shaders/blending/advanced_blend.frag index 1d8202c957927..75e5e24198f95 100644 --- a/impeller/entity/shaders/blending/advanced_blend.frag +++ b/impeller/entity/shaders/blending/advanced_blend.frag @@ -42,7 +42,7 @@ void main() { ); int nblend_type = int(blend_type); - if (nblend_type == /*BlendSelectValues::kPlus*/ 14) { + if (nblend_type == /*BlendSelectValues::kPlusAdvanced*/ 14) { f16vec4 premultiplied_src = Sample(texture_sampler_src, // sampler v_src_texture_coords // texture coordinates diff --git a/impeller/entity/shaders/blending/blend_select.glsl b/impeller/entity/shaders/blending/blend_select.glsl index c0b90acc77416..3b81ae4b0d984 100644 --- a/impeller/entity/shaders/blending/blend_select.glsl +++ b/impeller/entity/shaders/blending/blend_select.glsl @@ -20,7 +20,7 @@ // kHue, // kSaturation, // kColor, -// kPlus, +// kPlusAdvanced, // kLuminosity, // Note, this isn't a switch as GLSL ES 1.0 does not support them. f16vec3 AdvancedBlend(f16vec3 dst, f16vec3 src, int blend_type) { diff --git a/impeller/entity/shaders/blending/framebuffer_blend.frag b/impeller/entity/shaders/blending/framebuffer_blend.frag index b4beba329c3c6..7f0aa6e8e66de 100644 --- a/impeller/entity/shaders/blending/framebuffer_blend.frag +++ b/impeller/entity/shaders/blending/framebuffer_blend.frag @@ -50,7 +50,7 @@ void main() { )); int nblend_type = int(blend_type); - if (nblend_type == /*BlendSelectValues::kPlus*/ 14) { + if (nblend_type == /*BlendSelectValues::kPlusAdvanced*/ 14) { f16vec4 plus = premultiplied_dst + premultiplied_src; if (plus.a > 1.0hf) { plus.a = 1.0hf; diff --git a/impeller/geometry/color.cc b/impeller/geometry/color.cc index d2565e6e6fd1d..a8c70e1862359 100644 --- a/impeller/geometry/color.cc +++ b/impeller/geometry/color.cc @@ -276,6 +276,8 @@ Color Color::Blend(Color src, BlendMode blend_mode) const { return (src.Premultiply() * (1 - dst.alpha) + dst.Premultiply() * (1 - src.alpha)) .Unpremultiply(); + case BlendMode::kPlusAdvanced: + [[fallthrough]]; case BlendMode::kPlus: // r = min(s + d, 1) return (Min(src.Premultiply() + dst.Premultiply(), 1)).Unpremultiply(); diff --git a/impeller/geometry/color.h b/impeller/geometry/color.h index f1c07c7beb0f8..59805e952ec02 100644 --- a/impeller/geometry/color.h +++ b/impeller/geometry/color.h @@ -29,6 +29,7 @@ V(SourceATop) \ V(DestinationATop) \ V(Xor) \ + V(Plus) \ V(Modulate) \ V(Screen) \ V(Overlay) \ @@ -44,7 +45,7 @@ V(Hue) \ V(Saturation) \ V(Color) \ - V(Plus) \ + V(PlusAdvanced) \ V(Luminosity) namespace impeller { @@ -71,6 +72,7 @@ enum class BlendMode : uint8_t { kSourceATop, kDestinationATop, kXor, + kPlus, kModulate, // The following blend modes use equations that are not available for @@ -90,7 +92,7 @@ enum class BlendMode : uint8_t { kHue, kSaturation, kColor, - kPlus, + kPlusAdvanced, kLuminosity, kLast = kLuminosity, diff --git a/impeller/geometry/geometry_unittests.cc b/impeller/geometry/geometry_unittests.cc index 941a6070140f1..af9a2a1cfe9df 100644 --- a/impeller/geometry/geometry_unittests.cc +++ b/impeller/geometry/geometry_unittests.cc @@ -1474,6 +1474,7 @@ const std::map ColorBlendTestData::kExpectedResults[sizeof( {BlendMode::kSourceATop, {0.848039, 0.896078, 0.982353, 0.75}}, {BlendMode::kDestinationATop, {0.544118, 0.688235, 0.947059, 0.75}}, {BlendMode::kXor, {0.696078, 0.792157, 0.964706, 0.375}}, + {BlendMode::kPlus, {1, 1, 1, 1}}, {BlendMode::kModulate, {0.392157, 0.584314, 0.929412, 0.5625}}, {BlendMode::kScreen, {0.878431, 0.916863, 0.985882, 0.9375}}, {BlendMode::kOverlay, {0.74902, 0.916863, 0.985882, 0.9375}}, @@ -1489,7 +1490,7 @@ const std::map ColorBlendTestData::kExpectedResults[sizeof( {BlendMode::kHue, {0.617208, 0.655639, 0.724659, 0.9375}}, {BlendMode::kSaturation, {0.617208, 0.655639, 0.724659, 0.9375}}, {BlendMode::kColor, {0.617208, 0.655639, 0.724659, 0.9375}}, - {BlendMode::kPlus, {1, 1, 1, 1}}, + {BlendMode::kPlusAdvanced, {1, 1, 1, 1}}, {BlendMode::kLuminosity, {0.878431, 0.916863, 0.985882, 0.9375}}, }, { @@ -1505,6 +1506,7 @@ const std::map ColorBlendTestData::kExpectedResults[sizeof( {BlendMode::kSourceATop, {0.245098, 0.74902, 0.379412, 0.75}}, {BlendMode::kDestinationATop, {0.343137, 0.639216, 0.746078, 0.75}}, {BlendMode::kXor, {0.294118, 0.694118, 0.562745, 0.375}}, + {BlendMode::kPlus, {0.441176, 1, 0.844118, 1}}, {BlendMode::kModulate, {0.0768935, 0.469742, 0.182238, 0.5625}}, {BlendMode::kScreen, {0.424452, 0.828743, 0.79105, 0.9375}}, {BlendMode::kOverlay, {0.209919, 0.779839, 0.757001, 0.9375}}, @@ -1520,7 +1522,7 @@ const std::map ColorBlendTestData::kExpectedResults[sizeof( {BlendMode::kHue, {0.266235, 0.748588, 0.373686, 0.9375}}, {BlendMode::kSaturation, {0.339345, 0.629787, 0.811502, 0.9375}}, {BlendMode::kColor, {0.241247, 0.765953, 0.348698, 0.9375}}, - {BlendMode::kPlus, {0.441176, 1, 0.844118, 1}}, + {BlendMode::kPlusAdvanced, {0.441176, 1, 0.844118, 1}}, {BlendMode::kLuminosity, {0.346988, 0.622282, 0.776792, 0.9375}}, }, { @@ -1536,6 +1538,7 @@ const std::map ColorBlendTestData::kExpectedResults[sizeof( {BlendMode::kSourceATop, {0.0980392, 0.146078, 0.232353, 0.75}}, {BlendMode::kDestinationATop, {0.294118, 0.438235, 0.697059, 0.75}}, {BlendMode::kXor, {0.196078, 0.292157, 0.464706, 0.375}}, + {BlendMode::kPlus, {0.294118, 0.438235, 0.697059, 1}}, {BlendMode::kModulate, {0, 0, 0, 0.5625}}, {BlendMode::kScreen, {0.313726, 0.467451, 0.743529, 0.9375}}, {BlendMode::kOverlay, {0.0784314, 0.218039, 0.701176, 0.9375}}, @@ -1551,7 +1554,7 @@ const std::map ColorBlendTestData::kExpectedResults[sizeof( {BlendMode::kHue, {0.417208, 0.455639, 0.524659, 0.9375}}, {BlendMode::kSaturation, {0.417208, 0.455639, 0.524659, 0.9375}}, {BlendMode::kColor, {0.417208, 0.455639, 0.524659, 0.9375}}, - {BlendMode::kPlus, {0.294118, 0.438235, 0.697059, 1}}, + {BlendMode::kPlusAdvanced, {0.294118, 0.438235, 0.697059, 1}}, {BlendMode::kLuminosity, {0.0784314, 0.116863, 0.185882, 0.9375}}, }, }; From eb038108da644b73fc8993c0e7143c027a7ba90a Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Tue, 26 Mar 2024 15:53:02 -0700 Subject: [PATCH 14/25] added switch for the advancedblend --- impeller/entity/entity_pass.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc index c128dd06e9747..a7946882ab323 100644 --- a/impeller/entity/entity_pass.cc +++ b/impeller/entity/entity_pass.cc @@ -841,6 +841,13 @@ bool EntityPass::RenderElement(Entity& element_entity, return true; } +namespace { +bool IsAlphaClampedToOne(PixelFormat pixel_format) { + return !(pixel_format == PixelFormat::kR32G32B32A32Float || + pixel_format == PixelFormat::kR16G16B16A16Float); +} +} // namespace + bool EntityPass::OnRender( ContentContext& renderer, Capture& capture, @@ -941,6 +948,13 @@ bool EntityPass::OnRender( /// Setup advanced blends. /// + if (result.entity.GetBlendMode() == BlendMode::kPlus && + !IsAlphaClampedToOne(pass_context.GetPassTarget() + .GetRenderTarget() + .GetRenderTargetPixelFormat())) { + result.entity.SetBlendMode(BlendMode::kPlusAdvanced); + } + if (result.entity.GetBlendMode() > Entity::kLastPipelineBlendMode) { if (renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) { auto src_contents = result.entity.GetContents(); From 9a8ee6f2d34ce03659a127a500f540b745a1c850 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 27 Mar 2024 08:42:48 -0700 Subject: [PATCH 15/25] added tests for the magic test name --- impeller/aiks/aiks_unittests.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 43accfb20a2b1..b0f306369de70 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -1101,8 +1101,21 @@ TEST_P(AiksTest, PaintBlendModeIsRespected) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } +// This makes sure the WideGamut named tests use 16bit float pixel format. +TEST_P(AiksTest, F16WideGamut) { + EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(), + PixelFormat::kR16G16B16A16Float); +} + +TEST_P(AiksTest, NotF16) { + EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(), + PixelFormat::kB8G8R8A8UNormInt); +} + // Bug: https://github.com/flutter/flutter/issues/142549 TEST_P(AiksTest, BlendModePlusAlphaWideGamut) { + EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(), + PixelFormat::kR16G16B16A16Float); auto texture = CreateTextureForFixture("airplane.jpg", /*enable_mipmapping=*/true); From 7ca79f670cbc330cf135eeed820b21d59d9b5c81 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 27 Mar 2024 08:48:37 -0700 Subject: [PATCH 16/25] renamed some variables --- impeller/entity/contents/content_context.cc | 4 ++-- impeller/entity/contents/content_context.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 79822bf439921..3da5a18e1362b 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -331,7 +331,7 @@ ContentContext::ContentContext( framebuffer_blend_lighten_pipelines_.CreateDefault( *context_, options_trianglestrip, {static_cast(BlendSelectValues::kLighten), supports_decal}); - framebuffer_blend_plus_pipelines_.CreateDefault( + framebuffer_blend_plus_advanced_pipelines_.CreateDefault( *context_, options_trianglestrip, {static_cast(BlendSelectValues::kPlusAdvanced), supports_decal}); @@ -382,7 +382,7 @@ ContentContext::ContentContext( blend_lighten_pipelines_.CreateDefault( *context_, options_trianglestrip, {static_cast(BlendSelectValues::kLighten), supports_decal}); - blend_plus_pipelines_.CreateDefault( + blend_plus_advanced_pipelines_.CreateDefault( *context_, options_trianglestrip, {static_cast(BlendSelectValues::kPlusAdvanced), supports_decal}); blend_luminosity_pipelines_.CreateDefault( diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 7b624548c8fdd..5f0380a15461b 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -647,7 +647,7 @@ class ContentContext { std::shared_ptr> GetBlendPlusAdvancedPipeline( ContentContextOptions opts) const { - return GetPipeline(blend_plus_pipelines_, opts); + return GetPipeline(blend_plus_advanced_pipelines_, opts); } std::shared_ptr> GetBlendLuminosityPipeline( @@ -738,7 +738,7 @@ class ContentContext { std::shared_ptr> GetFramebufferBlendPlusAdvancedPipeline(ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); - return GetPipeline(framebuffer_blend_plus_pipelines_, opts); + return GetPipeline(framebuffer_blend_plus_advanced_pipelines_, opts); } std::shared_ptr> @@ -1005,7 +1005,7 @@ class ContentContext { mutable Variants blend_hardlight_pipelines_; mutable Variants blend_hue_pipelines_; mutable Variants blend_lighten_pipelines_; - mutable Variants blend_plus_pipelines_; + mutable Variants blend_plus_advanced_pipelines_; mutable Variants blend_luminosity_pipelines_; mutable Variants blend_multiply_pipelines_; mutable Variants blend_overlay_pipelines_; @@ -1032,7 +1032,7 @@ class ContentContext { mutable Variants framebuffer_blend_lighten_pipelines_; mutable Variants - framebuffer_blend_plus_pipelines_; + framebuffer_blend_plus_advanced_pipelines_; mutable Variants framebuffer_blend_luminosity_pipelines_; mutable Variants From 337876d4daab2f8ddaf8def3545676b4e7105d0b Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 27 Mar 2024 08:50:36 -0700 Subject: [PATCH 17/25] moved things to match how they were --- impeller/entity/contents/content_context.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 3da5a18e1362b..5ea4527d9cedf 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -128,12 +128,6 @@ void ContentContextOptions::ApplyToPipelineDescriptor( color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha; color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha; break; - case BlendMode::kModulate: - color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha; - color0.dst_color_blend_factor = BlendFactor::kSourceColor; - color0.src_alpha_blend_factor = BlendFactor::kZero; - color0.src_color_blend_factor = BlendFactor::kZero; - break; case BlendMode::kPlus: // The kPlusAdvanced should be used instead. FML_DCHECK(IsAlphaClampedToOne(color_attachment_pixel_format)); @@ -142,6 +136,12 @@ void ContentContextOptions::ApplyToPipelineDescriptor( color0.src_alpha_blend_factor = BlendFactor::kOne; color0.src_color_blend_factor = BlendFactor::kOne; break; + case BlendMode::kModulate: + color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha; + color0.dst_color_blend_factor = BlendFactor::kSourceColor; + color0.src_alpha_blend_factor = BlendFactor::kZero; + color0.src_color_blend_factor = BlendFactor::kZero; + break; default: FML_UNREACHABLE(); } From 669a096eb842d0d444cd39d510bc39313c961866 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 27 Mar 2024 09:20:09 -0700 Subject: [PATCH 18/25] factored out the shared blend function --- impeller/compiler/shader_lib/impeller/color.glsl | 8 ++++++++ impeller/entity/shaders/blending/advanced_blend.frag | 6 +----- impeller/entity/shaders/blending/blend_select.glsl | 3 ++- impeller/entity/shaders/blending/framebuffer_blend.frag | 6 +----- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/impeller/compiler/shader_lib/impeller/color.glsl b/impeller/compiler/shader_lib/impeller/color.glsl index 310e22e779f76..c497f379fd550 100644 --- a/impeller/compiler/shader_lib/impeller/color.glsl +++ b/impeller/compiler/shader_lib/impeller/color.glsl @@ -46,4 +46,12 @@ f16vec4 IPHalfPremultiply(f16vec4 color) { return f16vec4(color.rgb * color.a, color.a); } +/// Performs the plus blend on `src` and `dst` which are premultiplied colors. +//`max` determines the values the results are clamped to. +f16vec4 IPHalfPlusBlend(f16vec4 src, f16vec4 dst) { + float16_t min = 0.0hf; + float16_t max = 1.0hf; + return clamp(dst + src, min, max); +} + #endif diff --git a/impeller/entity/shaders/blending/advanced_blend.frag b/impeller/entity/shaders/blending/advanced_blend.frag index 75e5e24198f95..07f72dab63af7 100644 --- a/impeller/entity/shaders/blending/advanced_blend.frag +++ b/impeller/entity/shaders/blending/advanced_blend.frag @@ -47,11 +47,7 @@ void main() { Sample(texture_sampler_src, // sampler v_src_texture_coords // texture coordinates ); - f16vec4 plus = premultiplied_dst + premultiplied_src; - if (plus.a > 1.0hf) { - plus.a = 1.0hf; - } - frag_color = plus; + frag_color = IPHalfPlusBlend(premultiplied_src, premultiplied_dst); } else { f16vec4 dst = IPHalfUnpremultiply(premultiplied_dst); dst *= blend_info.dst_input_alpha; diff --git a/impeller/entity/shaders/blending/blend_select.glsl b/impeller/entity/shaders/blending/blend_select.glsl index 3b81ae4b0d984..b03e6eb520abd 100644 --- a/impeller/entity/shaders/blending/blend_select.glsl +++ b/impeller/entity/shaders/blending/blend_select.glsl @@ -66,7 +66,8 @@ f16vec3 AdvancedBlend(f16vec3 dst, f16vec3 src, int blend_type) { if (blend_type == 13) { return IPBlendColor(dst, src); } - // 14 is `plus`, it's handled in advanced_blend.frag. + // 14 is `PlusAdvanced`, it's handled in advanced_blend.frag and + // framebuffer_blend.frag. if (blend_type == 15) { return IPBlendLuminosity(dst, src); } diff --git a/impeller/entity/shaders/blending/framebuffer_blend.frag b/impeller/entity/shaders/blending/framebuffer_blend.frag index 7f0aa6e8e66de..1eba2de9a9b3a 100644 --- a/impeller/entity/shaders/blending/framebuffer_blend.frag +++ b/impeller/entity/shaders/blending/framebuffer_blend.frag @@ -51,11 +51,7 @@ void main() { int nblend_type = int(blend_type); if (nblend_type == /*BlendSelectValues::kPlusAdvanced*/ 14) { - f16vec4 plus = premultiplied_dst + premultiplied_src; - if (plus.a > 1.0hf) { - plus.a = 1.0hf; - } - frag_color = plus; + frag_color = IPHalfPlusBlend(premultiplied_src, premultiplied_dst); } else { f16vec4 dst = IPHalfUnpremultiply(premultiplied_dst); f16vec4 src = IPHalfUnpremultiply(premultiplied_src); From cc8ab6afa29bc0460088c075e23aa0b053909475 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 27 Mar 2024 10:01:34 -0700 Subject: [PATCH 19/25] factored out shared function --- impeller/core/formats.h | 8 ++++++++ impeller/entity/contents/content_context.cc | 5 ----- impeller/entity/entity_pass.cc | 7 ------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/impeller/core/formats.h b/impeller/core/formats.h index aa859b45f6818..108cd454cd2fa 100644 --- a/impeller/core/formats.h +++ b/impeller/core/formats.h @@ -138,6 +138,14 @@ constexpr bool IsStencilWritable(PixelFormat format) { } } +/// Returns `true` if the pixel format has an implicit `clamp(x, 0, 1)` in the +/// pixel format. This is important for example when performing the `Plus` blend +/// where we don't want alpha values over 1.0. +constexpr bool IsAlphaClampedToOne(PixelFormat pixel_format) { + return !(pixel_format == PixelFormat::kR32G32B32A32Float || + pixel_format == PixelFormat::kR16G16B16A16Float); +} + constexpr const char* PixelFormatToString(PixelFormat format) { switch (format) { case PixelFormat::kUnknown: diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 5ea4527d9cedf..f27096cd876d1 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -24,11 +24,6 @@ namespace impeller { -bool IsAlphaClampedToOne(PixelFormat pixel_format) { - return !(pixel_format == PixelFormat::kR32G32B32A32Float || - pixel_format == PixelFormat::kR16G16B16A16Float); -} - void ContentContextOptions::ApplyToPipelineDescriptor( PipelineDescriptor& desc) const { auto pipeline_blend = blend_mode; diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc index a7946882ab323..a3664ed816cb9 100644 --- a/impeller/entity/entity_pass.cc +++ b/impeller/entity/entity_pass.cc @@ -841,13 +841,6 @@ bool EntityPass::RenderElement(Entity& element_entity, return true; } -namespace { -bool IsAlphaClampedToOne(PixelFormat pixel_format) { - return !(pixel_format == PixelFormat::kR32G32B32A32Float || - pixel_format == PixelFormat::kR16G16B16A16Float); -} -} // namespace - bool EntityPass::OnRender( ContentContext& renderer, Capture& capture, From 90330f47f53b01723f0ba4915915cb708f86342f Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 27 Mar 2024 10:23:07 -0700 Subject: [PATCH 20/25] added skip for non metal tests --- impeller/aiks/aiks_unittests.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index b0f306369de70..da8659b520ad2 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -1103,6 +1103,9 @@ TEST_P(AiksTest, PaintBlendModeIsRespected) { // This makes sure the WideGamut named tests use 16bit float pixel format. TEST_P(AiksTest, F16WideGamut) { + if (GetParam() != PlaygroundBackend::kMetal) { + GTEST_SKIP_("This backend doesn't yet support wide gamut."); + } EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(), PixelFormat::kR16G16B16A16Float); } @@ -1114,6 +1117,9 @@ TEST_P(AiksTest, NotF16) { // Bug: https://github.com/flutter/flutter/issues/142549 TEST_P(AiksTest, BlendModePlusAlphaWideGamut) { + if (GetParam() != PlaygroundBackend::kMetal) { + GTEST_SKIP_("This backend doesn't yet support wide gamut."); + } EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(), PixelFormat::kR16G16B16A16Float); auto texture = CreateTextureForFixture("airplane.jpg", From 2650ee066590640945fdf9447126455d6705ca3f Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 27 Mar 2024 11:00:49 -0700 Subject: [PATCH 21/25] fixed opengl run --- impeller/aiks/aiks_unittests.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index da8659b520ad2..801284f1eecb1 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -1108,11 +1108,13 @@ TEST_P(AiksTest, F16WideGamut) { } EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(), PixelFormat::kR16G16B16A16Float); + EXPECT_FALSE(IsAlphaClampedToOne( + GetContext()->GetCapabilities()->GetDefaultColorFormat())); } TEST_P(AiksTest, NotF16) { - EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(), - PixelFormat::kB8G8R8A8UNormInt); + EXPECT_TRUE(IsAlphaClampedToOne( + GetContext()->GetCapabilities()->GetDefaultColorFormat())); } // Bug: https://github.com/flutter/flutter/issues/142549 From afa79085368ebf3c6effd0ee92cca8ac9232b529 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 27 Mar 2024 11:04:23 -0700 Subject: [PATCH 22/25] updated goldens --- testing/impeller_golden_tests_output.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/impeller_golden_tests_output.txt b/testing/impeller_golden_tests_output.txt index aae87f0f42e8c..eafb12d9156e9 100644 --- a/testing/impeller_golden_tests_output.txt +++ b/testing/impeller_golden_tests_output.txt @@ -60,6 +60,7 @@ impeller_Play_AiksTest_BlendModeOverlay_Vulkan.png impeller_Play_AiksTest_BlendModePlus_Metal.png impeller_Play_AiksTest_BlendModePlus_OpenGLES.png impeller_Play_AiksTest_BlendModePlus_Vulkan.png +impeller_Play_AiksTest_BlendModePlusAlphaWideGamut_Metal.png impeller_Play_AiksTest_BlendModeSaturation_Metal.png impeller_Play_AiksTest_BlendModeSaturation_OpenGLES.png impeller_Play_AiksTest_BlendModeSaturation_Vulkan.png From 7081ef753ca2c3657414217b0102f9f05326499f Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 27 Mar 2024 12:41:16 -0700 Subject: [PATCH 23/25] updated goldens --- testing/impeller_golden_tests_output.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/testing/impeller_golden_tests_output.txt b/testing/impeller_golden_tests_output.txt index eafb12d9156e9..8a812acd71987 100644 --- a/testing/impeller_golden_tests_output.txt +++ b/testing/impeller_golden_tests_output.txt @@ -57,10 +57,13 @@ impeller_Play_AiksTest_BlendModeMultiply_Vulkan.png impeller_Play_AiksTest_BlendModeOverlay_Metal.png impeller_Play_AiksTest_BlendModeOverlay_OpenGLES.png impeller_Play_AiksTest_BlendModeOverlay_Vulkan.png +impeller_Play_AiksTest_BlendModePlusAdvanced_Metal.png +impeller_Play_AiksTest_BlendModePlusAdvanced_OpenGLES.png +impeller_Play_AiksTest_BlendModePlusAdvanced_Vulkan.png +impeller_Play_AiksTest_BlendModePlusAlphaWideGamut_Metal.png impeller_Play_AiksTest_BlendModePlus_Metal.png impeller_Play_AiksTest_BlendModePlus_OpenGLES.png impeller_Play_AiksTest_BlendModePlus_Vulkan.png -impeller_Play_AiksTest_BlendModePlusAlphaWideGamut_Metal.png impeller_Play_AiksTest_BlendModeSaturation_Metal.png impeller_Play_AiksTest_BlendModeSaturation_OpenGLES.png impeller_Play_AiksTest_BlendModeSaturation_Vulkan.png From 5025ec1903c84ab28a2b2d7708eca208ae910d81 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 27 Mar 2024 14:55:46 -0700 Subject: [PATCH 24/25] added support for colorfilters --- impeller/aiks/aiks_unittests.cc | 27 +++++++++++++++++++ .../contents/filters/blend_filter_contents.cc | 17 ++++++++---- testing/impeller_golden_tests_output.txt | 1 + 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 801284f1eecb1..ffd197dc3609d 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -1143,6 +1143,33 @@ TEST_P(AiksTest, BlendModePlusAlphaWideGamut) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } +// Bug: https://github.com/flutter/flutter/issues/142549 +TEST_P(AiksTest, BlendModePlusAlphaColorFilterWideGamut) { + if (GetParam() != PlaygroundBackend::kMetal) { + GTEST_SKIP_("This backend doesn't yet support wide gamut."); + } + EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(), + PixelFormat::kR16G16B16A16Float); + auto texture = CreateTextureForFixture("airplane.jpg", + /*enable_mipmapping=*/true); + + Canvas canvas; + canvas.Scale(GetContentScale()); + canvas.DrawPaint({.color = Color(0.1, 0.2, 0.1, 1.0)}); + canvas.SaveLayer({ + .color_filter = ColorFilter::MakeBlend(BlendMode::kPlus, Color(Vector4{1,0,0,1})), + }); + Paint paint; + paint.color = Color::Red(); + canvas.DrawRect(Rect::MakeXYWH(100, 100, 400, 400), paint); + paint.color = Color::White(); + canvas.DrawImageRect( + std::make_shared(texture), Rect::MakeSize(texture->GetSize()), + Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100), paint); + canvas.Restore(); + ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); +} + TEST_P(AiksTest, ColorWheel) { // Compare with https://fiddle.skia.org/c/@BlendModes diff --git a/impeller/entity/contents/filters/blend_filter_contents.cc b/impeller/entity/contents/filters/blend_filter_contents.cc index 21c15e93a66de..7941f9f7a9b6a 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/impeller/entity/contents/filters/blend_filter_contents.cc @@ -615,19 +615,26 @@ std::optional BlendFilterContents::RenderFilter( std::nullopt, GetAbsorbOpacity(), GetAlpha()); } - if (blend_mode_ <= Entity::kLastPipelineBlendMode) { - return PipelineBlend(inputs, renderer, entity, coverage, blend_mode_, + BlendMode blend_mode = blend_mode_; + if (blend_mode == BlendMode::kPlus && + !IsAlphaClampedToOne( + renderer.GetContext()->GetCapabilities()->GetDefaultColorFormat())) { + blend_mode = BlendMode::kPlusAdvanced; + } + + if (blend_mode <= Entity::kLastPipelineBlendMode) { + return PipelineBlend(inputs, renderer, entity, coverage, blend_mode, foreground_color_, GetAbsorbOpacity(), GetAlpha()); } - if (blend_mode_ <= Entity::kLastAdvancedBlendMode) { + if (blend_mode <= Entity::kLastAdvancedBlendMode) { if (inputs.size() == 1 && foreground_color_.has_value() && GetAbsorbOpacity() == ColorFilterContents::AbsorbOpacity::kYes) { return CreateForegroundAdvancedBlend( inputs[0], renderer, entity, coverage, foreground_color_.value(), - blend_mode_, GetAlpha(), GetAbsorbOpacity()); + blend_mode, GetAlpha(), GetAbsorbOpacity()); } - return advanced_blend_proc_(inputs, renderer, entity, coverage, blend_mode_, + return advanced_blend_proc_(inputs, renderer, entity, coverage, blend_mode, foreground_color_, GetAbsorbOpacity(), GetAlpha()); } diff --git a/testing/impeller_golden_tests_output.txt b/testing/impeller_golden_tests_output.txt index 8a812acd71987..9c13bcb384302 100644 --- a/testing/impeller_golden_tests_output.txt +++ b/testing/impeller_golden_tests_output.txt @@ -60,6 +60,7 @@ impeller_Play_AiksTest_BlendModeOverlay_Vulkan.png impeller_Play_AiksTest_BlendModePlusAdvanced_Metal.png impeller_Play_AiksTest_BlendModePlusAdvanced_OpenGLES.png impeller_Play_AiksTest_BlendModePlusAdvanced_Vulkan.png +impeller_Play_AiksTest_BlendModePlusAlphaColorFilterWideGamut_Metal.png impeller_Play_AiksTest_BlendModePlusAlphaWideGamut_Metal.png impeller_Play_AiksTest_BlendModePlus_Metal.png impeller_Play_AiksTest_BlendModePlus_OpenGLES.png From 202f56d53a5153a91fdbd74637ce1a45b63a5a58 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Wed, 27 Mar 2024 15:34:23 -0700 Subject: [PATCH 25/25] format --- impeller/aiks/aiks_unittests.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index ffd197dc3609d..c48a8bfc36206 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -1157,7 +1157,8 @@ TEST_P(AiksTest, BlendModePlusAlphaColorFilterWideGamut) { canvas.Scale(GetContentScale()); canvas.DrawPaint({.color = Color(0.1, 0.2, 0.1, 1.0)}); canvas.SaveLayer({ - .color_filter = ColorFilter::MakeBlend(BlendMode::kPlus, Color(Vector4{1,0,0,1})), + .color_filter = + ColorFilter::MakeBlend(BlendMode::kPlus, Color(Vector4{1, 0, 0, 1})), }); Paint paint; paint.color = Color::Red();