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