#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#include <dlfcn.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
};
/*
- * This is the list of EGL extensions exposed to applications,
- * some of them are mandatory because used by the ANDROID system.
+ * This is the list of EGL extensions exposed to applications.
*
- * Mandatory extensions are required per the CDD and not explicitly
- * checked during EGL initialization. the system *assumes* these extensions
- * are present. the system may not function properly if some mandatory
- * extensions are missing.
+ * Some of them (gBuiltinExtensionString) are implemented entirely in this EGL
+ * wrapper and are always available.
*
- * NOTE: gExtensionString MUST have a single space as the last character.
+ * The rest (gExtensionString) depend on support in the EGL driver, and are
+ * only available if the driver supports them. However, some of these must be
+ * supported because they are used by the Android system itself; these are
+ * listd as mandatory below and are required by the CDD. The system *assumes*
+ * the mandatory extensions are present and may not function properly if some
+ * are missing.
+ *
+ * NOTE: Both strings MUST have a single space as the last character.
*/
+extern char const * const gBuiltinExtensionString =
+ "EGL_KHR_get_all_proc_addresses "
+ "EGL_ANDROID_presentation_time "
+ ;
extern char const * const gExtensionString =
"EGL_KHR_image " // mandatory
"EGL_KHR_image_base " // mandatory
"EGL_NV_system_time "
"EGL_ANDROID_image_native_buffer " // mandatory
"EGL_KHR_wait_sync " // strongly recommended
- "EGL_ANDROID_presentation_time "
;
// extensions not exposed to applications but used by the ANDROID system
if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != OK) {
ALOGE("EGLNativeWindowType %p already connected to another API",
window);
- return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
// set the native window's buffers format to match this config
setError(EGL_BAD_SURFACE, EGL_FALSE);
return;
}
-
- int64_t timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
-
- egl_surface_t const * const s = get_surface(surface);
- native_window_set_buffers_timestamp(s->win.get(), timestamp);
}
// ----------------------------------------------------------------------------
return err;
}
+static __eglMustCastToProperFunctionPointerType findBuiltinGLWrapper(
+ const char* procname) {
+ const egl_connection_t* cnx = &gEGLImpl;
+ void* proc = NULL;
+
+ proc = dlsym(cnx->libGles2, procname);
+ if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
+
+ proc = dlsym(cnx->libGles1, procname);
+ if (proc) return (__eglMustCastToProperFunctionPointerType)proc;
+
+ return NULL;
+}
+
__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
{
// eglGetProcAddress() could be the very first function called
addr = findProcAddress(procname, sExtensionMap, NELEM(sExtensionMap));
if (addr) return addr;
+ addr = findBuiltinGLWrapper(procname);
+ if (addr) return addr;
// this protects accesses to sGLExtentionMap and sGLExtentionSlot
pthread_mutex_lock(&sExtensionMapMutex);
}
if (found) {
-#if USE_FAST_TLS_KEY
addr = gExtensionForwarders[slot];
-#endif
sGLExtentionMap.add(name, addr);
sGLExtentionSlot++;
}
{
clearError();
+#if EGL_TRACE
+ if (getEGLDebugLevel() > 0)
+ GLTrace_eglReleaseThread();
+#endif
+
// If there is context bound to the thread, release it
egl_display_t::loseCurrent(get_context(getContext()));
if (cnx->dso && cnx->egl.eglReleaseThread) {
cnx->egl.eglReleaseThread();
}
-
egl_tls_t::clearTLS();
-#if EGL_TRACE
- if (getEGLDebugLevel() > 0)
- GLTrace_eglReleaseThread();
-#endif
return EGL_TRUE;
}