VIGS/YaGL: Use CGL instead of AGL 01/16701/1
authorStanislav Vorobiov <s.vorobiov@samsung.com>
Sat, 22 Feb 2014 13:39:08 +0000 (17:39 +0400)
committerStanislav Vorobiov <s.vorobiov@samsung.com>
Sat, 22 Feb 2014 13:40:50 +0000 (17:40 +0400)
AGL is a deprecated API and it doesn't
allow one to create OpenGL 3.2 contexts, so
use CGL instead

Change-Id: Iaa63fee0aeda7348c256f177b3a96b10142870d4

hw/vigs/Makefile.objs
hw/vigs/vigs_gl_backend_agl.c [deleted file]
hw/vigs/vigs_gl_backend_cgl.c [new file with mode: 0644]
hw/yagl/yagl_drivers/Makefile.objs
hw/yagl/yagl_drivers/egl_agl/Makefile.objs [deleted file]
hw/yagl/yagl_drivers/egl_agl/yagl_egl_agl.c [deleted file]
hw/yagl/yagl_drivers/egl_cgl/Makefile.objs [new file with mode: 0644]
hw/yagl/yagl_drivers/egl_cgl/yagl_egl_cgl.c [new file with mode: 0644]

index b227b1c..93f7e3b 100644 (file)
@@ -21,7 +21,7 @@ endif
 ifdef CONFIG_WIN32
 obj-y += vigs_gl_backend_wgl.o
 endif
-# GL AGL backend
+# GL CGL backend
 ifdef CONFIG_DARWIN
-obj-y += vigs_gl_backend_agl.o
+obj-y += vigs_gl_backend_cgl.o
 endif
