openGL: load lobGL calls explicitly if openGLES support is enabled
authorIgor Mitsyanko <i.mitsyanko@samsung.com>
Mon, 20 Aug 2012 09:26:35 +0000 (13:26 +0400)
committerEvgeny Voevodin <e.voevodin@samsung.com>
Mon, 20 Aug 2012 12:51:58 +0000 (16:51 +0400)
If we enable openGLES support then QEMU links with libGL and`libGLES, which
has the same symbols. This results in unpredictable behaviour.

Open libGL explicitly if openGLES is enabled and use function handlers to call
openGL functions.

Signed-off-by: Igor Mitsyanko <i.mitsyanko@samsung.com>
14 files changed:
configure
tizen/emulator_configure_arm.sh
tizen/emulator_configure_arm_debug.sh
tizen/emulator_configure_x86.sh
tizen/emulator_configure_x86_debug.sh
tizen/src/Makefile.tizen
tizen/src/hw/gloffscreen_common.c
tizen/src/hw/gloffscreen_glx.c
tizen/src/hw/gloffscreen_test.c
tizen/src/hw/gloffscreen_wgl.c
tizen/src/hw/gloffscreen_xcomposite.c
tizen/src/hw/parse_gl_h.c
tizen/src/hw/virtio-gl-stub.c
tizen/src/maru_sdl.c

index a995aff..8e43d79 100755 (executable)
--- a/configure
+++ b/configure
@@ -3886,7 +3886,7 @@ if test "$gl" = "yes" ; then
     if test "$mingw32" = "yes" ; then
       echo "LIBS+=-lopengl32 -lglu32" >> $config_target_mak
     else
-      echo "LIBS+=-lGL -lGLU -lXcomposite -lXext -ldl" >> $config_target_mak
+      echo "LIBS+=-lGLU -ldl" >> $config_target_mak
     fi
   ;;
   *)
@@ -3970,6 +3970,9 @@ fi
 
 if test "$target_arch2" = "arm" -a "$opengles" = "yes" ; then
   echo "CONFIG_BUILD_GLES=y" >> $config_target_mak
+# When OpenGLES enabled, QEMU uses two libGL and libGLES with the same symbols
+# Explicitly load openGL symbols from host libGL library
+  cflags="-DMANGLE_OPENGL_SYMBOLS $cflags"
   if test "$mingw32" = "yes" ; then
     cflags="-mthreads $cflags"
     ldflags="-mthreads $ldflags"
index f7c2b8c..f9895ef 100755 (executable)
@@ -35,7 +35,7 @@ exec ./configure \
  --enable-maru \
  --disable-vnc \
  --enable-opengles \
- --enable-gl \
+ --disable-gl \
  --disable-pie
 ;;
 MINGW*)
@@ -59,7 +59,7 @@ exec ./configure \
  --enable-maru \
  --disable-vnc \
  --enable-opengles \
- --enable-gl $1
+ --disable-gl $1
 ;;
 Darwin*)
 cd distrib/libav
@@ -83,7 +83,7 @@ exec ./configure \
  --enable-maru \
  --disable-vnc \
  --enable-opengles \
- --enable-gl \
+ --disable-gl \
  --disable-pie
 ;;
 esac
index 3351432..20b9cf5 100755 (executable)
@@ -35,7 +35,7 @@ exec ./configure \
  --enable-maru \
  --disable-vnc \
  --enable-opengles \
- --enable-gl \
+ --disable-gl \
  --enable-debug \
  --disable-pie
 ;;
@@ -61,7 +61,7 @@ exec ./configure \
  --disable-vnc \
  --enable-opengles \
  --enable-debug \
- --enable-gl $1
+ --disable-gl $1
 ;;
 Darwin*)
 cd distrib/libav
@@ -86,7 +86,7 @@ exec ./configure \
  --disable-vnc \
  --enable-opengles \
  --enable-debug \
- --enable-gl \
+ --disable-gl \
  --disable-pie
 ;;
 esac
index a3edf49..703ea2f 100755 (executable)
@@ -34,7 +34,7 @@ exec ./configure \
  --enable-ldst-optimization \
  --enable-maru \
  --disable-vnc \
- --enable-opengles \
+ --disable-opengles \
  --enable-gl \
  --disable-pie
 ;;
@@ -58,7 +58,7 @@ exec ./configure \
  --enable-hax \
  --enable-maru \
  --disable-vnc \
- --enable-opengles \
+ --disable-opengles \
  --enable-gl $1
 ;;
 Darwin*)
index fbd17b2..09335fd 100755 (executable)
@@ -34,7 +34,7 @@ exec ./configure \
  --enable-ldst-optimization \
  --enable-maru \
  --disable-vnc \
- --enable-opengles \
+ --disable-opengles \
  --enable-gl \
  --enable-debug \
  --disable-pie
@@ -59,7 +59,7 @@ exec ./configure \
  --enable-hax \
  --enable-maru \
  --disable-vnc \
- --enable-opengles \
+ --disable-opengles \
  --enable-debug \
  --enable-gl $1
 ;;
index bb137ac..1a5f4df 100755 (executable)
@@ -19,7 +19,7 @@ ifdef CONFIG_WIN32
 LIBS += -lavformat -lavcodec -lavutil -lm -lopengl32 -lglu32 -lgdi32
 endif
 ifdef CONFIG_LINUX
-LIBS += -lavformat -lavcodec -lavutil -lm -lGL
+LIBS += -lavformat -lavcodec -lavutil -lm -lGL -lXcomposite -lXext
 endif
 ifdef CONFIG_DARWIN
 # FIXME: disabled codec on Mac now
@@ -41,7 +41,7 @@ ifdef CONFIG_GL
 GL_CUR_PATH = $(SRC_PATH)/tizen/src/hw
 
 GL_CFLAGS += -I$(GL_CUR_PATH) -I$(SRC_PATH)/fpu
-GL_CFLAGS += $(addprefix -I$(SRC_PATH)/,$(TARGET_DIRS)) $(QEMU_CFLAGS) $(CFLAGS)
+GL_CFLAGS += -I$(SRC_PATH)/i386-softmmu $(QEMU_CFLAGS) $(CFLAGS)
 
 parse_gl_h: parse_gl_h.c
        $(CC) -g -o $@ $<
@@ -60,6 +60,24 @@ opengl_exec.o : opengl_exec.c server_stub.c opengl_func.h gl_beginend.h opengl_p
        $(CC) $(GL_CFLAGS) $(DEFINES) $(GL_LDFLAGS) -c -o $@ $<
 
 endif #CONFIG_GL
+
+ifdef CONFIG_OPENGLES
+
+parse_gl_h: parse_gl_h.c
+       $(CC) -g -o $@ $<
+
+gl_mangled.h: parse_gl_h
+       ./parse_gl_h mangle 2>/dev/null
+
+gl_mangled.c: gl_mangled.h
+       ./parse_gl_h mangle 2>/dev/null
+
+gloffscreen_glx.o gloffscreen_wgl.o gloffscreen_xcomposite.o: gl_mangled.h
+maru_sdl.o gloffscreen_test.o gloffscreen_common.o: gl_mangled.h
+
+obj-y += gl_mangled.o
+
+endif #CONFIG_OPENGLES
 ###########################################################
 endif #!CONFIG_DARWIN
 
@@ -117,8 +135,8 @@ ifndef CONFIG_DARWIN
 ###########################################################
 ## opengl library for i386
 obj-$(CONFIG_GL) += virtio-gl.o 
-obj-$(CONFIG_GL) += helper_opengl.o opengl_exec.o mesa_mipmap.o gloffscreen_common.o
-obj-$(CONFIG_GL) += gloffscreen_test.o gloffscreen_xcomposite.o gloffscreen_wgl.o
+obj-$(CONFIG_GL) += helper_opengl.o opengl_exec.o mesa_mipmap.o gloffscreen_wgl.o
 obj-$(CONFIG_NO_GL) += virtio-gl-stub.o 
+obj-y += gloffscreen_test.o gloffscreen_xcomposite.o gloffscreen_common.o
 ###########################################################
 endif
index c97b9c1..c853d51 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
+#ifdef MANGLE_OPENGL_SYMBOLS
+#include "gl_mangled.h"
+#endif
+
 void *g_malloc(size_t size);
 void *g_realloc(void *ptr, size_t size);
 void g_free(void *ptr);
index e807c6b..6e234ef 100644 (file)
 #include <sys/shm.h>
 #include <X11/extensions/XShm.h>
 
+#ifdef MANGLE_OPENGL_SYMBOLS
+#include "gl_mangled.h"
+#endif
+
 struct GloMain {
   Display *dpy;
   int use_ximage;
index 1e9e9bc..b0cb9c3 100644 (file)
 #include <sys/time.h>
 #endif
 
+#ifdef MANGLE_OPENGL_SYMBOLS
+#include "gl_mangled.h"
+#endif
+
 // ---------------------------------------------------
 //  Copied from glx.h as we need them in windows too
 /*
@@ -75,7 +79,7 @@ int gl_acceleration_capability_check (void) {
     unsigned char *dataout = (unsigned char *)malloc(4*TX*TY);
     unsigned char *p;
     int x,y;
-    unsigned int bufferAttributes[] = {
+    const int bufferAttributes[] = {
             GLX_RED_SIZE,      8,
             GLX_GREEN_SIZE,    8,
             GLX_BLUE_SIZE,     8,
@@ -84,6 +88,13 @@ int gl_acceleration_capability_check (void) {
             GLX_STENCIL_SIZE,  0,
             0,
         };
+
+#ifdef MANGLE_OPENGL_SYMBOLS
+    if (mgl_load_symbols("libGL.so.1")) {
+        return 1;
+    }
+#endif
+
     int bufferFlags = glo_flags_get_from_glx(bufferAttributes, 0);
     int bpp = glo_flags_get_bytes_per_pixel(bufferFlags);
     int glFormat, glType;
@@ -121,7 +132,7 @@ int gl_acceleration_capability_check (void) {
     printf("GL RENDERER %s\n", glGetString(GL_RENDERER));
     printf("GL VERSION %s\n", glGetString(GL_VERSION));
 
-    if (strstr (glGetString(GL_RENDERER), "Software")) {
+    if (strstr((const char*)glGetString(GL_RENDERER), "Software")) {
         printf ("Host does not have GL hardware acceleration!\n");
         test_failure = 1;
         goto TEST_END;
index 68487b3..5bc5cc3 100644 (file)
 #include <GL/glext.h>
 #include "GL/wglext.h"
 
+#ifdef MANGLE_OPENGL_SYMBOLS
+#include "gl_mangled.h"
+#endif
+
 /* In Windows, you must create a window *before* you can create a pbuffer or
  * get a context. So we create a hidden Window on startup (see glo_init/GloMain).
  *
index f111e98..14481f4 100644 (file)
 #include <X11/extensions/XShm.h>
 #include <X11/extensions/Xcomposite.h>
 
+#ifdef MANGLE_OPENGL_SYMBOLS
+#include "gl_mangled.h"
+#endif
+
 void *g_malloc(size_t size);
 void *g_realloc(void *ptr, size_t size);
 void g_free(void *ptr);
index e37cf71..3cd1932 100644 (file)
@@ -1132,6 +1132,100 @@ static void fprintf_prototype_args(FILE* f, FuncDesc* funcDesc)
   }
 }
 
+static void gen_mangled_gl(FuncDesc *funcs_p, int func_cnt)
+{
+    int i, j;
+    FILE *header = fopen("gl_mangled.h", "w");
+    FILE *source = fopen("gl_mangled.c", "w");
+    char** args;
+
+    assert(header && source);
+
+    /* Manually add glGetString */
+    args = malloc(1 * sizeof(char*));
+    args[0] = strdup("GLenum");
+    funcs_p[func_cnt].type = strdup("const GLubyte *");
+    funcs_p[func_cnt].name = strdup("glGetString");
+    funcs_p[func_cnt].nargs = 1;
+    funcs_p[func_cnt].args = args;
+    func_cnt++;
+
+    fprintf(header, "/* This file is generated by parse_gl_h.c - DO NOT EDIT ! */\n\n");
+    fprintf(header, "#include <GL/gl.h>\n\n");
+    fprintf(header, "typedef struct mglHDL {\n");
+
+    for (i = 0; i < func_cnt; ++i) {
+        fprintf(header, "\t%s (*%s)(", funcs_p[i].type, funcs_p[i].name);
+        if (funcs_p[i].nargs == 1 && !strncmp(funcs_p[i].args[0], "void",  4)) {
+            free(funcs_p[i].args[0]);
+            funcs_p[i].nargs = 0;
+            fprintf(header, "void");
+        }
+        fprintf_prototype_args(header, &funcs_p[i]);
+        fprintf(header, ");\n");
+    }
+    fprintf(header, "} mglHDL;\n\n");
+
+    fprintf(header, "extern mglHDL mgl_hdl;\n\n");
+    fprintf(header, "int mgl_load_symbols(const char *libname);\n");
+    fprintf(header, "int mgl_unload(void);\n\n");
+
+    for (i = 0; i < func_cnt; ++i) {
+        fprintf(header, "#define %s    mgl_hdl.%s\n", funcs_p[i].name, funcs_p[i].name);
+    }
+
+    fprintf(header, "\n");
+
+    fprintf(source, "/* This file is generated by parse_gl_h.c - DO NOT EDIT ! */\n\n");
+    fprintf(source, "#include <stdio.h>\n#include \"gl_mangled.h\"\n\n");
+    fprintf(source, "#ifdef _WIN32\n#include <Windows.h>\n"
+            "typedef HINSTANCE handle_t;\n#else\n#include <dlfcn.h>\n"
+            "typedef void * handle_t;\n#endif\n\n");
+    fprintf(source, "mglHDL mgl_hdl;\n");
+    fprintf(source, "static handle_t mgl_lib_hdl;\n\n");
+
+    fprintf(source, "static inline handle_t mgl_load_lib(const char *libname)\n{\n"
+            "#ifdef _WIN32\n\treturn LoadLibrary(libname);\n"
+            "#else\n\treturn dlopen(libname, RTLD_LAZY | RTLD_LOCAL);\n"
+            "#endif\n}\n\n");
+
+    fprintf(source, "static inline void *mgl_load_sym(const char *symname)\n{\n"
+            "#ifdef _WIN32\n\treturn GetProcAddress(mgl_lib_hdl, symname);\n"
+            "#else\n\treturn dlsym(mgl_lib_hdl, symname);\n"
+            "#endif\n}\n\n");
+
+    fprintf(source, "int mgl_unload(void)\n{\n"
+            "#ifdef _WIN32\n\treturn FreeLibrary(mgl_lib_hdl);\n"
+            "#else\n\treturn dlclose(mgl_lib_hdl);\n"
+            "#endif\n}\n\n");
+
+    fprintf(source, "int mgl_load_symbols(const char *libname)\n{\n"
+            "\tif (!(mgl_lib_hdl = mgl_load_lib(libname))) {\n"
+            "\t\tfprintf(stderr, \"ERROR: Couldn't load %%s library!\\n\", libname);\n"
+            "\t\treturn 1;\n\t}\n\n");
+
+    for (i = 0; i < func_cnt; ++i) {
+        fprintf(source, "\tif (!(%s = mgl_load_sym(\"%s\"))) {\n"
+                "\t\tmgl_unload();\n\t\t"
+                "fprintf(stderr, \"function %s not found!\\n\");\n\t\treturn 1;\n\t}\n\n",
+                funcs_p[i].name, funcs_p[i].name, funcs_p[i].name);
+    }
+
+    fprintf(source, "\treturn 0;\n}\n");
+
+    for (i = 0; i < func_cnt; ++i) {
+        free(funcs_p[func_cnt].name);
+        free(funcs_p[func_cnt].type);
+        for (; funcs_p[func_cnt].nargs; --funcs_p[func_cnt].nargs) {
+            free(funcs_p[func_cnt].args[funcs_p[func_cnt].nargs - 1]);
+        }
+        free(funcs_p[func_cnt].args);
+    }
+
+    fclose(header);
+    fclose(source);
+}
+
 int main(int argc, char* argv[])
 {
   FuncDesc funcDesc[3000];
@@ -1146,13 +1240,18 @@ int main(int argc, char* argv[])
   funcDescCount = parse(f, funcDesc, 0, 1);
   fclose(f);
   
+  if ((argc > 1) && !strncmp(argv[1], "mangle", 6)) {
+      gen_mangled_gl(funcDesc, funcDescCount);
+      return 0;
+  }
+
   f = fopen(GL_INCLUDE_PATH"mesa_glext.h", "r");
   assert(f);
   /*if (!f)
     f = fopen("/usr/include/GL/glext.h", "r");*/
   funcDescCount = parse(f, funcDesc, funcDescCount, 0);
   fclose(f);
-  
+
   FILE* header = fopen("gl_func.h", "w");
   FILE* client_stub = fopen("client_stub.c", "w");
   FILE* server_stub = fopen("server_stub.c", "w");
index 57fc77a..76fbcf6 100644 (file)
  */
 
 #include "virtio.h"
-int gl_acceleration_capability_check(void);
 
 VirtIODevice *virtio_gl_init(DeviceState *dev)
 {
        return NULL;
 }
 
-int gl_acceleration_capability_check (void)
-{
-       return 1;
-}
index d6a4ba2..37b4770 100644 (file)
 #include "debug_ch.h"
 #include "SDL_opengl.h"
 
+#ifdef MANGLE_OPENGL_SYMBOLS
+#include "gl_mangled.h"
+#endif
+
 MULTI_DEBUG_CHANNEL(tizen, maru_sdl);