diff options
author | Sven Gothel <[email protected]> | 2009-03-16 14:38:27 +0000 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2009-03-16 14:38:27 +0000 |
commit | 24fcece997ba911b0270033a357bbd83258d4f1a (patch) | |
tree | 4d01034154734897724d6a3b7738bf22693a8d36 /src/jogl/native/macosx | |
parent | 9517d52c18bfa93d78e03f4c212757eda421afb6 (diff) |
JOGL refactoring:
Refactored JOGL into 3 independent components.
1 NWI - Native windowing interface
Abstracts the the general NativeWindow interface and it's factory,
incl the basic JAWT and Xlib toolkit.
The latter was motivated to clean up the JOGL workspace,
and to allow other to reuse this part.
The generic core is nwi.core.jar, the AWT add-on is nwi.awt.jar.
2 JOGL - The OpenGL mapping
Further cleanup of the SPEC.
All non OpenGL toolkits are relocated to NWI and NEWT.
There is still openmax and the windows audio layer ..
Another cleanup of the fixed function pipeline emulation.
Moved utilities and implementations where they belong ..
Removed GLUnsupportedException.
Misc .. changes
3 NEWT - The new windowing toolkit
The generic NEWT, newt.core.jar.
The JOGL and AWT modules are seperate, newt.ogl.jar newt.awt.jar.
Their build can be switched off.
The modules source and builds resides in their own directory.
Because of their nature, they share the stub_includes, etc.
Each module has it's own ant build script
- build-nwi.xml
- build-jogl.xml
- build-newt.xml
They can be build at once using build.xml as ususal,
which just invokes the seperate build tasks.
if rootrel.build=build, then the build location is
jogl/build-nwi
jogl/build-jogl
jogl/build-newt
and the sources are under
jogl/src/nwi
jogl/src/jogl
jogl/src/newt
Tested: jogl-demos, d4; Linux, MacOsX; Nvidia
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JOGL_2_SANDBOX@1868 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/jogl/native/macosx')
-rw-r--r-- | src/jogl/native/macosx/ContextUpdater.h | 40 | ||||
-rw-r--r-- | src/jogl/native/macosx/ContextUpdater.m | 83 | ||||
-rw-r--r-- | src/jogl/native/macosx/MacOSXWindowSystemInterface.m | 702 |
3 files changed, 825 insertions, 0 deletions
diff --git a/src/jogl/native/macosx/ContextUpdater.h b/src/jogl/native/macosx/ContextUpdater.h new file mode 100644 index 000000000..e8b757fac --- /dev/null +++ b/src/jogl/native/macosx/ContextUpdater.h @@ -0,0 +1,40 @@ +/* + +Listens to NSViewGlobalFrameDidChangeNotification + +This notification is sent whenever an NSView that has an attached NSSurface changes size or changes screens (thus potentially changing graphics hardware drivers.) + +*/ + +#import <Cocoa/Cocoa.h> +#import <Foundation/Foundation.h> +#import <AppKit/NSView.h> +#import <OpenGL/OpenGL.h> +#import <OpenGL/gl.h> + +//#define DEBUG_GL_LOCKS + +#ifdef DEBUG_GL_LOCKS + #define LOCK_GL(func, line) [ContextUpdater lockInFunction:func atLine:line]; + #define UNLOCK_GL(func, line) [ContextUpdater unlockInFunction:func atLine:line]; +#else + #define LOCK_GL(func, line) [ContextUpdater lock]; + #define UNLOCK_GL(func, line) [ContextUpdater unlock]; +#endif + +// gznote: OpenGL NOT thread safe - need to sync on update and paints + +@interface ContextUpdater : NSObject +{ +} + ++ (void) lock; ++ (void) lockInFunction:(char *)func atLine:(int)line; ++ (void) unlock; ++ (void) unlockInFunction:(char *)func atLine:(int)line; + +- (void) registerFor:(NSOpenGLContext *)context with: (NSView *)window; + +- (void) update:(NSNotification *)notification; + +@end diff --git a/src/jogl/native/macosx/ContextUpdater.m b/src/jogl/native/macosx/ContextUpdater.m new file mode 100644 index 000000000..587782c98 --- /dev/null +++ b/src/jogl/native/macosx/ContextUpdater.m @@ -0,0 +1,83 @@ +#import "ContextUpdater.h" +#import <pthread.h> + +@implementation ContextUpdater +{ +} + +static NSOpenGLContext *theContext; +static pthread_mutex_t resourceLock = PTHREAD_MUTEX_INITIALIZER; + +static void printLockDebugInfo(char *message, char *func, int line) +{ + fprintf(stderr, "%s in function: \"%s\" at line: %d\n", message, func, line); + fflush(stderr); +} + ++ (void) lock +{ + if (theContext != NULL) + { + pthread_mutex_lock(&resourceLock); + } +} + ++ (void) lockInFunction:(char *)func atLine:(int)line +{ + if (theContext != NULL) + { + printLockDebugInfo("locked ", func, line); + [self lock]; + } +} + ++ (void) unlock +{ + if (theContext != NULL) + { + pthread_mutex_unlock(&resourceLock); + } +} + ++ (void) unlockInFunction:(char *)func atLine:(int)line +{ + if (theContext != NULL) + { + printLockDebugInfo("unlocked", func, line); + [self unlock]; + } +} + +- (void) registerFor:(NSOpenGLContext *)context with: (NSView *)view +{ + if (view != NULL) + { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(update:) name:NSViewGlobalFrameDidChangeNotification object: view]; + theContext = context; + } +} + +- (void) update:(NSNotification *)notification +{ + [ContextUpdater lock]; + + [theContext update]; + + [ContextUpdater unlock]; +} + +- (id) init +{ + theContext = NULL; + + return [super init]; +} + +- (void) dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [super dealloc]; +} + +@end
\ No newline at end of file diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m new file mode 100644 index 000000000..350f6152f --- /dev/null +++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m @@ -0,0 +1,702 @@ +/* Note: usage of AvailabilityMacros.h to detect whether we're + building on OS X 10.3 does not work because the header #defines + MAC_OS_X_VERSION_10_4 even though the machine is a 10.3 machine + +#include <AvailabilityMacros.h> + +#ifndef MAC_OS_X_VERSION_10_3 + #error building JOGL requires Mac OS X 10.3 or greater +#endif + +#ifndef MAC_OS_X_VERSION_10_4 + #define NSOpenGLPFAColorFloat kCGLPFAColorFloat + #define kCGLNoError 0 +#endif +*/ + +#import <Cocoa/Cocoa.h> +#import <OpenGL/gl.h> +#import <OpenGL/CGLTypes.h> +#import <jni.h> +#import "ContextUpdater.h" + +#import "macosx-window-system.h" + +// see MacOSXPbufferGLContext.java createPbuffer +#define USE_GL_TEXTURE_RECTANGLE_EXT + +#ifdef USE_GL_TEXTURE_RECTANGLE_EXT + #ifndef GL_TEXTURE_RECTANGLE_EXT + #define GL_TEXTURE_RECTANGLE_EXT 0x84F5 + #endif +#endif + +// Workarounds for compiling on 10.3 +#ifndef kCGLRGBA16161616Bit +#define kCGLRGBA16161616Bit 0x00800000 /* 64 argb bit/pixel, R=63:48, G=47:32, B=31:16, A=15:0 */ +#define kCGLRGBFloat64Bit 0x01000000 /* 64 rgb bit/pixel, half float */ +#define kCGLRGBAFloat64Bit 0x02000000 /* 64 argb bit/pixel, half float */ +#define kCGLRGBFloat128Bit 0x04000000 /* 128 rgb bit/pixel, ieee float */ +#define kCGLRGBAFloat128Bit 0x08000000 /* 128 argb bit/pixel, ieee float */ +#define kCGLRGBFloat256Bit 0x10000000 /* 256 rgb bit/pixel, ieee double */ +#define kCGLRGBAFloat256Bit 0x20000000 /* 256 argb bit/pixel, ieee double */ +#endif + +struct _RendererInfo +{ + long id; // kCGLRPRendererID + long displayMask; // kCGLRPDisplayMask + + long accelerated; // kCGLRPAccelerated + + long window; // kCGLRPWindow + long fullscreen; // kCGLRPFullScreen + long multiscreen; // kCGLRPMultiScreen + long offscreen; // kCGLRPOffScreen + long floatPixels; // see kCGLRPColorModes + long stereo; // kCGLRPBufferModes + + long auxBuffers; // kCGLRPMaxAuxBuffers + long sampleBuffers; // kCGLRPMaxSampleBuffers + long samples; // kCGLRPMaxSamples + long samplesModes; // kCGLRPSampleModes + long multiSample; // see kCGLRPSampleModes + long superSample; // see kCGLRPSampleModes + long alphaSample; // kCGLRPSampleAlpha + + long colorModes; // kCGLRPColorModes + long colorRGBSizeMAX; + long colorASizeMAX; + long colorFloatRGBSizeMAX; + long colorFloatASizeMAX; + long colorFloatRGBSizeMIN; + long colorFloatASizeMIN; + long colorModesCount; + long colorFloatModesCount; + long depthModes; // kCGLRPDepthModes + long depthSizeMAX; + long depthModesCount; + long stencilModes; // kCGLRPStencilModes + long stencilSizeMAX; + long stencilModesCount; + long accumModes; // kCGLRPAccumModes + long accumRGBSizeMAX; + long accumASizeMAX; + long accumModesCount; +} +typedef RendererInfo; + +RendererInfo *gRenderers = NULL; +long gRenderersCount = 0; + +long depthModes[] = { + kCGL0Bit, + kCGL1Bit, + kCGL2Bit, + kCGL3Bit, + kCGL4Bit, + kCGL5Bit, + kCGL6Bit, + kCGL8Bit, + kCGL10Bit, + kCGL12Bit, + kCGL16Bit, + kCGL24Bit, + kCGL32Bit, + kCGL48Bit, + kCGL64Bit, + kCGL96Bit, + kCGL128Bit, + 0 + }; +long depthModesBits[] = {0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 24, 32, 48, 64, 96, 128}; +long colorModes[] = { + kCGLRGB444Bit, + kCGLARGB4444Bit, + kCGLRGB444A8Bit, + kCGLRGB555Bit, + kCGLARGB1555Bit, + kCGLRGB555A8Bit, + kCGLRGB565Bit, + kCGLRGB565A8Bit, + kCGLRGB888Bit, + kCGLARGB8888Bit, + kCGLRGB888A8Bit, + kCGLRGB101010Bit, + kCGLARGB2101010Bit, + kCGLRGB101010_A8Bit, + kCGLRGB121212Bit, + kCGLARGB12121212Bit, + kCGLRGB161616Bit, + kCGLRGBA16161616Bit, + kCGLRGBFloat64Bit, + kCGLRGBAFloat64Bit, + kCGLRGBFloat128Bit, + kCGLRGBAFloat128Bit, + kCGLRGBFloat256Bit, + kCGLRGBAFloat256Bit, + 0 + }; +long colorModesBitsRGB[] = {4, 4, 4, 5, 5, 5, 5, 5, 8, 8, 8, 10, 10, 10, 12, 12, 16, 16, 16, 16, 32, 32, 64, 64}; +long colorModesBitsA[] = {0, 4, 8, 0, 1, 8, 0, 8, 0, 8, 8, 0, 2, 8, 0, 12, 0, 16, 0, 16, 0, 32, 0, 64}; + +void getRendererInfo() +{ + if (gRenderersCount == 0) + { + CGLRendererInfoObj info; + CGLError err = CGLQueryRendererInfo(CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &gRenderersCount); + if (err == 0 /* kCGLNoError */) + { + // how many renderers are available? + CGLDescribeRenderer(info, 0, kCGLRPRendererCount, &gRenderersCount); + + // allocate our global renderers info + gRenderers = (RendererInfo*)malloc(gRenderersCount*sizeof(RendererInfo)); + memset(gRenderers, 0x00, gRenderersCount*sizeof(RendererInfo)); + + // iterate through the renderers checking for their features + long j; + for (j=0; j<gRenderersCount; j++) + { + RendererInfo *renderer = &gRenderers[j]; + int i; + + CGLDescribeRenderer(info, j, kCGLRPRendererID, &(renderer->id)); + CGLDescribeRenderer(info, j, kCGLRPDisplayMask, &(renderer->displayMask)); + + CGLDescribeRenderer(info, j, kCGLRPAccelerated, &(renderer->accelerated)); + + CGLDescribeRenderer(info, j, kCGLRPWindow, &(renderer->window)); + CGLDescribeRenderer(info, j, kCGLRPFullScreen, &(renderer->fullscreen)); + CGLDescribeRenderer(info, j, kCGLRPMultiScreen, &(renderer->multiscreen)); + CGLDescribeRenderer(info, j, kCGLRPOffScreen, &(renderer->offscreen)); + CGLDescribeRenderer(info, j, kCGLRPColorModes, &(renderer->floatPixels)); + if ((renderer->floatPixels >= kCGLRGBFloat64Bit) != 0) + { + renderer->floatPixels = 1; + } + else + { + renderer->floatPixels = 0; + } + CGLDescribeRenderer(info, j, kCGLRPBufferModes, &(renderer->stereo)); + if ((renderer->stereo & kCGLStereoscopicBit) != 0) + { + renderer->stereo = 1; + } + else + { + renderer->stereo = 0; + } + + CGLDescribeRenderer(info, j, kCGLRPMaxAuxBuffers, &(renderer->auxBuffers)); + CGLDescribeRenderer(info, j, kCGLRPMaxSampleBuffers, &(renderer->sampleBuffers)); + CGLDescribeRenderer(info, j, kCGLRPMaxSamples, &(renderer->samples)); + // The following queries are only legal on 10.4 + // FIXME: should figure out a way to enable them dynamically +#ifdef kCGLRPSampleModes + CGLDescribeRenderer(info, j, kCGLRPSampleModes, &(renderer->samplesModes)); + if ((renderer->samplesModes & kCGLSupersampleBit) != 0) + { + renderer->multiSample = 1; + } + if ((renderer->samplesModes & kCGLMultisampleBit) != 0) + { + renderer->superSample = 1; + } + CGLDescribeRenderer(info, j, kCGLRPSampleAlpha, &(renderer->alphaSample)); +#endif + CGLDescribeRenderer(info, j, kCGLRPColorModes, &(renderer->colorModes)); + i=0; + int floatPixelFormatInitialized = 0; + while (colorModes[i] != 0) + { + if ((renderer->colorModes & colorModes[i]) != 0) + { + // non-float color model + if (colorModes[i] < kCGLRGBFloat64Bit) + { + // look for max color and alpha values - prefer color models that have alpha + if ((colorModesBitsRGB[i] >= renderer->colorRGBSizeMAX) && (colorModesBitsA[i] >= renderer->colorASizeMAX)) + { + renderer->colorRGBSizeMAX = colorModesBitsRGB[i]; + renderer->colorASizeMAX = colorModesBitsA[i]; + } + renderer->colorModesCount++; + } + // float-color model + if (colorModes[i] >= kCGLRGBFloat64Bit) + { + if (floatPixelFormatInitialized == 0) + { + floatPixelFormatInitialized = 1; + + renderer->colorFloatASizeMAX = colorModesBitsA[i]; + renderer->colorFloatRGBSizeMAX = colorModesBitsRGB[i]; + renderer->colorFloatASizeMIN = colorModesBitsA[i]; + renderer->colorFloatRGBSizeMIN = colorModesBitsRGB[i]; + } + // look for max color and alpha values - prefer color models that have alpha + if ((colorModesBitsRGB[i] >= renderer->colorFloatRGBSizeMAX) && (colorModesBitsA[i] >= renderer->colorFloatASizeMAX)) + { + renderer->colorFloatRGBSizeMAX = colorModesBitsRGB[i]; + renderer->colorFloatASizeMAX = colorModesBitsA[i]; + } + // find min color + if (colorModesBitsA[i] < renderer->colorFloatASizeMIN) + { + renderer->colorFloatASizeMIN = colorModesBitsA[i]; + } + // find min alpha color + if (colorModesBitsA[i] < renderer->colorFloatRGBSizeMIN) + { + renderer->colorFloatRGBSizeMIN = colorModesBitsRGB[i]; + } + renderer->colorFloatModesCount++; + } + } + i++; + } + CGLDescribeRenderer(info, j, kCGLRPDepthModes, &(renderer->depthModes)); + i=0; + while (depthModes[i] != 0) + { + if ((renderer->depthModes & depthModes[i]) != 0) + { + renderer->depthSizeMAX = depthModesBits[i]; + renderer->depthModesCount++; + } + i++; + } + CGLDescribeRenderer(info, j, kCGLRPStencilModes, &(renderer->stencilModes)); + i=0; + while (depthModes[i] != 0) + { + if ((renderer->stencilModes & depthModes[i]) != 0) + { + renderer->stencilSizeMAX = depthModesBits[i]; + renderer->stencilModesCount++; + } + i++; + } + CGLDescribeRenderer(info, j, kCGLRPAccumModes, &(renderer->accumModes)); + i=0; + while (colorModes[i] != 0) + { + if ((renderer->accumModes & colorModes[i]) != 0) + { + if ((colorModesBitsRGB[i] >= renderer->accumRGBSizeMAX) && (colorModesBitsA[i] >= renderer->accumASizeMAX)) + { + renderer->accumRGBSizeMAX = colorModesBitsRGB[i]; + renderer->accumASizeMAX = colorModesBitsA[i]; + } + renderer->accumModesCount++; + } + i++; + } + } + } + CGLDestroyRendererInfo (info); + } + +#if 0 + fprintf(stderr, "gRenderersCount=%ld\n", gRenderersCount); + int j; + for (j=0; j<gRenderersCount; j++) + { + RendererInfo *renderer = &gRenderers[j]; + fprintf(stderr, " id=%ld\n", renderer->id); + fprintf(stderr, " displayMask=%ld\n", renderer->displayMask); + + fprintf(stderr, " accelerated=%ld\n", renderer->accelerated); + + fprintf(stderr, " window=%ld\n", renderer->window); + fprintf(stderr, " fullscreen=%ld\n", renderer->fullscreen); + fprintf(stderr, " multiscreen=%ld\n", renderer->multiscreen); + fprintf(stderr, " offscreen=%ld\n", renderer->offscreen); + fprintf(stderr, " floatPixels=%ld\n", renderer->floatPixels); + fprintf(stderr, " stereo=%ld\n", renderer->stereo); + + fprintf(stderr, " auxBuffers=%ld\n", renderer->auxBuffers); + fprintf(stderr, " sampleBuffers=%ld\n", renderer->sampleBuffers); + fprintf(stderr, " samples=%ld\n", renderer->samples); + fprintf(stderr, " samplesModes=%ld\n", renderer->samplesModes); + fprintf(stderr, " multiSample=%ld\n", renderer->superSample); + fprintf(stderr, " superSample=%ld\n", renderer->superSample); + fprintf(stderr, " alphaSample=%ld\n", renderer->alphaSample); + + fprintf(stderr, " colorModes=%ld\n", renderer->colorModes); + fprintf(stderr, " colorRGBSizeMAX=%ld\n", renderer->colorRGBSizeMAX); + fprintf(stderr, " colorASizeMAX=%ld\n", renderer->colorASizeMAX); + fprintf(stderr, " colorFloatRGBSizeMAX=%ld\n", renderer->colorFloatRGBSizeMAX); + fprintf(stderr, " colorFloatASizeMAX=%ld\n", renderer->colorFloatASizeMAX); + fprintf(stderr, " colorFloatRGBSizeMIN=%ld\n", renderer->colorFloatRGBSizeMIN); + fprintf(stderr, " colorFloatASizeMIN=%ld\n", renderer->colorFloatASizeMIN); + fprintf(stderr, " colorModesCount=%ld\n", renderer->colorModesCount); + fprintf(stderr, " colorFloatModesCount=%ld\n", renderer->colorFloatModesCount); + fprintf(stderr, " depthModes=%ld\n", renderer->depthModes); + fprintf(stderr, " depthSizeMAX=%ld\n", renderer->depthSizeMAX); + fprintf(stderr, " depthModesCount=%ld\n", renderer->depthModesCount); + fprintf(stderr, " stencilModes=%ld\n", renderer->stencilModes); + fprintf(stderr, " stencilSizeMAX=%ld\n", renderer->stencilSizeMAX); + fprintf(stderr, " stencilModesCount=%ld\n", renderer->stencilModesCount); + fprintf(stderr, " accumModes=%ld\n", renderer->accumModes); + fprintf(stderr, " accumRGBSizeMAX=%ld\n", renderer->accumRGBSizeMAX); + fprintf(stderr, " accumASizeMAX=%ld\n", renderer->accumASizeMAX); + fprintf(stderr, " accumModesCount=%ld\n", renderer->accumModesCount); + fprintf(stderr, "\n"); + } +#endif +} + +long validateParameter(NSOpenGLPixelFormatAttribute attribute, long value) +{ + int i; + for (i=0; i<gRenderersCount; i++) { + RendererInfo* renderer = &gRenderers[i]; + if (renderer->accelerated != 0) { + switch (attribute) { + case NSOpenGLPFAStereo: + return renderer->stereo; + + case NSOpenGLPFAStencilSize: + return MIN(value, renderer->stencilSizeMAX); + + default: + break; + } + } + } + + return value; +} + +void* createPixelFormat(int* iattrs, int niattrs, int* ivalues) { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + getRendererInfo(); + + // http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/ObjC_classic/Classes/NSOpenGLPixelFormat.html + NSOpenGLPixelFormatAttribute attribs[256]; + + int idx = 0; + int i; + for (i = 0; i < niattrs; i++) { + int attr = iattrs[i]; + switch (attr) { + case NSOpenGLPFAPixelBuffer: + if (ivalues[i] != 0) { + attribs[idx++] = NSOpenGLPFAPixelBuffer; + } + break; + + case kCGLPFAColorFloat: + if (ivalues[i] != 0) { + attribs[idx++] = kCGLPFAColorFloat; + } + break; + + case NSOpenGLPFADoubleBuffer: + if (ivalues[i] != 0) { + attribs[idx++] = NSOpenGLPFADoubleBuffer; + } + break; + + case NSOpenGLPFAStereo: + if (ivalues[i] != 0 && (validateParameter(NSOpenGLPFAStereo, 0 /* dummy */) != 0)) { + attribs[idx++] = NSOpenGLPFAStereo; + } + break; + + case NSOpenGLPFAColorSize: + case NSOpenGLPFAAlphaSize: + case NSOpenGLPFADepthSize: + case NSOpenGLPFAAccumSize: + case NSOpenGLPFASampleBuffers: + case NSOpenGLPFASamples: + attribs[idx++] = attr; + attribs[idx++] = ivalues[i]; + break; + + case NSOpenGLPFAStencilSize: + attribs[idx++] = attr; + attribs[idx++] = validateParameter(NSOpenGLPFAStencilSize, ivalues[i]); + break; + + default: + // Need better way to signal to caller + return nil; + } + } + + // Zero-terminate + attribs[idx++] = 0; + + NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; + if (fmt == nil) { + // should we fallback to defaults or not? + fmt = [NSOpenGLView defaultPixelFormat]; + } + + [pool release]; + return fmt; +} + +void queryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalues) { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSOpenGLPixelFormat* fmt = (NSOpenGLPixelFormat*) pixelFormat; + long tmp; + // FIXME: think about how specifying this might affect the API + int virtualScreen = 0; + + int i; + for (i = 0; i < niattrs; i++) { + [fmt getValues: &tmp + forAttribute: (NSOpenGLPixelFormatAttribute) iattrs[i] + forVirtualScreen: virtualScreen]; + ivalues[i] = (int) tmp; + } + [pool release]; +} + +void deletePixelFormat(void* pixelFormat) { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSOpenGLPixelFormat* fmt = (NSOpenGLPixelFormat*) pixelFormat; + [fmt release]; + [pool release]; +} + +void* createContext(void* shareContext, + void* view, + void* pixelFormat, + int* viewNotReady) +{ + getRendererInfo(); + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + NSView *nsView = (NSView*)view; + + if (nsView != NULL) + { + Bool viewReady = true; + + if ([nsView lockFocusIfCanDraw] == NO) + { + viewReady = false; + } + else + { + NSRect frame = [nsView frame]; + if ((frame.size.width == 0) || (frame.size.height == 0)) + { + [nsView unlockFocus]; + viewReady = false; + } + } + + if (!viewReady) + { + if (viewNotReady != NULL) + { + *viewNotReady = 1; + } + + // the view is not ready yet + [pool release]; + return NULL; + } + } + + NSOpenGLContext* nsContext = [[NSOpenGLContext alloc] + initWithFormat: (NSOpenGLPixelFormat*) pixelFormat + shareContext: (NSOpenGLContext*) shareContext]; + + if (nsContext != nil) { + if (nsView != nil) { + [nsContext setView:nsView]; + [nsView unlockFocus]; + } + } + + [pool release]; + return nsContext; +} + +Bool makeCurrentContext(void* context) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [nsContext makeCurrentContext]; + [pool release]; + return true; +} + +Bool clearCurrentContext(void* context) { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [NSOpenGLContext clearCurrentContext]; + [pool release]; + return true; +} + +Bool deleteContext(void* context) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [nsContext clearDrawable]; + [nsContext release]; + [pool release]; + return true; +} + +Bool flushBuffer(void* context) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [nsContext flushBuffer]; + [pool release]; + return true; +} + +void setContextOpacity(void* context, int opacity) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + + [nsContext setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity]; +} + +void updateContext(void* context) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [nsContext update]; + [pool release]; +} + +void copyContext(void* destContext, void* srcContext, int mask) { + NSOpenGLContext *src = (NSOpenGLContext*) srcContext; + NSOpenGLContext *dst = (NSOpenGLContext*) destContext; + [dst copyAttributesFromContext: src withMask: mask]; +} + +void* updateContextRegister(void* context, void* view) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + NSView *nsView = (NSView*)view; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + ContextUpdater *contextUpdater = [[ContextUpdater alloc] init]; + [contextUpdater registerFor:nsContext with:nsView]; + [pool release]; + return NULL; +} + +void updateContextUnregister(void* context, void* view, void* updater) { + ContextUpdater *contextUpdater = (ContextUpdater *)updater; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [contextUpdater release]; + [pool release]; +} + +void* createPBuffer(int renderTarget, int internalFormat, int width, int height) { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSOpenGLPixelBuffer* pBuffer = [[NSOpenGLPixelBuffer alloc] + initWithTextureTarget:renderTarget + textureInternalFormat:internalFormat + textureMaxMipMapLevel:0 + pixelsWide:width + pixelsHigh:height]; + [pool release]; + return pBuffer; +} + +Bool destroyPBuffer(void* context, void* buffer) { + /* FIXME: not clear whether we need to perform the clearDrawable below */ + /* FIXME: remove the context argument -- don't need it any more */ + /* NSOpenGLContext *nsContext = (NSOpenGLContext*)context; */ + NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + /* + if (nsContext != NULL) { + [nsContext clearDrawable]; + } + */ + [pBuffer release]; + [pool release]; + + return true; +} + +void setContextPBuffer(void* context, void* buffer) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [nsContext setPixelBuffer: pBuffer + cubeMapFace: 0 + mipMapLevel: 0 + currentVirtualScreen: [nsContext currentVirtualScreen]]; + [pool release]; +} + +void setContextTextureImageToPBuffer(void* context, void* buffer, int colorBuffer) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [nsContext setTextureImageToPixelBuffer: pBuffer + colorBuffer: (unsigned long) colorBuffer]; + [pool release]; +} + +#include <mach-o/dyld.h> +Bool imagesInitialized = false; +static char libGLStr[] = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"; +static char libGLUStr[] = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib"; +static const struct mach_header *libGLImage; +static const struct mach_header *libGLUImage; +void* getProcAddress(const char *procname) { + if (imagesInitialized == false) { + imagesInitialized = true; + unsigned long options = NSADDIMAGE_OPTION_RETURN_ON_ERROR; + libGLImage = NSAddImage(libGLStr, options); + libGLUImage = NSAddImage(libGLUStr, options); + } + + unsigned long options = NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR; + char underscoreName[512] = "_"; + strcat(underscoreName, procname); + + if (NSIsSymbolNameDefinedInImage(libGLImage, underscoreName) == YES) { + NSSymbol sym = NSLookupSymbolInImage(libGLImage, underscoreName, options); + return NSAddressOfSymbol(sym); + } + + if (NSIsSymbolNameDefinedInImage(libGLUImage, underscoreName) == YES) { + NSSymbol sym = NSLookupSymbolInImage(libGLUImage, underscoreName, options); + return NSAddressOfSymbol(sym); + } + + if (NSIsSymbolNameDefinedWithHint(underscoreName, "GL")) { + NSSymbol sym = NSLookupAndBindSymbol(underscoreName); + return NSAddressOfSymbol(sym); + } + + return NULL; +} + +void setSwapInterval(void* context, int interval) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + long swapInterval = interval; + [nsContext setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval]; +} + +Bool setGammaRamp(int tableSize, float* redRamp, float* greenRamp, float* blueRamp) { + CGDisplayErr err = CGSetDisplayTransferByTable(kCGDirectMainDisplay, tableSize, redRamp, greenRamp, blueRamp); + return (err == CGDisplayNoErr); +} + +void resetGammaRamp() { + CGDisplayRestoreColorSyncSettings(); +} |