19d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian/* 29d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian ** Copyright 2007, The Android Open Source Project 39d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian ** 49d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian ** Licensed under the Apache License, Version 2.0 (the "License"); 59d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian ** you may not use this file except in compliance with the License. 69d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian ** You may obtain a copy of the License at 79d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian ** 89d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian ** http://www.apache.org/licenses/LICENSE-2.0 99d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian ** 109d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian ** Unless required by applicable law or agreed to in writing, software 119d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian ** distributed under the License is distributed on an "AS IS" BASIS, 129d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian ** See the License for the specific language governing permissions and 149d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian ** limitations under the License. 159d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian */ 169d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 179d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian#include <ctype.h> 189d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian#include <stdlib.h> 199d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian#include <stdio.h> 209d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian#include <string.h> 219d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian#include <errno.h> 229d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian#include <dlfcn.h> 239d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian#include <limits.h> 249d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 259d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian#include <cutils/log.h> 269d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 279d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian#include <EGL/egl.h> 289d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 299d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian#include "hooks.h" 309d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian#include "egl_impl.h" 319d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 329d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian#include "Loader.h" 339d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 349d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian// ---------------------------------------------------------------------------- 359d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopiannamespace android { 369d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian// ---------------------------------------------------------------------------- 379d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 389d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 399d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian/* 409d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian * EGL drivers are called 419d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian * 429d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian * /system/lib/egl/lib{[EGL|GLESv1_CM|GLESv2] | GLES}_$TAG.so 439d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian * 449d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian */ 459d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 469d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias AgopianANDROID_SINGLETON_STATIC_INSTANCE( Loader ) 479d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 489d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian// ---------------------------------------------------------------------------- 499d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 509d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias AgopianLoader::driver_t::driver_t(void* gles) 519d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian{ 529d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian dso[0] = gles; 539d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian for (size_t i=1 ; i<NELEM(dso) ; i++) 549d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian dso[i] = 0; 559d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian} 569d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 579d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias AgopianLoader::driver_t::~driver_t() 589d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian{ 599d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian for (size_t i=0 ; i<NELEM(dso) ; i++) { 609d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (dso[i]) { 619d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian dlclose(dso[i]); 629d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian dso[i] = 0; 639d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 649d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 659d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian} 669d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 679d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopianstatus_t Loader::driver_t::set(void* hnd, int32_t api) 689d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian{ 699d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian switch (api) { 709d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian case EGL: 719d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian dso[0] = hnd; 729d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian break; 739d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian case GLESv1_CM: 749d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian dso[1] = hnd; 759d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian break; 769d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian case GLESv2: 779d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian dso[2] = hnd; 789d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian break; 799d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian default: 809d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian return BAD_INDEX; 819d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 829d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian return NO_ERROR; 839d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian} 849d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 859d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian// ---------------------------------------------------------------------------- 869d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 879d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias AgopianLoader::entry_t::entry_t(int dpy, int impl, const char* tag) 889d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian : dpy(dpy), impl(impl), tag(tag) { 899d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian} 909d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 919d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian// ---------------------------------------------------------------------------- 929d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 939d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias AgopianLoader::Loader() 949d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian{ 959d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian char line[256]; 969d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian char tag[256]; 979d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian FILE* cfg = fopen("/system/lib/egl/egl.cfg", "r"); 989d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (cfg == NULL) { 999d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian // default config 1009d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian LOGD("egl.cfg not found, using default config"); 1019d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian gConfig.add( entry_t(0, 0, "android") ); 1029d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } else { 1039d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian while (fgets(line, 256, cfg)) { 1049d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian int dpy; 1059d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian int impl; 1069d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (sscanf(line, "%u %u %s", &dpy, &impl, tag) == 3) { 1074098d78b3507bfecce9f7a8a4b5d334c7842ff88Mathias Agopian //LOGD(">>> %u %u %s", dpy, impl, tag); 1089d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian gConfig.add( entry_t(dpy, impl, tag) ); 1099d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 1109d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 1119d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian fclose(cfg); 1129d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 1139d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian} 1149d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 1159d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias AgopianLoader::~Loader() 1169d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian{ 1179d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian} 1189d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 1199d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopianconst char* Loader::getTag(int dpy, int impl) 1209d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian{ 1219d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian const Vector<entry_t>& cfgs(gConfig); 1229d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian const size_t c = cfgs.size(); 1239d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian for (size_t i=0 ; i<c ; i++) { 1249d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (dpy == cfgs[i].dpy) 1259d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (impl == cfgs[i].impl) 1269d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian return cfgs[i].tag.string(); 1279d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 1289d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian return 0; 1299d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian} 1309d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 1316fc569971faa342b2e2da46c55fbfbba3a2a7814Mathias Agopianvoid* Loader::open(EGLNativeDisplayType display, int impl, egl_connection_t* cnx) 1329d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian{ 1339d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian /* 1349d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian * TODO: if we don't find display/0, then use 0/0 1359d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian * (0/0 should always work) 1369d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian */ 1379d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 1389d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian void* dso; 1399d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian char path[PATH_MAX]; 1409d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian int index = int(display); 1419d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian driver_t* hnd = 0; 14292a3ed43645150a79b5abdc3508ca7e4f64aba89Marco Nelissen const char* const format = "/system/lib/egl/lib%s_%s.so"; 1439d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 1449d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian char const* tag = getTag(index, impl); 1459d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (tag) { 1469d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian snprintf(path, PATH_MAX, format, "GLES", tag); 1476fc569971faa342b2e2da46c55fbfbba3a2a7814Mathias Agopian dso = load_driver(path, cnx, EGL | GLESv1_CM | GLESv2); 1489d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (dso) { 1499d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian hnd = new driver_t(dso); 1509d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } else { 1519d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian // Always load EGL first 152c902bf8f133e0a60a888fbc2e86f66fcbc0f0430Mathias Agopian snprintf(path, PATH_MAX, format, "EGL", tag); 1536fc569971faa342b2e2da46c55fbfbba3a2a7814Mathias Agopian dso = load_driver(path, cnx, EGL); 1549d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (dso) { 1559d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian hnd = new driver_t(dso); 1569d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 1579d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian // TODO: make this more automated 1589d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian snprintf(path, PATH_MAX, format, "GLESv1_CM", tag); 1596fc569971faa342b2e2da46c55fbfbba3a2a7814Mathias Agopian hnd->set( load_driver(path, cnx, GLESv1_CM), GLESv1_CM ); 1609d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 1619d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian snprintf(path, PATH_MAX, format, "GLESv2", tag); 1626fc569971faa342b2e2da46c55fbfbba3a2a7814Mathias Agopian hnd->set( load_driver(path, cnx, GLESv2), GLESv2 ); 1639d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 1649d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 1659d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 1669d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 1679d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian LOG_FATAL_IF(!index && !impl && !hnd, 168b4b4c11f82e88f9a1cecd97460a9fcc192b37612Mathias Agopian "couldn't find the default OpenGL ES implementation " 1699d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian "for default display"); 1709d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 1719d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian return (void*)hnd; 1729d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian} 1739d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 1749d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopianstatus_t Loader::close(void* driver) 1759d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian{ 1769d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian driver_t* hnd = (driver_t*)driver; 1779d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian delete hnd; 1789d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian return NO_ERROR; 1799d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian} 1809d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 1819d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopianvoid Loader::init_api(void* dso, 1829d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian char const * const * api, 1839d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian __eglMustCastToProperFunctionPointerType* curr, 1849d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian getProcAddressType getProcAddress) 1859d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian{ 1869d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian char scrap[256]; 1879d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian while (*api) { 1889d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian char const * name = *api; 1899d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian __eglMustCastToProperFunctionPointerType f = 1909d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); 1919d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (f == NULL) { 1929d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian // couldn't find the entry-point, use eglGetProcAddress() 1939d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian f = getProcAddress(name); 1949d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 1959d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (f == NULL) { 1969d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian // Try without the OES postfix 1979d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian ssize_t index = ssize_t(strlen(name)) - 3; 1989d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if ((index>0 && (index<255)) && (!strcmp(name+index, "OES"))) { 1999d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian strncpy(scrap, name, index); 2009d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian scrap[index] = 0; 2019d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); 2029d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian //LOGD_IF(f, "found <%s> instead", scrap); 2039d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 2049d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 2059d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (f == NULL) { 2069d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian // Try with the OES postfix 2079d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian ssize_t index = ssize_t(strlen(name)) - 3; 2089d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if ((index>0 && (index<252)) && (strcmp(name+index, "OES"))) { 2099d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian strncpy(scrap, name, index); 2109d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian scrap[index] = 0; 2119d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian strcat(scrap, "OES"); 2129d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); 2139d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian //LOGD_IF(f, "found <%s> instead", scrap); 2149d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 2159d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 2169d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (f == NULL) { 2179d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian //LOGD("%s", name); 2189d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented; 2199d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 2209d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian *curr++ = f; 2219d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian api++; 2229d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 2239d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian} 2249d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 22540621774ec648c7d0089f66b4e3aeb94e4232769Mathias Agopianvoid *Loader::load_driver(const char* driver_absolute_path, 2266fc569971faa342b2e2da46c55fbfbba3a2a7814Mathias Agopian egl_connection_t* cnx, uint32_t mask) 2279d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian{ 22840621774ec648c7d0089f66b4e3aeb94e4232769Mathias Agopian if (access(driver_absolute_path, R_OK)) { 22940621774ec648c7d0089f66b4e3aeb94e4232769Mathias Agopian // this happens often, we don't want to log an error 2309d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian return 0; 23140621774ec648c7d0089f66b4e3aeb94e4232769Mathias Agopian } 23240621774ec648c7d0089f66b4e3aeb94e4232769Mathias Agopian 23340621774ec648c7d0089f66b4e3aeb94e4232769Mathias Agopian void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL); 23440621774ec648c7d0089f66b4e3aeb94e4232769Mathias Agopian if (dso == 0) { 23540621774ec648c7d0089f66b4e3aeb94e4232769Mathias Agopian const char* err = dlerror(); 23640621774ec648c7d0089f66b4e3aeb94e4232769Mathias Agopian LOGE("load_driver(%s): %s", driver_absolute_path, err?err:"unknown"); 23740621774ec648c7d0089f66b4e3aeb94e4232769Mathias Agopian return 0; 23840621774ec648c7d0089f66b4e3aeb94e4232769Mathias Agopian } 2399d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 24040621774ec648c7d0089f66b4e3aeb94e4232769Mathias Agopian LOGD("loaded %s", driver_absolute_path); 24182fd4fce16b9bbde25d044acc86ddf7306ebdd10Mathias Agopian 2429d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (mask & EGL) { 2439d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress"); 2449d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 2459d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian LOGE_IF(!getProcAddress, 24640621774ec648c7d0089f66b4e3aeb94e4232769Mathias Agopian "can't find eglGetProcAddress() in %s", driver_absolute_path); 2479d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 2486fc569971faa342b2e2da46c55fbfbba3a2a7814Mathias Agopian egl_t* egl = &cnx->egl; 2499d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian __eglMustCastToProperFunctionPointerType* curr = 2509d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian (__eglMustCastToProperFunctionPointerType*)egl; 2519d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian char const * const * api = egl_names; 2529d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian while (*api) { 2539d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian char const * name = *api; 2549d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian __eglMustCastToProperFunctionPointerType f = 2559d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); 2569d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (f == NULL) { 2579d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian // couldn't find the entry-point, use eglGetProcAddress() 2589d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian f = getProcAddress(name); 2599d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (f == NULL) { 2609d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian f = (__eglMustCastToProperFunctionPointerType)0; 2619d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 2629d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 2639d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian *curr++ = f; 2649d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian api++; 2659d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 2669d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 2679d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 2689d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (mask & GLESv1_CM) { 2696fc569971faa342b2e2da46c55fbfbba3a2a7814Mathias Agopian init_api(dso, gl_names, 2706fc569971faa342b2e2da46c55fbfbba3a2a7814Mathias Agopian (__eglMustCastToProperFunctionPointerType*) 2716fc569971faa342b2e2da46c55fbfbba3a2a7814Mathias Agopian &cnx->hooks[GLESv1_INDEX]->gl, 2726fc569971faa342b2e2da46c55fbfbba3a2a7814Mathias Agopian getProcAddress); 2739d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 2749d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 2759d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian if (mask & GLESv2) { 2766fc569971faa342b2e2da46c55fbfbba3a2a7814Mathias Agopian init_api(dso, gl_names, 2776fc569971faa342b2e2da46c55fbfbba3a2a7814Mathias Agopian (__eglMustCastToProperFunctionPointerType*) 2786fc569971faa342b2e2da46c55fbfbba3a2a7814Mathias Agopian &cnx->hooks[GLESv2_INDEX]->gl, 2799d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian getProcAddress); 2809d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian } 2819d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 2829d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian return dso; 2839d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian} 2849d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian 2859d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian// ---------------------------------------------------------------------------- 2869d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian}; // namespace android 2879d17c057bdb9da5fa991a2c3efebe453106ca0a7Mathias Agopian// ---------------------------------------------------------------------------- 288