Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Mac: Support for multiple contexts per SDL_Window.
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgenpt committed Aug 7, 2013
1 parent 879053c commit 6a505b3
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 20 deletions.
2 changes: 2 additions & 0 deletions src/video/cocoa/SDL_cocoaopengl.h
Expand Up @@ -35,12 +35,14 @@ struct SDL_GLDriverData

@interface SDLOpenGLContext : NSOpenGLContext {
SDL_atomic_t dirty;
SDL_Window *window;
}

- (id)initWithFormat:(NSOpenGLPixelFormat *)format
shareContext:(NSOpenGLContext *)share;
- (void)scheduleUpdate;
- (void)updateIfNeeded;
- (void)setWindow:(SDL_Window *)window;

@end

Expand Down
57 changes: 44 additions & 13 deletions src/video/cocoa/SDL_cocoaopengl.m
Expand Up @@ -51,8 +51,12 @@ @implementation SDLOpenGLContext : NSOpenGLContext
- (id)initWithFormat:(NSOpenGLPixelFormat *)format
shareContext:(NSOpenGLContext *)share
{
SDL_AtomicSet(&self->dirty, 0);
return [super initWithFormat:format shareContext:share];
self = [super initWithFormat:format shareContext:share];
if (self) {
SDL_AtomicSet(&self->dirty, 0);
self->window = NULL;
}
return self;
}

- (void)scheduleUpdate
Expand All @@ -78,6 +82,40 @@ - (void)update
[self updateIfNeeded];
}

/* Updates the drawable for the contexts and manages related state. */
- (void)setWindow:(SDL_Window *)newWindow
{
if (self->window) {
SDL_WindowData *oldwindowdata = (SDL_WindowData *)self->window->driverdata;

/* Make sure to remove us from the old window's context list, or we'll get scheduled updates from it too. */
NSMutableArray *contexts = oldwindowdata->nscontexts;
@synchronized (contexts) {
[contexts removeObject:self];
}
}

self->window = newWindow;

if (newWindow) {
SDL_WindowData *windowdata = (SDL_WindowData *)newWindow->driverdata;

/* Now sign up for scheduled updates for the new window. */
NSMutableArray *contexts = windowdata->nscontexts;
@synchronized (contexts) {
[contexts addObject:self];
}

if ([self view] != [windowdata->nswindow contentView]) {
[self setView:[windowdata->nswindow contentView]];
[self scheduleUpdate];
}
} else {
[self clearDrawable];
[self scheduleUpdate];
}
}

@end


Expand Down Expand Up @@ -244,14 +282,8 @@ - (void)update
pool = [[NSAutoreleasePool alloc] init];

