Loader::Loader() { char line[256]; char tag[256]; /* Special case for GLES emulation */ if (checkGlesEmulationStatus() == 0) { LOGD("Emulator without GPU support detected. Fallback to software renderer."); gConfig.add( entry_t(0, 0, "android") ); return; } /* Otherwise, use egl.cfg */ FILE* cfg = fopen("/system/lib/egl/egl.cfg", "r"); if (cfg == NULL) { // default config LOGD("egl.cfg not found, using default config"); gConfig.add( entry_t(0, 0, "android") ); } else { while (fgets(line, 256, cfg)) { int dpy; int impl; if (sscanf(line, "%u %u %s", &dpy, &impl, tag) == 3) { //LOGD(">>> %u %u %s", dpy, impl, tag); gConfig.add( entry_t(dpy, impl, tag) ); } } fclose(cfg); } }
Loader::Loader() { char line[256]; char tag[256]; /* Special case for GLES emulation */ if (checkGlesEmulationStatus() == 0) { ALOGD("Emulator without GPU support detected. " "Fallback to software renderer."); mDriverTag.setTo("android"); return; } /* Otherwise, use egl.cfg */ FILE* cfg = fopen("/system/lib/egl/egl.cfg", "r"); if (cfg == NULL) { // default config ALOGD("egl.cfg not found, using default config"); mDriverTag.setTo("android"); } else { while (fgets(line, 256, cfg)) { int dpy, impl; if (sscanf(line, "%u %u %s", &dpy, &impl, tag) == 3) { //ALOGD(">>> %u %u %s", dpy, impl, tag); // We only load the h/w accelerated implementation if (tag != String8("android")) { mDriverTag = tag; } } } fclose(cfg); } }
static bool find(String8& result, const String8& pattern, const char* const search, bool exact) { // in the emulator case, we just return the hardcoded name // of the software renderer. if (checkGlesEmulationStatus() == 0) { ALOGD("Emulator without GPU support detected. " "Fallback to software renderer."); #if defined(__LP64__) result.setTo("/system/lib64/egl/libGLES_android.so"); #else result.setTo("/system/lib/egl/libGLES_android.so"); #endif return true; } if (exact) { String8 absolutePath; absolutePath.appendFormat("%s/%s.so", search, pattern.string()); if (!access(absolutePath.string(), R_OK)) { result = absolutePath; return true; } return false; } DIR* d = opendir(search); if (d != NULL) { struct dirent cur; struct dirent* e; while (readdir_r(d, &cur, &e) == 0 && e) { if (e->d_type == DT_DIR) { continue; } if (!strcmp(e->d_name, "libGLES_android.so")) { // always skip the software renderer continue; } if (strstr(e->d_name, pattern.string()) == e->d_name) { if (!strcmp(e->d_name + strlen(e->d_name) - 3, ".so")) { result.clear(); result.appendFormat("%s/%s", search, e->d_name); closedir(d); return true; } } } closedir(d); } return false; }
static String8 find(const char* kind) { String8 result; int emulationStatus = checkGlesEmulationStatus(); switch (emulationStatus) { case 0: #if defined(__LP64__) result.setTo("/system/lib64/egl/libGLES_android.so"); #else result.setTo("/system/lib/egl/libGLES_android.so"); #endif return result; case 1: // Use host-side OpenGL through the "emulation" library #if defined(__LP64__) result.appendFormat("/system/lib64/egl/lib%s_emulation.so", kind); #else result.appendFormat("/system/lib/egl/lib%s_emulation.so", kind); #endif return result; default: // Not in emulator, or use other guest-side implementation break; } String8 pattern; pattern.appendFormat("lib%s", kind); const char* const searchPaths[] = { #if defined(__LP64__) "/vendor/lib64/egl", "/system/lib64/egl" #else "/vendor/lib/egl", "/system/lib/egl" #endif }; // first, we search for the exact name of the GLES userspace // driver in both locations. // i.e.: // libGLES.so, or: // libEGL.so, libGLESv1_CM.so, libGLESv2.so for (size_t i=0 ; i<NELEM(searchPaths) ; i++) { if (find(result, pattern, searchPaths[i], true)) { return result; } } // for compatibility with the old "egl.cfg" naming convention // we look for files that match: // libGLES_*.so, or: // libEGL_*.so, libGLESv1_CM_*.so, libGLESv2_*.so pattern.append("_"); for (size_t i=0 ; i<NELEM(searchPaths) ; i++) { if (find(result, pattern, searchPaths[i], false)) { return result; } } // we didn't find the driver. gah. result.clear(); return result; }