Home | History | Annotate | Download | only in egl-static
      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