flutter_flutter/shell/platform/embedder/tests/embedder_config_builder.h
Chinmay Garde bf81971f7a
Allow embedders to specify a render task runner description. (#13124)
Embedders may use this to specify a thread whose event loop is managed by them
instead of the engine. In addition, specifying the same task runner for both
the platform and render task runners allows embedders to effectively perform
GPU rendering operations on the platform thread.

To affect this change, the following non breaking changes to the API have been
made:

* The `FlutterCustomTaskRunners` struct now has a new field `render_task_runner`
  for the specification of a custom render task runner.
* The `FlutterTaskRunnerDescription` has a new field `identifier`. Embedders
  must supply a unique identifier for each task runner they specify. In
  addition, when describing multiple task runners that run their tasks on the
  same thread, their identifiers must match.
* The embedder may need to process tasks during `FlutterEngineRun` and
  `FlutterEngineShutdown`. However, the embedder doesn't have the Flutter engine
  handle before `FlutterEngineRun` and is supposed to relinquish handle right
  before `FlutterEngineShutdown`. Since the embedder needs the Flutter engine
  handle to service tasks on other threads while these calls are underway,
  there exist opportunities for deadlock. To work around this scenario, three
  new calls have been added that allow more deliberate management of the Flutter
  engine instance.
  * `FlutterEngineRun` can be replaced with `FlutterEngineInitialize` and
    `FlutterEngineRunInitialized`. The embedder can obtain a handle to the
    engine after the first call but the engine will not post any tasks to custom
    task runners specified by the embedder till the
    `FlutterEngineRunInitialized` call. Embedders can guard the Flutter engine
    handle behind a mutex for safe task runner interop.
  * `FlutterEngineShutdown` can be preceded by the `FlutterEngineDeinitialize`
    call. After this call the Flutter engine will no longer post tasks onto
    embedder managed task runners. It is still embedder responsibility to
    collect the Flutter engine handle via `FlutterEngineShutdown`.
* To maintain backwards compatibility with the old APIs, `FlutterEngineRun` is
  now just a convenience for `FlutterEngineInitialize` and
  `FlutterEngineRunInitilaized`. `FlutterEngineShutdown` now implicitly calls
  `FlutterEngineDeinitialize` as well. This allows existing users who don't care
  are custom task runner interop to keep using the old APIs.
* Adds complete test coverage for both old and new paths.

Fixes https://github.com/flutter/flutter/issues/42460
Prerequisite for https://github.com/flutter/flutter/issues/17579
2019-10-15 14:26:31 -07:00

97 lines
2.8 KiB
C++

// 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.
#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_CONFIG_BUILDER_H_
#define FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_CONFIG_BUILDER_H_
#include "flutter/fml/macros.h"
#include "flutter/fml/unique_object.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/tests/embedder_test.h"
#include "flutter/shell/platform/embedder/tests/embedder_test_compositor.h"
#include "flutter/shell/platform/embedder/tests/embedder_test_context.h"
namespace flutter {
namespace testing {
struct UniqueEngineTraits {
static FlutterEngine InvalidValue() { return nullptr; }
static bool IsValid(const FlutterEngine& value) { return value != nullptr; }
static void Free(FlutterEngine& engine) {
auto result = FlutterEngineShutdown(engine);
FML_CHECK(result == kSuccess);
}
};
using UniqueEngine = fml::UniqueObject<FlutterEngine, UniqueEngineTraits>;
class EmbedderConfigBuilder {
public:
enum class InitializationPreference {
kInitialize,
kNoInitialize,
};
EmbedderConfigBuilder(EmbedderTestContext& context,
InitializationPreference preference =
InitializationPreference::kInitialize);
~EmbedderConfigBuilder();
FlutterProjectArgs& GetProjectArgs();
void SetSoftwareRendererConfig(SkISize surface_size = SkISize::Make(1, 1));
void SetOpenGLRendererConfig(SkISize surface_size);
void SetAssetsPath();
void SetSnapshots();
void SetIsolateCreateCallbackHook();
void SetSemanticsCallbackHooks();
void SetDartEntrypoint(std::string entrypoint);
void AddCommandLineArgument(std::string arg);
void SetPlatformTaskRunner(const FlutterTaskRunnerDescription* runner);
void SetRenderTaskRunner(const FlutterTaskRunnerDescription* runner);
void SetPlatformMessageCallback(
std::function<void(const FlutterPlatformMessage*)> callback);
void SetCompositor();
FlutterCompositor& GetCompositor();
UniqueEngine LaunchEngine() const;
UniqueEngine InitializeEngine() const;
private:
EmbedderTestContext& context_;
FlutterProjectArgs project_args_ = {};
FlutterRendererConfig renderer_config_ = {};
FlutterSoftwareRendererConfig software_renderer_config_ = {};
FlutterOpenGLRendererConfig opengl_renderer_config_ = {};
std::string dart_entrypoint_;
FlutterCustomTaskRunners custom_task_runners_ = {};
FlutterCompositor compositor_ = {};
std::vector<std::string> command_line_arguments_;
UniqueEngine SetupEngine(bool run) const;
FML_DISALLOW_COPY_AND_ASSIGN(EmbedderConfigBuilder);
};
} // namespace testing
} // namespace flutter
#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_CONFIG_BUILDER_H_