Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not serialize on UI/Raster threads for Shell::OnCreatePlatformView #29145

Merged
merged 5 commits into from
Oct 18, 2021

Conversation

dnfield
Copy link
Contributor

@dnfield dnfield commented Oct 12, 2021

Fixes flutter/flutter#91711

This patch shows a substantial improvement influtter_gallery__start_up.

I did two runs each with and without this patch:

BEFORE:
    "engineEnterTimestampMicros": 158129422997,
    "timeToFrameworkInitMicros": 344941,
    "timeToFirstFrameRasterizedMicros": 502523,
    "timeToFirstFrameMicros": 382552,
    "timeAfterFrameworkInitMicros": 37610
    
    "engineEnterTimestampMicros": 157811156937,
    "timeToFrameworkInitMicros": 193769,
    "timeToFirstFrameRasterizedMicros": 302143,
    "timeToFirstFrameMicros": 223207,
    "timeAfterFrameworkInitMicros": 29437

AFTER:
    "engineEnterTimestampMicros": 157962907452,
    "timeToFrameworkInitMicros": 139606,
    "timeToFirstFrameRasterizedMicros": 279967,
    "timeToFirstFrameMicros": 171701,
    "timeAfterFrameworkInitMicros": 32094

    "engineEnterTimestampMicros": 158047992070,
    "timeToFrameworkInitMicros": 145351,
    "timeToFirstFrameRasterizedMicros": 273628,
    "timeToFirstFrameMicros": 187442,
    "timeAfterFrameworkInitMicros": 42091

I believe the existing tests are enough to cover the thread safety, particularly around the raster thread merging tests in shell_unittests.cc. I've added a shell_benchmark for this. Before this patch, the values locally for host_profile are:

Run on (16 X 2400 MHz CPU s)
2021-10-12 21:45:46
Benchmark                                                                Time           CPU Iterations
------------------------------------------------------------------------------------------------------
BM_ShellOnPlatformViewCreated                                      6336030 ns     117060 ns       1000

After,

Run on (16 X 2400 MHz CPU s)
2021-10-12 21:45:46
Benchmark                                                                Time           CPU Iterations
------------------------------------------------------------------------------------------------------
BM_ShellOnPlatformViewCreated                                       238989 ns     107066 ns       6398

In one internal application, the time for this call went from >130ms to <100us on the platform thread.

@google-cla google-cla bot added the cla: yes label Oct 12, 2021
@dnfield dnfield marked this pull request as ready for review October 13, 2021 04:49
@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat.

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@dnfield
Copy link
Contributor Author

dnfield commented Oct 13, 2021

The bot will recognize benchmark changes as having a test after flutter/cocoon#1392

Copy link
Member

@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.

While it's easy to intuit why removing the latching would make this faster, this code at the intersection or application-lifecycle, shell-lifecycle, thread-merging, and, background GPU access has been the cause of significant instability in the engine in the past. For this reason, I don't think we should count on existing tests to verify correctness or count the benchmark as a test.

From the Discord thread, the following testing approach was discussed. Can we add a test for that instead?

"In shell_unittests, create a shell that calls OnPlatformViewCreated, invoke main
that calls back into native code to wait for a latch. This will block the UI thread.
Then call PlatformViewDestroyed and release the latch. In dart code,
the add a platform view and try to render a frame with it. See what happens?"

SkCanvas* CompositeEmbeddedView(int view_id) override { return &canvas_; }

private:
SkCanvas canvas_;
Copy link
Member

Choose a reason for hiding this comment

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

Here and elsewhere: Disallow copy and assign.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

raster_task, should_post_raster_task,
&latch //
] {
// TODO(dnfield): This probably isn't necessary. The engine should be able to
Copy link
Member

Choose a reason for hiding this comment

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

Nit: TODO(91717) instead

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

// snapshot.
fml::TaskRunner::RunNowOrPostTask(
thread_host->ui_thread->GetTaskRunner(),
[]() { std::this_thread::sleep_for(std::chrono::milliseconds(5)); });
Copy link
Member

Choose a reason for hiding this comment

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

Please avoid magic timeouts.

Copy link
Member

Choose a reason for hiding this comment

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

To elaborate on how to avoid magic timeouts, you could either setup a latch that gets signaled on the NotifyDestroyed. That can be after the timing for the run has been paused if needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was thinking a latch wouldn't be great here because the benchmark wouldn't even work without my change, but I guess it's fine and I have to re-order the threading anyway because of a misuse of GetPlatformView.

@dnfield
Copy link
Contributor Author

dnfield commented Oct 13, 2021

Per offline conversation, updating this PR to also have the OnDestroyed call not latch the UI task runner, which shoul dbe equally safe. Will push tests and updated benchmark shortly.

@dnfield
Copy link
Contributor Author

dnfield commented Oct 13, 2021

Benchmark is just giving me lots of headaches, and I'm not sure how much value it has. I've added tests.

I also removed the check about whether we need to post the raster task or not from OnDestroy. It seems completely unnecessary at this point, since we're running the task from the platform thread immediately after firing off the UI task. Nothing could interrupt us at that point to change the merge status.

@dnfield
Copy link
Contributor Author

dnfield commented Oct 15, 2021

@chinmaygarde - mind giving this another review?

yx-mike added a commit to yx-mike/engine that referenced this pull request May 18, 2022
yx-mike added a commit to yx-mike/engine that referenced this pull request Aug 10, 2022
yx-mike added a commit to yx-mike/engine that referenced this pull request Aug 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
2 participants