Unverified Commit 233ceed4 authored by Oleksandr Karpovich's avatar Oleksandr Karpovich Committed by GitHub

document js Wrapper functions and hide internal functions (#483)

* document js Wrapper functions and hide internal functions

* docs for CanvasRenderer and SkiaLayer in jsMain
Co-authored-by: 's avatarOleksandr Karpovich <oleksandr.karpovich@jetbrains.com>
parent 99eeba54
......@@ -8,19 +8,39 @@ import org.jetbrains.skia.DirectContext
import org.jetbrains.skia.Surface
import org.jetbrains.skia.SurfaceColorFormat
import org.jetbrains.skia.SurfaceOrigin
import org.jetbrains.skiko.wasm.CreateWebGLContext
import org.jetbrains.skiko.wasm.createWebGLContext
import org.jetbrains.skiko.wasm.GL
import org.w3c.dom.HTMLCanvasElement
/**
* CanvasRenderer takes an [HTMLCanvasElement] instance and initializes
* skiko's [Canvas] used for drawing (see [initCanvas]).
*
* After initialization [needRedraw] can be used to schedule a call to [drawFrame].
* [drawFrame] has to be implemented to perform the actual drawing on [canvas].
*/
abstract class CanvasRenderer constructor(val htmlCanvas: HTMLCanvasElement) {
private val contextPointer = CreateWebGLContext(htmlCanvas)
private val contextPointer = createWebGLContext(htmlCanvas)
private val context: DirectContext
private var surface: Surface? = null
private var renderTarget: BackendRenderTarget? = null
var canvas: Canvas? = null
/**
* An instance of skiko [Canvas] used for drawing.
* Created in [initCanvas].
*/
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
......@@ -29,6 +49,14 @@ abstract class CanvasRenderer constructor(val htmlCanvas: HTMLCanvasElement) {
context = DirectContext.makeGL()
}
/**
* 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) {
disposeCanvas()
htmlCanvas.width = (desiredWidth * scale).toInt()
......@@ -44,17 +72,25 @@ abstract class CanvasRenderer constructor(val htmlCanvas: HTMLCanvasElement) {
canvas = surface!!.canvas
}
fun disposeCanvas() {
private fun disposeCanvas() {
surface?.close()
surface = null
renderTarget?.close()
renderTarget = null
}
/**
* This function should implement the actual drawing on the canvas.
*
* @param currentTimestamp - in milliseconds
*/
abstract fun drawFrame(currentTimestamp: Double)
private var redrawScheduled = false
/**
* Schedules a call to [drawFrame] to the appropriate moment.
*/
fun needRedraw() {
if (redrawScheduled) {
return
......
......@@ -8,27 +8,56 @@ import org.w3c.dom.events.KeyboardEvent
import org.w3c.dom.events.MouseEvent
import org.w3c.dom.events.WheelEvent
/**
* Provides a way to render the content and to receive the input events.
* Rendering and events processing should be implemented in [skikoView].
*
* SkikoLayer needs to be initialized with [HTMLCanvasElement] instance
* using [attachTo] method.
*/
actual open class SkiaLayer {
private var state: CanvasRenderer? = null
/**
* [GraphicsApi.WEBGL] is the only supported renderApi for k/js (browser).
*/
actual var renderApi: GraphicsApi = GraphicsApi.WEBGL
/**
* See https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio
*/
actual val contentScale: Float
get() = window.devicePixelRatio.toFloat()
/**
* Fullscreen is not supported
*/
actual var fullscreen: Boolean
get() = false
set(value) {
if (value) throw Exception("Fullscreen is not supported!")
}
/**
* Transparency is not supported
*/
actual var transparency: Boolean
get() = false
set(value) {
if (value) throw Exception("Transparency is not supported!")
}
/**
* Schedules a drawFrame to the appropriate moment.
*/
actual fun needRedraw() {
state?.needRedraw()
}
/**
* An implementation of SkikoView with content rendering and
* event processing logic.
*/
actual var skikoView: SkikoView? = null
actual fun attachTo(container: Any) {
......@@ -44,6 +73,10 @@ actual open class SkiaLayer {
private var desiredWidth = 0
private var desiredHeight = 0
/**
* Initializes the [CanvasRenderer] and events listeners.
* Delegates rendering and events processing to [skikoView].
*/
fun attachTo(htmlCanvas: HTMLCanvasElement, autoDetach: Boolean = true) {
// Scale canvas to allow high DPI rendering as suggested in
// https://www.khronos.org/webgl/wiki/HandlingHighDPI.
......
......@@ -4,20 +4,26 @@ import org.jetbrains.skia.impl.NativePointer
import org.w3c.dom.HTMLCanvasElement
import kotlin.js.Promise
external val wasmSetup: Promise<Boolean>
/**
* Invokes a callback [onReady] as soon as onRuntimeInitialized happens.
* Calling onWasmReady after onRuntimeInitialized invokes [onReady] as well.
* It's safe to call wasm functions within [onReady] callback, or after it was invoked.
*/
external fun onWasmReady(onReady: () -> Unit)
external interface GLInterface {
internal external val wasmSetup: Promise<Boolean>
private external interface GLInterface {
fun createContext(context: HTMLCanvasElement, contextAttributes: dynamic): NativePointer;
fun makeContextCurrent(contextPointer: NativePointer): Boolean;
}
external object GL : GLInterface {
internal external object GL : GLInterface {
override fun createContext(context: HTMLCanvasElement, contextAttributes: dynamic): Int = definedExternally
override fun makeContextCurrent(contextPointer: NativePointer): Boolean = definedExternally
}
external interface ContextAttributes {
internal external interface ContextAttributes {
val alpha: Int?
val depth: Int?
val stencil: Int?
......@@ -32,7 +38,7 @@ external interface ContextAttributes {
val majorVersion: Int?
}
fun ContextAttributes.asJsObject(): dynamic {
internal fun ContextAttributes.asJsObject(): dynamic {
val jsObject = js("{}")
alpha?.let { jsObject.alpha = alpha }
depth?.let { jsObject.depth = depth }
......@@ -50,7 +56,7 @@ fun ContextAttributes.asJsObject(): dynamic {
}
fun CreateWebGLContext(canvas: HTMLCanvasElement, attr: ContextAttributes? = null): NativePointer {
internal fun createWebGLContext(canvas: HTMLCanvasElement, attr: ContextAttributes? = null): NativePointer {
val contextAttributes = object : ContextAttributes {
override val alpha = attr?.alpha ?: 1
override val depth = attr?.depth ?: 1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment