Skip to content

Commit

Permalink
Wire rendering settings
Browse files Browse the repository at this point in the history
  • Loading branch information
elijah-semyonov committed Jun 12, 2024
1 parent dee558d commit 22022fa
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,26 @@ import org.jetbrains.skiko.SkiaLayerAnalytics
class ComposePanel @ExperimentalComposeUiApi constructor(
private val skiaLayerAnalytics: SkiaLayerAnalytics,
) : JLayeredPane() {
private var renderingSettings = RenderingSettings.Default

constructor() : this(SkiaLayerAnalytics.Empty)

/**
* Creates a ComposePanel with the given [skiaLayerAnalytics] and [renderingSettings].
*
* @param skiaLayerAnalytics Analytics that helps to know more about SkiaLayer behaviour.
* SkiaLayer is underlying class used internally to draw Compose content.
* Implementation usually uses third-party solution to send info to some centralized analytics gatherer.
* @param renderingSettings Configuration class for rendering settings.
*/
@ExperimentalComposeUiApi
constructor(
skiaLayerAnalytics: SkiaLayerAnalytics = SkiaLayerAnalytics.Empty,
renderingSettings: RenderingSettings,
) : this(skiaLayerAnalytics) {
this.renderingSettings = renderingSettings
}

init {
check(isEventDispatchThread()) {
"ComposePanel should be created inside AWT Event Dispatch Thread" +
Expand Down Expand Up @@ -196,7 +214,8 @@ class ComposePanel @ExperimentalComposeUiApi constructor(
return ComposeContainer(
container = this,
skiaLayerAnalytics = skiaLayerAnalytics,
windowContainer = windowContainer
windowContainer = windowContainer,
renderingSettings = renderingSettings,
).apply {
focusManager.releaseFocus()
setBounds(0, 0, width, height)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ internal class ComposeWindowPanel(
// but it's always disabled here. Using fallback instead of [check] to support
// opening separate windows from [ComposePanel] with such layer type.
if (it == LayerType.OnComponent) LayerType.OnSameCanvas else it
}
},
// TODO: Add RenderingSettings to ComposeWindowPanel constructor
renderingSettings = RenderingSettings.Default
)
private val composeContainer
get() = requireNotNull(_composeContainer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package androidx.compose.ui.awt

import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.ComposeFeatureFlags
import org.jetbrains.skiko.SkikoProperties

/**
* Configuration class for rendering settings.
Expand All @@ -28,12 +29,23 @@ import androidx.compose.ui.ComposeFeatureFlags
* exchange for a latency increase.
* When false, the internal implementation will not attempt to synchronize drawable presentations
* it can reduce latency but may introduce visual artifacts like screen tearing.
* When null, the internal implementation will use the global configuration from [SkikoProperties.vsyncEnabled]
*
* This flag has no effect if [ComposeFeatureFlags.useSwingGraphics] is true. In this case Compose
* will render the content to Swing provided offscreen buffer and the presentation will be controlled
* by Swing.
*/
@ExperimentalComposeUiApi
class RenderingSettings(
val isVsyncEnabled: Boolean
)
val isVsyncEnabled: Boolean?

) {
companion object {
/**
* Default rendering settings
*/
val Default = RenderingSettings(
isVsyncEnabled = null
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import androidx.compose.ui.LayerType
import androidx.compose.ui.awt.AwtEventFilter
import androidx.compose.ui.awt.AwtEventListener
import androidx.compose.ui.awt.AwtEventListeners
import androidx.compose.ui.awt.RenderingSettings
import androidx.compose.ui.input.key.KeyEvent
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.platform.LocalInternalViewModelStoreOwner
Expand Down Expand Up @@ -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.
*/
internal class ComposeContainer(
val container: JLayeredPane,
Expand All @@ -88,6 +90,7 @@ internal class ComposeContainer(

private val useSwingGraphics: Boolean = ComposeFeatureFlags.useSwingGraphics,
private val layerType: LayerType = ComposeFeatureFlags.layerType,
private val renderingSettings: RenderingSettings,
) : WindowFocusListener, WindowListener, LifecycleOwner, ViewModelStoreOwner {
val windowContext = PlatformWindowContext()
var window: Window? = null
Expand Down Expand Up @@ -338,7 +341,13 @@ internal class ComposeContainer(
return if (useSwingGraphics) {
SwingSkiaLayerComponent(mediator, renderDelegate, skiaLayerAnalytics)
} else {
WindowSkiaLayerComponent(mediator, windowContext, renderDelegate, skiaLayerAnalytics)
WindowSkiaLayerComponent(
mediator,
windowContext,
renderDelegate,
skiaLayerAnalytics,
renderingSettings
)
}
}

Expand Down Expand Up @@ -381,7 +390,8 @@ internal class ComposeContainer(
density = density,
layoutDirection = layoutDirection,
focusable = focusable,
compositionContext = compositionContext
compositionContext = compositionContext,
renderingSettings = renderingSettings
)
LayerType.OnComponent -> SwingComposeSceneLayer(
composeContainer = this,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package androidx.compose.ui.scene

import org.jetbrains.skia.Rect as SkRect
import androidx.compose.runtime.CompositionContext
import androidx.compose.ui.awt.RenderingSettings
import androidx.compose.ui.awt.getTransparentWindowBackground
import androidx.compose.ui.awt.setTransparent
import androidx.compose.ui.awt.toAwtRectangle
Expand Down Expand Up @@ -52,7 +53,8 @@ internal class WindowComposeSceneLayer(
density: Density,
layoutDirection: LayoutDirection,
focusable: Boolean,
compositionContext: CompositionContext
compositionContext: CompositionContext,
private val renderingSettings: RenderingSettings
) : DesktopComposeSceneLayer(composeContainer, density, layoutDirection) {
private val window get() = requireNotNull(composeContainer.window)
private val windowContext = PlatformWindowContext().also {
Expand Down Expand Up @@ -193,7 +195,8 @@ internal class WindowComposeSceneLayer(
mediator = mediator,
windowContext = windowContext,
renderDelegate = renderDelegate,
skiaLayerAnalytics = skiaLayerAnalytics
skiaLayerAnalytics = skiaLayerAnalytics,
renderingSettings = renderingSettings,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package androidx.compose.ui.scene.skia

import androidx.compose.ui.awt.RenderingSettings
import androidx.compose.ui.platform.PlatformWindowContext
import androidx.compose.ui.scene.ComposeSceneMediator
import java.awt.Dimension
Expand All @@ -24,6 +25,7 @@ import javax.accessibility.Accessible
import org.jetbrains.skiko.GraphicsApi
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skiko.SkiaLayerAnalytics
import org.jetbrains.skiko.SkiaLayerProperties
import org.jetbrains.skiko.SkikoRenderDelegate

/**
Expand All @@ -36,7 +38,8 @@ internal class WindowSkiaLayerComponent(
private val mediator: ComposeSceneMediator,
private val windowContext: PlatformWindowContext,
renderDelegate: SkikoRenderDelegate,
skiaLayerAnalytics: SkiaLayerAnalytics
skiaLayerAnalytics: SkiaLayerAnalytics,
private val renderingSettings: RenderingSettings,
) : SkiaLayerComponent {
/**
* See also backend layer for swing interop in [SwingSkiaLayerComponent]
Expand All @@ -47,6 +50,13 @@ internal class WindowSkiaLayerComponent(
// apply `checkNotNull` for "non-null" field.
checkNotNull(mediator.accessible)
},
properties = run {
val defaultProperties = SkiaLayerProperties()

SkiaLayerProperties(
isVsyncEnabled = renderingSettings.isVsyncEnabled ?: defaultProperties.isVsyncEnabled,
)
},
analytics = skiaLayerAnalytics
) {
override fun paint(g: Graphics) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package androidx.compose.ui.window

import androidx.compose.ui.assertThat
import androidx.compose.ui.awt.RenderingSettings
import androidx.compose.ui.isEqualTo
import androidx.compose.ui.scene.ComposeContainer
import androidx.lifecycle.Lifecycle
Expand Down Expand Up @@ -142,7 +143,8 @@ class ComposeContainerLifecycleOwnerTest {
container = ComposeContainer(
container = pane,
skiaLayerAnalytics = SkiaLayerAnalytics.Empty,
window = window
window = window,
renderingSettings = RenderingSettings.Default
).also {
it.lifecycle.addObserver(allEvents)
}
Expand Down Expand Up @@ -172,7 +174,8 @@ class ComposeContainerLifecycleOwnerTest {
container = ComposeContainer(
container = pane,
skiaLayerAnalytics = SkiaLayerAnalytics.Empty,
window = window
window = window,
renderingSettings = RenderingSettings.Default
).also {
it.lifecycle.addObserver(allEvents)
}
Expand Down Expand Up @@ -202,7 +205,8 @@ class ComposeContainerLifecycleOwnerTest {
container = ComposeContainer(
container = pane,
skiaLayerAnalytics = SkiaLayerAnalytics.Empty,
window = window
window = window,
renderingSettings = RenderingSettings.Default
).also {
it.lifecycle.addObserver(allEvents)
}
Expand Down Expand Up @@ -250,7 +254,8 @@ class ComposeContainerLifecycleOwnerTest {
container = ComposeContainer(
container = this,
skiaLayerAnalytics = SkiaLayerAnalytics.Empty,
window = window
window = window,
renderingSettings = RenderingSettings.Default
)
container.lifecycle.addObserver(observer)
window.add(this)
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ moshi = "1.13.0"
protobuf = "3.21.8"
paparazzi = "1.0.0"
paparazziNative = "2022.1.1-canary-f5f9f71"
skiko = "0.8.4"
skiko = "0.8.6"
sqldelight = "1.3.0"
retrofit = "2.7.2"
wire = "4.5.1"
Expand Down

0 comments on commit 22022fa

Please sign in to comment.