Flutter Engine
The Flutter Engine
Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
impeller::Playground Class Referenceabstract

#include <playground.h>

Inheritance diagram for impeller::Playground:
impeller::ComputePlaygroundTest impeller::PlaygroundTest impeller::AiksPlayground impeller::DlPlayground impeller::EntityPlayground impeller::RuntimeStagePlayground impeller::testing::RendererDartTest impeller::testing::BlendFilterContentsTest impeller::testing::GaussianBlurFilterContentsTest impeller::testing::MatrixFilterContentsTest

Public Types

using SinglePassCallback = std::function< bool(RenderPass &pass)>
 

Public Member Functions

 Playground (PlaygroundSwitches switches)
 
virtual ~Playground ()
 
void SetupContext (PlaygroundBackend backend, const PlaygroundSwitches &switches)
 
void SetupWindow ()
 
void TeardownWindow ()
 
bool IsPlaygroundEnabled () const
 
Point GetCursorPosition () const
 
ISize GetWindowSize () const
 
Point GetContentScale () const
 
Scalar GetSecondsElapsed () const
 Get the amount of time elapsed from the start of the playground's execution. More...
 
std::shared_ptr< ContextGetContext () const
 
std::shared_ptr< ContextMakeContext () const
 
bool OpenPlaygroundHere (const Renderer::RenderCallback &render_callback)
 
bool OpenPlaygroundHere (SinglePassCallback pass_callback)
 
std::shared_ptr< TextureCreateTextureForFixture (const char *fixture_name, bool enable_mipmapping=false) const
 
std::shared_ptr< TextureCreateTextureCubeForFixture (std::array< const char *, 6 > fixture_names) const
 
virtual std::unique_ptr< fml::MappingOpenAssetAsMapping (std::string asset_name) const =0
 
virtual std::string GetWindowTitle () const =0
 
fml::Status SetCapabilities (const std::shared_ptr< Capabilities > &capabilities)
 
bool WillRenderSomething () const
 

Static Public Member Functions

static bool ShouldOpenNewPlaygrounds ()
 
static std::shared_ptr< CompressedImageLoadFixtureImageCompressed (std::shared_ptr< fml::Mapping > mapping)
 
static std::optional< DecompressedImageDecodeImageRGBA (const std::shared_ptr< CompressedImage > &compressed)
 
static std::shared_ptr< TextureCreateTextureForMapping (const std::shared_ptr< Context > &context, std::shared_ptr< fml::Mapping > mapping, bool enable_mipmapping=false)
 
static bool SupportsBackend (PlaygroundBackend backend)
 

Protected Member Functions

virtual bool ShouldKeepRendering () const
 
void SetWindowSize (ISize size)
 

Protected Attributes

const PlaygroundSwitches switches_
 

Detailed Description

Definition at line 48 of file playground.h.

Member Typedef Documentation

◆ SinglePassCallback

Definition at line 50 of file playground.h.

Constructor & Destructor Documentation

◆ Playground()

impeller::Playground::Playground ( PlaygroundSwitches  switches)
explicit

Definition at line 83 of file playground.cc.

83 : switches_(switches) {
86}
const PlaygroundSwitches switches_
Definition: playground.h:118
static void InitializeGLFWOnce()
Definition: playground.cc:57
void SetupSwiftshaderOnce(bool use_swiftshader)
Find and setup the installable client driver for a locally built SwiftShader at known paths....

◆ ~Playground()

impeller::Playground::~Playground ( )
virtualdefault

Member Function Documentation

◆ CreateTextureCubeForFixture()

std::shared_ptr< Texture > impeller::Playground::CreateTextureCubeForFixture ( std::array< const char *, 6 >  fixture_names) const

Definition at line 467 of file playground.cc.

