check-gl: updated for YaGL/VIGS 53/18753/1
authorStanislav Vorobiov <s.vorobiov@samsung.com>
Fri, 28 Mar 2014 14:25:30 +0000 (18:25 +0400)
committerStanislav Vorobiov <s.vorobiov@samsung.com>
Mon, 31 Mar 2014 09:30:09 +0000 (13:30 +0400)
Change-Id: Ie6421de6ccb0b9a3a2460d114950a9fb190f4d95
Signed-off-by: Stanislav Vorobiov <s.vorobiov@samsung.com>
Makefile.target
tizen/src/check_gl.c
tizen/src/check_gl.h [new file with mode: 0644]
tizen/src/check_gl_cgl.c [new file with mode: 0644]
tizen/src/check_gl_glx.c [new file with mode: 0644]
tizen/src/check_gl_wgl.c [new file with mode: 0644]

index 3fa46ab..df09d20 100644 (file)
@@ -178,31 +178,37 @@ $(QEMU_PROG): $(all-obj-y) ../libqemuutil.a ../libqemustub.a
        $(call LINK,$^)
 endif
 
-CHECK_GL_OBJS = check_gl.o gloffscreen_test.o gloffscreen_common.o 
+CHECK_GL_OBJS = check_gl.o
 CHECK_GL_LDFLAGS =
 CHECK_GL_TARGET =
 ifdef CONFIG_LINUX
-CHECK_GL_OBJS += gloffscreen_xcomposite.o
+CHECK_GL_OBJS += check_gl_glx.o
 #CHECK_GL_LDFLAGS += -lGL -lXcomposite -lXext -lglib-2.0
 # Fix linking error on Ubuntu 13.04
-CHECK_GL_LDFLAGS += -lGL -lXcomposite -lX11 -lXext -lglib-2.0
+CHECK_GL_LDFLAGS += -lX11 -lXext -lglib-2.0
 CHECK_GL_TARGET = check-gl
 endif
 ifdef CONFIG_WIN32
-CHECK_GL_OBJS += gloffscreen_wgl.o
-CHECK_GL_LDFLAGS += -fstack-protector `pkg-config --libs glib-2.0` -lopengl32 -lglu32 -lgdi32
+CHECK_GL_OBJS += check_gl_wgl.o
+CHECK_GL_LDFLAGS += -fstack-protector `pkg-config --libs glib-2.0` -lgdi32
 CHECK_GL_TARGET = check-gl.exe
 endif
 ifdef CONFIG_DARWIN
-CHECK_GL_OBJS += gloffscreen_agl.o
-CHECK_GL_LDFLAGS += -mmacosx-version-min=10.4 `pkg-config --cflags --libs glib-2.0` -framework GLUT -framework OpenGL -framework AGL
+CHECK_GL_OBJS += check_gl_cgl.o
+CHECK_GL_LDFLAGS += -mmacosx-version-min=10.4 `pkg-config --cflags --libs glib-2.0` -framework OpenGL
 CHECK_GL_TARGET = check-gl
 endif
 
-check-gl: check_gl.o
+check-gl: $(CHECK_GL_OBJS)
        gcc -o $(CHECK_GL_TARGET) $(CHECK_GL_OBJS) $(CHECK_GL_LDFLAGS)
 check_gl.o: check_gl.c
-       gcc -c ../tizen/src/check_gl.c
+       gcc -c ../tizen/src/check_gl.c -I../hw/yagl/yagl_inc
+check_gl_glx.o: check_gl_glx.c
+       gcc -c ../tizen/src/check_gl_glx.c -I../hw/yagl/yagl_inc
+check_gl_wgl.o: check_gl_wgl.c
+       gcc -c ../tizen/src/check_gl_wgl.c -I../hw/yagl/yagl_inc
+check_gl_cgl.o: check_gl_cgl.c
+       gcc -c ../tizen/src/check_gl_cgl.c -I../hw/yagl/yagl_inc
 
 gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
        $(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES),"  GEN   $(TARGET_DIR)$@")
index 1d83edb..a2815b3 100644 (file)
@@ -1,7 +1,220 @@
-#include "hw/gloffscreen_test.h"
-#include "debug_ch.h"
+/*
+ * Copyright (c) 2011 - 2014 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
+ *
+ */
 
