summaryrefslogtreecommitdiff
path: root/src/powdertoyjava/OpenGLCanvasMacOS.mm
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2012-11-17 19:44:09 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2012-11-17 19:44:09 (GMT)
commit058a2edd75debbd0297f92572316daa704bd379f (patch)
treead303f091f9a08b209b91eb34a9fcad996a3de69 /src/powdertoyjava/OpenGLCanvasMacOS.mm
parente3594aba9e05c6865d396418c028049cda92c2f3 (diff)
parent7a21ae192fe19868539956f3fe28e62b2c7c4429 (diff)
downloadpowder-058a2edd75debbd0297f92572316daa704bd379f.zip
powder-058a2edd75debbd0297f92572316daa704bd379f.tar.gz
Merge branch 'master' of github.com:FacialTurd/PowderToypp
Diffstat (limited to 'src/powdertoyjava/OpenGLCanvasMacOS.mm')
-rw-r--r--src/powdertoyjava/OpenGLCanvasMacOS.mm169
1 files changed, 169 insertions, 0 deletions
diff --git a/src/powdertoyjava/OpenGLCanvasMacOS.mm b/src/powdertoyjava/OpenGLCanvasMacOS.mm
new file mode 100644
index 0000000..c169c5f
--- /dev/null
+++ b/src/powdertoyjava/OpenGLCanvasMacOS.mm
@@ -0,0 +1,169 @@
+#ifdef USE_JNI
+#include "OpenGLCanvasMacOS.h"
+
+static jfieldID ctxID = NULL;
+
+NSOpenGLPixelFormat* defaultPixelFormat()
+{
+ NSOpenGLPixelFormatAttribute attributes [] = {
+ NSOpenGLPFAWindow,
+ NSOpenGLPFADoubleBuffer,
+ NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)16,
+ 0
+ };
+ return [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
+}
+
+NSOpenGLContext* ensureContext(NSOpenGLContext* openGLContext, NSView *view) {
+ NSOpenGLContext* _openGLContext = openGLContext;
+ if (!_openGLContext) {
+ NSOpenGLPixelFormat* pixelFormat = defaultPixelFormat();
+ _openGLContext = [[NSOpenGLContext alloc]
+ initWithFormat:pixelFormat
+ shareContext:nil];
+ [pixelFormat release];
+ }
+ if ([_openGLContext view] != view) {
+ [_openGLContext setView:view];
+ }
+ [_openGLContext makeCurrentContext];
+
+ return _openGLContext;
+}
+
+ContextInfo* getContext(JNIEnv *env, jobject canvas)
+{
+ if (!ctxID) {
+ jclass cls = env->GetObjectClass(canvas);
+ ctxID = env->GetFieldID(cls, "openGLContext", "J");
+ }
+
+ ContextInfo *ci = (ContextInfo *)(long)(env->GetLongField(canvas, ctxID));
+
+ if (!ci) {
+ ci = (ContextInfo *)calloc(sizeof(ContextInfo), 1);
+ ci->awt = (JAWT *)calloc(sizeof(JAWT), 1);
+ env->SetLongField(canvas, ctxID, (jlong)(long)ci);
+ }
+
+ return ci;
+}
+
+void freeContext(JNIEnv *env, jobject canvas, ContextInfo* ci)
+{
+ if (ci) {
+ free(ci->awt);
+ free(ci);
+ env->SetLongField(canvas, ctxID, 0L);
+ }
+}
+
+JNIEXPORT jboolean JNICALL Java_OpenGLCanvas_beginOpenGL(JNIEnv *env, jobject canvas)
+{
+ ContextInfo *ci = getContext(env, canvas);
+
+ // Lock the drawing surface
+ // You must lock EACH TIME before drawing
+ jint lock = ci->ds->Lock(ci->ds);
+ if (env->ExceptionOccurred()) {
+ env->ExceptionDescribe();
+ }
+ assert((lock & JAWT_LOCK_ERROR) == 0);
+
+ // Get the drawing surface info
+ ci->dsi = ci->ds->GetDrawingSurfaceInfo(ci->ds);
+
+ // Check DrawingSurfaceInfo. This can be NULL on Mac OS X
+ // if the windowing system is not ready
+ if (ci->dsi != NULL) {
+ // Get the platform-specific drawing info
+ // We will use this to get at Cocoa and CoreGraphics
+ // See <JavaVM/jawt_md.h>
+ ci->dsi_mac = (JAWT_MacOSXDrawingSurfaceInfo*)ci->dsi->platformInfo;
+ if (env->ExceptionOccurred()) {
+ env->ExceptionDescribe();
+ }
+
+ // Get the corresponding peer from the caller canvas
+ ci->view = ci->dsi_mac->cocoaViewRef;
+ ci->openGLContext = ensureContext(ci->openGLContext, ci->view);
+
+ return JNI_TRUE;
+ }
+
+ return JNI_FALSE;
+}
+
+JNIEXPORT void JNICALL Java_OpenGLCanvas_endOpenGL(JNIEnv *env, jobject canvas)
+{
+ ContextInfo *ci = getContext(env, canvas);
+
+ [ci->openGLContext flushBuffer];
+
+ // Free the DrawingSurfaceInfo
+ ci->ds->FreeDrawingSurfaceInfo(ci->dsi);
+ if (env->ExceptionOccurred()){
+ env->ExceptionDescribe();
+ }
+
+ // Unlock the drawing surface
+ // You must unlock EACH TIME when done drawing
+ ci->ds->Unlock(ci->ds);
+ if (env->ExceptionOccurred()) {
+ env->ExceptionDescribe();
+ }
+}
+
+JNIEXPORT void JNICALL Java_OpenGLCanvas_updateOpenGL(JNIEnv *env, jobject canvas)
+{
+ ContextInfo *ci = getContext(env, canvas);
+
+ [ci->openGLContext update];
+}
+
+JNIEXPORT void JNICALL Java_OpenGLCanvas_allocOpenGL(JNIEnv *env, jobject canvas)
+{
+ ContextInfo *ci = getContext(env, canvas);
+
+ jboolean result = JNI_FALSE;
+
+ // get the AWT
+ ci->awt->version = JAWT_VERSION_1_4;
+ result = JAWT_GetAWT(env, ci->awt);
+ if (env->ExceptionOccurred()) {
+ env->ExceptionDescribe();
+ }
+ assert(result != JNI_FALSE);
+
+ // Get the drawing surface. This can be safely cached.
+ // Anything below the DS (DSI, contexts, etc)
+ // can possibly change/go away and should not be cached.
+ ci->ds = ci->awt->GetDrawingSurface(env, canvas);
+ if (env->ExceptionOccurred()) {
+ env->ExceptionDescribe();
+ }
+ assert(ci->ds != NULL);
+
+ NSLog(@"Alloc Context %d", ci);
+}
+
+JNIEXPORT void JNICALL Java_OpenGLCanvas_releaseOpenGL(JNIEnv *env, jobject canvas)
+{
+ ContextInfo *ci = getContext(env, canvas);
+ NSLog(@"Release Context %d", ci);
+ if (ci->openGLContext) {
+ if ([ci->openGLContext view] /* == self */) {
+ [ci->openGLContext clearDrawable];
+ }
+ [ci->openGLContext release];
+ }
+
+ // Free the drawing surface (if not caching it)
+ ci->awt->FreeDrawingSurface(ci->ds);
+ if (env->ExceptionOccurred()) {
+ env->ExceptionDescribe();
+ }
+
+ freeContext(env, canvas, ci);
+}
+#endif \ No newline at end of file