468 {
469 std::array<DecompressedImage, 6> images;
470 for (size_t i = 0; i < fixture_names.size(); i++) {
471 auto image = DecodeImageRGBA(
473 if (!image.has_value()) {
474 return nullptr;
475 }
476 images[i] = image.value();
477 }
478
479 auto texture_descriptor = TextureDescriptor{};
480 texture_descriptor.storage_mode = StorageMode::kHostVisible;
481 texture_descriptor.type = TextureType::kTextureCube;
482 texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
483 texture_descriptor.size = images[0].GetSize();
484 texture_descriptor.mip_count = 1u;
485
486 auto texture = renderer_->GetContext()->GetResourceAllocator()->CreateTexture(
487 texture_descriptor);
488 if (!texture) {
489 VALIDATION_LOG << "Could not allocate texture cube.";
490 return nullptr;
491 }
492 texture->SetLabel("Texture cube");
493
494 auto cmd_buffer = renderer_->GetContext()->CreateCommandBuffer();
495 auto blit_pass = cmd_buffer->CreateBlitPass();
496 for (size_t i = 0; i < fixture_names.size(); i++) {
497 auto device_buffer =
498 renderer_->GetContext()->GetResourceAllocator()->CreateBufferWithCopy(
499 *images[i].GetAllocation());
500 blit_pass->AddCopy(DeviceBuffer::AsBufferView(device_buffer), texture, {},
501 "", /*slice=*/i);
502 }
503
504 if (!blit_pass->EncodeCommands(
505 renderer_->GetContext()->GetResourceAllocator()) ||
506 !renderer_->GetContext()
507 ->GetCommandQueue()
508 ->Submit({std::move(cmd_buffer)})
509 .ok()) {
510 VALIDATION_LOG << "Could not upload texture to device memory.";
511 return nullptr;
512 }
513
514 return texture;
515}
static BufferView AsBufferView(std::shared_ptr< DeviceBuffer > buffer)
Create a buffer view of this entire buffer.
static std::shared_ptr< CompressedImage > LoadFixtureImageCompressed(std::shared_ptr< fml::Mapping > mapping)
Definition: playground.cc:369
virtual std::unique_ptr< fml::Mapping > OpenAssetAsMapping(std::string asset_name) const =0
static std::optional< DecompressedImage > DecodeImageRGBA(const std::shared_ptr< CompressedImage > &compressed)
Definition: playground.cc:380
FlTexture * texture
std::array< MockImage, 3 > images
Definition: mock_vulkan.cc:41
sk_sp< const SkImage > image
Definition: SkRecords.h:269
#define VALIDATION_LOG
Definition: validation.h:73

◆ CreateTextureForFixture()

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

Definition at line 454 of file playground.cc.

456 {
457 auto texture = CreateTextureForMapping(renderer_->GetContext(),
458 OpenAssetAsMapping(fixture_name),
459 enable_mipmapping);
460 if (texture == nullptr) {
461 return nullptr;
462 }
463 texture->SetLabel(fixture_name);
464 return texture;
465}
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:441

◆ CreateTextureForMapping()

std::shared_ptr< Texture > impeller::Playground::CreateTextureForMapping ( const std::shared_ptr< Context > &  context,
std::shared_ptr< fml::Mapping mapping,
bool  enable_mipmapping = false 
)
static

Definition at line 441 of file playground.cc.

444 {
446 Playground::LoadFixtureImageCompressed(std::move(mapping)));
447 if (!image.has_value()) {
448 return nullptr;
449 }
450 return CreateTextureForDecompressedImage(context, image.value(),
451 enable_mipmapping);
452}
static std::shared_ptr< Texture > CreateTextureForDecompressedImage(const std::shared_ptr< Context > &context, DecompressedImage &decompressed_image, bool enable_mipmapping)
Definition: playground.cc:399

◆ DecodeImageRGBA()

std::optional< DecompressedImage > impeller::Playground::DecodeImageRGBA ( const std::shared_ptr< CompressedImage > &  compressed)
static

Definition at line 380 of file playground.cc.

381 {
382 if (compressed == nullptr) {
383 return std::nullopt;
384 }
385 // The decoded image is immediately converted into RGBA as that format is
386 // known to be supported everywhere. For image sources that don't need 32
387 // bit pixel strides, this is overkill. Since this is a test fixture we
388 // aren't necessarily trying to eke out memory savings here and instead
389 // favor simplicity.
390 auto image = compressed->Decode().ConvertToRGBA();
391 if (!image.IsValid()) {
392 VALIDATION_LOG << "Could not decode image.";
393 return std::nullopt;
394 }
395
396 return image;
397}

◆ GetContentScale()

Point impeller::Playground::GetContentScale ( ) const

Definition at line 192 of file playground.cc.

192 {
193 return impl_->GetContentScale();
194}

◆ GetContext()

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

Definition at line 90 of file playground.cc.

