Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Conversation

@chinmaygarde
Copy link
Member

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 flutter/flutter#42460
Prerequisite for flutter/flutter#17579

/// cases where the embedder specifies custom task runners via
/// `FlutterProjectArgs::custom_task_runners`. In such cases, the
/// engine may need the embedder to post tasks back to it before
/// `FluterEngineRun` has returned. Embedders can only post tasks to
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: "Flutter"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

engine_out);

//------------------------------------------------------------------------------
/// @brief Shuts down a Flutter engine Tnstance. the engine handle is no
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: "instance"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

/// custom task runners supplied by the embedder are expected to
/// start servicing tasks.
///
/// @param[in] engine A initialized engine instance that has not previously
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: "an"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

/// @param[in] engine A initialized engine instance that has not previously
/// been run.
///
/// @return The result of the call to run the initialized the Flutter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove "the initialized"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

uint64_t engine_thread_host_mask =
ThreadHost::Type::UI | ThreadHost::Type::IO;

auto optional_platform_task_runner = CreateEmbedderTaskRunner(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imho it would be clearer if CreateEmbedderTaskRunner returned a bool indicating success and used a RefPtr<EmbedderTaskRunner>* output parameter for the runner.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. But instead of the out parameter, I used a pair instead.

return nullptr;
// If both the platform task runner and the GPU task runner are specified and
// have the same identifier, store only one.
if (optional_platform_task_runner.has_value() &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be value() - at this point optional_platform_task_runner is known to contain a value, but the value might be null.

(see the comment above - removing usage of std::optional here would make this clearer)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed using the pair.

Copy link
Member Author

@chinmaygarde chinmaygarde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed other concerns. Will work on making CreateEmbedderTaskRunner clearer.

/// cases where the embedder specifies custom task runners via
/// `FlutterProjectArgs::custom_task_runners`. In such cases, the
/// engine may need the embedder to post tasks back to it before
/// `FluterEngineRun` has returned. Embedders can only post tasks to
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

engine_out);

//------------------------------------------------------------------------------
/// @brief Shuts down a Flutter engine Tnstance. the engine handle is no
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

/// custom task runners supplied by the embedder are expected to
/// start servicing tasks.
///
/// @param[in] engine A initialized engine instance that has not previously
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

/// @param[in] engine A initialized engine instance that has not previously
/// been run.
///
/// @return The result of the call to run the initialized the Flutter
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@chinmaygarde
Copy link
Member Author

I tried the suggestion to make CreateEmbedderTaskRunner easier to understand but I believe the current model is still clearer because:

The method needs to handle the following states:

  1. The embedder does not specify any task runner.
  2. The embedder specifies a task runner but messes up by not specifying all required fields.
  3. The embedder correctly specifies a task runner.

In case of 1 and 3, engine initialization must continue. In case of 2, engine intialization must be terminated with kInvalid arguments.

In case of 1, an fml::TaskRunner fallback must be selected. In case of 3, an fml::EmbedderTaskRunner (a subclass of fml::TaskRunner) must be used. This is because the embedder task runner must be added to the task runner dispatch table in the embedder thread host.

Either approach has to handle all these cases and I couldn't find the out parameter approach any clearer. That a null ref ptr signifies a fallback to fml::TaskRunner defaults has already been specified in the docstring.

One other idea was passing a fml::TaskRunner as a default to the method. But this wont work because in case of the default return, I can't downcast to an EmbedderTaskRunner (to do the disambiguation via the identifier).

For these reasons, I'd rather keep the behavior of CreateEmbedderTaskRunner as-is.

@chinmaygarde chinmaygarde force-pushed the custom_gpu_task_runner branch from aee0733 to 299f0d9 Compare October 15, 2019 00:50
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 flutter/flutter#42460
Prerequisite for flutter/flutter#17579
@chinmaygarde chinmaygarde force-pushed the custom_gpu_task_runner branch from 299f0d9 to c63561e Compare October 15, 2019 00:51
engine_out);

//------------------------------------------------------------------------------
/// @brief Shuts down a Flutter engine instance. the engine handle is no
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The*

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

shell_args_->on_create_platform_view,
shell_args_->on_create_rasterizer);

// Reset the args no matter what. We are never going to use them to initialize
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

go/avoidwe

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


~EmbedderTaskRunner() override;

size_t GetEmbedderIdentifier() const;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth documenting the class and methods

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Documented all methods and the class.

const auto platform_task_runner = CreateEmbedderTaskRunner(
// The UI and IO threads are always created by the engine and the embedder has
// no opportunity to specify task runners for the same.
// TODO(chinmaygarde): If we ever decide to expose more task runners to engine
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using github issue ids for TODOs instead of personal IDs, since they might be confusing for future readers (is the person going to implement? are they the person to ask questions? is this in their current priorities? etc).

In this case I don't see much value in using either, seems like it could just be part of the comment (but still avoid "we" ) :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

if (!optional_platform_task_runner.has_value() ||
!optional_render_task_runner.has_value()) {
// User error while supplying a custom task runner. Return an invalid thread
// host. This will abort engine initialization. We don't want to fallback to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoid "we" here and below as well

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

///
TEST_F(EmbedderTest,
CanCreateEmbedderWithCustomRenderTaskRunnerTheSameAsPlatformTaskRunner) {
// We need to create a new thread to act as the platform thread because we
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: avoid "we" and remove extra line below?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@chinmaygarde chinmaygarde merged commit bf81971 into flutter:master Oct 15, 2019
@chinmaygarde chinmaygarde deleted the custom_gpu_task_runner branch October 15, 2019 21:26
engine-flutter-autoroll added a commit to flutter/flutter that referenced this pull request Oct 16, 2019
git@github.com:flutter/engine.git/compare/540fc977bb6b...5e6c005

git log 540fc97..5e6c005 --no-merges --oneline
2019-10-16 skia-flutter-autoroll@skia.org Roll src/third_party/skia 083a75d6762c..59e72b71b5cf (1 commits) (flutter/engine#13169)
2019-10-16 a-siva@users.noreply.github.com Roll src/third_party/dart 4131d3d7c4...41b65b27c2 (28 commits) (flutter/engine#13163)
2019-10-16 skia-flutter-autoroll@skia.org Roll src/third_party/skia 7274850f96f2..083a75d6762c (1 commits) (flutter/engine#13168)
2019-10-16 skia-flutter-autoroll@skia.org Roll fuchsia/sdk/core/linux-amd64 from 5I4Iw... to oTVah... (flutter/engine#13167)
2019-10-16 skia-flutter-autoroll@skia.org Roll fuchsia/sdk/core/mac-amd64 from qpzUe... to KVDL4... (flutter/engine#13166)
2019-10-16 skia-flutter-autoroll@skia.org Roll src/third_party/skia 634d15032d37..7274850f96f2 (3 commits) (flutter/engine#13165)
2019-10-16 yjbanov@google.com Move surface-based SceneBuilder implementation under surface/ (flutter/engine#13159)
2019-10-16 skia-flutter-autoroll@skia.org Roll src/third_party/skia ba8752f37dab..634d15032d37 (2 commits) (flutter/engine#13164)
2019-10-16 chinmaygarde@gmail.com Revert "Issue 13238: on iOS, force an orientation change when the current orientation is not allowed" (flutter/engine#13160)
2019-10-15 chinmaygarde@google.com Roll buildroot to pull in static thread safety analysis options. (flutter/engine#13155)
2019-10-15 skia-flutter-autoroll@skia.org Roll src/third_party/skia fb6a1abe4567..ba8752f37dab (8 commits) (flutter/engine#13156)
2019-10-15 chinmaygarde@google.com Make the Dart isolate constructor private. (flutter/engine#13153)
2019-10-15 iska.kaushik@gmail.com Revert "Upgrades the ICU version to 64.2 (#13123)" (flutter/engine#13146)
2019-10-15 1541038+josh-ksr@users.noreply.github.com Issue 13238: on iOS, force an orientation change when the current orientation is not allowed (flutter/engine#12295)
2019-10-15 chinmaygarde@google.com Allow embedders to specify a render task runner description. (flutter/engine#13124)
2019-10-15 skia-flutter-autoroll@skia.org Roll fuchsia/sdk/core/linux-amd64 from Jv4XM... to 5I4Iw... (flutter/engine#13150)
2019-10-15 skia-flutter-autoroll@skia.org Roll fuchsia/sdk/core/mac-amd64 from i5xD1... to qpzUe... (flutter/engine#13149)
2019-10-15 bkonyi@google.com Roll src/third_party/dart fc933312f7..4131d3d7c4 (3 commits)
2019-10-15 chinmaygarde@google.com Document //flutter/runtime/dart_vm (flutter/engine#13144)
2019-10-15 iska.kaushik@gmail.com Revert "Enable/tweak web sdk source maps (#13141)" (flutter/engine#13148)
2019-10-15 jason-simmons@users.noreply.github.com Merge the Fuchsia frontend_server build script into the new flutter_frontend_server target (flutter/engine#13145)
2019-10-15 iska.kaushik@gmail.com Add `flutter_tester` binary to the CIPD package (flutter/engine#13143)
2019-10-15 skia-flutter-autoroll@skia.org Roll src/third_party/skia f22c57ddcc8c..fb6a1abe4567 (2 commits) (flutter/engine#13142)
2019-10-15 vsm@google.com Enable/tweak web sdk source maps (flutter/engine#13141)
2019-10-15 filmil@gmail.com Upgrades the ICU version to 64.2 (flutter/engine#13123)
2019-10-15 rmacnak@google.com [frontend_server] Include bytecode generation in the training run. (flutter/engine#13126)
2019-10-15 wvvwwvw@gmail.com Support empty strings and vectors in standard codec (flutter/engine#12974)
2019-10-15 bkonyi@google.com Roll src/third_party/dart 50f7ae9c5d..fc933312f7 (2 commits)
2019-10-15 skia-flutter-autoroll@skia.org Roll src/third_party/skia 55f9cba6e2e7..f22c57ddcc8c (1 commits) (flutter/engine#13136)
2019-10-15 skia-flutter-autoroll@skia.org Roll fuchsia/sdk/core/linux-amd64 from xRgq0... to Jv4XM... (flutter/engine#13135)
2019-10-15 skia-flutter-autoroll@skia.org Roll fuchsia/sdk/core/mac-amd64 from Lk7iT... to i5xD1... (flutter/engine#13134)
2019-10-15 skia-flutter-autoroll@skia.org Roll src/third_party/skia 858cf233ef71..55f9cba6e2e7 (3 commits) (flutter/engine#13133)
2019-10-15 bkonyi@google.com Roll src/third_party/dart 70a7ef3f58..50f7ae9c5d (18 commits)


If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC franciscojma@google.com on the revert to ensure that a human
is aware of the problem.

To report a problem with the AutoRoller itself, please file a bug:
https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug

Documentation for the AutoRoller is here:
...
Inconnu08 pushed a commit to Inconnu08/flutter that referenced this pull request Nov 26, 2019
git@github.com:flutter/engine.git/compare/540fc977bb6b...5e6c005

git log 540fc97..5e6c005 --no-merges --oneline
2019-10-16 skia-flutter-autoroll@skia.org Roll src/third_party/skia 083a75d6762c..59e72b71b5cf (1 commits) (flutter/engine#13169)
2019-10-16 a-siva@users.noreply.github.com Roll src/third_party/dart 4131d3d7c4...41b65b27c2 (28 commits) (flutter/engine#13163)
2019-10-16 skia-flutter-autoroll@skia.org Roll src/third_party/skia 7274850f96f2..083a75d6762c (1 commits) (flutter/engine#13168)
2019-10-16 skia-flutter-autoroll@skia.org Roll fuchsia/sdk/core/linux-amd64 from 5I4Iw... to oTVah... (flutter/engine#13167)
2019-10-16 skia-flutter-autoroll@skia.org Roll fuchsia/sdk/core/mac-amd64 from qpzUe... to KVDL4... (flutter/engine#13166)
2019-10-16 skia-flutter-autoroll@skia.org Roll src/third_party/skia 634d15032d37..7274850f96f2 (3 commits) (flutter/engine#13165)
2019-10-16 yjbanov@google.com Move surface-based SceneBuilder implementation under surface/ (flutter/engine#13159)
2019-10-16 skia-flutter-autoroll@skia.org Roll src/third_party/skia ba8752f37dab..634d15032d37 (2 commits) (flutter/engine#13164)
2019-10-16 chinmaygarde@gmail.com Revert "Issue 13238: on iOS, force an orientation change when the current orientation is not allowed" (flutter/engine#13160)
2019-10-15 chinmaygarde@google.com Roll buildroot to pull in static thread safety analysis options. (flutter/engine#13155)
2019-10-15 skia-flutter-autoroll@skia.org Roll src/third_party/skia fb6a1abe4567..ba8752f37dab (8 commits) (flutter/engine#13156)
2019-10-15 chinmaygarde@google.com Make the Dart isolate constructor private. (flutter/engine#13153)
2019-10-15 iska.kaushik@gmail.com Revert "Upgrades the ICU version to 64.2 (flutter#13123)" (flutter/engine#13146)
2019-10-15 1541038+josh-ksr@users.noreply.github.com Issue 13238: on iOS, force an orientation change when the current orientation is not allowed (flutter/engine#12295)
2019-10-15 chinmaygarde@google.com Allow embedders to specify a render task runner description. (flutter/engine#13124)
2019-10-15 skia-flutter-autoroll@skia.org Roll fuchsia/sdk/core/linux-amd64 from Jv4XM... to 5I4Iw... (flutter/engine#13150)
2019-10-15 skia-flutter-autoroll@skia.org Roll fuchsia/sdk/core/mac-amd64 from i5xD1... to qpzUe... (flutter/engine#13149)
2019-10-15 bkonyi@google.com Roll src/third_party/dart fc933312f7..4131d3d7c4 (3 commits)
2019-10-15 chinmaygarde@google.com Document //flutter/runtime/dart_vm (flutter/engine#13144)
2019-10-15 iska.kaushik@gmail.com Revert "Enable/tweak web sdk source maps (flutter#13141)" (flutter/engine#13148)
2019-10-15 jason-simmons@users.noreply.github.com Merge the Fuchsia frontend_server build script into the new flutter_frontend_server target (flutter/engine#13145)
2019-10-15 iska.kaushik@gmail.com Add `flutter_tester` binary to the CIPD package (flutter/engine#13143)
2019-10-15 skia-flutter-autoroll@skia.org Roll src/third_party/skia f22c57ddcc8c..fb6a1abe4567 (2 commits) (flutter/engine#13142)
2019-10-15 vsm@google.com Enable/tweak web sdk source maps (flutter/engine#13141)
2019-10-15 filmil@gmail.com Upgrades the ICU version to 64.2 (flutter/engine#13123)
2019-10-15 rmacnak@google.com [frontend_server] Include bytecode generation in the training run. (flutter/engine#13126)
2019-10-15 wvvwwvw@gmail.com Support empty strings and vectors in standard codec (flutter/engine#12974)
2019-10-15 bkonyi@google.com Roll src/third_party/dart 50f7ae9c5d..fc933312f7 (2 commits)
2019-10-15 skia-flutter-autoroll@skia.org Roll src/third_party/skia 55f9cba6e2e7..f22c57ddcc8c (1 commits) (flutter/engine#13136)
2019-10-15 skia-flutter-autoroll@skia.org Roll fuchsia/sdk/core/linux-amd64 from xRgq0... to Jv4XM... (flutter/engine#13135)
2019-10-15 skia-flutter-autoroll@skia.org Roll fuchsia/sdk/core/mac-amd64 from Lk7iT... to i5xD1... (flutter/engine#13134)
2019-10-15 skia-flutter-autoroll@skia.org Roll src/third_party/skia 858cf233ef71..55f9cba6e2e7 (3 commits) (flutter/engine#13133)
2019-10-15 bkonyi@google.com Roll src/third_party/dart 70a7ef3f58..50f7ae9c5d (18 commits)


If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC franciscojma@google.com on the revert to ensure that a human
is aware of the problem.

To report a problem with the AutoRoller itself, please file a bug:
https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug

Documentation for the AutoRoller is here:
...
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom task runners are difficult to use with FlutterEngineRun.

4 participants