blob: ab69f921d96a58f41a9aef687855f481cefa22f5 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#define FML_USED_ON_EMBEDDER
#include <memory>
#include "flutter/common/settings.h"
#include "flutter/common/task_runners.h"
#include "flutter/lib/gpu/context.h"
#include "flutter/lib/gpu/shader_library.h"
#include "flutter/runtime/dart_isolate.h"
#include "flutter/runtime/dart_vm_lifecycle.h"
#include "flutter/testing/dart_fixture.h"
#include "flutter/testing/dart_isolate_runner.h"
#include "flutter/testing/testing.h"
#include "fml/memory/ref_ptr.h"
#include "impeller/playground/playground_test.h"
#include "impeller/renderer/render_pass.h"
#include "gtest/gtest.h"
#include "third_party/imgui/imgui.h"
namespace impeller {
namespace testing {
static void InstantiateTestShaderLibrary(Context::BackendType backend_type) {
auto fixture =
flutter::testing::OpenFixtureAsMapping("playground.shaderbundle");
auto library = flutter::gpu::ShaderLibrary::MakeFromFlatbuffer(
backend_type, std::move(fixture));
flutter::gpu::ShaderLibrary::SetOverride(library);
}
class RendererDartTest : public PlaygroundTest,
public flutter::testing::DartFixture {
public:
RendererDartTest()
: settings_(CreateSettingsForFixture()),
vm_ref_(flutter::DartVMRef::Create(settings_)) {
fml::MessageLoop::EnsureInitializedForCurrentThread();
current_task_runner_ = fml::MessageLoop::GetCurrent().GetTaskRunner();
isolate_ = CreateDartIsolate();
assert(isolate_);
assert(isolate_->get()->GetPhase() == flutter::DartIsolate::Phase::Running);
}
flutter::testing::AutoIsolateShutdown* GetIsolate() {
// Sneak the context into the Flutter GPU API.
assert(GetContext() != nullptr);
flutter::gpu::Context::SetOverrideContext(GetContext());
InstantiateTestShaderLibrary(GetContext()->GetBackendType());
return isolate_.get();
}
private:
std::unique_ptr<flutter::testing::AutoIsolateShutdown> CreateDartIsolate() {
const auto settings = CreateSettingsForFixture();
flutter::TaskRunners task_runners(flutter::testing::GetCurrentTestName(),
current_task_runner_, //
current_task_runner_, //
current_task_runner_, //
current_task_runner_ //
);
return flutter::testing::RunDartCodeInIsolate(
vm_ref_, settings, task_runners, "main", {},
flutter::testing::GetDefaultKernelFilePath());
}
const flutter::Settings settings_;
flutter::DartVMRef vm_ref_;
fml::RefPtr<fml::TaskRunner> current_task_runner_;
std::unique_ptr<flutter::testing::AutoIsolateShutdown> isolate_;
};
INSTANTIATE_PLAYGROUND_SUITE(RendererDartTest);
TEST_P(RendererDartTest, CanRunDartInPlaygroundFrame) {
auto isolate = GetIsolate();
SinglePassCallback callback = [&](RenderPass& pass) {
ImGui::Begin("Dart test", nullptr);
ImGui::Text(
"This test executes Dart code during the playground frame callback.");
ImGui::End();
return isolate->RunInIsolateScope([]() -> bool {
if (tonic::CheckAndHandleError(::Dart_Invoke(
Dart_RootLibrary(), tonic::ToDart("sayHi"), 0, nullptr))) {
return false;
}
return true;
});
};
OpenPlaygroundHere(callback);
}
TEST_P(RendererDartTest, CanInstantiateFlutterGPUContext) {
auto isolate = GetIsolate();
bool result = isolate->RunInIsolateScope([]() -> bool {
if (tonic::CheckAndHandleError(::Dart_Invoke(
Dart_RootLibrary(), tonic::ToDart("instantiateDefaultContext"), 0,
nullptr))) {
return false;
}
return true;
});
ASSERT_TRUE(result);
}
#define DART_TEST_CASE(name) \
TEST_P(RendererDartTest, name) { \
auto isolate = GetIsolate(); \
bool result = isolate->RunInIsolateScope([]() -> bool { \
if (tonic::CheckAndHandleError(::Dart_Invoke( \
Dart_RootLibrary(), tonic::ToDart(#name), 0, nullptr))) { \
return false; \
} \
return true; \
}); \
ASSERT_TRUE(result); \
}
/// These test entries correspond to Dart functions located in
/// `flutter/impeller/fixtures/dart_tests.dart`
DART_TEST_CASE(canCreateShaderLibrary);
DART_TEST_CASE(canReflectUniformStructs);
DART_TEST_CASE(uniformBindFailsForInvalidHostBufferOffset);
DART_TEST_CASE(canCreateRenderPassAndSubmit);
} // namespace testing
} // namespace impeller