diff options
Diffstat (limited to 'opengl/libs/EGL')
| -rw-r--r-- | opengl/libs/EGL/egl.cpp | 371 | ||||
| -rw-r--r-- | opengl/libs/EGL/getProcAddress.cpp | 122 |
2 files changed, 324 insertions, 169 deletions
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index 89b3e1f2abca..df21358dc784 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -37,12 +37,13 @@ #include <cutils/memory.h> #include <utils/SortedVector.h> +#include <utils/KeyedVector.h> +#include <utils/String8.h> #include "hooks.h" #include "egl_impl.h" #include "Loader.h" -#define MAKE_CONFIG(_impl, _index) ((EGLConfig)(((_impl)<<24) | (_index))) #define setError(_e, _r) setErrorEtc(__FUNCTION__, __LINE__, _e, _r) // ---------------------------------------------------------------------------- @@ -60,7 +61,6 @@ static char const * const gExtensionString = "EGL_KHR_image_pixmap " "EGL_ANDROID_image_native_buffer " "EGL_ANDROID_swap_rectangle " - "EGL_ANDROID_get_render_buffer " ; // ---------------------------------------------------------------------------- @@ -143,6 +143,22 @@ public: SortedVector<egl_object_t*> egl_object_t::sObjects; Mutex egl_object_t::sLock; + +struct egl_config_t { + egl_config_t() {} + egl_config_t(int impl, EGLConfig config) + : impl(impl), config(config), configId(0), implConfigId(0) { } + int impl; // the implementation this config is for + EGLConfig config; // the implementation's EGLConfig + EGLint configId; // our CONFIG_ID + EGLint implConfigId; // the implementation's CONFIG_ID + inline bool operator < (const egl_config_t& rhs) const { + if (impl < rhs.impl) return true; + if (impl > rhs.impl) return false; + return config < rhs.config; + } +}; + struct egl_display_t { enum { NOT_INITIALIZED, INITIALIZED, TERMINATED }; @@ -163,13 +179,14 @@ struct egl_display_t { strings_t queryString; }; - uint32_t magic; - DisplayImpl disp[IMPL_NUM_IMPLEMENTATIONS]; - EGLint numTotalConfigs; - uint32_t refs; - Mutex lock; + uint32_t magic; + DisplayImpl disp[IMPL_NUM_IMPLEMENTATIONS]; + EGLint numTotalConfigs; + egl_config_t* configs; + uint32_t refs; + Mutex lock; - egl_display_t() : magic('_dpy'), numTotalConfigs(0) { } + egl_display_t() : magic('_dpy'), numTotalConfigs(0), configs(0) { } ~egl_display_t() { magic = 0; } inline bool isValid() const { return magic == '_dpy'; } inline bool isAlive() const { return isValid(); } @@ -179,14 +196,15 @@ struct egl_surface_t : public egl_object_t { typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref; - egl_surface_t(EGLDisplay dpy, EGLSurface surface, + egl_surface_t(EGLDisplay dpy, EGLSurface surface, EGLConfig config, int impl, egl_connection_t const* cnx) - : dpy(dpy), surface(surface), impl(impl), cnx(cnx) { + : dpy(dpy), surface(surface), config(config), impl(impl), cnx(cnx) { } ~egl_surface_t() { } EGLDisplay dpy; EGLSurface surface; + EGLConfig config; int impl; egl_connection_t const* cnx; }; @@ -195,7 +213,7 @@ struct egl_context_t : public egl_object_t { typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref; - egl_context_t(EGLDisplay dpy, EGLContext context, + egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config, int impl, egl_connection_t const* cnx, int version) : dpy(dpy), context(context), read(0), draw(0), impl(impl), cnx(cnx), version(version) @@ -203,6 +221,7 @@ struct egl_context_t : public egl_object_t } EGLDisplay dpy; EGLContext context; + EGLConfig config; EGLSurface read; EGLSurface draw; int impl; @@ -220,7 +239,7 @@ struct egl_image_t : public egl_object_t memset(images, 0, sizeof(images)); } EGLDisplay dpy; - EGLConfig context; + EGLContext context; EGLImageKHR images[IMPL_NUM_IMPLEMENTATIONS]; }; @@ -239,7 +258,7 @@ struct tls_t // ---------------------------------------------------------------------------- -egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS]; +static egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS]; static egl_display_t gDisplay[NUM_DISPLAYS]; static pthread_mutex_t gThreadLocalStorageKeyMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_key_t gEGLThreadLocalStorageKey = -1; @@ -354,7 +373,7 @@ int binarySearch( { while (first <= last) { int mid = (first + last) / 2; - if (key > sortedArray[mid]) { + if (sortedArray[mid] < key) { first = mid + 1; } else if (key < sortedArray[mid]) { last = mid - 1; @@ -365,26 +384,11 @@ int binarySearch( return -1; } -static EGLint configToUniqueId(egl_display_t const* dp, int i, int index) -{ - // NOTE: this mapping works only if we have no more than two EGLimpl - return (i>0 ? dp->disp[0].numConfigs : 0) + index; -} - -static void uniqueIdToConfig(egl_display_t const* dp, EGLint configId, - int& i, int& index) -{ - // NOTE: this mapping works only if we have no more than two EGLimpl - size_t numConfigs = dp->disp[0].numConfigs; - i = configId / numConfigs; - index = configId % numConfigs; -} - static int cmp_configs(const void* a, const void *b) { - EGLConfig c0 = *(EGLConfig const *)a; - EGLConfig c1 = *(EGLConfig const *)b; - return c0<c1 ? -1 : (c0>c1 ? 1 : 0); + const egl_config_t& c0 = *(egl_config_t const *)a; + const egl_config_t& c1 = *(egl_config_t const *)b; + return c0<c1 ? -1 : (c1<c0 ? 1 : 0); } struct extention_map_t { @@ -403,11 +407,13 @@ static const extention_map_t gExtentionMap[] = { (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, { "eglSetSwapRectangleANDROID", (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, - { "eglGetRenderBufferANDROID", - (__eglMustCastToProperFunctionPointerType)&eglGetRenderBufferANDROID }, }; -static extention_map_t gGLExtentionMap[MAX_NUMBER_OF_GL_EXTENSIONS]; +extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS]; + +// accesses protected by gInitDriverMutex +static DefaultKeyedVector<String8, __eglMustCastToProperFunctionPointerType> gGLExtentionMap; +static int gGLExtentionSlot = 0; static void(*findProcAddress(const char* name, const extention_map_t* map, size_t n))() @@ -477,20 +483,15 @@ egl_image_t* get_image(EGLImageKHR image) { static egl_connection_t* validate_display_config( EGLDisplay dpy, EGLConfig config, - egl_display_t const*& dp, int& impl, int& index) + egl_display_t const*& dp) { dp = get_display(dpy); if (!dp) return setError(EGL_BAD_DISPLAY, (egl_connection_t*)NULL); - impl = uintptr_t(config)>>24; - if (uint32_t(impl) >= IMPL_NUM_IMPLEMENTATIONS) { - return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL); - } - index = uintptr_t(config) & 0xFFFFFF; - if (index >= dp->disp[impl].numConfigs) { + if (intptr_t(config) >= dp->numTotalConfigs) { return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL); } - egl_connection_t* const cnx = &gEGLImpl[impl]; + egl_connection_t* const cnx = &gEGLImpl[dp->configs[intptr_t(config)].impl]; if (cnx->dso == 0) { return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL); } @@ -718,11 +719,6 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) dp->disp[i].dpy, dp->disp[i].config, n, &dp->disp[i].numConfigs)) { - // sort the configurations so we can do binary searches - qsort( dp->disp[i].config, - dp->disp[i].numConfigs, - sizeof(EGLConfig), cmp_configs); - dp->numTotalConfigs += n; res = EGL_TRUE; } @@ -732,6 +728,30 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) } if (res == EGL_TRUE) { + dp->configs = new egl_config_t[ dp->numTotalConfigs ]; + for (int i=0, k=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { + egl_connection_t* const cnx = &gEGLImpl[i]; + if (cnx->dso && cnx->major>=0 && cnx->minor>=0) { + for (int j=0 ; j<dp->disp[i].numConfigs ; j++) { + dp->configs[k].impl = i; + dp->configs[k].config = dp->disp[i].config[j]; + dp->configs[k].configId = k + 1; // CONFIG_ID start at 1 + // store the implementation's CONFIG_ID + cnx->egl.eglGetConfigAttrib( + dp->disp[i].dpy, + dp->disp[i].config[j], + EGL_CONFIG_ID, + &dp->configs[k].implConfigId); + k++; + } + } + } + + // sort our configurations so we can do binary-searches + qsort( dp->configs, + dp->numTotalConfigs, + sizeof(egl_config_t), cmp_configs); + dp->refs++; if (major != NULL) *major = VERSION_MAJOR; if (minor != NULL) *minor = VERSION_MINOR; @@ -784,6 +804,7 @@ EGLBoolean eglTerminate(EGLDisplay dpy) dp->refs--; dp->numTotalConfigs = 0; + delete [] dp->configs; clearTLS(); return res; } @@ -804,14 +825,13 @@ EGLBoolean eglGetConfigs( EGLDisplay dpy, *num_config = numConfigs; return EGL_TRUE; } + GLint n = 0; - for (int j=0 ; j<IMPL_NUM_IMPLEMENTATIONS ; j++) { - for (int i=0 ; i<dp->disp[j].numConfigs && config_size ; i++) { - *configs++ = MAKE_CONFIG(j, i); - config_size--; - n++; - } - } + for (intptr_t i=0 ; i<dp->numTotalConfigs && config_size ; i++) { + *configs++ = EGLConfig(i); + config_size--; + n++; + } *num_config = n; return EGL_TRUE; @@ -834,7 +854,7 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, // It is unfortunate, but we need to remap the EGL_CONFIG_IDs, - // to do this, we have to go through the attrib_list array once + // to do this, we have to go through the attrib_list array once // to figure out both its size and if it contains an EGL_CONFIG_ID // key. If so, the full array is copied and patched. // NOTE: we assume that there can be only one occurrence @@ -843,10 +863,12 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, EGLint patch_index = -1; GLint attr; size_t size = 0; - while ((attr=attrib_list[size]) != EGL_NONE) { - if (attr == EGL_CONFIG_ID) - patch_index = size; - size += 2; + if (attrib_list) { + while ((attr=attrib_list[size]) != EGL_NONE) { + if (attr == EGL_CONFIG_ID) + patch_index = size; + size += 2; + } } if (patch_index >= 0) { size += 2; // we need copy the sentinel as well @@ -856,16 +878,20 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, memcpy(new_list, attrib_list, size*sizeof(EGLint)); // patch the requested EGL_CONFIG_ID - int i, index; + bool found = false; + EGLConfig ourConfig(0); EGLint& configId(new_list[patch_index+1]); - uniqueIdToConfig(dp, configId, i, index); - - egl_connection_t* const cnx = &gEGLImpl[i]; - if (cnx->dso) { - cnx->egl.eglGetConfigAttrib( - dp->disp[i].dpy, dp->disp[i].config[index], - EGL_CONFIG_ID, &configId); + for (intptr_t i=0 ; i<dp->numTotalConfigs ; i++) { + if (dp->configs[i].configId == configId) { + ourConfig = EGLConfig(i); + configId = dp->configs[i].implConfigId; + found = true; + break; + } + } + egl_connection_t* const cnx = &gEGLImpl[dp->configs[intptr_t(ourConfig)].impl]; + if (found && cnx->dso) { // and switch to the new list attrib_list = const_cast<const EGLint *>(new_list); @@ -878,12 +904,13 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, // which one. res = cnx->egl.eglChooseConfig( - dp->disp[i].dpy, attrib_list, configs, config_size, &n); + dp->disp[ dp->configs[intptr_t(ourConfig)].impl ].dpy, + attrib_list, configs, config_size, &n); if (res && n>0) { // n has to be 0 or 1, by construction, and we already know // which config it will return (since there can be only one). if (configs) { - configs[0] = MAKE_CONFIG(i, index); + configs[0] = ourConfig; } *num_config = 1; } @@ -893,6 +920,7 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, return res; } + for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso) { @@ -900,15 +928,14 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, dp->disp[i].dpy, attrib_list, configs, config_size, &n)) { if (configs) { // now we need to convert these client EGLConfig to our - // internal EGLConfig format. This is done in O(n log n). + // internal EGLConfig format. + // This is done in O(n Log(n)) time. for (int j=0 ; j<n ; j++) { - int index = binarySearch<EGLConfig>( - dp->disp[i].config, 0, - dp->disp[i].numConfigs-1, configs[j]); + egl_config_t key(i, configs[j]); + intptr_t index = binarySearch<egl_config_t>( + dp->configs, 0, dp->numTotalConfigs, key); if (index >= 0) { - if (configs) { - configs[j] = MAKE_CONFIG(i, index); - } + configs[j] = EGLConfig(index); } else { return setError(EGL_BAD_CONFIG, EGL_FALSE); } @@ -928,18 +955,16 @@ EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) { egl_display_t const* dp = 0; - int i=0, index=0; - egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); + egl_connection_t* cnx = validate_display_config(dpy, config, dp); if (!cnx) return EGL_FALSE; if (attribute == EGL_CONFIG_ID) { - // EGL_CONFIG_IDs must be unique, just use the order of the selected - // EGLConfig. - *value = configToUniqueId(dp, i, index); + *value = dp->configs[intptr_t(config)].configId; return EGL_TRUE; } return cnx->egl.eglGetConfigAttrib( - dp->disp[i].dpy, dp->disp[i].config[index], attribute, value); + dp->disp[ dp->configs[intptr_t(config)].impl ].dpy, + dp->configs[intptr_t(config)].config, attribute, value); } // ---------------------------------------------------------------------------- @@ -951,13 +976,14 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { egl_display_t const* dp = 0; - int i=0, index=0; - egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); + egl_connection_t* cnx = validate_display_config(dpy, config, dp); if (cnx) { EGLSurface surface = cnx->egl.eglCreateWindowSurface( - dp->disp[i].dpy, dp->disp[i].config[index], window, attrib_list); + dp->disp[ dp->configs[intptr_t(config)].impl ].dpy, + dp->configs[intptr_t(config)].config, window, attrib_list); if (surface != EGL_NO_SURFACE) { - egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx); + egl_surface_t* s = new egl_surface_t(dpy, surface, config, + dp->configs[intptr_t(config)].impl, cnx); return s; } } @@ -969,13 +995,14 @@ EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { egl_display_t const* dp = 0; - int i=0, index=0; - egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); + egl_connection_t* cnx = validate_display_config(dpy, config, dp); if (cnx) { EGLSurface surface = cnx->egl.eglCreatePixmapSurface( - dp->disp[i].dpy, dp->disp[i].config[index], pixmap, attrib_list); + dp->disp[ dp->configs[intptr_t(config)].impl ].dpy, + dp->configs[intptr_t(config)].config, pixmap, attrib_list); if (surface != EGL_NO_SURFACE) { - egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx); + egl_surface_t* s = new egl_surface_t(dpy, surface, config, + dp->configs[intptr_t(config)].impl, cnx); return s; } } @@ -986,13 +1013,14 @@ EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { egl_display_t const* dp = 0; - int i=0, index=0; - egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); + egl_connection_t* cnx = validate_display_config(dpy, config, dp); if (cnx) { EGLSurface surface = cnx->egl.eglCreatePbufferSurface( - dp->disp[i].dpy, dp->disp[i].config[index], attrib_list); + dp->disp[ dp->configs[intptr_t(config)].impl ].dpy, + dp->configs[intptr_t(config)].config, attrib_list); if (surface != EGL_NO_SURFACE) { - egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx); + egl_surface_t* s = new egl_surface_t(dpy, surface, config, + dp->configs[intptr_t(config)].impl, cnx); return s; } } @@ -1028,23 +1056,35 @@ EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface, egl_display_t const * const dp = get_display(dpy); egl_surface_t const * const s = get_surface(surface); - return s->cnx->egl.eglQuerySurface( - dp->disp[s->impl].dpy, s->surface, attribute, value); + EGLBoolean result(EGL_TRUE); + if (attribute == EGL_CONFIG_ID) { + // We need to remap EGL_CONFIG_IDs + *value = dp->configs[intptr_t(s->config)].configId; + } else { + result = s->cnx->egl.eglQuerySurface( + dp->disp[s->impl].dpy, s->surface, attribute, value); + } + + return result; } // ---------------------------------------------------------------------------- -// contextes +// Contexts // ---------------------------------------------------------------------------- EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) { egl_display_t const* dp = 0; - int i=0, index=0; - egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); + egl_connection_t* cnx = validate_display_config(dpy, config, dp); if (cnx) { + if (share_list != EGL_NO_CONTEXT) { + egl_context_t* const c = get_context(share_list); + share_list = c->context; + } EGLContext context = cnx->egl.eglCreateContext( - dp->disp[i].dpy, dp->disp[i].config[index], + dp->disp[ dp->configs[intptr_t(config)].impl ].dpy, + dp->configs[intptr_t(config)].config, share_list, attrib_list); if (context != EGL_NO_CONTEXT) { // figure out if it's a GLESv1 or GLESv2 @@ -1062,7 +1102,8 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, } }; } - egl_context_t* c = new egl_context_t(dpy, context, i, cnx, version); + egl_context_t* c = new egl_context_t(dpy, context, config, + dp->configs[intptr_t(config)].impl, cnx, version); return c; } } @@ -1207,8 +1248,16 @@ EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx, egl_display_t const * const dp = get_display(dpy); egl_context_t * const c = get_context(ctx); - return c->cnx->egl.eglQueryContext( - dp->disp[c->impl].dpy, c->context, attribute, value); + EGLBoolean result(EGL_TRUE); + if (attribute == EGL_CONFIG_ID) { + *value = dp->configs[intptr_t(c->config)].configId; + } else { + // We need to remap EGL_CONFIG_IDs + result = c->cnx->egl.eglQueryContext( + dp->disp[c->impl].dpy, c->context, attribute, value); + } + + return result; } EGLContext eglGetCurrentContext(void) @@ -1323,55 +1372,55 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) addr = findProcAddress(procname, gExtentionMap, NELEM(gExtentionMap)); if (addr) return addr; - return NULL; // TODO: finish implementation below + // this protects accesses to gGLExtentionMap and gGLExtentionSlot + pthread_mutex_lock(&gInitDriverMutex); - addr = findProcAddress(procname, gGLExtentionMap, NELEM(gGLExtentionMap)); - if (addr) return addr; - - addr = 0; - int slot = -1; - for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { - egl_connection_t* const cnx = &gEGLImpl[i]; - if (cnx->dso) { - if (cnx->egl.eglGetProcAddress) { - addr = cnx->egl.eglGetProcAddress(procname); - if (addr) { - if (slot == -1) { - slot = 0; // XXX: find free slot - if (slot == -1) { - addr = 0; - break; - } - } - //cnx->hooks->ext.extensions[slot] = addr; + /* + * Since eglGetProcAddress() is not associated to anything, it needs + * to return a function pointer that "works" regardless of what + * the current context is. + * + * For this reason, we return a "forwarder", a small stub that takes + * care of calling the function associated with the context + * currently bound. + * + * We first look for extensions we've already resolved, if we're seeing + * this extension for the first time, we go through all our + * implementations and call eglGetProcAddress() and record the + * result in the appropriate implementation hooks and return the + * address of the forwarder corresponding to that hook set. + * + */ + + const String8 name(procname); + addr = gGLExtentionMap.valueFor(name); + const int slot = gGLExtentionSlot; + + LOGE_IF(slot >= MAX_NUMBER_OF_GL_EXTENSIONS, + "no more slots for eglGetProcAddress(\"%s\")", + procname); + + if (!addr && (slot < MAX_NUMBER_OF_GL_EXTENSIONS)) { + bool found = false; + for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { + egl_connection_t* const cnx = &gEGLImpl[i]; + if (cnx->dso && cnx->egl.eglGetProcAddress) { + found = true; + // Extensions are independent of the bound context + cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] = + cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] = + cnx->egl.eglGetProcAddress(procname); } } + if (found) { + addr = gExtensionForwarders[slot]; + gGLExtentionMap.add(name, addr); + gGLExtentionSlot++; + } } - } - - if (slot >= 0) { - addr = 0; // XXX: address of stub 'slot' - gGLExtentionMap[slot].name = strdup(procname); - gGLExtentionMap[slot].address = addr; - } - - return addr; - - /* - * TODO: For OpenGL ES extensions, we must generate a stub - * that looks like - * mov r12, #0xFFFF0FFF - * ldr r12, [r12, #-15] - * ldr r12, [r12, #TLS_SLOT_OPENGL_API*4] - * mov r12, [r12, #api_offset] - * ldrne pc, r12 - * mov pc, #unsupported_extension - * - * and write the address of the extension in *all* - * gl_hooks_t::gl_ext_t at offset "api_offset" from gl_hooks_t - * - */ + pthread_mutex_unlock(&gInitDriverMutex); + return addr; } EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) @@ -1580,13 +1629,13 @@ EGLSurface eglCreatePbufferFromClientBuffer( EGLConfig config, const EGLint *attrib_list) { egl_display_t const* dp = 0; - int i=0, index=0; - egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); + egl_connection_t* cnx = validate_display_config(dpy, config, dp); if (!cnx) return EGL_FALSE; if (cnx->egl.eglCreatePbufferFromClientBuffer) { return cnx->egl.eglCreatePbufferFromClientBuffer( - dp->disp[i].dpy, buftype, buffer, - dp->disp[i].config[index], attrib_list); + dp->disp[ dp->configs[intptr_t(config)].impl ].dpy, + buftype, buffer, + dp->configs[intptr_t(config)].config, attrib_list); } return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE); } @@ -1720,7 +1769,7 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) egl_connection_t* const cnx = &gEGLImpl[i]; if (image->images[i] != EGL_NO_IMAGE_KHR) { if (cnx->dso) { - if (cnx->egl.eglCreateImageKHR) { + if (cnx->egl.eglDestroyImageKHR) { if (cnx->egl.eglDestroyImageKHR( dp->disp[i].dpy, image->images[i])) { success = true; @@ -1758,19 +1807,3 @@ EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, } return setError(EGL_BAD_DISPLAY, NULL); } - -EGLClientBuffer eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw) -{ - SurfaceRef _s(draw); - if (!_s.get()) return setError(EGL_BAD_SURFACE, (EGLClientBuffer*)0); - - if (!validate_display_surface(dpy, draw)) - return 0; - egl_display_t const * const dp = get_display(dpy); - egl_surface_t const * const s = get_surface(draw); - if (s->cnx->egl.eglGetRenderBufferANDROID) { - return s->cnx->egl.eglGetRenderBufferANDROID( - dp->disp[s->impl].dpy, s->surface); - } - return setError(EGL_BAD_DISPLAY, (EGLClientBuffer*)0); -} diff --git a/opengl/libs/EGL/getProcAddress.cpp b/opengl/libs/EGL/getProcAddress.cpp new file mode 100644 index 000000000000..dcf8735c634d --- /dev/null +++ b/opengl/libs/EGL/getProcAddress.cpp @@ -0,0 +1,122 @@ +/* + ** Copyright 2009, 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 + ** + ** 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 + ** limitations under the License. + */ + +#include <ctype.h> +#include <stdlib.h> +#include <errno.h> + +#include <cutils/log.h> + +#include "hooks.h" + +// ---------------------------------------------------------------------------- +namespace android { +// ---------------------------------------------------------------------------- + +#undef API_ENTRY +#undef CALL_GL_EXTENSION_API +#undef GL_EXTENSION +#undef GL_EXTENSION_NAME +#undef GL_EXTENSION_ARRAY +#undef GL_EXTENSION_LIST +#undef GET_TLS + +#if defined(__arm__) + + #ifdef HAVE_ARM_TLS_REGISTER + #define GET_TLS(reg) \ + "mrc p15, 0, " #reg ", c13, c0, 3 \n" + #else + #define GET_TLS(reg) \ + "mov " #reg ", #0xFFFF0FFF \n" \ + "ldr " #reg ", [" #reg ", #-15] \n" + #endif + + #define API_ENTRY(_api) __attribute__((naked)) _api + + #define CALL_GL_EXTENSION_API(_api) \ + asm volatile( \ + GET_TLS(r12) \ + "ldr r12, [r12, %[tls]] \n" \ + "cmp r12, #0 \n" \ + "ldrne r12, [r12, %[api]] \n" \ + "cmpne r12, #0 \n" \ + "bxne r12 \n" \ + "bx lr \n" \ + : \ + : [tls] "J"(TLS_SLOT_OPENGL_API*4), \ + [api] "J"(__builtin_offsetof(gl_hooks_t, \ + ext.extensions[_api])) \ + : \ + ); + + #define GL_EXTENSION_NAME(_n) __glExtFwd##_n + + #define GL_EXTENSION(_n) \ + void API_ENTRY(GL_EXTENSION_NAME(_n))() { \ + CALL_GL_EXTENSION_API(_n); \ + } + + +#else + + #define GL_EXTENSION_NAME(_n) NULL + + #define GL_EXTENSION(_n) + + #warning "eglGetProcAddress() partially supported on this architecture" + +#endif + +#define GL_EXTENSION_LIST(name) \ + name(0) name(1) name(2) name(3) \ + name(4) name(5) name(6) name(7) \ + name(8) name(9) name(10) name(11) \ + name(12) name(13) name(14) name(15) \ + name(16) name(17) name(18) name(19) \ + name(20) name(21) name(22) name(23) \ + name(24) name(25) name(26) name(27) \ + name(28) name(29) name(30) name(31) \ + name(32) name(33) name(34) name(35) \ + name(36) name(37) name(38) name(39) \ + name(40) name(41) name(42) name(43) \ + name(44) name(45) name(46) name(47) \ + name(48) name(49) name(50) name(51) \ + name(52) name(53) name(54) name(55) \ + name(56) name(57) name(58) name(59) \ + name(60) name(61) name(62) name(63) + + +GL_EXTENSION_LIST( GL_EXTENSION ) + +#define GL_EXTENSION_ARRAY(_n) GL_EXTENSION_NAME(_n), + +extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS] = { + GL_EXTENSION_LIST( GL_EXTENSION_ARRAY ) + }; + +#undef GET_TLS +#undef GL_EXTENSION_LIST +#undef GL_EXTENSION_ARRAY +#undef GL_EXTENSION_NAME +#undef GL_EXTENSION +#undef API_ENTRY +#undef CALL_GL_EXTENSION_API + +// ---------------------------------------------------------------------------- +}; // namespace android +// ---------------------------------------------------------------------------- + |
