Unverified Commit 87a5526e authored by Nikolay Igotti's avatar Nikolay Igotti Committed by GitHub

Actual MPP conversion of native functions for all platforms. (#177)

parent 8d260f5a
......@@ -340,7 +340,7 @@ project.tasks.register<Exec>("wasmCompile") {
dependsOn(skiaWasmDir)
val inputDir = "$projectDir/src/jsMain/cpp"
val outDir = "$buildDir/wasm"
val names = File(inputDir).listFiles()!!.map { it.name.removeSuffix(".cc") }
val names = File(inputDir).listFiles()!!.filter { it.name.endsWith(".cc") }.map { it.name.removeSuffix(".cc") }
val srcs = names.map { "$inputDir/$it.cc" }.toTypedArray()
val outJs = "$outDir/skiko.js"
val outWasm = "$outDir/skiko.wasm"
......@@ -352,6 +352,8 @@ project.tasks.register<Exec>("wasmCompile") {
*Arch.Wasm.clangFlags,
"-I$skiaDir",
"-I$skiaDir/include",
"-I$skiaDir/include/core",
"-I$skiaDir/include/effects",
"-I$skiaDir/include/gpu",
"-std=c++17",
"--bind",
......
......@@ -2,12 +2,8 @@
package org.jetbrains.skia
import org.jetbrains.skia.impl.Library.Companion.staticLoad
import org.jetbrains.skia.impl.RefCnt
import org.jetbrains.skia.impl.Stats
import org.jetbrains.skia.impl.reachabilityBarrier
import org.jetbrains.skia.ExternalSymbolName
import org.jetbrains.skia.impl.NativePointer
import org.jetbrains.skia.impl.getPtr
import org.jetbrains.skia.impl.*
import kotlin.jvm.JvmStatic
class ColorFilter : RefCnt {
......@@ -75,7 +71,13 @@ class ColorFilter : RefCnt {
require(r == null || r.size == 256) { "Expected 256 elements in r[], got " + r!!.size }
require(g == null || g.size == 256) { "Expected 256 elements in g[], got " + g!!.size }
require(b == null || b.size == 256) { "Expected 256 elements in b[], got " + b!!.size }
return ColorFilter(_nMakeTableARGB(a, r, g, b))
interopScope {
return ColorFilter(_nMakeTableARGB(
toInterop(a), a?.size ?: 0,
toInterop(r), r?.size ?: 0,
toInterop(g), g?.size ?: 0,
toInterop(b), a?.size ?: 0))
}
}
fun makeOverdraw(colors: IntArray): ColorFilter {
......@@ -114,9 +116,6 @@ class ColorFilter : RefCnt {
@ExternalSymbolName("org_jetbrains_skia_ColorFilter__1nMakeTable")
external fun _nMakeTable(table: ByteArray?): NativePointer
@JvmStatic
@ExternalSymbolName("org_jetbrains_skia_ColorFilter__1nMakeTableARGB")
external fun _nMakeTableARGB(a: ByteArray?, r: ByteArray?, g: ByteArray?, b: ByteArray?): NativePointer
@JvmStatic
@ExternalSymbolName("org_jetbrains_skia_ColorFilter__1nMakeOverdraw")
external fun _nMakeOverdraw(c0: Int, c1: Int, c2: Int, c3: Int, c4: Int, c5: Int): NativePointer
@JvmStatic
......@@ -134,4 +133,12 @@ class ColorFilter : RefCnt {
internal constructor(ptr: NativePointer) : super(ptr)
internal constructor(ptr: NativePointer, allowClose: Boolean) : super(ptr, allowClose)
}
\ No newline at end of file
}
@ExternalSymbolName("org_jetbrains_skia_ColorFilter__nMakeTableARGB")
private external fun _nMakeTableARGB(
a: InteropPointer, aSize: Int,
r: InteropPointer, rSize: Int,
g: InteropPointer, gSize: Int,
b: InteropPointer, bSize: Int
): NativePointer
......@@ -2,12 +2,8 @@
package org.jetbrains.skia
import org.jetbrains.skia.impl.Library.Companion.staticLoad
import org.jetbrains.skia.impl.Managed
import org.jetbrains.skia.impl.Stats
import org.jetbrains.skia.impl.reachabilityBarrier
import org.jetbrains.skia.ExternalSymbolName
import org.jetbrains.skia.impl.NativePointer
import org.jetbrains.skia.impl.getPtr
import org.jetbrains.skia.impl.*
import kotlin.jvm.JvmStatic
class ColorSpace : Managed {
......@@ -25,9 +21,6 @@ class ColorSpace : Managed {
@ExternalSymbolName("org_jetbrains_skia_ColorSpace__1nMakeSRGBLinear")
external fun _nMakeSRGBLinear(): NativePointer
@JvmStatic
@ExternalSymbolName("org_jetbrains_skia_ColorSpace__1nConvert")
external fun _nConvert(fromPtr: NativePointer, toPtr: NativePointer, r: Float, g: Float, b: Float, a: Float): FloatArray
@JvmStatic
@ExternalSymbolName("org_jetbrains_skia_ColorSpace__1nIsGammaCloseToSRGB")
external fun _nIsGammaCloseToSRGB(ptr: NativePointer): Boolean
@JvmStatic
......@@ -51,16 +44,17 @@ class ColorSpace : Managed {
var to = to
to = to ?: sRGB
return try {
Color4f(
_nConvert(
_ptr,
getPtr(to),
color.r,
color.g,
color.b,
color.a
)
)
Color4f(withResult(FloatArray(4)) {
_nConvert(
_ptr,
getPtr(to),
color.r,
color.g,
color.b,
color.a,
it
)
})
} finally {
reachabilityBarrier(this)
reachabilityBarrier(to)
......@@ -118,4 +112,8 @@ class ColorSpace : Managed {
private object _FinalizerHolder {
val PTR = _nGetFinalizer()
}
}
\ No newline at end of file
}
@ExternalSymbolName("org_jetbrains_skia_ColorSpace__nConvert")
private external fun _nConvert(
fromPtr: NativePointer, toPtr: NativePointer, r: Float, g: Float, b: Float, a: Float, result: InteropPointer)
package org.jetbrains.skia.impl
import org.jetbrains.skia.IPoint
expect class NativePointer
expect class InteropPointer
expect abstract class Native(ptr: NativePointer) {
var _ptr: NativePointer
open fun _nativeEquals(other: Native?): Boolean
......@@ -16,3 +16,37 @@ expect abstract class Native(ptr: NativePointer) {
expect fun reachabilityBarrier(obj: Any?)
fun getPtr(n: Native?): NativePointer = n?._ptr ?: Native.NullPointer
expect class InteropScope() {
fun toInterop(string: String?): InteropPointer
fun InteropPointer.fromInterop(result: CharArray)
fun toInterop(array: ByteArray?): InteropPointer
fun InteropPointer.fromInterop(result: ByteArray)
fun toInterop(array: FloatArray?): InteropPointer
fun InteropPointer.fromInterop(result: FloatArray)
fun release()
}
inline fun <T> interopScope(block: InteropScope.() -> T): T {
val scope = InteropScope()
try {
return scope.block()
} finally {
scope.release()
}
}
inline fun withResult(result: ByteArray, block: (InteropPointer) -> Unit): ByteArray = interopScope {
val handle = toInterop(result)
block(handle)
handle.fromInterop(result)
result
}
inline fun withResult(result: FloatArray, block: (InteropPointer) -> Unit): FloatArray = interopScope {
val handle = toInterop(result)
block(handle)
handle.fromInterop(result)
result
}
......@@ -7,7 +7,7 @@ class SVGPreserveAspectRatio(align: SVGPreserveAspectRatioAlign, scale: SVGPrese
internal constructor(align: Int, scale: Int) : this(
SVGPreserveAspectRatioAlign.valueOf(align),
SVGPreserveAspectRatioScale.values().get(scale)
SVGPreserveAspectRatioScale.values()[scale]
)
constructor() : this(SVGPreserveAspectRatioAlign.XMID_YMID, SVGPreserveAspectRatioScale.MEET) {}
......@@ -26,10 +26,10 @@ class SVGPreserveAspectRatio(align: SVGPreserveAspectRatioAlign, scale: SVGPrese
if (!other.canEqual(this as Any)) return false
val `this$_align`: Any = align
val `other$_align`: Any = other.align
if (if (`this$_align` == null) `other$_align` != null else `this$_align` != `other$_align`) return false
if (`this$_align` != `other$_align`) return false
val `this$_scale`: Any = scale
val `other$_scale`: Any = other.scale
return !if (`this$_scale` == null) true else `this$_scale` != `other$_scale`
return `this$_scale` == `other$_scale`
}
protected fun canEqual(other: Any?): Boolean {
......
#include "GrBackendSurface.h"
#include <emscripten.h>
#include "common.h"
typedef int32_t jint;
// TODO: likely we shall use jint, not jlong for passing pointers.
typedef int64_t jlong;
#include <emscripten.h>
static void deleteBackendRenderTarget(GrBackendRenderTarget* rt) {
delete rt;
}
EMSCRIPTEN_KEEPALIVE
extern "C" jlong BackendRenderTarget_nGetFinalizer() {
return static_cast<jlong>(reinterpret_cast<uintptr_t>(&deleteBackendRenderTarget));
extern "C" KPointer BackendRenderTarget_nGetFinalizer() {
return static_cast<KPointer>(reinterpret_cast<uintptr_t>(&deleteBackendRenderTarget));
}
EMSCRIPTEN_KEEPALIVE
extern "C" jlong BackendRenderTarget_nMakeGL
(jint width, jint height, jint sampleCnt, jint stencilBits, jint fbId, jint fbFormat) {
extern "C" KPointer BackendRenderTarget_nMakeGL
(KInt width, KInt height, KInt sampleCnt, KInt stencilBits, KInt fbId, KInt fbFormat) {
GrGLFramebufferInfo glInfo = { static_cast<unsigned int>(fbId), static_cast<unsigned int>(fbFormat) };
GrBackendRenderTarget* instance = new GrBackendRenderTarget(width, height, sampleCnt, stencilBits, glInfo);
return reinterpret_cast<jlong>(instance);
return reinterpret_cast<KPointer>(instance);
}
EMSCRIPTEN_KEEPALIVE
extern "C" jlong BackendRenderTarget_nMakeMetal
(jint width, jint height, jlong texturePtr) {
extern "C" KPointer BackendRenderTarget_nMakeMetal
(KInt width, KInt height, KPointer texturePtr) {
#ifdef SK_METAL
GrMTLHandle texture = reinterpret_cast<GrMTLHandle>(static_cast<uintptr_t>(texturePtr));
GrMtlTextureInfo fbInfo;
fbInfo.fTexture.retain(texture);
GrBackendRenderTarget* instance = new GrBackendRenderTarget(width, height, fbInfo);
return reinterpret_cast<jlong>(instance);
return reinterpret_cast<KPointer>(instance);
#else
return 0;
#endif
......@@ -41,8 +39,8 @@ extern "C" jlong BackendRenderTarget_nMakeMetal
#endif
EMSCRIPTEN_KEEPALIVE
extern "C" jlong BackendRenderTarget_MakeDirect3D
(jint width, jint height, jlong texturePtr, jint format, jint sampleCnt, jint levelCnt) {
extern "C" KPointer BackendRenderTarget_MakeDirect3D
(KInt width, KInt height, KPointer texturePtr, KInt format, KInt sampleCnt, KInt levelCnt) {
#ifdef SK_DIRECT3D
GrD3DTextureResourceInfo texResInfo = {};
ID3D12Resource* resource = reinterpret_cast<ID3D12Resource*>(static_cast<uintptr_t>(texturePtr));
......@@ -52,7 +50,7 @@ extern "C" jlong BackendRenderTarget_MakeDirect3D
texResInfo.fSampleCount = static_cast<uint32_t>(sampleCnt);
texResInfo.fLevelCount = static_cast<uint32_t>(levelCnt);
GrBackendRenderTarget* instance = new GrBackendRenderTarget(width, height, texResInfo);
return reinterpret_cast<jlong>(instance);
return reinterpret_cast<KPointer>(instance);
#else
return 0;
#endif
......
#include "SkColorFilter.h"
#include "SkColorMatrixFilter.h"
#include "SkHighContrastFilter.h"
#include "SkLumaColorFilter.h"
#include "SkOverdrawColorFilter.h"
#include "SkTableColorFilter.h"
#include "common.h"
#include <emscripten.h>
EMSCRIPTEN_KEEPALIVE
extern "C" KPointer org_jetbrains_skia_ColorFilter__nMakeTableARGB(
KByteArray arrayA, KInt arrayASize,
KByteArray arrayR, KInt arrayRSize,
KByteArray arrayG, KInt arrayGSize,
KByteArray arrayB, KInt arrayBSize
) {
SkColorFilter* ptr = SkTableColorFilter::MakeARGB(arrayA, arrayR, arrayG, arrayB).release();
return reinterpret_cast<KPointer>(ptr);
}
\ No newline at end of file
#include "SkColorSpace.h"
#include "common.h"
#include <emscripten.h>
extern "C" void org_jetbrains_skia_ColorSpace__nConvert(
KPointer fromPtr, KPointer toPtr, float r, float g, float b, float a, float* result) {
SkColorSpace* from = reinterpret_cast<SkColorSpace*>(fromPtr);
SkColorSpace* to = reinterpret_cast<SkColorSpace*>(toPtr);
skcms_TransferFunction fromFn;
from->transferFn(&fromFn);
skcms_TransferFunction toFn;
to->invTransferFn(&toFn);
result[0] = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, r));
result[1] = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, g));
result[2] = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, b));
result[3] = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, a));
}
\ No newline at end of file
#pragma once
typedef int32_t KInt;
typedef int64_t KLong;
typedef int32_t KPointer;
typedef uint8_t* KByteArray;
......@@ -21,3 +21,95 @@ actual fun reachabilityBarrier(obj: Any?) {
}
actual typealias NativePointer = Int
actual typealias InteropPointer = Int
actual class InteropScope actual constructor() {
private val elements = mutableListOf<NativePointer>()
actual fun toInterop(string: String?): InteropPointer {
return if (string != null) {
val data = _malloc(string.length * 4)
stringToUTF8(string, data, string.length * 4)
elements.add(data)
data
} else {
0
}
}
actual fun InteropPointer.fromInterop(result: CharArray) {
fromWasm(this@fromInterop, result)
}
actual fun toInterop(array: ByteArray?): InteropPointer {
return if (array != null) {
val data = _malloc(array.size)
elements.add(data)
toWasm(data, array)
data
} else {
0
}
}
actual fun InteropPointer.fromInterop(result: FloatArray) {
fromWasm(this@fromInterop, result)
}
actual fun toInterop(array: FloatArray?): InteropPointer {
return if (array != null) {
val data = _malloc(array.size * 4)
elements.add(data)
toWasm(data, array)
data
} else {
0
}
}
actual fun InteropPointer.fromInterop(result: ByteArray) {
fromWasm(this@fromInterop, result)
}
actual fun release() {
elements.forEach {
_free(it)
}
}
}
// Those functions are defined by Emscripten.
private external fun _malloc(size: Int): NativePointer
private external fun _free(ptr: NativePointer)
private external fun stringToUTF8(str: String, outPtr: NativePointer, maxBytesToWrite: Int)
private external val HEAPU8: ByteArray
// Data copying routines.
private fun toWasm(dest: NativePointer, src: ByteArray) {
js("HEAPU8.set(src, dest)")
}
private fun toWasm(dest: NativePointer, src: CharArray) {
js("HEAPU16.set(src, dest)")
}
private fun toWasm(dest: NativePointer, src: FloatArray) {
js("HEAPU32.set(src, dest)")
}
private fun fromWasm(src: NativePointer, result: ByteArray) {
js("result.set(HEAPU8.subarray(src, result.size))")
}
private fun fromWasm(src: NativePointer, result: CharArray) {
js("result.set(HEAPU16.subarray(src, result.size))")
}
private fun fromWasm(src: NativePointer, result: FloatArray) {
js("result.set(HEAPU32.subarray(src, result.size))")
}
......@@ -81,7 +81,7 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ColorFilter__1nMakeTa
return reinterpret_cast<jlong>(ptr);
}
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ColorFilter__1nMakeTableARGB
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ColorFilter__nMakeTableARGB
(JNIEnv* env, jclass jclass, jbyteArray arrayA, jbyteArray arrayR, jbyteArray arrayG, jbyteArray arrayB) {
jbyte* a = arrayA ? env->GetByteArrayElements(arrayA, 0) : nullptr;
jbyte* r = arrayR ? env->GetByteArrayElements(arrayR, 0) : nullptr;
......
......@@ -27,8 +27,8 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ColorSpace__1nMakeDis
return reinterpret_cast<jlong>(ptr);
}
extern "C" JNIEXPORT jfloatArray JNICALL Java_org_jetbrains_skia_ColorSpace__1nConvert
(JNIEnv* env, jclass jclass, jlong fromPtr, jlong toPtr, float r, float g, float b, float a) {
extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skia_ColorSpaceKt__nConvert
(JNIEnv* env, jobject jclass, jlong fromPtr, jlong toPtr, float r, float g, float b, float a, jfloatArray jresult) {
SkColorSpace* from = reinterpret_cast<SkColorSpace*>(static_cast<uintptr_t>(fromPtr));
SkColorSpace* to = reinterpret_cast<SkColorSpace*>(static_cast<uintptr_t>(toPtr));
......@@ -38,11 +38,13 @@ extern "C" JNIEXPORT jfloatArray JNICALL Java_org_jetbrains_skia_ColorSpace__1nC
skcms_TransferFunction toFn;
to->invTransferFn(&toFn);
float r1 = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, r));
float g1 = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, g));
float b1 = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, b));
float a1 = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, a));
return javaFloatArray(env, {r1, g1, b1, a1});
float result[4];
result[0] = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, r));
result[1] = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, g));
result[2] = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, b));
result[3] = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, a));
env->SetFloatArrayRegion(jresult, 0, 4, &result[0]);
}
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ColorSpace__1nIsGammaCloseToSRGB
......@@ -57,7 +59,7 @@ extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ColorSpace__1nIsGamma
return instance->gammaIsLinear();
}
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ColorSpace__1nIsSRGB
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_ColorSpaceKt__1nIsSRGB
(JNIEnv* env, jclass jclass, jlong ptr) {
SkColorSpace* instance = reinterpret_cast<SkColorSpace*>(static_cast<uintptr_t>(ptr));
return instance->isSRGB();
......
......@@ -2,8 +2,8 @@ package org.jetbrains.skia.impl
import java.lang.ref.Reference
actual abstract class Native actual constructor(ptr: Long) {
actual var _ptr: Long
actual abstract class Native actual constructor(ptr: NativePointer) {
actual var _ptr: NativePointer
actual companion object {
actual val NullPointer: NativePointer
......@@ -46,4 +46,16 @@ actual fun reachabilityBarrier(obj: Any?) {
Reference.reachabilityFence(obj)
}
actual typealias NativePointer = Long
\ No newline at end of file
actual typealias NativePointer = Long
actual typealias InteropPointer = Any?
actual class InteropScope actual constructor() {
actual fun toInterop(string: String?): InteropPointer = string
actual fun InteropPointer.fromInterop(result: CharArray) {}
actual fun toInterop(array: ByteArray?): InteropPointer = array
actual fun InteropPointer.fromInterop(result: ByteArray) {}
actual fun toInterop(array: FloatArray?): InteropPointer = array
actual fun InteropPointer.fromInterop(result: FloatArray) {}
actual fun release() {}
}
......@@ -109,13 +109,22 @@ extern "C" jlong org_jetbrains_skia_ColorFilter__1nMakeTable
}
#endif
extern "C" jlong org_jetbrains_skia_ColorFilter__1nMakeTableARGB
(kref __Kinstance, jbyteArray arrayA, jbyteArray arrayR, jbyteArray arrayG, jbyteArray arrayB) {
throw std::runtime_error("TODO: implement org_jetbrains_skia_ColorFilter__1nMakeTableARGB");
typedef void* KPointer;
extern "C" KPointer org_jetbrains_skia_ColorFilter__nMakeTableARGB
(uint8_t* arrayA,
jint arrayASize,
uint8_t* arrayR,
jint arrayRSize,
uint8_t* arrayG,
jint arrayGSize,
uint8_t* arrayB,
jint arrayBSize
) {
SkColorFilter* ptr = SkTableColorFilter::MakeARGB(arrayA, arrayR, arrayG, arrayB).release();
return ptr;
}
#if 0
extern "C" jlong org_jetbrains_skia_ColorFilter__1nMakeTableARGB
(kref __Kinstance, jbyteArray arrayA, jbyteArray arrayR, jbyteArray arrayG, jbyteArray arrayB) {
......
......@@ -30,14 +30,8 @@ extern "C" jlong org_jetbrains_skia_ColorSpace__1nMakeDisplayP3(kref __Kinstance
}
extern "C" jfloatArray org_jetbrains_skia_ColorSpace__1nConvert
(kref __Kinstance, jlong fromPtr, jlong toPtr, float r, float g, float b, float a) {
throw std::runtime_error("TODO: implement org_jetbrains_skia_ColorSpace__1nConvert");
}
#if 0
extern "C" jfloatArray org_jetbrains_skia_ColorSpace__1nConvert
(kref __Kinstance, jlong fromPtr, jlong toPtr, float r, float g, float b, float a) {
extern "C" void org_jetbrains_skia_ColorSpace__nConvert(
jlong fromPtr, jlong toPtr, float r, float g, float b, float a, float* result) {
SkColorSpace* from = reinterpret_cast<SkColorSpace*>(static_cast<uintptr_t>(fromPtr));
SkColorSpace* to = reinterpret_cast<SkColorSpace*>(static_cast<uintptr_t>(toPtr));
......@@ -47,13 +41,11 @@ extern "C" jfloatArray org_jetbrains_skia_ColorSpace__1nConvert
skcms_TransferFunction toFn;
to->invTransferFn(&toFn);
float r1 = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, r));
float g1 = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, g));
float b1 = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, b));
float a1 = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, a));
return javaFloatArray(env, {r1, g1, b1, a1});
result[0] = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, r));
result[1] = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, g));
result[2] = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, b));
result[3] = skcms_TransferFunction_eval(&toFn, skcms_TransferFunction_eval(&fromFn, a));
}
#endif
extern "C" jlong org_jetbrains_skia_ColorSpace__1nIsGammaCloseToSRGB
......
package org.jetbrains.skia.impl
import kotlinx.cinterop.Pinned
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.pin
import kotlin.native.internal.NativePtr
actual abstract class Native actual constructor(ptr: NativePointer) {
......@@ -22,7 +25,58 @@ actual abstract class Native actual constructor(ptr: NativePointer) {
}
actual typealias NativePointer = NativePtr
actual typealias InteropPointer = NativePtr
actual fun reachabilityBarrier(obj: Any?) {
// TODO: implement native barrier
}
actual class InteropScope actual constructor() {
actual fun toInterop(string: String?): InteropPointer {
return if (string != null) {
val pinned = string.pin()
elements.add(pinned)
val result = pinned.addressOf(0).rawValue
result
} else {
NativePtr.NULL
}
}
actual fun InteropPointer.fromInterop(result: CharArray) {}
actual fun toInterop(array: ByteArray?): InteropPointer {
return if (array != null) {
val pinned = array.pin()
elements.add(pinned)
val result = pinned.addressOf(0).rawValue
result
} else {
NativePtr.NULL
}
}
actual fun InteropPointer.fromInterop(result: ByteArray) {}
actual fun toInterop(array: FloatArray?): InteropPointer {
return if (array != null) {
val pinned = array.pin()
elements.add(pinned)
val result = pinned.addressOf(0).rawValue
result
} else {
NativePtr.NULL
}
}
actual fun InteropPointer.fromInterop(result: FloatArray) {}
actual fun release() {
elements.forEach {
it.unpin()
}
}
private val elements = mutableListOf<Pinned<*>>()
}
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