diff options
Diffstat (limited to 'opengl/libs/EGL/egl.cpp')
| -rw-r--r-- | opengl/libs/EGL/egl.cpp | 371 | 
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); -} | 
