diff --git a/impeller/golden_tests/golden_playground_test_mac.cc b/impeller/golden_tests/golden_playground_test_mac.cc index 5a85e5d269a6e..d5cb282c4bf98 100644 --- a/impeller/golden_tests/golden_playground_test_mac.cc +++ b/impeller/golden_tests/golden_playground_test_mac.cc @@ -6,6 +6,7 @@ #include #include +#include "display_list/display_list.h" #include "flutter/impeller/golden_tests/golden_playground_test.h" #include "flutter/impeller/aiks/picture.h" @@ -14,6 +15,7 @@ #include "flutter/impeller/golden_tests/vulkan_screenshotter.h" #include "flutter/third_party/abseil-cpp/absl/base/no_destructor.h" #include "fml/closure.h" +#include "impeller/aiks/aiks_context.h" #include "impeller/display_list/dl_dispatcher.h" #include "impeller/display_list/dl_image_impeller.h" #include "impeller/typographer/backends/skia/typographer_context_skia.h" @@ -22,6 +24,8 @@ #define GLFW_INCLUDE_NONE #include "third_party/glfw/include/GLFW/glfw3.h" +#define EXPERIMENTAL_CANVAS false + namespace impeller { namespace { @@ -55,6 +59,56 @@ const std::unique_ptr& GetSharedVulkanPlayground( return *vulkan_playground; } } + +#if EXPERIMENTAL_CANVAS +std::shared_ptr DisplayListToTexture( + sk_sp& display_list, + ISize size, + AiksContext& context) { + // Do not use the render target cache as the lifecycle of this texture + // will outlive a particular frame. + impeller::RenderTargetAllocator render_target_allocator = + impeller::RenderTargetAllocator( + context.GetContext()->GetResourceAllocator()); + impeller::RenderTarget target; + if (context.GetContext()->GetCapabilities()->SupportsOffscreenMSAA()) { + target = render_target_allocator.CreateOffscreenMSAA( + *context.GetContext(), // context + size, // size + /*mip_count=*/1, + "Picture Snapshot MSAA", // label + impeller::RenderTarget:: + kDefaultColorAttachmentConfigMSAA // color_attachment_config + ); + } else { + target = render_target_allocator.CreateOffscreen( + *context.GetContext(), // context + size, // size + /*mip_count=*/1, + "Picture Snapshot", // label + impeller::RenderTarget:: + kDefaultColorAttachmentConfig // color_attachment_config + ); + } + + impeller::TextFrameDispatcher collector(context.GetContentContext(), + impeller::Matrix()); + display_list->Dispatch( + collector, SkIRect::MakeSize(SkISize::Make(size.width, size.height))); + impeller::ExperimentalDlDispatcher impeller_dispatcher( + context.GetContentContext(), target, + display_list->root_has_backdrop_filter(), + display_list->max_root_blend_mode(), impeller::IRect::MakeSize(size)); + display_list->Dispatch(impeller_dispatcher, SkIRect::MakeSize(SkISize::Make( + size.width, size.height))); + impeller_dispatcher.FinishRecording(); + + context.GetContentContext().GetLazyGlyphAtlas()->ResetTextFrames(); + + return target.GetRenderTargetTexture(); +} +#endif // EXPERIMENTAL_CANVAS + } // namespace #define IMP_AIKSTEST(name) \ @@ -214,8 +268,16 @@ bool GoldenPlaygroundTest::OpenPlaygroundHere( const AiksDlPlaygroundCallback& callback) { AiksContext renderer(GetContext(), typographer_context_); - std::optional picture; std::unique_ptr screenshot; +#if EXPERIMENTAL_CANVAS + for (int i = 0; i < 2; ++i) { + auto display_list = callback(); + auto texture = + DisplayListToTexture(display_list, pimpl_->window_size, renderer); + screenshot = pimpl_->screenshotter->MakeScreenshot(renderer, texture); + } +#else + std::optional picture; for (int i = 0; i < 2; ++i) { auto display_list = callback(); DlDispatcher dispatcher; @@ -225,7 +287,7 @@ bool GoldenPlaygroundTest::OpenPlaygroundHere( screenshot = pimpl_->screenshotter->MakeScreenshot(renderer, picture, pimpl_->window_size); } - +#endif // EXPERIMENTAL_CANVAS return SaveScreenshot(std::move(screenshot)); } @@ -250,10 +312,7 @@ bool GoldenPlaygroundTest::OpenPlaygroundHere( bool GoldenPlaygroundTest::OpenPlaygroundHere( const sk_sp& list) { - DlDispatcher dispatcher; - list->Dispatch(dispatcher); - Picture picture = dispatcher.EndRecordingAsPicture(); - return OpenPlaygroundHere(std::move(picture)); + return OpenPlaygroundHere([&list]() { return list; }); } bool GoldenPlaygroundTest::ImGuiBegin(const char* name, diff --git a/impeller/golden_tests/metal_screenshotter.h b/impeller/golden_tests/metal_screenshotter.h index 8dc8ce53c5df1..57bd8fc11598f 100644 --- a/impeller/golden_tests/metal_screenshotter.h +++ b/impeller/golden_tests/metal_screenshotter.h @@ -25,6 +25,10 @@ class MetalScreenshotter : public Screenshotter { const ISize& size = {300, 300}, bool scale_content = true) override; + std::unique_ptr MakeScreenshot( + AiksContext& aiks_context, + const std::shared_ptr texture) override; + PlaygroundImpl& GetPlayground() override { return *playground_; } private: diff --git a/impeller/golden_tests/metal_screenshotter.mm b/impeller/golden_tests/metal_screenshotter.mm index f09cb10e03849..9ab6f422e7d98 100644 --- a/impeller/golden_tests/metal_screenshotter.mm +++ b/impeller/golden_tests/metal_screenshotter.mm @@ -31,6 +31,12 @@ aiks_context, ISize(size.width * content_scale.x, size.height * content_scale.y)); std::shared_ptr texture = image->GetTexture(); + return MakeScreenshot(aiks_context, texture); +} + +std::unique_ptr MetalScreenshotter::MakeScreenshot( + AiksContext& aiks_context, + const std::shared_ptr texture) { id metal_texture = std::static_pointer_cast(texture)->GetMTLTexture(); diff --git a/impeller/golden_tests/screenshotter.h b/impeller/golden_tests/screenshotter.h index c3581461aa39d..1fbf478c8b572 100644 --- a/impeller/golden_tests/screenshotter.h +++ b/impeller/golden_tests/screenshotter.h @@ -24,6 +24,10 @@ class Screenshotter { const ISize& size = {300, 300}, bool scale_content = true) = 0; + virtual std::unique_ptr MakeScreenshot( + AiksContext& aiks_context, + const std::shared_ptr texture) = 0; + virtual PlaygroundImpl& GetPlayground() = 0; }; diff --git a/impeller/golden_tests/vulkan_screenshotter.h b/impeller/golden_tests/vulkan_screenshotter.h index fa47e44d0591b..14347ee0ec3ce 100644 --- a/impeller/golden_tests/vulkan_screenshotter.h +++ b/impeller/golden_tests/vulkan_screenshotter.h @@ -26,6 +26,10 @@ class VulkanScreenshotter : public Screenshotter { const ISize& size = {300, 300}, bool scale_content = true) override; + std::unique_ptr MakeScreenshot( + AiksContext& aiks_context, + const std::shared_ptr texture) override; + PlaygroundImpl& GetPlayground() override { return *playground_; } private: diff --git a/impeller/golden_tests/vulkan_screenshotter.mm b/impeller/golden_tests/vulkan_screenshotter.mm index a896c72f6975d..04792b15f00e6 100644 --- a/impeller/golden_tests/vulkan_screenshotter.mm +++ b/impeller/golden_tests/vulkan_screenshotter.mm @@ -120,5 +120,11 @@ CGImagePtr flipped_image(CGBitmapContextCreateImage(flipped_context.get()), return ReadTexture(aiks_context.GetContext(), texture); } +std::unique_ptr VulkanScreenshotter::MakeScreenshot( + AiksContext& aiks_context, + const std::shared_ptr texture) { + return ReadTexture(aiks_context.GetContext(), texture); +} + } // namespace testing } // namespace impeller