Loading opengl/libs/EGL/egl.cpp +138 −98 Original line number Original line Diff line number Diff line Loading @@ -42,7 +42,6 @@ #include "egl_impl.h" #include "egl_impl.h" #include "Loader.h" #include "Loader.h" #define MAKE_CONFIG(_impl, _index) ((EGLConfig)(((_impl)<<24) | (_index))) #define setError(_e, _r) setErrorEtc(__FUNCTION__, __LINE__, _e, _r) #define setError(_e, _r) setErrorEtc(__FUNCTION__, __LINE__, _e, _r) // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- Loading Loading @@ -143,6 +142,22 @@ public: SortedVector<egl_object_t*> egl_object_t::sObjects; SortedVector<egl_object_t*> egl_object_t::sObjects; Mutex egl_object_t::sLock; 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 { struct egl_display_t { enum { NOT_INITIALIZED, INITIALIZED, TERMINATED }; enum { NOT_INITIALIZED, INITIALIZED, TERMINATED }; Loading @@ -166,10 +181,11 @@ struct egl_display_t { uint32_t magic; uint32_t magic; DisplayImpl disp[IMPL_NUM_IMPLEMENTATIONS]; DisplayImpl disp[IMPL_NUM_IMPLEMENTATIONS]; EGLint numTotalConfigs; EGLint numTotalConfigs; egl_config_t* configs; uint32_t refs; uint32_t refs; Mutex lock; Mutex lock; egl_display_t() : magic('_dpy'), numTotalConfigs(0) { } egl_display_t() : magic('_dpy'), numTotalConfigs(0), configs(0) { } ~egl_display_t() { magic = 0; } ~egl_display_t() { magic = 0; } inline bool isValid() const { return magic == '_dpy'; } inline bool isValid() const { return magic == '_dpy'; } inline bool isAlive() const { return isValid(); } inline bool isAlive() const { return isValid(); } Loading @@ -179,14 +195,15 @@ struct egl_surface_t : public egl_object_t { { typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref; 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) 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() { ~egl_surface_t() { } } EGLDisplay dpy; EGLDisplay dpy; EGLSurface surface; EGLSurface surface; EGLConfig config; int impl; int impl; egl_connection_t const* cnx; egl_connection_t const* cnx; }; }; Loading @@ -195,7 +212,7 @@ struct egl_context_t : public egl_object_t { { typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref; 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) int impl, egl_connection_t const* cnx, int version) : dpy(dpy), context(context), read(0), draw(0), impl(impl), cnx(cnx), : dpy(dpy), context(context), read(0), draw(0), impl(impl), cnx(cnx), version(version) version(version) Loading @@ -203,6 +220,7 @@ struct egl_context_t : public egl_object_t } } EGLDisplay dpy; EGLDisplay dpy; EGLContext context; EGLContext context; EGLConfig config; EGLSurface read; EGLSurface read; EGLSurface draw; EGLSurface draw; int impl; int impl; Loading Loading @@ -354,7 +372,7 @@ int binarySearch( { { while (first <= last) { while (first <= last) { int mid = (first + last) / 2; int mid = (first + last) / 2; if (key > sortedArray[mid]) { if (sortedArray[mid] < key) { first = mid + 1; first = mid + 1; } else if (key < sortedArray[mid]) { } else if (key < sortedArray[mid]) { last = mid - 1; last = mid - 1; Loading @@ -365,26 +383,11 @@ int binarySearch( return -1; 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) static int cmp_configs(const void* a, const void *b) { { EGLConfig c0 = *(EGLConfig const *)a; const egl_config_t& c0 = *(egl_config_t const *)a; EGLConfig c1 = *(EGLConfig const *)b; const egl_config_t& c1 = *(egl_config_t const *)b; return c0<c1 ? -1 : (c0>c1 ? 1 : 0); return c0<c1 ? -1 : (c1<c0 ? 1 : 0); } } struct extention_map_t { struct extention_map_t { Loading Loading @@ -477,20 +480,15 @@ egl_image_t* get_image(EGLImageKHR image) { static egl_connection_t* validate_display_config( static egl_connection_t* validate_display_config( EGLDisplay dpy, EGLConfig config, EGLDisplay dpy, EGLConfig config, egl_display_t const*& dp, int& impl, int& index) egl_display_t const*& dp) { { dp = get_display(dpy); dp = get_display(dpy); if (!dp) return setError(EGL_BAD_DISPLAY, (egl_connection_t*)NULL); if (!dp) return setError(EGL_BAD_DISPLAY, (egl_connection_t*)NULL); impl = uintptr_t(config)>>24; if (intptr_t(config) >= dp->numTotalConfigs) { 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) { return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL); 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) { if (cnx->dso == 0) { return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL); return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL); } } Loading Loading @@ -718,11 +716,6 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) dp->disp[i].dpy, dp->disp[i].config, n, dp->disp[i].dpy, dp->disp[i].config, n, &dp->disp[i].numConfigs)) &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; dp->numTotalConfigs += n; res = EGL_TRUE; res = EGL_TRUE; } } Loading @@ -732,6 +725,30 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) } } if (res == EGL_TRUE) { 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++; dp->refs++; if (major != NULL) *major = VERSION_MAJOR; if (major != NULL) *major = VERSION_MAJOR; if (minor != NULL) *minor = VERSION_MINOR; if (minor != NULL) *minor = VERSION_MINOR; Loading Loading @@ -784,6 +801,7 @@ EGLBoolean eglTerminate(EGLDisplay dpy) dp->refs--; dp->refs--; dp->numTotalConfigs = 0; dp->numTotalConfigs = 0; delete [] dp->configs; clearTLS(); clearTLS(); return res; return res; } } Loading @@ -804,14 +822,13 @@ EGLBoolean eglGetConfigs( EGLDisplay dpy, *num_config = numConfigs; *num_config = numConfigs; return EGL_TRUE; return EGL_TRUE; } } GLint n = 0; GLint n = 0; for (int j=0 ; j<IMPL_NUM_IMPLEMENTATIONS ; j++) { for (intptr_t i=0 ; i<dp->numTotalConfigs && config_size ; i++) { for (int i=0 ; i<dp->disp[j].numConfigs && config_size ; i++) { *configs++ = EGLConfig(i); *configs++ = MAKE_CONFIG(j, i); config_size--; config_size--; n++; n++; } } } *num_config = n; *num_config = n; return EGL_TRUE; return EGL_TRUE; Loading Loading @@ -858,16 +875,20 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, memcpy(new_list, attrib_list, size*sizeof(EGLint)); memcpy(new_list, attrib_list, size*sizeof(EGLint)); // patch the requested EGL_CONFIG_ID // patch the requested EGL_CONFIG_ID int i, index; bool found = false; EGLConfig ourConfig(0); EGLint& configId(new_list[patch_index+1]); EGLint& configId(new_list[patch_index+1]); uniqueIdToConfig(dp, configId, i, index); for (intptr_t i=0 ; i<dp->numTotalConfigs ; i++) { if (dp->configs[i].configId == configId) { egl_connection_t* const cnx = &gEGLImpl[i]; ourConfig = EGLConfig(i); if (cnx->dso) { configId = dp->configs[i].implConfigId; cnx->egl.eglGetConfigAttrib( found = true; dp->disp[i].dpy, dp->disp[i].config[index], break; EGL_CONFIG_ID, &configId); } } egl_connection_t* const cnx = &gEGLImpl[dp->configs[intptr_t(ourConfig)].impl]; if (found && cnx->dso) { // and switch to the new list // and switch to the new list attrib_list = const_cast<const EGLint *>(new_list); attrib_list = const_cast<const EGLint *>(new_list); Loading @@ -880,12 +901,13 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, // which one. // which one. res = cnx->egl.eglChooseConfig( 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) { if (res && n>0) { // n has to be 0 or 1, by construction, and we already know // n has to be 0 or 1, by construction, and we already know // which config it will return (since there can be only one). // which config it will return (since there can be only one). if (configs) { if (configs) { configs[0] = MAKE_CONFIG(i, index); configs[0] = ourConfig; } } *num_config = 1; *num_config = 1; } } Loading @@ -895,6 +917,7 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, return res; return res; } } for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso) { if (cnx->dso) { Loading @@ -902,15 +925,14 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, dp->disp[i].dpy, attrib_list, configs, config_size, &n)) { dp->disp[i].dpy, attrib_list, configs, config_size, &n)) { if (configs) { if (configs) { // now we need to convert these client EGLConfig to our // 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++) { for (int j=0 ; j<n ; j++) { int index = binarySearch<EGLConfig>( egl_config_t key(i, configs[j]); dp->disp[i].config, 0, intptr_t index = binarySearch<egl_config_t>( dp->disp[i].numConfigs-1, configs[j]); dp->configs, 0, dp->numTotalConfigs, key); if (index >= 0) { if (index >= 0) { if (configs) { configs[j] = EGLConfig(index); configs[j] = MAKE_CONFIG(i, index); } } else { } else { return setError(EGL_BAD_CONFIG, EGL_FALSE); return setError(EGL_BAD_CONFIG, EGL_FALSE); } } Loading @@ -930,18 +952,16 @@ EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) EGLint attribute, EGLint *value) { { egl_display_t const* dp = 0; egl_display_t const* dp = 0; int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (!cnx) return EGL_FALSE; if (!cnx) return EGL_FALSE; if (attribute == EGL_CONFIG_ID) { if (attribute == EGL_CONFIG_ID) { // EGL_CONFIG_IDs must be unique, just use the order of the selected *value = dp->configs[intptr_t(config)].configId; // EGLConfig. *value = configToUniqueId(dp, i, index); return EGL_TRUE; return EGL_TRUE; } } return cnx->egl.eglGetConfigAttrib( 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); } } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- Loading @@ -953,13 +973,14 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) const EGLint *attrib_list) { { egl_display_t const* dp = 0; egl_display_t const* dp = 0; int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (cnx) { if (cnx) { EGLSurface surface = cnx->egl.eglCreateWindowSurface( 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) { 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; return s; } } } } Loading @@ -971,13 +992,14 @@ EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) const EGLint *attrib_list) { { egl_display_t const* dp = 0; egl_display_t const* dp = 0; int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (cnx) { if (cnx) { EGLSurface surface = cnx->egl.eglCreatePixmapSurface( 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) { 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; return s; } } } } Loading @@ -988,13 +1010,14 @@ EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) const EGLint *attrib_list) { { egl_display_t const* dp = 0; egl_display_t const* dp = 0; int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (cnx) { if (cnx) { EGLSurface surface = cnx->egl.eglCreatePbufferSurface( 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) { 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; return s; } } } } Loading Loading @@ -1030,27 +1053,35 @@ EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface, egl_display_t const * const dp = get_display(dpy); egl_display_t const * const dp = get_display(dpy); egl_surface_t const * const s = get_surface(surface); egl_surface_t const * const s = get_surface(surface); return s->cnx->egl.eglQuerySurface( 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); dp->disp[s->impl].dpy, s->surface, attribute, value); } } return result; } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // contextes // Contexts // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) EGLContext share_list, const EGLint *attrib_list) { { egl_display_t const* dp = 0; egl_display_t const* dp = 0; int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (cnx) { if (cnx) { if (share_list != EGL_NO_CONTEXT) { if (share_list != EGL_NO_CONTEXT) { egl_context_t* const c = get_context(share_list); egl_context_t* const c = get_context(share_list); share_list = c->context; share_list = c->context; } } EGLContext context = cnx->egl.eglCreateContext( 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); share_list, attrib_list); if (context != EGL_NO_CONTEXT) { if (context != EGL_NO_CONTEXT) { // figure out if it's a GLESv1 or GLESv2 // figure out if it's a GLESv1 or GLESv2 Loading @@ -1068,7 +1099,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; return c; } } } } Loading Loading @@ -1213,10 +1245,18 @@ EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx, egl_display_t const * const dp = get_display(dpy); egl_display_t const * const dp = get_display(dpy); egl_context_t * const c = get_context(ctx); egl_context_t * const c = get_context(ctx); return c->cnx->egl.eglQueryContext( 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); dp->disp[c->impl].dpy, c->context, attribute, value); } } return result; } EGLContext eglGetCurrentContext(void) EGLContext eglGetCurrentContext(void) { { // could be called before eglInitialize(), but we wouldn't have a context // could be called before eglInitialize(), but we wouldn't have a context Loading Loading @@ -1586,13 +1626,13 @@ EGLSurface eglCreatePbufferFromClientBuffer( EGLConfig config, const EGLint *attrib_list) EGLConfig config, const EGLint *attrib_list) { { egl_display_t const* dp = 0; egl_display_t const* dp = 0; int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (!cnx) return EGL_FALSE; if (!cnx) return EGL_FALSE; if (cnx->egl.eglCreatePbufferFromClientBuffer) { if (cnx->egl.eglCreatePbufferFromClientBuffer) { return cnx->egl.eglCreatePbufferFromClientBuffer( return cnx->egl.eglCreatePbufferFromClientBuffer( dp->disp[i].dpy, buftype, buffer, dp->disp[ dp->configs[intptr_t(config)].impl ].dpy, dp->disp[i].config[index], attrib_list); buftype, buffer, dp->configs[intptr_t(config)].config, attrib_list); } } return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE); return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE); } } Loading Loading
opengl/libs/EGL/egl.cpp +138 −98 Original line number Original line Diff line number Diff line Loading @@ -42,7 +42,6 @@ #include "egl_impl.h" #include "egl_impl.h" #include "Loader.h" #include "Loader.h" #define MAKE_CONFIG(_impl, _index) ((EGLConfig)(((_impl)<<24) | (_index))) #define setError(_e, _r) setErrorEtc(__FUNCTION__, __LINE__, _e, _r) #define setError(_e, _r) setErrorEtc(__FUNCTION__, __LINE__, _e, _r) // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- Loading Loading @@ -143,6 +142,22 @@ public: SortedVector<egl_object_t*> egl_object_t::sObjects; SortedVector<egl_object_t*> egl_object_t::sObjects; Mutex egl_object_t::sLock; 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 { struct egl_display_t { enum { NOT_INITIALIZED, INITIALIZED, TERMINATED }; enum { NOT_INITIALIZED, INITIALIZED, TERMINATED }; Loading @@ -166,10 +181,11 @@ struct egl_display_t { uint32_t magic; uint32_t magic; DisplayImpl disp[IMPL_NUM_IMPLEMENTATIONS]; DisplayImpl disp[IMPL_NUM_IMPLEMENTATIONS]; EGLint numTotalConfigs; EGLint numTotalConfigs; egl_config_t* configs; uint32_t refs; uint32_t refs; Mutex lock; Mutex lock; egl_display_t() : magic('_dpy'), numTotalConfigs(0) { } egl_display_t() : magic('_dpy'), numTotalConfigs(0), configs(0) { } ~egl_display_t() { magic = 0; } ~egl_display_t() { magic = 0; } inline bool isValid() const { return magic == '_dpy'; } inline bool isValid() const { return magic == '_dpy'; } inline bool isAlive() const { return isValid(); } inline bool isAlive() const { return isValid(); } Loading @@ -179,14 +195,15 @@ struct egl_surface_t : public egl_object_t { { typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref; 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) 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() { ~egl_surface_t() { } } EGLDisplay dpy; EGLDisplay dpy; EGLSurface surface; EGLSurface surface; EGLConfig config; int impl; int impl; egl_connection_t const* cnx; egl_connection_t const* cnx; }; }; Loading @@ -195,7 +212,7 @@ struct egl_context_t : public egl_object_t { { typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref; 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) int impl, egl_connection_t const* cnx, int version) : dpy(dpy), context(context), read(0), draw(0), impl(impl), cnx(cnx), : dpy(dpy), context(context), read(0), draw(0), impl(impl), cnx(cnx), version(version) version(version) Loading @@ -203,6 +220,7 @@ struct egl_context_t : public egl_object_t } } EGLDisplay dpy; EGLDisplay dpy; EGLContext context; EGLContext context; EGLConfig config; EGLSurface read; EGLSurface read; EGLSurface draw; EGLSurface draw; int impl; int impl; Loading Loading @@ -354,7 +372,7 @@ int binarySearch( { { while (first <= last) { while (first <= last) { int mid = (first + last) / 2; int mid = (first + last) / 2; if (key > sortedArray[mid]) { if (sortedArray[mid] < key) { first = mid + 1; first = mid + 1; } else if (key < sortedArray[mid]) { } else if (key < sortedArray[mid]) { last = mid - 1; last = mid - 1; Loading @@ -365,26 +383,11 @@ int binarySearch( return -1; 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) static int cmp_configs(const void* a, const void *b) { { EGLConfig c0 = *(EGLConfig const *)a; const egl_config_t& c0 = *(egl_config_t const *)a; EGLConfig c1 = *(EGLConfig const *)b; const egl_config_t& c1 = *(egl_config_t const *)b; return c0<c1 ? -1 : (c0>c1 ? 1 : 0); return c0<c1 ? -1 : (c1<c0 ? 1 : 0); } } struct extention_map_t { struct extention_map_t { Loading Loading @@ -477,20 +480,15 @@ egl_image_t* get_image(EGLImageKHR image) { static egl_connection_t* validate_display_config( static egl_connection_t* validate_display_config( EGLDisplay dpy, EGLConfig config, EGLDisplay dpy, EGLConfig config, egl_display_t const*& dp, int& impl, int& index) egl_display_t const*& dp) { { dp = get_display(dpy); dp = get_display(dpy); if (!dp) return setError(EGL_BAD_DISPLAY, (egl_connection_t*)NULL); if (!dp) return setError(EGL_BAD_DISPLAY, (egl_connection_t*)NULL); impl = uintptr_t(config)>>24; if (intptr_t(config) >= dp->numTotalConfigs) { 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) { return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL); 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) { if (cnx->dso == 0) { return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL); return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL); } } Loading Loading @@ -718,11 +716,6 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) dp->disp[i].dpy, dp->disp[i].config, n, dp->disp[i].dpy, dp->disp[i].config, n, &dp->disp[i].numConfigs)) &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; dp->numTotalConfigs += n; res = EGL_TRUE; res = EGL_TRUE; } } Loading @@ -732,6 +725,30 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) } } if (res == EGL_TRUE) { 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++; dp->refs++; if (major != NULL) *major = VERSION_MAJOR; if (major != NULL) *major = VERSION_MAJOR; if (minor != NULL) *minor = VERSION_MINOR; if (minor != NULL) *minor = VERSION_MINOR; Loading Loading @@ -784,6 +801,7 @@ EGLBoolean eglTerminate(EGLDisplay dpy) dp->refs--; dp->refs--; dp->numTotalConfigs = 0; dp->numTotalConfigs = 0; delete [] dp->configs; clearTLS(); clearTLS(); return res; return res; } } Loading @@ -804,14 +822,13 @@ EGLBoolean eglGetConfigs( EGLDisplay dpy, *num_config = numConfigs; *num_config = numConfigs; return EGL_TRUE; return EGL_TRUE; } } GLint n = 0; GLint n = 0; for (int j=0 ; j<IMPL_NUM_IMPLEMENTATIONS ; j++) { for (intptr_t i=0 ; i<dp->numTotalConfigs && config_size ; i++) { for (int i=0 ; i<dp->disp[j].numConfigs && config_size ; i++) { *configs++ = EGLConfig(i); *configs++ = MAKE_CONFIG(j, i); config_size--; config_size--; n++; n++; } } } *num_config = n; *num_config = n; return EGL_TRUE; return EGL_TRUE; Loading Loading @@ -858,16 +875,20 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, memcpy(new_list, attrib_list, size*sizeof(EGLint)); memcpy(new_list, attrib_list, size*sizeof(EGLint)); // patch the requested EGL_CONFIG_ID // patch the requested EGL_CONFIG_ID int i, index; bool found = false; EGLConfig ourConfig(0); EGLint& configId(new_list[patch_index+1]); EGLint& configId(new_list[patch_index+1]); uniqueIdToConfig(dp, configId, i, index); for (intptr_t i=0 ; i<dp->numTotalConfigs ; i++) { if (dp->configs[i].configId == configId) { egl_connection_t* const cnx = &gEGLImpl[i]; ourConfig = EGLConfig(i); if (cnx->dso) { configId = dp->configs[i].implConfigId; cnx->egl.eglGetConfigAttrib( found = true; dp->disp[i].dpy, dp->disp[i].config[index], break; EGL_CONFIG_ID, &configId); } } egl_connection_t* const cnx = &gEGLImpl[dp->configs[intptr_t(ourConfig)].impl]; if (found && cnx->dso) { // and switch to the new list // and switch to the new list attrib_list = const_cast<const EGLint *>(new_list); attrib_list = const_cast<const EGLint *>(new_list); Loading @@ -880,12 +901,13 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, // which one. // which one. res = cnx->egl.eglChooseConfig( 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) { if (res && n>0) { // n has to be 0 or 1, by construction, and we already know // n has to be 0 or 1, by construction, and we already know // which config it will return (since there can be only one). // which config it will return (since there can be only one). if (configs) { if (configs) { configs[0] = MAKE_CONFIG(i, index); configs[0] = ourConfig; } } *num_config = 1; *num_config = 1; } } Loading @@ -895,6 +917,7 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, return res; return res; } } for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso) { if (cnx->dso) { Loading @@ -902,15 +925,14 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, dp->disp[i].dpy, attrib_list, configs, config_size, &n)) { dp->disp[i].dpy, attrib_list, configs, config_size, &n)) { if (configs) { if (configs) { // now we need to convert these client EGLConfig to our // 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++) { for (int j=0 ; j<n ; j++) { int index = binarySearch<EGLConfig>( egl_config_t key(i, configs[j]); dp->disp[i].config, 0, intptr_t index = binarySearch<egl_config_t>( dp->disp[i].numConfigs-1, configs[j]); dp->configs, 0, dp->numTotalConfigs, key); if (index >= 0) { if (index >= 0) { if (configs) { configs[j] = EGLConfig(index); configs[j] = MAKE_CONFIG(i, index); } } else { } else { return setError(EGL_BAD_CONFIG, EGL_FALSE); return setError(EGL_BAD_CONFIG, EGL_FALSE); } } Loading @@ -930,18 +952,16 @@ EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) EGLint attribute, EGLint *value) { { egl_display_t const* dp = 0; egl_display_t const* dp = 0; int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (!cnx) return EGL_FALSE; if (!cnx) return EGL_FALSE; if (attribute == EGL_CONFIG_ID) { if (attribute == EGL_CONFIG_ID) { // EGL_CONFIG_IDs must be unique, just use the order of the selected *value = dp->configs[intptr_t(config)].configId; // EGLConfig. *value = configToUniqueId(dp, i, index); return EGL_TRUE; return EGL_TRUE; } } return cnx->egl.eglGetConfigAttrib( 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); } } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- Loading @@ -953,13 +973,14 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) const EGLint *attrib_list) { { egl_display_t const* dp = 0; egl_display_t const* dp = 0; int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (cnx) { if (cnx) { EGLSurface surface = cnx->egl.eglCreateWindowSurface( 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) { 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; return s; } } } } Loading @@ -971,13 +992,14 @@ EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) const EGLint *attrib_list) { { egl_display_t const* dp = 0; egl_display_t const* dp = 0; int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (cnx) { if (cnx) { EGLSurface surface = cnx->egl.eglCreatePixmapSurface( 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) { 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; return s; } } } } Loading @@ -988,13 +1010,14 @@ EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) const EGLint *attrib_list) { { egl_display_t const* dp = 0; egl_display_t const* dp = 0; int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (cnx) { if (cnx) { EGLSurface surface = cnx->egl.eglCreatePbufferSurface( 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) { 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; return s; } } } } Loading Loading @@ -1030,27 +1053,35 @@ EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface, egl_display_t const * const dp = get_display(dpy); egl_display_t const * const dp = get_display(dpy); egl_surface_t const * const s = get_surface(surface); egl_surface_t const * const s = get_surface(surface); return s->cnx->egl.eglQuerySurface( 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); dp->disp[s->impl].dpy, s->surface, attribute, value); } } return result; } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // contextes // Contexts // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) EGLContext share_list, const EGLint *attrib_list) { { egl_display_t const* dp = 0; egl_display_t const* dp = 0; int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (cnx) { if (cnx) { if (share_list != EGL_NO_CONTEXT) { if (share_list != EGL_NO_CONTEXT) { egl_context_t* const c = get_context(share_list); egl_context_t* const c = get_context(share_list); share_list = c->context; share_list = c->context; } } EGLContext context = cnx->egl.eglCreateContext( 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); share_list, attrib_list); if (context != EGL_NO_CONTEXT) { if (context != EGL_NO_CONTEXT) { // figure out if it's a GLESv1 or GLESv2 // figure out if it's a GLESv1 or GLESv2 Loading @@ -1068,7 +1099,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; return c; } } } } Loading Loading @@ -1213,10 +1245,18 @@ EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx, egl_display_t const * const dp = get_display(dpy); egl_display_t const * const dp = get_display(dpy); egl_context_t * const c = get_context(ctx); egl_context_t * const c = get_context(ctx); return c->cnx->egl.eglQueryContext( 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); dp->disp[c->impl].dpy, c->context, attribute, value); } } return result; } EGLContext eglGetCurrentContext(void) EGLContext eglGetCurrentContext(void) { { // could be called before eglInitialize(), but we wouldn't have a context // could be called before eglInitialize(), but we wouldn't have a context Loading Loading @@ -1586,13 +1626,13 @@ EGLSurface eglCreatePbufferFromClientBuffer( EGLConfig config, const EGLint *attrib_list) EGLConfig config, const EGLint *attrib_list) { { egl_display_t const* dp = 0; egl_display_t const* dp = 0; int i=0, index=0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index); if (!cnx) return EGL_FALSE; if (!cnx) return EGL_FALSE; if (cnx->egl.eglCreatePbufferFromClientBuffer) { if (cnx->egl.eglCreatePbufferFromClientBuffer) { return cnx->egl.eglCreatePbufferFromClientBuffer( return cnx->egl.eglCreatePbufferFromClientBuffer( dp->disp[i].dpy, buftype, buffer, dp->disp[ dp->configs[intptr_t(config)].impl ].dpy, dp->disp[i].config[index], attrib_list); buftype, buffer, dp->configs[intptr_t(config)].config, attrib_list); } } return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE); return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE); } } Loading