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@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 47static struct util_dl_library *egl_st_gl_lib; 48 49static EGLBoolean 50dlopen_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 74static struct st_api * 75load_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 97static struct st_api * 98egl_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 125struct st_api * 126egl_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 153void 154egl_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 170uint 171egl_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