1 #include "HalideRuntime.h"
2 #include "printer.h"
3 #include "scoped_mutex_lock.h"
4 
5 #define USE_AGL 0
6 #if USE_AGL
7 extern "C" void *aglChoosePixelFormat(void *, int, const int *);
8 extern "C" void *aglCreateContext(void *, void *);
9 extern "C" int aglGetError();
10 extern "C" void aglDestroyPixelFormat(void *);
11 extern "C" unsigned char aglSetCurrentContext(void *);
12 #endif
13 
14 #if !USE_AGL
15 namespace Halide {
16 namespace Runtime {
17 namespace Internal {
18 namespace OpenGL {
19 
20 WEAK halide_mutex cgl_functions_mutex;
21 WEAK bool cgl_initialized = false;
22 WEAK int (*CGLChoosePixelFormat)(int *attributes, void **pixel_format_result, int *num_formats);
23 WEAK int (*CGLCreateContext)(void *pixel_format, void *share_context, void **context_Result);
24 WEAK int (*CGLDestroyPixelFormat)(void *);
25 WEAK int (*CGLSetCurrentContext)(void *);
26 
27 }  // namespace OpenGL
28 }  // namespace Internal
29 }  // namespace Runtime
30 }  // namespace Halide
31 
32 using namespace Halide::Runtime::Internal::OpenGL;
33 #endif
34 
35 extern "C" {
36 
halide_opengl_get_proc_address(void * user_context,const char * name)37 WEAK void *halide_opengl_get_proc_address(void *user_context, const char *name) {
38     static void *dylib = NULL;
39     if (!dylib) {
40         dylib = halide_load_library(
41             "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL");
42         if (!dylib) return NULL;
43     }
44     return halide_get_library_symbol(dylib, name);
45 }
46 
47 // Initialize OpenGL
halide_opengl_create_context(void * user_context)48 WEAK int halide_opengl_create_context(void *user_context) {
49 #if USE_AGL
50     void *ctx = NULL;
51 
52     int attrib[] = {4 /* AGL_RGBA */, 0 /* Sentinel */};
53     void *pf = aglChoosePixelFormat(NULL, 0, attrib);
54     if (!pf) {
55         halide_error(user_context, "Could not create pixel format\n");
56         return -1;
57     }
58     ctx = aglCreateContext(pf, NULL);
59     if (!ctx || aglGetError()) {
60         halide_error(user_context, "Could not create context\n");
61         return -1;
62     }
63     aglDestroyPixelFormat(pf);
64     if (!aglSetCurrentContext(ctx)) {
65         halide_error(user_context, "Could not activate OpenGL context\n");
66         return -1;
67     }
68 #else
69     {  // locking scope
70         ScopedMutexLock lock(&cgl_functions_mutex);
71 
72         if (!cgl_initialized) {
73             if ((CGLChoosePixelFormat =
74                      (int (*)(int *, void **, int *))halide_opengl_get_proc_address(user_context, "CGLChoosePixelFormat")) == NULL) {
75                 return -1;
76             }
77             if ((CGLCreateContext =
78                      (int (*)(void *, void *, void **))halide_opengl_get_proc_address(user_context, "CGLCreateContext")) == NULL) {
79                 return -1;
80             }
81             if ((CGLDestroyPixelFormat =
82                      (int (*)(void *))halide_opengl_get_proc_address(user_context, "CGLDestroyPixelFormat")) == NULL) {
83                 return -1;
84             }
85             if ((CGLSetCurrentContext =
86                      (int (*)(void *))halide_opengl_get_proc_address(user_context, "CGLSetCurrentContext")) == NULL) {
87                 return -1;
88             }
89         }
90         cgl_initialized = true;
91     }
92 
93     void *ctx = NULL;
94     int attribs[] = {
95         /* 5 kCGLPFADoubleBuffer */
96         72,      // kCGLPFANoRecovery
97         96,      // kCGLPFAAllowOfflineRenderers
98         99,      // kCGLPFAOpenGLProfile
99         0x1000,  // kCGLOGLPVersion_Legacy -- 0x3200 is kCGLOGLPVersion_3_2_Core -- kCGLOGLPVersion_GL4_Core is 0x4100
100         0        // sentinel ending list
101     };
102 
103     void *fmt;
104     int numFormats = 0;
105     if (CGLChoosePixelFormat(attribs, &fmt, &numFormats) != 0) {
106         return -1;
107     }
108     if (CGLCreateContext(fmt, NULL, &ctx) != 0) {
109         CGLDestroyPixelFormat(fmt);
110         return -1;
111     }
112     CGLSetCurrentContext(ctx);
113 #endif
114     return 0;
115 }
116 }
117