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