Flutter Impeller
impeller::GoldenPlaygroundTest Class Reference

#include <golden_playground_test.h>

Inheritance diagram for impeller::GoldenPlaygroundTest:

Classes

struct  GoldenPlaygroundTestImpl
 

Public Types

using AiksPlaygroundCallback = std::function< std::optional< Picture >(AiksContext &renderer)>
 
using AiksDlPlaygroundCallback = std::function< sk_sp< flutter::DisplayList >()>
 

Public Member Functions

 GoldenPlaygroundTest ()
 
 ~GoldenPlaygroundTest () override
 
void SetUp ()
 
void TearDown ()
 
PlaygroundBackend GetBackend () const
 
void SetTypographerContext (std::shared_ptr< TypographerContext > typographer_context)
 
bool OpenPlaygroundHere (Picture picture)
 
bool OpenPlaygroundHere (AiksPlaygroundCallback callback)
 
bool OpenPlaygroundHere (const AiksDlPlaygroundCallback &callback)
 
bool OpenPlaygroundHere (const sk_sp< flutter::DisplayList > &list)
 
bool OpenPlaygroundHere (const Playground::SinglePassCallback &callback)
 
std::unique_ptr< testing::Screenshot > MakeScreenshot (const sk_sp< flutter::DisplayList > &list)
 
std::shared_ptr< Texture > CreateTextureForFixture (const char *fixture_name, bool enable_mipmapping=false) const
 
sk_sp< flutter::DlImage > CreateDlImageForFixture (const char *fixture_name, bool enable_mipmapping=false) const
 
absl::StatusOr< RuntimeStage::Map > OpenAssetAsRuntimeStage (const char *asset_name) const
 
std::shared_ptr< Context > GetContext () const
 
std::shared_ptr< Context > MakeContext () const
 
Point GetContentScale () const
 
Scalar GetSecondsElapsed () const
 
ISize GetWindowSize () const
 
IRect GetWindowBounds () const
 
fml::Status SetCapabilities (const std::shared_ptr< Capabilities > &capabilities)
 
bool WillRenderSomething () const
 Returns true if OpenPlaygroundHere will actually render anything. More...
 
RuntimeStageBackend GetRuntimeStageBackend () const
 
bool IsGoldenTest ()
 

Static Public Member Functions

static bool SaveScreenshot (std::unique_ptr< testing::Screenshot > screenshot, const std::string &postfix="")
 
static bool ImGuiBegin (const char *name, bool *p_open, ImGuiWindowFlags flags)
 

Protected Member Functions

void SetWindowSize (ISize size)
 
bool PlatformSupportsWideGamutTests () const
 
void EnsureContextIsUnique ()
 
bool EnsureContextSupportsWideGamut ()
 
void EnsureContextSupportsAntialiasLines ()
 

Detailed Description

Definition at line 27 of file golden_playground_test.h.

Member Typedef Documentation

◆ AiksDlPlaygroundCallback

using impeller::GoldenPlaygroundTest::AiksDlPlaygroundCallback = std::function<sk_sp<flutter::DisplayList>()>

Definition at line 33 of file golden_playground_test.h.

◆ AiksPlaygroundCallback

using impeller::GoldenPlaygroundTest::AiksPlaygroundCallback = std::function<std::optional<Picture>(AiksContext& renderer)>

Definition at line 30 of file golden_playground_test.h.

Constructor & Destructor Documentation

◆ GoldenPlaygroundTest()

impeller::GoldenPlaygroundTest::GoldenPlaygroundTest ( )
default

Definition at line 157 of file golden_playground_test_mac.cc.

158  : typographer_context_(TypographerContextSkia::Make()),
159  pimpl_(new GoldenPlaygroundTest::GoldenPlaygroundTestImpl()) {}
static std::shared_ptr< TypographerContext > Make()

◆ ~GoldenPlaygroundTest()

impeller::GoldenPlaygroundTest::~GoldenPlaygroundTest ( )
overridedefault

Member Function Documentation

◆ CreateDlImageForFixture()

sk_sp< flutter::DlImage > impeller::GoldenPlaygroundTest::CreateDlImageForFixture ( const char *  fixture_name,
bool  enable_mipmapping = false 
) const

