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

Making first frame render synchronous #2989

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

yard
Copy link

@yard yard commented Mar 2, 2025

This PR aims to address the issue described in #2968.

Summary of changes

  1. <Canvas /> component populates SkiaSGRoot instance with the children elements so that it has content from the get-go instead of letting the first render to come through and appending children in an effect
  2. WindowContexts present() method has been extended with a boolean flush argument instructing the context to render the image immediately (i.e. perform a synchronous presentation)
  3. Corresponding implementations (iOS, Android) have been amended to take flush argument into account.

Disclaimer: I am by no means an expert in the inner workings of Skia's renderers and did the change using (my very own) common sense and testing locally; happy to adhere to changes to provide a better implementation, shall there be an oversight in this changeset.

@yard
Copy link
Author

yard commented Mar 2, 2025

I have signed the CLA!

@wcandillon
Copy link
Contributor

looks very nice :)

@@ -76,7 +76,12 @@ export const Canvas = forwardRef(
}, []);

// Root
const root = useMemo(() => new SkiaSGRoot(Skia, nativeId), [nativeId]);
const root = useMemo(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm surprised this change helps, do you have examples I can try where I could see a difference there?

Copy link
Author

Choose a reason for hiding this comment

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

Funnily enough, removing either set of changes (this one or the synchronous presentation) makes the bug return (i.e. the first frame renders empty).

Copy link
Author

Choose a reason for hiding this comment

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

Happy to provide an example, but not sure what would be the best form? Ideally I would prepare a unit test demonstrating the issue, but I didn't find a suitable example to start off with – I would need to render a component, preferrably with frame-by-frame control, would appreciate hints on how to do it.

@wcandillon
Copy link
Contributor

Could you provide me some small examples that would help me experience the issue described in #2968? This would allow me to review this more easily but overall this looks very good 👍

@yard
Copy link
Author

yard commented Mar 2, 2025

Could you provide me some small examples that would help me experience the issue described in #2968? This would allow me to review this more easily but overall this looks very good 👍

Sure thing. The snack (https://snack.expo.dev/@anton9001/react-native-skia-error-app) in the original issue is a one-component example that exhibits the problem; I can as well create a separate branch in my fork to demonstrate that if that's easier? Lmk what's the easiest for you.

@wcandillon
Copy link
Contributor

let me know if #2991 fixes fixes #2968

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants