This repository has been archived on 2025-03-20. You can view files and clone it, but cannot push or open issues or pull requests.
The-Powder-Toy/src/powdertoyjava/OpenGLCanvasMacOS.mm
2012-06-04 12:21:07 +01:00

169 lines
4.5 KiB
Plaintext

#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