Definition at line 360 of file golden_playground_test_mac.cc.

362  {
363  std::shared_ptr<Texture> texture =
364  CreateTextureForFixture(fixture_name, enable_mipmapping);
365  return DlImageImpeller::Make(texture);
366 }
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
std::shared_ptr< Texture > CreateTextureForFixture(const char *fixture_name, bool enable_mipmapping=false) const

References CreateTextureForFixture(), and impeller::DlImageImpeller::Make().

◆ CreateTextureForFixture()

std::shared_ptr< Texture > impeller::GoldenPlaygroundTest::CreateTextureForFixture ( const char *  fixture_name,
bool  enable_mipmapping = false 
) const

Definition at line 347 of file golden_playground_test_mac.cc.

349  {
350  std::shared_ptr<fml::Mapping> mapping =
351  flutter::testing::OpenFixtureAsMapping(fixture_name);
352  auto result = Playground::CreateTextureForMapping(GetContext(), mapping,
353  enable_mipmapping);
354  if (result) {
355  result->SetLabel(fixture_name);
356  }
357  return result;
358 }
std::shared_ptr< Context > GetContext() const
static std::shared_ptr< Texture > CreateTextureForMapping(const std::shared_ptr< Context > &context, std::shared_ptr< fml::Mapping > mapping, bool enable_mipmapping=false)
Definition: playground.cc:522

References impeller::Playground::CreateTextureForMapping(), and GetContext().

Referenced by CreateDlImageForFixture().

◆ EnsureContextIsUnique()

void impeller::GoldenPlaygroundTest::EnsureContextIsUnique ( )
inlineprotected

Definition at line 117 of file golden_playground_test.h.

117 {}

◆ EnsureContextSupportsAntialiasLines()

void impeller::GoldenPlaygroundTest::EnsureContextSupportsAntialiasLines ( )
inlineprotected

Definition at line 125 of file golden_playground_test.h.

125 {}

◆ EnsureContextSupportsWideGamut()

bool impeller::GoldenPlaygroundTest::EnsureContextSupportsWideGamut ( )
inlineprotected

Definition at line 121 of file golden_playground_test.h.

121 { return true; }

◆ GetBackend()

PlaygroundBackend impeller::GoldenPlaygroundTest::GetBackend ( ) const

Definition at line 265 of file golden_playground_test_mac.cc.

265  {
266  return GetParam();
267 }

◆ GetContentScale()

Point impeller::GoldenPlaygroundTest::GetContentScale ( ) const

Definition at line 414 of file golden_playground_test_mac.cc.

414  {
415  return pimpl_->screenshotter->GetPlayground().GetContentScale();
416 }

◆ GetContext()

std::shared_ptr< Context > impeller::GoldenPlaygroundTest::GetContext ( ) const

Definition at line 378 of file golden_playground_test_mac.cc.

378  {
379  if (!pimpl_->screenshotter) {
380  return nullptr;
381  }
382  return pimpl_->screenshotter->GetPlayground().GetContext();
383 }

Referenced by CreateTextureForFixture(), MakeContext(), MakeScreenshot(), OpenPlaygroundHere(), SetUp(), and TearDown().

◆ GetRuntimeStageBackend()

RuntimeStageBackend impeller::GoldenPlaygroundTest::GetRuntimeStageBackend ( ) const

Definition at line 452 of file golden_playground_test_mac.cc.

452  {
453  return pimpl_->screenshotter->GetPlayground().GetRuntimeStageBackend();
454 }

◆ GetSecondsElapsed()

Scalar impeller::GoldenPlaygroundTest::GetSecondsElapsed ( ) const

Definition at line 418 of file golden_playground_test_mac.cc.

418  {
419  return 0.0f;
420 }

◆ GetWindowBounds()

IRect impeller::GoldenPlaygroundTest::GetWindowBounds ( ) const

Definition at line 426 of file golden_playground_test_mac.cc.

426  {
427  return IRect::MakeSize(pimpl_->window_size);
428 }
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:150

References impeller::TRect< T >::MakeSize().

◆ GetWindowSize()

ISize impeller::GoldenPlaygroundTest::GetWindowSize ( ) const

Definition at line 422 of file golden_playground_test_mac.cc.

422  {
423  return pimpl_->window_size;
424 }

◆ ImGuiBegin()

bool impeller::GoldenPlaygroundTest::ImGuiBegin ( const char *  name,
bool *  p_open,
ImGuiWindowFlags  flags 
)
static

Definition at line 341 of file golden_playground_test_mac.cc.

343  {
344  return false;
345 }

◆ IsGoldenTest()

bool impeller::GoldenPlaygroundTest::IsGoldenTest ( )
inline

Definition at line 107 of file golden_playground_test.h.

107 { return true; }

◆ MakeContext()

std::shared_ptr< Context > impeller::GoldenPlaygroundTest::MakeContext ( ) const

On Metal we create a context for each test.

Definition at line 385 of file golden_playground_test_mac.cc.

385  {
386  if (GetParam() == PlaygroundBackend::kMetal ||
387  GetParam() == PlaygroundBackend::kMetalSDF) {
388  /// On Metal we create a context for each test.
389  return GetContext();
390  } else if (GetParam() == PlaygroundBackend::kVulkan) {
391  bool enable_vulkan_validations = true;
392  FML_CHECK(!pimpl_->test_vulkan_playground)
393  << "We don't support creating multiple contexts for one test";
394  pimpl_->test_vulkan_playground =
395  MakeVulkanPlayground(enable_vulkan_validations);
396  pimpl_->screenshotter = std::make_unique<testing::VulkanScreenshotter>(
397  pimpl_->test_vulkan_playground);
398  return pimpl_->test_vulkan_playground->GetContext();
399  } else if (GetParam() == PlaygroundBackend::kOpenGLES ||
400  GetParam() == PlaygroundBackend::kOpenGLESSDF) {
401  FML_CHECK(!pimpl_->test_opengl_playground)
402  << "We don't support creating multiple contexts for one test";
403  bool use_sdfs = (GetParam() == PlaygroundBackend::kOpenGLESSDF);
404  pimpl_->test_opengl_playground = MakeOpenGLESPlayground(use_sdfs);
405  pimpl_->screenshotter = std::make_unique<testing::VulkanScreenshotter>(
406  pimpl_->test_opengl_playground);
407  return pimpl_->test_opengl_playground->GetContext();
408  } else {
409  FML_CHECK(false);
410  return nullptr;
411  }
412 }

References GetContext(), impeller::kMetal, impeller::kMetalSDF, impeller::kOpenGLES, impeller::kOpenGLESSDF, and impeller::kVulkan.

◆ MakeScreenshot()

std::unique_ptr< testing::Screenshot > impeller::GoldenPlaygroundTest::MakeScreenshot ( const sk_sp< flutter::DisplayList > &  list)

Definition at line 439 of file golden_playground_test_mac.cc.

440  {
441  AiksContext renderer(GetContext(), typographer_context_);
442  Point content_scale =
443  pimpl_->screenshotter->GetPlayground().GetContentScale();
444 
445  ISize physical_window_size(
446  std::round(pimpl_->window_size.width * content_scale.x),
447  std::round(pimpl_->window_size.height * content_scale.y));
448  return pimpl_->screenshotter->MakeScreenshot(
449  renderer, DisplayListToTexture(list, physical_window_size, renderer));
450 }
std::shared_ptr< Texture > DisplayListToTexture(const sk_sp< flutter::DisplayList > &display_list, ISize size, AiksContext &context, bool reset_host_buffer, bool generate_mips, std::optional< PixelFormat > target_pixel_format)
Render the provided display list to a texture with the given size.
TPoint< Scalar > Point
Definition: point.h:426
ISize64 ISize
Definition: size.h:162

