/* ** Copyright 2007, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #include #include #include #include #include #include #include #include #include #include "hooks.h" #include "egl_impl.h" #include "Loader.h" // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- /* * EGL drivers are called * * /system/lib/egl/lib{[EGL|GLESv1_CM|GLESv2] | GLES}_$TAG.so * */ ANDROID_SINGLETON_STATIC_INSTANCE( Loader ) // ---------------------------------------------------------------------------- Loader::driver_t::driver_t(void* gles) { dso[0] = gles; for (size_t i=1 ; i>> %u %u %s", dpy, impl, tag); gConfig.add( entry_t(dpy, impl, tag) ); } } fclose(cfg); } } Loader::~Loader() { } const char* Loader::getTag(int dpy, int impl) { const Vector& cfgs(gConfig); const size_t c = cfgs.size(); for (size_t i=0 ; iset( load_driver(path, hooks, GLESv1_CM), GLESv1_CM ); snprintf(path, PATH_MAX, format, "GLESv2", tag); hnd->set( load_driver(path, hooks, GLESv2), GLESv2 ); } } } LOG_FATAL_IF(!index && !impl && !hnd, "couldn't find the default OpenGL ES implementation " "for default display"); return (void*)hnd; } status_t Loader::close(void* driver) { driver_t* hnd = (driver_t*)driver; delete hnd; return NO_ERROR; } void Loader::init_api(void* dso, char const * const * api, __eglMustCastToProperFunctionPointerType* curr, getProcAddressType getProcAddress) { char scrap[256]; while (*api) { char const * name = *api; __eglMustCastToProperFunctionPointerType f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); if (f == NULL) { // couldn't find the entry-point, use eglGetProcAddress() f = getProcAddress(name); } if (f == NULL) { // Try without the OES postfix ssize_t index = ssize_t(strlen(name)) - 3; if ((index>0 && (index<255)) && (!strcmp(name+index, "OES"))) { strncpy(scrap, name, index); scrap[index] = 0; f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); //LOGD_IF(f, "found <%s> instead", scrap); } } if (f == NULL) { // Try with the OES postfix ssize_t index = ssize_t(strlen(name)) - 3; if ((index>0 && (index<252)) && (strcmp(name+index, "OES"))) { strncpy(scrap, name, index); scrap[index] = 0; strcat(scrap, "OES"); f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); //LOGD_IF(f, "found <%s> instead", scrap); } } if (f == NULL) { //LOGD("%s", name); f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented; } *curr++ = f; api++; } } void *Loader::load_driver(const char* driver, gl_hooks_t* hooks, uint32_t mask) { void* dso = dlopen(driver, RTLD_NOW | RTLD_LOCAL); if (dso == 0) return 0; LOGD("loaded %s", driver); if (mask & EGL) { getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress"); LOGE_IF(!getProcAddress, "can't find eglGetProcAddress() in %s", driver); gl_hooks_t::egl_t* egl = &hooks->egl; __eglMustCastToProperFunctionPointerType* curr = (__eglMustCastToProperFunctionPointerType*)egl; char const * const * api = egl_names; while (*api) { char const * name = *api; __eglMustCastToProperFunctionPointerType f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); if (f == NULL) { // couldn't find the entry-point, use eglGetProcAddress() f = getProcAddress(name); if (f == NULL) { f = (__eglMustCastToProperFunctionPointerType)0; } } *curr++ = f; api++; } } if (mask & GLESv1_CM) { init_api(dso, gl_names, (__eglMustCastToProperFunctionPointerType*)&hooks->gl, getProcAddress); } if (mask & GLESv2) { init_api(dso, gl2_names, (__eglMustCastToProperFunctionPointerType*)&hooks->gl2, getProcAddress); } return dso; } // ---------------------------------------------------------------------------- }; // namespace android // ----------------------------------------------------------------------------