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

[fuchsia][shader warmup] fix for fxbug.dev/90387 #30482

Merged
merged 1 commit into from
Jan 5, 2022

Conversation

freiling
Copy link
Contributor

Warmup surface was being initialized on the platform thread rather than
the raster thread which was causing races in the skia cache, this change
just moves the warmup surface intiialization to the raster thread.

This change also addresses another minor problem where invoking shader
warmup with 0 skps would drop the callback on the floor and that would
cause the dart future to hang forever. Simply invoke the dart future if
no SKP's are provided.

Replace this paragraph with a description of what this PR is changing or adding, and why. Consider including before/after screenshots.

List which issues are fixed by this PR. You must list at least one issue.

If you had to change anything in the flutter/tests repo, include a link to the migration guide as per the breaking change policy.

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See testing the engine for instructions on
    writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

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

Copy link
Contributor

@arbreng arbreng left a comment

Choose a reason for hiding this comment

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

+2 so you can land it, but please fix the static thing first

// all gpu work is done and the callbacks skia takes for this are
// function pointers so we are unable to use a lambda that captures the
// smart pointer.
static SurfaceProducerSurface* skp_warmup_surface =
Copy link
Contributor

Choose a reason for hiding this comment

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

I was confused about the static inside a lambda here, so I looked it up: https://stackoverflow.com/questions/8391058/how-do-static-variables-in-lambda-function-objects-work/35038341 and https://stackoverflow.com/questions/55510/when-do-function-level-static-variables-get-allocated-initialized/58804#58804

This will work for the first time shader warmup is done within a given process, but subsequent warmup requests will fail mysteriously with the "Failed to create" error. This is because the static will be re-used across all lambda invocations....

Since you delete skp_warmup_surface when you're done with it below, it will be nullptr forever after and subsequent shader warmups will always fail (and it'll be really hard to debug).

It seems like you'll have to post 1 task to create the surface, and then post a bunch more inside the for loop which use the surface as a capture.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh damn good catch I didnt even think about that with the lambda, lemme chew on that and I'll cook up a solution. I guess i can move the pointer declaration to the outer function and then just initialize the pointer in the lambda. That way well get a new pointer for each invocation of WarmupSkps

@freiling
Copy link
Contributor Author

Yeah will do ASAP. Heater in my house is broken so dealing with that first while theres daylight, will try to fix the static thing and land by EOD

@freiling
Copy link
Contributor Author

freiling commented Dec 29, 2021

I think this is right but I need to get my arm workflow working to test on arm before i land, pls dont land this without talking to me

Copy link
Contributor

@akbiggs akbiggs left a comment

Choose a reason for hiding this comment

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

Sorry for the slow review.