References impeller::DisplayListToTexture(), GetContext(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ OpenAssetAsRuntimeStage()

absl::StatusOr< RuntimeStage::Map > impeller::GoldenPlaygroundTest::OpenAssetAsRuntimeStage ( const char *  asset_name) const

Definition at line 368 of file golden_playground_test_mac.cc.

369  {
370  const std::shared_ptr<fml::Mapping> fixture =
371  flutter::testing::OpenFixtureAsMapping(asset_name);
372  if (!fixture || fixture->GetSize() == 0) {
373  return absl::NotFoundError("Asset not found or empty.");
374  }
375  return RuntimeStage::DecodeRuntimeStages(fixture);
376 }
static absl::StatusOr< Map > DecodeRuntimeStages(const std::shared_ptr< fml::Mapping > &payload)

References impeller::RuntimeStage::DecodeRuntimeStages().

◆ OpenPlaygroundHere() [1/5]

bool impeller::GoldenPlaygroundTest::OpenPlaygroundHere ( AiksPlaygroundCallback  callback)

◆ OpenPlaygroundHere() [2/5]

bool impeller::GoldenPlaygroundTest::OpenPlaygroundHere ( const AiksDlPlaygroundCallback &  callback)

Definition at line 269 of file golden_playground_test_mac.cc.

270  {
271  AiksContext renderer(GetContext(), typographer_context_);
272 
273  std::unique_ptr<testing::Screenshot> screenshot;
274  Point content_scale =
275  pimpl_->screenshotter->GetPlayground().GetContentScale();
276 
277  ISize physical_window_size(
278  std::round(pimpl_->window_size.width * content_scale.x),
279  std::round(pimpl_->window_size.height * content_scale.y));
280  for (int i = 0; i < 2; ++i) {
281  auto display_list = callback();
282  auto texture =
283  DisplayListToTexture(display_list, physical_window_size, renderer);
284  screenshot = pimpl_->screenshotter->MakeScreenshot(renderer, texture);
285  }
286  return SaveScreenshot(std::move(screenshot));
287 }
static bool SaveScreenshot(std::unique_ptr< testing::Screenshot > screenshot, const std::string &postfix="")

References impeller::DisplayListToTexture(), GetContext(), SaveScreenshot(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ OpenPlaygroundHere() [3/5]

bool impeller::GoldenPlaygroundTest::OpenPlaygroundHere ( const Playground::SinglePassCallback &  callback)

Renders callback into an offscreen render pass and saves the result as a golden image. The render target is single-sampled, uses the context's default color format, and has no depth or stencil attachment, so a pipeline built from PipelineBuilder<>::MakeDefaultPipelineDescriptor must be reduced to match by calling SetSampleCount(kCount1), ClearStencilAttachments(), and ClearDepthAttachment() on it. Calling only SetStencilAttachmentDescriptors(nullopt) leaves the stencil pixel format set and trips Metal's render pipeline validation.

Definition at line 294 of file golden_playground_test_mac.cc.

295  {
296  AiksContext renderer(GetContext(), typographer_context_);
297  std::shared_ptr<Context> context = GetContext();
298  Point content_scale =
299  pimpl_->screenshotter->GetPlayground().GetContentScale();
300  ISize size(std::round(pimpl_->window_size.width * content_scale.x),
301  std::round(pimpl_->window_size.height * content_scale.y));
302 
303  std::unique_ptr<testing::Screenshot> screenshot;
304  // Render twice so the second pass observes warmed pipeline and resource
305  // caches, matching the display list path above.
306  for (int i = 0; i < 2; ++i) {
307  RenderTargetAllocator render_target_allocator(
308  context->GetResourceAllocator());
309  RenderTarget render_target = render_target_allocator.CreateOffscreen(
310  *context, size, /*mip_count=*/1, "Golden Render Pass",
312  /*stencil_attachment_config=*/std::nullopt);
313  if (!render_target.IsValid()) {
314  return false;
315  }
316  std::shared_ptr<CommandBuffer> command_buffer =
317  context->CreateCommandBuffer();
318  if (!command_buffer) {
319  return false;
320  }
321  std::shared_ptr<RenderPass> render_pass =
322  command_buffer->CreateRenderPass(render_target);
323  if (!render_pass) {
324  return false;
325  }
326  if (!callback(*render_pass)) {
327  return false;
328  }
329  if (!render_pass->EncodeCommands()) {
330  return false;
331  }
332  if (!context->GetCommandQueue()->Submit({command_buffer}).ok()) {
333  return false;
334  }
335  screenshot = pimpl_->screenshotter->MakeScreenshot(
336  renderer, render_target.GetRenderTargetTexture());
337  }
338  return SaveScreenshot(std::move(screenshot));
339 }
static constexpr AttachmentConfig kDefaultColorAttachmentConfig
Definition: render_target.h:55
std::shared_ptr< ContextGLES > context
std::shared_ptr< RenderPass > render_pass
std::shared_ptr< CommandBuffer > command_buffer

References command_buffer, context, impeller::RenderTargetAllocator::CreateOffscreen(), GetContext(), impeller::RenderTarget::GetRenderTargetTexture(), impeller::RenderTarget::IsValid(), impeller::RenderTarget::kDefaultColorAttachmentConfig, render_pass, SaveScreenshot(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ OpenPlaygroundHere() [4/5]

bool impeller::GoldenPlaygroundTest::OpenPlaygroundHere ( const sk_sp< flutter::DisplayList > &  list)

Definition at line 289 of file golden_playground_test_mac.cc.

290  {
291  return OpenPlaygroundHere([&list]() { return list; });
292 }
bool OpenPlaygroundHere(Picture picture)

References OpenPlaygroundHere().

◆ OpenPlaygroundHere() [5/5]

bool impeller::GoldenPlaygroundTest::OpenPlaygroundHere ( Picture  picture)

Referenced by OpenPlaygroundHere().

◆ PlatformSupportsWideGamutTests()

bool impeller::GoldenPlaygroundTest::PlatformSupportsWideGamutTests ( ) const
protected

Definition at line 187 of file golden_playground_test_mac.cc.

187  {
188  return DoesSupportWideGamutTests() && GetParam() == PlaygroundBackend::kMetal;
189 }

References impeller::kMetal.

◆ SaveScreenshot()

bool impeller::GoldenPlaygroundTest::SaveScreenshot ( std::unique_ptr< testing::Screenshot >  screenshot,
const std::string &  postfix = "" 
)
static

Definition at line 131 of file golden_playground_test_mac.cc.

133  {
134  if (!screenshot || !screenshot->GetBytes()) {
135  FML_LOG(ERROR) << "Failed to collect screenshot for test " << GetTestName();
136  return false;
137  }
138  std::string test_name = GetTestName();
139  std::string filename = GetGoldenFilename(postfix);
141  test_name, filename, screenshot->GetWidth(), screenshot->GetHeight());
142  if (!screenshot->WriteToPNG(
144  FML_LOG(ERROR) << "Failed to write screenshot to " << filename;
145  return false;
146  }
147  return true;
148 }
static GoldenDigest * Instance()
void AddImage(const std::string &test_name, const std::string &filename, int32_t width, int32_t height)
std::string GetFilenamePath(const std::string &filename) const
static WorkingDirectory * Instance()

References impeller::testing::GoldenDigest::AddImage(), impeller::testing::WorkingDirectory::GetFilenamePath(), impeller::testing::GoldenDigest::Instance(), and impeller::testing::WorkingDirectory::Instance().

Referenced by OpenPlaygroundHere().

◆ SetCapabilities()

fml::Status impeller::GoldenPlaygroundTest::SetCapabilities ( const std::shared_ptr< Capabilities > &  capabilities)

Definition at line 434 of file golden_playground_test_mac.cc.

435  {
436  return pimpl_->screenshotter->GetPlayground().SetCapabilities(capabilities);
437 }

◆ SetTypographerContext()

void impeller::GoldenPlaygroundTest::SetTypographerContext ( std::shared_ptr< TypographerContext >  typographer_context)

Definition at line 163 of file golden_playground_test_mac.cc.

164  {
165  typographer_context_ = std::move(typographer_context);
166 };

◆ SetUp()

void impeller::GoldenPlaygroundTest::SetUp ( )

Definition at line 191 of file golden_playground_test_mac.cc.

191  {
192  std::filesystem::path testing_assets_path =
193  flutter::testing::GetTestingAssetsPath();
194  std::filesystem::path target_path = testing_assets_path.parent_path()
195  .parent_path()
196  .parent_path()
197  .parent_path();
198  std::filesystem::path icd_path = target_path / "vk_swiftshader_icd.json";
199  setenv("VK_ICD_FILENAMES", icd_path.c_str(), 1);
200 
201  std::string test_name = GetTestName();
202  PlaygroundSwitches switches;
203  switches.enable_wide_gamut =
204  test_name.find("WideGamut_") != std::string::npos;
205  switches.flags.antialiased_lines =
206  test_name.find("ExperimentAntialiasLines_") != std::string::npos;
207  switch (GetParam()) {
209  switches.flags.use_sdfs = true;
210  [[fallthrough]];
212  if (!DoesSupportWideGamutTests()) {
213  GTEST_SKIP()
214  << "This metal device doesn't support wide gamut golden tests.";
215  }
216  pimpl_->screenshotter =
217  std::make_unique<testing::MetalScreenshotter>(switches);
218  break;
220  if (switches.enable_wide_gamut) {
221  GTEST_SKIP() << "Vulkan doesn't support wide gamut golden tests.";
222  }
223  if (switches.flags.antialiased_lines) {
224  GTEST_SKIP()
225  << "Vulkan doesn't support antialiased lines golden tests.";
226  }
227  const std::unique_ptr<PlaygroundImpl>& playground =
228  GetSharedVulkanPlayground(/*enable_validations=*/true);
229  pimpl_->screenshotter =
230  std::make_unique<testing::VulkanScreenshotter>(playground);
231  break;
232  }
234  switches.flags.use_sdfs = true;
235  [[fallthrough]];
237  if (switches.enable_wide_gamut) {
238  GTEST_SKIP() << "OpenGLES doesn't support wide gamut golden tests.";
239  }
240  if (switches.flags.antialiased_lines) {
241  GTEST_SKIP()
242  << "OpenGLES doesn't support antialiased lines golden tests.";
243  }
244  const std::unique_ptr<PlaygroundImpl>& playground =
245  GetSharedOpenGLESPlayground(switches.flags.use_sdfs);
246  ::glfwMakeContextCurrent(
247  reinterpret_cast<GLFWwindow*>(playground->GetWindowHandle()));
248  pimpl_->screenshotter =
249  std::make_unique<testing::VulkanScreenshotter>(playground);
250  break;
251  }
252  }
253 
254  if (std::find(kSkipTests.begin(), kSkipTests.end(), test_name) !=
255  kSkipTests.end()) {
256  GTEST_SKIP()
257  << "GoldenPlaygroundTest doesn't support interactive playground tests "
258  "yet.";
259  }
260 
262  "gpu_string", GetContext()->DescribeGpuModel());
263 }
void AddDimension(const std::string &name, const std::string &value)
static const std::vector< std::string > kSkipTests

