summaryrefslogtreecommitdiff
path: root/opengl/libs/EGL/egl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'opengl/libs/EGL/egl.cpp')
-rw-r--r--opengl/libs/EGL/egl.cpp371
1 files changed, 202 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);
-}