Unverified Commit 1c4afac6 authored by nikola-kocic-jetbrains's avatar nikola-kocic-jetbrains Committed by GitHub

feat(jvm): add GLAssembledInterface.createFromNativePointers and...

feat(jvm): add GLAssembledInterface.createFromNativePointers and DirectContext.makeGLWithInterface (#1048)

Needed to enable OpenGL on Wayland (via EGL)
parent 6955c19e
#include <iostream> #include <iostream>
#include <jni.h> #include <jni.h>
#include "ganesh/GrDirectContext.h" #include "ganesh/GrDirectContext.h"
#include "ganesh/gl/GrGLAssembleInterface.h"
#include "ganesh/gl/GrGLDirectContext.h" #include "ganesh/gl/GrGLDirectContext.h"
#include "ganesh/gl/GrGLInterface.h"
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_DirectContextKt__1nMakeGL extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_DirectContextKt__1nMakeGL
(JNIEnv* env, jclass jclass) { (JNIEnv* env, jclass jclass) {
return reinterpret_cast<jlong>(GrDirectContexts::MakeGL().release()); return reinterpret_cast<jlong>(GrDirectContexts::MakeGL().release());
} }
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_DirectContext_1jvmKt__1nMakeGLWithInterface
(JNIEnv* env, jclass jclass, jlong interfacePtr) {
sk_sp<const GrGLInterface> interface = sk_ref_sp(reinterpret_cast<const GrGLInterface*>(interfacePtr));
return reinterpret_cast<jlong>(GrDirectContexts::MakeGL(interface).release());
}
#ifdef SK_METAL #ifdef SK_METAL
#include "ganesh/mtl/GrMtlBackendContext.h" #include "ganesh/mtl/GrMtlBackendContext.h"
#include "ganesh/mtl/GrMtlDirectContext.h" #include "ganesh/mtl/GrMtlDirectContext.h"
......
#include <jni.h>
#include "ganesh/gl/GrGLAssembleInterface.h"
#include "ganesh/gl/GrGLInterface.h"
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_GLAssembledInterfaceKt__1nCreateFromNativePointers
(JNIEnv* env, jclass jclass, jlong ctxPtr, jlong fPtr) {
void* ctx = reinterpret_cast<void*>(static_cast<uintptr_t>(ctxPtr));
GrGLGetProc f = reinterpret_cast<GrGLGetProc>(static_cast<uintptr_t>(fPtr));
sk_sp<const GrGLInterface> interface = GrGLMakeAssembledInterface(ctx, f);
return reinterpret_cast<jlong>(interface.release());
}
package org.jetbrains.skia
import org.jetbrains.skia.impl.Native.Companion.NullPointer
import org.jetbrains.skia.impl.NativePointer
import org.jetbrains.skia.impl.Stats
import org.jetbrains.skiko.RenderException
/**
* Creates OpenGL [DirectContext] using the provided interface.
* This allows usage of different OpenGL interfaces (e.g., EGL).
*
* There must be a current OpenGL context set (i.e., by calling `eglMakeCurrent` before this), otherwise
* this function will fail.
* For more information refer to skia `GrGLMakeAssembledInterface` function.
*/
fun DirectContext.Companion.makeGLWithInterface(assembledInterface: GLAssembledInterface): DirectContext {
if (assembledInterface._ptr == NullPointer) throw RenderException("Interface pointer must not be null")
Stats.onNativeCall()
val ptr = _nMakeGLWithInterface(assembledInterface._ptr)
if (ptr == NullPointer) throw RenderException("Can't create OpenGL DirectContext with provided interface")
return DirectContext(ptr)
}
private external fun _nMakeGLWithInterface(interfacePtr: NativePointer): NativePointer
package org.jetbrains.skia
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.Stats
import org.jetbrains.skiko.RenderException
class GLAssembledInterface internal constructor(ptr: NativePointer) : RefCnt(ptr) {
companion object {
/**
* Creates an OpenGL interface object.
*
* There must be a current OpenGL context set (i.e., by calling `eglMakeCurrent` before this), otherwise
* this function will fail.
* For more information refer to skia `GrGLMakeAssembledInterface` function.
*
* For example, this `GetGLFuncPtrByName` function could be passed as a [fPtr]:
* ```
* typedef void(*GLFuncPtr)();
* GLFuncPtr GetGLFuncPtrByName(void* ctx, const char* name);
* ```
*
* @param ctxPtr native pointer to the custom context, that [fPtr] will be called with.
* @param fPtr native pointer to the function that takes [ctxPtr] and the OpenGL function name,
* and returns a function pointer of that OpenGL function (see skia `GrGLGetProc`).
*/
fun createFromNativePointers(ctxPtr: NativePointer, fPtr: NativePointer): GLAssembledInterface {
if (fPtr == NullPointer) throw RenderException("Function pointer must not be null")
Stats.onNativeCall()
val ptr = _nCreateFromNativePointers(ctxPtr, fPtr)
if (ptr == NullPointer) throw RenderException("Can't assemble OpenGL interface")
return GLAssembledInterface(ptr)
}
init {
staticLoad()
}
}
}
private external fun _nCreateFromNativePointers(ctxPtr: NativePointer, fPtr: NativePointer): NativePointer
#include <cassert>
#include <jni.h>
#include <cstdio>
#include <cstring>
static void fakeGlDummy() {
std::printf("!!!dummy called\n");
assert(false);
}
typedef unsigned int GLenum;
typedef int GLint;
static const char *fakeGlGetString(GLenum name) {
constexpr GLenum GL_VERSION = 0x1F02;
constexpr GLenum GL_EXTENSIONS = 0x1F03;
constexpr GLenum GL_SHADING_LANGUAGE_VERSION = 0x8B8C;
switch (name) {
case GL_VERSION: return "OpenGL ES 2.0 Custom";
case GL_SHADING_LANGUAGE_VERSION: return "OpenGL ES GLSL ES 2.00";
case GL_EXTENSIONS: return "GL_EXT_framebuffer_object";
default: return "";
}
}
static GLenum fakeGlGetError() {
return 0;
}
static void fakeGlGetIntegerv(GLenum pname, GLint *data) {
*data = 0;
}
static void fakeGlFinish(){}
typedef void(*GLFuncPtr)();
static GLFuncPtr GetGLFakeFunc(void* ctx, const char* name) {
if (ctx != nullptr) {
return nullptr;
}
if (0 == std::strcmp(name, "glFinish")) { return fakeGlFinish; }
if (0 == std::strcmp(name, "glGetError")) { return reinterpret_cast<GLFuncPtr>(fakeGlGetError); }
if (0 == std::strcmp(name, "glGetIntegerv")) { return reinterpret_cast<GLFuncPtr>(fakeGlGetIntegerv); }
if (0 == std::strcmp(name, "glGetString")) { return reinterpret_cast<GLFuncPtr>(fakeGlGetString); }
if (0 == std::strcmp(name, "eglGetCurrentDisplay")) { return nullptr; }
if (0 == std::strcmp(name, "glGetStringi")) { return nullptr; }
return fakeGlDummy;
}
extern "C" JNIEXPORT jlong JNICALL Java_org_jetbrains_skia_DirectContextTest_1jvmKt__1nGetMakeGLAssembledInterfaceFunc
(JNIEnv* env, jclass jclass) {
return reinterpret_cast<jlong>(GetGLFakeFunc);
}
package org.jetbrains.skia
import org.jetbrains.skia.impl.Native.Companion.NullPointer
import org.jetbrains.skia.impl.NativePointer
import org.jetbrains.skia.impl.interopScope
import kotlin.test.Test
fun getMakeGLAssembledInterfaceFunc(): NativePointer {
return interopScope {
_nGetMakeGLAssembledInterfaceFunc()
}
}
class DirectContextTest {
@Test
fun makeFromInterfaceTest() {
val fPtr = getMakeGLAssembledInterfaceFunc()
val i = GLAssembledInterface.createFromNativePointers(NullPointer, fPtr)
DirectContext.makeGLWithInterface(i)
}
}
private external fun _nGetMakeGLAssembledInterfaceFunc(): NativePointer
...@@ -14,13 +14,13 @@ ...@@ -14,13 +14,13 @@
SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeGL SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeGL
() { () {
return reinterpret_cast<KNativePointer>(GrDirectContexts::MakeGL().release()); return static_cast<KNativePointer>(GrDirectContexts::MakeGL().release());
} }
SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeGLWithInterface SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeGLWithInterface
(KNativePointer ptr) { (KNativePointer ptr) {
sk_sp<GrGLInterface> iface = sk_ref_sp(reinterpret_cast<GrGLInterface*>(ptr)); sk_sp<GrGLInterface> iface = sk_ref_sp(reinterpret_cast<GrGLInterface*>(ptr));
return reinterpret_cast<KNativePointer>(GrDirectContexts::MakeGL(iface).release()); return static_cast<KNativePointer>(GrDirectContexts::MakeGL(iface).release());
} }
SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeMetal SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeMetal
...@@ -32,7 +32,7 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeMetal ...@@ -32,7 +32,7 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeMetal
backendContext.fDevice.retain(device); backendContext.fDevice.retain(device);
backendContext.fQueue.retain(queue); backendContext.fQueue.retain(queue);
sk_sp<GrDirectContext> instance = GrDirectContexts::MakeMetal(backendContext); sk_sp<GrDirectContext> instance = GrDirectContexts::MakeMetal(backendContext);
return reinterpret_cast<KNativePointer>(instance.release()); return static_cast<KNativePointer>(instance.release());
#else #else
return nullptr; return nullptr;
#endif // SK_METAL #endif // SK_METAL
...@@ -49,7 +49,7 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeDirect3D ...@@ -49,7 +49,7 @@ SKIKO_EXPORT KNativePointer org_jetbrains_skia_DirectContext__1nMakeDirect3D
backendContext.fDevice.retain(device); backendContext.fDevice.retain(device);
backendContext.fQueue.retain(queue); backendContext.fQueue.retain(queue);
sk_sp<GrDirectContext> instance = GrDirectContext::MakeDirect3D(backendContext); sk_sp<GrDirectContext> instance = GrDirectContext::MakeDirect3D(backendContext);
return reinterpret_cast<KNativePointer>(instance.release()); return static_cast<KNativePointer>(instance.release());
#else // SK_DIRECT3D #else // SK_DIRECT3D
return nullptr; return nullptr;
#endif // SK_DIRECT3D #endif // SK_DIRECT3D
......
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