2005-04-22 21:09:39 +00:00
|
|
|
/**
|
|
|
|
* Surface-related functions.
|
|
|
|
*
|
|
|
|
* See the eglcontext.c file for comments that also apply here.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "eglcontext.h"
|
|
|
|
#include "eglconfig.h"
|
|
|
|
#include "eglsurface.h"
|
|
|
|
#include "eglglobals.h"
|
|
|
|
#include "eglhash.h"
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
_eglInitSurface(_EGLSurface *surf)
|
|
|
|
{
|
|
|
|
/* XXX fix this up */
|
|
|
|
memset(surf, 0, sizeof(_EGLSurface));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
_eglSaveSurface(_EGLSurface *surf)
|
|
|
|
{
|
|
|
|
assert(surf);
|
|
|
|
surf->Handle = _eglHashGenKey(_eglGlobal.Contexts);
|
|
|
|
_eglHashInsert(_eglGlobal.Surfaces, surf->Handle, surf);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
_eglRemoveSurface(_EGLSurface *surf)
|
|
|
|
{
|
|
|
|
_eglHashRemove(_eglGlobal.Surfaces, surf->Handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_EGLSurface *
|
|
|
|
_eglLookupSurface(EGLSurface surf)
|
|
|
|
{
|
|
|
|
_EGLSurface *c = (_EGLSurface *) _eglHashLookup(_eglGlobal.Surfaces, surf);
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
_EGLSurface *
|
|
|
|
_eglGetCurrentSurface(EGLint readdraw)
|
|
|
|
{
|
|
|
|
_EGLContext *ctx = _eglGetCurrentContext();
|
|
|
|
if (ctx) {
|
|
|
|
switch (readdraw) {
|
|
|
|
case EGL_DRAW:
|
|
|
|
return ctx->DrawSurface;
|
|
|
|
case EGL_READ:
|
|
|
|
return ctx->ReadSurface;
|
|
|
|
default:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EGLBoolean
|
|
|
|
_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
|
|
|
|
{
|
|
|
|
/* Basically just do error checking */
|
|
|
|
_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;
|
|
|
|
}
|
|
|
|
return EGL_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EGLBoolean
|
|
|
|
_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
|
|
|
|
{
|
|
|
|
/* XXX unfinished */
|
|
|
|
return EGL_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EGLBoolean
|
|
|
|
_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, 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;
|
|
|
|
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_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;
|
2005-05-16 16:50:38 +00:00
|
|
|
case EGL_SURFACE_TYPE:
|
|
|
|
*value = surface->Type;
|
|
|
|
return EGL_TRUE;
|
2005-04-22 21:09:39 +00:00
|
|
|
default:
|
|
|
|
_eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
|
|
|
|
return EGL_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Default fallback routine - drivers should usually override this.
|
|
|
|
*/
|
|
|
|
EGLSurface
|
|
|
|
_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
|
|
|
|
{
|
|
|
|
/* nothing - just a placeholder */
|
|
|
|
return EGL_NO_SURFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Default fallback routine - drivers should usually override this.
|
|
|
|
*/
|
|
|
|
EGLSurface
|
|
|
|
_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
|
|
|
|
{
|
|
|
|
/* nothing - just a placeholder */
|
|
|
|
return EGL_NO_SURFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Default fallback routine - drivers should usually override this.
|
|
|
|
*/
|
|
|
|
EGLSurface
|
|
|
|
_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
|
|
|
|
{
|
|
|
|
/* nothing - just a placeholder */
|
|
|
|
return EGL_NO_SURFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Default fallback routine - drivers should usually override this.
|
|
|
|
*/
|
|
|
|
EGLBoolean
|
|
|
|
_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
|
|
|
|
{
|
|
|
|
_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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Default fallback routine - drivers might override this.
|
|
|
|
*/
|
|
|
|
EGLBoolean
|
|
|
|
_eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, 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;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
_eglError(EGL_BAD_ATTRIBUTE, "eglSurfaceAttrib");
|
|
|
|
return EGL_FALSE;
|
|
|
|
}
|
|
|
|
return EGL_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EGLBoolean
|
|
|
|
_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer)
|
|
|
|
{
|
|
|
|
/* XXX unfinished */
|
|
|
|
return EGL_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EGLBoolean
|
|
|
|
_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer)
|
|
|
|
{
|
|
|
|
/* XXX unfinished */
|
|
|
|
return EGL_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EGLBoolean
|
|
|
|
_eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval)
|
|
|
|
{
|
|
|
|
_EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW);
|
|
|
|
if (surf == NULL) {
|
|
|
|
_eglError(EGL_BAD_SURFACE, "eglSwapInterval");
|
|
|
|
return EGL_FALSE;
|
|
|
|
}
|
|
|
|
surf->SwapInterval = interval;
|
|
|
|
return EGL_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-05-17 02:12:26 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
** EGL Surface Utility Functions. This could be handy for device drivers.
|
|
|
|
**/
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
EGLSurface
|
|
|
|
_eglInitPbufferSurface(_EGLSurface *surface, _EGLDriver *drv, EGLDisplay dpy,
|
|
|
|
EGLConfig config, 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|