diff options
author | Stefano Pigozzi <stefano.pigozzi@gmail.com> | 2014-07-08 08:17:15 +0200 |
---|---|---|
committer | Stefano Pigozzi <stefano.pigozzi@gmail.com> | 2014-07-08 21:06:57 +0200 |
commit | b5bbb49a1af7b0b167987f3b638d99baeb6a36bf (patch) | |
tree | 8d3b62912b9989c14a2e3f47d635ee46cee71262 /video/out/gl_cocoa.c | |
parent | 469ec23f852b97425c4d810ce030316c6efbdd35 (diff) | |
download | mpv-b5bbb49a1af7b0b167987f3b638d99baeb6a36bf.tar.bz2 mpv-b5bbb49a1af7b0b167987f3b638d99baeb6a36bf.tar.xz |
cocoa: move CGL context creation to gl_cocoa
This approach is similar to what other vo_opengl backends do. It can also be
used in the future to create another cocoa backend that renders offscreen
with IOSurfaces or FBOs.
Diffstat (limited to 'video/out/gl_cocoa.c')
-rw-r--r-- | video/out/gl_cocoa.c | 106 |
1 files changed, 98 insertions, 8 deletions
diff --git a/video/out/gl_cocoa.c b/video/out/gl_cocoa.c index 77f416135f..a32ba8f23d 100644 --- a/video/out/gl_cocoa.c +++ b/video/out/gl_cocoa.c @@ -19,9 +19,15 @@ * version 2.1 of the License, or (at your option) any later version. */ +#include <OpenGL/OpenGL.h> #include "cocoa_common.h" #include "gl_common.h" +struct cgl_context { + CGLPixelFormatObj pix; + CGLContextObj ctx; +}; + static void gl_clear(void *ctx) { struct GL *gl = ctx; @@ -29,22 +35,102 @@ static void gl_clear(void *ctx) gl->Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } -static bool config_window_cocoa(struct MPGLContext *ctx, int flags) +static int set_swap_interval(int enabled) +{ + CGLContextObj ctx = CGLGetCurrentContext(); + CGLError err = CGLSetParameter(ctx, kCGLCPSwapInterval, &enabled); + return (err == kCGLNoError) ? 0 : -1; +} + +static int cgl_color_size(struct MPGLContext *ctx) { - int rv = vo_cocoa_config_window(ctx->vo, flags, - ctx->requested_gl_version >= MPGL_VER(3, 0)); - if (rv != 0) + struct cgl_context *p = ctx->priv; + GLint value; + CGLDescribePixelFormat(p->pix, 0, kCGLPFAColorSize, &value); + switch (value) { + case 32: + case 24: + return 8; + case 16: + return 5; + default: + return 8; + } +} + +static bool create_gl_context(struct MPGLContext *ctx) +{ + struct cgl_context *p = ctx->priv; + CGLError err; + + CGLOpenGLProfile gl_vers_map[] = { + [2] = kCGLOGLPVersion_Legacy, + [3] = kCGLOGLPVersion_GL3_Core, + [4] = kCGLOGLPVersion_GL4_Core, + }; + + int gl_major = MPGL_VER_GET_MAJOR(ctx->requested_gl_version); + if (gl_major < 2 || gl_major >= MP_ARRAY_SIZE(gl_vers_map)) { + MP_FATAL(ctx->vo, "OpenGL major version %d not supported", gl_major); + return false; + } + + CGLPixelFormatAttribute attrs[] = { + kCGLPFAOpenGLProfile, + (CGLPixelFormatAttribute) gl_vers_map[gl_major], + kCGLPFADoubleBuffer, + kCGLPFAAccelerated, + #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8 + // leave this as the last entry of the array to not break the fallback + // code + kCGLPFASupportsAutomaticGraphicsSwitching, + #endif + 0 + }; + + GLint npix; + err = CGLChoosePixelFormat(attrs, &p->pix, &npix); + if (err == kCGLBadAttribute) { + // kCGLPFASupportsAutomaticGraphicsSwitching is probably not supported + // by the current hardware. Falling back to not using it. + MP_ERR(ctx->vo, "error creating CGL pixel format with automatic GPU " + "switching. falling back\n"); + attrs[MP_ARRAY_SIZE(attrs) - 2] = 0; + err = CGLChoosePixelFormat(attrs, &p->pix, &npix); + } + + if (err != kCGLNoError) { + MP_FATAL(ctx->vo, "error creating CGL pixel format: %s (%d)\n", + CGLErrorString(err), err); + } + + if ((err = CGLCreateContext(p->pix, 0, &p->ctx)) != kCGLNoError) { + MP_FATAL(ctx->vo, "error creating CGL context: %s (%d)\n", + CGLErrorString(err), err); return false; + } + vo_cocoa_create_nsgl_ctx(ctx->vo, p->ctx); + ctx->depth_r = ctx->depth_g = ctx->depth_b = cgl_color_size(ctx); mpgl_load_functions(ctx->gl, (void *)vo_cocoa_glgetaddr, NULL, ctx->vo->log); - ctx->depth_r = vo_cocoa_cgl_color_size(ctx->vo); - ctx->depth_g = vo_cocoa_cgl_color_size(ctx->vo); - ctx->depth_b = vo_cocoa_cgl_color_size(ctx->vo); + CGLReleasePixelFormat(p->pix); + + return true; +} + +static bool config_window_cocoa(struct MPGLContext *ctx, int flags) +{ + struct cgl_context *p = ctx->priv; + + if (p->ctx == NULL) + if (!create_gl_context(ctx)) + return false; if (!ctx->gl->SwapInterval) - ctx->gl->SwapInterval = vo_cocoa_swap_interval; + ctx->gl->SwapInterval = set_swap_interval; + vo_cocoa_config_window(ctx->vo, flags, p->ctx); vo_cocoa_register_gl_clear_callback(ctx->vo, ctx->gl, gl_clear); return true; @@ -52,6 +138,9 @@ static bool config_window_cocoa(struct MPGLContext *ctx, int flags) static void releaseGlContext_cocoa(MPGLContext *ctx) { + struct cgl_context *p = ctx->priv; + vo_cocoa_release_nsgl_ctx(ctx->vo); + CGLReleaseContext(p->ctx); } static void swapGlBuffers_cocoa(MPGLContext *ctx) @@ -66,6 +155,7 @@ static void set_current_cocoa(MPGLContext *ctx, bool current) void mpgl_set_backend_cocoa(MPGLContext *ctx) { + ctx->priv = talloc_zero(ctx, struct cgl_context); ctx->config_window = config_window_cocoa; ctx->releaseGlContext = releaseGlContext_cocoa; ctx->swapGlBuffers = swapGlBuffers_cocoa; |