References impeller::testing::GoldenDigest::AddDimension(), impeller::Flags::antialiased_lines, impeller::PlaygroundSwitches::enable_wide_gamut, impeller::PlaygroundSwitches::flags, GetContext(), impeller::testing::GoldenDigest::Instance(), impeller::kMetal, impeller::kMetalSDF, impeller::kOpenGLES, impeller::kOpenGLESSDF, impeller::kSkipTests, impeller::kVulkan, and impeller::Flags::use_sdfs.

◆ SetWindowSize()

void impeller::GoldenPlaygroundTest::SetWindowSize ( ISize  size)
protected

Definition at line 80 of file golden_playground_test_stub.cc.

80 {}

◆ TearDown()

void impeller::GoldenPlaygroundTest::TearDown ( )

Definition at line 168 of file golden_playground_test_mac.cc.

168  {
169  ASSERT_FALSE(dlopen("/usr/local/lib/libMoltenVK.dylib", RTLD_NOLOAD));
170 
171  auto context = GetContext();
172  if (context) {
173  context->DisposeThreadLocalCachedResources();
174  }
175 }

References context, and GetContext().

◆ WillRenderSomething()

bool impeller::GoldenPlaygroundTest::WillRenderSomething ( ) const
inline

Returns true if OpenPlaygroundHere will actually render anything.

Definition at line 103 of file golden_playground_test.h.

103 { return true; }

The documentation for this class was generated from the following files: