diff options
Diffstat (limited to 'opengl/libs/EGL/eglApi.cpp')
-rw-r--r-- | opengl/libs/EGL/eglApi.cpp | 285 |
1 files changed, 223 insertions, 62 deletions
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index d1f7c57..f39c386 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -1,21 +1,22 @@ -/* +/* ** Copyright 2007, The Android Open Source Project ** - ** Licensed under the Apache License, Version 2.0 (the "License"); - ** you may not use this file except in compliance with the License. - ** You may obtain a copy of the License at + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at ** - ** http://www.apache.org/licenses/LICENSE-2.0 + ** http://www.apache.org/licenses/LICENSE-2.0 ** - ** Unless required by applicable law or agreed to in writing, software - ** distributed under the License is distributed on an "AS IS" BASIS, - ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - ** See the License for the specific language governing permissions and + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and ** limitations under the License. */ #define ATRACE_TAG ATRACE_TAG_GRAPHICS +#include <dlfcn.h> #include <ctype.h> #include <stdlib.h> #include <string.h> @@ -25,8 +26,6 @@ #include <EGL/egl.h> #include <EGL/eglext.h> -#include <GLES/gl.h> -#include <GLES/glext.h> #include <cutils/log.h> #include <cutils/atomic.h> @@ -39,13 +38,11 @@ #include <utils/String8.h> #include <utils/Trace.h> -#include "egl_impl.h" -#include "egl_tls.h" -#include "glestrace.h" -#include "hooks.h" +#include "../egl_impl.h" +#include "../glestrace.h" +#include "../hooks.h" #include "egl_display.h" -#include "egl_impl.h" #include "egl_object.h" #include "egl_tls.h" #include "egldefs.h" @@ -54,28 +51,107 @@ using namespace android; // ---------------------------------------------------------------------------- -#define EGL_VERSION_HW_ANDROID 0x3143 +namespace android { struct extention_map_t { const char* name; __eglMustCastToProperFunctionPointerType address; }; -static const extention_map_t sExtentionMap[] = { +/* + * This is the list of EGL extensions exposed to applications, + * some of them are mandatory because used by the ANDROID system. + * + * 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. + * + * NOTE: gExtensionString MUST have a single space as the last character. + */ +extern char const * const gExtensionString = + "EGL_KHR_image " // mandatory + "EGL_KHR_image_base " // mandatory + "EGL_KHR_image_pixmap " + "EGL_KHR_lock_surface " + "EGL_KHR_gl_texture_2D_image " + "EGL_KHR_gl_texture_cubemap_image " + "EGL_KHR_gl_renderbuffer_image " + "EGL_KHR_reusable_sync " + "EGL_KHR_fence_sync " + "EGL_KHR_create_context " + "EGL_EXT_create_context_robustness " + "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 +// "EGL_ANDROID_blob_cache " // strongly recommended +// "EGL_IMG_hibernate_process " // optional +// "EGL_ANDROID_native_fence_sync " // strongly recommended +// "EGL_ANDROID_framebuffer_target " // mandatory for HWC 1.1 +// "EGL_ANDROID_recordable " // mandatory + + +/* + * EGL Extensions entry-points exposed to 3rd party applications + * (keep in sync with gExtensionString above) + * + */ +static const extention_map_t sExtensionMap[] = { + // EGL_KHR_lock_surface { "eglLockSurfaceKHR", (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR }, { "eglUnlockSurfaceKHR", (__eglMustCastToProperFunctionPointerType)&eglUnlockSurfaceKHR }, + + // EGL_KHR_image, EGL_KHR_image_base { "eglCreateImageKHR", (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR }, { "eglDestroyImageKHR", (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, + + // EGL_KHR_reusable_sync, EGL_KHR_fence_sync + { "eglCreateSyncKHR", + (__eglMustCastToProperFunctionPointerType)&eglCreateSyncKHR }, + { "eglDestroySyncKHR", + (__eglMustCastToProperFunctionPointerType)&eglDestroySyncKHR }, + { "eglClientWaitSyncKHR", + (__eglMustCastToProperFunctionPointerType)&eglClientWaitSyncKHR }, + { "eglSignalSyncKHR", + (__eglMustCastToProperFunctionPointerType)&eglSignalSyncKHR }, + { "eglGetSyncAttribKHR", + (__eglMustCastToProperFunctionPointerType)&eglGetSyncAttribKHR }, + + // EGL_NV_system_time { "eglGetSystemTimeFrequencyNV", (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeFrequencyNV }, { "eglGetSystemTimeNV", (__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeNV }, + + // EGL_KHR_wait_sync + { "eglWaitSyncKHR", + (__eglMustCastToProperFunctionPointerType)&eglWaitSyncKHR }, + + // EGL_ANDROID_presentation_time + { "eglPresentationTimeANDROID", + (__eglMustCastToProperFunctionPointerType)&eglPresentationTimeANDROID }, }; +/* + * These extensions entry-points should not be exposed to applications. + * They're used internally by the Android EGL layer. + */ +#define FILTER_EXTENSIONS(procname) \ + (!strcmp((procname), "eglSetBlobCacheFuncsANDROID") || \ + !strcmp((procname), "eglHibernateProcessIMG") || \ + !strcmp((procname), "eglAwakenProcessIMG") || \ + !strcmp((procname), "eglDupNativeFenceFDANDROID")) + + + // accesses protected by sExtensionMapMutex static DefaultKeyedVector<String8, __eglMustCastToProperFunctionPointerType> sGLExtentionMap; static int sGLExtentionSlot = 0; @@ -93,14 +169,16 @@ static void(*findProcAddress(const char* name, // ---------------------------------------------------------------------------- -namespace android { extern void setGLHooksThreadSpecific(gl_hooks_t const *value); extern EGLBoolean egl_init_drivers(); extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS]; -extern int gEGLDebugLevel; +extern int getEGLDebugLevel(); +extern void setEGLDebugLevel(int level); extern gl_hooks_t gHooksTrace; + } // namespace android; + // ---------------------------------------------------------------------------- static inline void clearError() { egl_tls_t::clearError(); } @@ -153,7 +231,7 @@ EGLBoolean eglTerminate(EGLDisplay dpy) if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE); EGLBoolean res = dp->terminate(); - + return res; } @@ -234,7 +312,7 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, if (attribRendererable && attribRendererable[1] == EGL_OPENGL_ES2_BIT && (!attribCaveat || attribCaveat[1] != EGL_NONE)) { - + // Insert 2 extra attributes to force-enable MSAA 4x EGLint aaAttribs[attribCount + 4]; aaAttribs[0] = EGL_SAMPLE_BUFFERS; @@ -271,7 +349,7 @@ EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, egl_connection_t* cnx = NULL; const egl_display_ptr dp = validate_display_connection(dpy, cnx); if (!dp) return EGL_FALSE; - + return cnx->egl.eglGetConfigAttrib( dp->disp.dpy, config, attribute, value); } @@ -370,7 +448,7 @@ EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config, } return EGL_NO_SURFACE; } - + EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { clearError(); @@ -459,7 +537,7 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, if (attr == EGL_CONTEXT_CLIENT_VERSION) { if (value == 1) { version = egl_connection_t::GLESv1_INDEX; - } else if (value == 2) { + } else if (value == 2 || value == 3) { version = egl_connection_t::GLESv2_INDEX; } } @@ -468,7 +546,7 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, egl_context_t* c = new egl_context_t(dpy, context, config, cnx, version); #if EGL_TRACE - if (gEGLDebugLevel > 0) + if (getEGLDebugLevel() > 0) GLTrace_eglCreateContext(version, c); #endif return c; @@ -494,7 +572,7 @@ EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) ContextRef _c(dp.get(), ctx); if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE); - + egl_context_t * const c = get_context(ctx); EGLBoolean result = c->cnx->egl.eglDestroyContext(dp->disp.dpy, c->context); if (result == EGL_TRUE) { @@ -542,7 +620,7 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, // these are the current objects structs egl_context_t * cur_c = get_context(getContext()); - + if (ctx != EGL_NO_CONTEXT) { c = get_context(ctx); impl_ctx = c->context; @@ -583,7 +661,7 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, setGLHooksThreadSpecific(c->cnx->hooks[c->version]); egl_tls_t::setContext(ctx); #if EGL_TRACE - if (gEGLDebugLevel > 0) + if (getEGLDebugLevel() > 0) GLTrace_eglMakeCurrent(c->version, c->cnx->hooks[c->version], ctx); #endif _c.acquire(); @@ -642,7 +720,7 @@ EGLSurface eglGetCurrentSurface(EGLint readdraw) if (!c) return setError(EGL_BAD_CONTEXT, EGL_NO_SURFACE); switch (readdraw) { case EGL_READ: return c->read; - case EGL_DRAW: return c->draw; + case EGL_DRAW: return c->draw; default: return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE); } } @@ -700,6 +778,20 @@ EGLint eglGetError(void) 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 @@ -713,20 +805,16 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) return NULL; } - // These extensions should not be exposed to applications. They're used - // internally by the Android EGL layer. - if (!strcmp(procname, "eglSetBlobCacheFuncsANDROID") || - !strcmp(procname, "eglDupNativeFenceFDANDROID") || - !strcmp(procname, "eglWaitSyncANDROID") || - !strcmp(procname, "eglHibernateProcessIMG") || - !strcmp(procname, "eglAwakenProcessIMG")) { + if (FILTER_EXTENSIONS(procname)) { return NULL; } __eglMustCastToProperFunctionPointerType addr; - addr = findProcAddress(procname, sExtentionMap, NELEM(sExtentionMap)); + 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); @@ -866,12 +954,42 @@ EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) return setError(EGL_BAD_SURFACE, EGL_FALSE); #if EGL_TRACE - if (gEGLDebugLevel > 0) + gl_hooks_t const *trace_hooks = getGLTraceThreadSpecific(); + if (getEGLDebugLevel() > 0) { + if (trace_hooks == NULL) { + if (GLTrace_start() < 0) { + ALOGE("Disabling Tracer for OpenGL ES"); + setEGLDebugLevel(0); + } else { + // switch over to the trace version of hooks + EGLContext ctx = egl_tls_t::getContext(); + egl_context_t * const c = get_context(ctx); + if (c) { + setGLHooksThreadSpecific(c->cnx->hooks[c->version]); + GLTrace_eglMakeCurrent(c->version, c->cnx->hooks[c->version], ctx); + } + } + } + GLTrace_eglSwapBuffers(dpy, draw); + } else if (trace_hooks != NULL) { + // tracing is now disabled, so switch back to the non trace version + EGLContext ctx = egl_tls_t::getContext(); + egl_context_t * const c = get_context(ctx); + if (c) setGLHooksThreadSpecific(c->cnx->hooks[c->version]); + GLTrace_stop(); + } #endif egl_surface_t const * const s = get_surface(draw); + if (CC_UNLIKELY(dp->traceGpuCompletion)) { + EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); + if (sync != EGL_NO_SYNC_KHR) { + FrameCompletionThread::queueSync(sync); + } + } + if (CC_UNLIKELY(dp->finishOnSwap)) { uint32_t pixel; egl_context_t * const c = get_context( egl_tls_t::getContext() ); @@ -882,19 +1000,7 @@ EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) } } - EGLBoolean result = s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface); - - if (CC_UNLIKELY(dp->traceGpuCompletion)) { - EGLSyncKHR sync = EGL_NO_SYNC_KHR; - { - sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL); - } - if (sync != EGL_NO_SYNC_KHR) { - FrameCompletionThread::queueSync(sync); - } - } - - return result; + return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface); } EGLBoolean eglCopyBuffers( EGLDisplay dpy, EGLSurface surface, @@ -929,12 +1035,29 @@ const char* eglQueryString(EGLDisplay dpy, EGLint name) return dp->getExtensionString(); case EGL_CLIENT_APIS: return dp->getClientApiString(); - case EGL_VERSION_HW_ANDROID: - return dp->disp.queryString.version; } return setError(EGL_BAD_PARAMETER, (const char *)0); } +EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint name) +{ + clearError(); + + const egl_display_ptr dp = validate_display(dpy); + if (!dp) return (const char *) NULL; + + switch (name) { + case EGL_VENDOR: + return dp->disp.queryString.vendor; + case EGL_VERSION: + return dp->disp.queryString.version; + case EGL_EXTENSIONS: + return dp->disp.queryString.extensions; + case EGL_CLIENT_APIS: + return dp->disp.queryString.clientApi; + } + return setError(EGL_BAD_PARAMETER, (const char *)0); +} // ---------------------------------------------------------------------------- // EGL 1.1 @@ -1086,7 +1209,7 @@ EGLBoolean eglReleaseThread(void) egl_tls_t::clearTLS(); #if EGL_TRACE - if (gEGLDebugLevel > 0) + if (getEGLDebugLevel() > 0) GLTrace_eglReleaseThread(); #endif return EGL_TRUE; @@ -1222,6 +1345,21 @@ EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) return result; } +EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) { + clearError(); + + const egl_display_ptr dp = validate_display(dpy); + if (!dp) return EGL_FALSE; + + EGLBoolean result = EGL_FALSE; + egl_connection_t* const cnx = &gEGLImpl; + if (cnx->dso && cnx->egl.eglSignalSyncKHR) { + result = cnx->egl.eglSignalSyncKHR( + dp->disp.dpy, sync, mode); + } + return result; +} + EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) { @@ -1257,6 +1395,22 @@ EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, } // ---------------------------------------------------------------------------- +// EGL_EGLEXT_VERSION 15 +// ---------------------------------------------------------------------------- + +EGLint eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) { + clearError(); + const egl_display_ptr dp = validate_display(dpy); + if (!dp) return EGL_FALSE; + EGLint result = EGL_FALSE; + egl_connection_t* const cnx = &gEGLImpl; + if (cnx->dso && cnx->egl.eglWaitSyncKHR) { + result = cnx->egl.eglWaitSyncKHR(dp->disp.dpy, sync, flags); + } + return result; +} + +// ---------------------------------------------------------------------------- // ANDROID extensions // ---------------------------------------------------------------------------- @@ -1275,19 +1429,26 @@ EGLint eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync) return result; } -EGLint eglWaitSyncANDROID(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags) +EGLBoolean eglPresentationTimeANDROID(EGLDisplay dpy, EGLSurface surface, + EGLnsecsANDROID time) { clearError(); const egl_display_ptr dp = validate_display(dpy); - if (!dp) return EGL_NO_NATIVE_FENCE_FD_ANDROID; + if (!dp) { + return EGL_FALSE; + } - EGLint result = EGL_FALSE; - egl_connection_t* const cnx = &gEGLImpl; - if (cnx->dso && cnx->egl.eglWaitSyncANDROID) { - result = cnx->egl.eglWaitSyncANDROID(dp->disp.dpy, sync, flags); + SurfaceRef _s(dp.get(), surface); + if (!_s.get()) { + setError(EGL_BAD_SURFACE, EGL_FALSE); + return EGL_FALSE; } - return result; + + egl_surface_t const * const s = get_surface(surface); + native_window_set_buffers_timestamp(s->win.get(), time); + + return EGL_TRUE; } // ---------------------------------------------------------------------------- |