#include <glib.h>
#include <dlfcn.h>
-
#define LIBGL_IMAGE_NAME \
"/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
} \
} while (0)
-struct vigs_gl_backend_agl
-{
+struct vigs_gl_backend_agl {
struct vigs_gl_backend base;
-
+
void *handle;
AGLContext context;
AGLPbuffer surface;
AGLPixelFormat pixfmt;
};
-
-static int vigs_gl_backend_agl_choose_config(struct vigs_gl_backend_agl *gl_backend_agl)
+static int vigs_gl_backend_agl_choose_config(struct vigs_gl_backend_agl
+ *gl_backend_agl)
{
const int attrib_list[] = {
AGL_RGBA,
AGL_NONE
};
AGLPixelFormat pixfmt;
-
+
/* Select first AGL pixel format matching our constraints */
-
+
pixfmt = aglChoosePixelFormat(NULL, 0, attrib_list);
-
+
gl_backend_agl->pixfmt = pixfmt;
-
+
return (pixfmt != NULL);
}
-
-static bool vigs_gl_backend_agl_create_surface(struct vigs_gl_backend_agl *gl_backend_agl,
- int config_id)
+static bool vigs_gl_backend_agl_create_surface(struct vigs_gl_backend_agl
+ *gl_backend_agl, int config_id)
{
gl_backend_agl->surface = NULL;
-
- aglCreatePBuffer(2048, 2048, GL_TEXTURE_2D, GL_RGBA, 0, &gl_backend_agl->surface);
-
+
+ aglCreatePBuffer(2048, 2048, GL_TEXTURE_2D, GL_RGBA, 0,
+ &gl_backend_agl->surface);
+
if (!gl_backend_agl->surface) {
VIGS_LOG_CRITICAL("aglCreatePBuffer failed");
return false;
}
-
+
return true;
}
-
-static bool vigs_gl_backend_agl_create_context(struct vigs_gl_backend_agl *gl_backend_agl)
+static bool vigs_gl_backend_agl_create_context(struct vigs_gl_backend_agl
+ *gl_backend_agl)
{
gl_backend_agl->context = aglCreateContext(gl_backend_agl->pixfmt, NULL);
-
+
if (!gl_backend_agl->context) {
VIGS_LOG_CRITICAL("aglCreateContext failed");
return false;
}
-
+
return true;
}
-
static void vigs_gl_backend_agl_destroy(struct vigs_backend *backend)
{
- struct vigs_gl_backend_agl *gl_backend_agl = (struct vigs_gl_backend_agl*)backend;
-
+ struct vigs_gl_backend_agl *gl_backend_agl =
+ (struct vigs_gl_backend_agl *)backend;
+
vigs_gl_backend_cleanup(&gl_backend_agl->base);
-
+
if (gl_backend_agl->surface) {
aglDestroyPBuffer(gl_backend_agl->surface);
}
-
+
if (gl_backend_agl->context) {
aglDestroyContext(gl_backend_agl->context);
}
-
+
if (gl_backend_agl->handle) {
dlclose(gl_backend_agl->handle);
}
-
+
vigs_backend_cleanup(&gl_backend_agl->base.base);
-
+
g_free(gl_backend_agl);
-
+
VIGS_LOG_DEBUG("destroyed");
}
-
static bool vigs_gl_backend_agl_has_current(struct vigs_gl_backend *gl_backend)
{
return aglGetCurrentContext() != NULL;
}
-
static bool vigs_gl_backend_agl_make_current(struct vigs_gl_backend *gl_backend,
bool enable)
{
struct vigs_gl_backend_agl *gl_backend_agl =
- (struct vigs_gl_backend_agl*)gl_backend;
+ (struct vigs_gl_backend_agl *)gl_backend;
AGLPbuffer buf = NULL;
AGLContext context = gl_backend_agl->context;
-
+
if (enable) {
buf = gl_backend_agl->surface;
-
+
if (!buf) {
VIGS_LOG_CRITICAL("surface retrieval failed");
return false;
}
-
+
if (aglSetPBuffer(context, buf, 0, 0, 0) == GL_FALSE) {
VIGS_LOG_CRITICAL("aglSetPBuffer failed");
return false;
}
-
+
if (aglSetCurrentContext(context) == GL_FALSE) {
VIGS_LOG_CRITICAL("aglSetCurrentContext failed");
aglSetPBuffer(context, NULL, 0, 0, 0);
return false;
}
}
-
+
return true;
}
-
struct vigs_backend *vigs_gl_backend_create(void *display)
{
struct vigs_gl_backend_agl *gl_backend_agl;
int config_id;
-
+
gl_backend_agl = g_malloc0(sizeof(*gl_backend_agl));
-
+
vigs_backend_init(&gl_backend_agl->base.base,
&gl_backend_agl->base.ws_info.base);
-
+
gl_backend_agl->handle = dlopen(LIBGL_IMAGE_NAME, RTLD_GLOBAL);
-
+
VIGS_GL_GET_PROC(GenTextures, glGenTextures);
VIGS_GL_GET_PROC(DeleteTextures, glDeleteTextures);
VIGS_GL_GET_PROC(BindTexture, glBindTexture);
VIGS_GL_GET_PROC(BlendFunc, glBlendFunc);
VIGS_GL_GET_PROC(CopyTexImage2D, glCopyTexImage2D);
VIGS_GL_GET_PROC(BlitFramebuffer, glBlitFramebufferEXT);
-
+
config_id = vigs_gl_backend_agl_choose_config(gl_backend_agl);
-
+
if (!config_id) {
goto fail;
}
-
+
if (!vigs_gl_backend_agl_create_surface(gl_backend_agl, config_id)) {
goto fail;
}
-
+
if (!vigs_gl_backend_agl_create_context(gl_backend_agl)) {
goto fail;
}
-
-
+
gl_backend_agl->base.base.destroy = &vigs_gl_backend_agl_destroy;
gl_backend_agl->base.has_current = &vigs_gl_backend_agl_has_current;
gl_backend_agl->base.make_current = &vigs_gl_backend_agl_make_current;
gl_backend_agl->base.ws_info.context = &gl_backend_agl->context;
-
+
if (!vigs_gl_backend_init(&gl_backend_agl->base)) {
goto fail;
}
-
+
VIGS_LOG_DEBUG("created");
-
+
return &gl_backend_agl->base.base;
-
-fail:
-
+
+ fail:
+
if (gl_backend_agl->handle) {
dlclose(gl_backend_agl->handle);
}
-
+
if (gl_backend_agl->surface) {
aglDestroyPBuffer(gl_backend_agl->surface);
}
-
+
if (gl_backend_agl->context) {
- aglDestroyContext(gl_backend_agl->context);
+ aglDestroyContext(gl_backend_agl->context);
}
-
+
vigs_backend_cleanup(&gl_backend_agl->base.base);
-
+
g_free(gl_backend_agl);
-
+
return NULL;
}
YAGL_LOG_ERROR("AGL status: %s", aglErrorString(aglGetError()))
typedef struct YaglEglAglContext {
- AGLContext context;
+ AGLContext context;
} YaglEglAglContext;
typedef struct YaglEglAglDriver {
- struct yagl_egl_driver base;
+ struct yagl_egl_driver base;
} YaglEglAglDriver;
-
static EGLNativeDisplayType
yagl_egl_agl_display_open(struct yagl_egl_driver *driver)
{
- void* dpy = (void*) 0x1;
+ void *dpy = (void *)0x1;
YAGL_LOG_FUNC_ENTER(yagl_egl_agl_display_open, NULL);
-
+
YAGL_LOG_FUNC_EXIT("Display created: %p", dpy);
return (EGLNativeDisplayType) dpy;
}
-
static void yagl_egl_agl_display_close(struct yagl_egl_driver *driver,
EGLNativeDisplayType egl_dpy)
{
YAGL_LOG_FUNC_EXIT(NULL);
}
-
static struct yagl_egl_native_config
- *yagl_egl_agl_config_enum(struct yagl_egl_driver *driver,
- EGLNativeDisplayType egl_dpy,
- int *num_configs)
+*yagl_egl_agl_config_enum(struct yagl_egl_driver *driver,
+ EGLNativeDisplayType egl_dpy, int *num_configs)
{
struct yagl_egl_native_config *egl_configs = NULL;
struct yagl_egl_native_config *cur_config;
int usable_configs = 0;
-
+
const int attrib_list[] = {
AGL_RGBA,
AGL_ACCELERATED,
YAGL_LOG_FUNC_ENTER(yagl_egl_agl_config_enum, "display %p", egl_dpy);
-
/* Enumerate AGL pixel formats matching our constraints */
-
+
pixfmt = aglChoosePixelFormat(NULL, 0, attrib_list);
-
+
while (pixfmt) {
egl_configs = g_renew(struct yagl_egl_native_config,
- egl_configs,
- usable_configs+1);
-
+ egl_configs, usable_configs + 1);
+
cur_config = &egl_configs[usable_configs];
-
+
/* Initialize fields */
- yagl_egl_native_config_init(cur_config);
-
+ yagl_egl_native_config_init(cur_config);
+
cur_config->transparent_type = EGL_NONE;
cur_config->config_id = usable_configs;
-
- aglDescribePixelFormat(pixfmt, AGL_BUFFER_SIZE, &cur_config->buffer_size);
+
+ aglDescribePixelFormat(pixfmt, AGL_BUFFER_SIZE,
+ &cur_config->buffer_size);
aglDescribePixelFormat(pixfmt, AGL_RED_SIZE, &cur_config->red_size);
- aglDescribePixelFormat(pixfmt, AGL_GREEN_SIZE,&cur_config->green_size);
+ aglDescribePixelFormat(pixfmt, AGL_GREEN_SIZE, &cur_config->green_size);
aglDescribePixelFormat(pixfmt, AGL_BLUE_SIZE, &cur_config->blue_size);
aglDescribePixelFormat(pixfmt, AGL_ALPHA_SIZE, &cur_config->alpha_size);
aglDescribePixelFormat(pixfmt, AGL_DEPTH_SIZE, &cur_config->depth_size);
- aglDescribePixelFormat(pixfmt, AGL_STENCIL_SIZE, &cur_config->stencil_size);
-
+ aglDescribePixelFormat(pixfmt, AGL_STENCIL_SIZE,
+ &cur_config->stencil_size);
+
cur_config->max_pbuffer_width = 4096;
cur_config->max_pbuffer_height = 4096;
- cur_config->max_pbuffer_size = 4096*4096;
+ cur_config->max_pbuffer_size = 4096 * 4096;
cur_config->native_visual_type = EGL_NONE;
cur_config->native_visual_id = 0;
cur_config->caveat = EGL_NONE;
cur_config->samples_per_pixel = 0;
cur_config->max_swap_interval = 1000;
cur_config->min_swap_interval = 0;
-
- cur_config->driver_data = (void*) pixfmt;
-
+
+ cur_config->driver_data = (void *)pixfmt;
+
usable_configs++;
-
+
pixfmt = aglNextPixelFormat(pixfmt);
}
YAGL_LOG_FUNC_EXIT("Enumerated %d configs", usable_configs);
-
+
/* It's up to the caller to call config_cleanup on each
of the returned entries, as well as call g_free on the array */
return egl_configs;
}
-
static void yagl_egl_agl_config_cleanup(struct yagl_egl_driver *driver,
EGLNativeDisplayType egl_dpy,
- const struct yagl_egl_native_config *cfg)
+ const struct yagl_egl_native_config
+ *cfg)
{
YAGL_LOG_FUNC_ENTER(yagl_egl_agl_config_cleanup,
- "dpy = %p, cfg = %d",
- egl_dpy, cfg->config_id);
+ "dpy = %p, cfg = %d", egl_dpy, cfg->config_id);
aglDestroyPixelFormat(cfg->driver_data);
YAGL_LOG_FUNC_EXIT(NULL);
}
-
static EGLContext yagl_egl_agl_context_create(struct yagl_egl_driver *driver,
EGLNativeDisplayType egl_dpy,
- const struct yagl_egl_native_config *cfg,
+ const struct
+ yagl_egl_native_config *cfg,
yagl_client_api client_api,
EGLContext share_context)
{
AGLContext agl_share_glc;
YAGL_LOG_FUNC_ENTER(yagl_egl_agl_context_create,
- "dpy = %p, api = %u, share_context = %p, cfgid=%d",
- egl_dpy, client_api, share_context, cfg->config_id);
+ "dpy = %p, api = %u, share_context = %p, cfgid=%d",
+ egl_dpy, client_api, share_context, cfg->config_id);
egl_glc = g_new0(YaglEglAglContext, 1);
-
+
if (share_context != EGL_NO_CONTEXT) {
- agl_share_glc = ((YaglEglAglContext*)share_context)->context;
- }
- else
+ agl_share_glc = ((YaglEglAglContext *) share_context)->context;
+ } else
agl_share_glc = NULL;
-
+
egl_glc->context = aglCreateContext(cfg->driver_data, agl_share_glc);
-
+
if (!egl_glc->context)
goto fail;
-
+
YAGL_LOG_FUNC_EXIT("Context created: %p", egl_glc);
-
- return (EGLContext)egl_glc;
-fail:
+ return (EGLContext) egl_glc;
+
+ fail:
g_free(egl_glc);
-
+
YAGL_LOG_AGL_STATUS();
YAGL_LOG_FUNC_EXIT("Failed to create new context");
return EGL_NO_CONTEXT;
}
-
static bool yagl_egl_agl_make_current(struct yagl_egl_driver *driver,
EGLNativeDisplayType egl_dpy,
EGLSurface egl_draw_surf,
AGLPbuffer read_buf = NULL;
YAGL_LOG_FUNC_ENTER(yagl_egl_agl_make_current,
- "dpy = %p, draw = %p, read = %p, ctx = %p",
- egl_dpy,
- egl_draw_surf,
- egl_read_surf,
- egl_glc);
+ "dpy = %p, draw = %p, read = %p, ctx = %p",
+ egl_dpy, egl_draw_surf, egl_read_surf, egl_glc);
if (egl_glc != EGL_NO_CONTEXT) {
- context = ((YaglEglAglContext*) egl_glc)->context;
+ context = ((YaglEglAglContext *) egl_glc)->context;
}
-
+
if (egl_read_surf != EGL_NO_SURFACE) {
read_buf = (AGLPbuffer) egl_read_surf;
-
+
if (aglSetPBuffer(context, read_buf, 0, 0, 0) == GL_FALSE) {
goto fail;
}
}
-
+
if (egl_draw_surf != EGL_NO_SURFACE) {
draw_buf = (AGLPbuffer) egl_draw_surf;
-
+
if (aglSetPBuffer(context, draw_buf, 0, 0, 0) == GL_FALSE) {
goto fail;
}
}
-
+
if (aglSetCurrentContext(context) == GL_FALSE) {
goto fail;
}
return true;
-fail:
+ fail:
YAGL_LOG_AGL_STATUS();
YAGL_LOG_FUNC_EXIT("Failed to make context %p current", context);
return false;
}
-
static void yagl_egl_agl_context_destroy(struct yagl_egl_driver *driver,
EGLNativeDisplayType egl_dpy,
EGLContext egl_glc)
AGLContext context;
YAGL_LOG_FUNC_ENTER(yagl_egl_agl_context_destroy,
- "dpy = %p, ctx = %p",
- egl_dpy, egl_glc);
+ "dpy = %p, ctx = %p", egl_dpy, egl_glc);
if (egl_glc != EGL_NO_CONTEXT) {
- context = ((YaglEglAglContext*) egl_glc)->context;
-
+ context = ((YaglEglAglContext *) egl_glc)->context;
+
if (aglDestroyContext(context) == GL_TRUE) {
g_free(egl_glc);
YAGL_LOG_FUNC_EXIT("Context destroyed");
return;
}
-
+
g_free(egl_glc);
YAGL_LOG_AGL_STATUS();
}
-
+
YAGL_LOG_FUNC_EXIT("Could not destroy context");
}
-
-static EGLSurface yagl_egl_agl_pbuffer_surface_create(struct yagl_egl_driver *driver,
- EGLNativeDisplayType egl_dpy,
- const struct yagl_egl_native_config *cfg,
- EGLint width,
+static EGLSurface yagl_egl_agl_pbuffer_surface_create(struct yagl_egl_driver
+ *driver,
+ EGLNativeDisplayType
+ egl_dpy,
+ const struct
+ yagl_egl_native_config
+ *cfg, EGLint width,
EGLint height,
- const struct yagl_egl_pbuffer_attribs *attribs)
+ const struct
+ yagl_egl_pbuffer_attribs
+ *attribs)
{
AGLPbuffer pbuffer = NULL;
YAGL_LOG_FUNC_ENTER(yagl_egl_agl_pbuffer_surface_create,
- "dpy = %p, width = %d, height = %d, cfgid=%d",
- egl_dpy,
- width,
- height,
- cfg->config_id);
+ "dpy = %p, width = %d, height = %d, cfgid=%d",
+ egl_dpy, width, height, cfg->config_id);
- if (aglCreatePBuffer(width, height, GL_TEXTURE_2D, GL_RGBA, 0, &pbuffer) == GL_FALSE)
+ if (aglCreatePBuffer(width, height, GL_TEXTURE_2D, GL_RGBA, 0, &pbuffer) ==
+ GL_FALSE)
goto fail;
YAGL_LOG_FUNC_EXIT("Surface created: %p", pbuffer);
- return (EGLSurface)pbuffer;
+ return (EGLSurface) pbuffer;
-fail:
+ fail:
YAGL_LOG_AGL_STATUS();
YAGL_LOG_FUNC_EXIT("Surface creation failed");
return EGL_NO_SURFACE;
}
-
static void yagl_egl_agl_pbuffer_surface_destroy(struct yagl_egl_driver *driver,
EGLNativeDisplayType egl_dpy,
EGLSurface surf)
{
YAGL_LOG_FUNC_ENTER(yagl_egl_agl_pbuffer_surface_destroy,
- "dpy = %p, sfc = %p",
- egl_dpy,
- (AGLPbuffer)surf);
-
- if (aglDestroyPBuffer((AGLPbuffer)surf) == GL_FALSE) {
- YAGL_LOG_AGL_STATUS();
- YAGL_LOG_FUNC_EXIT("Failed to destroy surface");
- } else {
- YAGL_LOG_FUNC_EXIT("Surface destroyed");
- }
-}
+ "dpy = %p, sfc = %p", egl_dpy, (AGLPbuffer) surf);
+ if (aglDestroyPBuffer((AGLPbuffer) surf) == GL_FALSE) {
+ YAGL_LOG_AGL_STATUS();
+ YAGL_LOG_FUNC_EXIT("Failed to destroy surface");
+ } else {
+ YAGL_LOG_FUNC_EXIT("Surface destroyed");
+ }
+}
static void yagl_egl_agl_destroy(struct yagl_egl_driver *driver)
{
YAGL_LOG_FUNC_EXIT(NULL);
}
-
struct yagl_egl_driver *yagl_egl_driver_create(void *display)
{
YaglEglAglDriver *egl_agl;
YAGL_LOG_FUNC_ENTER(yagl_egl_agl_create, NULL);
egl_agl = g_try_new0(YaglEglAglDriver, 1);
-
+
if (!egl_agl)
goto inconceivable;
egl_driver = &egl_agl->base;
-
+
/* Initialize portable YaGL machinery */
yagl_egl_driver_init(egl_driver);
egl_driver->context_destroy = &yagl_egl_agl_context_destroy;
egl_driver->make_current = &yagl_egl_agl_make_current;
egl_driver->destroy = &yagl_egl_agl_destroy;
-
+
egl_driver->dyn_lib = yagl_dyn_lib_create();
if (!yagl_dyn_lib_load(egl_driver->dyn_lib, LIBGL_IMAGE_NAME)) {
return egl_driver;
-fail:
+ fail:
yagl_egl_driver_cleanup(egl_driver);
g_free(egl_agl);
-inconceivable:
+ inconceivable:
YAGL_LOG_AGL_STATUS();
YAGL_LOG_FUNC_EXIT("EGL_AGL driver creation failed");
return NULL;
}
-
void *yagl_dyn_lib_get_ogl_procaddr(struct yagl_dyn_lib *dyn_lib,
const char *sym)
{
void *proc;
YAGL_LOG_FUNC_ENTER(yagl_egl_agl_get_procaddr,
- "Retrieving %s address", sym);
+ "Retrieving %s address", sym);
/* The dlsym code path is shared by Linux and Mac builds */
proc = yagl_dyn_lib_get_sym(dyn_lib, sym);