Move attrib-list handling into Display

Move the handling of attrib-lists in eglCreatePbufferSurface and eglCreateWindowList into methods in Display, so we can keep libEGL.cpp as a thin layer.

BUG=
TEST=

Review URL: http://codereview.appspot.com/4453051

git-svn-id: https://angleproject.googlecode.com/svn/trunk@628 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/common/version.h b/src/common/version.h
index 5bc17b5..6aa65d0 100644
--- a/src/common/version.h
+++ b/src/common/version.h
@@ -1,7 +1,7 @@
 #define MAJOR_VERSION 0
 #define MINOR_VERSION 0
 #define BUILD_VERSION 0
-#define BUILD_REVISION 626
+#define BUILD_REVISION 628
 
 #define STRINGIFY(x) #x
 #define MACRO_STRINGIFY(x) STRINGIFY(x)
diff --git a/src/libEGL/Display.cpp b/src/libEGL/Display.cpp
index 1ee449d..02d2e30 100644
--- a/src/libEGL/Display.cpp
+++ b/src/libEGL/Display.cpp
@@ -14,6 +14,7 @@
 #include <vector>
 
 #include "common/debug.h"
+#include "libGLESv2/mathutil.h"
 
 #include "libEGL/main.h"
 
@@ -411,24 +412,148 @@
     return true;
 }
 
-Surface *Display::createWindowSurface(HWND window, EGLConfig config)
+EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList)
 {
     const Config *configuration = mConfigSet.get(config);
 
+    if (attribList)
+    {
+        while (*attribList != EGL_NONE)
+        {
+            switch (attribList[0])
+            {
+              case EGL_RENDER_BUFFER:
+                switch (attribList[1])
+                {
+                  case EGL_BACK_BUFFER:
+                    break;
+                  case EGL_SINGLE_BUFFER:
+                    return error(EGL_BAD_MATCH, EGL_NO_SURFACE);   // Rendering directly to front buffer not supported
+                  default:
+                    return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+                }
+                break;
+              case EGL_VG_COLORSPACE:
+                return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+              case EGL_VG_ALPHA_FORMAT:
+                return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+              default:
+                return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+            }
+
+            attribList += 2;
+        }
+    }
+
+    if (hasExistingWindowSurface(window))
+    {
+        return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+    }
+
     Surface *surface = new Surface(this, configuration, window);
     mSurfaceSet.insert(surface);
 
-    return surface;
+    return success(surface);
 }
 
-Surface *Display::createOffscreenSurface(int width, int height, EGLConfig config, EGLenum textureFormat, EGLenum textureTarget)
+EGLSurface Display::createOffscreenSurface(EGLConfig config, const EGLint *attribList)
 {
+    EGLint width = 0, height = 0;
+    EGLenum textureFormat = EGL_NO_TEXTURE;
+    EGLenum textureTarget = EGL_NO_TEXTURE;
     const Config *configuration = mConfigSet.get(config);
 
+    if (attribList)
+    {
+        while (*attribList != EGL_NONE)
+        {
+            switch (attribList[0])
+            {
+              case EGL_WIDTH:
+                width = attribList[1];
+                break;
+              case EGL_HEIGHT:
+                height = attribList[1];
+                break;
+              case EGL_LARGEST_PBUFFER:
+                if (attribList[1] != EGL_FALSE)
+                  UNIMPLEMENTED(); // FIXME
+                break;
+              case EGL_TEXTURE_FORMAT:
+                switch (attribList[1])
+                {
+                  case EGL_NO_TEXTURE:
+                  case EGL_TEXTURE_RGB:
+                  case EGL_TEXTURE_RGBA:
+                    textureFormat = attribList[1];
+                    break;
+                  default:
+                    return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+                }
+                break;
+              case EGL_TEXTURE_TARGET:
+                switch (attribList[1])
+                {
+                  case EGL_NO_TEXTURE:
+                  case EGL_TEXTURE_2D:
+                    textureTarget = attribList[1];
+                    break;
+                  default:
+                    return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+                }
+                break;
+              case EGL_MIPMAP_TEXTURE:
+                if (attribList[1] != EGL_FALSE)
+                  return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+                break;
+              case EGL_VG_COLORSPACE:
+                return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+              case EGL_VG_ALPHA_FORMAT:
+                return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+              default:
+                return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+            }
+
+            attribList += 2;
+        }
+    }
+
+    if (width < 0 || height < 0)
+    {
+        return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+    }
+
+    if (width == 0 || height == 0)
+    {
+        return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+    }
+
+    if (textureFormat != EGL_NO_TEXTURE && !getNonPow2TextureSupport() && (!gl::isPow2(width) || !gl::isPow2(height)))
+    {
+        return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
+        (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
+    {
+        return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    if (!(configuration->mSurfaceType & EGL_PBUFFER_BIT))
+    {
+        return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    if ((textureFormat == EGL_TEXTURE_RGB && configuration->mBindToTextureRGB != EGL_TRUE) ||
+        (textureFormat == EGL_TEXTURE_RGBA && configuration->mBindToTextureRGBA != EGL_TRUE))
+    {
+        return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
+    }
+
     Surface *surface = new Surface(this, configuration, width, height, textureFormat, textureTarget);
     mSurfaceSet.insert(surface);
 
-    return surface;
+    return success(surface);
 }
 
 EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext)
diff --git a/src/libEGL/Display.h b/src/libEGL/Display.h
index 2a8f55e..5265db6 100644
--- a/src/libEGL/Display.h
+++ b/src/libEGL/Display.h
@@ -42,8 +42,8 @@
     bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
     bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
 
-    egl::Surface *createWindowSurface(HWND window, EGLConfig config);
-    egl::Surface *createOffscreenSurface(int width, int height, EGLConfig config, EGLenum textureFormat, EGLenum textureTarget);
+    EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList);
+    EGLSurface createOffscreenSurface(EGLConfig config, const EGLint *attribList);
     EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext);
 
     void destroySurface(egl::Surface *surface);
diff --git a/src/libEGL/libEGL.cpp b/src/libEGL/libEGL.cpp
index 227e746..607db3d 100644
--- a/src/libEGL/libEGL.cpp
+++ b/src/libEGL/libEGL.cpp
@@ -11,7 +11,6 @@
 #include "common/debug.h"
 #include "common/version.h"
 #include "libGLESv2/Context.h"
-#include "libGLESv2/mathutil.h"
 #include "libGLESv2/Texture.h"
 
 #include "libEGL/main.h"
@@ -339,43 +338,7 @@
             return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
         }
 
