Skip to content

Commit

Permalink
Remove media events from Skiko completely (#892)
Browse files Browse the repository at this point in the history
This is the skiko part of
https://youtrack.jetbrains.com/issue/COMPOSE-1149/wasm-js-Remove-media-events-from-Skiko

This commit introduces following changes:

 * CanvasRenderer is html-agnostic and deals with NativePointer
* SkiaLayer does not set any DOM dimensions of the canvas - it's up to
the user of the Skia to resolve this dimensions
 * Media event listeners are removed completely
  • Loading branch information
Schahen authored Mar 13, 2024
1 parent 574e3ee commit 4721587
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 91 deletions.
6 changes: 3 additions & 3 deletions samples/SkiaJsSample/src/jsMain/resources/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@

<body>
<h1>Skiko running with K/JS</h1>
<canvas id="c1" width="300" height="300"></canvas>
<canvas id="c2" width="300" height="300"></canvas>
<canvas id="c1" width="600" height="600" style="width: 300px; height: 300px"></canvas>
<canvas id="c2" width="600" height="600" style="width: 300px; height: 300px"></canvas>
<div>
<canvas id="c3" width="606" height="400"></canvas>
<canvas id="c3" width="1212" height="800" style="width: 606px; height: 400px"></canvas>
</div>
</body>
</html>
6 changes: 3 additions & 3 deletions samples/SkiaJsSample/src/wasmJsMain/resources/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@

<body>
<h1>Skiko running with K/Wasm</h1>
<canvas id="c1" width="300" height="300"></canvas>
<canvas id="c2" width="300" height="300"></canvas>
<canvas id="c1" width="600" height="600" style="width: 300px; height: 300px"></canvas>
<canvas id="c2" width="600" height="600" style="width: 300px; height: 300px"></canvas>
<div>
<canvas id="c3" width="606" height="400"></canvas>
<canvas id="c3" width="1212" height="800" style="width: 606px; height: 400px"></canvas>
</div>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ fun main() {

internal fun runApp() {
val skiaLayer = SkiaLayer()
skiaLayer.onContentScaleChanged = { scale -> println(scale) }
val game = JsClocks(skiaLayer)
skiaLayer.skikoView = GenericSkikoView(skiaLayer, game)
val canvas = document.getElementById("SkikoTarget") as HTMLCanvasElement
canvas.setAttribute("tabindex", "0")
skiaLayer.attachTo(canvas)
skiaLayer.needRedraw()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ fun main() {

internal fun runApp() {
val skiaLayer = SkiaLayer()
skiaLayer.onContentScaleChanged = { scale -> println(scale) }
val game = JsClocks(skiaLayer)
skiaLayer.skikoView = GenericSkikoView(skiaLayer, game)
val canvas = document.getElementById("SkikoTarget") as HTMLCanvasElement
canvas.setAttribute("tabindex", "0")
skiaLayer.attachTo(canvas)
skiaLayer.needRedraw()
}
}
16 changes: 1 addition & 15 deletions skiko/src/jsMain/kotlin/org/jetbrains/skiko/SkiaLayer.js.kt
Original file line number Diff line number Diff line change
@@ -1,25 +1,11 @@
package org.jetbrains.skiko

import kotlinx.browser.window
import org.w3c.dom.AddEventListenerOptions
import org.w3c.dom.MediaQueryListEvent
import org.w3c.dom.events.KeyboardEvent
import org.w3c.dom.events.UIEvent

actual typealias SkikoGesturePlatformEvent = Any
actual typealias SkikoPlatformInputEvent = KeyboardEvent
actual typealias SkikoPlatformKeyboardEvent = KeyboardEvent

// MouseEvent is base class of PointerEvent
actual typealias SkikoPlatformPointerEvent = UIEvent

internal actual fun SkiaLayer.setOnChangeScaleNotifier() {
state?.initCanvas(desiredWidth, desiredHeight, contentScale, this.pixelGeometry)
window.matchMedia("(resolution: ${contentScale}dppx)")
.addEventListener("change", { evt ->
evt as MediaQueryListEvent
if (!evt.matches) {
setOnChangeScaleNotifier()
}
}, AddEventListenerOptions(capture = true, once = true))
onContentScaleChanged?.invoke(contentScale)
}
33 changes: 7 additions & 26 deletions skiko/src/jsWasmMain/kotlin/org/jetbrains/skiko/CanvasRenderer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import org.jetbrains.skiko.wasm.createWebGLContext
* [drawFrame] has to be implemented to perform the actual drawing on [canvas].
*/
internal abstract class CanvasRenderer(
private val htmlCanvas: HTMLCanvasElement
private val contextPointer: NativePointer,
val width: Int,
val height: Int,
) {
private val contextPointer = createWebGLContext(htmlCanvas)
private val context: DirectContext
private var surface: Surface? = null
private var renderTarget: BackendRenderTarget? = null
Expand All @@ -28,43 +29,23 @@ internal abstract class CanvasRenderer(
protected var canvas: Canvas? = null
private set

/**
* The current width of [htmlCanvas]
*/
val width: Int
get() = htmlCanvas.width

/**
* The current height of [htmlCanvas]
*/
val height: Int
get() = htmlCanvas.height

init {
makeGLContextCurrent(contextPointer)
context = DirectContext.makeGL()
initCanvas()
}

/**
* Initializes the canvas.
*
* @param desiredWidth - width in pixels
* @param desiredHeight - height in pixels
* @param scale - a value to adjust the canvas' size
* (https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio)
*/
fun initCanvas(desiredWidth: Int, desiredHeight: Int, scale: Float, pixelGeometry: PixelGeometry) {
fun initCanvas() {
disposeCanvas()
htmlCanvas.width = (desiredWidth * scale).toInt()
htmlCanvas.height = (desiredHeight * scale).toInt()

renderTarget = BackendRenderTarget.makeGL(width, height, 1, 8, 0, 0x8058)
surface = Surface.makeFromBackendRenderTarget(
context,
renderTarget!!,
SurfaceOrigin.BOTTOM_LEFT,
SurfaceColorFormat.RGBA_8888,
ColorSpace.sRGB,
SurfaceProps(pixelGeometry = pixelGeometry)
SurfaceProps()
) ?: throw RenderException("Cannot create surface")
canvas = surface!!.canvas
}
Expand Down
30 changes: 6 additions & 24 deletions skiko/src/jsWasmMain/kotlin/org/jetbrains/skiko/SkiaLayer.js.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.jetbrains.skia.Canvas
import org.jetbrains.skia.PixelGeometry
import org.jetbrains.skiko.w3c.HTMLCanvasElement
import org.jetbrains.skiko.w3c.window
import org.jetbrains.skiko.wasm.createWebGLContext

/**
* Provides a way to render the content and to receive the input events.
Expand Down Expand Up @@ -61,18 +62,13 @@ actual open class SkiaLayer {
* @param container - should be an instance of [HTMLCanvasElement]
*/
actual fun attachTo(container: Any) {
attachTo(container as HTMLCanvasElement, false)
attachTo(container as HTMLCanvasElement)
}

actual fun detach() {
// TODO: when switch to the frame dispatcher - stop it here.
}

internal var isPointerPressed = false

internal var desiredWidth = 0
internal var desiredHeight = 0

actual val component: Any?
get() = this.htmlCanvas

Expand All @@ -82,25 +78,16 @@ actual open class SkiaLayer {
* Initializes the [CanvasRenderer] and events listeners.
* Delegates rendering and events processing to [skikoView].
*/
private fun attachTo(htmlCanvas: HTMLCanvasElement, autoDetach: Boolean = true) {
private fun attachTo(htmlCanvas: HTMLCanvasElement) {
this.htmlCanvas = htmlCanvas

// Scale canvas to allow high DPI rendering as suggested in
// https://www.khronos.org/webgl/wiki/HandlingHighDPI.
desiredWidth = htmlCanvas.width
desiredHeight = htmlCanvas.height
htmlCanvas.style.width = "${desiredWidth}px"
htmlCanvas.style.height = "${desiredHeight}px"
setOnChangeScaleNotifier()
state = object: CanvasRenderer(htmlCanvas) {
state = object: CanvasRenderer(createWebGLContext(htmlCanvas), htmlCanvas.width, htmlCanvas.height) {
override fun drawFrame(currentTimestamp: Double) {
// currentTimestamp is in milliseconds.
val currentNanos = currentTimestamp * 1_000_000
skikoView?.onRender(canvas!!, width, height, currentNanos.toLong())
}
}.apply { initCanvas(desiredWidth, desiredHeight, contentScale, pixelGeometry) }
// See https://www.w3schools.com/jsref/dom_obj_event.asp
// https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events
}
}

internal actual fun draw(canvas: Canvas) {
Expand All @@ -109,9 +96,4 @@ actual open class SkiaLayer {

actual val pixelGeometry: PixelGeometry
get() = PixelGeometry.UNKNOWN

var onContentScaleChanged: ((Float) -> Unit)? = null
}


internal expect fun SkiaLayer.setOnChangeScaleNotifier()
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package org.jetbrains.skiko

import kotlinx.browser.window
import org.w3c.dom.AddEventListenerOptions
import org.w3c.dom.MediaQueryListEvent

import org.w3c.dom.events.KeyboardEvent
import org.w3c.dom.events.UIEvent

Expand All @@ -12,15 +8,3 @@ actual typealias SkikoGesturePlatformEvent = Any
actual typealias SkikoPlatformInputEvent = KeyboardEvent
actual typealias SkikoPlatformKeyboardEvent = KeyboardEvent
actual typealias SkikoPlatformPointerEvent = UIEvent

internal actual fun SkiaLayer.setOnChangeScaleNotifier() {
state?.initCanvas(desiredWidth, desiredHeight, contentScale, this.pixelGeometry)
window.matchMedia("(resolution: ${contentScale}dppx)")
.addEventListener("change", { evt ->
evt as MediaQueryListEvent
if (!evt.matches) {
setOnChangeScaleNotifier()
}
}, AddEventListenerOptions(capture = true, once = true))
onContentScaleChanged?.invoke(contentScale)
}

0 comments on commit 4721587

Please sign in to comment.