this repo has no description
at fixPythonPipStalling 417 lines 10 kB view raw
1#include <stdlib.h> 2#include <stdio.h> // for fprintf(stderr, "unimplemented") 3 4#include <pthread.h> 5 6#include <OpenGL/OpenGL.h> 7#include <OpenGL/CGLInternal.h> 8#include <CoreFoundation/CFDictionary.h> 9#include <pthread.h> 10 11// Try to get the right (generic) type definitions. 12// In particular, we really want EGLNativeDisplayType to be void *, 13// not int as it is if __APPLE__ is defined. 14#undef APPLE 15#undef __APPLE__ 16 17#define __unix__ 18#define EGL_NO_X11 19 20#include <EGL/egl.h> 21 22#define APPLE 23#define __APPLE__ 24 25static EGLDisplay display; 26 27static EGLConfig config; 28static int num_config; 29 30static EGLint const attribute_list[] = { 31 EGL_RED_SIZE, 1, 32 EGL_GREEN_SIZE, 1, 33 EGL_BLUE_SIZE, 1, 34 EGL_NONE 35}; 36 37struct _CGLDisplay 38{ 39 EGLDisplay display; 40 EGLConfig config; 41 int num_config; 42}; 43 44static CFMutableDictionaryRef g_displays; 45static pthread_mutex_t g_displaysMutex = PTHREAD_MUTEX_INITIALIZER; 46 47struct _CGLContextObj { 48 GLuint retain_count; 49 pthread_mutex_t lock; 50 EGLContext egl_context; 51 EGLSurface egl_surface; 52 // EGL has no function for getting the current swap interval, 53 // so we need to save the last set value. The default is 1. 54 int swap_interval; 55}; 56 57struct _CGLPixelFormatObj { 58 GLuint retain_count; 59 CGLPixelFormatAttribute *attributes; 60}; 61 62static inline int attribute_has_argument(CGLPixelFormatAttribute attr) { 63 switch (attr) { 64 case kCGLPFAAuxBuffers: 65 case kCGLPFAColorSize: 66 case kCGLPFAAlphaSize: 67 case kCGLPFADepthSize: 68 case kCGLPFAStencilSize: 69 case kCGLPFAAccumSize: 70 case kCGLPFARendererID: 71 case kCGLPFADisplayMask: 72 return 1; 73 default: 74 return 0; 75 } 76} 77 78__attribute__((constructor)) 79static void _CGLInitialize(void) 80{ 81 g_displays = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); 82} 83 84static int attributes_count(const CGLPixelFormatAttribute *attrs) { 85 int result; 86 for (result = 0; attrs[result] != 0; result++) { 87 if (attribute_has_argument(attrs[result])) { 88 result++; 89 } 90 } 91 return result; 92} 93 94CGLError CGLRegisterNativeDisplay(void *native_display) { 95 96 display = eglGetDisplay(native_display); 97 98 if (display == EGL_NO_DISPLAY) { 99 return kCGLBadConnection; 100 } 101 102 eglInitialize(display, NULL, NULL); 103 eglChooseConfig(display, attribute_list, &config, 1, &num_config); 104 105 eglBindAPI(EGL_OPENGL_API); 106 107 return kCGLNoError; 108} 109 110static struct _CGLDisplay* getCGLDisplay(CGSConnectionID cid) 111{ 112 struct _CGLDisplay* rv; 113 114 pthread_mutex_lock(&g_displaysMutex); 115 rv = (struct _CGLDisplay*) CFDictionaryGetValue(g_displays, (const void*)(unsigned long) cid); 116 pthread_mutex_unlock(&g_displaysMutex); 117 118 if (!rv) 119 { 120 EGLDisplay disp = eglGetDisplay(_CGSNativeDisplay(cid)); 121 if (disp == EGL_NO_DISPLAY) 122 return NULL; 123 124 rv = (struct _CGLDisplay*) malloc(sizeof(*rv)); 125 rv->display = disp; 126 127 eglInitialize(rv->display, NULL, NULL); 128 eglChooseConfig(rv->display, attribute_list, &rv->config, 1, &rv->num_config); 129 130 eglBindAPI(EGL_OPENGL_API); 131 132 pthread_mutex_lock(&g_displaysMutex); 133 CFDictionaryAddValue(g_displays, (const void*)(unsigned long) cid, rv); 134 pthread_mutex_unlock(&g_displaysMutex); 135 } 136 137 return rv; 138} 139 140CGLError CGLSetSurface(CGLContextObj gl, CGSConnectionID cid, CGSWindowID wid, CGSSurfaceID sid) 141{ 142 struct _CGLDisplay* disp = getCGLDisplay(cid); 143 if (!disp) 144 return kCGLBadConnection; 145 146 EGLNativeWindowType window; 147 if (sid) 148 window = (EGLNativeWindowType) _CGSNativeWindowForSurfaceID(cid, wid, sid); 149 else 150 window = (EGLNativeWindowType) _CGSNativeWindowForID(cid, wid); 151 152 if (!window) 153 return kCGLBadWindow; 154 155 gl->egl_surface = eglCreateWindowSurface(disp->display, disp->config, window, NULL); 156 if (gl->egl_surface == EGL_NO_SURFACE) 157 return kCGLBadState; 158 return kCGLNoError; 159} 160 161CGLWindowRef CGLGetWindow(void *native_window) { 162 163 EGLNativeWindowType window = (EGLNativeWindowType) native_window; 164 EGLSurface surface = eglCreateWindowSurface(display, config, window, NULL); 165 166 if (surface == EGL_NO_SURFACE) { 167 return NULL; 168 } 169 170 return (CGLWindowRef) surface; 171} 172 173CGL_EXPORT void CGLDestroyWindow(CGLWindowRef window) { 174 eglDestroySurface(display, (EGLSurface) window); 175} 176 177CGL_EXPORT CGLError CGLContextMakeCurrentAndAttachToWindow(CGLContextObj context, CGLWindowRef window) { 178 if (!context) 179 return kCGLBadContext; 180 context->egl_surface = (EGLSurface) window; 181 return CGLSetCurrentContext(context); 182} 183 184static pthread_key_t current_context_key; 185 186static void make_key() { 187 pthread_key_create(&current_context_key, NULL); 188} 189 190static pthread_key_t get_current_context_key() { 191 static pthread_once_t key_once = PTHREAD_ONCE_INIT; 192 pthread_once(&key_once, make_key); 193 return current_context_key; 194} 195 196CGLContextObj CGLGetCurrentContext(void) { 197 pthread_key_t key = get_current_context_key(); 198 return pthread_getspecific(key); 199} 200 201CGLError CGLSetCurrentContext(CGLContextObj context) { 202 pthread_key_t key = get_current_context_key(); 203 pthread_setspecific(key, context); 204 205 if (context != NULL) { 206 EGLSurface surface = context->egl_surface; 207 eglMakeCurrent(display, surface, surface, context->egl_context); 208 } else { 209 eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 210 } 211 212 return kCGLNoError; // FIXME 213} 214 215CGLError CGLChoosePixelFormat( 216 const CGLPixelFormatAttribute *attrs, 217 CGLPixelFormatObj *result, 218 GLint *number_of_screens 219) { 220 CGLPixelFormatObj format = malloc(sizeof(struct _CGLPixelFormatObj)); 221 int count = attributes_count(attrs); 222 223 format->retain_count = 1; 224 format->attributes = malloc(sizeof(CGLPixelFormatAttribute) * count); 225 for (int i = 0; i < count; i++) { 226 format->attributes[i] = attrs[i]; 227 } 228 229 *result = format; 230 *number_of_screens = 1; 231 232 return kCGLNoError; 233} 234 235CGLError CGLDescribePixelFormat( 236 CGLPixelFormatObj format, 237 GLint sreen_num, 238 CGLPixelFormatAttribute attr, 239 GLint *value 240) { 241 for (int i = 0; format->attributes[i] != 0; i++) { 242 int has_arg = attribute_has_argument(format->attributes[i]); 243 244 if (format->attributes[i] == attr) { 245 if (has_arg) { 246 *value = format->attributes[i + 1]; 247 } else { 248 *value = 1; 249 } 250 return kCGLNoError; 251 } 252 253 if (has_arg) { 254 i++; 255 } 256 } 257 258 *value = 0; 259 return kCGLNoError; 260} 261 262CGLPixelFormatObj CGLRetainPixelFormat(CGLPixelFormatObj format) { 263 if (format == NULL) { 264 return NULL; 265 } 266 267 format->retain_count++; 268 return format; 269} 270 271void CGLReleasePixelFormat(CGLPixelFormatObj format) { 272 if (format == NULL) { 273 return; 274 } 275 276 format->retain_count--; 277 278 if (format->retain_count == 0) { 279 free(format->attributes); 280 free(format); 281 } 282} 283 284CGLError CGLDestroyPixelFormat(CGLPixelFormatObj pixelFormat) { 285 CGLReleasePixelFormat(pixelFormat); 286 return kCGLNoError; 287} 288 289GLuint CGLGetPixelFormatRetainCount(CGLPixelFormatObj pixelFormat) { 290 return pixelFormat->retain_count; 291} 292 293CGLError CGLCreateContext(CGLPixelFormatObj pixelFormat, CGLContextObj share, CGLContextObj *resultp) { 294 295 EGLContext egl_share = EGL_NO_CONTEXT; 296 if (share != NULL) { 297 egl_share = share->egl_context; 298 } 299 EGLContext egl_context = eglCreateContext(display, config, egl_share, NULL); 300 301 if (egl_context == EGL_NO_CONTEXT) { 302 return kCGLBadContext; 303 } 304 305 CGLContextObj context = malloc(sizeof(struct _CGLContextObj)); 306 307 context->retain_count = 1; 308 pthread_mutex_init(&(context->lock), NULL); 309 context->egl_context = egl_context; 310 context->egl_surface = NULL; 311 context->swap_interval = 1; 312 313 *resultp = context; 314 315 return kCGLNoError; 316} 317 318CGLContextObj CGLRetainContext(CGLContextObj context) { 319 if (context == NULL) { 320 return NULL; 321 } 322 323 context->retain_count++; 324 return context; 325} 326 327void CGLReleaseContext(CGLContextObj context) { 328 if (context == NULL) { 329 return; 330 } 331 332 context->retain_count--; 333 334 if (context->retain_count != 0) { 335 return; 336 } 337 338 if (CGLGetCurrentContext() == context) { 339 CGLSetCurrentContext(NULL); 340 } 341 342 pthread_mutex_destroy(&(context->lock)); 343 344 eglDestroyContext(display, context->egl_context); 345 346 free(context); 347} 348 349GLuint CGLGetContextRetainCount(CGLContextObj context) { 350 if (context == NULL) { 351 return 0; 352 } 353 354 return context->retain_count; 355} 356 357CGLError CGLDestroyContext(CGLContextObj context) { 358 CGLReleaseContext(context); 359 360 return kCGLNoError; 361} 362 363CGLError CGLLockContext(CGLContextObj context) { 364 pthread_mutex_lock(&(context->lock)); 365 return kCGLNoError; 366} 367 368CGLError CGLUnlockContext(CGLContextObj context) { 369 pthread_mutex_unlock(&(context->lock)); 370 return kCGLNoError; 371} 372 373CGLError CGLFlushDrawable(CGLContextObj context) { 374 eglSwapBuffers(display,context->egl_surface); 375 return kCGLNoError; 376} 377 378CGLError CGLSetParameter(CGLContextObj context, CGLContextParameter parameter, const GLint *value) { 379 if (!value) 380 return kCGLBadAddress; 381 382 if (parameter == kCGLCPSwapInterval) 383 { 384 GLint v = *value; 385 EGLBoolean success = eglSwapInterval(display, v); 386 if (success) 387 context->swap_interval = v; 388 return success ? kCGLNoError : kCGLBadValue; 389 } 390 fprintf(stderr, "CGLSetParameter unimplemented for parameter %d\n", parameter); 391 return kCGLNoError; 392} 393 394CGLError CGLGetParameter(CGLContextObj context, CGLContextParameter parameter, GLint *value) { 395 if (!value) 396 return kCGLBadAddress; 397 398 if (parameter == kCGLCPSwapInterval) 399 { 400 *value = context->swap_interval; 401 return kCGLNoError; 402 } 403 fprintf(stderr, "CGLGetParameter unimplemented for parameter %d\n", parameter); 404 return kCGLNoError; 405} 406 407CGLError CGLDescribeRenderer(CGLRendererInfoObj rend, long rend_num, CGLRendererProperty prop, long *value) { 408 return kCGLNoError; 409} 410 411CGLError CGLQueryRendererInfo(unsigned long display_mask, CGLRendererInfoObj *rend, long *nrend) { 412 return kCGLNoError; 413} 414 415CGLError CGLDestroyRendererInfo(CGLRendererInfoObj rend) { 416 return kCGLNoError; 417}