90 {
91 return context_;
92}

◆ GetCursorPosition()

Point impeller::Playground::GetCursorPosition ( ) const

Definition at line 184 of file playground.cc.

184 {
185 return cursor_position_;
186}

◆ GetSecondsElapsed()

Scalar impeller::Playground::GetSecondsElapsed ( ) const

Get the amount of time elapsed from the start of the playground's execution.

Definition at line 196 of file playground.cc.

196 {
197 return (fml::TimePoint::Now().ToEpochDelta() - start_time_).ToSecondsF();
198}
static TimePoint Now()
Definition: time_point.cc:49

◆ GetWindowSize()

ISize impeller::Playground::GetWindowSize ( ) const

Definition at line 188 of file playground.cc.

188 {
189 return window_size_;
190}

◆ GetWindowTitle()

virtual std::string impeller::Playground::GetWindowTitle ( ) const
pure virtual

◆ IsPlaygroundEnabled()

bool impeller::Playground::IsPlaygroundEnabled ( ) const

Definition at line 152 of file playground.cc.

152 {
154}

◆ LoadFixtureImageCompressed()

std::shared_ptr< CompressedImage > impeller::Playground::LoadFixtureImageCompressed ( std::shared_ptr< fml::Mapping mapping)
static

Definition at line 369 of file playground.cc.

370 {
371 auto compressed_image = CompressedImageSkia::Create(std::move(mapping));
372 if (!compressed_image) {
373 VALIDATION_LOG << "Could not create compressed image.";
374 return nullptr;
375 }
376
377 return compressed_image;
378}
static std::shared_ptr< CompressedImage > Create(std::shared_ptr< const fml::Mapping > allocation)

◆ MakeContext()

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

Definition at line 94 of file playground.cc.

94 {
95 // Playgrounds are already making a context for each test, so we can just
96 // return the `context_`.
97 return context_;
98}

◆ OpenAssetAsMapping()

virtual std::unique_ptr< fml::Mapping > impeller::Playground::OpenAssetAsMapping ( std::string  asset_name) const
pure virtual

◆ OpenPlaygroundHere() [1/2]

bool impeller::Playground::OpenPlaygroundHere ( const Renderer::RenderCallback render_callback)

Definition at line 204 of file playground.cc.