surface_producer, completion_callback, i,
count = skp_mappings.size()] {
TRACE_DURATION("flutter", "WarmupSkp");
skp_warmup_surface->GetSkiaSurface()->getCanvas()->drawPicture(picture);
if (!(*skp_warmup_surface)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

if (*skp_warmup_surface == nullptr) might be more readable here and below.

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

@@ -861,24 +861,24 @@ void Engine::WarmupSkps(
std::shared_ptr<flutter::AssetManager> asset_manager,
std::optional<const std::vector<std::string>> skp_names,
std::optional<std::function<void(uint32_t)>> completion_callback) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Optional: We could simplify invoking completion_callback here a bit by doing:

void Engine::WarmupSkps(..., std::optional<std::function<void(uint32_t)>> maybe_completion_callback) {
  auto completion_callback = [maybe_completion_callback](uint32_t skp_count) {
    if (maybe_completion_callback.has_value() && maybe_completion_callback.value()) {
      maybe_completion_callback.value()(skp_count);
    }
  };
  ...
}

That way we can invoke it like:

completion_callback(0);

But it might obfuscate things a bit too much so leaving this as optional.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good idea I like it :) done.

// statically initialialize it in the lambda itself). Basically the result
// of a mashup of wierd call dynamics, multithreading, and lifecycle
// management with C style Skia callbacks.
std::unique_ptr<SurfaceProducerSurface>* skp_warmup_surface =
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it okay that we're doing delete static_cast<SurfaceProducerSurface*>(skp_warmup_surface); on this below as though it were a SurfaceProducerSurface* instead of a unique_ptr<SurfaceProducerSurface*>?

Copy link
Contributor

Choose a reason for hiding this comment

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

NVM, I see that skp_warmup_surface is redefined within that scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no you're right thats very bad and will cause crashes. Good catch. Looks like the tests werent catching this because they tear down the context before it completes so the callback never runs. I'll fix this and plumb the tests to wait the for completion properly so theyll catch things like this.

@freiling freiling force-pushed the freiling-fxb-90387 branch from e26bef6 to 1dce56c Compare January 4, 2022 20:19
Warmup surface was being initialized on the platform thread rather than
the raster thread which was causing races in the skia cache, this change
just moves the warmup surface intiialization to the raster thread.

This change also addresses another minor problem where invoking shader
warmup with 0 skps would drop the callback on the floor and that would
cause the dart future to hang forever. Simply invoke the dart future if
no SKP's are provided.
@freiling freiling force-pushed the freiling-fxb-90387 branch from 1dce56c to 3583940 Compare January 5, 2022 21:05
@freiling freiling merged commit 36eafae into flutter:main Jan 5, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jan 5, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jan 6, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jan 6, 2022
zanderso pushed a commit to flutter/flutter that referenced this pull request Jan 6, 2022
* 9481a79 Roll Skia from 45f64bd52835 to 6bebf036a502 (2 revisions) (flutter/engine#30659)

* fb4a86c Roll Fuchsia Mac SDK from RyUwCnr_M... to vpa6vKu7U... (flutter/engine#30661)

* 154bd96 Roll Skia from 6bebf036a502 to 5726d457cf15 (1 revision) (flutter/engine#30665)

* ba23c6c Roll Skia from 5726d457cf15 to 61d0fbbca795 (5 revisions) (flutter/engine#30673)

* e749ba3 Impl and test (flutter/engine#30488)

* a78103c Removed "UiThread" annotation from MethodChannel#Result. (flutter/engine#30671)

* f8a398f Fix crash in BackdropFilterLayer::Diff (flutter/engine#30460)

* a6a856f Only provide frame damage to rasterizer if partial repaint is enabled (flutter/engine#30461)

* 3a667ab Roll Fuchsia Mac SDK from vpa6vKu7U... to Al-HXHXyQ... (flutter/engine#30677)

* 830abeb [web] roll CanvasKit 0.32.0; fix frame order in animated images (flutter/engine#30680)

* c726121 Add a new display_list_benchmarks test suite (flutter/engine#30678)

* f181c4d [web] flip browser image codec flag to opt-out (flutter/engine#30681)

* 436a346 Remove the ios_tools Chromium-style dependency (flutter/engine#30538)

* 3f63998 [web] bring libraries.yaml/libraries.json up to date (flutter/engine#30467)

* ab1e8f5 Roll Skia from 61d0fbbca795 to 4981c921c6d7 (1 revision) (flutter/engine#30684)

* 8e4124b Roll Skia from 4981c921c6d7 to d7771857e9e2 (2 revisions) (flutter/engine#30685)

* acb60b4 Roll Fuchsia Mac SDK from Al-HXHXyQ... to G04Sc3__F... (flutter/engine#30687)

* 0176295 [Win32, Keyboard] TextInputPlugin is no longer a KeyboardHandlerBase (flutter/engine#30456)

* bcb4b35 Roll Skia from d7771857e9e2 to ec2e8f11b97a (1 revision) (flutter/engine#30688)

* e09f8d1 Roll Dart SDK from 1697706df708 to ab5047720a9e (5 revisions) (flutter/engine#30690)

* d60c816 Roll Dart SDK from 1697706df708 to f59531cc2973 (10 revisions) (flutter/engine#30691)

* 417042c GN targets for generating release artifacts (flutter/engine#30679)

* 7f31015 Roll Skia from ec2e8f11b97a to 84d6cf9b5b76 (7 revisions) (flutter/engine#30693)

* fed9e0b Roll Skia from 84d6cf9b5b76 to 88c5af7ecd72 (3 revisions) (flutter/engine#30695)

* 36eafae [fuchsia][shader warmup] fix for fxbug.dev/90387 (flutter/engine#30482)

* 0c036a7 Revert "Only provide frame damage to rasterizer if partial repaint is enabled (#30461)" (flutter/engine#30696)

* 8498779 [fuchsia] Fix failing SDK roll. (flutter/engine#30675)
JsouLiang pushed a commit to JsouLiang/engine that referenced this pull request Jan 14, 2022
Warmup surface was being initialized on the platform thread rather than
the raster thread which was causing races in the skia cache, this change
just moves the warmup surface intiialization to the raster thread.

This change also addresses another minor problem where invoking shader
warmup with 0 skps would drop the callback on the floor and that would
cause the dart future to hang forever. Simply invoke the dart future if
no SKP's are provided.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants