mesa/src/egl/main/eglsurface.c

477 lines
12 KiB
C
Raw Normal View History

2005-04-22 22:09:39 +01:00
/**
* Surface-related functions.
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "egldisplay.h"
2005-04-22 22:09:39 +01:00
#include "eglcontext.h"
#include "eglconfig.h"
#include "eglcurrent.h"
#include "egllog.h"
#include "eglsurface.h"
2005-04-22 22:09:39 +01:00
static void
_eglClampSwapInterval(_EGLSurface *surf, EGLint interval)
{
EGLint bound = GET_CONFIG_ATTRIB(surf->Config, EGL_MAX_SWAP_INTERVAL);
if (interval >= bound) {
interval = bound;
}
else {
bound = GET_CONFIG_ATTRIB(surf->Config, EGL_MIN_SWAP_INTERVAL);
if (interval < bound)
interval = bound;
}
surf->SwapInterval = 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) {
#ifdef EGL_VERSION_1_3
/* 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->Colorspace = 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->AlphaFormat = 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;
#endif /* EGL_VERSION_1_3 */
/* 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;
}
break;
case EGL_TEXTURE_FORMAT:
if (type != EGL_PBUFFER_BIT) {
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->TextureFormat = val;
break;
case EGL_TEXTURE_TARGET:
if (type != EGL_PBUFFER_BIT) {
err = EGL_BAD_ATTRIBUTE;
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(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type,
_EGLConfig *conf, const EGLint *attrib_list)
2005-04-22 22:09:39 +01:00
{
const char *func;
2006-01-30 00:10:55 +00:00
EGLint renderBuffer = EGL_BACK_BUFFER;
EGLint err;
switch (type) {
case EGL_WINDOW_BIT:
func = "eglCreateWindowSurface";
break;
case EGL_PIXMAP_BIT:
func = "eglCreatePixmapSurface";
2006-01-30 00:10:55 +00:00
renderBuffer = EGL_SINGLE_BUFFER;
break;
case EGL_PBUFFER_BIT:
func = "eglCreatePBufferSurface";
break;
case EGL_SCREEN_BIT_MESA:
func = "eglCreateScreenSurface";
2006-01-30 00:10:55 +00:00
renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */
break;
default:
_eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
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;
}
2005-04-22 22:09:39 +01:00
memset(surf, 0, sizeof(_EGLSurface));
surf->Resource.Display = dpy;
surf->Type = type;
surf->Config = conf;
surf->Width = 0;
surf->Height = 0;
surf->TextureFormat = EGL_NO_TEXTURE;
surf->TextureTarget = EGL_NO_TEXTURE;
surf->MipmapTexture = EGL_FALSE;
surf->MipmapLevel = 0;
/* the default swap interval is 1 */
_eglClampSwapInterval(surf, 1);
2006-01-30 00:10:55 +00:00
#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 = EGL_ALPHA_FORMAT_NONPRE;
surf->Colorspace = EGL_COLORSPACE_sRGB;
2006-01-30 00:10:55 +00:00
#endif
err = _eglParseSurfaceAttribList(surf, attrib_list);
if (err != EGL_SUCCESS)
return _eglError(err, func);
return EGL_TRUE;
2005-04-22 22:09:39 +01:00
}
EGLBoolean
_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
2005-04-22 22:09:39 +01:00
{
/* Drivers have to do the actual buffer swap. */
2005-04-22 22:09:39 +01:00
return EGL_TRUE;
}
EGLBoolean
_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
EGLNativePixmapType target)
2005-04-22 22:09:39 +01:00
{
2005-11-23 01:42:40 +00:00
/* copy surface to native pixmap */
/* All implementation burdon for this is in the device driver */
2005-04-22 22:09:39 +01:00
return EGL_FALSE;
}
EGLBoolean
_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLint attribute, EGLint *value)
2005-04-22 22:09:39 +01:00
{
switch (attribute) {
case EGL_WIDTH:
*value = surface->Width;
return EGL_TRUE;
case EGL_HEIGHT:
*value = surface->Height;
return EGL_TRUE;
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;
2006-01-30 00:10:55 +00:00
case EGL_SURFACE_TYPE:
*value = surface->Type;
return EGL_TRUE;
#ifdef EGL_VERSION_1_1
2005-04-22 22:09:39 +01:00
case EGL_TEXTURE_FORMAT:
/* texture attributes: only for pbuffers, no error otherwise */
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->TextureFormat;
return EGL_TRUE;
case EGL_TEXTURE_TARGET:
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->TextureTarget;
return EGL_TRUE;
case EGL_MIPMAP_TEXTURE:
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->MipmapTexture;
return EGL_TRUE;
case EGL_MIPMAP_LEVEL:
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->MipmapLevel;
return EGL_TRUE;
2006-01-30 00:10:55 +00:00
#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;
2005-05-16 17:50:38 +01:00
return EGL_TRUE;
2006-01-30 00:10:55 +00:00
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 */
2005-04-22 22:09:39 +01:00
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
return EGL_FALSE;
}
}
/**
* Drivers should do a proper implementation.
2005-04-22 22:09:39 +01:00
*/
_EGLSurface *
_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
EGLNativeWindowType window, const EGLint *attrib_list)
2005-04-22 22:09:39 +01:00
{
return NULL;
2005-04-22 22:09:39 +01:00
}
/**
* Drivers should do a proper implementation.
2005-04-22 22:09:39 +01:00
*/
_EGLSurface *
_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
EGLNativePixmapType pixmap, const EGLint *attrib_list)
2005-04-22 22:09:39 +01:00
{
return NULL;
2005-04-22 22:09:39 +01:00
}
/**
* Drivers should do a proper implementation.
2005-04-22 22:09:39 +01:00
*/
_EGLSurface *
_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
const EGLint *attrib_list)
2005-04-22 22:09:39 +01:00
{
return NULL;
2005-04-22 22:09:39 +01:00
}
/**
* Default fallback routine - drivers should usually override this.
*/
EGLBoolean
_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
2005-04-22 22:09:39 +01:00
{
if (!_eglIsSurfaceBound(surf))
free(surf);
return EGL_TRUE;
2005-04-22 22:09:39 +01:00
}
/**
* Default fallback routine - drivers might override this.
*/
EGLBoolean
_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLint attribute, EGLint value)
2005-04-22 22:09:39 +01:00
{
switch (attribute) {
case EGL_MIPMAP_LEVEL:
surface->MipmapLevel = value;
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglSurfaceAttrib");
return EGL_FALSE;
}
return EGL_TRUE;
}
EGLBoolean
_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLint buffer)
2005-04-22 22:09:39 +01:00
{
/* 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;
}
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;
2005-04-22 22:09:39 +01:00
}
EGLBoolean
_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLint buffer)
2005-04-22 22:09:39 +01:00
{
/* 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;
}
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;
2005-04-22 22:09:39 +01:00
}
EGLBoolean
_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
EGLint interval)
2005-04-22 22:09:39 +01:00
{
_eglClampSwapInterval(surf, interval);
2005-04-22 22:09:39 +01:00
return EGL_TRUE;
}
2006-01-30 00:10:55 +00:00
#ifdef EGL_VERSION_1_2
/**
* Example function - drivers should do a proper implementation.
*/
_EGLSurface *
_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy,
2006-01-30 00:10:55 +00:00
EGLenum buftype, EGLClientBuffer buffer,
_EGLConfig *conf, const EGLint *attrib_list)
2006-01-30 00:10:55 +00:00
{
if (buftype != EGL_OPENVG_IMAGE) {
_eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
return NULL;
2006-01-30 00:10:55 +00:00
}
return NULL;
2006-01-30 00:10:55 +00:00
}
#endif /* EGL_VERSION_1_2 */