205 {
207 return true;
208 }
209
210 if (!render_callback) {
211 return true;
212 }
213
214 if (!renderer_ || !renderer_->IsValid()) {
215 return false;
216 }
217
218 IMGUI_CHECKVERSION();
220 fml::ScopedCleanupClosure destroy_imgui_context(
221 []() { ImGui::DestroyContext(); });
222 ImGui::StyleColorsDark();
223
224 auto& io = ImGui::GetIO();
225 io.IniFilename = nullptr;
226 io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
227 io.ConfigWindowsResizeFromEdges = true;
228
229 auto window = reinterpret_cast<GLFWwindow*>(impl_->GetWindowHandle());
230 if (!window) {
231 return false;
232 }
233 ::glfwSetWindowTitle(window, GetWindowTitle().c_str());
234 ::glfwSetWindowUserPointer(window, this);
235 ::glfwSetWindowSizeCallback(
236 window, [](GLFWwindow* window, int width, int height) -> void {
237 auto playground =
238 reinterpret_cast<Playground*>(::glfwGetWindowUserPointer(window));
239 if (!playground) {
240 return;
241 }
242 playground->SetWindowSize(ISize{width, height}.Max({}));
243 });
244 ::glfwSetKeyCallback(window, &PlaygroundKeyCallback);
245 ::glfwSetCursorPosCallback(window, [](GLFWwindow* window, double x,
246 double y) {
247 reinterpret_cast<Playground*>(::glfwGetWindowUserPointer(window))
248 ->SetCursorPosition({static_cast<Scalar>(x), static_cast<Scalar>(y)});
249 });
250
251 ImGui_ImplGlfw_InitForOther(window, true);
252 fml::ScopedCleanupClosure shutdown_imgui([]() { ImGui_ImplGlfw_Shutdown(); });
253
254 ImGui_ImplImpeller_Init(renderer_->GetContext());
255 fml::ScopedCleanupClosure shutdown_imgui_impeller(
256 []() { ImGui_ImplImpeller_Shutdown(); });
257
258 ImGui::SetNextWindowPos({10, 10});
259
260 ::glfwSetWindowSize(window, GetWindowSize().width, GetWindowSize().height);
261 ::glfwSetWindowPos(window, 200, 100);
262 ::glfwShowWindow(window);
263
264 while (true) {
265#if FML_OS_MACOSX
267#endif
268 ::glfwPollEvents();
269
270 if (::glfwWindowShouldClose(window)) {
271 return true;
272 }
273
274 ImGui_ImplGlfw_NewFrame();
275
276 Renderer::RenderCallback wrapped_callback =
277 [render_callback,
278 &renderer = renderer_](RenderTarget& render_target) -> bool {
279 ImGui::NewFrame();
280 ImGui::DockSpaceOverViewport(ImGui::GetMainViewport(),
281 ImGuiDockNodeFlags_PassthruCentralNode);
282 bool result = render_callback(render_target);
283 ImGui::Render();
284
285 // Render ImGui overlay.
286 {
287 auto buffer = renderer->GetContext()->CreateCommandBuffer();
288 if (!buffer) {
289 return false;
290 }
291 buffer->SetLabel("ImGui Command Buffer");
292
293 if (render_target.GetColorAttachments().empty()) {
294 return false;
295 }
296
297 auto color0 = render_target.GetColorAttachments().find(0)->second;
298 color0.load_action = LoadAction::kLoad;
299 if (color0.resolve_texture) {
300 color0.texture = color0.resolve_texture;
301 color0.resolve_texture = nullptr;
302 color0.store_action = StoreAction::kStore;
303 }
304 render_target.SetColorAttachment(color0, 0);
305
306 render_target.SetStencilAttachment(std::nullopt);
307 render_target.SetDepthAttachment(std::nullopt);
308
309 auto pass = buffer->CreateRenderPass(render_target);
310 if (!pass) {
311 return false;
312 }
313 pass->SetLabel("ImGui Render Pass");
314
315 ImGui_ImplImpeller_RenderDrawData(ImGui::GetDrawData(), *pass);
316
317 pass->EncodeCommands();
318 if (!renderer->GetContext()->GetCommandQueue()->Submit({buffer}).ok()) {
319 return false;
320 }
321 }
322
323 return result;
324 };
325
326 if (!renderer_->Render(impl_->AcquireSurfaceFrame(renderer_->GetContext()),
327 wrapped_callback)) {
328 VALIDATION_LOG << "Could not render into the surface.";
329 return false;
330 }
331
332 if (!ShouldKeepRendering()) {
333 break;
334 }
335 }
336
337 ::glfwHideWindow(window);
338
339 return true;
340}
AutoreleasePool pool
Wraps a closure that is invoked in the destructor unless released by the caller.
Definition: closure.h:32
Playground(PlaygroundSwitches switches)
Definition: playground.cc:83
virtual bool ShouldKeepRendering() const
Definition: playground.cc:521
ISize GetWindowSize() const
Definition: playground.cc:188
virtual std::string GetWindowTitle() const =0
std::function< bool(RenderTarget &render_target)> RenderCallback
Definition: renderer.h:23
GLFWwindow * window
Definition: main.cc:45
GAsyncResult * result
bool ImGui_ImplImpeller_Init(const std::shared_ptr< impeller::Context > &context)
void ImGui_ImplImpeller_RenderDrawData(ImDrawData *draw_data, impeller::RenderPass &render_pass)
void ImGui_ImplImpeller_Shutdown()
double y
double x
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
static EGLResult< EGLContext > CreateContext(EGLDisplay display, EGLConfig config, EGLContext share=EGL_NO_CONTEXT)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
float Scalar
Definition: scalar.h:18
static void PlaygroundKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
Definition: playground.cc:171
ISize64 ISize
Definition: size.h:140
int32_t height
int32_t width

◆ OpenPlaygroundHere() [2/2]

bool impeller::Playground::OpenPlaygroundHere ( SinglePassCallback  pass_callback)

Definition at line 342 of file playground.cc.