-        if (attrib_list)
-        {
-            while (*attrib_list != EGL_NONE)
-            {
-                switch (attrib_list[0])
-                {
-                  case EGL_RENDER_BUFFER:
-                    switch (attrib_list[1])
-                    {
-                      case EGL_BACK_BUFFER:
-                        break;
-                      case EGL_SINGLE_BUFFER:
-                        return error(EGL_BAD_MATCH, EGL_NO_SURFACE);   // Rendering directly to front buffer not supported
-                      default:
-                        return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-                    }
-                    break;
-                  case EGL_VG_COLORSPACE:
-                    return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-                  case EGL_VG_ALPHA_FORMAT:
-                    return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-                  default:
-                    return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-                }
-
-                attrib_list += 2;
-            }
-        }
-
-        if (display->hasExistingWindowSurface(window))
-        {
-            return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
-        }
-
-        EGLSurface surface = (EGLSurface)display->createWindowSurface(window, config);
-
-        return success(surface);
+        return display->createWindowSurface(window, config, attrib_list);
     }
     catch(std::bad_alloc&)
     {
@@ -393,113 +356,13 @@
     try
     {
         egl::Display *display = static_cast<egl::Display*>(dpy);
-        EGLint width = 0, height = 0;
-        EGLenum textureFormat = EGL_NO_TEXTURE;
-        EGLenum textureTarget = EGL_NO_TEXTURE;
 
         if (!validate(display, config))
         {
             return EGL_NO_SURFACE;
         }
 
-        if (attrib_list)
-        {
-            while (*attrib_list != EGL_NONE)
-            {
-                switch (attrib_list[0])
-                {
-                  case EGL_WIDTH:
-                    width = attrib_list[1];
-                    break;
-                  case EGL_HEIGHT:
-                    height = attrib_list[1];
-                    break;
-                  case EGL_LARGEST_PBUFFER:
-                    if (attrib_list[1] != EGL_FALSE)
-                      UNIMPLEMENTED(); // FIXME
-                    break;
-                  case EGL_TEXTURE_FORMAT:
-                    switch (attrib_list[1])
-                    {
-                      case EGL_NO_TEXTURE:
-                      case EGL_TEXTURE_RGB:
-                      case EGL_TEXTURE_RGBA:
-                        textureFormat = attrib_list[1];
-                        break;
-                      default:
-                        return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-                    }
-                    break;
-                  case EGL_TEXTURE_TARGET:
-                    switch (attrib_list[1])
-                    {
-                      case EGL_NO_TEXTURE:
-                      case EGL_TEXTURE_2D:
-                        textureTarget = attrib_list[1];
-                        break;
-                      default:
-                        return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-                    }
-                    break;
-                  case EGL_MIPMAP_TEXTURE:
-                    if (attrib_list[1] != EGL_FALSE)
-                      return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-                    break;
-                  case EGL_VG_COLORSPACE:
-                    return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-                  case EGL_VG_ALPHA_FORMAT:
-                    return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-                  default:
-                    return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-                }
-
-                attrib_list += 2;
-            }
-        }
-
-        if (width < 0 || height < 0)
-        {
-            return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
-        }
-
-        if (width == 0 || height == 0)
-        {
-            return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-        }
-
-        if (textureFormat != EGL_NO_TEXTURE && !display->getNonPow2TextureSupport() && (!gl::isPow2(width) || !gl::isPow2(height)))
-        {
-            return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-        }
-
-        if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
-            (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
-        {
-            return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-        }
-
-        EGLint surfaceTypeValue;
-        EGLint bindToTextureRGBValue;
-        EGLint bindToTextureRGBAValue;
-
-        display->getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceTypeValue);
-        display->getConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGB, &bindToTextureRGBValue);
-        display->getConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGBA, &bindToTextureRGBAValue);
-
-        if (!(surfaceTypeValue & EGL_PBUFFER_BIT))
-        {
-            return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
-        }
-
-        if ((textureFormat == EGL_TEXTURE_RGB && bindToTextureRGBValue != EGL_TRUE) ||
-            (textureFormat == EGL_TEXTURE_RGBA && bindToTextureRGBAValue != EGL_TRUE))
-        {
-            return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
-        }
-
-        EGLSurface surface = (EGLSurface)display->createOffscreenSurface(width, height, config, textureFormat, textureTarget);
-
-        return success(surface);
+        return display->createOffscreenSurface(config, attrib_list);
     }
     catch(std::bad_alloc&)
     {