Add initial GLX context management

master
Graham 5 years ago
parent 90a92246d0
commit 4b71824b53
  1. 27
      gl-natives/pom.xml
  2. 258
      gl-natives/src/main/c/jaggl.c

@ -12,4 +12,31 @@
<packaging>nar</packaging> <packaging>nar</packaging>
<name>OpenRS2 GL Natives</name> <name>OpenRS2 GL Natives</name>
<build>
<plugins>
<plugin>
<groupId>com.github.maven-nar</groupId>
<artifactId>nar-maven-plugin</artifactId>
<configuration>
<linker>
<sysLibs>
<sysLib>
<type>shared</type>
<name>GL</name>
</sysLib>
<sysLib>
<type>shared</type>
<name>GLX</name>
</sysLib>
<sysLib>
<type>shared</type>
<name>jawt</name>
</sysLib>
</sysLibs>
</linker>
</configuration>
</plugin>
</plugins>
</build>
</project> </project>

@ -0,0 +1,258 @@
#include "jaggl_context.h"
#include "jaggl_opengl.h"
#include <GL/glx.h>
#include <jawt.h>
#include <jawt_md.h>
#include <stdbool.h>
#include <stddef.h>
#define JAGGL_LOCK(env) \
JAWT awt = { .version = JAWT_VERSION_1_4 }; \
bool awt_valid = JAWT_GetAWT(env, &awt); \
if (awt_valid) { \
awt.Lock(env); \
}
#define JAGGL_UNLOCK(env) \
if (awt_valid) { \
awt.Unlock(env); \
}
static Display *jaggl_display;
static XVisualInfo *jaggl_visual_info;
static VisualID jaggl_visual_id;
static GLXContext jaggl_context;
static GLXDrawable jaggl_drawable;
static int jaggl_alpha_bits;
static bool jaggl_double_buffered;
static PFNGLXSWAPINTERVALSGIPROC jaggl_glXSwapIntervalSGI;
static void jaggl_init_proc_table(void) {
jaggl_glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) glXGetProcAddressARB((const GLubyte *) "glXSwapIntervalSGI");
}
JNIEXPORT jboolean JNICALL Java_jaggl_context_createContext(JNIEnv *env, jclass cls) {
JAGGL_LOCK(env);
GLXContext current = glXGetCurrentContext();
if (current) {
glXMakeCurrent(jaggl_display, None, NULL);
}
if (jaggl_context) {
glXDestroyContext(jaggl_display, jaggl_context);
jaggl_context = NULL;
}
jaggl_context = glXCreateContext(jaggl_display, jaggl_visual_info, NULL, True);
JAGGL_UNLOCK(env);
return jaggl_context != NULL;
}
JNIEXPORT jboolean JNICALL Java_jaggl_context_releaseContext(JNIEnv *env, jclass cls) {
JAGGL_LOCK(env);
jboolean result = JNI_TRUE;
GLXContext current = glXGetCurrentContext();
if (current) {
result = (jboolean) glXMakeCurrent(jaggl_display, None, NULL);
}
JAGGL_UNLOCK(env);
return result;
}
JNIEXPORT jboolean JNICALL Java_jaggl_context_destroy(JNIEnv *env, jclass cls) {
JAGGL_LOCK(env);
GLXContext current = glXGetCurrentContext();
if (current) {
glXMakeCurrent(jaggl_display, None, NULL);
}
if (jaggl_context) {
glXDestroyContext(jaggl_display, jaggl_context);
jaggl_context = NULL;
}
if (jaggl_visual_info) {
XFree(jaggl_visual_info);
jaggl_visual_info = NULL;
}
jaggl_display = None;
JAGGL_UNLOCK(env);
return JNI_TRUE;
}
JNIEXPORT jboolean JNICALL Java_jaggl_context_swapBuffers(JNIEnv *env, jclass cls) {
JAGGL_LOCK(env);
if (jaggl_double_buffered) {
glXSwapBuffers(jaggl_display, jaggl_drawable);
} else {
glFlush();
}
JAGGL_UNLOCK(env);
return JNI_TRUE;
}
JNIEXPORT jint JNICALL Java_jaggl_context_getLastError(JNIEnv *env, jclass cls) {
return 0;
}
JNIEXPORT void JNICALL Java_jaggl_context_setSwapInterval(JNIEnv *env, jclass cls, jint interval) {
JAGGL_LOCK(env);
if (jaggl_glXSwapIntervalSGI) {
jaggl_glXSwapIntervalSGI(interval);
}
JAGGL_UNLOCK(env);
}
JNIEXPORT jstring JNICALL Java_jaggl_context_getExtensionsString(JNIEnv *env, jclass cls) {
JAGGL_LOCK(env);
const char *extensions_str = glXQueryExtensionsString(jaggl_display, jaggl_visual_info->screen);
jstring extensions = (*env)->NewStringUTF(env, extensions_str);
JAGGL_UNLOCK(env);
return extensions;
}
JNIEXPORT jint JNICALL Java_jaggl_context_getAlphaBits(JNIEnv *env, jclass cls) {
return jaggl_alpha_bits;
}
JNIEXPORT jboolean JNICALL Java_jaggl_context_choosePixelFormat1(JNIEnv *env, jclass cls, jobject component, jint num_samples, jint alpha_bits) {
JAGGL_LOCK(env);
jboolean result = JNI_FALSE;
if (!awt_valid) {
goto awt_unlock;
}
JAWT_DrawingSurface *ds = awt.GetDrawingSurface(env, component);
if (!ds) {
goto awt_unlock;
}
jint lock_result = ds->Lock(ds);
if ((lock_result & JAWT_LOCK_ERROR) != 0) {
goto ds_free;
}
JAWT_DrawingSurfaceInfo *dsi = ds->GetDrawingSurfaceInfo(ds);
if (!dsi) {
goto ds_unlock;
}
JAWT_X11DrawingSurfaceInfo *platformInfo = (JAWT_X11DrawingSurfaceInfo *) dsi->platformInfo;
if (!platformInfo) {
goto dsi_free;
}
jaggl_display = platformInfo->display;
jaggl_drawable = platformInfo->drawable;
jaggl_visual_id = platformInfo->visualID;
if (!glXQueryExtension(jaggl_display, NULL, NULL)) {
goto dsi_free;
}
XWindowAttributes window_attribs;
if (XGetWindowAttributes(jaggl_display, jaggl_drawable, &window_attribs)) {
XVisualInfo visual_info_template = { .visualid = window_attribs.visual->visualid };
int matches;
jaggl_visual_info = XGetVisualInfo(jaggl_display, VisualIDMask, &visual_info_template, &matches);
if (jaggl_visual_info) {
int value;
glXGetConfig(jaggl_display, jaggl_visual_info, GLX_DOUBLEBUFFER, &value);
jaggl_double_buffered = value;
glXGetConfig(jaggl_display, jaggl_visual_info, GLX_ALPHA_SIZE, &value);
jaggl_alpha_bits = value;
result = JNI_TRUE;
goto dsi_free;
}
}
for (int i = 0; i < 2; i++) {
bool double_buffered = i == 0;
int attribs[] = {
GLX_RGBA,
GLX_RED_SIZE,
8,
GLX_GREEN_SIZE,
8,
GLX_BLUE_SIZE,
8,
GLX_ALPHA_SIZE,
alpha_bits,
GLX_DEPTH_SIZE,
24,
GLX_SAMPLE_BUFFERS,
num_samples ? True : False,
GLX_SAMPLES,
num_samples,
double_buffered ? GLX_DOUBLEBUFFER : None,
None
};
jaggl_visual_info = glXChooseVisual(jaggl_display, DefaultScreen(jaggl_display), attribs);
if (jaggl_visual_info) {
jaggl_double_buffered = double_buffered;
jaggl_alpha_bits = alpha_bits;
result = JNI_TRUE;
goto dsi_free;
}
}
dsi_free:
ds->FreeDrawingSurfaceInfo(dsi);
ds_unlock:
ds->Unlock(ds);
ds_free:
awt.FreeDrawingSurface(ds);
awt_unlock:
JAGGL_UNLOCK(env);
return result;
}
JNIEXPORT jboolean JNICALL Java_jaggl_context_makeCurrent1(JNIEnv *env, jclass cls) {
JAGGL_LOCK(env);
jboolean result = JNI_FALSE;
if (!jaggl_context) {
goto done;
}
GLXContext current = glXGetCurrentContext();
if (jaggl_context == current) {
result = JNI_TRUE;
goto done;
}
glXMakeCurrent(jaggl_display, None, NULL);
if (!glXMakeCurrent(jaggl_display, jaggl_drawable, jaggl_context)) {
goto done;
}
jaggl_init_proc_table();
result = JNI_TRUE;
done:
JAGGL_UNLOCK(env);
return result;
}
Loading…
Cancel
Save