194cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall/* 2de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian ** Copyright 2007, The Android Open Source Project 3de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian ** 494cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall ** Licensed under the Apache License, Version 2.0 (the "License"); 594cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall ** you may not use this file except in compliance with the License. 694cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall ** You may obtain a copy of the License at 7de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian ** 894cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall ** http://www.apache.org/licenses/LICENSE-2.0 9de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian ** 1094cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall ** Unless required by applicable law or agreed to in writing, software 1194cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall ** distributed under the License is distributed on an "AS IS" BASIS, 1294cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1394cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall ** See the License for the specific language governing permissions and 14de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian ** limitations under the License. 15de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian */ 16de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 177a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall//#define LOG_NDEBUG 0 181508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall#define ATRACE_TAG ATRACE_TAG_GRAPHICS 197a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall 20311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian#include "Loader.h" 21311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian 2265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#include <string> 2365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian 24a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <dirent.h> 25de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian#include <dlfcn.h> 26de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 277a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall#include <android/dlext.h> 2880b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner#include <cutils/properties.h> 297823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h> 30311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian 31311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian#include <ui/GraphicsEnv.h> 32ea404010c2706f01a7b2622bbbf76acaaddad49dJustin Yun#include <vndksupport/linker.h> 33de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 3465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian#include "egl_trace.h" 351cadb25da1ed875bdd078270e642966724a0c39aMathias Agopian#include "egldefs.h" 36de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 375910dc7365f94ea10a879342710c76d577cb2690Jiyong Parkextern "C" { 385910dc7365f94ea10a879342710c76d577cb2690Jiyong Park android_namespace_t* android_get_exported_namespace(const char*); 395910dc7365f94ea10a879342710c76d577cb2690Jiyong Park} 405910dc7365f94ea10a879342710c76d577cb2690Jiyong Park 41de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian// ---------------------------------------------------------------------------- 42de58697644a52a614ad9498aa087e95d4a223673Mathias Agopiannamespace android { 43de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian// ---------------------------------------------------------------------------- 44de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 45de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 46de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian/* 47993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * EGL userspace drivers must be provided either: 48993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * - as a single library: 49993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * /vendor/lib/egl/libGLES.so 50993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * 51993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * - as separate libraries: 52993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * /vendor/lib/egl/libEGL.so 53993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * /vendor/lib/egl/libGLESv1_CM.so 54993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * /vendor/lib/egl/libGLESv2.so 55993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * 56993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * The software renderer for the emulator must be provided as a single 57993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * library at: 58993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * 59993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * /system/lib/egl/libGLES_android.so 60993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * 61993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * 62993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * For backward compatibility and to facilitate the transition to 63993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * this new naming scheme, the loader will additionally look for: 6494cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall * 65993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian * /{vendor|system}/lib/egl/lib{GLES | [EGL|GLESv1_CM|GLESv2]}_*.so 6694cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall * 67de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian */ 68de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 6965421435a67b881dad79e7008e9dee7fb425f180Mathias AgopianLoader& Loader::getInstance() { 7065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian static Loader loader; 7165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian return loader; 7265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian} 73de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 7480b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner/* This function is called to check whether we run inside the emulator, 7580b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner * and if this is the case whether GLES GPU emulation is supported. 7680b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner * 7780b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner * Returned values are: 7880b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner * -1 -> not running inside the emulator 7980b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner * 0 -> running inside the emulator, but GPU emulation not supported 8080b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner * 1 -> running inside the emulator, GPU emulation is supported 81776951f9db5744c94167d463584e9ee42c849712Nicolas Capens * through the "emulation" host-side OpenGL ES implementation. 82776951f9db5744c94167d463584e9ee42c849712Nicolas Capens * 2 -> running inside the emulator, GPU emulation is supported 83776951f9db5744c94167d463584e9ee42c849712Nicolas Capens * through a guest-side vendor driver's OpenGL ES implementation. 8480b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner */ 8580b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turnerstatic int 8680b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' TurnercheckGlesEmulationStatus(void) 8780b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner{ 8880b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner /* We're going to check for the following kernel parameters: 8980b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner * 9080b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner * qemu=1 -> tells us that we run inside the emulator 9180b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner * android.qemu.gles=<number> -> tells us the GLES GPU emulation status 9280b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner * 9380b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner * Note that we will return <number> if we find it. This let us support 9480b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner * more additionnal emulation modes in the future. 9580b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner */ 9680b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner char prop[PROPERTY_VALUE_MAX]; 9780b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner int result = -1; 9880b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner 9980b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner /* First, check for qemu=1 */ 10080b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner property_get("ro.kernel.qemu",prop,"0"); 10180b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner if (atoi(prop) != 1) 10280b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner return -1; 10380b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner 10480b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner /* We are in the emulator, get GPU status value */ 10569e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu property_get("qemu.gles",prop,"0"); 10680b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner return atoi(prop); 10780b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner} 10880b30c24ffc0f67b87d7a6b29f616d1c521d40aeDavid 'Digit' Turner 1091508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hallstatic void* do_dlopen(const char* path, int mode) { 1101508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall ATRACE_CALL(); 1111508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall return dlopen(path, mode); 1121508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall} 1131508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall 1145910dc7365f94ea10a879342710c76d577cb2690Jiyong Parkstatic void* do_android_dlopen_ext(const char* path, int mode, const android_dlextinfo* info) { 1155910dc7365f94ea10a879342710c76d577cb2690Jiyong Park ATRACE_CALL(); 1165910dc7365f94ea10a879342710c76d577cb2690Jiyong Park return android_dlopen_ext(path, mode, info); 1175910dc7365f94ea10a879342710c76d577cb2690Jiyong Park} 1185910dc7365f94ea10a879342710c76d577cb2690Jiyong Park 119ea404010c2706f01a7b2622bbbf76acaaddad49dJustin Yunstatic void* do_android_load_sphal_library(const char* path, int mode) { 120ea404010c2706f01a7b2622bbbf76acaaddad49dJustin Yun ATRACE_CALL(); 121ea404010c2706f01a7b2622bbbf76acaaddad49dJustin Yun return android_load_sphal_library(path, mode); 122ea404010c2706f01a7b2622bbbf76acaaddad49dJustin Yun} 123ea404010c2706f01a7b2622bbbf76acaaddad49dJustin Yun 124de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian// ---------------------------------------------------------------------------- 125de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 12694cdba97ce1de140623d84c14fb15f12f7da89ddJesse HallLoader::driver_t::driver_t(void* gles) 127de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{ 128de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian dso[0] = gles; 129de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian for (size_t i=1 ; i<NELEM(dso) ; i++) 130de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian dso[i] = 0; 131de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian} 132de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 13394cdba97ce1de140623d84c14fb15f12f7da89ddJesse HallLoader::driver_t::~driver_t() 134de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{ 135de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian for (size_t i=0 ; i<NELEM(dso) ; i++) { 136de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian if (dso[i]) { 137de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian dlclose(dso[i]); 138de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian dso[i] = 0; 139de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 140de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 141de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian} 142de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 14365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopianint Loader::driver_t::set(void* hnd, int32_t api) 144de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{ 145de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian switch (api) { 146de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian case EGL: 147de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian dso[0] = hnd; 148de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian break; 149de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian case GLESv1_CM: 150de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian dso[1] = hnd; 151de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian break; 152de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian case GLESv2: 153de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian dso[2] = hnd; 154de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian break; 155de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian default: 15665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian return -EOVERFLOW; 157de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 15865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian return 0; 159de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian} 160de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 161de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian// ---------------------------------------------------------------------------- 162de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 163de58697644a52a614ad9498aa087e95d4a223673Mathias AgopianLoader::Loader() 164991d2545afb325a3ebb8679519c4b0c13e29fadaMathias Agopian : getProcAddress(NULL) 1657a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall{ 166de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian} 167de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 168993814255fc248454368ed9fe34b4703a05eaf99Mathias AgopianLoader::~Loader() { 169de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian} 170de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 171c07b52060acd627c8510c1a9151e0753fce76330Jesse Hallstatic void* load_wrapper(const char* path) { 1721508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall void* so = do_dlopen(path, RTLD_NOW | RTLD_LOCAL); 173c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall ALOGE_IF(!so, "dlopen(\"%s\") failed: %s", path, dlerror()); 174c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall return so; 175c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall} 176c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall 177c2466e6f005e9cbeea7764e9d8864fa6bca17633Evgenii Stepanov#ifndef EGL_WRAPPER_DIR 178c2466e6f005e9cbeea7764e9d8864fa6bca17633Evgenii Stepanov#if defined(__LP64__) 179c2466e6f005e9cbeea7764e9d8864fa6bca17633Evgenii Stepanov#define EGL_WRAPPER_DIR "/system/lib64" 180c2466e6f005e9cbeea7764e9d8864fa6bca17633Evgenii Stepanov#else 181c2466e6f005e9cbeea7764e9d8864fa6bca17633Evgenii Stepanov#define EGL_WRAPPER_DIR "/system/lib" 182c2466e6f005e9cbeea7764e9d8864fa6bca17633Evgenii Stepanov#endif 183c2466e6f005e9cbeea7764e9d8864fa6bca17633Evgenii Stepanov#endif 184c2466e6f005e9cbeea7764e9d8864fa6bca17633Evgenii Stepanov 18569e5b1ab80018817b1d4ffbbdb5695ff70168c95bohustatic void setEmulatorGlesValue(void) { 18669e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu char prop[PROPERTY_VALUE_MAX]; 18769e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu property_get("ro.kernel.qemu", prop, "0"); 18869e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu if (atoi(prop) != 1) return; 18969e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu 19069e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu property_get("ro.kernel.qemu.gles",prop,"0"); 19169e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu if (atoi(prop) == 1) { 19269e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu ALOGD("Emulator has host GPU support, qemu.gles is set to 1."); 19369e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu property_set("qemu.gles", "1"); 19469e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu return; 19569e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu } 19669e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu 19769e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu // for now, checking the following 19869e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu // directory is good enough for emulator system images 19969e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu const char* vendor_lib_path = 20069e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu#if defined(__LP64__) 20169e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu "/vendor/lib64/egl"; 20269e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu#else 20369e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu "/vendor/lib/egl"; 20469e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu#endif 20569e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu 20669e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu const bool has_vendor_lib = (access(vendor_lib_path, R_OK) == 0); 20769e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu if (has_vendor_lib) { 20869e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu ALOGD("Emulator has vendor provided software renderer, qemu.gles is set to 2."); 20969e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu property_set("qemu.gles", "2"); 21069e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu } else { 21169e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu ALOGD("Emulator without GPU support detected. " 21269e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu "Fallback to legacy software renderer, qemu.gles is set to 0."); 21369e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu property_set("qemu.gles", "0"); 21469e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu } 21569e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu} 21669e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu 217ada798b7ca7cabc255aa159964b64975e7fdb2dfMathias Agopianvoid* Loader::open(egl_connection_t* cnx) 218de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{ 2191508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall ATRACE_CALL(); 2201508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall 221de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian void* dso; 222de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian driver_t* hnd = 0; 22394cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall 22469e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu setEmulatorGlesValue(); 22569e5b1ab80018817b1d4ffbbdb5695ff70168c95bohu 226993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian dso = load_driver("GLES", cnx, EGL | GLESv1_CM | GLESv2); 227993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian if (dso) { 228993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian hnd = new driver_t(dso); 229993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian } else { 230993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian // Always load EGL first 231993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian dso = load_driver("EGL", cnx, EGL); 232de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian if (dso) { 233de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian hnd = new driver_t(dso); 234993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian hnd->set( load_driver("GLESv1_CM", cnx, GLESv1_CM), GLESv1_CM ); 235993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian hnd->set( load_driver("GLESv2", cnx, GLESv2), GLESv2 ); 236de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 237de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 238de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 239993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian LOG_ALWAYS_FATAL_IF(!hnd, "couldn't find an OpenGL ES implementation"); 240c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall 241c2466e6f005e9cbeea7764e9d8864fa6bca17633Evgenii Stepanov cnx->libEgl = load_wrapper(EGL_WRAPPER_DIR "/libEGL.so"); 242c2466e6f005e9cbeea7764e9d8864fa6bca17633Evgenii Stepanov cnx->libGles2 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv2.so"); 243c2466e6f005e9cbeea7764e9d8864fa6bca17633Evgenii Stepanov cnx->libGles1 = load_wrapper(EGL_WRAPPER_DIR "/libGLESv1_CM.so"); 244c2466e6f005e9cbeea7764e9d8864fa6bca17633Evgenii Stepanov 245c0ec5e2333b6350480851b8b48f000c78ea3f88aMichael Chock LOG_ALWAYS_FATAL_IF(!cnx->libEgl, 246c0ec5e2333b6350480851b8b48f000c78ea3f88aMichael Chock "couldn't load system EGL wrapper libraries"); 247c0ec5e2333b6350480851b8b48f000c78ea3f88aMichael Chock 248c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall LOG_ALWAYS_FATAL_IF(!cnx->libGles2 || !cnx->libGles1, 249c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall "couldn't load system OpenGL ES wrapper libraries"); 250c07b52060acd627c8510c1a9151e0753fce76330Jesse Hall 251de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian return (void*)hnd; 252de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian} 253de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 25465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopianvoid Loader::close(void* driver) 255de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{ 256de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian driver_t* hnd = (driver_t*)driver; 257de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian delete hnd; 258de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian} 259de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 26094cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hallvoid Loader::init_api(void* dso, 26194cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall char const * const * api, 26294cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall __eglMustCastToProperFunctionPointerType* curr, 26394cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall getProcAddressType getProcAddress) 264de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian{ 2651508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall ATRACE_CALL(); 2661508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall 2677773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian const ssize_t SIZE = 256; 2680ad71a97c6061e3b12d2308bd43e02dfeeb63db4Mathias Agopian char scrap[SIZE]; 269de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian while (*api) { 270de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian char const * name = *api; 27194cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall __eglMustCastToProperFunctionPointerType f = 272de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); 273de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian if (f == NULL) { 274de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian // couldn't find the entry-point, use eglGetProcAddress() 275de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian f = getProcAddress(name); 276de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 277de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian if (f == NULL) { 278de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian // Try without the OES postfix 279de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian ssize_t index = ssize_t(strlen(name)) - 3; 2800ad71a97c6061e3b12d2308bd43e02dfeeb63db4Mathias Agopian if ((index>0 && (index<SIZE-1)) && (!strcmp(name+index, "OES"))) { 281de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian strncpy(scrap, name, index); 282de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian scrap[index] = 0; 283de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); 2849d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD_IF(f, "found <%s> instead", scrap); 285de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 286de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 287de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian if (f == NULL) { 288de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian // Try with the OES postfix 2890ad71a97c6061e3b12d2308bd43e02dfeeb63db4Mathias Agopian ssize_t index = ssize_t(strlen(name)) - 3; 2900ad71a97c6061e3b12d2308bd43e02dfeeb63db4Mathias Agopian if (index>0 && strcmp(name+index, "OES")) { 2910ad71a97c6061e3b12d2308bd43e02dfeeb63db4Mathias Agopian snprintf(scrap, SIZE, "%sOES", name); 292de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap); 2939d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD_IF(f, "found <%s> instead", scrap); 294de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 295de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 296de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian if (f == NULL) { 2979d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("%s", name); 298de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented; 29948d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian 30048d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian /* 30148d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian * GL_EXT_debug_label is special, we always report it as 30248d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian * supported, it's handled by GLES_trace. If GLES_trace is not 30348d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian * enabled, then these are no-ops. 30448d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian */ 30548d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian if (!strcmp(name, "glInsertEventMarkerEXT")) { 30648d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian f = (__eglMustCastToProperFunctionPointerType)gl_noop; 30748d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian } else if (!strcmp(name, "glPushGroupMarkerEXT")) { 30848d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian f = (__eglMustCastToProperFunctionPointerType)gl_noop; 30948d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian } else if (!strcmp(name, "glPopGroupMarkerEXT")) { 31048d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian f = (__eglMustCastToProperFunctionPointerType)gl_noop; 31148d438d05f14c2f4bd83ae89f520368cd49122dfMathias Agopian } 312de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 313de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian *curr++ = f; 314de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian api++; 315de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 316de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian} 317de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 3187a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hallstatic void* load_system_driver(const char* kind) { 3191508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall ATRACE_CALL(); 320993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian class MatchFile { 321993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian public: 32265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian static std::string find(const char* kind) { 32365421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian std::string result; 324776951f9db5744c94167d463584e9ee42c849712Nicolas Capens int emulationStatus = checkGlesEmulationStatus(); 325776951f9db5744c94167d463584e9ee42c849712Nicolas Capens switch (emulationStatus) { 326776951f9db5744c94167d463584e9ee42c849712Nicolas Capens case 0: 327776951f9db5744c94167d463584e9ee42c849712Nicolas Capens#if defined(__LP64__) 32865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian result = "/system/lib64/egl/libGLES_android.so"; 329776951f9db5744c94167d463584e9ee42c849712Nicolas Capens#else 33065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian result = "/system/lib/egl/libGLES_android.so"; 331776951f9db5744c94167d463584e9ee42c849712Nicolas Capens#endif 332776951f9db5744c94167d463584e9ee42c849712Nicolas Capens return result; 333776951f9db5744c94167d463584e9ee42c849712Nicolas Capens case 1: 334776951f9db5744c94167d463584e9ee42c849712Nicolas Capens // Use host-side OpenGL through the "emulation" library 335776951f9db5744c94167d463584e9ee42c849712Nicolas Capens#if defined(__LP64__) 33665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian result = std::string("/system/lib64/egl/lib") + kind + "_emulation.so"; 337776951f9db5744c94167d463584e9ee42c849712Nicolas Capens#else 33865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian result = std::string("/system/lib/egl/lib") + kind + "_emulation.so"; 339776951f9db5744c94167d463584e9ee42c849712Nicolas Capens#endif 340776951f9db5744c94167d463584e9ee42c849712Nicolas Capens return result; 341776951f9db5744c94167d463584e9ee42c849712Nicolas Capens default: 342776951f9db5744c94167d463584e9ee42c849712Nicolas Capens // Not in emulator, or use other guest-side implementation 343776951f9db5744c94167d463584e9ee42c849712Nicolas Capens break; 344776951f9db5744c94167d463584e9ee42c849712Nicolas Capens } 345776951f9db5744c94167d463584e9ee42c849712Nicolas Capens 34665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian std::string pattern = std::string("lib") + kind; 347993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian const char* const searchPaths[] = { 3488edb8f5f2d016e4e31530ad7a0c44a4a7a853f64Dan Willemsen#if defined(__LP64__) 3498edb8f5f2d016e4e31530ad7a0c44a4a7a853f64Dan Willemsen "/vendor/lib64/egl", 3508edb8f5f2d016e4e31530ad7a0c44a4a7a853f64Dan Willemsen "/system/lib64/egl" 3518edb8f5f2d016e4e31530ad7a0c44a4a7a853f64Dan Willemsen#else 352993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian "/vendor/lib/egl", 353993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian "/system/lib/egl" 3548edb8f5f2d016e4e31530ad7a0c44a4a7a853f64Dan Willemsen#endif 355993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian }; 356993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian 357993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian // first, we search for the exact name of the GLES userspace 358993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian // driver in both locations. 359993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian // i.e.: 360993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian // libGLES.so, or: 361993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian // libEGL.so, libGLESv1_CM.so, libGLESv2.so 362993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian 363993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian for (size_t i=0 ; i<NELEM(searchPaths) ; i++) { 364993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian if (find(result, pattern, searchPaths[i], true)) { 365993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian return result; 366993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian } 367993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian } 368993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian 369993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian // for compatibility with the old "egl.cfg" naming convention 370993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian // we look for files that match: 371993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian // libGLES_*.so, or: 372993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian // libEGL_*.so, libGLESv1_CM_*.so, libGLESv2_*.so 373993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian 374993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian pattern.append("_"); 375993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian for (size_t i=0 ; i<NELEM(searchPaths) ; i++) { 376993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian if (find(result, pattern, searchPaths[i], false)) { 377993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian return result; 378993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian } 379993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian } 380993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian 381993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian // we didn't find the driver. gah. 382993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian result.clear(); 383993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian return result; 384993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian } 385993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian 386993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian private: 38765421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian static bool find(std::string& result, 38865421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian const std::string& pattern, const char* const search, bool exact) { 389993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian if (exact) { 39065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian std::string absolutePath = std::string(search) + "/" + pattern; 39165421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian if (!access(absolutePath.c_str(), R_OK)) { 392993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian result = absolutePath; 393993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian return true; 394993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian } 395993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian return false; 396993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian } 397993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian 398993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian DIR* d = opendir(search); 399993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian if (d != NULL) { 400993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian struct dirent cur; 401993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian struct dirent* e; 402993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian while (readdir_r(d, &cur, &e) == 0 && e) { 403993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian if (e->d_type == DT_DIR) { 404993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian continue; 405993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian } 406993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian if (!strcmp(e->d_name, "libGLES_android.so")) { 407993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian // always skip the software renderer 408993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian continue; 409993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian } 41065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian if (strstr(e->d_name, pattern.c_str()) == e->d_name) { 411993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian if (!strcmp(e->d_name + strlen(e->d_name) - 3, ".so")) { 41265421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian result = std::string(search) + "/" + e->d_name; 413993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian closedir(d); 414993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian return true; 415993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian } 416993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian } 417993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian } 418993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian closedir(d); 419993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian } 420993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian return false; 4212b9e4f6a2490864ead44e88a68da78be5cb3da22Brian Swetland } 422993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian }; 423993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian 424993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian 42565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian std::string absolutePath = MatchFile::find(kind); 42665421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian if (absolutePath.empty()) { 427993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian // this happens often, we don't want to log an error 428993814255fc248454368ed9fe34b4703a05eaf99Mathias Agopian return 0; 4298c17384a5edd027376926b857af1fb170dbe9b43Mathias Agopian } 43065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian const char* const driver_absolute_path = absolutePath.c_str(); 4318c17384a5edd027376926b857af1fb170dbe9b43Mathias Agopian 4325910dc7365f94ea10a879342710c76d577cb2690Jiyong Park // Try to load drivers from the 'sphal' namespace, if it exist. Fall back to 433ea404010c2706f01a7b2622bbbf76acaaddad49dJustin Yun // the original routine when the namespace does not exist. 4345910dc7365f94ea10a879342710c76d577cb2690Jiyong Park // See /system/core/rootdir/etc/ld.config.txt for the configuration of the 4355910dc7365f94ea10a879342710c76d577cb2690Jiyong Park // sphal namespace. 436ea404010c2706f01a7b2622bbbf76acaaddad49dJustin Yun void* dso = do_android_load_sphal_library(driver_absolute_path, 437ea404010c2706f01a7b2622bbbf76acaaddad49dJustin Yun RTLD_NOW | RTLD_LOCAL); 4388c17384a5edd027376926b857af1fb170dbe9b43Mathias Agopian if (dso == 0) { 4398c17384a5edd027376926b857af1fb170dbe9b43Mathias Agopian const char* err = dlerror(); 44065421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian ALOGE("load_driver(%s): %s", driver_absolute_path, err ? err : "unknown"); 4418c17384a5edd027376926b857af1fb170dbe9b43Mathias Agopian return 0; 4428c17384a5edd027376926b857af1fb170dbe9b43Mathias Agopian } 443de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 4449d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("loaded %s", driver_absolute_path); 445baca89c06a40c6c19ae2294fb4263d893126320cMathias Agopian 4467a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall return dso; 4477a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall} 4487a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall 449311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopianstatic const char* HAL_SUBNAME_KEY_PROPERTIES[2] = { 4507a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall "ro.hardware.egl", 4517a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall "ro.board.platform", 452311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian}; 4537a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall 4547a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hallstatic void* load_updated_driver(const char* kind, android_namespace_t* ns) { 4551508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall ATRACE_CALL(); 4567a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall const android_dlextinfo dlextinfo = { 4577a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall .flags = ANDROID_DLEXT_USE_NAMESPACE, 4587a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall .library_namespace = ns, 4597a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall }; 4607a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall void* so = nullptr; 4617a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall char prop[PROPERTY_VALUE_MAX + 1]; 4627a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall for (auto key : HAL_SUBNAME_KEY_PROPERTIES) { 4637a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall if (property_get(key, prop, nullptr) > 0) { 46465421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian std::string name = std::string("lib") + kind + "_" + prop + ".so"; 46565421435a67b881dad79e7008e9dee7fb425f180Mathias Agopian so = do_android_dlopen_ext(name.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo); 466311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian if (so) { 4677a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall return so; 468311b479d7f50bc9e487cf9b4859843d0f4778382Mathias Agopian } 4697a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall } 4707a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall } 4717a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall return nullptr; 4727a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall} 4737a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall 4747a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hallvoid *Loader::load_driver(const char* kind, 4757a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall egl_connection_t* cnx, uint32_t mask) 4767a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall{ 4771508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall ATRACE_CALL(); 4781508ae60cc02d0ed84f216f3ddd43a932c2ede42Jesse Hall 4797a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall void* dso = nullptr; 480991d2545afb325a3ebb8679519c4b0c13e29fadaMathias Agopian android_namespace_t* ns = android_getDriverNamespace(); 481991d2545afb325a3ebb8679519c4b0c13e29fadaMathias Agopian if (ns) { 482991d2545afb325a3ebb8679519c4b0c13e29fadaMathias Agopian dso = load_updated_driver(kind, ns); 4837a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall } 4847a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall if (!dso) { 4857a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall dso = load_system_driver(kind); 4867a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall if (!dso) 4877a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall return NULL; 4887a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall } 4897a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall 490de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian if (mask & EGL) { 491de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress"); 492de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 49394cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall ALOGE_IF(!getProcAddress, 4947a8d83ef77b31097cbccfc89ee93414b3f2c2d03Jesse Hall "can't find eglGetProcAddress() in EGL driver library"); 495de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 496618fa10949c42eb83fa5fe105fe542bcff833ddaMathias Agopian egl_t* egl = &cnx->egl; 497de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian __eglMustCastToProperFunctionPointerType* curr = 498de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian (__eglMustCastToProperFunctionPointerType*)egl; 499de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian char const * const * api = egl_names; 500de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian while (*api) { 501de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian char const * name = *api; 50294cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall __eglMustCastToProperFunctionPointerType f = 503de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian (__eglMustCastToProperFunctionPointerType)dlsym(dso, name); 504de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian if (f == NULL) { 505de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian // couldn't find the entry-point, use eglGetProcAddress() 506de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian f = getProcAddress(name); 507de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian if (f == NULL) { 508de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian f = (__eglMustCastToProperFunctionPointerType)0; 509de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 510de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 511de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian *curr++ = f; 512de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian api++; 513de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 514de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 51594cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall 516de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian if (mask & GLESv1_CM) { 517618fa10949c42eb83fa5fe105fe542bcff833ddaMathias Agopian init_api(dso, gl_names, 518618fa10949c42eb83fa5fe105fe542bcff833ddaMathias Agopian (__eglMustCastToProperFunctionPointerType*) 5197773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian &cnx->hooks[egl_connection_t::GLESv1_INDEX]->gl, 520618fa10949c42eb83fa5fe105fe542bcff833ddaMathias Agopian getProcAddress); 521de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 522de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 523de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian if (mask & GLESv2) { 524618fa10949c42eb83fa5fe105fe542bcff833ddaMathias Agopian init_api(dso, gl_names, 525618fa10949c42eb83fa5fe105fe542bcff833ddaMathias Agopian (__eglMustCastToProperFunctionPointerType*) 5267773c435bc5da8217433e1b242d3a6712a17b5f7Mathias Agopian &cnx->hooks[egl_connection_t::GLESv2_INDEX]->gl, 527de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian getProcAddress); 528de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian } 52994cdba97ce1de140623d84c14fb15f12f7da89ddJesse Hall 530de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian return dso; 531de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian} 532de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian 533de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian// ---------------------------------------------------------------------------- 534de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian}; // namespace android 535de58697644a52a614ad9498aa087e95d4a223673Mathias Agopian// ---------------------------------------------------------------------------- 536