summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorStanislav Vorobiov <s.vorobiov@samsung.com>2014-02-22 17:39:08 +0400
committerStanislav Vorobiov <s.vorobiov@samsung.com>2014-02-22 17:40:50 +0400
commit45cdbe450359cead30da060e5a89e45818d856e9 (patch)
treed4335d6e9647c7e347d7dbc53c70dd180501b14e /hw
parentb07dd0fc1d12de73337896a5a8aa3287d17b9a25 (diff)
downloadqemu-45cdbe450359cead30da060e5a89e45818d856e9.tar.gz
qemu-45cdbe450359cead30da060e5a89e45818d856e9.tar.bz2
qemu-45cdbe450359cead30da060e5a89e45818d856e9.zip
VIGS/YaGL: Use CGL instead of AGL
AGL is a deprecated API and it doesn't allow one to create OpenGL 3.2 contexts, so use CGL instead Change-Id: Iaa63fee0aeda7348c256f177b3a96b10142870d4
Diffstat (limited to 'hw')
-rw-r--r--hw/vigs/Makefile.objs4
-rw-r--r--hw/vigs/vigs_gl_backend_agl.c364
-rw-r--r--hw/vigs/vigs_gl_backend_cgl.c378
-rw-r--r--hw/yagl/yagl_drivers/Makefile.objs2
-rw-r--r--hw/yagl/yagl_drivers/egl_agl/Makefile.objs3
-rw-r--r--hw/yagl/yagl_drivers/egl_agl/yagl_egl_agl.c408
-rw-r--r--hw/yagl/yagl_drivers/egl_cgl/Makefile.objs3
-rw-r--r--hw/yagl/yagl_drivers/egl_cgl/yagl_egl_cgl.c507
8 files changed, 891 insertions, 778 deletions
diff --git a/hw/vigs/Makefile.objs b/hw/vigs/Makefile.objs
index b227b1c913..93f7e3b8d9 100644
--- a/hw/vigs/Makefile.objs
+++ b/hw/vigs/Makefile.objs
@@ -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
index 9ee6c05e8f..0000000000
--- a/hw/vigs/vigs_gl_backend_agl.c
+++ /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
index 0000000000..2112138333
--- /dev/null
+++ b/hw/vigs/vigs_gl_backend_cgl.c
@@ -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;
+}
diff --git a/hw/yagl/yagl_drivers/Makefile.objs b/hw/yagl/yagl_drivers/Makefile.objs
index f3544e70aa..773972b341 100644
--- a/hw/yagl/yagl_drivers/Makefile.objs
+++ b/hw/yagl/yagl_drivers/Makefile.objs
@@ -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
index 61fc900f32..0000000000
--- a/hw/yagl/yagl_drivers/egl_agl/Makefile.objs
+++ /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
index 8fc1af323c..0000000000
--- a/hw/yagl/yagl_drivers/egl_agl/yagl_egl_agl.c
+++ /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
index 0000000000..4dce0c752e
--- /dev/null
+++ b/hw/yagl/yagl_drivers/egl_cgl/Makefile.objs
@@ -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
index 0000000000..32839a6d7f
--- /dev/null
+++ b/hw/yagl/yagl_drivers/egl_cgl/yagl_egl_cgl.c
@@ -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);
+}