@interface MyNSOpenGLLayer: NSOpenGLLayer { @protected NSOpenGLContext* ctxShared; NSView* view; NSOpenGLPixelFormat* fmt; @public volatile BOOL shallDraw; } - (id) initWithContext: (NSOpenGLContext*) ctx pixelFormat: (NSOpenGLPixelFormat*) pfmt view: (NSView*) v opaque: (Bool) opaque; @end @implementation MyNSOpenGLLayer - (id) initWithContext: (NSOpenGLContext*) _ctx pixelFormat: (NSOpenGLPixelFormat*) _fmt view: (NSView*) _view opaque: (Bool) opaque { self = [super init]; ctxShared = _ctx; [ctxShared retain]; fmt = _fmt; [fmt retain]; view = _view; [view retain]; [self setView: view]; [view setLayer: self]; [view setWantsLayer: YES]; [self setAsynchronous: NO]; // [self setAsynchronous: YES]; // FIXME: JAU [self setNeedsDisplayOnBoundsChange: NO]; [self setOpaque: opaque ? YES : NO]; shallDraw = NO; textureID = 0; DBG_PRINT("MyNSOpenGLLayer::init %p, ctx %p, pfmt %p, view %p, opaque %d\n", self, ctx, fmt, view, opaque); return self; } - (void)dealloc { [fmt release]; [ctxShared release]; [view release]; DBG_PRINT("MyNSOpenGLLayer::dealloc %p\n", self); [super dealloc]; } - (void) setOpenGLContext: (NSOpenGLContext*) _ctx { DBG_PRINT("MyNSOpenGLLayer::setOpenGLContext: %p %p -> %p\n", self, [self openGLContext], _ctx); [super setOpenGLContext: _ctx]; } - (void) setOpenGLPixelFormat: (NSOpenGLPixelFormat*) _fmt { DBG_PRINT("MyNSOpenGLLayer::setOpenGLPixelFormat %p %p -> %p\n", self, fmt, _fmt); [super setOpenGLPixelFormat: fmt]; } - (NSOpenGLPixelFormat *) openGLPixelFormat { return fmt; } - (void) setView: (NSView*) v { DBG_PRINT("MyNSOpenGLLayer::setView %p %p -> %p (ignored/propagated)\n", self, view, v); [super setView: view]; // propagate } - (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask { DBG_PRINT("MyNSOpenGLLayer::openGLPixelFormatForDisplayMask %p %d -> %p\n", self, mask, fmt); return fmt; } - (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat { NSOpenGLContext* ctx = NULL; if(NULL == ctx) { int viewNotReady[] = { 0 }; ctx = createContext(ctxShared, view, true, fmt, [self isOpaque], viewNotReady); } DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat %p, fmt %p/%p, view %p, shared %p -> %p\n", self, fmt, pixelFormat, view, ctxShared, ctx); return ctx; } - (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp { DBG_PRINT("MyNSOpenGLLayer::canDrawInOpenGLContext %p: %d\n", self, self->shallDraw); return self->shallDraw; } - (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp { self->shallDraw = NO; DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p, ctx %p, pfmt %p\n", self, context, pixelFormat); [super drawInOpenGLContext: context pixelFormat: pixelFormat forLayerTime: timeInterval displayTime: timeStamp]; } @end NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSView* view, Bool opaque) { return [[MyNSOpenGLLayer alloc] initWithContext:ctx pixelFormat: fmt view: view opaque: opaque]; } void setNSOpenGLLayerNeedsDisplay(NSOpenGLLayer* layer) { MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; l->shallDraw = YES; [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:YES]; // NSView* view = [l view]; // [view setNeedsDisplay: YES]; // FIXME: JAU // [view performSelectorOnMainThread:@selector(setNeedsDisplay:) withObject:YES waitUntilDone:YES]; // [view performSelectorOnMainThread:@selector(display) withObject:nil waitUntilDone:YES]; DBG_PRINT("MyNSOpenGLLayer::setNSOpenGLLayerNeedsDisplay %p\n", l); [pool release]; } void releaseNSOpenGLLayer(NSOpenGLLayer* l) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; [l release]; [pool release]; }