-
Notifications
You must be signed in to change notification settings - Fork 76
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
Add constructor with RenderSettings
to ComposePanel
#1377
Conversation
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposePanel.desktop.kt
Outdated
Show resolved
Hide resolved
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposePanel.desktop.kt
Outdated
Show resolved
Hide resolved
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposePanel.desktop.kt
Outdated
Show resolved
Hide resolved
While I don't think this change is bad in and of itself (it's good to give more granularity to the vsync flag), I don't like how this is being used as a workaround for the presentation latency issue. It solves a very small aspect of the problem, and in a very inconvenient way.
I'd much rather we solved the underlying issue; if Swing/AWT can do it, why not us? |
@@ -46,8 +47,29 @@ import org.jetbrains.skiko.SkiaLayerAnalytics | |||
class ComposePanel @ExperimentalComposeUiApi constructor( | |||
private val skiaLayerAnalytics: SkiaLayerAnalytics, | |||
) : JLayeredPane() { | |||
private var reducePresentationLatency: Boolean? = null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with Ivan that vsyncEnabled
is better. reducePresentationLatency
doesn't hint at any downsides - why would anyone not want to reduce presentation latency?
But maybe consider going even farther and give it a (fake) enum, e.g. PresentationMode.VSYNC
, PresentationMode.IMMEDIATE
etc, if there's a chance we could have more modes...
I would too, but as we discussed, it is much harder, and I am not sure we are able to solve it in the foreseeble future. In the meantime, we can provide a property, that even makes sense outside of this issue. |
If we just disable vsync, we will have:
Swing can have the same issues. |
Are there no other solutions?
But in practice, it doesn't. Swing has low-latency presentation and no tearing out-of-the-box. |
This is the nature of vsync. If we sync with it, we have 1-frame latency. We sync with it to solve the issues I mentioned. Animations should always be in sync with v-sync, to avoid them. The solution might be to move input reaction changes out of vsync, but it can be not trivial. We might even need a new API that user should call explicitly, not sure. |
We also might have unnecessary frame lags in other places. Most probably it is easier to fix them than the vsync latency. But we need to profile the issue to understand if we have them. |
But, again, why is this problem not present in Swing, and (I assume) native frameworks? Can we double buffer ourselves to avoid tearing?
The problem reproduces in pure Skiko, and it appears that most (possibly all) the delay comes from vsync. |
Besides tearing I mentioned the animation issue, which Swing didn't solve. It doesn't sync it with vsync. I haven't investigated it properly in the past though. I discovered this when I tried to implement smooth animations on Swing, and didn't find a way. I am not saying that there is no proper way, I am saying that a proper way needs time to investigate/design/implement. And I am all for doing that.
What I meant that we can have issues in Compose, and solving them might also help. Skiko also can have additional lags besides that caused by vsync. |
I would look at the Android sources ( |
Ok, understood.
The experiments I've done show that this isn't the case. Or at least the contribution of other factors (in Skiko or Compose) to the latency are minimal.
|
Note that merely setting
while keeping everything else related to vsync (e.g. calling |
Yes, that's true. The introduced flag doesn't affect throttler behavior. |
Thank you for feedback and discussion, I'll do deeper investigation of other graphics backends and see if I can define a common denominator here. |
I noticed that even with vsync disabled, you can get better results with requesting redraw only 1 time per frame. |
Which platform did you test it on? |
5e5f3f2
to
f17214c
Compare
.../ui/src/desktopMain/kotlin/androidx/compose/ui/scene/skia/SwingSkiaLayerComponent.desktop.kt
Outdated
Show resolved
Hide resolved
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposePanel.desktop.kt
Outdated
Show resolved
Hide resolved
e9ec093
to
22022fa
Compare
There is quite a lot of effects for fully exposing |
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposePanel.desktop.kt
Outdated
Show resolved
Hide resolved
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/RenderingSettings.desktop.kt
Outdated
Show resolved
Hide resolved
* by Swing. | ||
*/ | ||
@ExperimentalComposeUiApi | ||
class RenderingSettings( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add equals/hashCode to it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nop, we don't do any comparisons/caching/using it as a key, etc.
@@ -78,6 +79,7 @@ import org.jetbrains.skiko.SkiaLayerAnalytics | |||
* for window coordinate space. | |||
* @property useSwingGraphics Flag indicating if offscreen rendering to Swing graphics is used. | |||
* @property layerType The type of layer used for Popup/Dialog. | |||
* @property renderingSettings The settings for rendering. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a note that it will work only with useSwingGraphics == true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's in the doc of RenderSettings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general it's not true, because we can add settings, that will work with swing
@@ -338,7 +341,13 @@ internal class ComposeContainer( | |||
return if (useSwingGraphics) { | |||
SwingSkiaLayerComponent(mediator, renderDelegate, skiaLayerAnalytics) | |||
} else { | |||
WindowSkiaLayerComponent(mediator, windowContext, renderDelegate, skiaLayerAnalytics) | |||
WindowSkiaLayerComponent( | |||
mediator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add explicit parameter names if it's not one-liner
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we add them when variables match parameter names or are obvious?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to add it to be on the safe side during possible refactoring
properties = run { | ||
val defaultProperties = SkiaLayerProperties() | ||
|
||
SkiaLayerProperties( | ||
isVsyncEnabled = renderingSettings.isVsyncEnabled ?: defaultProperties.isVsyncEnabled, | ||
) | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
properties = run { | |
val defaultProperties = SkiaLayerProperties() | |
SkiaLayerProperties( | |
isVsyncEnabled = renderingSettings.isVsyncEnabled ?: defaultProperties.isVsyncEnabled, | |
) | |
}, | |
properties = SkiaLayerProperties( | |
isVsyncEnabled = renderingSettings.isVsyncEnabled ?: SkiaLayerProperties.Default.isVsyncEnabled, | |
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There can be multiple properties in future, this approach will reconstruct SkiaLayerProperties every single time. There is no Default
in SkiaLayerProperties.Companion
…enderingSettings.desktop.kt Co-authored-by: Ivan Matkov <ivan.matkov@jetbrains.com>
This reverts commit d242e85.
reducePresentationLatency
to ComposePanel
RenderSettings
to ComposePanel
compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposePanel.desktop.kt
Outdated
Show resolved
Hide resolved
…omposePanel.desktop.kt Co-authored-by: Ivan Matkov <ivan.matkov@jetbrains.com>
*/ | ||
@ExperimentalComposeUiApi | ||
class RenderingSettings( | ||
val isVsyncEnabled: Boolean? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better/cleaner to put this in a (fake) enum, e.g. VSyncMode.Enabled
, VSyncMode.Disabled
, and VsyncMode.Default
. Although maybe it's overkill here; not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd leave it as it is now (ExperimentalAPI after all), I haven't yet performed an investigation about different presentation modes on non-Metal rendering backends.
* by Swing. | ||
*/ | ||
@ExperimentalComposeUiApi | ||
class RenderingSettings( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe RenderSettings
instead? A bit shorter and doesn't lose any meaning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, sounds fine
Btw the latency issue exists on windows as well (didn't try linux) and disabling vsync reduces the latency significantly there. So it's not only a macos thing. |
@elijah-semyonov, please actualise Release Notes |
Fixes JetBrains/compose-multiplatform#4870
Release Notes
Features - Desktop
RenderSettings
toComposePanel
. Added a classRenderSettings
withval isVsyncEnabled: Boolean?
. When set totrue
gives a hint to renderer implementation of the particularComposePanel
to reduce the latency between the input and visual changes in exchange for possible screen tearing.