Unverified Commit 60191b83 authored by Shagen Ogandzhanian's avatar Shagen Ogandzhanian Committed by GitHub

Introduce minimal initialization layer for using it as API on the frontend side (#194)

parent 16b2dee5
package org.jetbrains.skiko.sample.js package org.jetbrains.skiko.sample.js
import org.jetbrains.skia.Paint import org.jetbrains.skia.Paint
import org.jetbrains.skiko.wasm.onWasmReady
fun main(args: Array<String>) { fun main(args: Array<String>) {
println(Paint()) onWasmReady {
println(Paint())
}
} }
\ No newline at end of file
...@@ -4,10 +4,6 @@ ...@@ -4,10 +4,6 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>skiko for web demo</title> <title>skiko for web demo</title>
<script src="skiko.js"> </script> <script src="skiko.js"> </script>
<script>
// Temporary, to debug loading issues.
initRuntime();
</script>
<script src="SkiaJsSample.js"> </script> <script src="SkiaJsSample.js"> </script>
</head> </head>
<body> <body>
......
...@@ -354,13 +354,16 @@ val wasmCompile = project.tasks.register<Exec>("wasmCompile") { ...@@ -354,13 +354,16 @@ val wasmCompile = project.tasks.register<Exec>("wasmCompile") {
val outJs = "$outDir/skiko.js" val outJs = "$outDir/skiko.js"
val outWasm = "$outDir/skiko.wasm" val outWasm = "$outDir/skiko.wasm"
workingDir = File(outDir) workingDir = File(outDir)
val skikoJsPrefix = "$projectDir/src/jsMain/resources/setup.js"
if (supportWasm) { if (supportWasm) {
commandLine = listOf( commandLine = listOf(
"emcc", "emcc",
*buildType.clangFlags,
*Arch.Wasm.clangFlags, *Arch.Wasm.clangFlags,
"-I$projectDir/src/commonMain/cpp", "-I$projectDir/src/commonMain/cpp",
*skiaPreprocessorFlags(skiaDir), *skiaPreprocessorFlags(skiaDir),
"-o", outJs, "-o", outJs,
"--extern-post-js", skikoJsPrefix,
*srcs *srcs
) )
argumentProviders.add(CommandLineArgumentProvider { argumentProviders.add(CommandLineArgumentProvider {
...@@ -377,7 +380,7 @@ val wasmCompile = project.tasks.register<Exec>("wasmCompile") { ...@@ -377,7 +380,7 @@ val wasmCompile = project.tasks.register<Exec>("wasmCompile") {
) )
} }
file(outDir).mkdirs() file(outDir).mkdirs()
inputs.files(srcs) inputs.files(srcs + listOf(skikoJsPrefix))
outputs.files(outJs, outWasm) outputs.files(outJs, outWasm)
} }
......
...@@ -6,13 +6,11 @@ config.browserConsoleLogOptions.level = "debug"; ...@@ -6,13 +6,11 @@ config.browserConsoleLogOptions.level = "debug";
const basePath = config.basePath; const basePath = config.basePath;
const projectPath = path.resolve(basePath, "..", "..", "..", "..", ".."); const projectPath = path.resolve(basePath, "..", "..", "..", "..", "..");
const setupPath = path.resolve(projectPath, "src", "jsTest", "config");
const wasmPath = path.resolve(projectPath, "build", "wasm") const wasmPath = path.resolve(projectPath, "build", "wasm")
const debug = message => console.log(`[karma-config] ${message}`); const debug = message => console.log(`[karma-config] ${message}`);
debug(`karma basePath: ${basePath}`); debug(`karma basePath: ${basePath}`);
debug(`karma setupPath: ${setupPath}`);
debug(`karma wasmPath: ${wasmPath}`); debug(`karma wasmPath: ${wasmPath}`);
config.proxies = { config.proxies = {
...@@ -20,7 +18,6 @@ config.proxies = { ...@@ -20,7 +18,6 @@ config.proxies = {
} }
config.files = [ config.files = [
path.resolve(setupPath, "wasmsetup.js"),
path.resolve(wasmPath, "skiko.js"), path.resolve(wasmPath, "skiko.js"),
{pattern: path.resolve(wasmPath, "skiko.wasm"), included: false, served: true, watched: false}, {pattern: path.resolve(wasmPath, "skiko.wasm"), included: false, served: true, watched: false},
].concat(config.files); ].concat(config.files);
......
#include "common.h" #include "common.h"
#include <emscripten.h>
typedef void (*finalizer_t)(void*); typedef void (*finalizer_t)(void*);
EMSCRIPTEN_KEEPALIVE SKIKO_EXPORT void org_jetbrains_skia_impl_Managed__invokeFinalizer(KNativePointer finalizer, KNativePointer obj) {
extern "C" void org_jetbrains_skia_ColorSpace__nInvokeFinalizer(KPointer finalizer, KPointer obj) {
finalizer_t finalizer_f = reinterpret_cast<finalizer_t>(finalizer); finalizer_t finalizer_f = reinterpret_cast<finalizer_t>(finalizer);
finalizer_f(obj); finalizer_f(obj);
} }
\ No newline at end of file
#include "common.h" #include "common.h"
#include "SkRefCnt.h" #include "SkRefCnt.h"
class SkRefCntHack { class SkRefCntHack {
...@@ -11,12 +12,11 @@ void unrefSkRefCnt(SkRefCnt* p) { ...@@ -11,12 +12,11 @@ void unrefSkRefCnt(SkRefCnt* p) {
p->unref(); p->unref();
} }
extern "C" KNativePointer org_jetbrains_skia_impl_RefCnt__1nGetFinalizer() { SKIKO_EXPORT KNativePointer org_jetbrains_skia_impl_RefCnt__getFinalizer() {
return reinterpret_cast<KNativePointer>(&unrefSkRefCnt); return reinterpret_cast<KNativePointer>(&unrefSkRefCnt);
} }
extern "C" KInt org_jetbrains_skia_impl_RefCnt__1nGetRefCount(KNativePointer ptr) { SKIKO_EXPORT KInt org_jetbrains_skia_impl_RefCnt__getRefCount(KNativePointer ptr) {
SkRefCnt* instance = reinterpret_cast<SkRefCnt*>(ptr); SkRefCnt* instance = reinterpret_cast<SkRefCnt*>(ptr);
return reinterpret_cast<SkRefCntHack*>(instance)->fRefCnt.load(std::memory_order_relaxed); return reinterpret_cast<SkRefCntHack*>(instance)->fRefCnt.load(std::memory_order_relaxed);
} }
...@@ -11,17 +11,15 @@ ...@@ -11,17 +11,15 @@
#include "SkFilterQuality.h" #include "SkFilterQuality.h"
#include "common.h" #include "common.h"
static void deletePaint(SkPaint* paint) { void deletePaint(SkPaint* paint) {
delete paint; delete paint;
} }
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Paint__1nGetFinalizer SKIKO_EXPORT KNativePointer org_jetbrains_skia_Paint__1nGetFinalizer(){
(){ return reinterpret_cast<KNativePointer>(&deletePaint);
return reinterpret_cast<KNativePointer>((&deletePaint));
} }
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Paint__1nMake SKIKO_EXPORT KNativePointer org_jetbrains_skia_Paint__1nMake(){
(){
SkPaint* obj = new SkPaint(); SkPaint* obj = new SkPaint();
obj->setAntiAlias(true); obj->setAntiAlias(true);
return reinterpret_cast<KNativePointer>(obj); return reinterpret_cast<KNativePointer>(obj);
......
...@@ -11,6 +11,8 @@ expect abstract class Native(ptr: NativePointer) { ...@@ -11,6 +11,8 @@ expect abstract class Native(ptr: NativePointer) {
companion object { companion object {
val NullPointer: NativePointer val NullPointer: NativePointer
} }
override fun toString(): String
} }
expect fun reachabilityBarrier(obj: Any?) expect fun reachabilityBarrier(obj: Any?)
......
#include <emscripten.h>
#include "common.h"
#include "SkRefCnt.h"
class SkRefCntHack {
public:
void* x;
mutable std::atomic<int32_t> fRefCnt;
};
void unrefSkRefCnt(SkRefCnt* p) {
p->unref();
}
EMSCRIPTEN_KEEPALIVE
extern "C" KPointer org_jetbrains_skia_impl_RefCnt__1nGetFinalizer() {
return reinterpret_cast<KPointer>(&unrefSkRefCnt);
}
EMSCRIPTEN_KEEPALIVE
extern "C" KInt org_jetbrains_skia_impl_RefCnt__1nGetRefCount(KPointer ptr) {
SkRefCnt* instance = reinterpret_cast<SkRefCnt*>(ptr);
return reinterpret_cast<SkRefCntHack*>(instance)->fRefCnt.load(std::memory_order_relaxed);
}
#pragma once
#include <stdint.h>
typedef int32_t KInt;
typedef int64_t KLong;
typedef void* KPointer;
typedef uint8_t* KByteArray;
...@@ -3,8 +3,6 @@ package org.jetbrains.skia.impl ...@@ -3,8 +3,6 @@ package org.jetbrains.skia.impl
actual class Library { actual class Library {
actual companion object { actual companion object {
actual fun staticLoad() { actual fun staticLoad() {
// TODO: load wasm and js modules, maybe just js, as it will load Wasm.
TODO()
} }
} }
} }
...@@ -49,12 +49,12 @@ actual abstract class Managed actual constructor(ptr: NativePointer, finalizer: ...@@ -49,12 +49,12 @@ actual abstract class Managed actual constructor(ptr: NativePointer, finalizer:
if (managed) { if (managed) {
require(ptr != 0) { "Managed ptr is 0" } require(ptr != 0) { "Managed ptr is 0" }
require(finalizer != 0) { "Managed finalizer is 0" } require(finalizer != 0) { "Managed finalizer is 0" }
val thunk = FinalizationThunk(ptr, finalizer) val thunk = FinalizationThunk(finalizer, ptr)
register(this, thunk) register(this, thunk)
cleaner = thunk cleaner = thunk
} }
} }
} }
@JsName("org_jetbrains_skia_Managed__invokeFinalizer") @JsName("org_jetbrains_skia_impl_Managed__invokeFinalizer")
private external fun _nInvokeFinalizer(finalizer: NativePointer, obj: NativePointer) private external fun _nInvokeFinalizer(finalizer: NativePointer, obj: NativePointer)
\ No newline at end of file
...@@ -10,6 +10,10 @@ actual abstract class Native actual constructor(ptr: NativePointer) { ...@@ -10,6 +10,10 @@ actual abstract class Native actual constructor(ptr: NativePointer) {
get() = 0 get() = 0
} }
actual override fun toString(): String {
return this::class.simpleName + "(_ptr=0x" + _ptr.toString(16) + ")"
}
init { init {
if (ptr == NullPointer) throw RuntimeException("Can't wrap nullptr") if (ptr == NullPointer) throw RuntimeException("Can't wrap nullptr")
_ptr = ptr _ptr = ptr
......
...@@ -20,7 +20,7 @@ private object _FinalizerHolder { ...@@ -20,7 +20,7 @@ private object _FinalizerHolder {
val PTR = _nGetFinalizer() val PTR = _nGetFinalizer()
} }
@JsName("org_jetbrains_skia_RefCnt__nGetFinalizer") @JsName("org_jetbrains_skia_impl_RefCnt__getFinalizer")
private external fun _nGetFinalizer(): NativePointer private external fun _nGetFinalizer(): NativePointer
@JsName("org_jetbrains_skia_RefCnt__nGetCount") @JsName("org_jetbrains_skia_impl_RefCnt__getCount")
private external fun _nGetRefCount(ptr: NativePointer): Int private external fun _nGetRefCount(ptr: NativePointer): Int
...@@ -3,7 +3,10 @@ package org.jetbrains.skiko.wasm ...@@ -3,7 +3,10 @@ package org.jetbrains.skiko.wasm
import kotlinx.dom.createElement import kotlinx.dom.createElement
import kotlinx.browser.document import kotlinx.browser.document
import org.w3c.dom.HTMLCanvasElement import org.w3c.dom.HTMLCanvasElement
import kotlin.js.Promise
external val wasmSetup: Promise<Boolean>
external fun onWasmReady(onReady: () -> Unit)
@JsExport @JsExport
fun createSkikoCanvas(): HTMLCanvasElement { fun createSkikoCanvas(): HTMLCanvasElement {
......
var Module = {}; var wasmSetup = new Promise(function(resolve, reject) {
Module['locateFile'] = (path, scriptDirectory) => {
return "/wasm/skiko.wasm";
};
var ModulePromised = new Promise(function(resolve, reject) {
Module['onRuntimeInitialized'] = _ => { Module['onRuntimeInitialized'] = _ => {
resolve(Module); resolve(Module);
}; };
}); });
function onWasmReady(onReady) { wasmSetup.then(onReady); }
...@@ -12,24 +12,20 @@ external interface ModuleInterface { ...@@ -12,24 +12,20 @@ external interface ModuleInterface {
fun ping(): Boolean fun ping(): Boolean
} }
external val ModulePromised: Promise<ModuleInterface> external val Module: ModuleInterface
suspend fun <T> Promise<T>.await(): T = suspendCoroutine { cont -> suspend fun <T> Promise<T>.await(): T = suspendCoroutine { cont ->
then({ cont.resume(it) }, { cont.resumeWithException(it) }) then({ cont.resume(it) }, { cont.resumeWithException(it) })
} }
private fun async(block: suspend () -> Unit): dynamic = GlobalScope.promise { private fun wasmTest(block: () -> Unit) = GlobalScope.promise {
block() wasmSetup.await()
} block.invoke()
private fun withModule(block: ModuleInterface.() -> Unit) = async {
val module = ModulePromised.await()
block.invoke(module)
} }
class WasmTests { class WasmTests {
@Test @Test
fun pingTest() = withModule { fun pingTest() = wasmTest {
assertTrue(this.ping()) assertTrue(Module.ping())
} }
} }
\ No newline at end of file
...@@ -10,7 +10,7 @@ actual abstract class Native actual constructor(ptr: NativePointer) { ...@@ -10,7 +10,7 @@ actual abstract class Native actual constructor(ptr: NativePointer) {
get() = 0L get() = 0L
} }
override fun toString(): String { actual override fun toString(): String {
return javaClass.simpleName + "(_ptr=0x" + _ptr.toString(16) + ")" return javaClass.simpleName + "(_ptr=0x" + _ptr.toString(16) + ")"
} }
......
#include <iostream>
#include "common.h"
typedef void (*FreeFunction)(void*);
extern "C" void org_jetbrains_skia_impl_Managed__1nInvokeFinalizer
(KNativePointer finalizerPtr, KNativePointer ptr) {
FreeFunction finalizer = reinterpret_cast<FreeFunction>(finalizerPtr);
finalizer(ptr);
}
...@@ -59,5 +59,5 @@ actual abstract class Managed actual constructor( ...@@ -59,5 +59,5 @@ actual abstract class Managed actual constructor(
get() = _ptr == NullPointer get() = _ptr == NullPointer
} }
@ExternalSymbolName("org_jetbrains_skia_impl_Managed__1nInvokeFinalizer") @ExternalSymbolName("org_jetbrains_skia_impl_Managed__invokeFinalizer")
external fun _nInvokeFinalizer(finalizer: NativePointer, ptr: NativePointer) external fun _nInvokeFinalizer(finalizer: NativePointer, ptr: NativePointer)
...@@ -7,9 +7,6 @@ import kotlin.native.internal.NativePtr ...@@ -7,9 +7,6 @@ import kotlin.native.internal.NativePtr
actual abstract class Native actual constructor(ptr: NativePointer) { actual abstract class Native actual constructor(ptr: NativePointer) {
actual var _ptr: NativePointer actual var _ptr: NativePointer
override fun toString(): String {
return this::class.simpleName + "(_ptr=0x$_ptr)"
}
actual open fun _nativeEquals(other: Native?): Boolean = this._ptr == other?._ptr ?: Native.NullPointer actual open fun _nativeEquals(other: Native?): Boolean = this._ptr == other?._ptr ?: Native.NullPointer
...@@ -18,6 +15,10 @@ actual abstract class Native actual constructor(ptr: NativePointer) { ...@@ -18,6 +15,10 @@ actual abstract class Native actual constructor(ptr: NativePointer) {
get() = NativePtr.NULL get() = NativePtr.NULL
} }
actual override fun toString(): String {
return this::class.simpleName + "(_ptr=0x" + _ptr.toString() + ")"
}
init { init {
if (ptr == NativePtr.NULL) throw RuntimeException("Can't wrap nullptr") if (ptr == NativePtr.NULL) throw RuntimeException("Can't wrap nullptr")
_ptr = ptr _ptr = ptr
......
...@@ -24,7 +24,7 @@ actual abstract class RefCnt : Managed { ...@@ -24,7 +24,7 @@ actual abstract class RefCnt : Managed {
} }
} }
@ExternalSymbolName("org_jetbrains_skia_impl_RefCnt__1nGetFinalizer") @ExternalSymbolName("org_jetbrains_skia_impl_RefCnt__getFinalizer")
private external fun _nGetFinalizer(): NativePointer private external fun _nGetFinalizer(): NativePointer
@ExternalSymbolName("org_jetbrains_skia_impl_RefCnt__1nGetRefCount") @ExternalSymbolName("org_jetbrains_skia_impl_RefCnt__getRefCount")
private external fun _nGetRefCount(ptr: NativePointer): Int private external fun _nGetRefCount(ptr: NativePointer): Int
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