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

[macOS]: Call layer.setNeedsDisplay on show. #17096

Merged
merged 1 commit into from
Sep 23, 2024

Conversation

grokys
Copy link
Member

@grokys grokys commented Sep 23, 2024

What does the pull request do?

The AvaloniaNative.GlPlatformSurface.CreateGlRenderTarget method can only be called on the UI thread. In normal circumstances this method is called in response to a call to TopLevel.HandlePaint from the native AvnView.updateLayer method. The flow of operations goes like this:

  1. Window is created
  2. Window is shown
  3. Window is registered with the compositor
  4. AvnView.updateLayer is called
  5. Which calls TopLevel.HandlePaint
  6. Which calls MediaContext.ImmediateRenderRequested to render on the UI thread
  7. This render operation calls GlPlatformSurface.CreateGlRenderTarget on the UI thread and a GL render target is created
  8. Subsequent render operations on the render thread use this render target

However, a customer was experiencing a problem where AvnView.updateLayer and by extension TopLevel.HandlePaint were being called before the window is shown. This broke the creation of the GL render target:

  1. Window is created
  2. AvnView.updateLayer is called
  3. Which calls TopLevel.HandlePaint
  4. Which calls MediaContext.ImmediateRenderRequested
  5. But the window hasn't been registered with the compositor so nothing happens
  6. Subsequent render operations are run on the render thread and try to create a render target
  7. But this fails because the render target can only be created on the UI thread

This was happening because the customer is creating/showing the window by pushing jobs to the dispatcher, causing the HandlePaint request to come in earlier than expected.

What is the current behavior?

The window is blank until a resize happens (which causes HandlePaint to be called).

How was the solution implemented (if it's not obvious)?

The layer is invalidated at the end of a show operation, so AvnView.updateLayer/HandlePaint is called, creating the render target

The `AvaloniaNative.GlPlatformSurface.CreateGlRenderTarget` method can only be called on the UI thread. In normal circumstances this method is called in response to a call to `TopLevel.HandlePaint` from the native `AvnView.updateLayer` method. However, a customer was experiencing a problem where `AvnView.updateLayer` and by extension `TopLevel.HandlePaint` were being called before the window is shown. This broke the creation of the GL render target.
@grokys grokys added bug customer-priority Issue reported by a customer with a support agreement. backported-11.1.x backport-candidate-11.1.x Consider this PR for backporting to 11.1 branch and removed backported-11.1.x labels Sep 23, 2024
@grokys grokys changed the title [macOs]: Call layer.setNeedsDisplay on show. [macOS]: Call layer.setNeedsDisplay on show. Sep 23, 2024
@avaloniaui-bot
Copy link

You can test this PR using the following package version. 11.2.999-cibuild0051999-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@kekekeks kekekeks added this pull request to the merge queue Sep 23, 2024
Merged via the queue into master with commit 8c043d5 Sep 23, 2024
12 checks passed
@kekekeks kekekeks deleted the fixes/macos-handlepaint-race branch September 23, 2024 20:30
grokys added a commit that referenced this pull request Oct 4, 2024
The `AvaloniaNative.GlPlatformSurface.CreateGlRenderTarget` method can only be called on the UI thread. In normal circumstances this method is called in response to a call to `TopLevel.HandlePaint` from the native `AvnView.updateLayer` method. However, a customer was experiencing a problem where `AvnView.updateLayer` and by extension `TopLevel.HandlePaint` were being called before the window is shown. This broke the creation of the GL render target.
grokys added a commit that referenced this pull request Oct 8, 2024
The `AvaloniaNative.GlPlatformSurface.CreateGlRenderTarget` method can only be called on the UI thread. In normal circumstances this method is called in response to a call to `TopLevel.HandlePaint` from the native `AvnView.updateLayer` method. However, a customer was experiencing a problem where `AvnView.updateLayer` and by extension `TopLevel.HandlePaint` were being called before the window is shown. This broke the creation of the GL render target.
@grokys grokys added backported-11.1.x and removed backport-candidate-11.1.x Consider this PR for backporting to 11.1 branch labels Oct 8, 2024
@grokys grokys added the backport-candidate-11.2.x Consider this PR for backporting to 11.2 branch label Oct 31, 2024
@maxkatz6 maxkatz6 added backported-11.2.x and removed backport-candidate-11.2.x Consider this PR for backporting to 11.2 branch labels Nov 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backported-11.1.x backported-11.2.x bug customer-priority Issue reported by a customer with a support agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants