/**
* Surface-related functions.
- *
- * See the eglcontext.c file for comments that also apply here.
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+#include "egldisplay.h"
#include "eglcontext.h"
#include "eglconfig.h"
-#include "eglsurface.h"
+#include "egldriver.h"
#include "eglglobals.h"
#include "eglhash.h"
+#include "egllog.h"
+#include "eglsurface.h"
-void
-_eglInitSurface(_EGLSurface *surf)
-{
- /* XXX fix this up */
- memset(surf, 0, sizeof(_EGLSurface));
-}
-
-
-void
-_eglSaveSurface(_EGLSurface *surf)
+/**
+ * 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,
+ _EGLConfig *conf, const EGLint *attrib_list)
{
- assert(surf);
- surf->Handle = _eglHashGenKey(_eglGlobal.Contexts);
- _eglHashInsert(_eglGlobal.Surfaces, surf->Handle, surf);
-}
-
+ 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;
-void
-_eglRemoveSurface(_EGLSurface *surf)
-{
- _eglHashRemove(_eglGlobal.Surfaces, surf->Handle);
-}
+ switch (type) {
+ case EGL_WINDOW_BIT:
+ func = "eglCreateWindowSurface";
+ break;
+ case EGL_PIXMAP_BIT:
+ func = "eglCreatePixmapSurface";
+ renderBuffer = EGL_SINGLE_BUFFER;
+ break;
+ case EGL_PBUFFER_BIT:
+ func = "eglCreatePBufferSurface";
+ break;
+ case EGL_SCREEN_BIT_MESA:
+ func = "eglCreateScreenSurface";
+ renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */
+ break;
+ default:
+ _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
+ return EGL_FALSE;
+ }
+ if (!conf) {
+ _eglError(EGL_BAD_CONFIG, func);
+ return EGL_FALSE;
+ }
-_EGLSurface *
-_eglLookupSurface(EGLSurface surf)
-{
- _EGLSurface *c = (_EGLSurface *) _eglHashLookup(_eglGlobal.Surfaces, surf);
- return c;
-}
+ 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;
-_EGLSurface *
-_eglGetCurrentSurface(EGLint readdraw)
-{
- _EGLContext *ctx = _eglGetCurrentContext();
- if (ctx) {
- switch (readdraw) {
- case EGL_DRAW:
- return ctx->DrawSurface;
- case EGL_READ:
- return ctx->ReadSurface;
+#endif /* EGL_VERSION_1_2 */
default:
- return NULL;
+ _eglError(EGL_BAD_ATTRIBUTE, func);
+ return EGL_FALSE;
}
}
- return NULL;
+
+ if (width < 0 || height < 0) {
+ _eglError(EGL_BAD_ATTRIBUTE, func);
+ return EGL_FALSE;
+ }
+
+ memset(surf, 0, sizeof(_EGLSurface));
+ surf->Config = conf;
+ surf->Type = type;
+ surf->Width = width;
+ surf->Height = height;
+ surf->TextureFormat = texFormat;
+ surf->TextureTarget = texTarget;
+ surf->MipmapTexture = mipmapTex;
+ surf->MipmapLevel = 0;
+ surf->SwapInterval = 0;
+#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
+
+ return EGL_TRUE;
}
EGLBoolean
-_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
{
- /* Basically just do error checking here. Drivers have to do the
- * actual buffer swap.
- */
- _EGLContext *context = _eglGetCurrentContext();
- _EGLSurface *surface = _eglLookupSurface(draw);
- if (context && context->DrawSurface != surface) {
- _eglError(EGL_BAD_SURFACE, "eglSwapBuffers");
- return EGL_FALSE;
- }
- if (surface == NULL) {
- _eglError(EGL_BAD_SURFACE, "eglSwapBuffers");
- return EGL_FALSE;
- }
+ /* Drivers have to do the actual buffer swap. */
return EGL_TRUE;
}
EGLBoolean
-_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
+_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
+ NativePixmapType target)
{
/* copy surface to native pixmap */
/* All implementation burdon for this is in the device driver */
EGLBoolean
-_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, EGLint attribute, EGLint *value)
+_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
+ EGLint attribute, EGLint *value)
{
- _EGLSurface *surface = _eglLookupSurface(surf);
- if (surface == NULL) {
- _eglError(EGL_BAD_SURFACE, "eglQuerySurface");
- return EGL_FALSE;
- }
switch (attribute) {
case EGL_WIDTH:
*value = surface->Width;
case EGL_CONFIG_ID:
*value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID);
return EGL_TRUE;
+ 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
case EGL_TEXTURE_FORMAT:
/* texture attributes: only for pbuffers, no error otherwise */
if (surface->Type == EGL_PBUFFER_BIT)
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->MipmapLevel;
return EGL_TRUE;
- case EGL_SURFACE_TYPE:
- *value = surface->Type;
+#endif /* EGL_VERSION_1_1 */
+#ifdef EGL_VERSION_1_2
+ case EGL_SWAP_BEHAVIOR:
+ *value = surface->SwapBehavior;
+ return EGL_TRUE;
+ case EGL_RENDER_BUFFER:
+ *value = surface->RenderBuffer;
+ return EGL_TRUE;
+ case EGL_PIXEL_ASPECT_RATIO:
+ *value = surface->AspectRatio;
+ return EGL_TRUE;
+ case EGL_HORIZONTAL_RESOLUTION:
+ *value = surface->HorizontalResolution;
+ return EGL_TRUE;
+ 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 */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
return EGL_FALSE;
/**
- * Default fallback routine - drivers should usually override this.
+ * Example function - drivers should do a proper implementation.
*/
-EGLSurface
-_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
+_EGLSurface *
+_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+ NativeWindowType window, const EGLint *attrib_list)
{
- /* nothing - just a placeholder */
- return EGL_NO_SURFACE;
+#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;
}
/**
- * Default fallback routine - drivers should usually override this.
+ * Example function - drivers should do a proper implementation.
*/
-EGLSurface
-_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
+_EGLSurface *
+_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+ NativePixmapType pixmap, const EGLint *attrib_list)
{
- /* nothing - just a placeholder */
- return EGL_NO_SURFACE;
+#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;
}
/**
- * Default fallback routine - drivers should usually override this.
+ * Example function - drivers should do a proper implementation.
*/
-EGLSurface
-_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+_EGLSurface *
+_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+ const EGLint *attrib_list)
{
- /* nothing - just a placeholder */
- return EGL_NO_SURFACE;
+#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;
}
* Default fallback routine - drivers should usually override this.
*/
EGLBoolean
-_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
{
- _EGLSurface *surf = _eglLookupSurface(surface);
- if (surf) {
- _eglHashRemove(_eglGlobal.Surfaces, surface);
- if (surf->IsBound) {
- surf->DeletePending = EGL_TRUE;
- }
- else {
- free(surf);
- }
- return EGL_TRUE;
- }
- else {
- _eglError(EGL_BAD_SURFACE, "eglDestroySurface");
- return EGL_FALSE;
- }
+ if (!_eglIsSurfaceBound(surf))
+ free(surf);
+ return EGL_TRUE;
}
* Default fallback routine - drivers might override this.
*/
EGLBoolean
-_eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, EGLint attribute, EGLint value)
+_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
+ EGLint attribute, EGLint value)
{
- _EGLSurface *surface = _eglLookupSurface(surf);
-
- if (surface == NULL) {
- _eglError(EGL_BAD_SURFACE, "eglSurfaceAttrib");
- return EGL_FALSE;
- }
-
switch (attribute) {
case EGL_MIPMAP_LEVEL:
surface->MipmapLevel = value;
EGLBoolean
-_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
+ EGLint buffer)
{
- /* XXX unfinished */
- return EGL_FALSE;
-}
+ /* Just do basic error checking and return success/fail.
+ * Drivers must implement the real stuff.
+ */
+ if (surface->Type != EGL_PBUFFER_BIT) {
+ _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
+ return EGL_FALSE;
+ }
-EGLBoolean
-_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer)
-{
- /* XXX unfinished */
- return EGL_FALSE;
+ if (surface->TextureFormat == EGL_NO_TEXTURE) {
+ _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+ return EGL_FALSE;
+ }
+
+ if (buffer != EGL_BACK_BUFFER) {
+ _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
+ return EGL_FALSE;
+ }
+
+ surface->BoundToTexture = EGL_TRUE;
+
+ return EGL_TRUE;
}
EGLBoolean
-_eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval)
+_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
+ EGLint buffer)
{
- _EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW);
- if (surf == NULL) {
- _eglError(EGL_BAD_SURFACE, "eglSwapInterval");
+ /* Just do basic error checking and return success/fail.
+ * Drivers must implement the real stuff.
+ */
+
+ if (surface->Type != EGL_PBUFFER_BIT) {
+ _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
return EGL_FALSE;
}
- surf->SwapInterval = interval;
+
+ if (surface->TextureFormat == EGL_NO_TEXTURE) {
+ _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+ return EGL_FALSE;
+ }
+
+ if (buffer != EGL_BACK_BUFFER) {
+ _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
+ return EGL_FALSE;
+ }
+
+ if (!surface->BoundToTexture) {
+ _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
+ return EGL_FALSE;
+ }
+
+ surface->BoundToTexture = EGL_FALSE;
+
return EGL_TRUE;
}
+EGLBoolean
+_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, EGLint interval)
+{
+ _EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW);
+ if (surf)
+ surf->SwapInterval = interval;
+ return EGL_TRUE;
+}
-/**
- ** EGL Surface Utility Functions. This could be handy for device drivers.
- **/
+#ifdef EGL_VERSION_1_2
/**
- * Initialize the fields of the given _EGLSurface object from the other
- * parameters. Do error checking too. Allocate EGLSurface handle and
- * insert into hash table.
- * \return EGLSurface handle or EGL_NO_SURFACE if any error
+ * Example function - drivers should do a proper implementation.
*/
-EGLSurface
-_eglInitPbufferSurface(_EGLSurface *surface, _EGLDriver *drv, EGLDisplay dpy,
- EGLConfig config, const EGLint *attrib_list)
+_EGLSurface *
+_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy,
+ EGLenum buftype, EGLClientBuffer buffer,
+ _EGLConfig *conf, const EGLint *attrib_list)
{
- _EGLConfig *conf;
- EGLint width = 0, height = 0, largest = 0;
- EGLint texFormat = 0, texTarget = 0, mipmapTex = 0;
- EGLint i;
-
- conf = _eglLookupConfig(drv, dpy, config);
- if (!conf) {
- _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
- return EGL_NO_SURFACE;
+ if (buftype != EGL_OPENVG_IMAGE) {
+ _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
+ return NULL;
}
- for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
- switch (attrib_list[i]) {
- case EGL_WIDTH:
- width = attrib_list[++i];
- break;
- case EGL_HEIGHT:
- height = attrib_list[++i];
- break;
- case EGL_LARGEST_PBUFFER:
- largest = attrib_list[++i];
- break;
- case EGL_TEXTURE_FORMAT:
- texFormat = attrib_list[++i];
- break;
- case EGL_TEXTURE_TARGET:
- texTarget = attrib_list[++i];
- break;
- case EGL_MIPMAP_TEXTURE:
- mipmapTex = attrib_list[++i];
- break;
- default:
- _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
- return EGL_NO_SURFACE;
- }
- }
-
- if (width <= 0 || height <= 0) {
- _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface(width or height)");
- return EGL_NO_SURFACE;
- }
-
- surface->Config = conf;
- surface->Type = EGL_PBUFFER_BIT;
- surface->Width = width;
- surface->Height = height;
- surface->TextureFormat = texFormat;
- surface->TextureTarget = texTarget;
- surface->MipmapTexture = mipmapTex;
- surface->MipmapLevel = 0;
- surface->SwapInterval = 0;
-
- /* insert into hash table */
- _eglSaveSurface(surface);
- assert(surface->Handle);
-
- return surface->Handle;
+ return NULL;
}
+
+#endif /* EGL_VERSION_1_2 */