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);