342 {
343 return OpenPlaygroundHere(
344 [context = GetContext(), &pass_callback](RenderTarget& render_target) {
345 auto buffer = context->CreateCommandBuffer();
346 if (!buffer) {
347 return false;
348 }
349 buffer->SetLabel("Playground Command Buffer");
350
351 auto pass = buffer->CreateRenderPass(render_target);
352 if (!pass) {
353 return false;
354 }
355 pass->SetLabel("Playground Render Pass");
356
357 if (!pass_callback(*pass)) {
358 return false;
359 }
360
361 pass->EncodeCommands();
362 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
363 return false;
364 }
365 return true;
366 });
367}
std::shared_ptr< Context > GetContext() const
Definition: playground.cc:90
bool OpenPlaygroundHere(const Renderer::RenderCallback &render_callback)
Definition: playground.cc:204

◆ SetCapabilities()

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

Definition at line 525 of file playground.cc.

526 {
527 return impl_->SetCapabilities(capabilities);
528}

◆ SetupContext()

void impeller::Playground::SetupContext ( PlaygroundBackend  backend,
const PlaygroundSwitches switches 
)

Definition at line 124 of file playground.cc.

125 {
127
128 impl_ = PlaygroundImpl::Create(backend, switches);
129 if (!impl_) {
130 FML_LOG(WARNING) << "PlaygroundImpl::Create failed.";
131 return;
132 }
133
134 context_ = impl_->GetContext();
135}
const char * backend
static std::unique_ptr< PlaygroundImpl > Create(PlaygroundBackend backend, PlaygroundSwitches switches)
static bool SupportsBackend(PlaygroundBackend backend)
Definition: playground.cc:100
#define FML_LOG(severity)
Definition: logging.h:82
#define FML_CHECK(condition)
Definition: logging.h:85

◆ SetupWindow()

void impeller::Playground::SetupWindow ( )

Definition at line 137 of file playground.cc.

137 {
138 if (!context_) {
139 FML_LOG(WARNING) << "Asked to set up a window with no context (call "
140 "SetupContext first).";
141 return;
142 }
143 auto renderer = std::make_unique<Renderer>(context_);
144 if (!renderer->IsValid()) {
145 return;
146 }
147 renderer_ = std::move(renderer);
148
149 start_time_ = fml::TimePoint::Now().ToEpochDelta();
150}
TimeDelta ToEpochDelta() const
Definition: time_point.h:52

◆ SetWindowSize()

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

Definition at line 517 of file playground.cc.

517 {
518 window_size_ = size;
519}
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259

◆ ShouldKeepRendering()

bool impeller::Playground::ShouldKeepRendering ( ) const
protectedvirtual

Definition at line 521 of file playground.cc.

521 {
522 return true;
523}

◆ ShouldOpenNewPlaygrounds()

bool impeller::Playground::ShouldOpenNewPlaygrounds ( )
static

Definition at line 167 of file playground.cc.

167 {
169}
static std::atomic_bool gShouldOpenNewPlaygrounds
Definition: playground.cc:165

◆ SupportsBackend()

bool impeller::Playground::SupportsBackend ( PlaygroundBackend  backend)
static

Definition at line 100 of file playground.cc.

100 {
101 switch (backend) {
103#if IMPELLER_ENABLE_METAL
104 return true;
105#else // IMPELLER_ENABLE_METAL
106 return false;
107#endif // IMPELLER_ENABLE_METAL
109#if IMPELLER_ENABLE_OPENGLES
110 return true;
111#else // IMPELLER_ENABLE_OPENGLES
112 return false;
113#endif // IMPELLER_ENABLE_OPENGLES
115#if IMPELLER_ENABLE_VULKAN
117#else // IMPELLER_ENABLE_VULKAN
118 return false;
119#endif // IMPELLER_ENABLE_VULKAN
120 }
122}
#define FML_UNREACHABLE()
Definition: logging.h:109

◆ TeardownWindow()

void impeller::Playground::TeardownWindow ( )

Definition at line 156 of file playground.cc.

156 {
157 if (context_) {
158 context_->Shutdown();
159 }
160 context_.reset();
161 renderer_.reset();
162 impl_.reset();
163}

◆ WillRenderSomething()

bool impeller::Playground::WillRenderSomething ( ) const

TODO(https://github.com/flutter/flutter/issues/139950): Remove this. Returns true if OpenPlaygroundHere will actually render anything.

Definition at line 530 of file playground.cc.

530 {
532}

Member Data Documentation

◆ switches_

const PlaygroundSwitches impeller::Playground::switches_
protected

Definition at line 118 of file playground.h.


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