Loader.cpp revision 1cadb25da1ed875bdd078270e642966724a0c39a
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Copyright 2007, The Android Open Source Project 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Licensed under the Apache License, Version 2.0 (the "License"); 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** you may not use this file except in compliance with the License. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** You may obtain a copy of the License at 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ** 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** http://www.apache.org/licenses/LICENSE-2.0 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** Unless required by applicable law or agreed to in writing, software 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** distributed under the License is distributed on an "AS IS" BASIS, 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** See the License for the specific language governing permissions and 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** limitations under the License. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <ctype.h> 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <stdlib.h> 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <dlfcn.h> 23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <limits.h> 24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cutils/log.h> 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <EGL/egl.h> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "egldefs.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "glesv2dbg.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "hooks.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "Loader.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// ---------------------------------------------------------------------------- 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace android { 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// ---------------------------------------------------------------------------- 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * EGL drivers are called 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * /system/lib/egl/lib{[EGL|GLESv1_CM|GLESv2] | GLES}_$TAG.so 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) */ 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ANDROID_SINGLETON_STATIC_INSTANCE( Loader ) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ---------------------------------------------------------------------------- 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Loader::driver_t::driver_t(void* gles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dso[0] = gles; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i=1 ; i<NELEM(dso) ; i++) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dso[i] = 0; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Loader::driver_t::~driver_t() 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i=0 ; i<NELEM(dso) ; i++) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dso[i]) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dlclose(dso[i]); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dso[i] = 0; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)status_t Loader::driver_t::set(void* hnd, int32_t api) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (api) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EGL: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dso[0] = hnd; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case GLESv1_CM: 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dso[1] = hnd; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case GLESv2: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dso[2] = hnd; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return BAD_INDEX; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NO_ERROR; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ---------------------------------------------------------------------------- 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Loader::entry_t::entry_t(int dpy, int impl, const char* tag) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : dpy(dpy), impl(impl), tag(tag) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ---------------------------------------------------------------------------- 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Loader::Loader() 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char line[256]; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char tag[256]; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE* cfg = fopen("/system/lib/egl/egl.cfg", "r"); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cfg == NULL) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // default config 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOGD("egl.cfg not found, using default config"); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gConfig.add( entry_t(0, 0, "android") ); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (fgets(line, 256, cfg)) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int dpy; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int impl; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sscanf(line, "%u %u %s", &dpy, &impl, tag) == 3) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //LOGD(">>> %u %u %s", dpy, impl, tag); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gConfig.add( entry_t(dpy, impl, tag) ); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fclose(cfg); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Loader::~Loader() 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopDebugServer(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* Loader::getTag(int dpy, int impl) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Vector<entry_t>& cfgs(gConfig); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t c = cfgs.size(); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i=0 ; i<c ; i++) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dpy == cfgs[i].dpy) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (impl == cfgs[i].impl) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cfgs[i].tag.string(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* Loader::open(EGLNativeDisplayType display, int impl, egl_connection_t* cnx) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: if we don't find display/0, then use 0/0 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (0/0 should always work) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* dso; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index = int(display); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) driver_t* hnd = 0; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char const* tag = getTag(index, impl); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tag) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dso = load_driver("GLES", tag, cnx, EGL | GLESv1_CM | GLESv2); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dso) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hnd = new driver_t(dso); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Always load EGL first 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dso = load_driver("EGL", tag, cnx, EGL); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dso) { 152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) hnd = new driver_t(dso); 153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // TODO: make this more automated 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) hnd->set( load_driver("GLESv1_CM", tag, cnx, GLESv1_CM), GLESv1_CM ); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hnd->set( load_driver("GLESv2", tag, cnx, GLESv2), GLESv2 ); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG_FATAL_IF(!index && !impl && !hnd, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "couldn't find the default OpenGL ES implementation " 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "for default display"); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (void*)hnd; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)status_t Loader::close(void* driver) 170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles){ 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) driver_t* hnd = (driver_t*)driver; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete hnd; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NO_ERROR; 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Loader::init_api(void* dso, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char const * const * api, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __eglMustCastToProperFunctionPointerType* curr, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getProcAddressType getProcAddress) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t SIZE = 256; 182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) char scrap[SIZE]; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (*api) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char const * name = *api; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __eglMustCastToProperFunctionPointerType f = 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (f == NULL) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // couldn't find the entry-point, use eglGetProcAddress() 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f = getProcAddress(name); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (f == NULL) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try without the OES postfix 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssize_t index = ssize_t(strlen(name)) - 3; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((index>0 && (index<SIZE-1)) && (!strcmp(name+index, "OES"))) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strncpy(scrap, name, index); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scrap[index] = 0; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //LOGD_IF(f, "found <%s> instead", scrap); 199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (f == NULL) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try with the OES postfix 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssize_t index = ssize_t(strlen(name)) - 3; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index>0 && strcmp(name+index, "OES")) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(scrap, SIZE, "%sOES", name); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //LOGD_IF(f, "found <%s> instead", scrap); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (f == NULL) { 211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) //LOGD("%s", name); 212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *curr++ = f; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) api++; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void *Loader::load_driver(const char* kind, const char *tag, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) egl_connection_t* cnx, uint32_t mask) 22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles){ 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char driver_absolute_path[PATH_MAX]; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* const search1 = "/vendor/lib/egl/lib%s_%s.so"; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* const search2 = "/system/lib/egl/lib%s_%s.so"; 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(driver_absolute_path, PATH_MAX, search1, kind, tag); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (access(driver_absolute_path, R_OK)) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(driver_absolute_path, PATH_MAX, search2, kind, tag); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (access(driver_absolute_path, R_OK)) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this happens often, we don't want to log an error 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dso == 0) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* err = dlerror(); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOGE("load_driver(%s): %s", driver_absolute_path, err?err:"unknown"); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOGD("loaded %s", driver_absolute_path); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mask & EGL) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress"); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOGE_IF(!getProcAddress, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "can't find eglGetProcAddress() in %s", driver_absolute_path); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) egl_t* egl = &cnx->egl; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __eglMustCastToProperFunctionPointerType* curr = 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (__eglMustCastToProperFunctionPointerType*)egl; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char const * const * api = egl_names; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (*api) { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char const * name = *api; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __eglMustCastToProperFunctionPointerType f = 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (f == NULL) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // couldn't find the entry-point, use eglGetProcAddress() 260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch f = getProcAddress(name); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (f == NULL) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f = (__eglMustCastToProperFunctionPointerType)0; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *curr++ = f; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) api++; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (mask & GLESv1_CM) { 271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) init_api(dso, gl_names, 272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) (__eglMustCastToProperFunctionPointerType*) 273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) &cnx->hooks[GLESv1_INDEX]->gl, 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getProcAddress); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mask & GLESv2) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_api(dso, gl_names, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (__eglMustCastToProperFunctionPointerType*) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &cnx->hooks[GLESv2_INDEX]->gl, 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getProcAddress); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dso; 285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ---------------------------------------------------------------------------- 288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}; // namespace android 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ---------------------------------------------------------------------------- 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)