Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 13a1f1c

Browse files
[Impeller] add experimental canvas support to screenshotter. (#53751)
Fixes flutter/flutter#150993 This change allows testing the experimental canvas dispatcher in the playgrounds, which is important for golden testing. The plan to enable requires demonstrating that the goldens are the same.
1 parent 8f24e0d commit 13a1f1c

File tree

6 files changed

+89
-6
lines changed

6 files changed

+89
-6
lines changed

impeller/golden_tests/golden_playground_test_mac.cc

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <filesystem>
77
#include <memory>
88

9+
#include "display_list/display_list.h"
910
#include "flutter/impeller/golden_tests/golden_playground_test.h"
1011

1112
#include "flutter/impeller/aiks/picture.h"
@@ -14,6 +15,7 @@
1415
#include "flutter/impeller/golden_tests/vulkan_screenshotter.h"
1516
#include "flutter/third_party/abseil-cpp/absl/base/no_destructor.h"
1617
#include "fml/closure.h"
18+
#include "impeller/aiks/aiks_context.h"
1719
#include "impeller/display_list/dl_dispatcher.h"
1820
#include "impeller/display_list/dl_image_impeller.h"
1921
#include "impeller/typographer/backends/skia/typographer_context_skia.h"
@@ -22,6 +24,8 @@
2224
#define GLFW_INCLUDE_NONE
2325
#include "third_party/glfw/include/GLFW/glfw3.h"
2426

27+
#define EXPERIMENTAL_CANVAS false
28+
2529
namespace impeller {
2630

2731
namespace {
@@ -55,6 +59,56 @@ const std::unique_ptr<PlaygroundImpl>& GetSharedVulkanPlayground(
5559
return *vulkan_playground;
5660
}
5761
}
62+
63+
#if EXPERIMENTAL_CANVAS
64+
std::shared_ptr<Texture> DisplayListToTexture(
65+
sk_sp<flutter::DisplayList>& display_list,
66+
ISize size,
67+
AiksContext& context) {
68+
// Do not use the render target cache as the lifecycle of this texture
69+
// will outlive a particular frame.
70+
impeller::RenderTargetAllocator render_target_allocator =
71+
impeller::RenderTargetAllocator(
72+
context.GetContext()->GetResourceAllocator());
73+
impeller::RenderTarget target;
74+
if (context.GetContext()->GetCapabilities()->SupportsOffscreenMSAA()) {
75+
target = render_target_allocator.CreateOffscreenMSAA(
76+
*context.GetContext(), // context
77+
size, // size
78+
/*mip_count=*/1,
79+
"Picture Snapshot MSAA", // label
80+
impeller::RenderTarget::
81+
kDefaultColorAttachmentConfigMSAA // color_attachment_config
82+
);
83+
} else {
84+
target = render_target_allocator.CreateOffscreen(
85+
*context.GetContext(), // context
86+
size, // size
87+
/*mip_count=*/1,
88+
"Picture Snapshot", // label
89+
impeller::RenderTarget::
90+
kDefaultColorAttachmentConfig // color_attachment_config
91+
);
92+
}
93+
94+
impeller::TextFrameDispatcher collector(context.GetContentContext(),
95+
impeller::Matrix());
96+
display_list->Dispatch(
97+
collector, SkIRect::MakeSize(SkISize::Make(size.width, size.height)));
98+
impeller::ExperimentalDlDispatcher impeller_dispatcher(
99+
context.GetContentContext(), target,
100+
display_list->root_has_backdrop_filter(),
101+
display_list->max_root_blend_mode(), impeller::IRect::MakeSize(size));
102+
display_list->Dispatch(impeller_dispatcher, SkIRect::MakeSize(SkISize::Make(
103+
size.width, size.height)));
104+
impeller_dispatcher.FinishRecording();
105+
106+
context.GetContentContext().GetLazyGlyphAtlas()->ResetTextFrames();
107+
108+
return target.GetRenderTargetTexture();
109+
}
110+
#endif // EXPERIMENTAL_CANVAS
111+
58112
} // namespace
59113

60114
#define IMP_AIKSTEST(name) \
@@ -214,8 +268,16 @@ bool GoldenPlaygroundTest::OpenPlaygroundHere(
214268
const AiksDlPlaygroundCallback& callback) {
215269
AiksContext renderer(GetContext(), typographer_context_);
216270

217-
std::optional<Picture> picture;
218271
std::unique_ptr<testing::Screenshot> screenshot;
272+
#if EXPERIMENTAL_CANVAS
273+
for (int i = 0; i < 2; ++i) {
274+
auto display_list = callback();
275+
auto texture =
276+
DisplayListToTexture(display_list, pimpl_->window_size, renderer);
277+
screenshot = pimpl_->screenshotter->MakeScreenshot(renderer, texture);
278+
}
279+
#else
280+
std::optional<Picture> picture;
219281
for (int i = 0; i < 2; ++i) {
220282
auto display_list = callback();
221283
DlDispatcher dispatcher;
@@ -225,7 +287,7 @@ bool GoldenPlaygroundTest::OpenPlaygroundHere(
225287
screenshot = pimpl_->screenshotter->MakeScreenshot(renderer, picture,
226288
pimpl_->window_size);
227289
}
228-
290+
#endif // EXPERIMENTAL_CANVAS
229291
return SaveScreenshot(std::move(screenshot));
230292
}
231293

@@ -250,10 +312,7 @@ bool GoldenPlaygroundTest::OpenPlaygroundHere(
250312

251313
bool GoldenPlaygroundTest::OpenPlaygroundHere(
252314
const sk_sp<flutter::DisplayList>& list) {
253-
DlDispatcher dispatcher;
254-
list->Dispatch(dispatcher);
255-
Picture picture = dispatcher.EndRecordingAsPicture();
256-
return OpenPlaygroundHere(std::move(picture));
315+
return OpenPlaygroundHere([&list]() { return list; });
257316
}
258317

259318
bool GoldenPlaygroundTest::ImGuiBegin(const char* name,

impeller/golden_tests/metal_screenshotter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ class MetalScreenshotter : public Screenshotter {
2525
const ISize& size = {300, 300},
2626
bool scale_content = true) override;
2727

28+
std::unique_ptr<Screenshot> MakeScreenshot(
29+
AiksContext& aiks_context,
30+
const std::shared_ptr<Texture> texture) override;
31+
2832
PlaygroundImpl& GetPlayground() override { return *playground_; }
2933

3034
private:

impeller/golden_tests/metal_screenshotter.mm

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@
3131
aiks_context,
3232
ISize(size.width * content_scale.x, size.height * content_scale.y));
3333
std::shared_ptr<Texture> texture = image->GetTexture();
34+
return MakeScreenshot(aiks_context, texture);
35+
}
36+
37+
std::unique_ptr<Screenshot> MetalScreenshotter::MakeScreenshot(
38+
AiksContext& aiks_context,
39+
const std::shared_ptr<Texture> texture) {
3440
id<MTLTexture> metal_texture =
3541
std::static_pointer_cast<TextureMTL>(texture)->GetMTLTexture();
3642

impeller/golden_tests/screenshotter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ class Screenshotter {
2424
const ISize& size = {300, 300},
2525
bool scale_content = true) = 0;
2626

27+
virtual std::unique_ptr<Screenshot> MakeScreenshot(
28+
AiksContext& aiks_context,
29+
const std::shared_ptr<Texture> texture) = 0;
30+
2731
virtual PlaygroundImpl& GetPlayground() = 0;
2832
};
2933

impeller/golden_tests/vulkan_screenshotter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ class VulkanScreenshotter : public Screenshotter {
2626
const ISize& size = {300, 300},
2727
bool scale_content = true) override;
2828

29+
std::unique_ptr<Screenshot> MakeScreenshot(
30+
AiksContext& aiks_context,
31+
const std::shared_ptr<Texture> texture) override;
32+
2933
PlaygroundImpl& GetPlayground() override { return *playground_; }
3034

3135
private:

impeller/golden_tests/vulkan_screenshotter.mm

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,11 @@ CGImagePtr flipped_image(CGBitmapContextCreateImage(flipped_context.get()),
120120
return ReadTexture(aiks_context.GetContext(), texture);
121121
}
122122

123+
std::unique_ptr<Screenshot> VulkanScreenshotter::MakeScreenshot(
124+
AiksContext& aiks_context,
125+
const std::shared_ptr<Texture> texture) {
126+
return ReadTexture(aiks_context.GetContext(), texture);
127+
}
128+
123129
} // namespace testing
124130
} // namespace impeller

0 commit comments

Comments
 (0)