Unverified Commit 90f73ca5 authored by Aleksandr Veselov's avatar Aleksandr Veselov Committed by GitHub

Implement Surface and DirectContext for native (#379)

parent 25ff8bee
...@@ -84,7 +84,9 @@ jobs: ...@@ -84,7 +84,9 @@ jobs:
sudo apt-get install gcc-9 g++-9 -y sudo apt-get install gcc-9 g++-9 -y
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-9 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-9
sudo update-alternatives --config gcc sudo update-alternatives --config gcc
sudo apt-get install ninja-build fontconfig libfontconfig1-dev libglu1-mesa-dev libxrandr-dev zip -y sudo apt-get install ninja-build fontconfig libfontconfig1-dev libglu1-mesa-dev libxrandr-dev zip xvfb -y
sudo Xvfb :0 -screen 0 1280x720x24 &
export DISPLAY=:0
./gradlew -Pskiko.native.enabled=true -i linuxX64Test jvmTest ./gradlew -Pskiko.native.enabled=true -i linuxX64Test jvmTest
./gradlew publishToMavenLocal ./gradlew publishToMavenLocal
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
......
import de.undercouch.gradle.tasks.download.Download import de.undercouch.gradle.tasks.download.Download
import org.gradle.crypto.checksum.Checksum import org.gradle.crypto.checksum.Checksum
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
import org.jetbrains.compose.internal.publishing.MavenCentralProperties import org.jetbrains.compose.internal.publishing.MavenCentralProperties
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
plugins { plugins {
kotlin("multiplatform") version "1.5.31" kotlin("multiplatform") version "1.5.31"
...@@ -355,17 +355,18 @@ fun configureNativeTarget(os: OS, arch: Arch, target: KotlinNativeTarget) { ...@@ -355,17 +355,18 @@ fun configureNativeTarget(os: OS, arch: Arch, target: KotlinNativeTarget) {
target.compilations.all { target.compilations.all {
val skiaBinDir = "$skiaDir/out/${buildType.id}-$targetString" val skiaBinDir = "$skiaDir/out/${buildType.id}-$targetString"
this.
kotlinOptions { kotlinOptions {
val linkerFlags = when (os) { val linkerFlags = when (os) {
OS.MacOS -> listOf("-linker-option", "-framework", "-linker-option", "Metal", OS.MacOS -> mutableListOf("-linker-option", "-framework", "-linker-option", "Metal",
"-linker-option", "-framework", "-linker-option", "CoreGraphics", "-linker-option", "-framework", "-linker-option", "CoreGraphics",
"-linker-option", "-framework", "-linker-option", "CoreText", "-linker-option", "-framework", "-linker-option", "CoreText",
"-linker-option", "-framework", "-linker-option", "CoreServices" "-linker-option", "-framework", "-linker-option", "CoreServices"
) )
OS.IOS -> listOf("-linker-option", "-framework", "-linker-option", "Metal", OS.IOS -> mutableListOf("-linker-option", "-framework", "-linker-option", "Metal",
"-linker-option", "-framework", "-linker-option", "CoreGraphics", "-linker-option", "-framework", "-linker-option", "CoreGraphics",
"-linker-option", "-framework", "-linker-option", "CoreText") "-linker-option", "-framework", "-linker-option", "CoreText")
OS.Linux -> listOf( OS.Linux -> mutableListOf(
"-linker-option", "-L/usr/lib/x86_64-linux-gnu", "-linker-option", "-L/usr/lib/x86_64-linux-gnu",
"-linker-option", "-lfontconfig", "-linker-option", "-lfontconfig",
"-linker-option", "-lGL", "-linker-option", "-lGL",
...@@ -374,7 +375,16 @@ fun configureNativeTarget(os: OS, arch: Arch, target: KotlinNativeTarget) { ...@@ -374,7 +375,16 @@ fun configureNativeTarget(os: OS, arch: Arch, target: KotlinNativeTarget) {
"-linker-option", "$skiaBinDir/libskunicode.a", "-linker-option", "$skiaBinDir/libskunicode.a",
"-linker-option", "$skiaBinDir/libskia.a" "-linker-option", "$skiaBinDir/libskia.a"
) )
else -> emptyList() else -> mutableListOf()
}
if (skiko.includeTestHelpers) {
linkerFlags.addAll(when (os) {
OS.Linux -> listOf(
"-linker-option", "-lX11",
"-linker-option", "-lGLX",
)
else -> emptyList()
})
} }
freeCompilerArgs = allLibraries.map { listOf("-include-binary", it) }.flatten() + linkerFlags freeCompilerArgs = allLibraries.map { listOf("-include-binary", it) }.flatten() + linkerFlags
} }
......
...@@ -15,6 +15,15 @@ class Bitmap internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerH ...@@ -15,6 +15,15 @@ class Bitmap internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerH
} }
} }
fun makeFromImage(image: Image, context: DirectContext): Bitmap {
val bitmap = Bitmap()
bitmap.allocPixels(image.imageInfo)
return if (image.readPixels(context, bitmap)) bitmap else {
bitmap.close()
throw RuntimeException("Failed to readPixels from $image")
}
}
init { init {
staticLoad() staticLoad()
} }
......
package org.jetbrains.skia package org.jetbrains.skia
import org.jetbrains.skia.impl.Library.Companion.staticLoad import org.jetbrains.skia.impl.Library.Companion.staticLoad
import org.jetbrains.skia.impl.NativePointer
import org.jetbrains.skia.impl.RefCnt import org.jetbrains.skia.impl.RefCnt
import org.jetbrains.skia.impl.Stats import org.jetbrains.skia.impl.Stats
import org.jetbrains.skia.impl.reachabilityBarrier import org.jetbrains.skia.impl.reachabilityBarrier
import org.jetbrains.skia.impl.NativePointer
class DirectContext internal constructor(ptr: NativePointer) : RefCnt(ptr) { class DirectContext internal constructor(ptr: NativePointer) : RefCnt(ptr) {
companion object { companion object {
...@@ -25,7 +25,7 @@ class DirectContext internal constructor(ptr: NativePointer) : RefCnt(ptr) { ...@@ -25,7 +25,7 @@ class DirectContext internal constructor(ptr: NativePointer) : RefCnt(ptr) {
* For more information refer to skia GrDirectContext class. * For more information refer to skia GrDirectContext class.
* *
* @param adapterPtr pointer to IDXGIAdapter1 object; must be not zero * @param adapterPtr pointer to IDXGIAdapter1 object; must be not zero
* @param devicePtr pointer to ID3D12Device objetc, which is created with * @param devicePtr pointer to ID3D12Device object, which is created with
* provided adapter in adapterPtr; must be not zero * provided adapter in adapterPtr; must be not zero
* @param queuePtr Pointer to ID3D12CommandQueue object, which * @param queuePtr Pointer to ID3D12CommandQueue object, which
* is created with provided device in devicePtr with * is created with provided device in devicePtr with
......
...@@ -286,6 +286,15 @@ class Image internal constructor(ptr: NativePointer) : RefCnt(ptr), IHasImageInf ...@@ -286,6 +286,15 @@ class Image internal constructor(ptr: NativePointer) : RefCnt(ptr), IHasImageInf
return readPixels(null, dst, srcX, srcY, false) return readPixels(null, dst, srcX, srcY, false)
} }
fun readPixels(context: DirectContext, dst: Bitmap): Boolean {
return readPixels(context, dst, 0, 0, false)
}
fun readPixels(context: DirectContext, dst: Bitmap, srcX: Int, srcY: Int): Boolean {
return readPixels(context, dst, srcX, srcY, false)
}
/** /**
* *
* Copies Rect of pixels from Image to Bitmap. Copy starts at offset (srcX, srcY), * Copies Rect of pixels from Image to Bitmap. Copy starts at offset (srcX, srcY),
......
...@@ -2,6 +2,11 @@ package org.jetbrains.skia ...@@ -2,6 +2,11 @@ package org.jetbrains.skia
import org.jetbrains.skia.impl.interopScope import org.jetbrains.skia.impl.interopScope
import org.jetbrains.skia.impl.use import org.jetbrains.skia.impl.use
import org.jetbrains.skiko.KotlinBackend
import org.jetbrains.skiko.OS
import org.jetbrains.skiko.hostOs
import org.jetbrains.skiko.kotlinBackend
import org.jetbrains.skiko.tests.TestGlContext
import org.jetbrains.skiko.tests.allocateBytesForPixels import org.jetbrains.skiko.tests.allocateBytesForPixels
import org.jetbrains.skiko.tests.runTest import org.jetbrains.skiko.tests.runTest
import kotlin.test.* import kotlin.test.*
...@@ -101,4 +106,26 @@ class SurfaceTest { ...@@ -101,4 +106,26 @@ class SurfaceTest {
surface.writePixels(writePixelsBitmap, 0, 0) surface.writePixels(writePixelsBitmap, 0, 0)
} }
} }
@Test
fun canMakeRenderTarget() {
if (hostOs != OS.Linux || kotlinBackend != KotlinBackend.Native) {
// TODO implement for other platforms and render targets
return
}
val pixels = TestGlContext.run {
val ctx = DirectContext.makeGL()
val imageInfo = ImageInfo.makeN32Premul(16, 16)
val surface = Surface.makeRenderTarget(ctx, budgeted = false, imageInfo)
surface.canvas.drawRect(
r = Rect(4f, 4f, 12f, 12f),
paint = Paint().apply { color = Color.RED }
)
Bitmap.makeFromImage(surface.makeImageSnapshot(), ctx)
}
assertEquals(Color.RED, pixels.getColor(8, 8))
}
} }
...@@ -2,8 +2,31 @@ package org.jetbrains.skiko.tests ...@@ -2,8 +2,31 @@ package org.jetbrains.skiko.tests
import org.jetbrains.skia.ExternalSymbolName import org.jetbrains.skia.ExternalSymbolName
import org.jetbrains.skia.impl.* import org.jetbrains.skia.impl.*
import kotlin.test.Test
import kotlin.test.assertEquals internal class TestGlContext : Managed(TestGlContext_nCreate(), FinalizerHolder.PTR) {
private object FinalizerHolder {
val PTR = TestGlContext_nGetFinalizer()
}
fun makeCurrent() {
TestGlContext_nMakeCurrent(_ptr)
}
fun swapBuffers() {
TestGlContext_nSwapBuffers(_ptr)
}
companion object {
inline fun <T> run(block: TestGlContext.() -> T): T {
return TestGlContext().use {
it.makeCurrent()
val result = it.block()
it.swapBuffers()
result
}
}
}
}
class TestHelpers { class TestHelpers {
...@@ -77,3 +100,17 @@ private external fun _nWriteArraysOfInts(interopPointer: InteropPointer): Native ...@@ -77,3 +100,17 @@ private external fun _nWriteArraysOfInts(interopPointer: InteropPointer): Native
private external fun _nStringByIndex(index: Int): NativePointer private external fun _nStringByIndex(index: Int): NativePointer
internal fun nativeStringByIndex(index: Int): NativePointer = _nStringByIndex(index) internal fun nativeStringByIndex(index: Int): NativePointer = _nStringByIndex(index)
@ExternalSymbolName("org_jetbrains_skiko_tests_TestHelpers__1nCreateTestGlContext")
private external fun TestGlContext_nCreate(): NativePointer
@ExternalSymbolName("org_jetbrains_skiko_tests_TestHelpers__1nGlContextGetFinalizer")
private external fun TestGlContext_nGetFinalizer(): NativePointer
@ExternalSymbolName("org_jetbrains_skiko_tests_TestHelpers__1nMakeGlContextCurrent")
private external fun TestGlContext_nMakeCurrent(ptr: NativePointer)
@ExternalSymbolName("org_jetbrains_skiko_tests_TestHelpers__1nGlContextSwapBuffers")
private external fun TestGlContext_nSwapBuffers(ptr: NativePointer)
...@@ -9,11 +9,21 @@ ...@@ -9,11 +9,21 @@
#include "mtl/GrMtlBackendContext.h" #include "mtl/GrMtlBackendContext.h"
#endif #endif
#ifdef SK_DIRECT3D
#include "d3d/GrD3DBackendContext.h"
#endif
SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeGL SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeGL
() { () {
return reinterpret_cast<KNativePointer>(GrDirectContext::MakeGL().release()); return reinterpret_cast<KNativePointer>(GrDirectContext::MakeGL().release());
} }
SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeGLWithInterface
(KNativePointer ptr) {
sk_sp<GrGLInterface> iface = sk_ref_sp(reinterpret_cast<GrGLInterface*>(ptr));
return reinterpret_cast<KNativePointer>(GrDirectContext::MakeGL(iface).release());
}
#ifdef SK_METAL #ifdef SK_METAL
SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeMetal SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeMetal
(long devicePtr, long queuePtr) { (long devicePtr, long queuePtr) {
...@@ -25,11 +35,23 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeMetal ...@@ -25,11 +35,23 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeMetal
sk_sp<GrDirectContext> instance = GrDirectContext::MakeMetal(backendContext); sk_sp<GrDirectContext> instance = GrDirectContext::MakeMetal(backendContext);
return reinterpret_cast<KNativePointer>(instance.release()); return reinterpret_cast<KNativePointer>(instance.release());
} }
#endif #endif // SK_METAL
SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeDirect3D SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeDirect3D
(KNativePointer adapterPtr, KNativePointer devicePtr, KNativePointer queuePtr) { (KNativePointer adapterPtr, KNativePointer devicePtr, KNativePointer queuePtr) {
TODO("implement org_jetbrains_skia_DirectContext__1nMakeDirect3D"); #ifdef SK_DIRECT3D
GrD3DBackendContext backendContext = {};
IDXGIAdapter1* adapter = reinterpret_cast<IDXGIAdapter1*>(adapterPtr);
ID3D12Device* device = reinterpret_cast<ID3D12Device*>(devicePtr);
ID3D12CommandQueue* queue = reinterpret_cast<ID3D12CommandQueue*>(queuePtr);
backendContext.fAdapter.retain(adapter);
backendContext.fDevice.retain(device);
backendContext.fQueue.retain(queue);
sk_sp<GrDirectContext> instance = GrDirectContext::MakeDirect3D(backendContext);
return reinterpret_cast<KNativePointer>(instance.release());
#else // SK_DIRECT3D
return nullptr;
#endif // SK_DIRECT3D
} }
SKIKO_EXPORT void org_jetbrains_skia_DirectContext__1nFlush SKIKO_EXPORT void org_jetbrains_skia_DirectContext__1nFlush
......
...@@ -6,6 +6,10 @@ ...@@ -6,6 +6,10 @@
#include "SkSurface.h" #include "SkSurface.h"
#include "common.h" #include "common.h"
#ifdef SK_METAL
#include "include/gpu/mtl/GrMtlTypes.h"
#endif
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeRasterDirect SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeRasterDirect
(KInt width, KInt height, KInt colorType, KInt alphaType, KNativePointer colorSpacePtr, (KInt width, KInt height, KInt colorType, KInt alphaType, KNativePointer colorSpacePtr,
...@@ -81,7 +85,7 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeFromBackendRenderT ...@@ -81,7 +85,7 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeFromBackendRenderT
SkColorType skColorType = static_cast<SkColorType>(colorType); SkColorType skColorType = static_cast<SkColorType>(colorType);
sk_sp<SkColorSpace> colorSpace = sk_ref_sp<SkColorSpace>(reinterpret_cast<SkColorSpace*>((colorSpacePtr))); sk_sp<SkColorSpace> colorSpace = sk_ref_sp<SkColorSpace>(reinterpret_cast<SkColorSpace*>((colorSpacePtr)));
// std::unique_ptr<SkSurfaceProps> surfaceProps = skija::SurfaceProps::toSkSurfaceProps(env, surfacePropsObj); // std::unique_ptr<SkSurfaceProps> surfaceProps = skija::SurfaceProps::toSkSurfaceProps(surfacePropsObj);
sk_sp<SkSurface> surface = SkSurface::MakeFromBackendRenderTarget( sk_sp<SkSurface> surface = SkSurface::MakeFromBackendRenderTarget(
static_cast<GrRecordingContext*>(context), static_cast<GrRecordingContext*>(context),
...@@ -98,22 +102,15 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeFromBackendRenderT ...@@ -98,22 +102,15 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeFromBackendRenderT
return reinterpret_cast<KNativePointer>(surface.release()); return reinterpret_cast<KNativePointer>(surface.release());
} }
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeFromMTKView
(KNativePointer contextPtr, KNativePointer mtkViewPtr, KInt surfaceOrigin, KInt sampleCount, KInt colorType, KNativePointer colorSpacePtr, KInteropPointer surfacePropsObj) {
TODO("implement org_jetbrains_skia_Surface__1nMakeFromMTKView");
}
#if 0
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeFromMTKView SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeFromMTKView
(KNativePointer contextPtr, KNativePointer mtkViewPtr, KInt surfaceOrigin, KInt sampleCount, KInt colorType, KNativePointer colorSpacePtr, KInteropPointer surfacePropsObj) { (KNativePointer contextPtr, KNativePointer mtkViewPtr, KInt surfaceOrigin, KInt sampleCount, KInt colorType, KNativePointer colorSpacePtr, KInteropPointer surfacePropsObj) {
#ifdef SK_METAL
GrDirectContext* context = reinterpret_cast<GrDirectContext*>((contextPtr)); GrDirectContext* context = reinterpret_cast<GrDirectContext*>((contextPtr));
GrMTLHandle* mtkView = reinterpret_cast<GrMTLHandle*>((mtkViewPtr)); GrMTLHandle* mtkView = reinterpret_cast<GrMTLHandle*>((mtkViewPtr));
GrSurfaceOrigin grSurfaceOrigin = static_cast<GrSurfaceOrigin>(surfaceOrigin); GrSurfaceOrigin grSurfaceOrigin = static_cast<GrSurfaceOrigin>(surfaceOrigin);
SkColorType skColorType = static_cast<SkColorType>(colorType); SkColorType skColorType = static_cast<SkColorType>(colorType);
sk_sp<SkColorSpace> colorSpace = sk_ref_sp<SkColorSpace>(reinterpret_cast<SkColorSpace*>((colorSpacePtr))); sk_sp<SkColorSpace> colorSpace = sk_ref_sp<SkColorSpace>(reinterpret_cast<SkColorSpace*>((colorSpacePtr)));
std::unique_ptr<SkSurfaceProps> surfaceProps = skija::SurfaceProps::toSkSurfaceProps(env, surfacePropsObj); std::unique_ptr<SkSurfaceProps> surfaceProps = skija::SurfaceProps::toSkSurfaceProps(surfacePropsObj);
sk_sp<SkSurface> surface = SkSurface::MakeFromMTKView( sk_sp<SkSurface> surface = SkSurface::MakeFromMTKView(
static_cast<GrRecordingContext*>(context), static_cast<GrRecordingContext*>(context),
...@@ -124,22 +121,11 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeFromMTKView ...@@ -124,22 +121,11 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeFromMTKView
colorSpace, colorSpace,
surfaceProps.get()); surfaceProps.get());
return reinterpret_cast<KNativePointer>(surface.release()); return reinterpret_cast<KNativePointer>(surface.release());
} #else // SK_METAL
#endif return static_cast<KNativePointer>(nullptr);
#endif // SK_METAL
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeRenderTarget
(KNativePointer contextPtr, KBoolean budgeted,
KInt width, KInt height, KInt colorType, KInt alphaType, KNativePointer colorSpacePtr,
KInt sampleCount, KInt surfaceOrigin,
KInteropPointer surfacePropsObj,
KBoolean shouldCreateWithMips)
{
TODO("implement org_jetbrains_skia_Surface__1nMakeRenderTarget");
} }
#if 0
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeRenderTarget SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeRenderTarget
(KNativePointer contextPtr, KBoolean budgeted, (KNativePointer contextPtr, KBoolean budgeted,
KInt width, KInt height, KInt colorType, KInt alphaType, KNativePointer colorSpacePtr, KInt width, KInt height, KInt colorType, KInt alphaType, KNativePointer colorSpacePtr,
...@@ -154,7 +140,7 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeRenderTarget ...@@ -154,7 +140,7 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeRenderTarget
static_cast<SkColorType>(colorType), static_cast<SkColorType>(colorType),
static_cast<SkAlphaType>(alphaType), static_cast<SkAlphaType>(alphaType),
sk_ref_sp<SkColorSpace>(colorSpace)); sk_ref_sp<SkColorSpace>(colorSpace));
std::unique_ptr<SkSurfaceProps> surfaceProps = skija::SurfaceProps::toSkSurfaceProps(env, surfacePropsObj); std::unique_ptr<SkSurfaceProps> surfaceProps = skija::SurfaceProps::toSkSurfaceProps(surfacePropsObj);
sk_sp<SkSurface> instance = SkSurface::MakeRenderTarget( sk_sp<SkSurface> instance = SkSurface::MakeRenderTarget(
context, budgeted ? SkBudgeted::kYes : SkBudgeted::kNo, context, budgeted ? SkBudgeted::kYes : SkBudgeted::kNo,
...@@ -164,8 +150,6 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeRenderTarget ...@@ -164,8 +150,6 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeRenderTarget
shouldCreateWithMips); shouldCreateWithMips);
return reinterpret_cast<KNativePointer>(instance.release()); return reinterpret_cast<KNativePointer>(instance.release());
} }
#endif
SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeNull SKIKO_EXPORT KNativePointer org_jetbrains_skia_Surface__1nMakeNull
(KInt width, KInt height) { (KInt width, KInt height) {
......
...@@ -67,7 +67,7 @@ namespace skija { ...@@ -67,7 +67,7 @@ namespace skija {
} }
namespace SurfaceProps { namespace SurfaceProps {
std::unique_ptr<SkSurfaceProps> toSkSurfaceProps(KInt* surfacePropsInts); std::unique_ptr<SkSurfaceProps> toSkSurfaceProps(KInteropPointer surfacePropsInts);
} }
namespace IRect { namespace IRect {
...@@ -126,12 +126,8 @@ KNativePointer ptrToInterop(T* ptr) { ...@@ -126,12 +126,8 @@ KNativePointer ptrToInterop(T* ptr) {
return ptr; return ptr;
} }
#ifdef __clang__ [[ noreturn ]] void TODO(const char*);
__attribute__((noreturn)) void SKIKO_ASSERT(bool, const char*);
void TODO(const char*);
#else
void TODO(const char*);
#endif
#ifdef SKIKO_WASM #ifdef SKIKO_WASM
#include <emscripten.h> #include <emscripten.h>
......
...@@ -122,6 +122,14 @@ void TODO(const char* message) { ...@@ -122,6 +122,14 @@ void TODO(const char* message) {
abort(); abort();
} }
void SKIKO_ASSERT(bool condition, const char* message){
if (!condition) {
printf("ASSERTION FAILED: %s\n", message);
fflush(stdout);
abort();
}
}
std::unique_ptr<SkMatrix> skMatrix(KFloat* matrixArray) { std::unique_ptr<SkMatrix> skMatrix(KFloat* matrixArray) {
if (matrixArray == nullptr) if (matrixArray == nullptr)
return std::unique_ptr<SkMatrix>(nullptr); return std::unique_ptr<SkMatrix>(nullptr);
...@@ -255,12 +263,13 @@ namespace skija { ...@@ -255,12 +263,13 @@ namespace skija {
} }
namespace SurfaceProps { namespace SurfaceProps {
std::unique_ptr<SkSurfaceProps> toSkSurfaceProps(KInt* surfacePropsInts) { std::unique_ptr<SkSurfaceProps> toSkSurfaceProps(KInteropPointer surfacePropsInts) {
if (surfacePropsInts == nullptr) { if (surfacePropsInts == nullptr) {
return std::unique_ptr<SkSurfaceProps>(nullptr); return std::unique_ptr<SkSurfaceProps>(nullptr);
} }
int flags = surfacePropsInts[0]; KInt* surfaceProps = reinterpret_cast<KInt*>(surfacePropsInts);
SkPixelGeometry geom = static_cast<SkPixelGeometry>(surfacePropsInts[1]); int flags = surfaceProps[0];
SkPixelGeometry geom = static_cast<SkPixelGeometry>(surfaceProps[1]);
return std::make_unique<SkSurfaceProps>(flags, geom); return std::make_unique<SkSurfaceProps>(flags, geom);
} }
} }
......
...@@ -71,3 +71,113 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skiko_tests_TestHelpers__1nWriteArrays ...@@ -71,3 +71,113 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skiko_tests_TestHelpers__1nWriteArrays
return reinterpret_cast<KNativePointer>(mem); return reinterpret_cast<KNativePointer>(mem);
} }
struct SkikoTestGlContext;
SKIKO_EXPORT KNativePointer org_jetbrains_skiko_tests_TestHelpers__1nCreateTestGlContext();
SKIKO_EXPORT void org_jetbrains_skiko_tests_TestHelpers__1nDeleteTestGlContext(KNativePointer ptr);
SKIKO_EXPORT void org_jetbrains_skiko_tests_TestHelpers__1nMakeGlContextCurrent(KNativePointer ptr);
SKIKO_EXPORT void org_jetbrains_skiko_tests_TestHelpers__1nGlContextSwapBuffers(KNativePointer ptr);
SKIKO_EXPORT KNativePointer org_jetbrains_skiko_tests_TestHelpers__1nGlContextGetFinalizer() {
return reinterpret_cast<KNativePointer>(org_jetbrains_skiko_tests_TestHelpers__1nDeleteTestGlContext);
}
#ifdef SK_GL
#ifdef __linux__
#define SKIKO_TEST_GL_INCLUDED
#include <GL/glx.h>
#include <iostream>
#include "include/gpu/gl/GrGLInterface.h"
#include "include/gpu/gl/egl/GrGLMakeEGLInterface.h"
struct SkikoTestGlContext {
Display* display;
GLXWindow surface;
GLXContext context;
Window window;
};
static Bool waitForWindow(Display *dpy, XEvent *event, XPointer arg) {
return (event->xmap.window == (Window)arg) && (event->type == MapNotify);
}
SKIKO_EXPORT KNativePointer org_jetbrains_skiko_tests_TestHelpers__1nCreateTestGlContext() {
const int glxContextAttribs[] {
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DOUBLEBUFFER, True,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
None
};
Display* display = XOpenDisplay(nullptr);
SKIKO_ASSERT(display, "Failed to connect to Xserver");
int numConfigs = 0;
GLXFBConfig* fbConfigs = glXChooseFBConfig(display, DefaultScreen(display), glxContextAttribs, &numConfigs);
SKIKO_ASSERT(fbConfigs != nullptr && numConfigs > 0, "No suitable fbconfig available");
GLXFBConfig fbConfig = fbConfigs[0];
XFree(fbConfigs);
XVisualInfo* visual = glXGetVisualFromFBConfig(display, fbConfig);
XSetWindowAttributes setWindowAttributes;
setWindowAttributes.event_mask = StructureNotifyMask;
setWindowAttributes.border_pixel = 0;
setWindowAttributes.colormap = XCreateColormap(display, RootWindow(display, visual->screen), visual->visual, AllocNone);
int setWindowAttributesMask = CWBorderPixel | CWColormap | CWEventMask;
Window window = XCreateWindow(display, RootWindow(display, visual->screen),
0, 0, 1280, 720, 0, visual->depth, InputOutput, visual->visual,
setWindowAttributesMask, &setWindowAttributes);
GLXWindow surface = glXCreateWindow(display, fbConfig, window, nullptr);
SKIKO_ASSERT(surface, "Failed to create surface");
GLXContext context = glXCreateNewContext(display, fbConfig, GLX_RGBA_TYPE, nullptr, True);
SKIKO_ASSERT(context, "Failed to create context");
XMapWindow(display, window);
XEvent event;
XIfEvent(display, &event, waitForWindow, (XPointer)window);
return reinterpret_cast<KInteropPointer>(new SkikoTestGlContext { display, surface, context, window });
}
SKIKO_EXPORT void org_jetbrains_skiko_tests_TestHelpers__1nDeleteTestGlContext(KNativePointer ptr) {
auto* instance = reinterpret_cast<SkikoTestGlContext*>(ptr);
glXMakeContextCurrent(instance->display, None, None, nullptr);
glXDestroyWindow(instance->display, instance->surface);
glXDestroyContext(instance->display, instance->context);
XDestroyWindow(instance->display, instance->window);
XCloseDisplay(instance->display);
delete instance;
}
SKIKO_EXPORT void org_jetbrains_skiko_tests_TestHelpers__1nMakeGlContextCurrent(KNativePointer ptr) {
auto* instance = reinterpret_cast<SkikoTestGlContext*>(ptr);
glXMakeContextCurrent(instance->display, instance->surface, instance->surface, instance->context);
}
SKIKO_EXPORT void org_jetbrains_skiko_tests_TestHelpers__1nGlContextSwapBuffers(KNativePointer ptr) {
auto* instance = reinterpret_cast<SkikoTestGlContext*>(ptr);
glXSwapBuffers(instance->display, instance->surface);
}
#endif // __linux__
#endif // SK_GL
#ifndef SKIKO_TEST_GL_INCLUDED
SKIKO_EXPORT KNativePointer org_jetbrains_skiko_tests_TestHelpers__1nCreateTestGlContext() {
TODO("OpenGL context is not supported for this platform");
return nullptr;
}
SKIKO_EXPORT void org_jetbrains_skiko_tests_TestHelpers__1nDeleteTestGlContext(KNativePointer ptr) {}
SKIKO_EXPORT void org_jetbrains_skiko_tests_TestHelpers__1nMakeGlContextCurrent(KNativePointer ptr) {}
SKIKO_EXPORT void org_jetbrains_skiko_tests_TestHelpers__1nGlContextSwapBuffers(KNativePointer ptr) {}
#endif // SKIKO_TEST_GL_INCLUDED
\ No newline at end of file
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