diff --git a/src/external/cocotron b/src/external/cocotron index 73e689b9e..3596c05f2 160000 --- a/src/external/cocotron +++ b/src/external/cocotron @@ -1 +1 @@ -Subproject commit 73e689b9e037fe8f8b47bf785982120854d38e21 +Subproject commit 3596c05f26ad35edec252e219b878bc80a17d493 diff --git a/src/frameworks/OpenGL/CMakeLists.txt b/src/frameworks/OpenGL/CMakeLists.txt index 0766cd116..40c6e6a0c 100644 --- a/src/frameworks/OpenGL/CMakeLists.txt +++ b/src/frameworks/OpenGL/CMakeLists.txt @@ -23,6 +23,8 @@ add_framework(OpenGL GL GLU EGL + CoreFoundation + CoreGraphics ) set_property(TARGET OpenGL APPEND_STRING PROPERTY LINK_FLAGS diff --git a/src/frameworks/OpenGL/OpenGL.c b/src/frameworks/OpenGL/OpenGL.c index 0b794c8aa..b10cdd0f6 100644 --- a/src/frameworks/OpenGL/OpenGL.c +++ b/src/frameworks/OpenGL/OpenGL.c @@ -5,6 +5,7 @@ #include #include +#include // Try to get the right (generic) type definitions. // In particular, we really want EGLNativeDisplayType to be void *, @@ -32,6 +33,15 @@ static EGLint const attribute_list[] = { EGL_NONE }; +struct _CGLDisplay +{ + EGLDisplay display; + EGLConfig config; + int num_config; +}; + +static CFMutableDictionaryRef g_displays; + struct _CGLContextObj { GLuint retain_count; pthread_mutex_t lock; @@ -63,6 +73,12 @@ static inline int attribute_has_argument(CGLPixelFormatAttribute attr) { } } +__attribute__((constructor)) +static void _CGLInitialize(void) +{ + g_displays = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); +} + static int attributes_count(const CGLPixelFormatAttribute *attrs) { int result; for (result = 0; attrs[result] != 0; result++) { @@ -89,6 +105,72 @@ CGLError CGLRegisterNativeDisplay(void *native_display) { return kCGLNoError; } +static struct _CGLDisplay* getCGLDisplay(CGSConnectionID cid) +{ + struct _CGLDisplay* rv = (struct _CGLDisplay*) CFDictionaryGetValue(g_displays, (const void*)(unsigned long) cid); + + if (!rv) + { + EGLDisplay disp = eglGetDisplay(_CGSNativeDisplay(cid)); + if (disp == EGL_NO_DISPLAY) + return NULL; + + rv = (struct _CGLDisplay*) malloc(sizeof(*rv)); + rv->display = disp; + + eglInitialize(rv->display, NULL, NULL); + eglChooseConfig(rv->display, attribute_list, &rv->config, 1, &rv->num_config); + + eglBindAPI(EGL_OPENGL_API); + + CFDictionaryAddValue(g_displays, (const void*)(unsigned long) cid, rv); + } + + return rv; +} + +CGLError CGLSetSurface(CGLContextObj gl, CGSConnectionID cid, CGSWindowID wid, CGSSurfaceID sid) +{ + struct _CGLDisplay* disp = getCGLDisplay(cid); + if (!disp) + return kCGLBadConnection; + + EGLNativeWindowType window = (EGLNativeWindowType) _CGSNativeWindowForSurfaceID(cid, wid, sid); + if (!window) + return kCGLBadWindow; + + gl->egl_surface = eglCreateWindowSurface(disp->display, disp->config, window, NULL); + if (gl->egl_surface == EGL_NO_SURFACE) + return kCGLBadState; + return kCGLNoError; +} + +CGLContextObj CGWindowContextCreate(CGSConnectionID cid, CGSWindowID wid, CFDictionaryRef options) +{ + struct _CGLDisplay* disp = getCGLDisplay(cid); + if (!disp) + return NULL; + + EGLNativeWindowType window = (EGLNativeWindowType) _CGSNativeWindowForID(cid, wid); + if (!window) + return NULL; + + CGLContextObj context; + CGLError err = CGLCreateContext(NULL, NULL, &context); + + if (err != kCGLNoError) + return NULL; + + context->egl_surface = eglCreateWindowSurface(disp->display, disp->config, window, NULL); + if (context->egl_surface == EGL_NO_SURFACE) + { + CGLReleaseContext(context); + return NULL; + } + + return context; +} + CGLWindowRef CGLGetWindow(void *native_window) { EGLNativeWindowType window = (EGLNativeWindowType) native_window; @@ -246,11 +328,6 @@ CGLError CGLCreateContext(CGLPixelFormatObj pixelFormat, CGLContextObj share, CG return kCGLNoError; } -CGLError CGLSwapBuffers(CGLWindowRef window) { - eglSwapBuffers(display, window); - return kCGLNoError; -} - CGLContextObj CGLRetainContext(CGLContextObj context) { if (context == NULL) { return NULL; diff --git a/src/frameworks/OpenGL/include/OpenGL/CGLInternal.h b/src/frameworks/OpenGL/include/OpenGL/CGLInternal.h index fa0bd3d77..1d0b10e65 100644 --- a/src/frameworks/OpenGL/include/OpenGL/CGLInternal.h +++ b/src/frameworks/OpenGL/include/OpenGL/CGLInternal.h @@ -2,6 +2,8 @@ #define _CGL_INTERNAL_H_ #include +#include +#include #ifdef __cplusplus extern "C" { @@ -15,7 +17,8 @@ CGL_EXPORT CGLWindowRef CGLGetWindow(void *native_window); CGL_EXPORT void CGLDestroyWindow(CGLWindowRef window); CGL_EXPORT CGLError CGLContextMakeCurrentAndAttachToWindow(CGLContextObj context, CGLWindowRef window); -CGL_EXPORT CGLError CGLSwapBuffers(CGLWindowRef window); +CGLError CGLSetSurface(CGLContextObj gl, CGSConnectionID cid, CGSWindowID wid, CGSSurfaceID sid); +CGLContextObj CGWindowContextCreate(CGSConnectionID cid, CGSWindowID wid, CFDictionaryRef options); #ifdef __cplusplus }