diff --git a/skiko/build.gradle.kts b/skiko/build.gradle.kts index ee21c6184..37883d029 100644 --- a/skiko/build.gradle.kts +++ b/skiko/build.gradle.kts @@ -228,6 +228,7 @@ tasks.withType(CppCompile::class.java).configureEach { "-DSK_UNICODE_AVAILABLE", *buildType.flags )) + val includeDir = "$projectDir/src/jvmMain/cpp/include" when (targetOs) { OS.MacOS -> { compilerArgs.addAll( @@ -235,6 +236,7 @@ tasks.withType(CppCompile::class.java).configureEach { "-fvisibility=hidden", "-fvisibility-inlines-hidden", "-I$jdkHome/include/darwin", + "-I$includeDir", "-DSK_SHAPER_CORETEXT_AVAILABLE", "-DSK_BUILD_FOR_MAC", "-DSK_METAL", @@ -248,6 +250,7 @@ tasks.withType(CppCompile::class.java).configureEach { "-fvisibility=hidden", "-fvisibility-inlines-hidden", "-I$jdkHome/include/linux", + "-I$includeDir", "-DSK_BUILD_FOR_LINUX", "-DSK_R32_SHIFT=16", *buildType.clangFlags @@ -258,6 +261,7 @@ tasks.withType(CppCompile::class.java).configureEach { compilerArgs.addAll( listOf( "-I$jdkHome/include/win32", + "-I$includeDir", "-DSK_BUILD_FOR_WIN", "-D_CRT_SECURE_NO_WARNINGS", "-D_HAS_EXCEPTIONS=0", diff --git a/skiko/src/jvmMain/cpp/common/awt_jni.cc b/skiko/src/jvmMain/cpp/common/awt_jni.cc new file mode 100644 index 000000000..3875ebe77 --- /dev/null +++ b/skiko/src/jvmMain/cpp/common/awt_jni.cc @@ -0,0 +1,70 @@ +#include +#include +#include "jni_helpers.h" + +extern "C" jboolean Skiko_GetAWT(JNIEnv *env, JAWT *awt); + +extern "C" +{ + JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_AWTKt_getAWT(JNIEnv *env, jobject obj) + { + JAWT *awt = new JAWT(); + awt->version = (jint)JAWT_VERSION_9; + jboolean result = Skiko_GetAWT(env, awt); + + if (result == JNI_FALSE) + { + return 0; + } + else + { + return toJavaPointer(awt); + } + } + + JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_AWTKt_getDrawingSurface(JNIEnv *env, jobject obj, jlong awtPtr, jobject layer) + { + JAWT *awt = fromJavaPointer(awtPtr); + JAWT_DrawingSurface *ds = awt->GetDrawingSurface(env, layer); + return toJavaPointer(ds); + } + + JNIEXPORT void JNICALL Java_org_jetbrains_skiko_AWTKt_freeDrawingSurface(JNIEnv *env, jobject obj, jlong awtPtr, jlong drawingSurfacePtr) + { + JAWT *awt = fromJavaPointer(awtPtr); + JAWT_DrawingSurface *ds = fromJavaPointer(drawingSurfacePtr); + awt->FreeDrawingSurface(ds); + } + + JNIEXPORT void JNICALL Java_org_jetbrains_skiko_AWTKt_lockDrawingSurface(JNIEnv *env, jobject obj, jlong drawingSurfacePtr) + { + JAWT_DrawingSurface *ds = fromJavaPointer(drawingSurfacePtr); + ds->Lock(ds); + } + + JNIEXPORT void JNICALL Java_org_jetbrains_skiko_AWTKt_unlockDrawingSurface(JNIEnv *env, jobject obj, jlong drawingSurfacePtr) + { + JAWT_DrawingSurface *ds = fromJavaPointer(drawingSurfacePtr); + ds->Unlock(ds); + } + + JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_AWTKt_getDrawingSurfaceInfo(JNIEnv *env, jobject obj, jlong drawingSurfacePtr) + { + JAWT_DrawingSurface *ds = fromJavaPointer(drawingSurfacePtr); + JAWT_DrawingSurfaceInfo *dsi = ds->GetDrawingSurfaceInfo(ds); + return toJavaPointer(dsi); + } + + JNIEXPORT void JNICALL Java_org_jetbrains_skiko_AWTKt_freeDrawingSurfaceInfo(JNIEnv *env, jobject obj, jlong drawingSurfacePtr, jlong drawingSurfaceInfoPtr) + { + JAWT_DrawingSurface *ds = fromJavaPointer(drawingSurfacePtr); + JAWT_DrawingSurfaceInfo *dsi = fromJavaPointer(drawingSurfaceInfoPtr); + ds->FreeDrawingSurfaceInfo(dsi); + } + + JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_AWTKt_getPlatformInfo(JNIEnv *env, jobject obj, jlong drawingSurfaceInfoPtr) + { + JAWT_DrawingSurfaceInfo *dsi = fromJavaPointer(drawingSurfaceInfoPtr); + return toJavaPointer(dsi->platformInfo); + } +} \ No newline at end of file diff --git a/skiko/src/jvmMain/cpp/include/jni_helpers.h b/skiko/src/jvmMain/cpp/include/jni_helpers.h new file mode 100644 index 000000000..c724291f2 --- /dev/null +++ b/skiko/src/jvmMain/cpp/include/jni_helpers.h @@ -0,0 +1,7 @@ +#pragma once + +template +T inline fromJavaPointer(jlong ptr) { return reinterpret_cast(static_cast(ptr)); } + +template +jlong inline toJavaPointer(T ptr) { return static_cast(reinterpret_cast(ptr)); } \ No newline at end of file diff --git a/skiko/src/jvmMain/cpp/linux/drawlayer.cc b/skiko/src/jvmMain/cpp/linux/drawlayer.cc index 7b3f5c157..e203d677b 100755 --- a/skiko/src/jvmMain/cpp/linux/drawlayer.cc +++ b/skiko/src/jvmMain/cpp/linux/drawlayer.cc @@ -7,14 +7,13 @@ #include #include #include +#include "jni_helpers.h" typedef GLXContext (*glXCreateContextAttribsARBProc)(Display *, GLXFBConfig, GLXContext, Bool, const int *); -extern "C" jboolean Skiko_GetAWT(JNIEnv *env, JAWT *awt); - extern "C" { - JNIEXPORT void JNICALL Java_org_jetbrains_skiko_HardwareLayer_init(JNIEnv *env, jobject canvas) + JNIEXPORT void JNICALL Java_org_jetbrains_skiko_HardwareLayer_nativeInit(JNIEnv *env, jobject canvas, jlong platformInfoPtr) { } @@ -22,37 +21,10 @@ extern "C" { } - JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_HardwareLayer_getWindowHandle(JNIEnv *env, jobject canvas) + JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_HardwareLayer_getWindowHandle(JNIEnv *env, jobject canvas, jlong platformInfoPtr) { - JAWT awt; - JAWT_DrawingSurface *ds = NULL; - JAWT_DrawingSurfaceInfo *dsi = NULL; - - jboolean result = JNI_FALSE; - jint lock = 0; - JAWT_X11DrawingSurfaceInfo *dsi_x11; - - awt.version = (jint)JAWT_VERSION_9; - result = Skiko_GetAWT(env, &awt); - - if (result == JNI_FALSE) - { - fprintf(stderr, "JAWT_GetAWT failed! Result is JNI_FALSE\n"); - return -1; - } - - ds = awt.GetDrawingSurface(env, canvas); - lock = ds->Lock(ds); - dsi = ds->GetDrawingSurfaceInfo(ds); - dsi_x11 = (JAWT_X11DrawingSurfaceInfo *)dsi->platformInfo; - - Window window = dsi_x11->drawable; - - ds->FreeDrawingSurfaceInfo(dsi); - ds->Unlock(ds); - awt.FreeDrawingSurface(ds); - - return (jlong)window; + JAWT_X11DrawingSurfaceInfo *dsi_x11 = fromJavaPointer(platformInfoPtr); + return (jlong) dsi_x11->drawable; } double getDpiScaleByDisplay(Display *display) @@ -77,38 +49,9 @@ extern "C" return 1; } - JNIEXPORT jfloat JNICALL Java_org_jetbrains_skiko_PlatformOperationsKt_linuxGetDpiScaleNative(JNIEnv *env, jobject properties, jobject component) + JNIEXPORT jfloat JNICALL Java_org_jetbrains_skiko_PlatformOperationsKt_linuxGetDpiScaleNative(JNIEnv *env, jobject properties, jlong platformInfoPtr) { - JAWT awt; - JAWT_DrawingSurface *ds = NULL; - JAWT_DrawingSurfaceInfo *dsi = NULL; - - jboolean result = JNI_FALSE; - jint lock = 0; - JAWT_X11DrawingSurfaceInfo *dsi_x11; - - awt.version = (jint)JAWT_VERSION_9; - result = Skiko_GetAWT(env, &awt); - - if (result == JNI_FALSE) - { - fprintf(stderr, "JAWT_GetAWT failed! Result is JNI_FALSE\n"); - return -1; - } - - ds = awt.GetDrawingSurface(env, component); - lock = ds->Lock(ds); - dsi = ds->GetDrawingSurfaceInfo(ds); - dsi_x11 = (JAWT_X11DrawingSurfaceInfo *)dsi->platformInfo; - - Display *display = dsi_x11->display; - - float dpi = (float)getDpiScaleByDisplay(display); - - ds->FreeDrawingSurfaceInfo(dsi); - ds->Unlock(ds); - awt.FreeDrawingSurface(ds); - - return dpi; + JAWT_X11DrawingSurfaceInfo *dsi_x11 = fromJavaPointer(platformInfoPtr); + return (float) getDpiScaleByDisplay(dsi_x11->display); } } // extern "C" \ No newline at end of file diff --git a/skiko/src/jvmMain/cpp/linux/redrawer.cc b/skiko/src/jvmMain/cpp/linux/redrawer.cc index 92065fc63..a86431f78 100644 --- a/skiko/src/jvmMain/cpp/linux/redrawer.cc +++ b/skiko/src/jvmMain/cpp/linux/redrawer.cc @@ -7,74 +7,30 @@ #include #include #include +#include "jni_helpers.h" typedef GLXContext (*glXCreateContextAttribsARBProc)(Display *, GLXFBConfig, GLXContext, Bool, const int *); -extern "C" jboolean Skiko_GetAWT(JNIEnv *env, JAWT *awt); - extern "C" { - JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_LinuxOpenGLRedrawerKt_lockDrawingSurfaceNative(JNIEnv *env, jobject redrawer, jobject layer) - { - JAWT awt; - awt.version = (jint)JAWT_VERSION_9; - if (!Skiko_GetAWT(env, &awt)) - { - fprintf(stderr, "JAWT_GetAWT failed! Result is JNI_FALSE\n"); - return 0; - } - - JAWT_DrawingSurface *ds = awt.GetDrawingSurface(env, layer); - ds->Lock(ds); - - return static_cast(reinterpret_cast(ds)); - } - - JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_LinuxOpenGLRedrawerKt_unlockDrawingSurfaceNative(JNIEnv *env, jobject redrawer, jlong drawingSurfacePtr) + JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_LinuxOpenGLRedrawerKt_getDisplay(JNIEnv *env, jobject redrawer, jlong platformInfoPtr) { - JAWT_DrawingSurface *ds = reinterpret_cast(static_cast(drawingSurfacePtr)); - JAWT awt; - awt.version = (jint)JAWT_VERSION_9; - if (!Skiko_GetAWT(env, &awt)) - { - fprintf(stderr, "JAWT_GetAWT failed! Result is JNI_FALSE\n"); - return 0; - } - - ds->Unlock(ds); - awt.FreeDrawingSurface(ds); - - return static_cast(reinterpret_cast(ds)); - } - - JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_LinuxOpenGLRedrawerKt_getDisplay(JNIEnv *env, jobject redrawer, jlong drawingSurfacePtr) - { - JAWT_DrawingSurface *ds = reinterpret_cast(static_cast(drawingSurfacePtr)); - JAWT_DrawingSurfaceInfo *dsi = ds->GetDrawingSurfaceInfo(ds); - JAWT_X11DrawingSurfaceInfo *dsi_x11 = (JAWT_X11DrawingSurfaceInfo *)dsi->platformInfo; - + JAWT_X11DrawingSurfaceInfo *dsi_x11 = fromJavaPointer(platformInfoPtr); Display *display = dsi_x11->display; - - ds->FreeDrawingSurfaceInfo(dsi); - return static_cast(reinterpret_cast(display)); + return toJavaPointer(display); } - JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_LinuxOpenGLRedrawerKt_getWindow(JNIEnv *env, jobject redrawer, jlong drawingSurfacePtr) + JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_LinuxOpenGLRedrawerKt_getWindow(JNIEnv *env, jobject redrawer, jlong platformInfoPtr) { - JAWT_DrawingSurface *ds = reinterpret_cast(static_cast(drawingSurfacePtr)); - JAWT_DrawingSurfaceInfo *dsi = ds->GetDrawingSurfaceInfo(ds); - JAWT_X11DrawingSurfaceInfo *dsi_x11 = (JAWT_X11DrawingSurfaceInfo *)dsi->platformInfo; - + JAWT_X11DrawingSurfaceInfo *dsi_x11 = fromJavaPointer(platformInfoPtr); Window window = dsi_x11->drawable; - - ds->FreeDrawingSurfaceInfo(dsi); - return static_cast(reinterpret_cast(window)); + return toJavaPointer(window); } JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_LinuxOpenGLRedrawerKt_setSwapInterval(JNIEnv *env, jobject redrawer, jlong displayPtr, jlong windowPtr, jint interval) { - Display *display = reinterpret_cast(static_cast(displayPtr)); - Window window = reinterpret_cast(static_cast(windowPtr)); + Display *display = fromJavaPointer(displayPtr); + Window window = fromJavaPointer(windowPtr); // according to: // https://opengl.gpuinfo.org/listreports.php?extension=GLX_EXT_swap_control @@ -106,35 +62,35 @@ extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_LinuxOpenGLRedrawerKt_swapBuffers(JNIEnv *env, jobject redrawer, jlong displayPtr, jlong windowPtr) { - Display *display = reinterpret_cast(static_cast(displayPtr)); - Window window = reinterpret_cast(static_cast(windowPtr)); + Display *display = fromJavaPointer(displayPtr); + Window window = fromJavaPointer(windowPtr); glXSwapBuffers(display, window); } JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_LinuxOpenGLRedrawerKt_makeCurrent(JNIEnv *env, jobject redrawer, jlong displayPtr, jlong windowPtr, jlong contextPtr) { - Display *display = reinterpret_cast(static_cast(displayPtr)); - Window window = reinterpret_cast(static_cast(windowPtr)); - GLXContext *context = reinterpret_cast(static_cast(contextPtr)); + Display *display = fromJavaPointer(displayPtr); + Window window = fromJavaPointer(windowPtr); + GLXContext *context = fromJavaPointer(contextPtr); glXMakeCurrent(display, window, *context); } JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_LinuxOpenGLRedrawerKt_createContext(JNIEnv *env, jobject redrawer, jlong displayPtr) { - Display *display = reinterpret_cast(static_cast(displayPtr)); + Display *display = fromJavaPointer(displayPtr); GLint att[] = {GLX_RGBA, GLX_DOUBLEBUFFER, True, None}; XVisualInfo *vi = glXChooseVisual(display, 0, att); GLXContext *context = new GLXContext(glXCreateContext(display, vi, NULL, GL_TRUE)); - return static_cast(reinterpret_cast(context)); + return toJavaPointer(context); } JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_LinuxOpenGLRedrawerKt_destroyContext(JNIEnv *env, jobject redrawer, jlong displayPtr, jlong contextPtr) { - Display *display = reinterpret_cast(static_cast(displayPtr)); - GLXContext *context = reinterpret_cast(static_cast(contextPtr)); + Display *display = fromJavaPointer(displayPtr); + GLXContext *context = fromJavaPointer(contextPtr); glXDestroyContext(display, *context); delete context; diff --git a/skiko/src/jvmMain/cpp/windows/drawlayer.cc b/skiko/src/jvmMain/cpp/windows/drawlayer.cc index bbf15f4cb..7936fdf35 100755 --- a/skiko/src/jvmMain/cpp/windows/drawlayer.cc +++ b/skiko/src/jvmMain/cpp/windows/drawlayer.cc @@ -1,11 +1,10 @@ #define WIN32_LEAN_AND_MEAN #include - -extern "C" jboolean Skiko_GetAWT(JNIEnv *env, JAWT *awt); +#include "jni_helpers.h" extern "C" { - JNIEXPORT void JNICALL Java_org_jetbrains_skiko_HardwareLayer_init(JNIEnv *env, jobject canvas) + JNIEXPORT void JNICALL Java_org_jetbrains_skiko_HardwareLayer_nativeInit(JNIEnv *env, jobject canvas, jlong platformInfoPtr) { } @@ -13,36 +12,9 @@ extern "C" { } - JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_HardwareLayer_getWindowHandle(JNIEnv *env, jobject canvas) + JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_HardwareLayer_getWindowHandle(JNIEnv *env, jobject canvas, jlong platformInfoPtr) { - JAWT awt; - JAWT_DrawingSurface *ds = NULL; - JAWT_DrawingSurfaceInfo *dsi = NULL; - - jboolean result = JNI_FALSE; - jint lock = 0; - JAWT_Win32DrawingSurfaceInfo *dsi_win; - - awt.version = (jint)JAWT_VERSION_9; - result = Skiko_GetAWT(env, &awt); - - if (result == JNI_FALSE) - { - fprintf(stderr, "JAWT_GetAWT failed! Result is JNI_FALSE\n"); - return -1; - } - - ds = awt.GetDrawingSurface(env, canvas); - lock = ds->Lock(ds); - dsi = ds->GetDrawingSurfaceInfo(ds); - dsi_win = (JAWT_Win32DrawingSurfaceInfo *)dsi->platformInfo; - - HWND hwnd = dsi_win->hwnd; - - ds->FreeDrawingSurfaceInfo(dsi); - ds->Unlock(ds); - awt.FreeDrawingSurface(ds); - - return (jlong)hwnd; + JAWT_Win32DrawingSurfaceInfo* dsi_win = fromJavaPointer(platformInfoPtr); + return (jlong) dsi_win->hwnd; } } // extern "C" \ No newline at end of file diff --git a/skiko/src/jvmMain/cpp/windows/redrawer.cc b/skiko/src/jvmMain/cpp/windows/redrawer.cc index 2ad993ebe..cab918ccc 100644 --- a/skiko/src/jvmMain/cpp/windows/redrawer.cc +++ b/skiko/src/jvmMain/cpp/windows/redrawer.cc @@ -3,49 +3,30 @@ #include #include #include - -extern "C" jboolean Skiko_GetAWT(JNIEnv *env, JAWT *awt); +#include "jni_helpers.h" extern "C" { - JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_WindowsOpenGLRedrawerKt_getDevice(JNIEnv *env, jobject redrawer, jobject layer) + JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_WindowsOpenGLRedrawerKt_getDevice(JNIEnv *env, jobject redrawer, jlong platformInfoPtr) { - JAWT awt; - awt.version = (jint)JAWT_VERSION_9; - if (!Skiko_GetAWT(env, &awt)) - { - fprintf(stderr, "JAWT_GetAWT failed! Result is JNI_FALSE\n"); - return 0; - } - - JAWT_DrawingSurface *ds = awt.GetDrawingSurface(env, layer); - ds->Lock(ds); - JAWT_DrawingSurfaceInfo *dsi = ds->GetDrawingSurfaceInfo(ds); - JAWT_Win32DrawingSurfaceInfo *dsi_win = (JAWT_Win32DrawingSurfaceInfo *)dsi->platformInfo; + JAWT_Win32DrawingSurfaceInfo* dsi_win = fromJavaPointer(platformInfoPtr); HWND hwnd = dsi_win->hwnd; HDC device = GetDC(hwnd); - if (dsi != NULL) - { - PIXELFORMATDESCRIPTOR pixFormatDscr; - memset(&pixFormatDscr, 0, sizeof(PIXELFORMATDESCRIPTOR)); - pixFormatDscr.nSize = sizeof(PIXELFORMATDESCRIPTOR); - pixFormatDscr.nVersion = 1; - pixFormatDscr.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - - pixFormatDscr.iPixelType = PFD_TYPE_RGBA; - pixFormatDscr.cColorBits = 32; - int iPixelFormat = ChoosePixelFormat(device, &pixFormatDscr); - SetPixelFormat(device, iPixelFormat, &pixFormatDscr); - DescribePixelFormat(device, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pixFormatDscr); - } + PIXELFORMATDESCRIPTOR pixFormatDscr; + memset(&pixFormatDscr, 0, sizeof(PIXELFORMATDESCRIPTOR)); + pixFormatDscr.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pixFormatDscr.nVersion = 1; + pixFormatDscr.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - ds->FreeDrawingSurfaceInfo(dsi); - ds->Unlock(ds); - awt.FreeDrawingSurface(ds); + pixFormatDscr.iPixelType = PFD_TYPE_RGBA; + pixFormatDscr.cColorBits = 32; + int iPixelFormat = ChoosePixelFormat(device, &pixFormatDscr); + SetPixelFormat(device, iPixelFormat, &pixFormatDscr); + DescribePixelFormat(device, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pixFormatDscr); - return static_cast(reinterpret_cast(device)); + return toJavaPointer(device); } JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_WindowsOpenGLRedrawerKt_setSwapInterval(JNIEnv *env, jobject redrawer, jint interval) @@ -62,26 +43,26 @@ extern "C" JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_WindowsOpenGLRedrawerKt_swapBuffers(JNIEnv *env, jobject redrawer, jlong devicePtr) { - HDC device = reinterpret_cast(static_cast(devicePtr)); + HDC device = fromJavaPointer(devicePtr); SwapBuffers(device); } JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_WindowsOpenGLRedrawerKt_makeCurrent(JNIEnv *env, jobject redrawer, jlong devicePtr, jlong contextPtr) { - HDC device = reinterpret_cast(static_cast(devicePtr)); - HGLRC context = reinterpret_cast(static_cast(contextPtr)); + HDC device = fromJavaPointer(devicePtr); + HGLRC context = fromJavaPointer(contextPtr); wglMakeCurrent(device, context); } JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_WindowsOpenGLRedrawerKt_createContext(JNIEnv *env, jobject redrawer, jlong devicePtr) { - HDC device = reinterpret_cast(static_cast(devicePtr)); - return static_cast(reinterpret_cast(wglCreateContext(device))); + HDC device = fromJavaPointer(devicePtr); + return toJavaPointer(wglCreateContext(device)); } JNIEXPORT void JNICALL Java_org_jetbrains_skiko_redrawer_WindowsOpenGLRedrawerKt_deleteContext(JNIEnv *env, jobject redrawer, jlong contextPtr) { - HGLRC context = reinterpret_cast(static_cast(contextPtr)); + HGLRC context = fromJavaPointer(contextPtr); wglDeleteContext(context); } diff --git a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/AWT.kt b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/AWT.kt new file mode 100644 index 000000000..19d62b9ef --- /dev/null +++ b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/AWT.kt @@ -0,0 +1,83 @@ +package org.jetbrains.skiko + +import java.awt.Component + +private val awt = getAWT().also { + check(it != 0L) +} + +internal fun Component.useDrawingSurfacePlatformInfo( + block: (Long) -> T +) = useDrawingSurfaceInfo { block(it.platformInfo) } + +internal fun Component.useDrawingSurfaceInfo( + block: (DrawingSurfaceInfo) -> T +): T = getDrawingSurface().use { drawingSurface -> + drawingSurface.withLock { + drawingSurface.getInfo().use { info -> + block(info) + } + } +} + +internal fun Component.getDrawingSurface() = DrawingSurface(this) + +internal class DrawingSurface( + component: Component +) : AutoCloseable { + var ptr = + getDrawingSurface(awt, component).also { + check(it != 0L) + } + private set + + fun lock() = lockDrawingSurface(ptr) + + fun unlock() = unlockDrawingSurface(ptr) + + inline fun withLock(block: () -> T): T { + lock() + try { + return block() + } finally { + unlock() + } + } + + fun getInfo() = DrawingSurfaceInfo(ptr) + + override fun close() { + freeDrawingSurface(awt, ptr) + ptr = 0 + } +} + +internal class DrawingSurfaceInfo( + private val drawingSurface: Long +) : AutoCloseable { + var ptr = + getDrawingSurfaceInfo(drawingSurface).also { + check(it != 0L) + } + private set + + val platformInfo: Long get() = getPlatformInfo(ptr) + + override fun close() { + freeDrawingSurfaceInfo(drawingSurface, ptr) + ptr = 0 + } +} + +private external fun getAWT(): Long + +private external fun getDrawingSurface(awt: Long, layer: Component): Long +private external fun freeDrawingSurface(awt: Long, drawingSurface: Long) + +private external fun lockDrawingSurface(drawingSurface: Long) +private external fun unlockDrawingSurface(drawingSurface: Long) + +private external fun getDrawingSurfaceInfo(drawingSurface: Long): Long +private external fun freeDrawingSurfaceInfo(drawingSurface: Long, drawingSurfaceInfo: Long) + +private external fun getPlatformInfo(drawingSurfaceInfo: Long): Long \ No newline at end of file diff --git a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/HardwareLayer.kt b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/HardwareLayer.kt index b3fe7c1ef..f77a77728 100755 --- a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/HardwareLayer.kt +++ b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/HardwareLayer.kt @@ -32,7 +32,13 @@ abstract class HardwareLayer : Canvas() { } } - protected open external fun init() + + protected open fun init() { + useDrawingSurfacePlatformInfo(::nativeInit) + } + + protected open external fun nativeInit(platformInfo: Long) + open external fun dispose() protected open fun contentScaleChanged() = Unit @@ -68,7 +74,7 @@ abstract class HardwareLayer : Canvas() { internal abstract fun draw() val windowHandle: Long - external get + get() = useDrawingSurfacePlatformInfo(::getWindowHandle) val contentScale: Float get() = _contentScale!! @@ -76,4 +82,6 @@ abstract class HardwareLayer : Canvas() { var fullscreen: Boolean get() = platformOperations.isFullscreen(this) set(value) = platformOperations.setFullscreen(this, value) + + private external fun getWindowHandle(platformInfo: Long): Long } \ No newline at end of file diff --git a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/PlatformOperations.kt b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/PlatformOperations.kt index 62ed2fe55..854811bca 100644 --- a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/PlatformOperations.kt +++ b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/PlatformOperations.kt @@ -88,7 +88,7 @@ internal val platformOperations: PlatformOperations by lazy { // see also comment for HardwareLayer.checkContentScale - // return linuxGetDpiScaleNative(component) +// return component.useDrawingSurfacePlatformInfo(::linuxGetDpiScaleNative) } override fun createRedrawer(layer: HardwareLayer) = when(renderApi) { @@ -105,4 +105,4 @@ external private fun osxIsFullscreenNative(component: Component): Boolean external private fun osxSetFullscreenNative(component: Component, value: Boolean) // Linux -external private fun linuxGetDpiScaleNative(component: Component): Float +external private fun linuxGetDpiScaleNative(platformInfo: Long): Float diff --git a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/LinuxOpenGLRedrawer.kt b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/LinuxOpenGLRedrawer.kt index 2cd057f61..5b7f683ea 100644 --- a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/LinuxOpenGLRedrawer.kt +++ b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/LinuxOpenGLRedrawer.kt @@ -3,10 +3,12 @@ package org.jetbrains.skiko.redrawer import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.swing.Swing +import org.jetbrains.skiko.DrawingSurface import org.jetbrains.skiko.FrameDispatcher import org.jetbrains.skiko.HardwareLayer import org.jetbrains.skiko.OpenGLApi import org.jetbrains.skiko.SkikoProperties +import org.jetbrains.skiko.getDrawingSurface internal class LinuxOpenGLRedrawer( private val layer: HardwareLayer @@ -92,7 +94,7 @@ internal class LinuxOpenGLRedrawer( } } -private inline fun HardwareLayer.lockDrawingSurface(action: (DrawingSurface) -> T): T { +private inline fun HardwareLayer.lockDrawingSurface(action: (LinuxDrawingSurface) -> T): T { val drawingSurface = lockDrawingSurface(this) try { return action(drawingSurface) @@ -101,17 +103,21 @@ private inline fun HardwareLayer.lockDrawingSurface(action: (DrawingSurface) } } -private fun lockDrawingSurface(layer: HardwareLayer): DrawingSurface { - val ptr = lockDrawingSurfaceNative(layer) - return DrawingSurface(ptr, getDisplay(ptr), getWindow(ptr)) +private fun lockDrawingSurface(layer: HardwareLayer): LinuxDrawingSurface { + val drawingSurface = layer.getDrawingSurface() + drawingSurface.lock() + return drawingSurface.getInfo().use { + LinuxDrawingSurface(drawingSurface, getDisplay(it.platformInfo), getWindow(it.platformInfo)) + } } -private fun unlockDrawingSurface(drawingSurface: DrawingSurface) { - unlockDrawingSurfaceNative(drawingSurface.ptr) +private fun unlockDrawingSurface(drawingSurface: LinuxDrawingSurface) { + drawingSurface.common.unlock() + drawingSurface.common.close() } -private class DrawingSurface( - val ptr: Long, +private class LinuxDrawingSurface( + val common: DrawingSurface, val display: Long, val window: Long ) { @@ -122,10 +128,8 @@ private class DrawingSurface( fun setSwapInterval(interval: Int) = setSwapInterval(display, window, interval) } -private external fun lockDrawingSurfaceNative(layer: HardwareLayer): Long -private external fun unlockDrawingSurfaceNative(drawingSurface: Long) -private external fun getDisplay(drawingSurface: Long): Long -private external fun getWindow(drawingSurface: Long): Long +private external fun getDisplay(platformInfo: Long): Long +private external fun getWindow(platformInfo: Long): Long private external fun makeCurrent(display: Long, window: Long, context: Long) private external fun createContext(display: Long): Long diff --git a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/MacOsOpenGLRedrawer.kt b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/MacOsOpenGLRedrawer.kt index fe9190bb4..205e82944 100644 --- a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/MacOsOpenGLRedrawer.kt +++ b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/MacOsOpenGLRedrawer.kt @@ -6,6 +6,7 @@ import org.jetbrains.skiko.FrameDispatcher import org.jetbrains.skiko.HardwareLayer import org.jetbrains.skiko.OpenGLApi import org.jetbrains.skiko.SkikoProperties +import org.jetbrains.skiko.useDrawingSurfacePlatformInfo import org.jetbrains.skiko.Task import javax.swing.SwingUtilities.convertPoint import javax.swing.SwingUtilities.getRootPane @@ -13,7 +14,7 @@ import javax.swing.SwingUtilities.getRootPane internal class MacOsOpenGLRedrawer( private val layer: HardwareLayer ) : Redrawer { - private val containerLayerPtr = initContainer(layer) + private val containerLayerPtr = layer.useDrawingSurfacePlatformInfo(::initContainer) private val drawLock = Any() private var isDisposed = false @@ -161,7 +162,7 @@ private abstract class AWTGLLayer(private val containerPtr: Long, setNeedsDispla protected external fun setFrame(containerPtr: Long, ptr: Long, x: Float, y: Float, width: Float, height: Float) } -private external fun initContainer(layer: HardwareLayer): Long +private external fun initContainer(platformInfo: Long): Long private external fun setContentScale(layerNativePtr: Long, contentScale: Float) private external fun initAWTGLLayer(containerPtr: Long, layer: AWTGLLayer, setNeedsDisplayOnBoundsChange: Boolean): Long private external fun disposeAWTGLLayer(ptr: Long) \ No newline at end of file diff --git a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/WindowsOpenGLRedrawer.kt b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/WindowsOpenGLRedrawer.kt index 3c973e600..88c57faa2 100644 --- a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/WindowsOpenGLRedrawer.kt +++ b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/redrawer/WindowsOpenGLRedrawer.kt @@ -8,11 +8,12 @@ import org.jetbrains.skiko.FrameDispatcher import org.jetbrains.skiko.HardwareLayer import org.jetbrains.skiko.OpenGLApi import org.jetbrains.skiko.SkikoProperties +import org.jetbrains.skiko.useDrawingSurfacePlatformInfo internal class WindowsOpenGLRedrawer( private val layer: HardwareLayer ) : Redrawer { - private val device = getDevice(layer) + private val device = layer.useDrawingSurfacePlatformInfo(::getDevice) private val context = createContext(device) private var isDisposed = false @@ -101,7 +102,7 @@ internal class WindowsOpenGLRedrawer( } private external fun makeCurrent(device: Long, context: Long) -private external fun getDevice(layer: HardwareLayer): Long +private external fun getDevice(platformInfo: Long): Long private external fun createContext(device: Long): Long private external fun deleteContext(context: Long) private external fun setSwapInterval(interval: Int) diff --git a/skiko/src/jvmMain/objectiveC/macos/drawlayer.m b/skiko/src/jvmMain/objectiveC/macos/drawlayer.m index 02f931ddf..b087894b7 100755 --- a/skiko/src/jvmMain/objectiveC/macos/drawlayer.m +++ b/skiko/src/jvmMain/objectiveC/macos/drawlayer.m @@ -79,66 +79,37 @@ - (void) makeFullscreen: (BOOL) value return NULL; } -extern jboolean Skiko_GetAWT(JNIEnv* env, JAWT* awt); - -JNIEXPORT void JNICALL Java_org_jetbrains_skiko_HardwareLayer_init(JNIEnv *env, jobject canvas) +JNIEXPORT void JNICALL Java_org_jetbrains_skiko_HardwareLayer_nativeInit(JNIEnv *env, jobject canvas, jlong platformInfoPtr) { if (layerStorage == nil) { layerStorage = [[NSMutableSet alloc] init]; } - JAWT awt; - JAWT_DrawingSurface *ds = NULL; - JAWT_DrawingSurfaceInfo *dsi = NULL; - - jboolean result = JNI_FALSE; - jint lock = 0; - NSObject* dsi_mac = NULL; - - awt.version = JAWT_VERSION_9 /* | JAWT_MACOSX_USE_CALAYER */; - result = Skiko_GetAWT(env, &awt); - assert(result != JNI_FALSE); + NSObject* dsi_mac = (__bridge NSObject *) platformInfoPtr; - ds = awt.GetDrawingSurface(env, canvas); - assert(ds != NULL); + LayerHandler *layersSet = [[LayerHandler alloc] init]; - lock = ds->Lock(ds); - assert((lock & JAWT_LOCK_ERROR) == 0); + layersSet.container = [dsi_mac windowLayer]; + jobject canvasGlobalRef = (*env)->NewGlobalRef(env, canvas); + [layersSet setCanvasGlobalRef: canvasGlobalRef]; - dsi = ds->GetDrawingSurfaceInfo(ds); + NSMutableArray *windows = [NSMutableArray arrayWithArray: [[NSApplication sharedApplication] windows]]; - if (dsi != NULL) + for (LayerHandler* value in layerStorage) { - dsi_mac = ( __bridge NSObject *) dsi->platformInfo; - - LayerHandler *layersSet = [[LayerHandler alloc] init]; - - layersSet.container = [dsi_mac windowLayer]; - jobject canvasGlobalRef = (*env)->NewGlobalRef(env, canvas); - [layersSet setCanvasGlobalRef: canvasGlobalRef]; - - NSMutableArray *windows = [NSMutableArray arrayWithArray: [[NSApplication sharedApplication] windows]]; - - for (LayerHandler* value in layerStorage) - { - if (layersSet.container == value.container) - { - layersSet.window = value.window; - } - } - - if (layersSet.window == NULL) + if (layersSet.container == value.container) { - layersSet.window = [windows lastObject]; + layersSet.window = value.window; } + } - [layerStorage addObject: layersSet]; + if (layersSet.window == NULL) + { + layersSet.window = [windows lastObject]; } - ds->FreeDrawingSurfaceInfo(dsi); - ds->Unlock(ds); - awt.FreeDrawingSurface(ds); + [layerStorage addObject: layersSet]; } JNIEXPORT void JNICALL Java_org_jetbrains_skiko_HardwareLayer_dispose(JNIEnv *env, jobject canvas) diff --git a/skiko/src/jvmMain/objectiveC/macos/redrawer.m b/skiko/src/jvmMain/objectiveC/macos/redrawer.m index 386583be7..67a6d5a53 100644 --- a/skiko/src/jvmMain/objectiveC/macos/redrawer.m +++ b/skiko/src/jvmMain/objectiveC/macos/redrawer.m @@ -7,8 +7,6 @@ #import #import -extern jboolean Skiko_GetAWT(JNIEnv* env, JAWT* awt); - JavaVM *jvm = NULL; @interface AWTGLLayer : CAOpenGLLayer @@ -69,35 +67,17 @@ -(void)drawInCGLContext:(CGLContextObj)ctx @end -JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MacOsOpenGLRedrawerKt_initContainer(JNIEnv *env, jobject redrawer, jobject layer) +JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_MacOsOpenGLRedrawerKt_initContainer(JNIEnv *env, jobject redrawer, jlong platformInfoPtr) { - JAWT awt; - awt.version = JAWT_VERSION_9; - jboolean result = Skiko_GetAWT(env, &awt); - assert(result != JNI_FALSE); - (*env)->GetJavaVM(env, &jvm); - JAWT_DrawingSurface *ds = awt.GetDrawingSurface(env, layer); - assert(ds != NULL); - - jint lock = ds->Lock(ds); - assert((lock & JAWT_LOCK_ERROR) == 0); - - JAWT_DrawingSurfaceInfo *dsi = ds->GetDrawingSurfaceInfo(ds); - assert(dsi != NULL); - - NSObject* dsi_mac = (__bridge NSObject *) dsi->platformInfo; + NSObject* dsi_mac = (__bridge NSObject *) platformInfoPtr; CALayer *container = [dsi_mac windowLayer]; [container removeAllAnimations]; [container setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)]; [container setNeedsDisplayOnBoundsChange: YES]; - ds->FreeDrawingSurfaceInfo(dsi); - ds->Unlock(ds); - awt.FreeDrawingSurface(ds); - return (jlong) container; }