1/* 2 * Copyright (c) 2002-2008 LWJGL Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'LWJGL' nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33/** 34 * $Id$ 35 * 36 * @author elias_naur <elias_naur@users.sourceforge.net> 37 * @author kappaOne <one.kappa@gmail.com> 38 * @version $Revision$ 39 */ 40 41#import <jni.h> 42#import <OpenGL/CGLCurrent.h> 43#import <OpenGL/CGLTypes.h> 44#import <OpenGL/CGLDevice.h> 45#import <Cocoa/Cocoa.h> 46#import "org_lwjgl_opengl_MacOSXContextImplementation.h" 47#import "context.h" 48#import "common_tools.h" 49 50typedef struct { 51 NSOpenGLContext *context; 52 MacOSXPeerInfo *peer_info; 53} MacOSXContext; 54 55JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nCreate 56 (JNIEnv *env, jclass clazz, jobject peer_info_handle, jobject shared_context_handle) { 57 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 58 MacOSXPeerInfo *peer_info; 59 MacOSXContext *shared_context_info; 60 MacOSXContext *context_info; 61 NSOpenGLContext *context; 62 NSOpenGLContext *shared_context = NULL; 63 64 jobject context_handle = newJavaManagedByteBuffer(env, sizeof(MacOSXContext)); 65 if (context_handle == NULL) { 66 throwException(env, "Could not create handle buffer"); 67 return NULL; 68 } 69 peer_info = (MacOSXPeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); 70 if (shared_context_handle != NULL) { 71 shared_context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, shared_context_handle); 72 shared_context = shared_context_info->context; 73 } 74 context = [[NSOpenGLContext alloc] initWithFormat:peer_info->pixel_format shareContext:shared_context]; 75 if (context == NULL) { 76 throwException(env, "Could not create context"); 77 return NULL; 78 } 79 80 if (peer_info->isWindowed) { 81 if (peer_info->window_info->fullscreen) { 82 // set a fixed backbuffer size for fullscreen 83 CGLContextObj cgcontext = (CGLContextObj)[context CGLContextObj]; 84 NSSize displaySize = peer_info->window_info->display_rect.size; 85 GLint dim[2] = {displaySize.width, displaySize.height}; 86 CGLSetParameter(cgcontext, kCGLCPSurfaceBackingSize, dim); 87 CGLEnable(cgcontext, kCGLCESurfaceBackingSize); 88 } 89 else { 90 // disable any fixed backbuffer size to allow resizing 91 CGLContextObj cgcontext = (CGLContextObj)[context CGLContextObj]; 92 CGLDisable(cgcontext, kCGLCESurfaceBackingSize); 93 } 94 95 [peer_info->window_info->view setOpenGLContext:context]; 96 peer_info->window_info->context = context; 97 } 98 99 context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle); 100 context_info->context = context; 101 context_info->peer_info = peer_info; 102 103 [pool release]; 104 return context_handle; 105} 106 107JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_getCGLShareGroup 108 (JNIEnv *env, jclass clazz, jobject context_handle) { 109 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 110 MacOSXContext *context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle); 111 CGLContextObj cgl_context = [context_info->context CGLContextObj]; 112 CGLShareGroupObj share_group = CGLGetShareGroup(cgl_context); 113 [pool release]; 114 return (jlong)share_group; 115} 116 117JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nSwapBuffers 118 (JNIEnv *env, jclass clazz, jobject context_handle) { 119 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 120 MacOSXContext *context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle); 121 [context_info->context flushBuffer]; 122 123 if (context_info->peer_info->isCALayer) { 124 // blit the contents of buffer to CALayer 125 [context_info->peer_info->glLayer blitFrameBuffer]; 126 } 127 128 [pool release]; 129} 130 131JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nUpdate 132 (JNIEnv *env, jclass clazz, jobject context_handle) { 133 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 134 MacOSXContext *context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle); 135 [context_info->context update]; 136 [pool release]; 137} 138 139JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_clearDrawable 140(JNIEnv *env, jclass clazz, jobject context_handle) { 141 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 142 MacOSXContext *context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle); 143 [context_info->context clearDrawable]; 144 [pool release]; 145} 146 147JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nReleaseCurrentContext 148 (JNIEnv *env, jclass clazz) { 149 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 150 [NSOpenGLContext clearCurrentContext]; 151 [pool release]; 152} 153 154JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_setView 155 (JNIEnv *env, jclass clazz, jobject peer_info_handle, jobject context_handle) { 156 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 157 MacOSXContext *context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle); 158 MacOSXPeerInfo *peer_info = (MacOSXPeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle); 159 160 if (peer_info->isWindowed) { 161 if (peer_info->isCALayer && [context_info->context view] != peer_info->window_info->view) { 162 // mark glViewport to be set manually when setting a new context view 163 peer_info->glLayer->setViewport = YES; 164 } 165 166 [context_info->context setView: peer_info->window_info->view]; 167 } 168 else { 169 [context_info->context setPixelBuffer:peer_info->pbuffer cubeMapFace:0 mipMapLevel:0 currentVirtualScreen:0]; 170 } 171 172 if (peer_info->isCALayer) { 173 // if using a CALayer, attach it to AWT Canvas and create a shared opengl context with current context 174 [peer_info->glLayer performSelectorOnMainThread:@selector(attachLayer) withObject:nil waitUntilDone:NO]; 175 } 176 177 [pool release]; 178} 179 180JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nMakeCurrent 181 (JNIEnv *env, jclass clazz, jobject context_handle) { 182 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 183 MacOSXContext *context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle); 184 [context_info->context makeCurrentContext]; 185 186 if (context_info->peer_info->isCALayer && context_info->peer_info->glLayer->setViewport) { 187 context_info->peer_info->glLayer->setViewport = NO; 188 glViewport(0, 0, [context_info->peer_info->glLayer getWidth], [context_info->peer_info->glLayer getHeight]); 189 } 190 191 [pool release]; 192} 193 194JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nIsCurrent 195 (JNIEnv *env, jclass clazz, jobject context_handle) { 196 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 197 MacOSXContext *context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle); 198 bool result = context_info->context == [NSOpenGLContext currentContext]; 199 [pool release]; 200 return result ? JNI_TRUE : JNI_FALSE; 201} 202 203JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nSetSwapInterval 204 (JNIEnv *env, jclass clazz, jobject context_handle, jint int_value) { 205 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 206 MacOSXContext *context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle); 207 GLint value = int_value; 208 [context_info->context setValues:&value forParameter:NSOpenGLCPSwapInterval]; 209 [pool release]; 210} 211 212JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nDestroy 213 (JNIEnv *env, jclass clazz, jobject context_handle) { 214 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 215 216 MacOSXContext *context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle); 217 218 if (context_info->peer_info->isCALayer) { 219 context_info->peer_info->isCALayer = false; 220 [context_info->peer_info->glLayer performSelectorOnMainThread:@selector(removeLayer) withObject:nil waitUntilDone:YES]; 221 [context_info->peer_info->glLayer release]; 222 context_info->peer_info->glLayer = nil; 223 // don't release context due to nvidia driver bug when releasing shared contexts 224 [context_info->context retain]; 225 } 226 227 [context_info->context clearDrawable]; 228 229 if (context_info->peer_info->isWindowed) { 230 [context_info->peer_info->window_info->view setOpenGLContext:nil]; 231 [context_info->context release]; 232 context_info->context = nil; 233 context_info->peer_info->window_info->context = nil; 234 } 235 else { 236 // don't release context due to nvidia driver bug when releasing shared contexts 237 //[context_info->context release]; 238 //context_info->context = nil; 239 } 240 241 [pool release]; 242} 243