diff --git a/hw/vigs/vigs_gl_backend_agl.c b/hw/vigs/vigs_gl_backend_agl.c
deleted file mode 100644 (file)
index 9ee6c05..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * vigs
- *
- * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact:
- * Stanislav Vorobiov <s.vorobiov@samsung.com>
- * Jinhyung Jo <jinhyung.jo@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-#include "vigs_gl_backend.h"
-#include "vigs_log.h"
-#include <OpenGL/OpenGL.h>
-#include <AGL/agl.h>
-#include <glib.h>
-#include <dlfcn.h>
-
-#define LIBGL_IMAGE_NAME \
-"/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
-
-#define VIGS_GL_GET_PROC(func, proc_name) \
-    do { \
-        *(void**)(&gl_backend_agl->base.func) = dlsym(gl_backend_agl->handle, #proc_name); \
-        if (!gl_backend_agl->base.func) { \
-            VIGS_LOG_CRITICAL("Unable to load " #proc_name " symbol"); \
-            goto fail; \
-        } \
-    } while (0)
-
-struct vigs_gl_backend_agl {
-    struct vigs_gl_backend base;
-
-    void *handle;
-    AGLContext read_pixels_context;
-    AGLPbuffer read_pixels_surface;
-    AGLContext context;
-    AGLPbuffer surface;
-    AGLPixelFormat pixfmt;
-};
-
-static int vigs_gl_backend_agl_choose_config(struct vigs_gl_backend_agl
-                                             *gl_backend_agl)
-{
-    const int attrib_list[] = {
-        AGL_RGBA,
-        AGL_ACCELERATED,
-        AGL_MINIMUM_POLICY,
-        AGL_BUFFER_SIZE, 32,
-        AGL_RED_SIZE, 8,
-        AGL_GREEN_SIZE, 8,
-        AGL_BLUE_SIZE, 8,
-        AGL_ALPHA_SIZE, 8,
-        AGL_DEPTH_SIZE, 24,
-        AGL_STENCIL_SIZE, 8,
-        AGL_NO_RECOVERY,
-        AGL_DOUBLEBUFFER,
-        AGL_PBUFFER,
-        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,
-                                               AGLPbuffer *surface)
-{
-    aglCreatePBuffer(1, 1, GL_TEXTURE_2D, GL_RGBA, 0,
-                     surface);
-
-    if (!*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,
-                                               AGLContext share_context,
-                                               AGLContext *context)
-{
-    *context = aglCreateContext(gl_backend_agl->pixfmt, share_context);
-
-    if (!*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;
-
-    vigs_gl_backend_cleanup(&gl_backend_agl->base);
-
-    if (gl_backend_agl->surface) {
-        aglDestroyPBuffer(gl_backend_agl->surface);
-    }
-
-    if (gl_backend_agl->read_pixels_surface) {
-        aglDestroyPBuffer(gl_backend_agl->read_pixels_surface);
-    }
-
-    if (gl_backend_agl->context) {
-        aglDestroyContext(gl_backend_agl->context);
-    }
-
-    if (gl_backend_agl->read_pixels_context) {
-        aglDestroyContext(gl_backend_agl->read_pixels_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;
-    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;
-        }
-    } else {
-        if (aglSetCurrentContext(NULL) == GL_FALSE) {
-            VIGS_LOG_CRITICAL("aglSetCurrentContext(NULL) failed");
-            return false;
-        }
-    }
-
-    return true;
-}
-
-static bool vigs_gl_backend_agl_read_pixels_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;
-    AGLPbuffer buf = NULL;
-    AGLContext context = gl_backend_agl->read_pixels_context;
-
-    if (enable) {
-        buf = gl_backend_agl->read_pixels_surface;
-
-        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;
-        }
-    } else {
-        if (aglSetCurrentContext(NULL) == GL_FALSE) {
-            VIGS_LOG_CRITICAL("aglSetCurrentContext(NULL) failed");
-            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(CullFace, glCullFace);
-    VIGS_GL_GET_PROC(TexParameterf, glTexParameterf);
-    VIGS_GL_GET_PROC(TexParameterfv, glTexParameterfv);
-    VIGS_GL_GET_PROC(TexParameteri, glTexParameteri);
-    VIGS_GL_GET_PROC(TexParameteriv, glTexParameteriv);
-    VIGS_GL_GET_PROC(TexImage2D, glTexImage2D);
-    VIGS_GL_GET_PROC(TexSubImage2D, glTexSubImage2D);
-    VIGS_GL_GET_PROC(Clear, glClear);
-    VIGS_GL_GET_PROC(ClearColor, glClearColor);
-    VIGS_GL_GET_PROC(Disable, glDisable);
-    VIGS_GL_GET_PROC(Enable, glEnable);
-    VIGS_GL_GET_PROC(Finish, glFinish);
-    VIGS_GL_GET_PROC(Flush, glFlush);
-    VIGS_GL_GET_PROC(PixelStorei, glPixelStorei);
-    VIGS_GL_GET_PROC(ReadPixels, glReadPixels);
-    VIGS_GL_GET_PROC(Viewport, glViewport);
-    VIGS_GL_GET_PROC(GenFramebuffers, glGenFramebuffersEXT);
-    VIGS_GL_GET_PROC(GenRenderbuffers, glGenRenderbuffersEXT);
-    VIGS_GL_GET_PROC(DeleteFramebuffers, glDeleteFramebuffersEXT);
-    VIGS_GL_GET_PROC(DeleteRenderbuffers, glDeleteRenderbuffersEXT);
-    VIGS_GL_GET_PROC(BindFramebuffer, glBindFramebufferEXT);
-    VIGS_GL_GET_PROC(BindRenderbuffer, glBindRenderbufferEXT);
-    VIGS_GL_GET_PROC(RenderbufferStorage, glRenderbufferStorageEXT);
-    VIGS_GL_GET_PROC(FramebufferRenderbuffer, glFramebufferRenderbufferEXT);
-    VIGS_GL_GET_PROC(FramebufferTexture2D, glFramebufferTexture2DEXT);
-    VIGS_GL_GET_PROC(GetIntegerv, glGetIntegerv);
-    VIGS_GL_GET_PROC(DrawArrays, glDrawArrays);
-    VIGS_GL_GET_PROC(GenBuffers, glGenBuffers);
-    VIGS_GL_GET_PROC(DeleteBuffers, glDeleteBuffers);
-    VIGS_GL_GET_PROC(BindBuffer, glBindBuffer);
-    VIGS_GL_GET_PROC(BufferData, glBufferData);
-    VIGS_GL_GET_PROC(BufferSubData, glBufferSubData);
-    VIGS_GL_GET_PROC(MapBuffer, glMapBuffer);
-    VIGS_GL_GET_PROC(UnmapBuffer, glUnmapBuffer);
-    VIGS_GL_GET_PROC(CreateProgram, glCreateProgram);
-    VIGS_GL_GET_PROC(CreateShader, glCreateShader);
-    VIGS_GL_GET_PROC(CompileShader, glCompileShader);
-    VIGS_GL_GET_PROC(AttachShader, glAttachShader);
-    VIGS_GL_GET_PROC(LinkProgram, glLinkProgram);
-    VIGS_GL_GET_PROC(GetProgramiv, glGetProgramiv);
-    VIGS_GL_GET_PROC(GetProgramInfoLog, glGetProgramInfoLog);
-    VIGS_GL_GET_PROC(GetShaderiv, glGetShaderiv);
-    VIGS_GL_GET_PROC(GetShaderInfoLog, glGetShaderInfoLog);
-    VIGS_GL_GET_PROC(DetachShader, glDetachShader);
-    VIGS_GL_GET_PROC(DeleteProgram, glDeleteProgram);
-    VIGS_GL_GET_PROC(DeleteShader, glDeleteShader);
-    VIGS_GL_GET_PROC(DisableVertexAttribArray, glDisableVertexAttribArray);
-    VIGS_GL_GET_PROC(EnableVertexAttribArray, glEnableVertexAttribArray);
-    VIGS_GL_GET_PROC(ShaderSource, glShaderSource);
-    VIGS_GL_GET_PROC(UseProgram, glUseProgram);
-    VIGS_GL_GET_PROC(GetAttribLocation, glGetAttribLocation);
-    VIGS_GL_GET_PROC(GetUniformLocation, glGetUniformLocation);
-    VIGS_GL_GET_PROC(VertexAttribPointer, glVertexAttribPointer);
-    VIGS_GL_GET_PROC(Uniform4fv, glUniform4fv);
-    VIGS_GL_GET_PROC(UniformMatrix4fv, glUniformMatrix4fv);
-
-    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,
-                                            &gl_backend_agl->surface)) {
-        goto fail;
-    }
-
-    if (!vigs_gl_backend_agl_create_surface(gl_backend_agl, config_id,
-                                            &gl_backend_agl->read_pixels_surface)) {
-        goto fail;
-    }
-
-    if (!vigs_gl_backend_agl_create_context(gl_backend_agl, NULL,
-                                            &gl_backend_agl->context)) {
-        goto fail;
-    }
-
-    if (!vigs_gl_backend_agl_create_context(gl_backend_agl, gl_backend_agl->context,
-                                            &gl_backend_agl->read_pixels_context)) {
-        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.read_pixels_make_current = &vigs_gl_backend_agl_read_pixels_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:
-
-    if (gl_backend_agl->handle) {
-        dlclose(gl_backend_agl->handle);
-    }
-
-    if (gl_backend_agl->surface) {
-        aglDestroyPBuffer(gl_backend_agl->surface);
-    }
-
-    if (gl_backend_agl->read_pixels_surface) {
-        aglDestroyPBuffer(gl_backend_agl->read_pixels_surface);
-    }
-
-    if (gl_backend_agl->context) {
-        aglDestroyContext(gl_backend_agl->context);
-    }
-
-    if (gl_backend_agl->read_pixels_context) {
-        aglDestroyContext(gl_backend_agl->read_pixels_context);
-    }
-
-    vigs_backend_cleanup(&gl_backend_agl->base.base);
-
-    g_free(gl_backend_agl);
-
-    return NULL;
-}
diff --git a/hw/vigs/vigs_gl_backend_cgl.c b/hw/vigs/vigs_gl_backend_cgl.c
new file mode 100644 (file)
index 0000000..2112138
--- /dev/null
@@ -0,0 +1,378 @@
+/*
+ * vigs
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Stanislav Vorobiov <s.vorobiov@samsung.com>
+ * Jinhyung Jo <jinhyung.jo@samsung.com>
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include "vigs_gl_backend.h"
+#include "vigs_log.h"
+#include <OpenGL/OpenGL.h>
+#include <dlfcn.h>
+
+#define LIBGL_IMAGE_NAME \
+"/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
+
+#ifndef kCGLPFAOpenGLProfile
+#   define kCGLPFAOpenGLProfile 99
+#   define kCGLOGLPVersion_3_2_Core 0x3200
+#   define kCGLOGLPVersion_Legacy 0x1000
+#endif
+
+#define VIGS_GL_GET_PROC(func, proc_name) \
+    do { \
+        *(void**)(&gl_backend_cgl->base.func) = dlsym(gl_backend_cgl->handle, #proc_name); \
+        if (!gl_backend_cgl->base.func) { \
+            VIGS_LOG_CRITICAL("Unable to load " #proc_name " symbol"); \
+            goto fail2; \
+        } \
+    } while (0)
+
+static const CGLPixelFormatAttribute pixel_format_legacy_attrs[] =
+{
+    kCGLPFAAccelerated,
+    kCGLPFAMinimumPolicy,
+    kCGLPFAColorSize, 32,
+    kCGLPFAAlphaSize, 8,
+    kCGLPFADepthSize, 24,
+    kCGLPFAStencilSize, 8,
+    kCGLPFANoRecovery,
+    kCGLPFAPBuffer,
+    0
+};
+
+static const CGLPixelFormatAttribute pixel_format_3_2_core_attrs[] =
+{
+    kCGLPFAAccelerated,
+    kCGLPFAMinimumPolicy,
+    kCGLPFAColorSize, 32,
+    kCGLPFAAlphaSize, 8,
+    kCGLPFADepthSize, 24,
+    kCGLPFAStencilSize, 8,
+    kCGLPFANoRecovery,
+    kCGLPFAOpenGLProfile, kCGLOGLPVersion_3_2_Core,
+    0
+};
+
+struct vigs_gl_backend_cgl
+{
+    struct vigs_gl_backend base;
+
+    void *handle;
+    CGLContextObj read_pixels_context;
+    CGLContextObj context;
+};
+
+static bool vigs_gl_backend_cgl_check_gl_version(struct vigs_gl_backend_cgl *gl_backend_cgl,
+                                                 bool *is_gl_2)
+{
+    CGLError error;
+    bool res = false;
+    const char *tmp;
+    CGLPixelFormatObj pixel_format;
+    int n;
+
+    tmp = getenv("GL_VERSION");
+
+    if (tmp) {
+        if (strcmp(tmp, "2") == 0) {
+            VIGS_LOG_INFO("GL_VERSION forces OpenGL version to 2.1");
+            *is_gl_2 = true;
+            res = true;
+        } else if (strcmp(tmp, "3_2") == 0) {
+            VIGS_LOG_INFO("GL_VERSION forces OpenGL version to 3.2");
+            *is_gl_2 = false;
+            res = true;
+        } else {
+            VIGS_LOG_CRITICAL("Bad GL_VERSION value = %s", tmp);
+        }
+
+        goto out;
+    }
+
+    error = CGLChoosePixelFormat(pixel_format_3_2_core_attrs,
+                                 &pixel_format,
+                                 &n);
+
+    if (error) {
+        VIGS_LOG_INFO("CGLChoosePixelFormat failed for 3_2_core attrs: %s, using OpenGL 2.1", CGLErrorString(error));
+        *is_gl_2 = true;
+        res = true;
+        goto out;
+    }
+
+    if (!pixel_format) {
+        VIGS_LOG_INFO("CGLChoosePixelFormat failed to find formats for 3_2_core attrs, using OpenGL 2.1");
+        *is_gl_2 = true;
+        res = true;
+        goto out;
+    }
+
+    CGLDestroyPixelFormat(pixel_format);
+
+    VIGS_LOG_INFO("Using OpenGL 3.2");
+    *is_gl_2 = false;
+    res = true;
+
+out:
+    return res;
+}
+
+static bool vigs_gl_backend_cgl_create_context(struct vigs_gl_backend_cgl *gl_backend_cgl,
+                                               CGLPixelFormatObj pixel_format,
+                                               CGLContextObj share_context,
+                                               CGLContextObj *ctx)
+{
+    CGLError error;
+
+    error = CGLCreateContext(pixel_format, share_context, ctx);
+
+    if (error) {
+        VIGS_LOG_CRITICAL("CGLCreateContext failed: %s", CGLErrorString(error));
+        return false;
+    }
+
+    return true;
+}
+
+static bool vigs_gl_backend_cgl_has_current(struct vigs_gl_backend *gl_backend)
+{
+    return CGLGetCurrentContext() != NULL;
+}
+
+static bool vigs_gl_backend_cgl_make_current(struct vigs_gl_backend *gl_backend,
+                                             bool enable)
+{
+    struct vigs_gl_backend_cgl *gl_backend_cgl =
+        (struct vigs_gl_backend_cgl*)gl_backend;
+    CGLError error;
+
+    error = CGLSetCurrentContext(enable ? gl_backend_cgl->context : NULL);
+
+    if (error) {
+        VIGS_LOG_CRITICAL("CGLSetCurrentContext failed: %s", CGLErrorString(error));
+        return false;
+    }
+
+    return true;
+}
+
+static bool vigs_gl_backend_cgl_read_pixels_make_current(struct vigs_gl_backend *gl_backend,
+                                                         bool enable)
+{
+    struct vigs_gl_backend_cgl *gl_backend_cgl =
+        (struct vigs_gl_backend_cgl*)gl_backend;
+    CGLError error;
+
+    error = CGLSetCurrentContext(enable ? gl_backend_cgl->read_pixels_context : NULL);
+
+    if (error) {
+        VIGS_LOG_CRITICAL("CGLSetCurrentContext failed: %s", CGLErrorString(error));
+        return false;
+    }
+
+    return true;
+}
+
+static void vigs_gl_backend_cgl_destroy(struct vigs_backend *backend)
+{
+    struct vigs_gl_backend_cgl *gl_backend_cgl = (struct vigs_gl_backend_cgl*)backend;
+    CGLError error;
+
+    vigs_gl_backend_cleanup(&gl_backend_cgl->base);
+
+    error = CGLDestroyContext(gl_backend_cgl->context);
+
+    if (error) {
+        VIGS_LOG_ERROR("CGLDestroyContext failed: %s", CGLErrorString(error));
+    }
+
+    error = CGLDestroyContext(gl_backend_cgl->read_pixels_context);
+
+    if (error) {
+        VIGS_LOG_ERROR("CGLDestroyContext failed: %s", CGLErrorString(error));
+    }
+
+    dlclose(gl_backend_cgl->handle);
+
+    vigs_backend_cleanup(&gl_backend_cgl->base.base);
+
+    g_free(gl_backend_cgl);
+
+    VIGS_LOG_DEBUG("destroyed");
+}
+
+struct vigs_backend *vigs_gl_backend_create(void *display)
+{
+    struct vigs_gl_backend_cgl *gl_backend_cgl;
+    CGLError error;
+    CGLPixelFormatObj pixel_format;
+    int n;
+
+    gl_backend_cgl = g_malloc0(sizeof(*gl_backend_cgl));
+
+    vigs_backend_init(&gl_backend_cgl->base.base,
+                      &gl_backend_cgl->base.ws_info.base);
+
+    gl_backend_cgl->handle = dlopen(LIBGL_IMAGE_NAME, RTLD_NOW | RTLD_GLOBAL);
+
+    if (!gl_backend_cgl->handle) {
+        VIGS_LOG_CRITICAL("Unable to load " LIBGL_IMAGE_NAME ": %s", dlerror());
+        goto fail1;
+    }
+
+    VIGS_GL_GET_PROC(GenTextures, glGenTextures);
+    VIGS_GL_GET_PROC(DeleteTextures, glDeleteTextures);
+    VIGS_GL_GET_PROC(BindTexture, glBindTexture);
+    VIGS_GL_GET_PROC(CullFace, glCullFace);
+    VIGS_GL_GET_PROC(TexParameterf, glTexParameterf);
+    VIGS_GL_GET_PROC(TexParameterfv, glTexParameterfv);
+    VIGS_GL_GET_PROC(TexParameteri, glTexParameteri);
+    VIGS_GL_GET_PROC(TexParameteriv, glTexParameteriv);
+    VIGS_GL_GET_PROC(TexImage2D, glTexImage2D);
+    VIGS_GL_GET_PROC(TexSubImage2D, glTexSubImage2D);
+    VIGS_GL_GET_PROC(Clear, glClear);
+    VIGS_GL_GET_PROC(ClearColor, glClearColor);
+    VIGS_GL_GET_PROC(Disable, glDisable);
+    VIGS_GL_GET_PROC(Enable, glEnable);
+    VIGS_GL_GET_PROC(Finish, glFinish);
+    VIGS_GL_GET_PROC(Flush, glFlush);
+    VIGS_GL_GET_PROC(PixelStorei, glPixelStorei);
+    VIGS_GL_GET_PROC(ReadPixels, glReadPixels);
+    VIGS_GL_GET_PROC(Viewport, glViewport);
+    VIGS_GL_GET_PROC(GenFramebuffers, glGenFramebuffersEXT);
+    VIGS_GL_GET_PROC(GenRenderbuffers, glGenRenderbuffersEXT);
+    VIGS_GL_GET_PROC(DeleteFramebuffers, glDeleteFramebuffersEXT);
+    VIGS_GL_GET_PROC(DeleteRenderbuffers, glDeleteRenderbuffersEXT);
+    VIGS_GL_GET_PROC(BindFramebuffer, glBindFramebufferEXT);
+    VIGS_GL_GET_PROC(BindRenderbuffer, glBindRenderbufferEXT);
+    VIGS_GL_GET_PROC(RenderbufferStorage, glRenderbufferStorageEXT);
+    VIGS_GL_GET_PROC(FramebufferRenderbuffer, glFramebufferRenderbufferEXT);
+    VIGS_GL_GET_PROC(FramebufferTexture2D, glFramebufferTexture2DEXT);
+    VIGS_GL_GET_PROC(GetIntegerv, glGetIntegerv);
+    VIGS_GL_GET_PROC(DrawArrays, glDrawArrays);
+    VIGS_GL_GET_PROC(GenBuffers, glGenBuffers);
+    VIGS_GL_GET_PROC(DeleteBuffers, glDeleteBuffers);
+    VIGS_GL_GET_PROC(BindBuffer, glBindBuffer);
+    VIGS_GL_GET_PROC(BufferData, glBufferData);
+    VIGS_GL_GET_PROC(BufferSubData, glBufferSubData);
+    VIGS_GL_GET_PROC(MapBuffer, glMapBuffer);
+    VIGS_GL_GET_PROC(UnmapBuffer, glUnmapBuffer);
+    VIGS_GL_GET_PROC(CreateProgram, glCreateProgram);
+    VIGS_GL_GET_PROC(CreateShader, glCreateShader);
+    VIGS_GL_GET_PROC(CompileShader, glCompileShader);
+    VIGS_GL_GET_PROC(AttachShader, glAttachShader);
+    VIGS_GL_GET_PROC(LinkProgram, glLinkProgram);
+    VIGS_GL_GET_PROC(GetProgramiv, glGetProgramiv);
+    VIGS_GL_GET_PROC(GetProgramInfoLog, glGetProgramInfoLog);
+    VIGS_GL_GET_PROC(GetShaderiv, glGetShaderiv);
+    VIGS_GL_GET_PROC(GetShaderInfoLog, glGetShaderInfoLog);
+    VIGS_GL_GET_PROC(DetachShader, glDetachShader);
+    VIGS_GL_GET_PROC(DeleteProgram, glDeleteProgram);
+    VIGS_GL_GET_PROC(DeleteShader, glDeleteShader);
+    VIGS_GL_GET_PROC(DisableVertexAttribArray, glDisableVertexAttribArray);
+    VIGS_GL_GET_PROC(EnableVertexAttribArray, glEnableVertexAttribArray);
+    VIGS_GL_GET_PROC(ShaderSource, glShaderSource);
+    VIGS_GL_GET_PROC(UseProgram, glUseProgram);
+    VIGS_GL_GET_PROC(GetAttribLocation, glGetAttribLocation);
+    VIGS_GL_GET_PROC(GetUniformLocation, glGetUniformLocation);
+    VIGS_GL_GET_PROC(VertexAttribPointer, glVertexAttribPointer);
+    VIGS_GL_GET_PROC(Uniform4fv, glUniform4fv);
+    VIGS_GL_GET_PROC(UniformMatrix4fv, glUniformMatrix4fv);
+
+    if (!vigs_gl_backend_cgl_check_gl_version(gl_backend_cgl,
+                                              &gl_backend_cgl->base.is_gl_2)) {
+        goto fail2;
+    }
+
+    if (gl_backend_cgl->base.is_gl_2) {
+        error = CGLChoosePixelFormat(pixel_format_legacy_attrs,
+                                     &pixel_format,
+                                     &n);
+    } else {
+        VIGS_GL_GET_PROC(GenVertexArrays, glGenVertexArrays);
+        VIGS_GL_GET_PROC(BindVertexArray, glBindVertexArray);
+        VIGS_GL_GET_PROC(DeleteVertexArrays, glDeleteVertexArrays);
+
+        error = CGLChoosePixelFormat(pixel_format_3_2_core_attrs,
+                                     &pixel_format,
+                                     &n);
+    }
+
+    if (error) {
+        VIGS_LOG_INFO("CGLChoosePixelFormat failed for 3_2_core attrs: %s, using OpenGL 2.1", CGLErrorString(error));
+        goto fail2;
+    }
+
+    if (!pixel_format) {
+        VIGS_LOG_INFO("CGLChoosePixelFormat failed to find formats for 3_2_core attrs, using OpenGL 2.1");
+        goto fail2;
+    }
+
+    if (!vigs_gl_backend_cgl_create_context(gl_backend_cgl,
+                                            pixel_format,
+                                            NULL,
+                                            &gl_backend_cgl->context)) {
+        goto fail3;
+    }
+
+    if (!vigs_gl_backend_cgl_create_context(gl_backend_cgl,
+                                            pixel_format,
+                                            gl_backend_cgl->context,
+                                            &gl_backend_cgl->read_pixels_context)) {
+        goto fail4;
+    }
+
+    gl_backend_cgl->base.base.destroy = &vigs_gl_backend_cgl_destroy;
+    gl_backend_cgl->base.has_current = &vigs_gl_backend_cgl_has_current;
+    gl_backend_cgl->base.make_current = &vigs_gl_backend_cgl_make_current;
+    gl_backend_cgl->base.read_pixels_make_current = &vigs_gl_backend_cgl_read_pixels_make_current;
+    gl_backend_cgl->base.ws_info.context = &gl_backend_cgl->context;
+
+    if (!vigs_gl_backend_init(&gl_backend_cgl->base)) {
+        goto fail5;
+    }
+
+    VIGS_LOG_DEBUG("created");
+
+    CGLDestroyPixelFormat(pixel_format);
+
+    return &gl_backend_cgl->base.base;
+
+fail5:
+    CGLDestroyContext(gl_backend_cgl->read_pixels_context);
+fail4:
+    CGLDestroyContext(gl_backend_cgl->context);
+fail3:
+    CGLDestroyPixelFormat(pixel_format);
+fail2:
+    dlclose(gl_backend_cgl->handle);
+fail1:
+    vigs_backend_cleanup(&gl_backend_cgl->base.base);
+
+    g_free(gl_backend_cgl);
+
+    return NULL;
+}
index f3544e7..773972b 100644 (file)
@@ -1,6 +1,6 @@
 obj-$(CONFIG_LINUX) += egl_glx/
 obj-$(CONFIG_WIN32) += egl_wgl/
-obj-$(CONFIG_DARWIN) += egl_agl/
+obj-$(CONFIG_DARWIN) += egl_cgl/
 obj-y += gles_ogl/
 obj-y += gles_onscreen/
 
diff --git a/hw/yagl/yagl_drivers/egl_agl/Makefile.objs b/hw/yagl/yagl_drivers/egl_agl/Makefile.objs
deleted file mode 100644 (file)
index 61fc900..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# EGL AGL driver
-QEMU_CFLAGS += -Wno-comment
-obj-y += yagl_egl_agl.o
diff --git a/hw/yagl/yagl_drivers/egl_agl/yagl_egl_agl.c b/hw/yagl/yagl_drivers/egl_agl/yagl_egl_agl.c
deleted file mode 100644 (file)
index 8fc1af3..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * yagl
- *
- * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact:
- * Stanislav Vorobiov <s.vorobiov@samsung.com>
- * Jinhyung Jo <jinhyung.jo@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-#include <OpenGL/OpenGL.h>
-#include <AGL/agl.h>
-#include <glib.h>
-#include "yagl_egl_driver.h"
-#include "yagl_dyn_lib.h"
-#include "yagl_log.h"
-#include "yagl_egl_native_config.h"
-#include "yagl_egl_surface_attribs.h"
-#include "yagl_process.h"
-#include "yagl_tls.h"
-#include "yagl_thread.h"
-
-#define LIBGL_IMAGE_NAME \
-"/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
-
-#define YAGL_LOG_AGL_STATUS() \
-    YAGL_LOG_ERROR("AGL status: %s", aglErrorString(aglGetError()))
-
-typedef struct YaglEglAglContext {
-    AGLContext context;
-} YaglEglAglContext;
-
-typedef struct YaglEglAglDriver {
-    struct yagl_egl_driver base;
-} YaglEglAglDriver;
-
-static EGLNativeDisplayType
-yagl_egl_agl_display_open(struct yagl_egl_driver *driver)
-{
-    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_ENTER(yagl_egl_agl_display_close, "%p", 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)
-{
-    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,
-        AGL_MINIMUM_POLICY,
-        AGL_BUFFER_SIZE, 32,
-        AGL_RED_SIZE, 8,
-        AGL_GREEN_SIZE, 8,
-        AGL_BLUE_SIZE, 8,
-        AGL_ALPHA_SIZE, 8,
-        AGL_DEPTH_SIZE, 24,
-        AGL_STENCIL_SIZE, 8,
-        AGL_NO_RECOVERY,
-        AGL_DOUBLEBUFFER,
-        AGL_PBUFFER,
-        AGL_NONE
-    };
-    AGLPixelFormat pixfmt;
-
-    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);
-
-        cur_config = &egl_configs[usable_configs];
-
-        /* Initialize fields */
-        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_RED_SIZE, &cur_config->red_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);
-
-        cur_config->max_pbuffer_width = 4096;
-        cur_config->max_pbuffer_height = 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->frame_buffer_level = 0;
-        cur_config->samples_per_pixel = 0;
-        cur_config->max_swap_interval = 1000;
-        cur_config->min_swap_interval = 0;
-
-        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 */
-
-    *num_configs = usable_configs;
-    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)
-{
-    YAGL_LOG_FUNC_ENTER(yagl_egl_agl_config_cleanup,
-                        "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,
-                                              EGLContext share_context,
-                                              int version)
-{
-    YaglEglAglContext *egl_glc;
-    AGLContext agl_share_glc;
-
-    YAGL_LOG_FUNC_ENTER(yagl_egl_agl_context_create,
-                       "dpy = %p, share_context = %p, cfgid=%d",
-                       egl_dpy, 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 = 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:
-    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,
-                                      EGLSurface egl_read_surf,
-                                      EGLContext egl_glc)
-{
-    AGLContext context = NULL;
-    AGLPbuffer draw_buf = NULL;
-    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);
-
-    if (egl_glc != EGL_NO_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;
-    }
-
-    YAGL_LOG_FUNC_EXIT("context %p was made current", context);
-
-    return true;
-
- 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);
-
-    if (egl_glc != EGL_NO_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,
-                                                      EGLint height,
-                                                      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);
-
-    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;
-
- 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");
-    }
-}
-
-static void yagl_egl_agl_destroy(struct yagl_egl_driver *driver)
-{
-    YAGL_LOG_FUNC_ENTER(yagl_egl_agl_destroy, NULL);
-
-    yagl_egl_driver_cleanup(driver);
-
-    g_free(driver);
-
-    YAGL_LOG_FUNC_EXIT(NULL);
-}
-
-struct yagl_egl_driver *yagl_egl_driver_create(void *display)
-{
-    YaglEglAglDriver *egl_agl;
-    struct yagl_egl_driver *egl_driver;
-
-    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->display_open = &yagl_egl_agl_display_open;
-    egl_driver->display_close = &yagl_egl_agl_display_close;
-    egl_driver->config_enum = &yagl_egl_agl_config_enum;
-    egl_driver->config_cleanup = &yagl_egl_agl_config_cleanup;
-    egl_driver->pbuffer_surface_create = &yagl_egl_agl_pbuffer_surface_create;
-    egl_driver->pbuffer_surface_destroy = &yagl_egl_agl_pbuffer_surface_destroy;
-    egl_driver->context_create = &yagl_egl_agl_context_create;
-    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)) {
-        YAGL_LOG_ERROR("Loading %s failed with error: %s",
-                       LIBGL_IMAGE_NAME,
-                       yagl_dyn_lib_get_error(egl_driver->dyn_lib));
-        goto fail;
-    }
-
-    YAGL_LOG_FUNC_EXIT("EGL AGL driver created (%p)", egl_driver);
-
-    return egl_driver;
-
- fail:
-    yagl_egl_driver_cleanup(egl_driver);
-    g_free(egl_agl);
-
- 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);
-
-    /* The dlsym code path is shared by Linux and Mac builds */
-    proc = yagl_dyn_lib_get_sym(dyn_lib, sym);
-
-    YAGL_LOG_FUNC_EXIT("%s address: %p", sym, proc);
-
-    return proc;
-}
diff --git a/hw/yagl/yagl_drivers/egl_cgl/Makefile.objs b/hw/yagl/yagl_drivers/egl_cgl/Makefile.objs
new file mode 100644 (file)
index 0000000..4dce0c7
--- /dev/null
@@ -0,0 +1,3 @@
+# EGL CGL driver
+QEMU_CFLAGS += -Wno-comment
+obj-y += yagl_egl_cgl.o
diff --git a/hw/yagl/yagl_drivers/egl_cgl/yagl_egl_cgl.c b/hw/yagl/yagl_drivers/egl_cgl/yagl_egl_cgl.c
new file mode 100644 (file)
index 0000000..32839a6
--- /dev/null
@@ -0,0 +1,507 @@
+/*
+ * yagl
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Stanislav Vorobiov <s.vorobiov@samsung.com>
+ * Jinhyung Jo <jinhyung.jo@samsung.com>
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <GL/gl.h>
+#include <OpenGL/OpenGL.h>
+#include "yagl_egl_driver.h"
+#include "yagl_dyn_lib.h"
+#include "yagl_log.h"
+#include "yagl_egl_native_config.h"
+#include "yagl_egl_surface_attribs.h"
+#include "yagl_process.h"
+#include "yagl_tls.h"
+#include "yagl_thread.h"
+
+#define LIBGL_IMAGE_NAME \
+"/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib"
+
+#ifndef kCGLPFAOpenGLProfile
+#   define kCGLPFAOpenGLProfile 99
+#   define kCGLOGLPVersion_3_2_Core 0x3200
+#   define kCGLOGLPVersion_Legacy 0x1000
+#endif
+
+static const CGLPixelFormatAttribute pixel_format_legacy_attrs[] =
+{
+    kCGLPFAAccelerated,
+    kCGLPFAMinimumPolicy,
+    kCGLPFAColorSize, 32,
+    kCGLPFAAlphaSize, 8,
+    kCGLPFADepthSize, 24,
+    kCGLPFAStencilSize, 8,
+    kCGLPFANoRecovery,
+    kCGLPFAPBuffer,
+    0
+};
+
+static const CGLPixelFormatAttribute pixel_format_3_2_core_attrs[] =
+{
+    kCGLPFAAccelerated,
+    kCGLPFAMinimumPolicy,
+    kCGLPFAColorSize, 32,
+    kCGLPFAAlphaSize, 8,
+    kCGLPFADepthSize, 24,
+    kCGLPFAStencilSize, 8,
+    kCGLPFANoRecovery,
+    kCGLPFAOpenGLProfile, kCGLOGLPVersion_3_2_Core,
+    0
+};
+
+struct yagl_egl_cgl
+{
+    struct yagl_egl_driver base;
+
+    CGLPixelFormatObj pixel_format_legacy;
+    CGLPixelFormatObj pixel_format_3_2_core;
+};
+
+struct yagl_egl_cgl_context
+{
+    CGLContextObj base;
+
+    bool is_3_2_core;
+};
+
+static bool yagl_egl_cgl_get_gl_version(struct yagl_egl_cgl *egl_cgl,
+                                        yagl_gl_version *version)
+{
+    CGLError error;
+    bool res = false;
+    const char *tmp;
+    CGLPixelFormatObj pixel_format;
+    int n;
+
+    YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_get_gl_version, NULL);
+
+    tmp = getenv("GL_VERSION");
+
+    if (tmp) {
+        if (strcmp(tmp, "2") == 0) {
+            YAGL_LOG_INFO("GL_VERSION forces OpenGL version to 2.1");
+            *version = yagl_gl_2;
+            res = true;
+        } else if (strcmp(tmp, "3_2") == 0) {
+            YAGL_LOG_INFO("GL_VERSION forces OpenGL version to 3.2");
+            *version = yagl_gl_3_2;
+            res = true;
+        } else {
+            YAGL_LOG_CRITICAL("Bad GL_VERSION value = %s", tmp);
+        }
+
+        goto out;
+    }
+
+    error = CGLChoosePixelFormat(pixel_format_3_2_core_attrs,
+                                 &pixel_format,
+                                 &n);
+
+    if (error) {
+        YAGL_LOG_INFO("CGLChoosePixelFormat failed for 3_2_core attrs: %s, using OpenGL 2.1", CGLErrorString(error));
+        *version = yagl_gl_2;
+        res = true;
+        goto out;
+    }
+
+    if (!pixel_format) {
+        YAGL_LOG_INFO("CGLChoosePixelFormat failed to find formats for 3_2_core attrs, using OpenGL 2.1");
+        *version = yagl_gl_2;
+        res = true;
+        goto out;
+    }
+
+    CGLDestroyPixelFormat(pixel_format);
+
+    YAGL_LOG_INFO("Using OpenGL 3.2");
+    *version = yagl_gl_3_2;
+    res = true;
+
+out:
+    if (res) {
+        YAGL_LOG_FUNC_EXIT("%d, version = %u", res, *version);
+    } else {
+        YAGL_LOG_FUNC_EXIT("%d", res);
+    }
+
+    return res;
+}
+
+static EGLNativeDisplayType yagl_egl_cgl_display_open(struct yagl_egl_driver *driver)
+{
+    YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_display_open, NULL);
+
+    YAGL_LOG_FUNC_EXIT("%p", (void*)1);
+
+    return (EGLNativeDisplayType)1;
+}
+
+static void yagl_egl_cgl_display_close(struct yagl_egl_driver *driver,
+                                       EGLNativeDisplayType dpy)
+{
+    YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_display_close, "%p", dpy);
+
+    YAGL_LOG_FUNC_EXIT(NULL);
+}
+
+static struct yagl_egl_native_config
+    *yagl_egl_cgl_config_enum(struct yagl_egl_driver *driver,
+                              EGLNativeDisplayType dpy,
+                              int *num_configs)
+{
+    struct yagl_egl_native_config *cfg = NULL;
+
+    YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_config_enum, "%p", dpy);
+
+    YAGL_LOG_TRACE("got 1 config");
+
+    cfg = g_malloc0(sizeof(*cfg));
+
+    yagl_egl_native_config_init(cfg);
+
+    cfg->red_size = 8;
+    cfg->green_size = 8;
+    cfg->blue_size = 8;
+    cfg->alpha_size = 8;
+    cfg->buffer_size = 32;
+    cfg->caveat = EGL_NONE;
+    cfg->config_id = 1;
+    cfg->frame_buffer_level = 0;
+    cfg->depth_size = 24;
+    cfg->max_pbuffer_width = 4096;
+    cfg->max_pbuffer_height = 4096;
+    cfg->max_pbuffer_size = 4096 * 4096;
+    cfg->max_swap_interval = 1000;
+    cfg->min_swap_interval = 0;
+    cfg->native_visual_id = 0;
+    cfg->native_visual_type = EGL_NONE;
+    cfg->samples_per_pixel = 0;
+    cfg->stencil_size = 8;
+    cfg->transparent_type = EGL_NONE;
+    cfg->trans_red_val = 0;
+    cfg->trans_green_val = 0;
+    cfg->trans_blue_val = 0;
+    cfg->driver_data = NULL;
+
+    *num_configs = 1;
+
+    YAGL_LOG_FUNC_EXIT(NULL);
+
+    return cfg;
+}
+
+static void yagl_egl_cgl_config_cleanup(struct yagl_egl_driver *driver,
+                                        EGLNativeDisplayType dpy,
+                                        const struct yagl_egl_native_config *cfg)
+{
+    YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_config_cleanup,
+                        "dpy = %p, cfg = %d",
+                        dpy,
+                        cfg->config_id);
+
+    YAGL_LOG_FUNC_EXIT(NULL);
+}
+
+static EGLSurface yagl_egl_cgl_pbuffer_surface_create(struct yagl_egl_driver *driver,
+                                                      EGLNativeDisplayType dpy,
+                                                      const struct yagl_egl_native_config *cfg,
+                                                      EGLint width,
+                                                      EGLint height,
+                                                      const struct yagl_egl_pbuffer_attribs *attribs)
+{
+    CGLPBufferObj pbuffer = NULL;
+    CGLError error;
+
+    YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_pbuffer_surface_create,
+                        "dpy = %p, width = %d, height = %d",
+                        dpy,
+                        width,
+                        height);
+
+    error = CGLCreatePBuffer(width, height, GL_TEXTURE_2D, GL_RGBA,
+                             0, &pbuffer);
+
+    if (error) {
+        YAGL_LOG_ERROR("CGLCreatePBuffer failed: %s", CGLErrorString(error));
+        pbuffer = NULL;
+    }
+
+    YAGL_LOG_FUNC_EXIT("%p", pbuffer);
+
+    return pbuffer;
+}
+
+static void yagl_egl_cgl_pbuffer_surface_destroy(struct yagl_egl_driver *driver,
+                                                 EGLNativeDisplayType dpy,
+                                                 EGLSurface sfc)
+{
+    CGLError error;
+
+    YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_pbuffer_surface_destroy,
+                        "dpy = %p, sfc = %p",
+                        dpy,
+                        sfc);
+
+    error = CGLDestroyPBuffer((CGLPBufferObj)sfc);
+
+    if (error) {
+        YAGL_LOG_ERROR("CGLDestroyPBuffer failed: %s", CGLErrorString(error));
+    }
+
+    YAGL_LOG_FUNC_EXIT(NULL);
+}
+
+static EGLContext yagl_egl_cgl_context_create(struct yagl_egl_driver *driver,
+                                              EGLNativeDisplayType dpy,
+                                              const struct yagl_egl_native_config *cfg,
+                                              EGLContext share_context,
+                                              int version)
+{
+    struct yagl_egl_cgl *egl_cgl = (struct yagl_egl_cgl*)driver;
+    struct yagl_egl_cgl_context *ctx = NULL;
+    CGLContextObj share_ctx;
+    CGLError error;
+
+    YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_context_create,
+                        "dpy = %p, share_context = %p, version = %d",
+                        dpy,
+                        share_context,
+                        version);
+
+    ctx = g_malloc0(sizeof(*ctx));
+
+    if (share_context != EGL_NO_CONTEXT) {
+        share_ctx = ((struct yagl_egl_cgl_context*)share_context)->base;
+    } else {
+        share_ctx = NULL;
+    }
+
+    if ((egl_cgl->base.gl_version > yagl_gl_2) && (version != 1)) {
+        error = CGLCreateContext(egl_cgl->pixel_format_3_2_core,
+                                 share_ctx,
+                                 &ctx->base);
+        ctx->is_3_2_core = true;
+    } else {
+        error = CGLCreateContext(egl_cgl->pixel_format_legacy,
+                                 share_ctx,
+                                 &ctx->base);
+        ctx->is_3_2_core = false;
+    }
+
+    if (error) {
+        YAGL_LOG_ERROR("CGLCreateContext failed: %s", CGLErrorString(error));
+        g_free(ctx);
+        ctx = NULL;
+    }
+
+    YAGL_LOG_FUNC_EXIT("%p", ctx);
+
+    return (EGLContext)ctx;
+}
+
+static void yagl_egl_cgl_context_destroy(struct yagl_egl_driver *driver,
+                                         EGLNativeDisplayType dpy,
+                                         EGLContext ctx)
+{
+    CGLError error;
+
+    YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_context_destroy,
+                        "dpy = %p, ctx = %p",
+                        dpy,
+                        ctx);
+
+    error = CGLDestroyContext(((struct yagl_egl_cgl_context*)ctx)->base);
+
+    if (error) {
+        YAGL_LOG_ERROR("CGLDestroyContext failed: %s", CGLErrorString(error));
+    }
+
+    g_free(ctx);
+
+    YAGL_LOG_FUNC_EXIT(NULL);
+}
+
+static bool yagl_egl_cgl_make_current(struct yagl_egl_driver *driver,
+                                      EGLNativeDisplayType dpy,
+                                      EGLSurface draw,
+                                      EGLSurface read,
+                                      EGLContext ctx)
+{
+    struct yagl_egl_cgl_context *cgl_ctx = (struct yagl_egl_cgl_context*)ctx;
+    CGLPBufferObj draw_pbuffer = (CGLPBufferObj)draw;
+    CGLPBufferObj read_pbuffer = (CGLPBufferObj)read;
+    CGLError error;
+
+    YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_make_current,
+                        "dpy = %p, draw = %p, read = %p, ctx = %p",
+                        dpy,
+                        draw,
+                        read,
+                        ctx);
+
+    if (cgl_ctx && !cgl_ctx->is_3_2_core) {
+        if (read_pbuffer) {
+            error = CGLSetPBuffer(cgl_ctx->base, read_pbuffer, 0, 0, 0);
+
+            if (error) {
+                YAGL_LOG_ERROR("CGLSetPBuffer failed for read: %s", CGLErrorString(error));
+                goto fail;
+            }
+        }
+
+        if (draw_pbuffer) {
+            error = CGLSetPBuffer(cgl_ctx->base, draw_pbuffer, 0, 0, 0);
+
+            if (error) {
+                YAGL_LOG_ERROR("CGLSetPBuffer failed for draw: %s", CGLErrorString(error));
+                goto fail;
+            }
+        }
+    }
+
+    error = CGLSetCurrentContext(cgl_ctx ? cgl_ctx->base : NULL);
+
+    if (error) {
+        YAGL_LOG_ERROR("CGLSetCurrentContext failed: %s", CGLErrorString(error));
+        goto fail;
+    }
+
+    YAGL_LOG_FUNC_EXIT("context %p was made current", cgl_ctx);
+
+    return true;
+
+fail:
+    YAGL_LOG_FUNC_EXIT("Failed to make context %p current", cgl_ctx);
+
+    return false;
+}
+
+static void yagl_egl_cgl_destroy(struct yagl_egl_driver *driver)
+{
+    struct yagl_egl_cgl *egl_cgl = (struct yagl_egl_cgl*)driver;
+
+    YAGL_LOG_FUNC_ENTER(yagl_egl_cgl_destroy, NULL);
+
+    CGLDestroyPixelFormat(egl_cgl->pixel_format_legacy);
+    if (egl_cgl->pixel_format_3_2_core) {
+        CGLDestroyPixelFormat(egl_cgl->pixel_format_3_2_core);
+    }
+
+    yagl_egl_driver_cleanup(&egl_cgl->base);
+
+    g_free(egl_cgl);
+
+    YAGL_LOG_FUNC_EXIT(NULL);
+}
+
+struct yagl_egl_driver *yagl_egl_driver_create(void *display)
+{
+    CGLError error;
+    struct yagl_egl_cgl *egl_cgl;
+    int n;
+
+    YAGL_LOG_FUNC_ENTER(yagl_egl_driver_create, NULL);
+
+    egl_cgl = g_malloc0(sizeof(*egl_cgl));
+
+    yagl_egl_driver_init(&egl_cgl->base);
+
+    egl_cgl->base.dyn_lib = yagl_dyn_lib_create();
+
+    if (!egl_cgl->base.dyn_lib) {
+        goto fail;
+    }
+
+    if (!yagl_dyn_lib_load(egl_cgl->base.dyn_lib, LIBGL_IMAGE_NAME)) {
+        YAGL_LOG_ERROR("Unable to load " LIBGL_IMAGE_NAME ": %s",
+                       yagl_dyn_lib_get_error(egl_cgl->base.dyn_lib));
+        goto fail;
+    }
+
+    if (!yagl_egl_cgl_get_gl_version(egl_cgl, &egl_cgl->base.gl_version)) {
+        goto fail;
+    }
+
+    error = CGLChoosePixelFormat(pixel_format_legacy_attrs,
+                                 &egl_cgl->pixel_format_legacy,
+                                 &n);
+
+    if (error) {
+        YAGL_LOG_ERROR("CGLChoosePixelFormat failed for legacy attrs: %s", CGLErrorString(error));
+        goto fail;
+    }
+
+    if (!egl_cgl->pixel_format_legacy) {
+        YAGL_LOG_ERROR("CGLChoosePixelFormat failed to find formats for legacy attrs");
+        goto fail;
+    }
+
+    if (egl_cgl->base.gl_version >= yagl_gl_3_2) {
+        error = CGLChoosePixelFormat(pixel_format_3_2_core_attrs,
+                                     &egl_cgl->pixel_format_3_2_core,
+                                     &n);
+
+        if (error) {
+            YAGL_LOG_ERROR("CGLChoosePixelFormat failed for 3_2_core attrs: %s", CGLErrorString(error));
+            goto fail;
+        }
+
+        if (!egl_cgl->pixel_format_3_2_core) {
+            YAGL_LOG_ERROR("CGLChoosePixelFormat failed to find formats for 3_2_core attrs");
+            goto fail;
+        }
+    }
+
+    egl_cgl->base.display_open = &yagl_egl_cgl_display_open;
+    egl_cgl->base.display_close = &yagl_egl_cgl_display_close;
+    egl_cgl->base.config_enum = &yagl_egl_cgl_config_enum;
+    egl_cgl->base.config_cleanup = &yagl_egl_cgl_config_cleanup;
+    egl_cgl->base.pbuffer_surface_create = &yagl_egl_cgl_pbuffer_surface_create;
+    egl_cgl->base.pbuffer_surface_destroy = &yagl_egl_cgl_pbuffer_surface_destroy;
+    egl_cgl->base.context_create = &yagl_egl_cgl_context_create;
+    egl_cgl->base.context_destroy = &yagl_egl_cgl_context_destroy;
+    egl_cgl->base.make_current = &yagl_egl_cgl_make_current;
+    egl_cgl->base.destroy = &yagl_egl_cgl_destroy;
+
+    YAGL_LOG_FUNC_EXIT(NULL);
+
+    return &egl_cgl->base;
+
+fail:
+    yagl_egl_driver_cleanup(&egl_cgl->base);
+    g_free(egl_cgl);
+
+    YAGL_LOG_FUNC_EXIT(NULL);
+
+    return NULL;
+}
+
+void *yagl_dyn_lib_get_ogl_procaddr(struct yagl_dyn_lib *dyn_lib,
+                                    const char *sym_name)
+{
+    return yagl_dyn_lib_get_sym(dyn_lib, sym_name);
+}