1 /* 2 * Mesa 3-D graphics library 3 * Version: 7.10 4 * 5 * Copyright (C) 2011 LunarG Inc. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 * DEALINGS IN THE SOFTWARE. 24 * 25 * Authors: 26 * Chia-I Wu <olv (at) lunarg.com> 27 */ 28 #include "util/u_debug.h" 29 #include "state_tracker/st_api.h" 30 #include "egl_st.h" 31 32 #if FEATURE_GL || FEATURE_ES1 || FEATURE_ES2 33 #include "state_tracker/st_gl_api.h" 34 #endif 35 36 #if FEATURE_VG 37 #include "vg_api.h" 38 #endif 39 40 #if _EGL_EXTERNAL_GL 41 42 #include "util/u_string.h" 43 #include "util/u_dl.h" 44 #include "egldriver.h" 45 #include "egllog.h" 46 47 static struct util_dl_library *egl_st_gl_lib; 48 49 static EGLBoolean 50 dlopen_gl_lib_cb(const char *dir, size_t len, void *callback_data) 51 { 52 const char *name = (const char *) callback_data; 53 char path[1024]; 54 int ret; 55 56 if (len) { 57 assert(len <= INT_MAX && "path is insanely long!"); 58 ret = util_snprintf(path, sizeof(path), "%.*s/%s" UTIL_DL_EXT, 59 (int)len, dir, name); 60 } 61 else { 62 ret = util_snprintf(path, sizeof(path), "%s" UTIL_DL_EXT, name); 63 } 64 65 if (ret > 0 && ret < sizeof(path)) { 66 egl_st_gl_lib = util_dl_open(path); 67 if (egl_st_gl_lib) 68 _eglLog(_EGL_DEBUG, "loaded %s", path); 69 } 70 71 return !egl_st_gl_lib; 72 } 73 74 static struct st_api * 75 load_gl(const char *name, const char *procname) 76 { 77 struct st_api *(*create_api)(void); 78 struct st_api *stapi = NULL; 79 80 _eglSearchPathForEach(dlopen_gl_lib_cb, (void *) name); 81 if (!egl_st_gl_lib) 82 return NULL; 83 84 create_api = (struct st_api *(*)(void)) 85 util_dl_get_proc_address(egl_st_gl_lib, procname); 86 if (create_api) 87 stapi = create_api(); 88 89 if (!stapi) { 90 util_dl_close(egl_st_gl_lib); 91 egl_st_gl_lib = NULL; 92 } 93 94 return stapi; 95 } 96 97 static struct st_api * 98 egl_st_load_gl(void) 99 { 100 const char module[] = "st_GL"; 101 const char symbol[] = "st_api_create_OpenGL"; 102 struct st_api *stapi; 103 104 stapi = load_gl(module, symbol); 105 106 /* try again with libglapi.so loaded */ 107 if (!stapi) { 108 struct util_dl_library *glapi = util_dl_open("libglapi" UTIL_DL_EXT); 109 110 if (glapi) { 111 _eglLog(_EGL_DEBUG, "retry with libglapi" UTIL_DL_EXT " loaded"); 112 113 stapi = load_gl(module, symbol); 114 util_dl_close(glapi); 115 } 116 } 117 if (!stapi) 118 _eglLog(_EGL_WARNING, "unable to load %s" UTIL_DL_EXT, module); 119 120 return stapi; 121 } 122 123 #endif /* _EGL_EXTERNAL_GL */ 124 125 struct st_api * 126 egl_st_create_api(enum st_api_type api) 127 { 128 struct st_api *stapi = NULL; 129 130 switch (api) { 131 case ST_API_OPENGL: 132 #if FEATURE_GL || FEATURE_ES1 || FEATURE_ES2 133 #if _EGL_EXTERNAL_GL 134 stapi = egl_st_load_gl(); 135 #else 136 stapi = st_gl_api_create(); 137 #endif 138 #endif 139 break; 140 case ST_API_OPENVG: 141 #if FEATURE_VG 142 stapi = (struct st_api *) vg_api_get(); 143 #endif 144 break; 145 default: 146 assert(!"Unknown API Type\n"); 147 break; 148 } 149 150 return stapi; 151 } 152 153 void 154 egl_st_destroy_api(struct st_api *stapi) 155 { 156 #if _EGL_EXTERNAL_GL 157 boolean is_gl = (stapi->api == ST_API_OPENGL); 158 159 stapi->destroy(stapi); 160 161 if (is_gl) { 162 util_dl_close(egl_st_gl_lib); 163 egl_st_gl_lib = NULL; 164 } 165 #else 166 stapi->destroy(stapi); 167 #endif 168 } 169 170 uint 171 egl_st_get_profile_mask(enum st_api_type api) 172 { 173 uint mask = 0x0; 174 175 switch (api) { 176 case ST_API_OPENGL: 177 #if FEATURE_GL 178 mask |= ST_PROFILE_DEFAULT_MASK; 179 #endif 180 #if FEATURE_ES1 181 mask |= ST_PROFILE_OPENGL_ES1_MASK; 182 #endif 183 #if FEATURE_ES2 184 mask |= ST_PROFILE_OPENGL_ES2_MASK; 185 #endif 186 break; 187 case ST_API_OPENVG: 188 #if FEATURE_VG 189 mask |= ST_PROFILE_DEFAULT_MASK; 190 #endif 191 break; 192 default: 193 break; 194 } 195 196 return mask; 197 } 198