aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/native/macosx
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/native/macosx')
-rw-r--r--src/jogl/native/macosx/MacOSXCustomCGLCode.c2
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m966
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m494
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface.m167
4 files changed, 1058 insertions, 571 deletions
diff --git a/src/jogl/native/macosx/MacOSXCustomCGLCode.c b/src/jogl/native/macosx/MacOSXCustomCGLCode.c
index f8b7a800f..75896c3a2 100644
--- a/src/jogl/native/macosx/MacOSXCustomCGLCode.c
+++ b/src/jogl/native/macosx/MacOSXCustomCGLCode.c
@@ -2,7 +2,7 @@
#include <assert.h>
-#include </usr/include/machine/types.h>
+#include <machine/types.h>
#include "macosx-window-system.h"
void CGLQueryPixelFormat(CGLPixelFormatObj fmt, int* iattrs, int niattrs, int* ivalues) {
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
new file mode 100644
index 000000000..7ce8c58cf
--- /dev/null
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
@@ -0,0 +1,966 @@
+#import "MacOSXWindowSystemInterface.h"
+#import <QuartzCore/QuartzCore.h>
+#import <pthread.h>
+#import "NativeWindowProtocols.h"
+#include "timespec.h"
+
+#import <OpenGL/glext.h>
+
+/**
+ * Partial include of gl3.h - which we can only expect and use
+ * in case of a GL3 core context at runtime.
+ * Otherwise we would need to have 2 modules, one including GL2
+ * and one inclusing GL3 headers.
+ */
+#ifndef GL_ARB_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+extern void glBindVertexArray (GLuint array);
+extern void glDeleteVertexArrays (GLsizei n, const GLuint *arrays);
+extern void glGenVertexArrays (GLsizei n, GLuint *arrays);
+extern GLboolean glIsVertexArray (GLuint array);
+#endif
+
+//
+// CADisplayLink only available on iOS >= 3.1, sad, since it's convenient.
+// Use CVDisplayLink otherwise.
+//
+// #define HAS_CADisplayLink 1
+//
+
+// lock/sync debug output
+//
+// #define DBG_SYNC 1
+//
+#ifdef DBG_SYNC
+ // #define SYNC_PRINT(...) NSLog(@ ## __VA_ARGS__)
+ #define SYNC_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define SYNC_PRINT(...)
+#endif
+
+// fps debug output
+//
+// #define DBG_PERF 1
+
+// #define DBG_LIFECYCLE 1
+
+/**
+ * Capture setView(NULL), which produces a 'invalid drawable' message
+ *
+ * Also track lifecycle via DBG_PRINT messages, if VERBOSE is enabled!
+ */
+@interface MyNSOpenGLContext: NSOpenGLContext
+{
+}
+- (id)initWithFormat:(NSOpenGLPixelFormat *)format shareContext:(NSOpenGLContext *)share;
+- (void)setView:(NSView *)view;
+- (void)update;
+#ifdef DBG_LIFECYCLE
+- (id)retain;
+- (oneway void)release;
+#endif
+- (void)dealloc;
+
+@end
+
+@implementation MyNSOpenGLContext
+
+- (id)initWithFormat:(NSOpenGLPixelFormat *)format shareContext:(NSOpenGLContext *)share
+{
+ DBG_PRINT("MyNSOpenGLContext::initWithFormat.0: format %p, share %p\n", format, share);
+ MyNSOpenGLContext * o = [super initWithFormat:format shareContext:share];
+ DBG_PRINT("MyNSOpenGLContext::initWithFormat.X: new %p\n", o);
+ return o;
+}
+
+- (void)setView:(NSView *)view
+{
+ DBG_PRINT("MyNSOpenGLContext::setView: this.0 %p, view %p\n", self, view);
+ // NSLog(@"MyNSOpenGLContext::setView: %@",[NSThread callStackSymbols]);
+ if(NULL != view) {
+ [super setView:view];
+ } else {
+ [self clearDrawable];
+ }
+ DBG_PRINT("MyNSOpenGLContext::setView.X\n");
+}
+
+- (void)update
+{
+ DBG_PRINT("MyNSOpenGLContext::update: this.0 %p, view %p\n", self, [self view]);
+ [super update];
+ DBG_PRINT("MyNSOpenGLContext::update.X\n");
+}
+
+#ifdef DBG_LIFECYCLE
+
+- (id)retain
+{
+ DBG_PRINT("MyNSOpenGLContext::retain.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyNSOpenGLContext::retain: %@",[NSThread callStackSymbols]);
+ id o = [super retain];
+ DBG_PRINT("MyNSOpenGLContext::retain.X: %p (refcnt %d)\n", o, (int)[o retainCount]);
+ return o;
+}
+
+- (oneway void)release
+{
+ DBG_PRINT("MyNSOpenGLContext::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ [super release];
+ // DBG_PRINT("MyNSOpenGLContext::release.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
+}
+
+#endif
+
+#ifdef VERBOSE_ON
+ #define CGLRETAINCOUNT(c) (NULL!=c?(int)CGLGetContextRetainCount(c):-1)
+#else
+ #define CGLRETAINCOUNT(c)
+#endif
+
+- (void)dealloc
+{
+ /**
+ * The explicit CGLContext destruction below
+ * ensures that it is not left behind.
+ * Tests show that w/o these gymnastics, the CGLContext is not freed immediately after calling dealloc.
+ * The retain, release and dealloc ensures [super dealloc] won't message 'invalid context'.
+ */
+ CGLContextObj cglCtx = [self CGLContextObj];
+
+ DBG_PRINT("MyNSOpenGLContext::dealloc.0 %p (refcnt %d) - CGL-Ctx %p\n", self, (int)[self retainCount], cglCtx, CGLRETAINCOUNT(cglCtx));
+ // NSLog(@"MyNSOpenGLContext::dealloc: %@",[NSThread callStackSymbols]);
+
+ [self clearDrawable];
+ DBG_PRINT("MyNSOpenGLContext::dealloc.1 %d\n", CGLRETAINCOUNT(cglCtx));
+ if( NULL != cglCtx ) {
+ CGLRetainContext( cglCtx );
+ DBG_PRINT("MyNSOpenGLContext::dealloc.2 %d\n", CGLRETAINCOUNT(cglCtx));
+ }
+ [super dealloc];
+ DBG_PRINT("MyNSOpenGLContext::dealloc.3 %d\n", CGLRETAINCOUNT(cglCtx));
+ if( NULL != cglCtx ) {
+ CGLReleaseContext( cglCtx );
+ DBG_PRINT("MyNSOpenGLContext::dealloc.4 %d\n", CGLRETAINCOUNT(cglCtx));
+ CGLDestroyContext( cglCtx );
+ DBG_PRINT("MyNSOpenGLContext::dealloc.5 %d\n", CGLRETAINCOUNT(cglCtx));
+ }
+ DBG_PRINT("MyNSOpenGLContext::dealloc.X\n");
+}
+
+@end
+
+@interface MyNSOpenGLLayer: NSOpenGLLayer <NWDedicatedFrame>
+{
+@private
+ GLfloat gl_texCoords[8];
+ NSOpenGLContext* glContext;
+ Bool isGLEnabled;
+
+@protected
+ GLuint gl3ShaderProgramName;
+ GLuint vboBufVert;
+ GLuint vboBufTexCoord;
+ GLint vertAttrLoc;
+ GLint texCoordAttrLoc;
+ NSOpenGLPixelFormat* parentPixelFmt;
+ int texWidth;
+ int texHeight;
+ volatile Bool dedicatedFrameSet;
+ volatile CGRect dedicatedFrame;
+ volatile NSOpenGLPixelBuffer* pbuffer;
+ volatile GLuint textureID;
+ volatile NSOpenGLPixelBuffer* newPBuffer;
+#ifdef HAS_CADisplayLink
+ CADisplayLink* displayLink;
+#else
+ CVDisplayLinkRef displayLink;
+#endif
+ int tc;
+ struct timespec tStart;
+@public
+ struct timespec lastWaitTime;
+ GLint swapInterval;
+ GLint swapIntervalCounter;
+ pthread_mutex_t renderLock;
+ pthread_cond_t renderSignal;
+ volatile Bool shallDraw;
+}
+
+- (id) setupWithContext: (NSOpenGLContext*) parentCtx
+ gl3ShaderProgramName: (GLuint) gl3ShaderProgramName
+ pixelFormat: (NSOpenGLPixelFormat*) pfmt
+ pbuffer: (NSOpenGLPixelBuffer*) p
+ texIDArg: (GLuint) texID
+ opaque: (Bool) opaque
+ texWidth: (int) texWidth
+ texHeight: (int) texHeight;
+
+- (void)releaseLayer;
+- (void)deallocPBuffer;
+- (void)disableAnimation;
+- (void)pauseAnimation:(Bool)pause;
+- (void)setSwapInterval:(int)interval;
+- (void)tick;
+- (void)waitUntilRenderSignal: (long) to_micros;
+- (Bool)isGLSourceValid;
+
+- (void) setGLEnabled: (Bool) enable;
+- (Bool) validateTexSize: (CGRect) lRect;
+- (void) setTextureID: (int) _texID;
+
+- (Bool) isSamePBuffer: (NSOpenGLPixelBuffer*) p;
+- (void) setNewPBuffer: (NSOpenGLPixelBuffer*)p;
+- (void) applyNewPBuffer;
+
+- (void)setDedicatedFrame:(CGRect)frame quirks:(int)quirks; // @NWDedicatedFrame
+- (void) setFrame:(CGRect) frame;
+- (id<CAAction>)actionForKey:(NSString *)key ;
+- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask;
+- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat;
+- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp;
+- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp;
+
+#ifdef DBG_LIFECYCLE
+- (id)retain;
+- (oneway void)release;
+#endif
+- (void)dealloc;
+
+@end
+
+#ifndef HAS_CADisplayLink
+
+static CVReturn renderMyNSOpenGLLayer(CVDisplayLinkRef displayLink,
+ const CVTimeStamp *inNow,
+ const CVTimeStamp *inOutputTime,
+ CVOptionFlags flagsIn,
+ CVOptionFlags *flagsOut,
+ void *displayLinkContext)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*)displayLinkContext;
+ pthread_mutex_lock(&l->renderLock);
+ if( 0 < l->swapInterval ) {
+ l->swapIntervalCounter++;
+ if( l->swapIntervalCounter >= l->swapInterval ) {
+ SYNC_PRINT("<S %d/%d>", (int)l->swapIntervalCounter, l->swapInterval);
+ l->swapIntervalCounter = 0;
+ pthread_cond_signal(&l->renderSignal); // wake up vsync
+ }
+ }
+ pthread_mutex_unlock(&l->renderLock);
+ [pool release];
+ return kCVReturnSuccess;
+}
+
+#endif
+
+static const GLfloat gl_verts[] = {
+ -1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0,
+ 1.0, -1.0
+};
+
+@implementation MyNSOpenGLLayer
+
+- (id) setupWithContext: (NSOpenGLContext*) parentCtx
+ gl3ShaderProgramName: (GLuint) _gl3ShaderProgramName
+ pixelFormat: (NSOpenGLPixelFormat*) _parentPixelFmt
+ pbuffer: (NSOpenGLPixelBuffer*) p
+ texIDArg: (GLuint) texID
+ opaque: (Bool) opaque
+ texWidth: (int) _texWidth
+ texHeight: (int) _texHeight;
+{
+ pthread_mutexattr_t renderLockAttr;
+ pthread_mutexattr_init(&renderLockAttr);
+ pthread_mutexattr_settype(&renderLockAttr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&renderLock, &renderLockAttr); // recursive
+ pthread_cond_init(&renderSignal, NULL); // no attribute
+
+ {
+ int i;
+ for(i=0; i<8; i++) {
+ gl_texCoords[i] = 0.0f;
+ }
+ }
+ parentPixelFmt = [_parentPixelFmt retain]; // until destruction
+ glContext = [[MyNSOpenGLContext alloc] initWithFormat:parentPixelFmt shareContext:parentCtx];
+ gl3ShaderProgramName = _gl3ShaderProgramName;
+ vboBufVert = 0;
+ vboBufTexCoord = 0;
+ vertAttrLoc = 0;
+ texCoordAttrLoc = 0;
+ swapInterval = 1; // defaults to on (as w/ new GL profiles)
+ swapIntervalCounter = 0;
+ timespec_now(&lastWaitTime);
+ shallDraw = NO;
+ isGLEnabled = YES;
+ dedicatedFrameSet = NO;
+ dedicatedFrame = CGRectMake(0, 0, _texWidth, _texHeight);
+ [self validateTexSize: dedicatedFrame];
+ [self setTextureID: texID];
+
+ newPBuffer = NULL;
+ pbuffer = p;
+ if(NULL != pbuffer) {
+ [pbuffer retain];
+ }
+
+ {
+ // no animations for add/remove/swap sublayers etc
+ // doesn't work: [self removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
+ [self removeAllAnimations];
+ }
+
+ // instantiate a deactivated displayLink
+#ifdef HAS_CADisplayLink
+ displayLink = [[CVDisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)] retain];
+#else
+ CVReturn cvres;
+ {
+ int allDisplaysMask = 0;
+ int virtualScreen, accelerated, displayMask;
+ for (virtualScreen = 0; virtualScreen < [parentPixelFmt numberOfVirtualScreens]; virtualScreen++) {
+ [parentPixelFmt getValues:&displayMask forAttribute:NSOpenGLPFAScreenMask forVirtualScreen:virtualScreen];
+ [parentPixelFmt getValues:&accelerated forAttribute:NSOpenGLPFAAccelerated forVirtualScreen:virtualScreen];
+ if (accelerated) {
+ allDisplaysMask |= displayMask;
+ }
+ }
+ cvres = CVDisplayLinkCreateWithOpenGLDisplayMask(allDisplaysMask, &displayLink);
+ if(kCVReturnSuccess != cvres) {
+ DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkCreateWithOpenGLDisplayMask %X failed: %d\n", self, allDisplaysMask, cvres);
+ displayLink = NULL;
+ }
+ }
+ if(NULL != displayLink) {
+ CVReturn cvres;
+ DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.1: setup DisplayLink %p\n", displayLink);
+ cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [glContext CGLContextObj], [parentPixelFmt CGLPixelFormatObj]);
+ if(kCVReturnSuccess != cvres) {
+ DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext failed: %d\n", self, cvres);
+ }
+ }
+ if(NULL != displayLink) {
+ cvres = CVDisplayLinkSetOutputCallback(displayLink, renderMyNSOpenGLLayer, self);
+ if(kCVReturnSuccess != cvres) {
+ DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetOutputCallback failed: %d\n", self, cvres);
+ displayLink = NULL;
+ }
+ }
+#endif
+ [self pauseAnimation: YES];
+
+ [self removeAllAnimations];
+ [self setAutoresizingMask: (kCALayerWidthSizable|kCALayerHeightSizable)];
+ [self setNeedsDisplayOnBoundsChange: YES];
+
+ [self setOpaque: opaque ? YES : NO];
+
+#ifdef VERBOSE_ON
+ CGRect lRect = [self bounds];
+ if(NULL != pbuffer) {
+ DBG_PRINT("MyNSOpenGLLayer::init (pbuffer) %p, pctx %p, pfmt %p, pbuffer %p, ctx %p, opaque %d, pbuffer %dx%d -> tex %dx%d, bounds: %lf/%lf %lfx%lf, displayLink %p (refcnt %d)\n",
+ self, parentCtx, parentPixelFmt, pbuffer, glContext, opaque, [pbuffer pixelsWide], [pbuffer pixelsHigh], texWidth, texHeight,
+ lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, displayLink, (int)[self retainCount]);
+ } else {
+ DBG_PRINT("MyNSOpenGLLayer::init (texture) %p, pctx %p, pfmt %p, ctx %p, opaque %d, tex[id %d, %dx%d], bounds: %lf/%lf %lfx%lf, displayLink %p (refcnt %d)\n",
+ self, parentCtx, parentPixelFmt, glContext, opaque, (int)textureID, texWidth, texHeight,
+ lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, displayLink, (int)[self retainCount]);
+ }
+#endif
+ return self;
+}
+
+- (void) setGLEnabled: (Bool) enable
+{
+ DBG_PRINT("MyNSOpenGLLayer::setGLEnabled: %p, %d -> %d\n", self, (int)isGLEnabled, (int)enable);
+ isGLEnabled = enable;
+}
+
+- (Bool) validateTexSize: (CGRect) lRect
+{
+ const int lRectW = (int) (lRect.size.width + 0.5f);
+ const int lRectH = (int) (lRect.size.height + 0.5f);
+ Bool changed;
+
+ if( lRectH != texHeight || lRectW != texWidth ) {
+ texWidth = lRectW;
+ texHeight = lRectH;
+ changed = YES;
+
+ GLfloat texCoordWidth, texCoordHeight;
+ if(NULL != pbuffer) {
+ GLenum textureTarget = [pbuffer textureTarget] ;
+ GLsizei pwidth = [pbuffer pixelsWide];
+ GLsizei pheight = [pbuffer pixelsHigh];
+ if( GL_TEXTURE_2D == textureTarget ) {
+ texCoordWidth = (GLfloat)pwidth /(GLfloat)texWidth ;
+ texCoordHeight = (GLfloat)pheight/(GLfloat)texHeight ;
+ } else {
+ texCoordWidth = pwidth;
+ texCoordHeight = pheight;
+ }
+ } else {
+ texCoordWidth = (GLfloat)1.0f;
+ texCoordHeight = (GLfloat)1.0f;
+ }
+ gl_texCoords[3] = texCoordHeight;
+ gl_texCoords[5] = texCoordHeight;
+ gl_texCoords[4] = texCoordWidth;
+ gl_texCoords[6] = texCoordWidth;
+ #ifdef VERBOSE_ON
+ DBG_PRINT("MyNSOpenGLLayer::validateTexSize %p -> tex %dx%d, bounds: %lf/%lf %lfx%lf (%dx%d), dedicatedFrame set:%d %lf/%lf %lfx%lf\n",
+ self, texWidth, texHeight,
+ lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, lRectW, lRectH,
+ dedicatedFrameSet, dedicatedFrame.origin.x, dedicatedFrame.origin.y, dedicatedFrame.size.width, dedicatedFrame.size.height);
+ #endif
+ } else {
+ changed = NO;
+ }
+ return changed;
+}
+
+- (void) setTextureID: (int) _texID
+{
+ textureID = _texID;
+}
+
+- (Bool) isSamePBuffer: (NSOpenGLPixelBuffer*) p
+{
+ return pbuffer == p || newPBuffer == p;
+}
+
+- (void)setNewPBuffer: (NSOpenGLPixelBuffer*)p
+{
+ SYNC_PRINT("<NP-S %p -> %p>", pbuffer, p);
+ newPBuffer = p;
+ [newPBuffer retain];
+}
+
+- (void) applyNewPBuffer
+{
+ if( NULL != newPBuffer ) { // volatile OK
+ SYNC_PRINT("<NP-A %p -> %p>", pbuffer, newPBuffer);
+
+ if( 0 != textureID ) {
+ glDeleteTextures(1, (GLuint *)&textureID);
+ [self setTextureID: 0];
+ }
+ [pbuffer release];
+
+ pbuffer = newPBuffer;
+ newPBuffer = NULL;
+ }
+}
+
+- (void)deallocPBuffer
+{
+ if(NULL != pbuffer) {
+ NSOpenGLContext* context = [self openGLContext];
+ if(NULL!=context) {
+ [context makeCurrentContext];
+
+ DBG_PRINT("MyNSOpenGLLayer::deallocPBuffer (with ctx) %p (refcnt %d) - context %p, pbuffer %p, texID %d\n", self, (int)[self retainCount], context, pbuffer, (int)textureID);
+
+ if( 0 != textureID ) {
+ glDeleteTextures(1, (GLuint *)&textureID);
+ [self setTextureID: 0];
+ }
+ if(NULL != pbuffer) {
+ [pbuffer release];
+ pbuffer = NULL;
+ }
+ if(NULL != newPBuffer) {
+ [newPBuffer release];
+ newPBuffer = NULL;
+ }
+
+ [context clearDrawable];
+ } else {
+ DBG_PRINT("MyNSOpenGLLayer::deallocPBuffer (w/o ctx) %p (refcnt %d) - context %p, pbuffer %p, texID %d\n", self, (int)[self retainCount], context, pbuffer, (int)textureID);
+ }
+ }
+}
+
+- (void)disableAnimation
+{
+ DBG_PRINT("MyNSOpenGLLayer::disableAnimation.0: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink);
+ [self setAsynchronous: NO];
+ if(NULL != displayLink) {
+#ifdef HAS_CADisplayLink
+ [displayLink setPaused: YES];
+ [displayLink release];
+#else
+ CVDisplayLinkStop(displayLink);
+ CVDisplayLinkRelease(displayLink);
+#endif
+ displayLink = NULL;
+ }
+ DBG_PRINT("MyNSOpenGLLayer::disableAnimation.X: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink);
+}
+
+- (void)releaseLayer
+{
+ DBG_PRINT("MyNSOpenGLLayer::releaseLayer.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ [self setGLEnabled: NO];
+ [self disableAnimation];
+ pthread_mutex_lock(&renderLock);
+ [self deallocPBuffer];
+ if( NULL != glContext ) {
+ [glContext release];
+ glContext = NULL;
+ }
+ if( NULL != parentPixelFmt ) {
+ [parentPixelFmt release];
+ parentPixelFmt = NULL;
+ }
+ pthread_mutex_unlock(&renderLock);
+ [self release];
+ DBG_PRINT("MyNSOpenGLLayer::releaseLayer.X: %p\n", self);
+}
+
+#ifdef DBG_LIFECYCLE
+
+- (id)retain
+{
+ DBG_PRINT("MyNSOpenGLLayer::retain.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyNSOpenGLLayer::retain: %@",[NSThread callStackSymbols]);
+ id o = [super retain];
+ DBG_PRINT("MyNSOpenGLLayer::retain.X: %p (refcnt %d)\n", o, (int)[o retainCount]);
+ return o;
+}
+
+- (oneway void)release
+{
+ DBG_PRINT("MyNSOpenGLLayer::release.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyNSOpenGLLayer::release: %@",[NSThread callStackSymbols]);
+ [super release];
+ // DBG_PRINT("MyNSOpenGLLayer::release.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
+}
+
+#endif
+
+- (void)dealloc
+{
+ DBG_PRINT("MyNSOpenGLLayer::dealloc.0 %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyNSOpenGLLayer::dealloc: %@",[NSThread callStackSymbols]);
+ [self disableAnimation];
+ pthread_mutex_lock(&renderLock);
+ [self deallocPBuffer];
+ pthread_mutex_unlock(&renderLock);
+ pthread_cond_destroy(&renderSignal);
+ pthread_mutex_destroy(&renderLock);
+ [super dealloc];
+ // DBG_PRINT("MyNSOpenGLLayer::dealloc.X %p\n", self);
+}
+
+- (Bool)isGLSourceValid
+{
+ return NULL != pbuffer || NULL != newPBuffer || 0 != textureID ;
+}
+
+// @NWDedicatedFrame
+- (void)setDedicatedFrame:(CGRect)dFrame quirks:(int)quirks {
+ CGRect lRect = [self frame];
+ Bool dedicatedFramePosSet = 0 != ( NW_DEDICATEDFRAME_QUIRK_POSITION & quirks );
+ Bool dedicatedFrameSizeSet = 0 != ( NW_DEDICATEDFRAME_QUIRK_SIZE & quirks );
+ Bool dedicatedLayoutSet = 0 != ( NW_DEDICATEDFRAME_QUIRK_LAYOUT & quirks );
+ dedicatedFrameSet = dedicatedFramePosSet || dedicatedFrameSizeSet || dedicatedLayoutSet;
+ dedicatedFrame = dFrame;
+
+ DBG_PRINT("MyNSOpenGLLayer::setDedicatedFrame: Quirks [%d, pos %d, size %d, lout %d], %p, texSize %dx%d, %lf/%lf %lfx%lf -> %lf/%lf %lfx%lf\n",
+ quirks, dedicatedFramePosSet, dedicatedFrameSizeSet, dedicatedLayoutSet, self, texWidth, texHeight,
+ lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height,
+ dFrame.origin.x, dFrame.origin.y, dFrame.size.width, dFrame.size.height);
+ (void)lRect; // silence
+
+ if( dedicatedFrameSet ) {
+ [super setFrame: dedicatedFrame];
+ }
+}
+
+- (void) setFrame:(CGRect) frame {
+ if( dedicatedFrameSet ) {
+ [super setFrame: dedicatedFrame];
+ } else {
+ [super setFrame: frame];
+ }
+}
+
+- (id<CAAction>)actionForKey:(NSString *)key
+{
+ DBG_PRINT("MyNSOpenGLLayer::actionForKey.0 %p key %s -> NIL\n", self, [key UTF8String]);
+ return nil;
+ // return [super actionForKey: key];
+}
+
+- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask
+{
+ DBG_PRINT("MyNSOpenGLLayer::openGLPixelFormatForDisplayMask: %p (refcnt %d) - parent-pfmt %p -> new-pfmt %p\n",
+ self, (int)[self retainCount], parentPixelFmt, parentPixelFmt);
+ // We simply take over ownership of parent PixelFormat until releaseLayer..
+ return parentPixelFmt;
+}
+
+- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+{
+ DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.0: %p (refcnt %d) - pfmt %p, ctx %p, DisplayLink %p\n",
+ self, (int)[self retainCount], pixelFormat, glContext, displayLink);
+ return glContext;
+}
+
+- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+ SYNC_PRINT("<? %d, %d>", (int)shallDraw, (int)isGLEnabled);
+ return shallDraw && isGLEnabled;
+}
+
+- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+ pthread_mutex_unlock(&renderLock);
+ SYNC_PRINT("<* ");
+ // NSLog(@"MyNSOpenGLLayer::DRAW: %@",[NSThread callStackSymbols]);
+
+ if( isGLEnabled && shallDraw && ( NULL != pbuffer || NULL != newPBuffer || 0 != textureID ) ) {
+ [context makeCurrentContext];
+
+ if( NULL != newPBuffer ) { // volatile OK
+ [self applyNewPBuffer];
+ }
+
+ GLenum textureTarget;
+
+ Bool texSizeChanged = [self validateTexSize: ( dedicatedFrameSet ? dedicatedFrame : [self bounds] ) ];
+ if( texSizeChanged ) {
+ [context update];
+ }
+
+ if( NULL != pbuffer ) {
+ if( texSizeChanged && 0 != textureID ) {
+ glDeleteTextures(1, (GLuint *)&textureID);
+ [self setTextureID: 0];
+ }
+ textureTarget = [pbuffer textureTarget];
+ if( 0 != gl3ShaderProgramName ) {
+ glUseProgram(gl3ShaderProgramName);
+ glActiveTexture(GL_TEXTURE0);
+ }
+ if( 0 == textureID ) {
+ glGenTextures(1, (GLuint *)&textureID);
+ glBindTexture(textureTarget, textureID);
+ glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ } else {
+ glBindTexture(textureTarget, textureID);
+ }
+ [context setTextureImageToPixelBuffer: (NSOpenGLPixelBuffer*) pbuffer colorBuffer: GL_FRONT];
+ } else {
+ if( 0 != gl3ShaderProgramName ) {
+ glUseProgram(gl3ShaderProgramName);
+ glActiveTexture(GL_TEXTURE0);
+ }
+ textureTarget = GL_TEXTURE_2D;
+ glBindTexture(textureTarget, textureID);
+ }
+ SYNC_PRINT(" %d gl3Prog %d/%d*>", (int)textureID, (int)gl3ShaderProgramName, (int)glIsProgram (gl3ShaderProgramName));
+
+ if( 0 == vboBufVert ) { // Once: Init Data and Bind to Pointer
+ if( 0 != gl3ShaderProgramName ) {
+ // Install default VAO as required by GL 3.2 core!
+ GLuint vaoBuf = 0;
+ glGenVertexArrays(1, &vaoBuf);
+ glBindVertexArray(vaoBuf);
+
+ // Set texture-unit 0
+ GLint texUnitLoc = glGetUniformLocation (gl3ShaderProgramName, "mgl_Texture0");
+ glUniform1i (texUnitLoc, 0);
+ }
+ glGenBuffers( 1, &vboBufVert );
+ glBindBuffer( GL_ARRAY_BUFFER, vboBufVert );
+ glBufferData( GL_ARRAY_BUFFER, 4 * 2 * sizeof(GLfloat), gl_verts, GL_STATIC_DRAW);
+ if( 0 != gl3ShaderProgramName ) {
+ vertAttrLoc = glGetAttribLocation( gl3ShaderProgramName, "mgl_Vertex" );
+ glVertexAttribPointer( vertAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL );
+ } else {
+ glVertexPointer(2, GL_FLOAT, 0, NULL);
+ }
+
+ glGenBuffers( 1, &vboBufTexCoord );
+ glBindBuffer( GL_ARRAY_BUFFER, vboBufTexCoord );
+ glBufferData( GL_ARRAY_BUFFER, 4 * 2 * sizeof(GLfloat), gl_texCoords, GL_STATIC_DRAW);
+ if( 0 != gl3ShaderProgramName ) {
+ texCoordAttrLoc = glGetAttribLocation( gl3ShaderProgramName, "mgl_MultiTexCoord" );
+ glVertexAttribPointer( texCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL );
+ } else {
+ glTexCoordPointer(2, GL_FLOAT, 0, NULL);
+ }
+ }
+ if( texSizeChanged ) {
+ glBindBuffer( GL_ARRAY_BUFFER, vboBufTexCoord );
+ glBufferSubData( GL_ARRAY_BUFFER, 0, 4 * 2 * sizeof(GLfloat), gl_texCoords);
+ if( 0 != gl3ShaderProgramName ) {
+ glVertexAttribPointer( texCoordAttrLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL );
+ } else {
+ glTexCoordPointer(2, GL_FLOAT, 0, NULL);
+ }
+ }
+ if( 0 != gl3ShaderProgramName ) {
+ glEnableVertexAttribArray( vertAttrLoc );
+ glEnableVertexAttribArray( texCoordAttrLoc );
+ } else {
+ glEnable(textureTarget);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ }
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ if( 0 != gl3ShaderProgramName ) {
+ glDisableVertexAttribArray( vertAttrLoc );
+ glDisableVertexAttribArray( texCoordAttrLoc );
+ glUseProgram(0);
+ } else {
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glDisable(textureTarget);
+ }
+
+ glBindTexture(textureTarget, 0);
+
+ [context clearDrawable];
+
+ [super drawInOpenGLContext: context pixelFormat: pixelFormat forLayerTime: timeInterval displayTime: timeStamp];
+
+ } else {
+ // glClear(GL_COLOR_BUFFER_BIT);
+ // glBlitFramebuffer(0, 0, texWidth, texHeight,
+ // 0, 0, texWidth, texHeight,
+ // GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ SYNC_PRINT(" 0*>");
+ }
+
+ #ifdef DBG_PERF
+ [self tick];
+ #endif
+ shallDraw = NO;
+
+ if( 0 >= swapInterval ) {
+ pthread_cond_signal(&renderSignal); // wake up !vsync
+ SYNC_PRINT("<s>");
+ }
+ SYNC_PRINT("<$>\n");
+ pthread_mutex_unlock(&renderLock);
+}
+
+- (void)pauseAnimation:(Bool)pause
+{
+ DBG_PRINT("MyNSOpenGLLayer::pauseAnimation: %d\n", (int)pause);
+ [self setAsynchronous: NO];
+ if(pause) {
+ if(NULL != displayLink) {
+ #ifdef HAS_CADisplayLink
+ [displayLink setPaused: YES];
+ #else
+ CVDisplayLinkStop(displayLink);
+ #endif
+ }
+ } else {
+ if(NULL != displayLink) {
+ #ifdef HAS_CADisplayLink
+ [displayLink setPaused: NO];
+ [displayLink setFrameInterval: swapInterval];
+ #else
+ CVDisplayLinkStart(displayLink);
+ #endif
+ }
+ }
+ tc = 0;
+ timespec_now(&tStart);
+}
+
+- (void)setSwapInterval:(int)interval
+{
+ /**
+ * v-sync doesn't works w/ NSOpenGLLayer's context .. well :(
+ * Using CVDisplayLink .. see setSwapInterval() below.
+ *
+ GLint si;
+ [context getValues: &si forParameter: NSOpenGLCPSwapInterval];
+ if(si != swapInterval) {
+ DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p setSwapInterval: %d -> %d\n", self, si, swapInterval);
+ [context setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
+ }
+ */
+
+ pthread_mutex_lock(&renderLock);
+ DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.0: %d - displayLink %p\n", interval, displayLink);
+ swapInterval = interval;
+ swapIntervalCounter = 0;
+ pthread_mutex_unlock(&renderLock);
+
+ if(0 < swapInterval) {
+ [self pauseAnimation: NO];
+ } else {
+ [self pauseAnimation: YES];
+ }
+ DBG_PRINT("MyNSOpenGLLayer::setSwapInterval.X: %d\n", interval);
+}
+
+-(void)tick
+{
+ tc++;
+ if(tc%60==0) {
+ struct timespec t1, td;
+ timespec_now(&t1);
+ timespec_subtract(&td, &t1, &tStart);
+ long td_ms = timespec_milliseconds(&td);
+ fprintf(stderr, "NSOpenGLLayer: %ld ms / %d frames, %ld ms / frame, %f fps\n",
+ td_ms, tc, td_ms/tc, (tc * 1000.0) / (float)td_ms );
+ fflush(NULL);
+ }
+}
+
+- (void)waitUntilRenderSignal: (long) to_micros
+{
+ struct timespec t0, to_until;
+ BOOL tooLate;
+ int wr;
+ if( 0 >= to_micros ) {
+ to_micros = 16666 + 1000; // defaults to 1/60s + 1ms
+ NSLog(@"MyNSOpenGLContext::waitUntilRenderSignal: to_micros was zero, using defaults");
+ }
+ pthread_mutex_lock(&renderLock);
+ timespec_now(&t0);
+ to_until = lastWaitTime;
+ timespec_addmicros(&to_until, to_micros);
+ tooLate = timespec_compare(&to_until, &t0) < 0;
+ #ifdef DBG_SYNC
+ struct timespec td_until;
+ timespec_subtract(&td_until, &to_until, &t0);
+ SYNC_PRINT("{W %ld ms, to %ld ms, late %d", to_micros/1000, timespec_milliseconds(&td_until), tooLate);
+ #endif
+ if( 0 < swapInterval ) {
+ if( tooLate ) {
+ // adjust!
+ to_until = t0;
+ timespec_addmicros(&to_until, to_micros);
+ }
+ wr = pthread_cond_timedwait(&renderSignal, &renderLock, &to_until);
+ #ifdef DBG_SYNC
+ struct timespec t1, td, td2;
+ timespec_now(&t1);
+ timespec_subtract(&td, &t1, &t0);
+ timespec_subtract(&td2, &t1, &lastWaitTime);
+ fprintf(stderr, "(%ld) / (%ld) ms", timespec_milliseconds(&td), timespec_milliseconds(&td2));
+ #endif
+ }
+ SYNC_PRINT("-%d-%d}\n", shallDraw, wr);
+ timespec_now(&lastWaitTime);
+ pthread_mutex_unlock(&renderLock);
+}
+
+@end
+
+NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, int gl3ShaderProgramName, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, uint32_t texID, Bool opaque, int texWidth, int texHeight) {
+ return [[[MyNSOpenGLLayer alloc] init] setupWithContext:ctx gl3ShaderProgramName: (GLuint)gl3ShaderProgramName pixelFormat: fmt pbuffer: p texIDArg: (GLuint)texID
+ opaque: opaque texWidth: texWidth texHeight: texHeight];
+}
+
+void setNSOpenGLLayerEnabled(NSOpenGLLayer* layer, Bool enable) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ [l setGLEnabled: enable];
+ [pool release];
+}
+
+void setNSOpenGLLayerSwapInterval(NSOpenGLLayer* layer, int interval) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ [l setSwapInterval: interval];
+ [pool release];
+}
+
+void waitUntilNSOpenGLLayerIsReady(NSOpenGLLayer* layer, long to_micros) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ [l waitUntilRenderSignal: to_micros];
+ [pool release];
+}
+
+void setNSOpenGLLayerNeedsDisplayFBO(NSOpenGLLayer* layer, uint32_t texID) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ Bool shallDraw;
+
+ // volatile OK
+ [l setTextureID: texID];
+ shallDraw = [l isGLSourceValid];
+ l->shallDraw = shallDraw;
+
+ SYNC_PRINT("<! T %d>", (int)shallDraw);
+ if(shallDraw) {
+ if ( [NSThread isMainThread] == YES ) {
+ [l setNeedsDisplay];
+ } else {
+ // don't wait - using doublebuffering
+ [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
+ }
+ }
+ // DBG_PRINT("MyNSOpenGLLayer::setNSOpenGLLayerNeedsDisplay %p\n", l);
+ [pool release];
+}
+
+void setNSOpenGLLayerNeedsDisplayPBuffer(NSOpenGLLayer* layer, NSOpenGLPixelBuffer* p) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ Bool shallDraw;
+
+ if( NO == [l isSamePBuffer: p] ) {
+ [l setNewPBuffer: p];
+ }
+
+ // volatile OK
+ shallDraw = [l isGLSourceValid];
+ l->shallDraw = shallDraw;
+
+ SYNC_PRINT("<! T %d>", (int)shallDraw);
+ if(shallDraw) {
+ if ( [NSThread isMainThread] == YES ) {
+ [l setNeedsDisplay];
+ } else {
+ // don't wait - using doublebuffering
+ [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
+ }
+ }
+ // DBG_PRINT("MyNSOpenGLLayer::setNSOpenGLLayerNeedsDisplay %p\n", l);
+ [pool release];
+}
+
+void releaseNSOpenGLLayer(NSOpenGLLayer* layer) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+
+ [CATransaction begin];
+ [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
+
+ DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.0: %p\n", l);
+ [l releaseLayer];
+ DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.X: %p\n", l);
+
+ [CATransaction commit];
+
+ [pool release];
+}
+
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
deleted file mode 100644
index 66bd10f89..000000000
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
+++ /dev/null
@@ -1,494 +0,0 @@
-#import "MacOSXWindowSystemInterface.h"
-#import <QuartzCore/QuartzCore.h>
-#import <pthread.h>
-#include "timespec.h"
-
-//
-// CADisplayLink only available on iOS >= 3.1, sad, since it's convenient.
-// Use CVDisplayLink otherwise.
-//
-// #define HAS_CADisplayLink 1
-//
-
-// lock/sync debug output
-//
-// #define DBG_SYNC 1
-//
-#ifdef DBG_SYNC
- // #define SYNC_PRINT(...) NSLog(@ ## __VA_ARGS__)
- #define SYNC_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
-#else
- #define SYNC_PRINT(...)
-#endif
-
-// fps debug output
-//
-// #define DBG_PERF 1
-
-@interface MyNSOpenGLLayer: NSOpenGLLayer
-{
-@protected
- NSOpenGLPixelBuffer* pbuffer;
- int texWidth;
- int texHeight;
- GLuint textureID;
- GLint swapInterval;
- GLint swapIntervalCounter;
- struct timespec lastWaitTime;
-#ifdef HAS_CADisplayLink
- CADisplayLink* displayLink;
-#else
- CVDisplayLinkRef displayLink;
-#endif
- int tc;
- struct timespec t0;
-@public
- pthread_mutex_t renderLock;
- pthread_cond_t renderSignal;
- BOOL shallDraw;
-}
-
-- (id) setupWithContext: (NSOpenGLContext*) ctx
- pixelFormat: (NSOpenGLPixelFormat*) pfmt
- pbuffer: (NSOpenGLPixelBuffer*) p
- opaque: (Bool) opaque
- texWidth: (int) texWidth
- texHeight: (int) texHeight;
-
-- (void)deallocTex;
-- (void)disableAnimation;
-- (void)releaseLayer;
-- (void)dealloc;
-- (int)getSwapInterval;
-- (void)setSwapInterval:(int)interval;
-- (void)tick;
-
-@end
-
-#ifndef HAS_CADisplayLink
-
-static CVReturn renderMyNSOpenGLLayer(CVDisplayLinkRef displayLink,
- const CVTimeStamp *inNow,
- const CVTimeStamp *inOutputTime,
- CVOptionFlags flagsIn,
- CVOptionFlags *flagsOut,
- void *displayLinkContext)
-{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*)displayLinkContext;
- pthread_mutex_lock(&l->renderLock);
- #ifdef DBG_PERF
- [l tick];
- #endif
- if(0 < l->swapInterval) {
- l->swapIntervalCounter++;
- if(l->swapIntervalCounter>=l->swapInterval) {
- l->swapIntervalCounter = 0;
- pthread_cond_signal(&l->renderSignal);
- SYNC_PRINT("S");
- }
- }
- pthread_mutex_unlock(&l->renderLock);
- [pool release];
- return kCVReturnSuccess;
-}
-
-#endif
-
-@implementation MyNSOpenGLLayer
-
-- (id) setupWithContext: (NSOpenGLContext*) _ctx
- pixelFormat: (NSOpenGLPixelFormat*) _fmt
- pbuffer: (NSOpenGLPixelBuffer*) p
- opaque: (Bool) opaque
- texWidth: (int) _texWidth
- texHeight: (int) _texHeight;
-{
- pthread_mutexattr_t renderLockAttr;
- pthread_mutexattr_init(&renderLockAttr);
- pthread_mutexattr_settype(&renderLockAttr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&renderLock, &renderLockAttr); // recursive
- pthread_cond_init(&renderSignal, NULL); // no attribute
-
- textureID = 0;
- swapInterval = 1; // defaults to on (as w/ new GL profiles)
- swapIntervalCounter = 0;
- timespec_now(&lastWaitTime);
- shallDraw = NO;
- texWidth = _texWidth;
- texHeight = _texHeight;
- pbuffer = p;
- [pbuffer retain];
-
- {
- CGRect lRect = CGRectMake(0, 0, texWidth, texHeight);
- [self setFrame:lRect];
-
- // no animations for add/remove/swap sublayers etc
- // doesn't work: [self removeAnimationForKey: kCAOnOrderIn, kCAOnOrderOut, kCATransition]
- [self removeAllAnimations];
- }
-
- // instantiate a deactivated displayLink
-#ifdef HAS_CADisplayLink
- displayLink = [[CVDisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)] retain];
- [displayLink setPaused: YES];
-#else
- CVReturn cvres;
- {
- int allDisplaysMask = 0;
- int virtualScreen, accelerated, displayMask;
- for (virtualScreen = 0; virtualScreen < [_fmt numberOfVirtualScreens]; virtualScreen++) {
- [_fmt getValues:&displayMask forAttribute:NSOpenGLPFAScreenMask forVirtualScreen:virtualScreen];
- [_fmt getValues:&accelerated forAttribute:NSOpenGLPFAAccelerated forVirtualScreen:virtualScreen];
- if (accelerated) {
- allDisplaysMask |= displayMask;
- }
- }
- cvres = CVDisplayLinkCreateWithOpenGLDisplayMask(allDisplaysMask, &displayLink);
- if(kCVReturnSuccess != cvres) {
- DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkCreateWithOpenGLDisplayMask %X failed: %d\n", self, allDisplaysMask, cvres);
- displayLink = NULL;
- }
- }
- if(NULL != displayLink) {
- cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [_ctx CGLContextObj], [_fmt CGLPixelFormatObj]);
- if(kCVReturnSuccess != cvres) {
- DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext failed: %d\n", self, cvres);
- displayLink = NULL;
- }
- }
- if(NULL != displayLink) {
- cvres = CVDisplayLinkSetOutputCallback(displayLink, renderMyNSOpenGLLayer, self);
- if(kCVReturnSuccess != cvres) {
- DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetOutputCallback failed: %d\n", self, cvres);
- displayLink = NULL;
- }
- }
- if(NULL != displayLink) {
- CVDisplayLinkStop(displayLink);
- }
-#endif
- [self setAsynchronous: YES];
-
- [self setNeedsDisplayOnBoundsChange: YES]; // FIXME: learn how to recreate on size change!
-
- [self setOpaque: opaque ? YES : NO];
-
- CGRect lRect = [self frame];
- DBG_PRINT("MyNSOpenGLLayer::init %p, ctx %p, pfmt %p, pbuffer %p, opaque %d, pbuffer %dx%d -> tex %dx%d, frame: %lf/%lf %lfx%lf (refcnt %d)\n",
- self, _ctx, _fmt, pbuffer, opaque, [pbuffer pixelsWide], [pbuffer pixelsHigh], texWidth, texHeight,
- lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, (int)[self retainCount]);
- return self;
-}
-
-- (void)disableAnimation
-{
- DBG_PRINT("MyNSOpenGLLayer::disableAnimation: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink);
- pthread_mutex_lock(&renderLock);
- [self setAsynchronous: NO];
- if(NULL != displayLink) {
-#ifdef HAS_CADisplayLink
- [displayLink setPaused: YES];
- [displayLink release];
-#else
- if(NULL!=displayLink) {
- CVDisplayLinkStop(displayLink);
- CVDisplayLinkRelease(displayLink);
- }
-#endif
- displayLink = NULL;
- }
- pthread_mutex_unlock(&renderLock);
-}
-
-- (void)deallocTex
-{
- pthread_mutex_lock(&renderLock);
- NSOpenGLContext* context = [self openGLContext];
- DBG_PRINT("MyNSOpenGLLayer::deallocTex %p (refcnt %d) - context %p, pbuffer %p\n", self, (int)[self retainCount], context, pbuffer);
- if(NULL != pbuffer) {
- if(NULL!=context) {
- [context makeCurrentContext];
- if(0 != textureID) {
- glDeleteTextures(1, &textureID);
- textureID = 0;
- }
- [context clearDrawable];
- }
- [pbuffer release];
- pbuffer = NULL;
- }
- pthread_mutex_unlock(&renderLock);
-}
-
-- (void)releaseLayer
-{
- DBG_PRINT("MyNSOpenGLLayer::releaseLayer.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
- pthread_mutex_lock(&renderLock);
- [self disableAnimation];
- [self deallocTex];
- [self release];
- DBG_PRINT("MyNSOpenGLLayer::releaseLayer.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
- pthread_mutex_unlock(&renderLock);
-}
-
-- (void)dealloc
-{
- DBG_PRINT("MyNSOpenGLLayer::dealloc.0 %p (refcnt %d)\n", self, (int)[self retainCount]);
- // NSLog(@"MyNSOpenGLLayer::dealloc: %@",[NSThread callStackSymbols]);
-
- [self disableAnimation];
- [self deallocTex];
- pthread_cond_destroy(&renderSignal);
- pthread_mutex_destroy(&renderLock);
- [super dealloc];
- DBG_PRINT("MyNSOpenGLLayer::dealloc.X %p\n", self);
-}
-
-- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
- forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
-{
- // assume both methods 'canDrawInOpenGLContext' and 'drawInOpenGLContext'
- // are called from the same thread subsequently
- pthread_mutex_lock(&renderLock);
- Bool res = NULL != pbuffer && YES == shallDraw;
- if(!res) {
- SYNC_PRINT("0");
- pthread_mutex_unlock(&renderLock);
- } else {
- SYNC_PRINT("1");
- }
- return res;
-}
-
-- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
- forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
-{
- [context makeCurrentContext];
-
- /**
- * v-sync doesn't works w/ NSOpenGLLayer's context .. well :(
- * Using CVDisplayLink .. see setSwapInterval() below.
- *
- if(0 <= swapInterval) {
- GLint si;
- [context getValues: &si forParameter: NSOpenGLCPSwapInterval];
- if(si != swapInterval) {
- DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p setSwapInterval: %d -> %d\n", self, si, swapInterval);
- [context setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
- }
- } */
- GLenum textureTarget = [pbuffer textureTarget];
- GLfloat tWidth, tHeight;
- {
- GLsizei pwidth = [pbuffer pixelsWide];
- GLsizei pheight = [pbuffer pixelsHigh];
- tWidth = textureTarget == GL_TEXTURE_2D ? (GLfloat)pwidth /(GLfloat)texWidth : pwidth;
- tHeight = textureTarget == GL_TEXTURE_2D ? (GLfloat)pheight/(GLfloat)texHeight : pheight;
- }
- Bool texCreated = 0 == textureID;
-
- if(texCreated) {
- glGenTextures(1, &textureID);
- DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p, ctx %p, pfmt %p tex %dx%d -> %fx%f 0x%X: creating texID 0x%X\n",
- self, context, pixelFormat, texWidth, texHeight, tWidth, tHeight, textureTarget, textureID);
-
- CGRect lRect = [self frame];
- DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p frame0: %lf/%lf %lfx%lf\n",
- self, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
- }
-
- glBindTexture(textureTarget, textureID);
-
- /**
- if(texCreated) {
- // proper tex size setup
- glTexImage2D(textureTarget, 0, GL_RGB, texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
- } */
-
- [context setTextureImageToPixelBuffer: pbuffer colorBuffer: GL_FRONT];
-
- glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glEnable(textureTarget);
-
- static GLfloat verts[] = {
- -1.0, -1.0,
- -1.0, 1.0,
- 1.0, 1.0,
- 1.0, -1.0
- };
-
- GLfloat tex[] = {
- 0.0, 0.0,
- 0.0, tHeight,
- tWidth, tHeight,
- tWidth, 0.0
- };
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, verts);
- glTexCoordPointer(2, GL_FLOAT, 0, tex);
-
- glDrawArrays(GL_QUADS, 0, 4);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glDisable(textureTarget);
- glBindTexture(textureTarget, 0);
-
- [super drawInOpenGLContext: context pixelFormat: pixelFormat forLayerTime: timeInterval displayTime: timeStamp];
- shallDraw = NO;
- if(0 >= swapInterval) {
- pthread_cond_signal(&renderSignal); // just to wake up
- SYNC_PRINT("s");
- }
- SYNC_PRINT("$");
- pthread_mutex_unlock(&renderLock);
-}
-
-- (int)getSwapInterval
-{
- return swapInterval;
-}
-
-- (void)setSwapInterval:(int)interval
-{
- DBG_PRINT("MyNSOpenGLLayer::setSwapInterval: %d\n", interval);
- swapInterval = interval;
- swapIntervalCounter = 0;
- if(0 < swapInterval) {
- tc = 0;
- timespec_now(&t0);
-
- [self setAsynchronous: NO];
- #ifdef HAS_CADisplayLink
- [displayLink setPaused: NO];
- [displayLink setFrameInterval: interval];
- #else
- if(NULL!=displayLink) {
- CVDisplayLinkStart(displayLink);
- // FIXME: doesn't support interval ..
- }
- #endif
- } else {
- #ifdef HAS_CADisplayLink
- [displayLink setPaused: YES];
- #else
- if(NULL!=displayLink) {
- CVDisplayLinkStop(displayLink);
- }
- #endif
- [self setAsynchronous: YES];
- }
-}
-
--(void)tick
-{
- tc++;
- if(tc%60==0) {
- struct timespec t1, td;
- timespec_now(&t1);
- timespec_subtract(&td, &t1, &t0);
- long td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "NSOpenGLLayer: %ld ms / %d frames, %ld ms / frame, %f fps\n",
- td_ms, tc, td_ms/tc, (tc * 1000.0) / (float)td_ms );
- fflush(NULL);
- }
-}
-
-@end
-
-NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, Bool opaque, int texWidth, int texHeight) {
- // This simply crashes after dealloc() has been called .. ie. ref-count -> 0 too early ?
- // However using alloc/init, actual dealloc happens at JAWT destruction, hence too later IMHO.
- // return [[MyNSOpenGLLayer layer] setupWithContext:ctx pixelFormat: fmt pbuffer: p opaque: opaque texWidth: texWidth texHeight: texHeight];
-
- return [[[MyNSOpenGLLayer alloc] init] setupWithContext:ctx pixelFormat: fmt pbuffer: p opaque: opaque texWidth: texWidth texHeight: texHeight];
-}
-
-void setNSOpenGLLayerSwapInterval(NSOpenGLLayer* layer, int interval) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
- pthread_mutex_lock(&l->renderLock);
- [l setSwapInterval: interval];
- pthread_mutex_unlock(&l->renderLock);
-}
-
-void waitUntilNSOpenGLLayerIsReady(NSOpenGLLayer* layer, long to_micros) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
- BOOL ready = NO;
- int wr = 0;
- pthread_mutex_lock(&l->renderLock);
- SYNC_PRINT("{");
- do {
- if([l getSwapInterval] <= 0) {
- ready = !l->shallDraw;
- }
- if(NO == ready) {
- if(0 < to_micros) {
- #ifdef DBG_SYNC
- struct timespec t0, t1, td, td2;
- timespec_now(&t0);
- #endif
- struct timespec to_abs = l->lastWaitTime;
- timespec_addmicros(&to_abs, to_micros);
- #ifdef DBG_SYNC
- timespec_subtract(&td, &to_abs, &t0);
- fprintf(stderr, "(%ld) / ", timespec_milliseconds(&td));
- #endif
- wr = pthread_cond_timedwait(&l->renderSignal, &l->renderLock, &to_abs);
- #ifdef DBG_SYNC
- timespec_now(&t1);
- timespec_subtract(&td, &t1, &t0);
- timespec_subtract(&td2, &t1, &l->lastWaitTime);
- fprintf(stderr, "(%ld) / (%ld) ms", timespec_milliseconds(&td), timespec_milliseconds(&td2));
- #endif
- } else {
- pthread_cond_wait (&l->renderSignal, &l->renderLock);
- }
- ready = !l->shallDraw;
- }
- } while (NO == ready && 0 == wr) ;
- SYNC_PRINT("-%d}", ready);
- timespec_now(&l->lastWaitTime);
- pthread_mutex_unlock(&l->renderLock);
-}
-
-void setNSOpenGLLayerNeedsDisplay(NSOpenGLLayer* layer) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- pthread_mutex_lock(&l->renderLock);
- l->shallDraw = YES;
- if ( [NSThread isMainThread] == YES ) {
- [l setNeedsDisplay];
- } else {
- // can't wait, otherwise we may deadlock AWT
- [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
- }
- SYNC_PRINT(".");
- pthread_mutex_unlock(&l->renderLock);
- // DBG_PRINT("MyNSOpenGLLayer::setNSOpenGLLayerNeedsDisplay %p\n", l);
- [pool release];
-}
-
-void releaseNSOpenGLLayer(NSOpenGLLayer* layer) {
- MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.0: %p\n", l);
-
- if ( [NSThread isMainThread] == YES ) {
- [l releaseLayer];
- } else {
- [l performSelectorOnMainThread:@selector(releaseLayer) withObject:nil waitUntilDone:NO];
- }
-
- DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.X: %p\n", l);
- [pool release];
-}
-
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
index 8ac9f4700..d4d3ddad9 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
@@ -446,7 +446,7 @@ NSOpenGLPixelFormat* createPixelFormat(int* iattrs, int niattrs, int* ivalues) {
NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
// if(fmt == nil) { fallback to a [NSOpenGLView defaultPixelFormat] crashed (SIGSEGV) on 10.6.7/NV }
- DBG_PRINT("createPixelFormat.X: pfmt %p\n", fmt);
+ DBG_PRINT("\ncreatePixelFormat.X: pfmt %p\n", fmt);
[pool release];
return fmt;
@@ -501,9 +501,31 @@ NSView* getNSView(NSOpenGLContext* ctx) {
return view;
}
+static Bool lockViewIfReady(NSView *view) {
+ Bool viewReady = false;
+
+ if (view != nil) {
+ if ([view lockFocusIfCanDraw] == NO) {
+ DBG_PRINT("lockViewIfReady.1 [view lockFocusIfCanDraw] failed\n");
+ } else {
+ NSRect frame = [view frame];
+ if ((frame.size.width == 0) || (frame.size.height == 0)) {
+ [view unlockFocus];
+ DBG_PRINT("lockViewIfReady.2 view.frame size %dx%d\n", (int)frame.size.width, (int)frame.size.height);
+ } else {
+ DBG_PRINT("lockViewIfReady.X ready and locked\n");
+ viewReady = true;
+ }
+ }
+ } else {
+ DBG_PRINT("lockViewIfReady.3 nil view\n");
+ }
+ return viewReady;
+}
+
NSOpenGLContext* createContext(NSOpenGLContext* share,
NSView* view,
- Bool isBackingLayerView,
+ Bool incompleteView,
NSOpenGLPixelFormat* fmt,
Bool opaque,
int* viewNotReady)
@@ -512,56 +534,32 @@ NSOpenGLContext* createContext(NSOpenGLContext* share,
getRendererInfo();
- DBG_PRINT("createContext.0: share %p, view %p, isBackingLayer %d, pixfmt %p, opaque %d\n",
- share, view, (int)isBackingLayerView, fmt, opaque);
-
- if (view != NULL) {
- Bool viewReady = true;
+ DBG_PRINT("createContext.0: share %p, view %p, incompleteView %d, pixfmt %p, opaque %d\n",
+ share, view, (int)incompleteView, fmt, opaque);
- if(!isBackingLayerView) {
- if ([view lockFocusIfCanDraw] == NO) {
- DBG_PRINT("createContext.1 [view lockFocusIfCanDraw] failed\n");
- viewReady = false;
- }
- }
- if(viewReady) {
- NSRect frame = [view frame];
- if ((frame.size.width == 0) || (frame.size.height == 0)) {
- if(!isBackingLayerView) {
- [view unlockFocus];
- }
- DBG_PRINT("createContext.2 view.frame size %dx%d\n", (int)frame.size.width, (int)frame.size.height);
- viewReady = false;
- }
- }
+ Bool viewReadyAndLocked = incompleteView ? false : lockViewIfReady(view);
- if (!viewReady)
- {
- if (viewNotReady != NULL)
- {
- *viewNotReady = 1;
- }
+ if (nil != viewNotReady) {
+ *viewNotReady = 1;
+ }
- // the view is not ready yet
- DBG_PRINT("createContext.X: view not ready yet\n");
- [pool release];
- return NULL;
- }
+ if (nil != view && !incompleteView && !viewReadyAndLocked) {
+ DBG_PRINT("createContext.X: Assumed complete view not ready yet\n");
+ [pool release];
+ return NULL;
}
-
+
NSOpenGLContext* ctx = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:share];
- if (ctx != nil) {
- if (view != nil) {
+ if ( nil != ctx && nil != view ) {
if(!opaque) {
GLint zeroOpacity = 0;
[ctx setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity];
}
- [ctx setView:view];
- if(!isBackingLayerView) {
+ if( viewReadyAndLocked ) {
+ [ctx setView:view];
[view unlockFocus];
}
- }
}
DBG_PRINT("createContext.X: ctx: %p\n", ctx);
@@ -569,6 +567,32 @@ NSOpenGLContext* createContext(NSOpenGLContext* share,
return ctx;
}
+void setContextView(NSOpenGLContext* ctx, NSView* view) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ if ( nil != ctx ) {
+ if ( nil != view ) {
+ Bool viewReadyAndLocked = lockViewIfReady(view);
+ DBG_PRINT("setContextView.0: ctx %p, view %p: setView: %d\n", ctx, view, viewReadyAndLocked);
+ if( viewReadyAndLocked ) {
+ [ctx setView:view];
+ [view unlockFocus];
+ }
+ }
+ DBG_PRINT("setContextView.X\n");
+ }
+ [pool release];
+}
+
+void clearDrawable(NSOpenGLContext* ctx) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ if ( nil != ctx ) {
+ DBG_PRINT("clearDrawable.0: %p\n", ctx);
+ [ctx clearDrawable];
+ DBG_PRINT("clearDrawable.X\n");
+ }
+ [pool release];
+}
+
Bool makeCurrentContext(NSOpenGLContext* ctx) {
#if 0
// we issue the CGL Lock from Java upfront!
@@ -628,7 +652,12 @@ void setContextOpacity(NSOpenGLContext* ctx, int opacity) {
void updateContext(NSOpenGLContext* ctx) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [ctx update];
+ NSView *nsView = [ctx view];
+ if(NULL != nsView) {
+ DBG_PRINT("updateContext.0: ctx %p, ctx.view %p\n", ctx, nsView);
+ [ctx update];
+ DBG_PRINT("updateContext.X\n");
+ }
[pool release];
}
@@ -638,7 +667,10 @@ void copyContext(NSOpenGLContext* dest, NSOpenGLContext* src, int mask) {
void* updateContextRegister(NSOpenGLContext* ctx, NSView* view) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ DBG_PRINT("updateContextRegister.0: ctx %p, view %p\n", ctx, view);
ContextUpdater *contextUpdater = [[ContextUpdater alloc] initWithContext: ctx view: view];
+ DBG_PRINT("updateContextRegister.X: ctxupd %p\n", contextUpdater);
[pool release];
return contextUpdater;
}
@@ -658,44 +690,62 @@ void updateContextUnregister(void* updater) {
ContextUpdater *contextUpdater = (ContextUpdater *)updater;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT("updateContextUnregister.0: ctxupd %p\n", contextUpdater);
[contextUpdater release];
+ DBG_PRINT("updateContextUnregister.X\n");
[pool release];
}
NSOpenGLPixelBuffer* createPBuffer(int renderTarget, int internalFormat, int width, int height) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT("createPBuffer.0: renderTarget 0x%x, ifmt 0x%x, %dx%d: \n", renderTarget, internalFormat, width, height);
NSOpenGLPixelBuffer* pBuffer = [[NSOpenGLPixelBuffer alloc]
initWithTextureTarget:renderTarget
textureInternalFormat:internalFormat
textureMaxMipMapLevel:0
pixelsWide:width
pixelsHigh:height];
+ DBG_PRINT("createPBuffer.X: res %p\n", pBuffer);
[pool release];
return pBuffer;
}
Bool destroyPBuffer(NSOpenGLPixelBuffer* pBuffer) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT("destroyPBuffer.0: pbuffer %p\n", pBuffer);
[pBuffer release];
+ DBG_PRINT("destroyPBuffer.X\n");
[pool release];
return true;
}
void setContextPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT("setContextPBuffer.0: ctx %p, pbuffer %p\n", ctx, pBuffer);
[ctx setPixelBuffer: pBuffer
cubeMapFace: 0
mipMapLevel: 0
currentVirtualScreen: [ctx currentVirtualScreen]];
+ DBG_PRINT("setContextPBuffer.X\n");
[pool release];
}
void setContextTextureImageToPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer, GLenum colorBuffer) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT("setContextTextureImageToPBuffer.0: ctx %p, pbuffer %p, colorBuffer 0x%x\n", ctx, pBuffer, (int)colorBuffer);
[ctx setTextureImageToPixelBuffer: pBuffer colorBuffer: colorBuffer];
+ DBG_PRINT("setContextTextureImageToPBuffer.X\n");
[pool release];
}
+Bool isNSOpenGLPixelBuffer(uint64_t object) {
+ NSObject *nsObj = (NSObject*) (intptr_t) object;
+ DBG_PRINT("isNSOpenGLPixelBuffer.0: obj %p\n", object);
+ Bool res = [nsObj isKindOfClass:[NSOpenGLPixelBuffer class]];
+ DBG_PRINT("isNSOpenGLPixelBuffer.X: res %d\n", (int)res);
+ return res;
+}
+
#include <mach-o/dyld.h>
Bool imagesInitialized = false;
static char libGLStr[] = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib";
@@ -746,38 +796,3 @@ void resetGammaRamp() {
CGDisplayRestoreColorSyncSettings();
}
-/***
- * The following static functions are copied out of NEWT's OSX impl. <src/newt/native/MacWindow.m>
- * May need to push code to NativeWindow, to remove duplication.
- */
-static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx) {
- NSArray *screens = [NSScreen screens];
- if(screen_idx<0) screen_idx=0;
- if(screen_idx>=[screens count]) screen_idx=0;
- return (NSScreen *) [screens objectAtIndex: screen_idx];
-}
-static CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen) {
- // Mind: typedef uint32_t CGDirectDisplayID; - however, we assume it's 64bit on 64bit ?!
- NSDictionary * dict = [screen deviceDescription];
- NSNumber * val = (NSNumber *) [dict objectForKey: @"NSScreenNumber"];
- // [NSNumber integerValue] returns NSInteger which is 32 or 64 bit native size
- return (CGDirectDisplayID) [val integerValue];
-}
-static long GetDictionaryLong(CFDictionaryRef theDict, const void* key)
-{
- long value = 0;
- CFNumberRef numRef;
- numRef = (CFNumberRef)CFDictionaryGetValue(theDict, key);
- if (numRef != NULL)
- CFNumberGetValue(numRef, kCFNumberLongType, &value);
- return value;
-}
-#define CGDDGetModeRefreshRate(mode) GetDictionaryLong((mode), kCGDisplayRefreshRate)
-
-int getScreenRefreshRate(int scrn_idx) {
- NSScreen *screen = NewtScreen_getNSScreenByIndex(scrn_idx);
- CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
- CFDictionaryRef mode = CGDisplayCurrentMode(display);
- return CGDDGetModeRefreshRate(mode);
-}
-