egl: only return nonzero EGLConfig values
bug: 22821866
Some apps are broken and think that EGLConfig 0 means an error state.
Change-Id: If5e42389d0dc3f459000e11852a20071d157a96c
diff --git a/system/egl/egl.cpp b/system/egl/egl.cpp
index 86c2c8e..17506cd 100644
--- a/system/egl/egl.cpp
+++ b/system/egl/egl.cpp
@@ -122,7 +122,7 @@
#endif //LOG_EGL_ERRORS
#define VALIDATE_CONFIG(cfg,ret) \
- if(((intptr_t)(cfg)<0)||((intptr_t)(cfg)>s_display.getNumConfigs())) { \
+ if (!s_display.isValidConfig(cfg)) { \
RETURN_ERROR(ret,EGL_BAD_CONFIG); \
}
@@ -410,7 +410,7 @@
setNativeHeight(nativeHeight);
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
- rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uintptr_t)config,
+ rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uintptr_t)s_display.getIndexOfConfig(config),
getWidth(), getHeight());
if (!rcSurface) {
@@ -670,7 +670,7 @@
{
DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
- rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uintptr_t)config,
+ rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uintptr_t)s_display.getIndexOfConfig(config),
getWidth(), getHeight());
if (!rcSurface) {
ALOGE("rcCreateWindowSurface returned 0");
@@ -947,7 +947,7 @@
EGLint i;
for (i = 0 ; i < numConfigs && i < config_size ; i++) {
- *configs++ = (EGLConfig)(uintptr_t)i;
+ *configs++ = (EGLConfig)(uintptr_t)s_display.getConfigAtIndex(i);
}
*num_config = i;
return EGL_TRUE;
@@ -1008,7 +1008,8 @@
if (configs!=NULL) {
EGLint i=0;
for (i=0;i<(*num_config);i++) {
- *((uintptr_t*)configs+i) = *((uint32_t*)tempConfigs+i);
+ EGLConfig guestConfig = s_display.getConfigAtIndex(*((uint32_t*)tempConfigs+i));
+ configs[i] = guestConfig;
}
}
@@ -1616,7 +1617,7 @@
if (majorVersion == 3 && minorVersion == 2) {
rcMajorVersion = 4;
}
- uint32_t rcContext = rcEnc->rcCreateContext(rcEnc, (uintptr_t)config, rcShareCtx, rcMajorVersion);
+ uint32_t rcContext = rcEnc->rcCreateContext(rcEnc, (uintptr_t)s_display.getIndexOfConfig(config), rcShareCtx, rcMajorVersion);
if (!rcContext) {
ALOGE("rcCreateContext returned 0");
setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
diff --git a/system/egl/eglDisplay.cpp b/system/egl/eglDisplay.cpp
index 2e18e11..b3f14da 100644
--- a/system/egl/eglDisplay.cpp
+++ b/system/egl/eglDisplay.cpp
@@ -171,7 +171,10 @@
uint32_t nInts = m_numConfigAttribs * (m_numConfigs + 1);
EGLint tmp_buf[nInts];
+ uint32_t configCount = nInts - m_numConfigAttribs;
+
m_configs = new EGLint[nInts-m_numConfigAttribs];
+
if (!m_configs) {
pthread_mutex_unlock(&m_lock);
return false;
@@ -204,7 +207,7 @@
void eglDisplay::processConfigs()
{
for (intptr_t i=0; i<m_numConfigs; i++) {
- EGLConfig config = (EGLConfig)i;
+ EGLConfig config = getConfigAtIndex(i);
PixelFormat format;
if (getConfigNativePixelFormat(config, &format)) {
setConfigAttrib(config, EGL_NATIVE_VISUAL_ID, format);
@@ -443,13 +446,29 @@
ALOGE("[%s] Bad attribute idx\n", __FUNCTION__);
return EGL_FALSE;
}
- *value = *(m_configs + (intptr_t)config*m_numConfigAttribs + attribIdx);
+ *value = *(m_configs + (intptr_t)(getIndexOfConfig(config))*m_numConfigAttribs + attribIdx);
return EGL_TRUE;
}
#define EGL_COLOR_COMPONENT_TYPE_EXT 0x3339
#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT 0x333A
+EGLConfig eglDisplay::getConfigAtIndex(uint32_t index) const {
+ uintptr_t asPtr = (uintptr_t)index;
+ return (EGLConfig)(asPtr + 1);
+}
+
+uint32_t eglDisplay::getIndexOfConfig(EGLConfig config) const {
+ uintptr_t asInteger = (uintptr_t)config;
+ return (uint32_t)(asInteger - 1);
+}
+
+bool eglDisplay::isValidConfig(EGLConfig cfg) const {
+ uint32_t index = getIndexOfConfig(cfg);
+ intptr_t asInt = (intptr_t)index;
+ return !(asInt < 0 || asInt > m_numConfigs);
+}
+
EGLBoolean eglDisplay::getConfigAttrib(EGLConfig config, EGLint attrib, EGLint * value)
{
if (attrib == EGL_FRAMEBUFFER_TARGET_ANDROID) {
@@ -484,10 +503,10 @@
void eglDisplay::dumpConfig(EGLConfig config)
{
EGLint value = 0;
- DBG("^^^^^^^^^^ dumpConfig %d ^^^^^^^^^^^^^^^^^^", (int)config);
+ DBG("^^^^^^^^^^ dumpConfig %p ^^^^^^^^^^^^^^^^^^", config);
for (int i=0; i<m_numConfigAttribs; i++) {
getAttribValue(config, i, &value);
- DBG("{%d}[%d] %d\n", (int)config, i, value);
+ DBG("Config %p: {%u}[%d] %d\n", config, getIndexOfConfig(config), i, value);
}
}
@@ -501,7 +520,7 @@
ALOGE("[%s] Bad attribute idx\n", __FUNCTION__);
return EGL_FALSE;
}
- *(m_configs + (intptr_t)config*m_numConfigAttribs + attribIdx) = value;
+ *(m_configs + (intptr_t)(getIndexOfConfig(config))*m_numConfigAttribs + attribIdx) = value;
return EGL_TRUE;
}
diff --git a/system/egl/eglDisplay.h b/system/egl/eglDisplay.h
index 2394da1..951075d 100644
--- a/system/egl/eglDisplay.h
+++ b/system/egl/eglDisplay.h
@@ -56,6 +56,11 @@
const EGLClient_glesInterface *gles2_iface() const { return m_gles2_iface; }
int getNumConfigs(){ return m_numConfigs; }
+
+ EGLConfig getConfigAtIndex(uint32_t index) const;
+ uint32_t getIndexOfConfig(EGLConfig config) const;
+ bool isValidConfig(EGLConfig cfg) const;
+
EGLBoolean getConfigAttrib(EGLConfig config, EGLint attrib, EGLint * value);
EGLBoolean setConfigAttrib(EGLConfig config, EGLint attrib, EGLint value);
EGLBoolean getConfigGLPixelFormat(EGLConfig config, GLenum * format);