parent
90a92246d0
commit
4b71824b53
@ -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…
Reference in new issue