Add per window GL context for Cocoa libobs-opengl implementation

This fixes some problems with multiple swap chains (e.g. flickering
between the render views)
This commit is contained in:
Palana 2014-03-24 17:41:28 +01:00
parent 7707773f7c
commit f8b90a5c8f

View File

@ -26,6 +26,7 @@
struct gl_windowinfo {
NSOpenGLContext *context;
NSView *view;
};
@ -34,6 +35,8 @@ struct gl_platform {
struct gs_swap_chain swap;
};
static NSOpenGLContext *plat_context;
static NSOpenGLContext *gl_context_create(struct gs_init_data *info)
{
unsigned attrib_count = 0;
@ -84,7 +87,8 @@ static NSOpenGLContext *gl_context_create(struct gs_init_data *info)
}
NSOpenGLContext *context;
context = [[NSOpenGLContext alloc] initWithFormat:pf shareContext:nil];
context = [[NSOpenGLContext alloc] initWithFormat:pf
shareContext:plat_context];
[pf release];
if(!context) {
blog(LOG_ERROR, "Failed to create context");
@ -99,14 +103,22 @@ static NSOpenGLContext *gl_context_create(struct gs_init_data *info)
static bool gl_init_default_swap(struct gl_platform *plat, device_t dev,
struct gs_init_data *info)
{
if(!(plat->context = gl_context_create(info)))
plat_context = nil;
struct gl_windowinfo *wi = gl_windowinfo_create(info);
if (!wi)
return false;
plat->swap.device = dev;
plat->swap.info = *info;
plat->swap.wi = gl_windowinfo_create(info);
plat->swap.wi = wi;
return plat->swap.wi != NULL;
plat->context = wi->context;
plat_context = plat->context;
return true;
}
struct gl_platform *gl_platform_create(device_t device,
@ -143,8 +155,6 @@ void gl_platform_destroy(struct gl_platform *platform)
if(!platform)
return;
[platform->context release];
platform->context = nil;
gl_windowinfo_destroy(platform->swap.wi);
bfree(platform);
@ -158,9 +168,9 @@ struct gl_windowinfo *gl_windowinfo_create(struct gs_init_data *info)
if(!info->window.view)
return NULL;
struct gl_windowinfo *wi = bmalloc(sizeof(struct gl_windowinfo));
memset(wi, 0, sizeof(struct gl_windowinfo));
struct gl_windowinfo *wi = bzalloc(sizeof(struct gl_windowinfo));
wi->context = gl_context_create(info);
wi->view = info->window.view;
return wi;
@ -171,25 +181,34 @@ void gl_windowinfo_destroy(struct gl_windowinfo *wi)
if(!wi)
return;
[wi->context release];
wi->context = nil;
wi->view = nil;
bfree(wi);
}
static inline NSOpenGLContext *current_context(device_t device)
{
if (device->cur_swap)
return device->cur_swap->wi->context;
return device->plat->context;
}
void gl_update(device_t device)
{
[device->plat->context update];
[current_context(device) update];
}
void device_entercontext(device_t device)
{
CGLLockContext([device->plat->context CGLContextObj]);
[device->plat->context makeCurrentContext];
[current_context(device) makeCurrentContext];
}
void device_leavecontext(device_t device)
{
UNUSED_PARAMETER(device);
[NSOpenGLContext clearCurrentContext];
CGLUnlockContext([device->plat->context CGLContextObj]);
}
void device_load_swapchain(device_t device, swapchain_t swap)
@ -201,11 +220,12 @@ void device_load_swapchain(device_t device, swapchain_t swap)
return;
device->cur_swap = swap;
[current_context(device) makeCurrentContext];
}
void device_present(device_t device)
{
[device->plat->context flushBuffer];
[current_context(device) flushBuffer];
}
void gl_getclientsize(struct gs_swap_chain *swap, uint32_t *width,