osx_opengl_context.cpp
#include "HalideRuntime.h"
#include "printer.h"
#include "scoped_mutex_lock.h"
#define USE_AGL 0
#if USE_AGL
extern "C" void *aglChoosePixelFormat(void *, int, const int *);
extern "C" void *aglCreateContext(void *, void *);
extern "C" int aglGetError();
extern "C" void aglDestroyPixelFormat(void *);
extern "C" unsigned char aglSetCurrentContext(void *);
#endif
#if !USE_AGL
namespace Halide {
namespace Runtime {
namespace Internal {
namespace OpenGL {
WEAK halide_mutex cgl_functions_mutex;
WEAK bool cgl_initialized = false;
WEAK int (*CGLChoosePixelFormat)(int *attributes, void **pixel_format_result, int *num_formats);
WEAK int (*CGLCreateContext)(void *pixel_format, void *share_context, void **context_Result);
WEAK int (*CGLDestroyPixelFormat)(void *);
WEAK int (*CGLSetCurrentContext)(void *);
} // namespace OpenGL
} // namespace Internal
} // namespace Runtime
} // namespace Halide
using namespace Halide::Runtime::Internal::OpenGL;
#endif
extern "C" {
WEAK void *halide_opengl_get_proc_address(void *user_context, const char *name) {
static void *dylib = nullptr;
if (!dylib) {
dylib = halide_load_library(
"/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL");
if (!dylib) {
return nullptr;
}
}
return halide_get_library_symbol(dylib, name);
}
// Initialize OpenGL
WEAK int halide_opengl_create_context(void *user_context) {
#if USE_AGL
void *ctx = nullptr;
int attrib[] = {4 /* AGL_RGBA */, 0 /* Sentinel */};
void *pf = aglChoosePixelFormat(nullptr, 0, attrib);
if (!pf) {
halide_error(user_context, "Could not create pixel format\n");
return -1;
}
ctx = aglCreateContext(pf, nullptr);
if (!ctx || aglGetError()) {
halide_error(user_context, "Could not create context\n");
return -1;
}
aglDestroyPixelFormat(pf);
if (!aglSetCurrentContext(ctx)) {
halide_error(user_context, "Could not activate OpenGL context\n");
return -1;
}
#else
{ // locking scope
ScopedMutexLock lock(&cgl_functions_mutex);
if (!cgl_initialized) {
if ((CGLChoosePixelFormat =
(int (*)(int *, void **, int *))halide_opengl_get_proc_address(user_context, "CGLChoosePixelFormat")) == nullptr) {
return -1;
}
if ((CGLCreateContext =
(int (*)(void *, void *, void **))halide_opengl_get_proc_address(user_context, "CGLCreateContext")) == nullptr) {
return -1;
}
if ((CGLDestroyPixelFormat =
(int (*)(void *))halide_opengl_get_proc_address(user_context, "CGLDestroyPixelFormat")) == nullptr) {
return -1;
}
if ((CGLSetCurrentContext =
(int (*)(void *))halide_opengl_get_proc_address(user_context, "CGLSetCurrentContext")) == nullptr) {
return -1;
}
}
cgl_initialized = true;
}
void *ctx = nullptr;
int attribs[] = {
/* 5 kCGLPFADoubleBuffer */
72, // kCGLPFANoRecovery
96, // kCGLPFAAllowOfflineRenderers
99, // kCGLPFAOpenGLProfile
0x1000, // kCGLOGLPVersion_Legacy -- 0x3200 is kCGLOGLPVersion_3_2_Core -- kCGLOGLPVersion_GL4_Core is 0x4100
0 // sentinel ending list
};
void *fmt;
int numFormats = 0;
if (CGLChoosePixelFormat(attribs, &fmt, &numFormats) != 0) {
return -1;
}
if (CGLCreateContext(fmt, nullptr, &ctx) != 0) {
CGLDestroyPixelFormat(fmt);
return -1;
}
CGLSetCurrentContext(ctx);
#endif
return 0;
}
}