-int main (int argc, char** argv)
+#include "check_gl.h"
+#include <GL/gl.h>
+#include <GL/glext.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+static const char *log_level_str[gl_error + 1] =
+{
+    "INFO",
+    "WARN",
+    "ERROR"
+};
+
+static const char *gl_version_str[gl_3_2 + 1] =
+{
+    "2.1",
+    "3.1",
+    "3.2"
+};
+
+void check_gl_log(gl_log_level level, const char *format, ...)
+{
+    va_list args;
+
+    fprintf(stderr, "%-5s", log_level_str[level]);
+
+    va_start(args, format);
+    fprintf(stderr, " - ");
+    vfprintf(stderr, format, args);
+    va_end(args);
+
+    fprintf(stderr, "\n");
+}
+
+static const GLubyte *(GLAPIENTRY *get_string)(GLenum);
+static const GLubyte *(GLAPIENTRY *get_stringi)(GLenum, GLuint);
+static void (GLAPIENTRY *get_integerv)(GLenum, GLint*);
+
+static struct gl_context *check_gl_version(gl_version version)
 {
-       return gl_acceleration_capability_check();
+    struct gl_context *ctx = NULL;
+    int hw = 1;
+
+    ctx = check_gl_context_create(NULL, version);
+
+    if (!ctx) {
+        goto fail;
+    }
+
+    if (!check_gl_make_current(ctx)) {
+        goto fail;
+    }
+
+    if ((strstr((const char*)get_string(GL_RENDERER), "Software") != NULL)) {
+        check_gl_log(gl_warn,
+                     "Host OpenGL %s - software",
+                     gl_version_str[version]);
+        hw = 0;
+    } else if (strncmp((const char*)get_string(GL_VERSION),
+                       "1.4", strlen("1.4")) == 0) {
+        /*
+         * Handle LIBGL_ALWAYS_INDIRECT=1 case.
+         */
+        check_gl_log(gl_warn,
+                     "Host OpenGL %s - NOT supported",
+                     gl_version_str[version]);
+        hw = 0;
+    } else {
+        check_gl_log(gl_info,
+                     "Host OpenGL %s - supported",
+                     gl_version_str[version]);
+    }
+
+    check_gl_log(gl_info, "+ GL_VENDOR = %s", (const char*)get_string(GL_VENDOR));
+    check_gl_log(gl_info, "+ GL_RENDERER = %s", (const char*)get_string(GL_RENDERER));
+    check_gl_log(gl_info, "+ GL_VERSION = %s", (const char*)get_string(GL_VERSION));
+
+    if (!hw) {
+        check_gl_context_destroy(ctx);
+        ctx = NULL;
+    }
+
+    check_gl_make_current(NULL);
+
+    return ctx;
+
+fail:
+    if (ctx) {
+        check_gl_context_destroy(ctx);
+    }
+
+    check_gl_log(gl_info,
+                 "Host OpenGL %s - NOT supported",
+                 gl_version_str[version]);
+
+    return NULL;
+}
+
+int main(int argc, char *argv[])
+{
+    struct gl_context *ctx_2;
+    struct gl_context *ctx_3_1;
+    struct gl_context *ctx_3_2;
+    int have_es3 = 0;
+    int have_es1 = 0;
+
+    if (!check_gl_init()) {
+        return 1;
+    }
+
+    if (!check_gl_procaddr((void**)&get_string, "glGetString", 0) ||
+        !check_gl_procaddr((void**)&get_stringi, "glGetStringi", 1) ||
+        !check_gl_procaddr((void**)&get_integerv, "glGetIntegerv", 0)) {
+        return 1;
+    }
+
+    ctx_2 = check_gl_version(gl_2);
+    ctx_3_1 = check_gl_version(gl_3_1);
+    ctx_3_2 = check_gl_version(gl_3_2);
+
+    if (!ctx_2 && !ctx_3_1 && !ctx_3_2) {
+        check_gl_log(gl_info, "Host does not have hardware GL acceleration!");
+        return 1;
+    }
+
+    have_es1 = (ctx_2 != NULL);
+    have_es3 = (ctx_3_2 != NULL);
+
+    /*
+     * Check if GL_ARB_ES3_compatibility is supported within
+     * OpenGL 3.1 context.
+     */
+
+    if (ctx_3_1 && get_stringi && check_gl_make_current(ctx_3_1)) {
+        GLint i, num_extensions = 0;
+
+        get_integerv(GL_NUM_EXTENSIONS, &num_extensions);
+
+        for (i = 0; i < num_extensions; ++i) {
+            const char *tmp;
+
+            tmp = (const char*)get_stringi(GL_EXTENSIONS, i);
+
+            if (strcmp(tmp, "GL_ARB_ES3_compatibility") == 0) {
+                have_es3 = 1;
+                break;
+            }
+        }
+
+        check_gl_make_current(NULL);
+    }
+
+    /*
+     * Check if OpenGL 2.1 contexts can be shared with OpenGL 3.x contexts
+     */
+
+    if (ctx_2 && ((ctx_3_1 && have_es3) || ctx_3_2)) {
+        struct gl_context *ctx = NULL;
+
+        ctx = check_gl_context_create(((ctx_3_1 && have_es3) ? ctx_3_1
+                                                             : ctx_3_2),
+                                      gl_2);
+
+        if (ctx) {
+            if (check_gl_make_current(ctx)) {
+                check_gl_make_current(NULL);
+            } else {
+                have_es1 = 0;
+            }
+            check_gl_context_destroy(ctx);
+        } else {
+            have_es1 = 0;
+        }
+    }
+
+    if (have_es1) {
+        check_gl_log(gl_info, "Guest OpenGL ES v1_CM - supported");
+    } else {
+        check_gl_log(gl_warn, "Guest OpenGL ES v1_CM - NOT supported");
+    }
+    check_gl_log(gl_info, "Guest OpenGL ES 2.0 - supported");
+    if (have_es3) {
+        check_gl_log(gl_info, "Guest OpenGL ES 3.0 - supported");
+    } else {
+        check_gl_log(gl_warn, "Guest OpenGL ES 3.0 - NOT supported");
+    }
+
+    check_gl_log(gl_info, "Host has hardware GL acceleration!");
+
+    return 0;
 }
