Unverified Commit 50d76ce2 authored by Aleksandr Veselov's avatar Aleksandr Veselov Committed by GitHub

Implement native methods of Pixmap (#352)

parent 0f45ab4e
package org.jetbrains.skia package org.jetbrains.skia
import org.jetbrains.skia.impl.* import org.jetbrains.skia.impl.*
import org.jetbrains.skiko.maybeSynchronized
class Pixmap internal constructor(ptr: NativePointer, managed: Boolean) : class Pixmap internal constructor(ptr: NativePointer, managed: Boolean) :
Managed(ptr, _FinalizerHolder.PTR, managed) { Managed(ptr, _FinalizerHolder.PTR, managed) {
...@@ -11,19 +12,27 @@ class Pixmap internal constructor(ptr: NativePointer, managed: Boolean) : ...@@ -11,19 +12,27 @@ class Pixmap internal constructor(ptr: NativePointer, managed: Boolean) :
*/ */
private var underlyingMemoryOwner: Managed? = null private var underlyingMemoryOwner: Managed? = null
private var _imageInfo: ImageInfo ? = null
private val _imageInfoLock = Unit
constructor() : this(_nMakeNull(), true) { constructor() : this(_nMakeNull(), true) {
Stats.onNativeCall() Stats.onNativeCall()
} }
fun reset() { fun reset() {
Stats.onNativeCall() Stats.onNativeCall()
maybeSynchronized(_imageInfoLock) {
_imageInfo = null
Pixmap_nReset(_ptr) Pixmap_nReset(_ptr)
}
underlyingMemoryOwner = null underlyingMemoryOwner = null
reachabilityBarrier(this) reachabilityBarrier(this)
} }
fun reset(info: ImageInfo, addr: NativePointer, rowBytes: Int, underlyingMemoryOwner: Managed? = null) { fun reset(info: ImageInfo, addr: NativePointer, rowBytes: Int, underlyingMemoryOwner: Managed? = null) {
Stats.onNativeCall() Stats.onNativeCall()
maybeSynchronized(_imageInfoLock) {
_imageInfo = null
_nResetWithInfo( _nResetWithInfo(
_ptr, _ptr,
info.width, info.height, info.width, info.height,
...@@ -31,6 +40,7 @@ class Pixmap internal constructor(ptr: NativePointer, managed: Boolean) : ...@@ -31,6 +40,7 @@ class Pixmap internal constructor(ptr: NativePointer, managed: Boolean) :
info.colorInfo.alphaType.ordinal, info.colorInfo.alphaType.ordinal,
getPtr(info.colorInfo.colorSpace), addr, rowBytes getPtr(info.colorInfo.colorSpace), addr, rowBytes
) )
}
this.underlyingMemoryOwner = underlyingMemoryOwner this.underlyingMemoryOwner = underlyingMemoryOwner
reachabilityBarrier(this) reachabilityBarrier(this)
reachabilityBarrier(info.colorInfo.colorSpace) reachabilityBarrier(info.colorInfo.colorSpace)
...@@ -42,14 +52,16 @@ class Pixmap internal constructor(ptr: NativePointer, managed: Boolean) : ...@@ -42,14 +52,16 @@ class Pixmap internal constructor(ptr: NativePointer, managed: Boolean) :
fun setColorSpace(colorSpace: ColorSpace?) { fun setColorSpace(colorSpace: ColorSpace?) {
Stats.onNativeCall() Stats.onNativeCall()
maybeSynchronized(_imageInfoLock) {
_imageInfo = null
_nSetColorSpace(_ptr, getPtr(colorSpace)) _nSetColorSpace(_ptr, getPtr(colorSpace))
}
reachabilityBarrier(this) reachabilityBarrier(this)
reachabilityBarrier(colorSpace) reachabilityBarrier(colorSpace)
} }
fun extractSubset(subsetPtr: NativePointer, area: IRect): Boolean { fun extractSubset(subsetPtr: NativePointer, area: IRect): Boolean {
return try { return try {
Stats.onNativeCall()
Pixmap_nExtractSubset( Pixmap_nExtractSubset(
_ptr, _ptr,
subsetPtr, subsetPtr,
...@@ -71,7 +83,15 @@ class Pixmap internal constructor(ptr: NativePointer, managed: Boolean) : ...@@ -71,7 +83,15 @@ class Pixmap internal constructor(ptr: NativePointer, managed: Boolean) :
get() { get() {
Stats.onNativeCall() Stats.onNativeCall()
return try { return try {
_nGetInfo(_ptr) maybeSynchronized(_imageInfoLock) {
if (_imageInfo == null) {
_imageInfo = ImageInfo.createUsing(
_ptr = _ptr,
_nGetImageInfo = ::_nGetInfo
)
}
_imageInfo!!
}
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
} }
...@@ -185,25 +205,31 @@ class Pixmap internal constructor(ptr: NativePointer, managed: Boolean) : ...@@ -185,25 +205,31 @@ class Pixmap internal constructor(ptr: NativePointer, managed: Boolean) :
fun readPixels(pixmap: Pixmap?): Boolean { fun readPixels(pixmap: Pixmap?): Boolean {
Stats.onNativeCall() Stats.onNativeCall()
return try { return try {
maybeSynchronized(_imageInfoLock) {
_imageInfo = null
_nReadPixelsToPixmap( _nReadPixelsToPixmap(
_ptr, _ptr,
getPtr(pixmap) getPtr(pixmap)
) )
}
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
reachabilityBarrier(pixmap) reachabilityBarrier(pixmap)
} }
} }
fun readPixels(pixmap: Pixmap?, srcX: Int, srcY: Int): Boolean { fun readPixels(pixmap: Pixmap, srcX: Int, srcY: Int): Boolean {
Stats.onNativeCall() Stats.onNativeCall()
return try { return try {
maybeSynchronized(pixmap._imageInfoLock) {
pixmap._imageInfo = null
_nReadPixelsToPixmapFromPoint( _nReadPixelsToPixmapFromPoint(
_ptr, _ptr,
getPtr(pixmap), getPtr(pixmap),
srcX, srcX,
srcY srcY
) )
}
} finally { } finally {
reachabilityBarrier(this) reachabilityBarrier(this)
reachabilityBarrier(pixmap) reachabilityBarrier(pixmap)
...@@ -341,7 +367,7 @@ private external fun _nResetWithInfo( ...@@ -341,7 +367,7 @@ private external fun _nResetWithInfo(
private external fun _nSetColorSpace(ptr: NativePointer, colorSpacePtr: NativePointer) private external fun _nSetColorSpace(ptr: NativePointer, colorSpacePtr: NativePointer)
@ExternalSymbolName("org_jetbrains_skia_Pixmap__1nGetInfo") @ExternalSymbolName("org_jetbrains_skia_Pixmap__1nGetInfo")
private external fun _nGetInfo(ptr: NativePointer): ImageInfo private external fun _nGetInfo(ptr: NativePointer, imageInfo: InteropPointer, colorSpacePtrs: InteropPointer)
@ExternalSymbolName("org_jetbrains_skia_Pixmap__1nGetAddr") @ExternalSymbolName("org_jetbrains_skia_Pixmap__1nGetAddr")
private external fun _nGetAddr(ptr: NativePointer): NativePointer private external fun _nGetAddr(ptr: NativePointer): NativePointer
......
package org.jetbrains.skia
import org.jetbrains.skia.tests.makeFromResource
import org.jetbrains.skiko.tests.runTest
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
class PixmapTest {
@Test
fun canCreate() = runTest {
val pixmap = Pixmap.make(
info = ImageInfo.makeN32(8, 8, ColorAlphaType.UNPREMUL),
buffer = Data.makeFromResource("./colors_8x8.png"),
rowBytes = 8,
)
assertEquals(8, pixmap.info.width)
assertEquals(8, pixmap.info.height)
assertFalse(pixmap.computeIsOpaque())
}
}
\ No newline at end of file
...@@ -64,11 +64,14 @@ extern "C" { ...@@ -64,11 +64,14 @@ extern "C" {
return pixmap->extractSubset(dst, { l, t, w, h }); return pixmap->extractSubset(dst, { l, t, w, h });
} }
JNIEXPORT jobject JNICALL Java_org_jetbrains_skia_PixmapKt__1nGetInfo JNIEXPORT void JNICALL Java_org_jetbrains_skia_PixmapKt__1nGetInfo
(JNIEnv *env, jclass klass, jlong ptr) { (JNIEnv* env, jclass jclass, jlong ptr, jintArray imageInfoResult, jlongArray colorSpaceResultPtr) {
SkPixmap* pixmap = jlongToPtr<SkPixmap*>(ptr); SkPixmap* instance = reinterpret_cast<SkPixmap*>(static_cast<uintptr_t>(ptr));
const SkImageInfo& imageInfo = pixmap->info(); SkImageInfo imageInfo = instance->info();
return skija::ImageInfo::toJava(env, imageInfo);
skija::ImageInfo::writeImageInfoForInterop(
env, imageInfo, imageInfoResult, colorSpaceResultPtr
);
} }
JNIEXPORT jint JNICALL Java_org_jetbrains_skia_PixmapKt_Pixmap_1nGetRowBytes JNIEXPORT jint JNICALL Java_org_jetbrains_skia_PixmapKt_Pixmap_1nGetRowBytes
......
...@@ -65,9 +65,11 @@ SKIKO_EXPORT KBoolean org_jetbrains_skia_Pixmap__1nExtractSubset ...@@ -65,9 +65,11 @@ SKIKO_EXPORT KBoolean org_jetbrains_skia_Pixmap__1nExtractSubset
} }
SKIKO_EXPORT KInteropPointer org_jetbrains_skia_Pixmap__1nGetInfo SKIKO_EXPORT void org_jetbrains_skia_Pixmap__1nGetInfo
(KNativePointer ptr) { (KNativePointer ptr, KInt* imageInfoResult, KNativePointer* colorSpacePtrsArray) {
TODO("implement org_jetbrains_skia_Pixmap__1nGetInfo"); SkPixmap* instance = reinterpret_cast<SkPixmap*>(ptr);
SkImageInfo imageInfo = instance->info();
skija::ImageInfo::writeImageInfoForInterop(imageInfo, imageInfoResult, colorSpacePtrsArray);
} }
SKIKO_EXPORT KInt org_jetbrains_skia_Pixmap__1nGetRowBytes SKIKO_EXPORT KInt org_jetbrains_skia_Pixmap__1nGetRowBytes
......
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