diff options
author | Cody Northrop <cnorthrop@google.com> | 2019-11-07 21:34:34 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2019-11-07 21:34:34 +0000 |
commit | 712c4a14715ff9f8349096a9401e645c2469344d (patch) | |
tree | c5ae15d5bc8bc3a113e5d8663c21b5c2e1abe1fc | |
parent | 1d10c6f32d32e37286d975a45c9e6703d47075eb (diff) | |
parent | b2306edb48e2a63b37a77524bdf8c5262b1783ed (diff) | |
download | native-712c4a14715ff9f8349096a9401e645c2469344d.tar.gz |
Merge "EGL: Fix repeated extension lookups"
-rw-r--r-- | opengl/libs/EGL/egl_platform_entries.cpp | 91 |
1 files changed, 55 insertions, 36 deletions
diff --git a/opengl/libs/EGL/egl_platform_entries.cpp b/opengl/libs/EGL/egl_platform_entries.cpp index e996be6853..a3bb6debe9 100644 --- a/opengl/libs/EGL/egl_platform_entries.cpp +++ b/opengl/libs/EGL/egl_platform_entries.cpp @@ -61,7 +61,7 @@ namespace android { using nsecs_t = int64_t; -struct extention_map_t { +struct extension_map_t { const char* name; __eglMustCastToProperFunctionPointerType address; }; @@ -154,7 +154,7 @@ char const * const gClientExtensionString = * (keep in sync with gExtensionString above) * */ -static const extention_map_t sExtensionMap[] = { +static const extension_map_t sExtensionMap[] = { // EGL_KHR_lock_surface { "eglLockSurfaceKHR", (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR }, @@ -257,13 +257,14 @@ static const extention_map_t sExtensionMap[] = { !strcmp((procname), "eglAwakenProcessIMG")) // accesses protected by sExtensionMapMutex -static std::unordered_map<std::string, __eglMustCastToProperFunctionPointerType> sGLExtentionMap; +static std::unordered_map<std::string, __eglMustCastToProperFunctionPointerType> sGLExtensionMap; +static std::unordered_map<std::string, int> sGLExtensionSlotMap; -static int sGLExtentionSlot = 0; +static int sGLExtensionSlot = 0; static pthread_mutex_t sExtensionMapMutex = PTHREAD_MUTEX_INITIALIZER; static void(*findProcAddress(const char* name, - const extention_map_t* map, size_t n))() { + const extension_map_t* map, size_t n))() { for (uint32_t i=0 ; i<n ; i++) { if (!strcmp(name, map[i].name)) { return map[i].address; @@ -1223,7 +1224,7 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddressImpl(const char *procn addr = findBuiltinWrapper(procname); if (addr) return addr; - // this protects accesses to sGLExtentionMap and sGLExtentionSlot + // this protects accesses to sGLExtensionMap, sGLExtensionSlot, and sGLExtensionSlotMap pthread_mutex_lock(&sExtensionMapMutex); /* @@ -1244,51 +1245,69 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddressImpl(const char *procn */ const std::string name(procname); + auto& extensionMap = sGLExtensionMap; + auto& extensionSlotMap = sGLExtensionSlotMap; + egl_connection_t* const cnx = &gEGLImpl; + LayerLoader& layer_loader(LayerLoader::getInstance()); - auto& extentionMap = sGLExtentionMap; - auto pos = extentionMap.find(name); - addr = (pos != extentionMap.end()) ? pos->second : nullptr; - const int slot = sGLExtentionSlot; + // See if we've already looked up this extension + auto pos = extensionMap.find(name); + addr = (pos != extensionMap.end()) ? pos->second : nullptr; - ALOGE_IF(slot >= MAX_NUMBER_OF_GL_EXTENSIONS, - "no more slots for eglGetProcAddress(\"%s\")", - procname); + if (!addr) { + // This is the first time we've looked this function up + // Ensure we have room to track it + const int slot = sGLExtensionSlot; + if (slot < MAX_NUMBER_OF_GL_EXTENSIONS) { - egl_connection_t* const cnx = &gEGLImpl; - LayerLoader& layer_loader(LayerLoader::getInstance()); + if (cnx->dso && cnx->egl.eglGetProcAddress) { - if (!addr && (slot < MAX_NUMBER_OF_GL_EXTENSIONS)) { + // Extensions are independent of the bound context + addr = cnx->egl.eglGetProcAddress(procname); + if (addr) { - if (cnx->dso && cnx->egl.eglGetProcAddress) { + // purposefully track the bottom of the stack in extensionMap + extensionMap[name] = addr; - // Extensions are independent of the bound context - addr = cnx->egl.eglGetProcAddress(procname); - if (addr) { + // Apply layers + addr = layer_loader.ApplyLayers(procname, addr); - // purposefully track the bottom of the stack in extensionMap - extentionMap[name] = addr; + // Track the top most entry point return the extension forwarder + cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] = + cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] = addr; + addr = gExtensionForwarders[slot]; - // Apply layers - addr = layer_loader.ApplyLayers(procname, addr); + // Remember the slot for this extension + extensionSlotMap[name] = slot; - // Track the top most entry point - cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] = - cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] = addr; - addr = gExtensionForwarders[slot]; - sGLExtentionSlot++; + // Increment the global extension index + sGLExtensionSlot++; + } } + } else { + // The extension forwarder has a fixed number of slots + ALOGE("no more slots for eglGetProcAddress(\"%s\")", procname); } - } else if (slot < MAX_NUMBER_OF_GL_EXTENSIONS) { + } else { + // We tracked an address, so we've seen this func before + // Look up the slot for this extension + auto slot_pos = extensionSlotMap.find(name); + int ext_slot = (slot_pos != extensionSlotMap.end()) ? slot_pos->second : -1; + if (ext_slot < 0) { + // Something has gone wrong, this should not happen + ALOGE("No extension slot found for %s", procname); + return nullptr; + } - // We've seen this func before, but we tracked the bottom, so re-apply layers - // More layers might have been enabled + // We tracked the bottom of the stack, so re-apply layers since + // more layers might have been enabled addr = layer_loader.ApplyLayers(procname, addr); - // Track the top most entry point - cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] = - cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] = addr; - addr = gExtensionForwarders[slot]; + // Track the top most entry point and return the extension forwarder + cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[ext_slot] = + cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[ext_slot] = addr; + addr = gExtensionForwarders[ext_slot]; } pthread_mutex_unlock(&sExtensionMapMutex); |