summaryrefslogtreecommitdiff
path: root/src/egl/main/eglsurface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl/main/eglsurface.c')
-rw-r--r--src/egl/main/eglsurface.c484
1 files changed, 256 insertions, 228 deletions
diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c
index 940a1b760c..8026a6314d 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -9,8 +9,7 @@
#include "egldisplay.h"
#include "eglcontext.h"
#include "eglconfig.h"
-#include "egldriver.h"
-#include "eglglobals.h"
+#include "eglcurrent.h"
#include "egllog.h"
#include "eglsurface.h"
@@ -32,23 +31,168 @@ _eglClampSwapInterval(_EGLSurface *surf, EGLint interval)
/**
+ * Parse the list of surface attributes and return the proper error code.
+ */
+static EGLint
+_eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
+{
+ EGLint type = surf->Type;
+ EGLint i, err = EGL_SUCCESS;
+
+ if (!attrib_list)
+ return EGL_SUCCESS;
+
+ for (i = 0; attrib_list[i] != EGL_NONE; i++) {
+ EGLint attr = attrib_list[i++];
+ EGLint val = attrib_list[i];
+
+ switch (attr) {
+ /* common (except for screen surfaces) attributes */
+ case EGL_VG_COLORSPACE:
+ if (type == EGL_SCREEN_BIT_MESA) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ switch (val) {
+ case EGL_VG_COLORSPACE_sRGB:
+ case EGL_VG_COLORSPACE_LINEAR:
+ break;
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ if (err != EGL_SUCCESS)
+ break;
+ surf->VGColorspace = val;
+ break;
+ case EGL_VG_ALPHA_FORMAT:
+ if (type == EGL_SCREEN_BIT_MESA) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ switch (val) {
+ case EGL_VG_ALPHA_FORMAT_NONPRE:
+ case EGL_VG_ALPHA_FORMAT_PRE:
+ break;
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ if (err != EGL_SUCCESS)
+ break;
+ surf->VGAlphaFormat = val;
+ break;
+ /* window surface attributes */
+ case EGL_RENDER_BUFFER:
+ if (type != EGL_WINDOW_BIT) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ if (val != EGL_BACK_BUFFER && val != EGL_SINGLE_BUFFER) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ surf->RenderBuffer = val;
+ break;
+ /* pbuffer surface attributes */
+ case EGL_WIDTH:
+ if (type != EGL_PBUFFER_BIT && type != EGL_SCREEN_BIT_MESA) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ if (val < 0) {
+ err = EGL_BAD_PARAMETER;
+ break;
+ }
+ surf->Width = val;
+ break;
+ case EGL_HEIGHT:
+ if (type != EGL_PBUFFER_BIT && type != EGL_SCREEN_BIT_MESA) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ if (val < 0) {
+ err = EGL_BAD_PARAMETER;
+ break;
+ }
+ surf->Height = val;
+ break;
+ case EGL_LARGEST_PBUFFER:
+ if (type != EGL_PBUFFER_BIT) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ surf->LargestPbuffer = !!val;
+ break;
+ case EGL_TEXTURE_FORMAT:
+ if (type != EGL_PBUFFER_BIT) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ switch (val) {
+ case EGL_TEXTURE_RGB:
+ case EGL_TEXTURE_RGBA:
+ case EGL_NO_TEXTURE:
+ break;
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ if (err != EGL_SUCCESS)
+ break;
+ surf->TextureFormat = val;
+ break;
+ case EGL_TEXTURE_TARGET:
+ if (type != EGL_PBUFFER_BIT) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ switch (val) {
+ case EGL_TEXTURE_2D:
+ case EGL_NO_TEXTURE:
+ break;
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ if (err != EGL_SUCCESS)
+ break;
+ surf->TextureTarget = val;
+ break;
+ case EGL_MIPMAP_TEXTURE:
+ if (type != EGL_PBUFFER_BIT) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ surf->MipmapTexture = !!val;
+ break;
+ /* no pixmap surface specific attributes */
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ if (err != EGL_SUCCESS) {
+ _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
+ break;
+ }
+ }
+
+ return err;
+}
+
+
+/**
* Do error check on parameters and initialize the given _EGLSurface object.
* \return EGL_TRUE if no errors, EGL_FALSE otherwise.
*/
EGLBoolean
-_eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type,
+_eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
_EGLConfig *conf, const EGLint *attrib_list)
{
const char *func;
- EGLint width = 0, height = 0, largest = 0;
- EGLint texFormat = EGL_NO_TEXTURE, texTarget = EGL_NO_TEXTURE;
- EGLint mipmapTex = EGL_FALSE;
EGLint renderBuffer = EGL_BACK_BUFFER;
-#ifdef EGL_VERSION_1_2
- EGLint colorspace = EGL_COLORSPACE_sRGB;
- EGLint alphaFormat = EGL_ALPHA_FORMAT_NONPRE;
-#endif
- EGLint i;
+ EGLint err;
switch (type) {
case EGL_WINDOW_BIT:
@@ -70,158 +214,41 @@ _eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type,
return EGL_FALSE;
}
- if (!conf) {
- _eglError(EGL_BAD_CONFIG, func);
- return EGL_FALSE;
- }
-
if ((GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE) & type) == 0) {
/* The config can't be used to create a surface of this type */
_eglError(EGL_BAD_CONFIG, func);
return EGL_FALSE;
}
- /*
- * Parse attribute list. Different kinds of surfaces support different
- * attributes.
- */
- for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
- switch (attrib_list[i]) {
- case EGL_WIDTH:
- if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) {
- width = attrib_list[++i];
- }
- else {
- _eglError(EGL_BAD_ATTRIBUTE, func);
- return EGL_FALSE;
- }
- break;
- case EGL_HEIGHT:
- if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) {
- height = attrib_list[++i];
- }
- else {
- _eglError(EGL_BAD_ATTRIBUTE, func);
- return EGL_FALSE;
- }
- break;
- case EGL_LARGEST_PBUFFER:
- if (type == EGL_PBUFFER_BIT) {
- largest = attrib_list[++i];
- }
- else {
- _eglError(EGL_BAD_ATTRIBUTE, func);
- return EGL_FALSE;
- }
- break;
- case EGL_TEXTURE_FORMAT:
- if (type == EGL_PBUFFER_BIT) {
- texFormat = attrib_list[++i];
- }
- else {
- _eglError(EGL_BAD_ATTRIBUTE, func);
- return EGL_FALSE;
- }
- break;
- case EGL_TEXTURE_TARGET:
- if (type == EGL_PBUFFER_BIT) {
- texTarget = attrib_list[++i];
- }
- else {
- _eglError(EGL_BAD_ATTRIBUTE, func);
- return EGL_FALSE;
- }
- break;
- case EGL_MIPMAP_TEXTURE:
- if (type == EGL_PBUFFER_BIT) {
- mipmapTex = attrib_list[++i];
- }
- else {
- _eglError(EGL_BAD_ATTRIBUTE, func);
- return EGL_FALSE;
- }
- break;
-#ifdef EGL_VERSION_1_2
- case EGL_RENDER_BUFFER:
- if (type == EGL_WINDOW_BIT) {
- renderBuffer = attrib_list[++i];
- if (renderBuffer != EGL_BACK_BUFFER &&
- renderBuffer != EGL_SINGLE_BUFFER) {
- _eglError(EGL_BAD_ATTRIBUTE, func);
- return EGL_FALSE;
- }
- }
- else {
- _eglError(EGL_BAD_ATTRIBUTE, func);
- return EGL_FALSE;
- }
- break;
- case EGL_COLORSPACE:
- if (type == EGL_WINDOW_BIT ||
- type == EGL_PBUFFER_BIT ||
- type == EGL_PIXMAP_BIT) {
- colorspace = attrib_list[++i];
- if (colorspace != EGL_COLORSPACE_sRGB &&
- colorspace != EGL_COLORSPACE_LINEAR) {
- _eglError(EGL_BAD_ATTRIBUTE, func);
- return EGL_FALSE;
- }
- }
- else {
- _eglError(EGL_BAD_ATTRIBUTE, func);
- return EGL_FALSE;
- }
- break;
- case EGL_ALPHA_FORMAT:
- if (type == EGL_WINDOW_BIT ||
- type == EGL_PBUFFER_BIT ||
- type == EGL_PIXMAP_BIT) {
- alphaFormat = attrib_list[++i];
- if (alphaFormat != EGL_ALPHA_FORMAT_NONPRE &&
- alphaFormat != EGL_ALPHA_FORMAT_PRE) {
- _eglError(EGL_BAD_ATTRIBUTE, func);
- return EGL_FALSE;
- }
- }
- else {
- _eglError(EGL_BAD_ATTRIBUTE, func);
- return EGL_FALSE;
- }
- break;
-
-#endif /* EGL_VERSION_1_2 */
- default:
- _eglError(EGL_BAD_ATTRIBUTE, func);
- return EGL_FALSE;
- }
- }
-
- if (width < 0 || height < 0) {
- _eglError(EGL_BAD_ATTRIBUTE, func);
- return EGL_FALSE;
- }
-
memset(surf, 0, sizeof(_EGLSurface));
- surf->Config = conf;
+ surf->Resource.Display = dpy;
surf->Type = type;
- surf->Width = width;
- surf->Height = height;
- surf->TextureFormat = texFormat;
- surf->TextureTarget = texTarget;
- surf->MipmapTexture = mipmapTex;
+ surf->Config = conf;
+
+ surf->Width = 0;
+ surf->Height = 0;
+ surf->TextureFormat = EGL_NO_TEXTURE;
+ surf->TextureTarget = EGL_NO_TEXTURE;
+ surf->MipmapTexture = EGL_FALSE;
+ surf->LargestPbuffer = EGL_FALSE;
+ surf->RenderBuffer = renderBuffer;
+ surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
+ surf->VGColorspace = EGL_VG_COLORSPACE_sRGB;
+
surf->MipmapLevel = 0;
+ surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT;
+ surf->SwapBehavior = EGL_BUFFER_DESTROYED;
+
+ surf->HorizontalResolution = EGL_UNKNOWN;
+ surf->VerticalResolution = EGL_UNKNOWN;
+ surf->AspectRatio = EGL_UNKNOWN;
+
/* the default swap interval is 1 */
_eglClampSwapInterval(surf, 1);
-#ifdef EGL_VERSION_1_2
- surf->SwapBehavior = EGL_BUFFER_DESTROYED; /* XXX ok? */
- surf->HorizontalResolution = EGL_UNKNOWN; /* set by caller */
- surf->VerticalResolution = EGL_UNKNOWN; /* set by caller */
- surf->AspectRatio = EGL_UNKNOWN; /* set by caller */
- surf->RenderBuffer = renderBuffer;
- surf->AlphaFormat = alphaFormat;
- surf->Colorspace = colorspace;
-#endif
+ err = _eglParseSurfaceAttribList(surf, attrib_list);
+ if (err != EGL_SUCCESS)
+ return _eglError(err, func);
return EGL_TRUE;
}
@@ -237,7 +264,7 @@ _eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
EGLBoolean
_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
- NativePixmapType target)
+ EGLNativePixmapType target)
{
/* copy surface to native pixmap */
/* All implementation burdon for this is in the device driver */
@@ -252,139 +279,95 @@ _eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
switch (attribute) {
case EGL_WIDTH:
*value = surface->Width;
- return EGL_TRUE;
+ break;
case EGL_HEIGHT:
*value = surface->Height;
- return EGL_TRUE;
+ break;
case EGL_CONFIG_ID:
*value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID);
- return EGL_TRUE;
+ break;
case EGL_LARGEST_PBUFFER:
- *value = dpy->LargestPbuffer;
- return EGL_TRUE;
- case EGL_SURFACE_TYPE:
- *value = surface->Type;
- return EGL_TRUE;
-#ifdef EGL_VERSION_1_1
+ *value = surface->LargestPbuffer;
+ break;
case EGL_TEXTURE_FORMAT:
/* texture attributes: only for pbuffers, no error otherwise */
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->TextureFormat;
- return EGL_TRUE;
+ break;
case EGL_TEXTURE_TARGET:
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->TextureTarget;
- return EGL_TRUE;
+ break;
case EGL_MIPMAP_TEXTURE:
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->MipmapTexture;
- return EGL_TRUE;
+ break;
case EGL_MIPMAP_LEVEL:
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->MipmapLevel;
- return EGL_TRUE;
-#endif /* EGL_VERSION_1_1 */
-#ifdef EGL_VERSION_1_2
+ break;
case EGL_SWAP_BEHAVIOR:
*value = surface->SwapBehavior;
- return EGL_TRUE;
+ break;
case EGL_RENDER_BUFFER:
*value = surface->RenderBuffer;
- return EGL_TRUE;
+ break;
case EGL_PIXEL_ASPECT_RATIO:
*value = surface->AspectRatio;
- return EGL_TRUE;
+ break;
case EGL_HORIZONTAL_RESOLUTION:
*value = surface->HorizontalResolution;
- return EGL_TRUE;
+ break;
case EGL_VERTICAL_RESOLUTION:
*value = surface->VerticalResolution;
- return EGL_TRUE;
- case EGL_ALPHA_FORMAT:
- *value = surface->AlphaFormat;
- return EGL_TRUE;
- case EGL_COLORSPACE:
- *value = surface->Colorspace;
- return EGL_TRUE;
-#endif /* EGL_VERSION_1_2 */
+ break;
+ case EGL_MULTISAMPLE_RESOLVE:
+ *value = surface->MultisampleResolve;
+ break;
+ case EGL_VG_ALPHA_FORMAT:
+ *value = surface->VGAlphaFormat;
+ break;
+ case EGL_VG_COLORSPACE:
+ *value = surface->VGColorspace;
+ break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
return EGL_FALSE;
}
+
+ return EGL_TRUE;
}
/**
- * Example function - drivers should do a proper implementation.
+ * Drivers should do a proper implementation.
*/
_EGLSurface *
_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- NativeWindowType window, const EGLint *attrib_list)
+ EGLNativeWindowType window, const EGLint *attrib_list)
{
-#if 0 /* THIS IS JUST EXAMPLE CODE */
- _EGLSurface *surf;
-
- surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
- if (!surf)
- return NULL;
-
- if (!_eglInitSurface(drv, surf, EGL_WINDOW_BIT, conf, attrib_list)) {
- free(surf);
- return NULL;
- }
-
- return surf;
-#endif
return NULL;
}
/**
- * Example function - drivers should do a proper implementation.
+ * Drivers should do a proper implementation.
*/
_EGLSurface *
_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- NativePixmapType pixmap, const EGLint *attrib_list)
+ EGLNativePixmapType pixmap, const EGLint *attrib_list)
{
-#if 0 /* THIS IS JUST EXAMPLE CODE */
- _EGLSurface *surf;
-
- surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
- if (!surf)
- return NULL;
-
- if (!_eglInitSurface(drv, surf, EGL_PIXMAP_BIT, conf, attrib_list)) {
- free(surf);
- return NULL;
- }
-
- return surf;
-#endif
return NULL;
}
/**
- * Example function - drivers should do a proper implementation.
+ * Drivers should do a proper implementation.
*/
_EGLSurface *
_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
const EGLint *attrib_list)
{
-#if 0 /* THIS IS JUST EXAMPLE CODE */
- _EGLSurface *surf;
-
- surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
- if (!surf)
- return NULL;
-
- if (!_eglInitSurface(drv, surf, EGL_PBUFFER_BIT, conf, attrib_list)) {
- free(surf);
- return NULL;
- }
-
- return NULL;
-#endif
return NULL;
}
@@ -408,14 +391,59 @@ EGLBoolean
_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLint attribute, EGLint value)
{
+ EGLint confval;
+ EGLint err = EGL_SUCCESS;
+
switch (attribute) {
case EGL_MIPMAP_LEVEL:
+ confval = GET_CONFIG_ATTRIB(surface->Config, EGL_RENDERABLE_TYPE);
+ if (!(confval & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT))) {
+ err = EGL_BAD_PARAMETER;
+ break;
+ }
surface->MipmapLevel = value;
break;
+ case EGL_MULTISAMPLE_RESOLVE:
+ switch (value) {
+ case EGL_MULTISAMPLE_RESOLVE_DEFAULT:
+ break;
+ case EGL_MULTISAMPLE_RESOLVE_BOX:
+ confval = GET_CONFIG_ATTRIB(surface->Config, EGL_SURFACE_TYPE);
+ if (!(confval & EGL_MULTISAMPLE_RESOLVE_BOX_BIT))
+ err = EGL_BAD_MATCH;
+ break;
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ if (err != EGL_SUCCESS)
+ break;
+ surface->MultisampleResolve = value;
+ break;
+ case EGL_SWAP_BEHAVIOR:
+ switch (value) {
+ case EGL_BUFFER_DESTROYED:
+ break;
+ case EGL_BUFFER_PRESERVED:
+ confval = GET_CONFIG_ATTRIB(surface->Config, EGL_SURFACE_TYPE);
+ if (!(confval & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
+ err = EGL_BAD_MATCH;
+ break;
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ if (err != EGL_SUCCESS)
+ break;
+ surface->SwapBehavior = value;
+ break;
default:
- _eglError(EGL_BAD_ATTRIBUTE, "eglSurfaceAttrib");
- return EGL_FALSE;
+ err = EGL_BAD_ATTRIBUTE;
+ break;
}
+
+ if (err != EGL_SUCCESS)
+ return _eglError(err, "eglSurfaceAttrib");
return EGL_TRUE;
}