Loader.cpp revision 2b9e4f6a2490864ead44e88a68da78be5cb3da22
1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ** Copyright 2007, The Android Open Source Project 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ** 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ** Licensed under the Apache License, Version 2.0 (the "License"); 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ** you may not use this file except in compliance with the License. 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ** You may obtain a copy of the License at 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ** 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ** http://www.apache.org/licenses/LICENSE-2.0 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ** 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ** Unless required by applicable law or agreed to in writing, software 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ** distributed under the License is distributed on an "AS IS" BASIS, 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ** See the License for the specific language governing permissions and 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ** limitations under the License. 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <ctype.h> 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <stdlib.h> 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <stdio.h> 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <string.h> 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <errno.h> 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <dlfcn.h> 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <limits.h> 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <cutils/log.h> 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <EGL/egl.h> 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "hooks.h" 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "egl_impl.h" 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "Loader.h" 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// ---------------------------------------------------------------------------- 3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace android { 3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// ---------------------------------------------------------------------------- 3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)/* 4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * EGL drivers are called 4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * 4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * /system/lib/egl/lib{[EGL|GLESv1_CM|GLESv2] | GLES}_$TAG.so 4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * 4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)ANDROID_SINGLETON_STATIC_INSTANCE( Loader ) 4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// ---------------------------------------------------------------------------- 4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)Loader::driver_t::driver_t(void* gles) 5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles){ 5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) dso[0] = gles; 5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i=1 ; i<NELEM(dso) ; i++) 5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) dso[i] = 0; 5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)Loader::driver_t::~driver_t() 5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles){ 5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i=0 ; i<NELEM(dso) ; i++) { 6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (dso[i]) { 6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) dlclose(dso[i]); 6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) dso[i] = 0; 6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)status_t Loader::driver_t::set(void* hnd, int32_t api) 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switch (api) { 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case EGL: 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) dso[0] = hnd; 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case GLESv1_CM: 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) dso[1] = hnd; 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case GLESv2: 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) dso[2] = hnd; 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) default: 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return BAD_INDEX; 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return NO_ERROR; 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// ---------------------------------------------------------------------------- 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)Loader::entry_t::entry_t(int dpy, int impl, const char* tag) 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : dpy(dpy), impl(impl), tag(tag) { 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// ---------------------------------------------------------------------------- 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)Loader::Loader() 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) char line[256]; 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) char tag[256]; 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FILE* cfg = fopen("/system/lib/egl/egl.cfg", "r"); 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (cfg == NULL) { 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // default config 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOGD("egl.cfg not found, using default config"); 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gConfig.add( entry_t(0, 0, "android") ); 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) while (fgets(line, 256, cfg)) { 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int dpy; 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int impl; 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (sscanf(line, "%u %u %s", &dpy, &impl, tag) == 3) { 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) //LOGD(">>> %u %u %s", dpy, impl, tag); 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gConfig.add( entry_t(dpy, impl, tag) ); 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) fclose(cfg); 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)Loader::~Loader() 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char* Loader::getTag(int dpy, int impl) 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Vector<entry_t>& cfgs(gConfig); 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const size_t c = cfgs.size(); 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i=0 ; i<c ; i++) { 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (dpy == cfgs[i].dpy) 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (impl == cfgs[i].impl) 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return cfgs[i].tag.string(); 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void* Loader::open(EGLNativeDisplayType display, int impl, egl_connection_t* cnx) 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) /* 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * TODO: if we don't find display/0, then use 0/0 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * (0/0 should always work) 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void* dso; 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int index = int(display); 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) driver_t* hnd = 0; 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) char const* tag = getTag(index, impl); 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (tag) { 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) dso = load_driver("GLES", tag, cnx, EGL | GLESv1_CM | GLESv2); 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (dso) { 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hnd = new driver_t(dso); 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Always load EGL first 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) dso = load_driver("EGL", tag, cnx, EGL); 150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (dso) { 151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hnd = new driver_t(dso); 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO: make this more automated 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hnd->set( load_driver("GLESv1_CM", tag, cnx, GLESv1_CM), GLESv1_CM ); 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hnd->set( load_driver("GLESv2", tag, cnx, GLESv2), GLESv2 ); 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) LOG_FATAL_IF(!index && !impl && !hnd, 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "couldn't find the default OpenGL ES implementation " 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "for default display"); 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return (void*)hnd; 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)status_t Loader::close(void* driver) 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) driver_t* hnd = (driver_t*)driver; 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delete hnd; 172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return NO_ERROR; 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void Loader::init_api(void* dso, 176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) char const * const * api, 177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) __eglMustCastToProperFunctionPointerType* curr, 178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) getProcAddressType getProcAddress) 179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) char scrap[256]; 181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) while (*api) { 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) char const * name = *api; 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) __eglMustCastToProperFunctionPointerType f = 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (f == NULL) { 186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // couldn't find the entry-point, use eglGetProcAddress() 187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f = getProcAddress(name); 188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (f == NULL) { 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Try without the OES postfix 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ssize_t index = ssize_t(strlen(name)) - 3; 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if ((index>0 && (index<255)) && (!strcmp(name+index, "OES"))) { 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) strncpy(scrap, name, index); 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scrap[index] = 0; 195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); 196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) //LOGD_IF(f, "found <%s> instead", scrap); 197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (f == NULL) { 200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Try with the OES postfix 201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ssize_t index = ssize_t(strlen(name)) - 3; 202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if ((index>0 && (index<252)) && (strcmp(name+index, "OES"))) { 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) strncpy(scrap, name, index); 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scrap[index] = 0; 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) strcat(scrap, "OES"); 206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); 207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) //LOGD_IF(f, "found <%s> instead", scrap); 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (f == NULL) { 211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) //LOGD("%s", name); 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented; 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *curr++ = f; 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) api++; 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void *Loader::load_driver(const char* kind, const char *tag, 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) egl_connection_t* cnx, uint32_t mask) 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) char driver_absolute_path[PATH_MAX]; 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char* const search1 = "/vendor/lib/egl/lib%s_%s.so"; 224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char* const search2 = "/system/lib/egl/lib%s_%s.so"; 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 22603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) snprintf(driver_absolute_path, PATH_MAX, search1, kind, tag); 22703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (access(driver_absolute_path, R_OK)) { 22803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) snprintf(driver_absolute_path, PATH_MAX, search2, kind, tag); 22903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (access(driver_absolute_path, R_OK)) { 23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // this happens often, we don't want to log an error 23103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return 0; 23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 23303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 23403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL); 23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (dso == 0) { 23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const char* err = dlerror(); 23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) LOGE("load_driver(%s): %s", driver_absolute_path, err?err:"unknown"); 23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return 0; 24003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 24203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) LOGD("loaded %s", driver_absolute_path); 24303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 24403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (mask & EGL) { 24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress"); 24603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 24703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) LOGE_IF(!getProcAddress, 24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) "can't find eglGetProcAddress() in %s", driver_absolute_path); 24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 25003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) egl_t* egl = &cnx->egl; 25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) __eglMustCastToProperFunctionPointerType* curr = 25203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) (__eglMustCastToProperFunctionPointerType*)egl; 25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) char const * const * api = egl_names; 25403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) while (*api) { 25503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) char const * name = *api; 25603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) __eglMustCastToProperFunctionPointerType f = 25703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); 25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (f == NULL) { 25903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // couldn't find the entry-point, use eglGetProcAddress() 26003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) f = getProcAddress(name); 26103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (f == NULL) { 26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) f = (__eglMustCastToProperFunctionPointerType)0; 26303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 26403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 26503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) *curr++ = f; 26603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) api++; 26703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 26803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 26903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 27003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (mask & GLESv1_CM) { 27103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) init_api(dso, gl_names, 27203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) (__eglMustCastToProperFunctionPointerType*) 27303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &cnx->hooks[GLESv1_INDEX]->gl, 27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) getProcAddress); 27503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 27603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 27703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (mask & GLESv2) { 27803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) init_api(dso, gl_names, 27903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) (__eglMustCastToProperFunctionPointerType*) 28003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) &cnx->hooks[GLESv2_INDEX]->gl, 28103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) getProcAddress); 28203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 28303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 28403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return dso; 28503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 28603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 28703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// ---------------------------------------------------------------------------- 28803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}; // namespace android 28903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// ---------------------------------------------------------------------------- 29003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)