5 #define FML_USED_ON_EMBEDDER
9 #include "flutter/common/settings.h"
10 #include "flutter/common/task_runners.h"
11 #include "flutter/lib/gpu/context.h"
12 #include "flutter/lib/gpu/shader_library.h"
13 #include "flutter/lib/gpu/texture.h"
14 #include "flutter/runtime/dart_isolate.h"
15 #include "flutter/runtime/dart_vm_lifecycle.h"
16 #include "flutter/testing/dart_fixture.h"
17 #include "flutter/testing/dart_isolate_runner.h"
18 #include "flutter/testing/test_dart_native_resolver.h"
19 #include "flutter/testing/testing.h"
20 #include "fml/memory/ref_ptr.h"
21 #include "impeller/fixtures/texture.frag.h"
22 #include "impeller/fixtures/texture.vert.h"
28 #include "gtest/gtest.h"
29 #include "third_party/imgui/imgui.h"
30 #include "third_party/tonic/dart_microtask_queue.h"
37 flutter::testing::OpenFixtureAsMapping(
"playground.shaderbundle");
38 auto library = flutter::gpu::ShaderLibrary::MakeFromFlatbuffer(
39 backend_type, std::move(fixture));
40 flutter::gpu::ShaderLibrary::SetOverride(library);
49 auto* queue = tonic::DartMicrotaskQueue::GetForCurrentThread();
50 if (queue ==
nullptr) {
53 queue->RunMicrotasks();
54 return queue->GetLastError() == tonic::kNoError;
58 public flutter::testing::DartFixture {
61 : settings_(CreateSettingsForFixture()),
63 fml::MessageLoop::EnsureInitializedForCurrentThread();
65 current_task_runner_ = fml::MessageLoop::GetCurrent().GetTaskRunner();
67 isolate_ = CreateDartIsolate();
69 assert(isolate_->get()->GetPhase() == flutter::DartIsolate::Phase::Running);
77 auto set_display_texture = [
this](Dart_NativeArguments args) {
78 flutter::gpu::Texture* texture =
79 tonic::DartConverter<flutter::gpu::Texture*>::FromDart(
80 Dart_GetNativeArgument(args, 0));
81 assert(texture !=
nullptr);
82 received_texture_ = texture->GetTexture();
84 AddNativeCallback(
"SetDisplayTexture",
85 CREATE_NATIVE_ENTRY(set_display_texture));
92 flutter::gpu::Context::SetOverrideContext(
GetContext());
96 return isolate_.get();
102 const char* dart_function_name) {
104 GetIsolate()->RunInIsolateScope([
this, &dart_function_name]() ->
bool {
107 if (tonic::CheckAndHandleError(
108 ::Dart_Invoke(Dart_RootLibrary(),
109 tonic::ToDart(dart_function_name), 2, args))) {
115 FML_LOG(ERROR) <<
"Failed to invoke dart test function:"
116 << dart_function_name;
119 if (!received_texture_) {
120 FML_LOG(ERROR) <<
"Dart test function `" << dart_function_name
121 <<
"` did not invoke `drawToPlaygroundSurface`.";
124 return received_texture_;
132 return GetIsolate()->RunInIsolateScope([&dart_function_name]() ->
bool {
133 if (tonic::CheckAndHandleError(
134 ::Dart_Invoke(Dart_RootLibrary(),
135 tonic::ToDart(dart_function_name), 0,
nullptr))) {
149 [
this, &dart_function_name]() ->
bool {
152 if (tonic::CheckAndHandleError(
153 ::Dart_Invoke(Dart_RootLibrary(),
154 tonic::ToDart(dart_function_name), 2, args))) {
180 using TextureVS = TextureVertexShader;
181 using TextureFS = TextureFragmentShader;
185 TexturePipelineBuilder::MakeDefaultPipelineDescriptor(*
context);
186 if (!pipeline_desc.has_value()) {
187 FML_LOG(ERROR) <<
"Failed to create default pipeline descriptor.";
191 pipeline_desc->SetStencilAttachmentDescriptors(std::nullopt);
192 pipeline_desc->SetDepthStencilAttachmentDescriptor(std::nullopt);
197 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
199 FML_LOG(ERROR) <<
"Failed to create default pipeline.";
213 {{-0.5, -0.5, 0.0}, {0.0, 0.0}},
214 {{ 0.5, -0.5, 0.0}, {1.0, 0.0}},
215 {{ 0.5, 0.5, 0.0}, {1.0, 1.0}},
216 {{-0.5, -0.5, 0.0}, {0.0, 0.0}},
217 {{ 0.5, 0.5, 0.0}, {1.0, 1.0}},
218 {{-0.5, 0.5, 0.0}, {0.0, 1.0}},
226 const auto& sampler =
context->GetSamplerLibrary()->GetSampler({});
228 FML_LOG(ERROR) <<
"Failed to create default sampler.";
244 context->GetCapabilities()->GetMinimumUniformAlignment());
247 *
context->GetResourceAllocator()));
249 TextureVS::UniformBuffer uniforms;
251 TextureVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
252 TextureFS::BindTextureContents(pass, texture, sampler);
256 if (!pass.Draw().ok()) {
265 std::unique_ptr<flutter::testing::AutoIsolateShutdown> CreateDartIsolate() {
266 const auto settings = CreateSettingsForFixture();
267 flutter::TaskRunners task_runners(flutter::testing::GetCurrentTestName(),
268 current_task_runner_,
269 current_task_runner_,
270 current_task_runner_,
273 return flutter::testing::RunDartCodeInIsolate(
274 vm_ref_, settings, task_runners,
"main", {},
275 flutter::testing::GetDefaultKernelFilePath());
278 const flutter::Settings settings_;
279 flutter::DartVMRef vm_ref_;
280 fml::RefPtr<fml::TaskRunner> current_task_runner_;
281 std::unique_ptr<flutter::testing::AutoIsolateShutdown> isolate_;
283 std::shared_ptr<Texture> received_texture_;
289 SinglePassCallback callback = [&](
RenderPass& pass) {
290 ImGui::Begin(
"Dart test",
nullptr);
292 "This test executes Dart code during the playground frame callback.");
295 return RunDartFunction(
"sayHi");
297 ASSERT_TRUE(OpenPlaygroundHere(callback));
304 ASSERT_TRUE(RunDartFunction(
"instantiateDefaultContext"));
308 ASSERT_TRUE(RunDartFunction(
"canCreateShaderLibrary"));
312 ASSERT_TRUE(RunDartFunction(
"canReflectUniformStructs"));
316 ASSERT_TRUE(RenderDartToPlayground(
"canCreateRenderPassAndSubmit"));
static std::shared_ptr< HostBuffer > Create(const std::shared_ptr< Allocator > &allocator, const std::shared_ptr< const IdleWaiter > &idle_waiter, size_t minimum_uniform_alignment)
bool OpenPlaygroundHere(const RenderCallback &render_callback)
bool IsPlaygroundEnabled() const
ISize GetWindowSize() const
std::function< bool(RenderPass &pass)> SinglePassCallback
std::shared_ptr< Context > GetContext() const
Render passes encode render commands directed as one specific render target into an underlying comman...
VertexBuffer CreateVertexBuffer(HostBuffer &data_host_buffer, HostBuffer &indexes_host_buffer) const
VertexBufferBuilder & AddVertices(std::initializer_list< VertexType_ > vertices)
bool RunDartFunctionWithWindowSize(const char *dart_function_name)
Invokes a Dart function with the window's width and height as arguments.
std::shared_ptr< Texture > GetRenderedTextureFromDart(const char *dart_function_name)
Run a Dart function that's expected to create a texture and pass it back for rendering via drawToPlay...
bool RenderDartToPlayground(const char *dart_function_name)
Call a dart function that produces a texture and render the result in the playground.
bool RunDartFunction(const char *dart_function_name)
Invokes a Dart function.
flutter::testing::AutoIsolateShutdown * GetIsolate()
ScopedObject< Object > Create(CtorArgs &&... args)
static bool DrainMicrotasks()
static void InstantiateTestShaderLibrary(Context::BackendType backend_type)
TEST_P(AiksTest, DrawAtlasNoColor)
INSTANTIATE_PLAYGROUND_SUITE(AiksTest)
std::shared_ptr< ContextGLES > context
std::shared_ptr< PipelineGLES > pipeline
A 4x4 matrix using column-major storage.
An optional (but highly recommended) utility for creating pipelines from reflected shader information...