diff --git a/tizen/src/check_gl.h b/tizen/src/check_gl.h
new file mode 100644 (file)
index 0000000..3e761be
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011 - 2014 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
+ *
+ */
+
+#ifndef __CHECK_GL_H__
+#define __CHECK_GL_H__
+
+struct gl_context;
+
+typedef enum
+{
+    gl_info = 0,
+    gl_warn = 1,
+    gl_error = 2
+} gl_log_level;
+
+typedef enum
+{
+    gl_2 = 0,
+    gl_3_1 = 1,
+    gl_3_2 = 2
+} gl_version;
+
+void check_gl_log(gl_log_level level, const char *format, ...);
+
+int check_gl_init(void);
+
+struct gl_context *check_gl_context_create(struct gl_context *share_ctx,
+                                           gl_version version);
+
+int check_gl_make_current(struct gl_context *ctx);
+
+void check_gl_context_destroy(struct gl_context *ctx);
+
+int check_gl_procaddr(void **func, const char *sym, int opt);
+
+#endif
diff --git a/tizen/src/check_gl_cgl.c b/tizen/src/check_gl_cgl.c
new file mode 100644 (file)
index 0000000..c776325
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2011 - 2014 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 "check_gl.h"
+#include <OpenGL/OpenGL.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <assert.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
+
+struct gl_context
+{
+    CGLContextObj base;
+};
+
+static void *handle;
+
+int check_gl_init(void)
+{
+    handle = dlopen(LIBGL_IMAGE_NAME, RTLD_NOW | RTLD_GLOBAL);
+
+    if (!handle) {
+        check_gl_log(gl_error, "%s", dlerror());
+        return 0;
+    }
+
+    return 1;
+}
+
+struct gl_context *check_gl_context_create(struct gl_context *share_ctx,
+                                           gl_version version)
+{
+    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
+    };
+    CGLError error;
+    CGLPixelFormatObj pixel_format;
+    int n;
+    CGLContextObj base = NULL;
+    struct gl_context *ctx;
+
+    switch (version) {
+    case gl_2:
+        error = CGLChoosePixelFormat(pixel_format_legacy_attrs,
+                                     &pixel_format,
+                                     &n);
+
+        if (error || !pixel_format) {
+            break;
+        }
+
+        error = CGLCreateContext(pixel_format,
+                                 (share_ctx ? share_ctx->base : NULL),
+                                 &base);
+
+        CGLDestroyPixelFormat(pixel_format);
+
+        if (error) {
+            base = NULL;
+        }
+
+        break;
+    case gl_3_1:
+        break;
+    case gl_3_2:
+        error = CGLChoosePixelFormat(pixel_format_3_2_core_attrs,
+                                     &pixel_format,
+                                     &n);
+
+        if (error || !pixel_format) {
+            break;
+        }
+
+        error = CGLCreateContext(pixel_format,
+                                 (share_ctx ? share_ctx->base : NULL),
+                                 &base);
+
+        CGLDestroyPixelFormat(pixel_format);
+
+        if (error) {
+            base = NULL;
+        }
+
+        break;
+    default:
+        assert(0);
+        return NULL;
+    }
+
+    if (!base) {
+        return NULL;
+    }
+
+    ctx = malloc(sizeof(*ctx));
+
+    if (!ctx) {
+        CGLDestroyContext(base);
+        return NULL;
+    }
+
+    ctx->base = base;
+
+    return ctx;
+}
+
+int check_gl_make_current(struct gl_context *ctx)
+{
+    return !CGLSetCurrentContext(ctx ? ctx->base : NULL);
+}
+
+void check_gl_context_destroy(struct gl_context *ctx)
+{
+    CGLDestroyContext(ctx->base);
+    free(ctx);
+}
+
+int check_gl_procaddr(void **func, const char *sym, int opt)
+{
+    *func = dlsym(handle, sym);
+
+    if (!*func && !opt) {
+        check_gl_log(gl_error, "Unable to find symbol \"%s\"", sym);
+        return 0;
+    }
+
+    return 1;
+}
diff --git a/tizen/src/check_gl_glx.c b/tizen/src/check_gl_glx.c
new file mode 100644 (file)
index 0000000..f8c13a8
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2011 - 2014 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 "check_gl.h"
+#include <GL/glx.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <assert.h>
+
+#ifndef GLX_VERSION_1_4
+#error GL/glx.h must be equal to or greater than GLX 1.4
+#endif
+
+#define GLX_GET_PROC(func, sym) \
+    do { \
+        *(void**)(&func) = (void*)get_proc_address((const GLubyte*)#sym); \
+        if (!func) { \
+            check_gl_log(gl_error, "%s", dlerror()); \
+            return 0; \
+        } \
+    } while (0)
+
+struct gl_context
+{
+    GLXContext base;
+    GLXPbuffer sfc;
+};
+
+typedef void (*PFNGLXDESTROYCONTEXTPROC)(Display *dpy, GLXContext ctx);
+
+static void *handle;
+static Display *x_dpy;
+static GLXFBConfig x_config;
+static PFNGLXGETPROCADDRESSPROC get_proc_address;
+static PFNGLXCHOOSEFBCONFIGPROC choose_fb_config;
+static PFNGLXCREATEPBUFFERPROC create_pbuffer;
+static PFNGLXDESTROYPBUFFERPROC destroy_pbuffer;
+static PFNGLXCREATENEWCONTEXTPROC create_context;
+static PFNGLXDESTROYCONTEXTPROC destroy_context;
+static PFNGLXMAKECONTEXTCURRENTPROC make_current;
+
+/* GLX_ARB_create_context */
+static PFNGLXCREATECONTEXTATTRIBSARBPROC create_context_attribs;
+
+static int check_gl_error_handler(Display *dpy, XErrorEvent *e)
+{
+    return 0;
+}
+
+int check_gl_init(void)
+{
+    static const int config_attribs[] =
+    {
+        GLX_DOUBLEBUFFER, True,
+        GLX_RED_SIZE, 8,
+        GLX_GREEN_SIZE, 8,
+        GLX_BLUE_SIZE, 8,
+        GLX_ALPHA_SIZE, 8,
+        GLX_BUFFER_SIZE, 32,
+        GLX_DEPTH_SIZE, 24,
+        GLX_STENCIL_SIZE, 8,
+        GLX_RENDER_TYPE, GLX_RGBA_BIT,
+        GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
+        None
+    };
+    int n = 0;
+    GLXFBConfig *configs;
+
+    x_dpy = XOpenDisplay(NULL);
+
+    if (!x_dpy) {
+        check_gl_log(gl_error, "Unable to open X display");
+        return 0;
+    }
+
+    XSetErrorHandler(check_gl_error_handler);
+
+    handle = dlopen("libGL.so.1", RTLD_NOW | RTLD_GLOBAL);
+
+    if (!handle) {
+        check_gl_log(gl_error, "%s", dlerror());
+        return 0;
+    }
+
+    get_proc_address = dlsym(handle, "glXGetProcAddress");
+
+    if (!get_proc_address) {
+        get_proc_address = dlsym(handle, "glXGetProcAddressARB");
+    }
+
+    if (!get_proc_address) {
+        check_gl_log(gl_error, "%s", dlerror());
+        return 0;
+    }
+
+    GLX_GET_PROC(choose_fb_config, glXChooseFBConfig);
+    GLX_GET_PROC(create_pbuffer, glXCreatePbuffer);
+    GLX_GET_PROC(destroy_pbuffer, glXDestroyPbuffer);
+    GLX_GET_PROC(create_context, glXCreateNewContext);
+    GLX_GET_PROC(destroy_context, glXDestroyContext);
+    GLX_GET_PROC(make_current, glXMakeContextCurrent);
+    GLX_GET_PROC(create_context_attribs, glXCreateContextAttribsARB);
+
+    configs = choose_fb_config(x_dpy,
+                               DefaultScreen(x_dpy),
+                               config_attribs,
+                               &n);
+
+    if (!configs || (n <= 0)) {
+        check_gl_log(gl_error, "Unable to find suitable FB config");
+        return 0;
+    }
+
+    x_config = configs[0];
+
+    XFree(configs);
+
+    return 1;
+}
+
+struct gl_context *check_gl_context_create(struct gl_context *share_ctx,
+                                           gl_version version)
+{
+    static const int ctx_attribs_3_1[] =
+    {
+        GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+        GLX_CONTEXT_MINOR_VERSION_ARB, 1,
+        GLX_RENDER_TYPE, GLX_RGBA_TYPE,
+        GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
+        None
+    };
+    static const int ctx_attribs_3_2[] =
+    {
+        GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+        GLX_CONTEXT_MINOR_VERSION_ARB, 2,
+        GLX_RENDER_TYPE, GLX_RGBA_TYPE,
+        GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
+        None
+    };
+    static const int surface_attribs[] =
+    {
+        GLX_PBUFFER_WIDTH, 1,
+        GLX_PBUFFER_HEIGHT, 1,
+        GLX_LARGEST_PBUFFER, False,
+        None
+    };
+    GLXContext base;
+    GLXPbuffer sfc;
+    struct gl_context *ctx;
+
+    switch (version) {
+    case gl_2:
+        base = create_context(x_dpy,
+                              x_config,
+                              GLX_RGBA_TYPE,
+                              (share_ctx ? share_ctx->base : NULL),
+                              True);
+        break;
+    case gl_3_1:
+        base = create_context_attribs(x_dpy,
+                                      x_config,
+                                      (share_ctx ? share_ctx->base : NULL),
+                                      True,
+                                      ctx_attribs_3_1);
+        break;
+    case gl_3_2:
+        base = create_context_attribs(x_dpy,
+                                      x_config,
+                                      (share_ctx ? share_ctx->base : NULL),
+                                      True,
+                                      ctx_attribs_3_2);
+        break;
+    default:
+        assert(0);
+        return NULL;
+    }
+
+    if (!base) {
+        return NULL;
+    }
+
+    sfc = create_pbuffer(x_dpy,
+                         x_config,
+                         surface_attribs);
+
+    if (!sfc) {
+        destroy_context(x_dpy, base);
+        return NULL;
+    }
+
+    ctx = malloc(sizeof(*ctx));
+
+    if (!ctx) {
+        destroy_pbuffer(x_dpy, sfc);
+        destroy_context(x_dpy, base);
+        return NULL;
+    }
+
+    ctx->base = base;
+    ctx->sfc = sfc;
+
+    return ctx;
+}
+
+int check_gl_make_current(struct gl_context *ctx)
+{
+    return make_current(x_dpy,
+                        (ctx ? ctx->sfc : None),
+                        (ctx ? ctx->sfc : None),
+                        (ctx ? ctx->base : NULL));
+}
+
+void check_gl_context_destroy(struct gl_context *ctx)
+{
+    destroy_pbuffer(x_dpy, ctx->sfc);
+    destroy_context(x_dpy, ctx->base);
+    free(ctx);
+}
+
+int check_gl_procaddr(void **func, const char *sym, int opt)
+{
+    *func = (void*)get_proc_address((const GLubyte*)sym);
+
+    if (!*func) {
+        *func = dlsym(handle, sym);
+    }
+
+    if (!*func && !opt) {
+        check_gl_log(gl_error, "Unable to find symbol \"%s\"", sym);
+        return 0;
+    }
+
+    return 1;
+}
diff --git a/tizen/src/check_gl_wgl.c b/tizen/src/check_gl_wgl.c
new file mode 100644 (file)
index 0000000..f447c5a
--- /dev/null
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2011 - 2014 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 "check_gl.h"
+#include <windows.h>
+#include <wingdi.h>
+#include <GL/gl.h>
+#include <GL/wglext.h>
+#include <assert.h>
+
+#define WGL_GET_PROC(func, sym) \
+    do { \
+        *(void**)(&func) = (void*)GetProcAddress(handle, #sym); \
+        if (!func) { \
+            check_gl_log(gl_error, "Unable to load %s symbol", #sym); \
+            goto fail; \
+        } \
+    } while (0)
+
+#define WGL_GET_EXT_PROC(func, ext, sym) \
+    do { \
+        if ((strstr(ext_str, #ext " ") == NULL)) { \
+            check_gl_log(gl_error, "Extension %s not supported", #ext); \
+            goto fail; \
+        } \
+        *(void**)(&func) = (void*)get_proc_address((LPCSTR)#sym); \
+        if (!func) { \
+            check_gl_log(gl_error, "Unable to load %s symbol", #sym); \
+            goto fail; \
+        } \
+    } while (0)
+
+struct gl_context
+{
+    HGLRC base;
+    HPBUFFERARB sfc;
+    HDC sfc_dc;
+};
+
+typedef HGLRC (WINAPI *PFNWGLCREATECONTEXTPROC)(HDC hdl);
+typedef BOOL (WINAPI *PFNWGLDELETECONTEXTPROC)(HGLRC hdl);
+typedef PROC (WINAPI *PFNWGLGETPROCADDRESSPROC)(LPCSTR sym);
+typedef BOOL (WINAPI *PFNWGLMAKECURRENTPROC)(HDC dev_ctx, HGLRC rend_ctx);
+typedef BOOL (WINAPI *PFNWGLSHARELISTSPROC)(HGLRC ctx1, HGLRC ctx2);
+
+static HINSTANCE handle = NULL;
+static HWND init_win = NULL;
+static HDC init_dc = NULL;
+static HGLRC init_ctx = NULL;
+static HWND win = NULL;
+static HDC dc = NULL;
+static int config_id = 0;
+static struct gl_context *current = NULL;
+static PFNWGLCREATECONTEXTPROC create_context;
+static PFNWGLDELETECONTEXTPROC delete_context;
+static PFNWGLGETPROCADDRESSPROC get_proc_address;
+static PFNWGLMAKECURRENTPROC make_current;
+static PFNWGLSHARELISTSPROC share_lists;
+
+/* WGL extensions */
+static PFNWGLGETEXTENSIONSSTRINGEXTPROC get_extensions_string_ext;
+static PFNWGLGETEXTENSIONSSTRINGARBPROC get_extensions_string_arb;
+static PFNWGLCHOOSEPIXELFORMATARBPROC choose_pixel_format;
+static PFNWGLCREATEPBUFFERARBPROC create_pbuffer;
+static PFNWGLGETPBUFFERDCARBPROC get_pbuffer_dc;
+static PFNWGLRELEASEPBUFFERDCARBPROC release_pbuffer_dc;
+static PFNWGLDESTROYPBUFFERARBPROC destroy_pbuffer;
+
+/* WGL_ARB_create_context */
+static PFNWGLCREATECONTEXTATTRIBSARBPROC create_context_attribs;
+
+int check_gl_init(void)
+{
+    WNDCLASSEXA win_class;
+    PIXELFORMATDESCRIPTOR init_pixfmt =
+    {
+        .nSize = sizeof(PIXELFORMATDESCRIPTOR),
+        .nVersion = 1,
+        .dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
+        .iPixelType = PFD_TYPE_RGBA,
+        .cColorBits = 32,
+        .cDepthBits = 24,
+        .cStencilBits = 8,
+        .iLayerType = PFD_MAIN_PLANE,
+    };
+    int init_config_id = 0;
+    const char *ext_str = NULL;
+    const int config_attribs[] =
+    {
+        WGL_SUPPORT_OPENGL_ARB, TRUE,
+        WGL_DOUBLE_BUFFER_ARB, TRUE,
+        WGL_DRAW_TO_PBUFFER_ARB, TRUE,
+        WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
+        WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
+        WGL_RED_BITS_ARB, 8,
+        WGL_GREEN_BITS_ARB, 8,
+        WGL_BLUE_BITS_ARB, 8,
+        WGL_ALPHA_BITS_ARB, 8,
+        WGL_COLOR_BITS_ARB, 32,
+        WGL_DEPTH_BITS_ARB, 24,
+        WGL_STENCIL_BITS_ARB, 8,
+        0,
+    };
+    UINT n = 0;
+    PIXELFORMATDESCRIPTOR pixfmt;
+
+    win_class.cbSize = sizeof(WNDCLASSEXA);
+    win_class.style = 0;
+    win_class.lpfnWndProc = &DefWindowProcA;
+    win_class.cbClsExtra = 0;
+    win_class.cbWndExtra = 0;
+    win_class.hInstance = NULL;
+    win_class.hIcon = NULL;
+    win_class.hCursor = NULL;
+    win_class.hbrBackground = NULL;
+    win_class.lpszMenuName =  NULL;
+    win_class.lpszClassName = "CheckGLWinClass";
+    win_class.hIconSm = NULL;
+
+    if (!RegisterClassExA(&win_class)) {
+        check_gl_log(gl_error, "Unable to register window class");
+        return 0;
+    }
+
+    handle = LoadLibraryA("opengl32");
+
+    if (!handle) {
+        check_gl_log(gl_error, "Unable to load opengl32.dll");
+        goto fail;
+    }
+
+    WGL_GET_PROC(create_context, wglCreateContext);
+    WGL_GET_PROC(delete_context, wglDeleteContext);
+    WGL_GET_PROC(get_proc_address, wglGetProcAddress);
+    WGL_GET_PROC(make_current, wglMakeCurrent);
+    WGL_GET_PROC(share_lists, wglShareLists);
+
+    init_win = CreateWindow("CheckGLWinClass", "CheckGLWin",
+                            WS_DISABLED | WS_POPUP,
+                            0, 0, 1, 1, NULL, NULL, 0, 0);
+
+    if (!init_win) {
+        check_gl_log(gl_error, "Unable to create window");
+        goto fail;
+    }
+
+    init_dc = GetDC(init_win);
+
+    if (!init_dc) {
+        check_gl_log(gl_error, "Unable to get window DC");
+        goto fail;
+    }
+
+    init_config_id = ChoosePixelFormat(init_dc, &init_pixfmt);
+
+    if (!init_config_id) {
+        check_gl_log(gl_error, "ChoosePixelFormat failed");
+        goto fail;
+    }
+
+    if (!SetPixelFormat(init_dc, init_config_id, &init_pixfmt)) {
+        check_gl_log(gl_error, "SetPixelFormat failed");
+        goto fail;
+    }
+
+    init_ctx = create_context(init_dc);
+    if (!init_ctx) {
+        check_gl_log(gl_error, "wglCreateContext failed");
+        goto fail;
+    }
+
+    if (!make_current(init_dc, init_ctx)) {
+        check_gl_log(gl_error, "wglMakeCurrent failed");
+        goto fail;
+    }
+
+    /*
+     * WGL extensions couldn't be queried by glGetString(), we need to use
+     * wglGetExtensionsStringARB or wglGetExtensionsStringEXT for this, which
+     * themselves are extensions
+     */
+    get_extensions_string_arb = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
+        get_proc_address((LPCSTR)"wglGetExtensionsStringARB");
+    get_extensions_string_ext = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
+        get_proc_address((LPCSTR)"wglGetExtensionsStringEXT");
+
+    if (get_extensions_string_arb) {
+        ext_str = get_extensions_string_arb(init_dc);
+    } else if (get_extensions_string_ext) {
+        ext_str = get_extensions_string_ext();
+    }
+
+    if (!ext_str) {
+        check_gl_log(gl_error, "Unable to obtain WGL extension string");
+        goto fail;
+    }
+
+    WGL_GET_EXT_PROC(create_pbuffer, WGL_ARB_pbuffer, wglCreatePbufferARB);
+    WGL_GET_EXT_PROC(get_pbuffer_dc, WGL_ARB_pbuffer, wglGetPbufferDCARB);
+    WGL_GET_EXT_PROC(release_pbuffer_dc, WGL_ARB_pbuffer, wglReleasePbufferDCARB);
+    WGL_GET_EXT_PROC(destroy_pbuffer, WGL_ARB_pbuffer, wglDestroyPbufferARB);
+    WGL_GET_EXT_PROC(choose_pixel_format, WGL_ARB_pixel_format, wglChoosePixelFormatARB);
+    WGL_GET_EXT_PROC(create_context_attribs, WGL_ARB_create_context, wglCreateContextAttribsARB);
+
+    make_current(NULL, NULL);
+
+    win = CreateWindow("CheckGLWinClass", "CheckGLWin2",
+                       WS_DISABLED | WS_POPUP,
+                       0, 0, 1, 1, NULL, NULL, 0, 0);
+
+    if (!win) {
+        check_gl_log(gl_error, "Unable to create window");
+        goto fail;
+    }
+
+    dc = GetDC(win);
+
+    if (!dc) {
+        check_gl_log(gl_error, "Unable to get window DC");
+        goto fail;
+    }
+
+    if (!choose_pixel_format(dc,
+                             config_attribs,
+                             NULL,
+                             1,
+                             &config_id,
+                             &n) || (n == 0)) {
+        check_gl_log(gl_error, "wglChoosePixelFormat failed");
+        goto fail;
+    }
+
+    if (!DescribePixelFormat(dc,
+                             config_id,
+                             sizeof(PIXELFORMATDESCRIPTOR),
+                             &pixfmt)) {
+        check_gl_log(gl_error, "DescribePixelFormat failed");
+        goto fail;
+    }
+
+    if (!SetPixelFormat(dc,
+                        config_id,
+                        &pixfmt)) {
+        check_gl_log(gl_error, "SetPixelFormat failed");
+        goto fail;
+    }
+
+    return 1;
+
+fail:
+    if (dc) {
+        ReleaseDC(win, dc);
+    }
+    if (win) {
+        DestroyWindow(win);
+    }
+    if (init_ctx) {
+        make_current(NULL, NULL);
+        delete_context(init_ctx);
+    }
+    if (init_dc) {
+        ReleaseDC(init_win, init_dc);
+    }
+    if (init_win) {
+        DestroyWindow(init_win);
+    }
+    if (handle) {
+        FreeLibrary(handle);
+    }
+
+    UnregisterClassA((LPCTSTR)"CheckGLWinClass", NULL);
+
+    return 0;
+}
+
+struct gl_context *check_gl_context_create(struct gl_context *share_ctx,
+                                           gl_version version)
+{
+    static const int ctx_attribs_3_1[] =
+    {
+        WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
+        WGL_CONTEXT_MINOR_VERSION_ARB, 1,
+        WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
+        0
+    };
+    static const int ctx_attribs_3_2[] =
+    {
+        WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
+        WGL_CONTEXT_MINOR_VERSION_ARB, 2,
+        WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
+        0
+    };
+    static const int surface_attribs[] =
+    {
+        WGL_PBUFFER_LARGEST_ARB, FALSE,
+        WGL_TEXTURE_TARGET_ARB, WGL_NO_TEXTURE_ARB,
+        WGL_TEXTURE_FORMAT_ARB, WGL_NO_TEXTURE_ARB,
+        0
+    };
+    HGLRC base;
+    HPBUFFERARB sfc;
+    HDC sfc_dc;
+    struct gl_context *ctx;
+
+    switch (version) {
+    case gl_2:
+        base = create_context(dc);
+        if (share_ctx && !share_lists(share_ctx->base, base)) {
+            delete_context(base);
+            base = NULL;
+        }
+        break;
+    case gl_3_1:
+        base = create_context_attribs(dc,
+                                      (share_ctx ? share_ctx->base : NULL),
+                                      ctx_attribs_3_1);
+        break;
+    case gl_3_2:
+        base = create_context_attribs(dc,
+                                      (share_ctx ? share_ctx->base : NULL),
+                                      ctx_attribs_3_2);
+        break;
+    default:
+        assert(0);
+        return NULL;
+    }
+
+    if (!base) {
+        return NULL;
+    }
+
+    sfc = create_pbuffer(dc,
+                         config_id, 1, 1,
+                         surface_attribs);
+
+    if (!sfc) {
+        delete_context(base);
+        return NULL;
+    }
+
+    sfc_dc = get_pbuffer_dc(sfc);
+
+    if (!sfc_dc) {
+        destroy_pbuffer(sfc);
+        delete_context(base);
+        return NULL;
+    }
+
+    ctx = malloc(sizeof(*ctx));
+
+    if (!ctx) {
+        release_pbuffer_dc(sfc, sfc_dc);
+        destroy_pbuffer(sfc);
+        delete_context(base);
+        return NULL;
+    }
+
+    ctx->base = base;
+    ctx->sfc = sfc;
+    ctx->sfc_dc = sfc_dc;
+
+    return ctx;
+}
+
+int check_gl_make_current(struct gl_context *ctx)
+{
+    current = ctx;
+    return make_current((ctx ? ctx->sfc_dc : NULL),
+                        (ctx ? ctx->base : NULL));
+}
+
+void check_gl_context_destroy(struct gl_context *ctx)
+{
+    release_pbuffer_dc(ctx->sfc, ctx->sfc_dc);
+    destroy_pbuffer(ctx->sfc);
+    delete_context(ctx->base);
+    free(ctx);
+}
+
+int check_gl_procaddr(void **func, const char *sym, int opt)
+{
+    if (!make_current(init_dc, init_ctx)) {
+        return 0;
+    }
+
+    *func = (void*)get_proc_address((LPCSTR)sym);
+
+    if (!*func) {
+        *func = GetProcAddress(handle, sym);
+    }
+
+    make_current((current ? current->sfc_dc : NULL),
+                 (current ? current->base : NULL));
+
+    if (!*func && !opt) {
+        check_gl_log(gl_error, "Unable to find symbol \"%s\"", sym);
+        return 0;
+    }
+
+    return 1;
+}