if (context) {
SDL_WindowData *windowdata = (SDL_WindowData *)window->driverdata;
SDLOpenGLContext *nscontext = (SDLOpenGLContext *)context;
windowdata->nscontext = nscontext;
if ([nscontext view] != [windowdata->nswindow contentView]) {
[nscontext setView:[windowdata->nswindow contentView]];
[nscontext scheduleUpdate];
}

[nscontext setWindow:window];
[nscontext updateIfNeeded];
[nscontext makeCurrentContext];
} else {
Expand Down Expand Up @@ -309,11 +341,10 @@ - (void)update
Cocoa_GL_SwapWindow(_THIS, SDL_Window * window)
{
NSAutoreleasePool *pool;
SDL_WindowData *windowdata = (SDL_WindowData *)window->driverdata;
SDLOpenGLContext *nscontext = windowdata->nscontext;

pool = [[NSAutoreleasePool alloc] init];

SDLOpenGLContext* nscontext = (NSOpenGLContext*)SDL_GL_GetCurrentContext();
[nscontext flushBuffer];
[nscontext updateIfNeeded];

Expand All @@ -324,11 +355,11 @@ - (void)update
Cocoa_GL_DeleteContext(_THIS, SDL_GLContext context)
{
NSAutoreleasePool *pool;
NSOpenGLContext *nscontext = (NSOpenGLContext *)context;
SDLOpenGLContext *nscontext = (SDLOpenGLContext *)context;

pool = [[NSAutoreleasePool alloc] init];

[nscontext clearDrawable];
[nscontext setWindow:NULL];
[nscontext release];

[pool release];
Expand Down
2 changes: 1 addition & 1 deletion src/video/cocoa/SDL_cocoawindow.h
Expand Up @@ -83,7 +83,7 @@ struct SDL_WindowData
{
SDL_Window *window;
NSWindow *nswindow;
SDLOpenGLContext *nscontext;
NSMutableArray *nscontexts;
SDL_bool created;
Cocoa_WindowListener *listener;
struct SDL_VideoData *videodata;
Expand Down
31 changes: 25 additions & 6 deletions src/video/cocoa/SDL_cocoawindow.m
Expand Up @@ -42,6 +42,16 @@ static __inline__ void ConvertNSRect(NSRect *r)
r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height;
}

static void ScheduleContextUpdates(SDL_WindowData *data)
{
NSMutableArray *contexts = data->nscontexts;
@synchronized (contexts) {
for (SDLOpenGLContext *context in contexts) {
[context scheduleUpdate];
}
}
}

@implementation Cocoa_WindowListener

- (void)listen:(SDL_WindowData *)data
Expand Down Expand Up @@ -211,7 +221,7 @@ - (void)windowDidMove:(NSNotification *)aNotification
x = (int)rect.origin.x;
y = (int)rect.origin.y;

[_data->nscontext scheduleUpdate];
ScheduleContextUpdates(_data);

SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y);
}
Expand All @@ -228,7 +238,7 @@ - (void)windowDidResize:(NSNotification *)aNotification
if (SDL_IsShapedWindow(_data->window))
Cocoa_ResizeWindowShape(_data->window);

[_data->nscontext scheduleUpdate];
ScheduleContextUpdates(_data);

/* The window can move during a resize event, such as when maximizing
or resizing from a corner */
Expand Down Expand Up @@ -605,6 +615,7 @@ - (void)resetCursorRects
data->nswindow = nswindow;
data->created = created;
data->videodata = videodata;
data->nscontexts = [[NSMutableArray alloc] init];

pool = [[NSAutoreleasePool alloc] init];

Expand Down Expand Up @@ -799,7 +810,7 @@ - (void)resetCursorRects
[nswindow setFrameOrigin:rect.origin];
s_moveHack = moveHack;

[windata->nscontext scheduleUpdate];
ScheduleContextUpdates(windata);

[pool release];
}
Expand All @@ -816,7 +827,7 @@ - (void)resetCursorRects
size.height = window->h;
[nswindow setContentSize:size];

[windata->nscontext scheduleUpdate];
ScheduleContextUpdates(windata);

[pool release];
}
Expand Down Expand Up @@ -903,7 +914,7 @@ - (void)resetCursorRects

[nswindow zoom:nil];

[windata->nscontext scheduleUpdate];
ScheduleContextUpdates(windata);

[pool release];
}
Expand Down Expand Up @@ -1040,7 +1051,7 @@ - (void)resetCursorRects
[nswindow makeKeyAndOrderFront:nil];
[data->listener resumeVisibleObservation];

[data->nscontext scheduleUpdate];
ScheduleContextUpdates(data);

[pool release];
}
Expand Down Expand Up @@ -1133,6 +1144,14 @@ - (void)resetCursorRects
if (data->created) {
[data->nswindow close];
}

NSArray *contexts = [[data->nscontexts copy] autorelease];
for (SDLOpenGLContext *context in contexts) {
/* Calling setWindow:NULL causes the context to remove itself from the context list. */
[context setWindow:NULL];
}
[data->nscontexts release];

SDL_free(data);
}
[pool release];
Expand Down

0 comments on commit 6a505b3

Please sign in to comment.