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"
36 flutter::testing::OpenFixtureAsMapping(
"playground.shaderbundle");
37 auto library = flutter::gpu::ShaderLibrary::MakeFromFlatbuffer(
38 backend_type, std::move(fixture));
39 flutter::gpu::ShaderLibrary::SetOverride(library);
43 public flutter::testing::DartFixture {
46 : settings_(CreateSettingsForFixture()),
48 fml::MessageLoop::EnsureInitializedForCurrentThread();
50 current_task_runner_ = fml::MessageLoop::GetCurrent().GetTaskRunner();
52 isolate_ = CreateDartIsolate();
54 assert(isolate_->get()->GetPhase() == flutter::DartIsolate::Phase::Running);
62 auto set_display_texture = [
this](Dart_NativeArguments args) {
63 flutter::gpu::Texture* texture =
64 tonic::DartConverter<flutter::gpu::Texture*>::FromDart(
65 Dart_GetNativeArgument(args, 0));
66 assert(texture !=
nullptr);
67 received_texture_ = texture->GetTexture();
69 AddNativeCallback(
"SetDisplayTexture",
70 CREATE_NATIVE_ENTRY(set_display_texture));
77 flutter::gpu::Context::SetOverrideContext(
GetContext());
81 return isolate_.get();
87 const char* dart_function_name) {
89 GetIsolate()->RunInIsolateScope([
this, &dart_function_name]() ->
bool {
92 if (tonic::CheckAndHandleError(
93 ::Dart_Invoke(Dart_RootLibrary(),
94 tonic::ToDart(dart_function_name), 2, args))) {
100 FML_LOG(ERROR) <<
"Failed to invoke dart test function:"
101 << dart_function_name;
104 if (!received_texture_) {
105 FML_LOG(ERROR) <<
"Dart test function `" << dart_function_name
106 <<
"` did not invoke `drawToPlaygroundSurface`.";
109 return received_texture_;
117 return GetIsolate()->RunInIsolateScope([&dart_function_name]() ->
bool {
118 if (tonic::CheckAndHandleError(
119 ::Dart_Invoke(Dart_RootLibrary(),
120 tonic::ToDart(dart_function_name), 0,
nullptr))) {
134 [
this, &dart_function_name]() ->
bool {
137 if (tonic::CheckAndHandleError(
138 ::Dart_Invoke(Dart_RootLibrary(),
139 tonic::ToDart(dart_function_name), 2, args))) {
159 assert(context !=
nullptr);
165 using TextureVS = TextureVertexShader;
166 using TextureFS = TextureFragmentShader;
170 TexturePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
171 if (!pipeline_desc.has_value()) {
172 FML_LOG(ERROR) <<
"Failed to create default pipeline descriptor.";
176 pipeline_desc->SetStencilAttachmentDescriptors(std::nullopt);
177 pipeline_desc->SetDepthStencilAttachmentDescriptor(std::nullopt);
182 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
183 if (!pipeline || !pipeline->IsValid()) {
184 FML_LOG(ERROR) <<
"Failed to create default pipeline.";
198 {{-0.5, -0.5, 0.0}, {0.0, 0.0}},
199 {{ 0.5, -0.5, 0.0}, {1.0, 0.0}},
200 {{ 0.5, 0.5, 0.0}, {1.0, 1.0}},
201 {{-0.5, -0.5, 0.0}, {0.0, 0.0}},
202 {{ 0.5, 0.5, 0.0}, {1.0, 1.0}},
203 {{-0.5, 0.5, 0.0}, {0.0, 1.0}},
211 const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
213 FML_LOG(ERROR) <<
"Failed to create default sampler.";
228 context->GetResourceAllocator(), context->GetIdleWaiter(),
229 context->GetCapabilities()->GetMinimumUniformAlignment());
232 *context->GetResourceAllocator()));
234 TextureVS::UniformBuffer uniforms;
236 TextureVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
237 TextureFS::BindTextureContents(pass, texture, sampler);
239 pass.SetPipeline(pipeline);
241 if (!pass.Draw().ok()) {
250 std::unique_ptr<flutter::testing::AutoIsolateShutdown> CreateDartIsolate() {
251 const auto settings = CreateSettingsForFixture();
252 flutter::TaskRunners task_runners(flutter::testing::GetCurrentTestName(),
253 current_task_runner_,
254 current_task_runner_,
255 current_task_runner_,
258 return flutter::testing::RunDartCodeInIsolate(
259 vm_ref_, settings, task_runners,
"main", {},
260 flutter::testing::GetDefaultKernelFilePath());
263 const flutter::Settings settings_;
264 flutter::DartVMRef vm_ref_;
265 fml::RefPtr<fml::TaskRunner> current_task_runner_;
266 std::unique_ptr<flutter::testing::AutoIsolateShutdown> isolate_;
268 std::shared_ptr<Texture> received_texture_;
274 SinglePassCallback callback = [&](
RenderPass& pass) {
275 ImGui::Begin(
"Dart test",
nullptr);
277 "This test executes Dart code during the playground frame callback.");
280 return RunDartFunction(
"sayHi");
282 ASSERT_TRUE(OpenPlaygroundHere(callback));
289 ASSERT_TRUE(RunDartFunction(
"instantiateDefaultContext"));
293 ASSERT_TRUE(RunDartFunction(
"canCreateShaderLibrary"));
297 ASSERT_TRUE(RunDartFunction(
"canReflectUniformStructs"));
301 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 &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 void InstantiateTestShaderLibrary(Context::BackendType backend_type)
TEST_P(AiksTest, DrawAtlasNoColor)
INSTANTIATE_PLAYGROUND_SUITE(AiksTest)
A 4x4 matrix using column-major storage.
An optional (but highly recommended) utility for creating pipelines from reflected shader information...