initial EGL code

This commit is contained in:
Brian Paul 2005-04-22 21:09:39 +00:00
parent a661654a33
commit adbff7e977
24 changed files with 3429 additions and 0 deletions

24
src/egl/Makefile Normal file
View File

@ -0,0 +1,24 @@
# src/egl/Makefile
TOP = ../..
SUBDIRS = main drivers/demo
default: subdirs
subdirs:
@for dir in $(SUBDIRS) ; do \
if [ -d $$dir ] ; then \
(cd $$dir ; $(MAKE)) || exit 1 ; \
fi \
done
clean:
@for dir in $(SUBDIRS) ; do \
if [ -d $$dir ] ; then \
(cd $$dir ; $(MAKE) clean) ; \
fi \
done

View File

@ -0,0 +1,31 @@
# src/egl/drivers/demo/Makefile
TOP = ../../../..
include $(TOP)/configs/current
INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/egl/main
SOURCES = demo.c
OBJECTS = $(SOURCES:.c=.o)
.c.o:
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
default: $(LIB_DIR)/demodriver.so
$(LIB_DIR)/demodriver.so: $(OBJECTS)
$(TOP)/bin/mklib -o demodriver.so -noprefix \
-install $(LIB_DIR) $(OBJECTS)
clean:
rm -f *.o
rm -f *.so

403
src/egl/drivers/demo/demo.c Normal file
View File

@ -0,0 +1,403 @@
/*
* Sample driver: Demo
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "eglconfig.h"
#include "eglcontext.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
#include "eglmode.h"
#include "eglscreen.h"
#include "eglsurface.h"
/**
* Demo driver-specific driver class derived from _EGLDriver
*/
typedef struct demo_driver
{
_EGLDriver Base; /* base class/object */
GLuint DemoStuff;
} DemoDriver;
#define DEMO_DRIVER(D) ((DemoDriver *) (D))
/**
* Demo driver-specific surface class derived from _EGLSurface
*/
typedef struct demo_surface
{
_EGLSurface Base; /* base class/object */
GLuint DemoStuff;
} DemoSurface;
/**
* Demo driver-specific context class derived from _EGLContext
*/
typedef struct demo_context
{
_EGLContext Base; /* base class/object */
GLuint DemoStuff;
} DemoContext;
static EGLBoolean
demoInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
_EGLScreen *scrn;
EGLint i;
disp->NumScreens = 1;
disp->Screens = (_EGLScreen *) calloc(disp->NumScreens, sizeof(_EGLScreen));
scrn = disp->Screens + 0;
scrn->NumModes = 4;
scrn->Modes = (_EGLMode *) calloc(scrn->NumModes, sizeof(_EGLMode));
scrn->Modes[0].Width = 1600;
scrn->Modes[0].Height = 1200;
scrn->Modes[0].Depth = 32;
scrn->Modes[0].RefreshRate = 72 * 1000;
scrn->Modes[1].Width = 1280;
scrn->Modes[1].Height = 1024;
scrn->Modes[1].Depth = 32;
scrn->Modes[1].RefreshRate = 72 * 1000;
scrn->Modes[2].Width = 1280;
scrn->Modes[2].Height = 1024;
scrn->Modes[2].Depth = 16;
scrn->Modes[2].RefreshRate = 72 * 1000;
scrn->Modes[3].Width = 1024;
scrn->Modes[3].Height = 768;
scrn->Modes[3].Depth = 16;
scrn->Modes[3].RefreshRate = 72 * 1000;
for (i = 0; i < scrn->NumModes; i++)
scrn->Modes[i].Handle = i + 1;
/* Create list of visual configs - this is a silly example */
disp->NumConfigs = 4;
disp->Configs = (_EGLConfig *) calloc(disp->NumConfigs, sizeof(_EGLConfig));
for (i = 0; i < disp->NumConfigs; i++) {
_EGLConfig *config = disp->Configs + i;
_eglInitConfig(config, i + 1);
SET_CONFIG_ATTRIB(config, EGL_RED_SIZE, 8);
SET_CONFIG_ATTRIB(config, EGL_GREEN_SIZE, 8);
SET_CONFIG_ATTRIB(config, EGL_BLUE_SIZE, 8);
SET_CONFIG_ATTRIB(config, EGL_ALPHA_SIZE, 8);
SET_CONFIG_ATTRIB(config, EGL_BUFFER_SIZE, 32);
if (i & 1) {
SET_CONFIG_ATTRIB(config, EGL_DEPTH_SIZE, 32);
}
if (i & 2) {
SET_CONFIG_ATTRIB(config, EGL_STENCIL_SIZE, 8);
}
SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE,
(EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT));
}
drv->Initialized = EGL_TRUE;
*major = 1;
*minor = 0;
return EGL_TRUE;
}
static EGLBoolean
demoTerminate(_EGLDriver *drv, EGLDisplay dpy)
{
/*DemoDriver *demo = DEMO_DRIVER(dpy);*/
free(drv);
return EGL_TRUE;
}
static DemoContext *
LookupDemoContext(EGLContext ctx)
{
_EGLContext *c = _eglLookupContext(ctx);
return (DemoContext *) c;
}
static DemoSurface *
LookupDemoSurface(EGLSurface surf)
{
_EGLSurface *s = _eglLookupSurface(surf);
return (DemoSurface *) s;
}
static EGLContext
demoCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
{
_EGLConfig *conf;
DemoContext *c;
_EGLDisplay *disp = _eglLookupDisplay(dpy);
int i;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreateContext");
return EGL_NO_CONTEXT;
}
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
/* no attribs defined for now */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
return EGL_NO_CONTEXT;
}
}
c = (DemoContext *) calloc(1, sizeof(DemoContext));
if (!c)
return EGL_NO_CONTEXT;
_eglInitContext(&c->Base);
c->Base.Display = disp;
c->Base.Config = conf;
c->Base.DrawSurface = EGL_NO_SURFACE;
c->Base.ReadSurface = EGL_NO_SURFACE;
c->DemoStuff = 1;
printf("demoCreateContext\n");
/* generate handle and insert into hash table */
_eglSaveContext(&c->Base);
assert(c->Base.Handle);
return c->Base.Handle;
}
static EGLSurface
demoCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
{
int i;
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
/* no attribs at this time */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreateWindowSurface");
return EGL_NO_SURFACE;
}
}
printf("eglCreateWindowSurface()\n");
/* XXX unfinished */
return EGL_NO_SURFACE;
}
static EGLSurface
demoCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
{
_EGLConfig *conf;
EGLint i;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface");
return EGL_NO_SURFACE;
}
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
/* no attribs at this time */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface");
return EGL_NO_SURFACE;
}
}
if (conf->Attrib[EGL_SURFACE_TYPE - FIRST_ATTRIB] == 0) {
_eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface");
return EGL_NO_SURFACE;
}
printf("eglCreatePixmapSurface()\n");
return EGL_NO_SURFACE;
}
static EGLSurface
demoCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
{
_EGLConfig *conf;
EGLint i, width = 0, height = 0, largest, texFormat, texTarget, mipmapTex;
DemoSurface *surf;
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;
}
surf = (DemoSurface *) calloc(1, sizeof(DemoSurface));
if (!surf)
return EGL_NO_SURFACE;
surf->Base.Config = conf;
surf->Base.Type = EGL_PBUFFER_BIT;
surf->Base.Width = width;
surf->Base.Height = height;
surf->Base.TextureFormat = texFormat;
surf->Base.TextureTarget = texTarget;
surf->Base.MipmapTexture = mipmapTex;
surf->Base.MipmapLevel = 0;
surf->Base.SwapInterval = 0;
printf("eglCreatePbufferSurface()\n");
/* insert into hash table */
_eglSaveSurface(&surf->Base);
assert(surf->Base.Handle);
return surf->Base.Handle;
}
static EGLBoolean
demoDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
DemoSurface *fs = LookupDemoSurface(surface);
_eglRemoveSurface(&fs->Base);
if (fs->Base.IsBound) {
fs->Base.DeletePending = EGL_TRUE;
}
else {
free(fs);
}
return EGL_TRUE;
}
static EGLBoolean
demoDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
{
DemoContext *fc = LookupDemoContext(context);
_eglRemoveContext(&fc->Base);
if (fc->Base.IsBound) {
fc->Base.DeletePending = EGL_TRUE;
}
else {
free(fc);
}
return EGL_TRUE;
}
static EGLBoolean
demoMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
{
/*DemoDriver *demo = DEMO_DRIVER(dpy);*/
DemoSurface *readSurf = LookupDemoSurface(read);
DemoSurface *drawSurf = LookupDemoSurface(draw);
DemoContext *ctx = LookupDemoContext(context);
EGLBoolean b;
b = _eglMakeCurrent(drv, dpy, draw, read, context);
if (!b)
return EGL_FALSE;
/* XXX this is where we'd do the hardware context switch */
(void) drawSurf;
(void) readSurf;
(void) ctx;
printf("eglMakeCurrent()\n");
return EGL_TRUE;
}
static const char *
demoQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
{
if (name == EGL_EXTENSIONS) {
return "EGL_MESA_screen_surface";
}
else {
return _eglQueryString(drv, dpy, name);
}
}
/*
* Just to silence warning
*/
extern _EGLDriver *
_eglMain(NativeDisplayType dpy);
/**
* The bootstrap function. Return a new DemoDriver object and
* plug in API functions.
*/
_EGLDriver *
_eglMain(NativeDisplayType dpy)
{
DemoDriver *demo;
demo = (DemoDriver *) calloc(1, sizeof(DemoDriver));
if (!demo) {
return NULL;
}
/* First fill in the dispatch table with defaults */
_eglInitDriverFallbacks(&demo->Base);
/* then plug in our Demo-specific functions */
demo->Base.Initialize = demoInitialize;
demo->Base.Terminate = demoTerminate;
demo->Base.CreateContext = demoCreateContext;
demo->Base.MakeCurrent = demoMakeCurrent;
demo->Base.CreateWindowSurface = demoCreateWindowSurface;
demo->Base.CreatePixmapSurface = demoCreatePixmapSurface;
demo->Base.CreatePbufferSurface = demoCreatePbufferSurface;
demo->Base.DestroySurface = demoDestroySurface;
demo->Base.DestroyContext = demoDestroyContext;
demo->Base.QueryString = demoQueryString;
return &demo->Base;
}

64
src/egl/main/Makefile Normal file
View File

@ -0,0 +1,64 @@
# src/egl/main/Makefile
TOP = ../../..
include $(TOP)/configs/current
INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi
HEADERS = \
eglconfig.h \
eglcontext.h \
egldisplay.h \
egldriver.h \
eglglobals.h \
eglhash.h \
eglmode.h \
eglscreen.h \
eglsurface.h
SOURCES = \
eglapi.c \
eglconfig.c \
eglcontext.c \
egldisplay.c \
egldriver.c \
eglglobals.c \
eglhash.c \
eglmode.c \
eglscreen.c \
eglsurface.c
OBJECTS = $(SOURCES:.c=.o)
.c.o:
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
default: depend library
# EGL Library
library: $(LIB_DIR)/libEGL.so
$(LIB_DIR)/libEGL.so: $(OBJECTS)
$(TOP)/bin/mklib -o EGL -major 1 -minor 0 \
-install $(LIB_DIR) -ldl $(OBJECTS)
clean:
rm -f *.o *.so*
rm -f core.*
depend: $(SOURCES) $(HEADERS)
@ echo "running $(MKDEP)"
@ touch depend
$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \
$(SOURCES) $(HEADERS) > /dev/null
include depend
# DO NOT DELETE

462
src/egl/main/eglapi.c Normal file
View File

@ -0,0 +1,462 @@
/**
* Public EGL API entrypoints
*
* Generally, we use the EGLDisplay parameter as a key to lookup the
* appropriate device driver handle, then jump though the driver's
* dispatch table to handle the function.
*
* That allows us the option of supporting multiple, simultaneous,
* heterogeneous hardware devices in the future.
*
* The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are
* opaque handles implemented with 32-bit unsigned integers.
* It's up to the driver function or fallback function to look up the
* handle and get an object.
* By using opaque handles, we leave open the possibility of having
* indirect rendering in the future, like GLX.
*
*
* Notes on naming conventions:
*
* eglFooBar - public EGL function
* EGL_FOO_BAR - public EGL token
* EGLDatatype - public EGL datatype
*
* _eglFooBar - private EGL function
* _EGLDatatype - private EGL datatype, typedef'd struct
* _egl_struct - private EGL struct, non-typedef'd
*
*/
#include <stdio.h>
#include <string.h>
/**#include "glapi.h"**/
#include "eglcontext.h"
#include "egldisplay.h"
#include "egltypedefs.h"
#include "eglglobals.h"
#include "egldriver.h"
#include "eglsurface.h"
/**
* NOTE: displayName is treated as a string in _eglChooseDriver()!!!
* This will probably change!
* See _eglChooseDriver() for details!
*/
EGLDisplay APIENTRY
eglGetDisplay(NativeDisplayType displayName)
{
_EGLDisplay *dpy;
_eglInitGlobals();
dpy = _eglNewDisplay(displayName);
if (dpy)
return dpy->Handle;
else
return EGL_NO_DISPLAY;
}
EGLBoolean APIENTRY
eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{
if (dpy) {
_EGLDriver *drv = _eglChooseDriver(dpy);
if (drv)
return drv->Initialize(drv, dpy, major, minor);
}
return EGL_FALSE;
}
EGLBoolean APIENTRY
eglTerminate(EGLDisplay dpy)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
if (drv)
return _eglCloseDriver(drv, dpy);
else
return EGL_FALSE;
}
const char * APIENTRY
eglQueryString(EGLDisplay dpy, EGLint name)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
if (drv)
return drv->QueryString(drv, dpy, name);
else
return NULL;
}
EGLBoolean APIENTRY
eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
/* XXX check drv for null in remaining functions */
return drv->GetConfigs(drv, dpy, configs, config_size, num_config);
}
EGLBoolean APIENTRY
eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->ChooseConfig(drv, dpy, attrib_list, configs, config_size, num_config);
}
EGLBoolean APIENTRY
eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->GetConfigAttrib(drv, dpy, config, attribute, value);
}
EGLContext APIENTRY
eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->CreateContext(drv, dpy, config, share_list, attrib_list);
}
EGLBoolean APIENTRY
eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->DestroyContext(drv, dpy, ctx);
}
EGLBoolean APIENTRY
eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->MakeCurrent(drv, dpy, draw, read, ctx);
}
EGLBoolean APIENTRY
eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->QueryContext(drv, dpy, ctx, attribute, value);
}
EGLSurface APIENTRY
eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->CreateWindowSurface(drv, dpy, config, window, attrib_list);
}
EGLSurface APIENTRY
eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->CreatePixmapSurface(drv, dpy, config, pixmap, attrib_list);
}
EGLSurface APIENTRY
eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->CreatePbufferSurface(drv, dpy, config, attrib_list);
}
EGLBoolean APIENTRY
eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->DestroySurface(drv, dpy, surface);
}
EGLBoolean APIENTRY
eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->QuerySurface(drv, dpy, surface, attribute, value);
}
EGLBoolean APIENTRY
eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->SurfaceAttrib(drv, dpy, surface, attribute, value);
}
EGLBoolean APIENTRY
eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->BindTexImage(drv, dpy, surface, buffer);
}
EGLBoolean APIENTRY
eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->ReleaseTexImage(drv, dpy, surface, buffer);
}
EGLBoolean APIENTRY
eglSwapInterval(EGLDisplay dpy, EGLint interval)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->SwapInterval(drv, dpy, interval);
}
EGLBoolean APIENTRY
eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->SwapBuffers(drv, dpy, draw);
}
EGLBoolean APIENTRY
eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->CopyBuffers(drv, dpy, surface, target);
}
EGLBoolean APIENTRY
eglWaitGL(void)
{
EGLDisplay dpy = eglGetCurrentDisplay();
if (dpy != EGL_NO_DISPLAY) {
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->WaitGL(drv, dpy);
}
else
return EGL_FALSE;
}
EGLBoolean APIENTRY
eglWaitNative(EGLint engine)
{
EGLDisplay dpy = eglGetCurrentDisplay();
if (dpy != EGL_NO_DISPLAY) {
_EGLDriver *drv = _eglLookupDriver(dpy);
return drv->WaitNative(drv, dpy, engine);
}
else
return EGL_FALSE;
}
EGLDisplay APIENTRY
eglGetCurrentDisplay(void)
{
_EGLDisplay *dpy = _eglGetCurrentDisplay();
if (dpy)
return dpy->Handle;
else
return EGL_NO_DISPLAY;
}
EGLContext APIENTRY
eglGetCurrentContext(void)
{
_EGLContext *ctx = _eglGetCurrentContext();
if (ctx)
return ctx->Handle;
else
return EGL_NO_CONTEXT;
}
EGLSurface APIENTRY
eglGetCurrentSurface(EGLint readdraw)
{
_EGLSurface *s = _eglGetCurrentSurface(readdraw);
if (s)
return s->Handle;
else
return EGL_NO_SURFACE;
}
EGLint APIENTRY
eglGetError(void)
{
EGLint e = _eglGlobal.LastError;
_eglGlobal.LastError = EGL_SUCCESS;
return e;
}
void (* APIENTRY eglGetProcAddress(const char *procname))()
{
typedef void (*genericFunc)();
struct name_function {
const char *name;
_EGLProc function;
};
static struct name_function egl_functions[] = {
/* alphabetical order */
{ "eglBindTexImage", (_EGLProc) eglBindTexImage },
{ "eglChooseConfig", (_EGLProc) eglChooseConfig },
{ "eglCopyBuffers", (_EGLProc) eglCopyBuffers },
{ "eglCreateContext", (_EGLProc) eglCreateContext },
{ "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface },
{ "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface },
{ "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface },
{ "eglDestroyContext", (_EGLProc) eglDestroyContext },
{ "eglDestroySurface", (_EGLProc) eglDestroySurface },
{ "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib },
{ "eglGetConfigs", (_EGLProc) eglGetConfigs },
{ "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext },
{ "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay },
{ "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface },
{ "eglGetDisplay", (_EGLProc) eglGetDisplay },
{ "eglGetError", (_EGLProc) eglGetError },
{ "eglGetProcAddress", (_EGLProc) eglGetProcAddress },
{ "eglInitialize", (_EGLProc) eglInitialize },
{ "eglMakeCurrent", (_EGLProc) eglMakeCurrent },
{ "eglQueryContext", (_EGLProc) eglQueryContext },
{ "eglQueryString", (_EGLProc) eglQueryString },
{ "eglQuerySurface", (_EGLProc) eglQuerySurface },
{ "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage },
{ "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib },
{ "eglSwapBuffers", (_EGLProc) eglSwapBuffers },
{ "eglSwapInterval", (_EGLProc) eglSwapInterval },
{ "eglTerminate", (_EGLProc) eglTerminate },
{ "eglWaitGL", (_EGLProc) eglWaitGL },
{ "eglWaitNative", (_EGLProc) eglWaitNative },
/* Extensions */
{ "eglShowSurfaceMESA", (_EGLProc) NULL },
{ "eglGetModesMESA", (_EGLProc) NULL },
{ NULL, NULL }
};
EGLint i;
for (i = 0; egl_functions[i].name; i++) {
if (strcmp(egl_functions[i].name, procname) == 0) {
return (genericFunc) egl_functions[i].function;
}
}
#if 0
/* XXX enable this code someday */
return (genericFunc) _glapi_get_proc_address(procname);
#else
return NULL;
#endif
}
/*
* EGL_MESA_screen extension
*/
EGLBoolean APIENTRY
eglChooseModeMESA(EGLDisplay dpy, EGLint screen_number,
const EGLint *attrib_list, EGLModeMESA *modes,
EGLint modes_size, EGLint *num_modes)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
if (drv)
return drv->ChooseModeMESA(drv, dpy, screen_number, attrib_list, modes, modes_size, num_modes);
else
return EGL_FALSE;
}
EGLBoolean APIENTRY
eglGetModesMESA(EGLDisplay dpy, EGLint screen_number, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
if (drv)
return drv->GetModesMESA(drv, dpy, screen_number, modes, mode_size, num_mode);
else
return EGL_FALSE;
}
EGLBoolean APIENTRY
eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value)
{
_EGLDriver *drv = _eglLookupDriver(dpy);
if (drv)
return drv->GetModeAttribMESA(drv, dpy, mode, attribute, value);
else
return EGL_FALSE;
}
EGLSurface
eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
{
return EGL_FALSE;
}
EGLBoolean
eglShowSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface)
{
return EGL_FALSE;
}
EGLBoolean
eglScreenModeMESA(EGLDisplay dpy, EGLint screen_number, EGLModeMESA mode)
{
return EGL_FALSE;
}
EGLBoolean
eglScreenAttribsMESA(EGLDisplay dpy, EGLint screen, const EGLint *attrib_list)
{
return EGL_FALSE;
}
EGLBoolean
eglQueryDisplayMESA(EGLDisplay dpy, EGLint attribute, EGLint *value)
{
return EGL_FALSE;
}
EGLBoolean
eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLint screen_number, EGLSurface *surface)
{
return EGL_FALSE;
}
EGLBoolean
eglQueryScreenModeMESA(EGLDisplay dpy, EGLint screen_number, EGLModeMESA *mode)
{
return EGL_FALSE;
}
EGLBoolean
eglQueryScreenMESA( EGLDisplay dpy, EGLint screen_number, EGLint attribute, EGLint *value)
{
return EGL_FALSE;
}

286
src/egl/main/eglconfig.c Normal file
View File

@ -0,0 +1,286 @@
#include <string.h>
#include <assert.h>
#include "eglconfig.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
#define MIN2(A, B) (((A) < (B)) ? (A) : (B))
/**
* Init the given _EGLconfig to default values.
* \param id the configuration's ID.
*/
void
_eglInitConfig(_EGLConfig *config, EGLint id)
{
memset(config, 0, sizeof(*config));
config->Handle = id;
SET_CONFIG_ATTRIB(config, EGL_CONFIG_ID, id);
SET_CONFIG_ATTRIB(config, EGL_BIND_TO_TEXTURE_RGB, EGL_DONT_CARE);
SET_CONFIG_ATTRIB(config, EGL_BIND_TO_TEXTURE_RGBA, EGL_DONT_CARE);
SET_CONFIG_ATTRIB(config, EGL_CONFIG_CAVEAT, EGL_DONT_CARE);
SET_CONFIG_ATTRIB(config, EGL_NATIVE_RENDERABLE, EGL_DONT_CARE);
SET_CONFIG_ATTRIB(config, EGL_NATIVE_VISUAL_TYPE, EGL_DONT_CARE);
SET_CONFIG_ATTRIB(config, EGL_MIN_SWAP_INTERVAL, EGL_DONT_CARE);
SET_CONFIG_ATTRIB(config, EGL_MAX_SWAP_INTERVAL, EGL_DONT_CARE);
SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
SET_CONFIG_ATTRIB(config, EGL_TRANSPARENT_TYPE, EGL_NONE);
SET_CONFIG_ATTRIB(config, EGL_TRANSPARENT_RED_VALUE, EGL_DONT_CARE);
SET_CONFIG_ATTRIB(config, EGL_TRANSPARENT_GREEN_VALUE, EGL_DONT_CARE);
SET_CONFIG_ATTRIB(config, EGL_TRANSPARENT_BLUE_VALUE, EGL_DONT_CARE);
}
/**
* Given an EGLConfig handle, return the corresponding _EGLConfig object.
*/
_EGLConfig *
_eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config)
{
EGLint i;
_EGLDisplay *disp = _eglLookupDisplay(dpy);
for (i = 0; i < disp->NumConfigs; i++) {
if (disp->Configs[i].Handle == config) {
return disp->Configs + i;
}
}
return NULL;
}
/**
* Parse the attrib_list to fill in the fields of the given _egl_config
* Return EGL_FALSE if any errors, EGL_TRUE otherwise.
*/
EGLBoolean
_eglParseConfigAttribs(_EGLConfig *config, const EGLint *attrib_list)
{
EGLint i;
/* XXX set all config attribs to EGL_DONT_CARE */
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
EGLint k = attrib_list[i] - FIRST_ATTRIB;
if (k >= 0 && k < MAX_ATTRIBS) {
config->Attrib[k] = attrib_list[++i];
}
else {
_eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
return EGL_FALSE;
}
}
return EGL_TRUE;
}
#define EXACT 1
#define ATLEAST 2
#define MASK 3
#define SMALLER 4
#define SPECIAL 5
#define NONE 6
struct sort_info {
EGLint Attribute;
EGLint MatchCriteria;
EGLint SortOrder;
};
/* This encodes the info from Table 3.5 of the EGL spec, ordered by
* Sort Priority.
*/
static struct sort_info SortInfo[] = {
{ EGL_CONFIG_CAVEAT, EXACT, SPECIAL },
{ EGL_RED_SIZE, ATLEAST, SPECIAL },
{ EGL_GREEN_SIZE, ATLEAST, SPECIAL },
{ EGL_BLUE_SIZE, ATLEAST, SPECIAL },
{ EGL_ALPHA_SIZE, ATLEAST, SPECIAL },
{ EGL_BUFFER_SIZE, ATLEAST, SMALLER },
{ EGL_SAMPLE_BUFFERS, ATLEAST, SMALLER },
{ EGL_SAMPLES, ATLEAST, SMALLER },
{ EGL_DEPTH_SIZE, ATLEAST, SMALLER },
{ EGL_STENCIL_SIZE, ATLEAST, SMALLER },
{ EGL_NATIVE_VISUAL_TYPE, EXACT, SPECIAL },
{ EGL_CONFIG_ID, EXACT, SMALLER },
{ EGL_BIND_TO_TEXTURE_RGB, EXACT, NONE },
{ EGL_BIND_TO_TEXTURE_RGBA, EXACT, NONE },
{ EGL_LEVEL, EXACT, NONE },
{ EGL_NATIVE_RENDERABLE, EXACT, NONE },
{ EGL_MAX_SWAP_INTERVAL, EXACT, NONE },
{ EGL_MIN_SWAP_INTERVAL, EXACT, NONE },
{ EGL_SURFACE_TYPE, MASK, NONE },
{ EGL_TRANSPARENT_TYPE, EXACT, NONE },
{ EGL_TRANSPARENT_RED_VALUE, EXACT, NONE },
{ EGL_TRANSPARENT_GREEN_VALUE, EXACT, NONE },
{ EGL_TRANSPARENT_BLUE_VALUE, EXACT, NONE },
{ 0, 0, 0 }
};
/**
* Return EGL_TRUE if the attributes of c meet or exceed the minimums
* specified by min.
*/
EGLBoolean
_eglConfigQualifies(const _EGLConfig *c, const _EGLConfig *min)
{
EGLint i;
for (i = 0; SortInfo[i].Attribute != 0; i++) {
const EGLint mv = GET_CONFIG_ATTRIB(min, SortInfo[i].Attribute);
if (mv != EGL_DONT_CARE) {
const EGLint cv = GET_CONFIG_ATTRIB(c, SortInfo[i].Attribute);
if (SortInfo[i].MatchCriteria == EXACT) {
if (cv != mv) {
return EGL_FALSE;
}
}
else if (SortInfo[i].MatchCriteria == ATLEAST) {
if (cv < mv) {
return EGL_FALSE;
}
}
else {
assert(SortInfo[i].MatchCriteria == MASK);
if ((mv & cv) != mv) {
return EGL_FALSE;
}
}
}
}
return EGL_TRUE;
}
/**
* Compare configs 'a' and 'b' and return -1 if a belongs before b,
* 1 if a belongs after b, or 0 if they're equal.
*/
EGLint
_eglCompareConfigs(const _EGLConfig *a, const _EGLConfig *b)
{
EGLint i;
for (i = 0; SortInfo[i].Attribute != 0; i++) {
const EGLint av = GET_CONFIG_ATTRIB(a, SortInfo[i].Attribute);
const EGLint bv = GET_CONFIG_ATTRIB(b, SortInfo[i].Attribute);
if (SortInfo[i].SortOrder == SMALLER) {
if (av < bv)
return -1;
else if (av > bv)
return 1;
/* else, continue examining attribute values */
}
else if (SortInfo[i].SortOrder == SPECIAL) {
if (SortInfo[i].Attribute == EGL_CONFIG_CAVEAT) {
/* values are EGL_NONE, SLOW_CONFIG, or NON_CONFORMANT_CONFIG */
if (av < bv)
return -1;
else if (av > bv)
return 1;
}
else if (SortInfo[i].Attribute == EGL_RED_SIZE ||
SortInfo[i].Attribute == EGL_GREEN_SIZE ||
SortInfo[i].Attribute == EGL_BLUE_SIZE ||
SortInfo[i].Attribute == EGL_ALPHA_SIZE) {
if (av > bv)
return -1;
else if (av < bv)
return 1;
}
else {
assert(SortInfo[i].Attribute == EGL_NATIVE_VISUAL_TYPE);
if (av < bv)
return -1;
else if (av > bv)
return 1;
}
}
else {
assert(SortInfo[i].SortOrder == NONE);
/* continue examining attribute values */
}
}
return 0;
}
/**
* Typical fallback routine for eglChooseConfig
*/
EGLBoolean
_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
_EGLConfig criteria;
EGLint i;
/* parse the attrib_list to initialize criteria */
if (!_eglParseConfigAttribs(&criteria, attrib_list)) {
return EGL_FALSE;
}
*num_config = 0;
for (i = 0; i < disp->NumConfigs; i++) {
const _EGLConfig *conf = disp->Configs + i;
if (_eglConfigQualifies(conf, &criteria)) {
if (*num_config < config_size) {
/* save */
configs[*num_config] = conf->Handle;
(*num_config)++;
}
else {
break;
}
}
}
/* XXX sort the list here */
return EGL_TRUE;
}
/**
* Fallback for eglGetConfigAttrib.
*/
EGLBoolean
_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
{
const _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
const EGLint k = attribute - FIRST_ATTRIB;
if (k >= 0 && k < MAX_ATTRIBS) {
*value = conf->Attrib[k];
return EGL_TRUE;
}
else {
_eglError(EGL_BAD_ATTRIBUTE, "eglGetConfigAttrib");
return EGL_FALSE;
}
}
/**
* Fallback for eglGetConfigs.
*/
EGLBoolean
_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
if (!drv->Initialized) {
_eglError(EGL_NOT_INITIALIZED, "eglGetConfigs");
return EGL_FALSE;
}
*num_config = MIN2(disp->NumConfigs, config_size);
if (configs) {
EGLint i;
for (i = 0; i < *num_config; i++) {
configs[i] = disp->Configs[i].Handle;
}
}
return EGL_TRUE;
}

56
src/egl/main/eglconfig.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef EGLCONFIG_INCLUDED
#define EGLCONFIG_INCLUDED
#include "egltypedefs.h"
#define MAX_ATTRIBS 100
#define FIRST_ATTRIB EGL_BUFFER_SIZE
struct _egl_config
{
EGLConfig Handle; /* the public/opaque handle which names this config */
EGLint Attrib[MAX_ATTRIBS];
};
#define SET_CONFIG_ATTRIB(CONF, ATTR, VAL) ((CONF)->Attrib[(ATTR) - FIRST_ATTRIB] = VAL)
#define GET_CONFIG_ATTRIB(CONF, ATTR) ((CONF)->Attrib[(ATTR) - FIRST_ATTRIB])
extern void
_eglInitConfig(_EGLConfig *config, EGLint id);
extern _EGLConfig *
_eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config);
extern EGLBoolean
_eglParseConfigAttribs(_EGLConfig *config, const EGLint *attrib_list);
extern EGLBoolean
_eglConfigQualifies(const _EGLConfig *c, const _EGLConfig *min);
extern EGLint
_eglCompareConfigs(const _EGLConfig *a, const _EGLConfig *b);
extern EGLBoolean
_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
extern EGLBoolean
_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
extern EGLBoolean
_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
#endif /* EGLCONFIG_INCLUDED */

226
src/egl/main/eglcontext.c Normal file
View File

@ -0,0 +1,226 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "eglconfig.h"
#include "eglcontext.h"
#include "egldriver.h"
#include "eglglobals.h"
#include "eglhash.h"
#include "eglsurface.h"
/**
* Initialize the given _EGLContext object to defaults.
*/
void
_eglInitContext(_EGLContext *ctx)
{
/* just init to zer for now */
memset(ctx, 0, sizeof(_EGLContext));
}
/*
* Assign an EGLContext handle to the _EGLContext object then put it into
* the hash table.
*/
void
_eglSaveContext(_EGLContext *ctx)
{
assert(ctx);
ctx->Handle = _eglHashGenKey(_eglGlobal.Contexts);
_eglHashInsert(_eglGlobal.Contexts, ctx->Handle, ctx);
}
/**
* Remove the given _EGLContext object from the hash table.
*/
void
_eglRemoveContext(_EGLContext *ctx)
{
_eglHashRemove(_eglGlobal.Contexts, ctx->Handle);
}
/**
* Return the _EGLContext object that corresponds to the given
* EGLContext handle.
*/
_EGLContext *
_eglLookupContext(EGLContext ctx)
{
_EGLContext *c = (_EGLContext *) _eglHashLookup(_eglGlobal.Contexts, ctx);
return c;
}
/**
* Return the currently bound _EGLContext object, or NULL.
*/
_EGLContext *
_eglGetCurrentContext(void)
{
/* XXX this should be per-thread someday */
return _eglGlobal.CurrentContext;
}
/**
* Just a placeholder/demo function. Real driver will never use this!
*/
EGLContext
_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
{
_EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreateContext");
return EGL_NO_CONTEXT;
}
if (share_list != EGL_NO_CONTEXT) {
_EGLContext *shareCtx = _eglLookupContext(share_list);
if (!shareCtx) {
_eglError(EGL_BAD_CONTEXT, "eglCreateContext(share_list)");
return EGL_NO_CONTEXT;
}
}
return EGL_NO_CONTEXT;
}
/**
* Default fallback routine - drivers should usually override this.
*/
EGLBoolean
_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
{
_EGLContext *context = _eglLookupContext(ctx);
if (context) {
_eglHashRemove(_eglGlobal.Contexts, ctx);
if (context->IsBound) {
context->DeletePending = EGL_TRUE;
}
else {
free(context);
}
return EGL_TRUE;
}
else {
_eglError(EGL_BAD_CONTEXT, "eglDestroyContext");
return EGL_TRUE;
}
}
EGLBoolean
_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
{
_EGLContext *c = _eglLookupContext(ctx);
(void) drv;
(void) dpy;
if (!c) {
_eglError(EGL_BAD_CONTEXT, "eglQueryContext");
return EGL_FALSE;
}
switch (attribute) {
case EGL_CONFIG_ID:
*value = GET_CONFIG_ATTRIB(c->Config, EGL_CONFIG_ID);
return EGL_TRUE;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext");
return EGL_FALSE;
}
}
/**
* Drivers will typically call this to do the error checking and
* update the various IsBound and DeletePending flags.
* Then, the driver will do its device-dependent Make-Current stuff.
*/
EGLBoolean
_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, EGLSurface r, EGLContext context)
{
_EGLContext *ctx = _eglLookupContext(context);
_EGLSurface *draw = _eglLookupSurface(d);
_EGLSurface *read = _eglLookupSurface(r);
_EGLContext *oldContext = _eglGetCurrentContext();
_EGLSurface *oldDrawSurface = _eglGetCurrentSurface(EGL_DRAW);
_EGLSurface *oldReadSurface = _eglGetCurrentSurface(EGL_READ);
/* error checking */
if (ctx) {
if (draw == NULL || read == NULL) {
_eglError(EGL_BAD_MATCH, "eglMakeCurrent");
return EGL_FALSE;
}
if (draw->Config != ctx->Config) {
_eglError(EGL_BAD_MATCH, "eglMakeCurrent");
return EGL_FALSE;
}
if (read->Config != ctx->Config) {
_eglError(EGL_BAD_MATCH, "eglMakeCurrent");
return EGL_FALSE;
}
}
/*
* check if the old context or surfaces need to be deleted
*/
if (oldDrawSurface != NULL) {
oldDrawSurface->IsBound = EGL_FALSE;
if (oldDrawSurface->DeletePending) {
/* make sure we don't try to rebind a deleted surface */
if (draw == oldDrawSurface || draw == oldReadSurface) {
draw = NULL;
}
/* really delete surface now */
drv->DestroySurface(drv, dpy, oldDrawSurface->Handle);
}
}
if (oldReadSurface != NULL && oldReadSurface != oldDrawSurface) {
oldReadSurface->IsBound = EGL_FALSE;
if (oldReadSurface->DeletePending) {
/* make sure we don't try to rebind a deleted surface */
if (read == oldDrawSurface || read == oldReadSurface) {
read = NULL;
}
/* really delete surface now */
drv->DestroySurface(drv, dpy, oldReadSurface->Handle);
}
}
if (oldContext != NULL) {
oldContext->IsBound = EGL_FALSE;
if (oldContext->DeletePending) {
/* make sure we don't try to rebind a deleted context */
if (ctx == oldContext) {
ctx = NULL;
}
/* really delete context now */
drv->DestroyContext(drv, dpy, oldContext->Handle);
}
}
if (ctx) {
/* check read/draw again, in case we deleted them above */
if (draw == NULL || read == NULL) {
_eglError(EGL_BAD_MATCH, "eglMakeCurrent");
return EGL_FALSE;
}
ctx->DrawSurface = draw;
ctx->ReadSurface = read;
ctx->IsBound = EGL_TRUE;
draw->IsBound = EGL_TRUE;
read->IsBound = EGL_TRUE;
}
_eglGlobal.CurrentContext = ctx;
return EGL_TRUE;
}

64
src/egl/main/eglcontext.h Normal file
View File

@ -0,0 +1,64 @@
#ifndef EGLCONTEXT_INCLUDED
#define EGLCONTEXT_INCLUDED
#include "egltypedefs.h"
/**
* "Base" class for device driver contexts.
*/
struct _egl_context
{
EGLContext Handle; /* The public/opaque handle which names this object */
_EGLDisplay *Display; /* who do I belong to? */
_EGLConfig *Config;
_EGLSurface *DrawSurface;
_EGLSurface *ReadSurface;
EGLBoolean IsBound;
EGLBoolean DeletePending;
};
extern void
_eglInitContext(_EGLContext *ctx);
extern void
_eglSaveContext(_EGLContext *ctx);
extern void
_eglRemoveContext(_EGLContext *ctx);
extern _EGLContext *
_eglLookupContext(EGLContext ctx);
extern _EGLContext *
_eglGetCurrentContext(void);
extern EGLContext
_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
extern EGLBoolean
_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx);
extern EGLBoolean
_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
extern EGLBoolean
_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
#endif /* EGLCONTEXT_INCLUDED */

71
src/egl/main/egldisplay.c Normal file
View File

@ -0,0 +1,71 @@
#include <stdlib.h>
#include <string.h>
#include "eglcontext.h"
#include "egldisplay.h"
#include "eglglobals.h"
#include "eglhash.h"
static char *
my_strdup(const char *s)
{
int l = strlen(s);
char *s2 = malloc(l + 1);
strcpy(s2, s);
return s2;
}
/**
* We're assuming that the NativeDisplayType parameter is actually
* a string.
* Return a new _EGLDisplay object for the given displayName
*/
_EGLDisplay *
_eglNewDisplay(NativeDisplayType displayName)
{
_EGLDisplay *dpy = (_EGLDisplay *) malloc(sizeof(_EGLDisplay));
if (dpy) {
dpy->Handle = _eglHashGenKey(_eglGlobal.Displays);
_eglHashInsert(_eglGlobal.Displays, dpy->Handle, dpy);
if (displayName)
dpy->Name = my_strdup(displayName);
else
dpy->Name = NULL;
dpy->Driver = NULL; /* this gets set later */
}
return dpy;
}
/**
* Return the _EGLDisplay object that corresponds to the given public/
* opaque display handle.
*/
_EGLDisplay *
_eglLookupDisplay(EGLDisplay dpy)
{
_EGLDisplay *d = (_EGLDisplay *) _eglHashLookup(_eglGlobal.Displays, dpy);
return d;
}
_EGLDisplay *
_eglGetCurrentDisplay(void)
{
_EGLContext *ctx = _eglGetCurrentContext();
if (ctx)
return ctx->Display;
else
return NULL;
}
void
_eglDeleteDisplay(_EGLDisplay *disp)
{
/* XXX incomplete */
free(disp->Configs);
free(disp);
}

39
src/egl/main/egldisplay.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef EGLDISPLAY_INCLUDED
#define EGLDISPLAY_INCLUDED
#include "egltypedefs.h"
struct _egl_display
{
EGLDisplay Handle;
char *Name;
_EGLDriver *Driver;
EGLint NumScreens;
_EGLScreen *Screens; /* array [NumScreens] */
EGLint NumConfigs;
_EGLConfig *Configs; /* array [NumConfigs] */
};
extern _EGLDisplay *
_eglNewDisplay(NativeDisplayType displayName);
extern _EGLDisplay *
_eglLookupDisplay(EGLDisplay dpy);
extern _EGLDisplay *
_eglGetCurrentDisplay(void);
extern void
_eglDeleteDisplay(_EGLDisplay *disp);
#endif /* EGLDISPLAY_INCLUDED */

226
src/egl/main/egldriver.c Normal file
View File

@ -0,0 +1,226 @@
#include <assert.h>
#include <dlfcn.h>
#include <stdio.h>
#include <string.h>
#include "eglconfig.h"
#include "eglcontext.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
#include "eglmode.h"
#include "eglsurface.h"
const char *DefaultDriverName = "demo";
/**
* Choose and open/init the hardware driver for the given EGLDisplay.
* Previously, the EGLDisplay was created with _eglNewDisplay() where
* we recorded the user's NativeDisplayType parameter.
*
* Now we'll use the NativeDisplayType value.
*
* Currently, the native display value is treated as a string.
* If the first character is ':' we interpret it as a screen or card index
* number (i.e. ":0" or ":1", etc)
* Else if the first character is '!' we interpret it as specific driver name
* (i.e. "!r200" or "!i830".
*/
_EGLDriver *
_eglChooseDriver(EGLDisplay display)
{
_EGLDisplay *dpy = _eglLookupDisplay(display);
_EGLDriver *drv;
const char *driverName = DefaultDriverName;
const char *name;
assert(dpy);
name = dpy->Name;
if (!name) {
/* use default */
}
else if (name[0] == ':' && (name[1] >= '0' && name[1] <= '9') && !name[2]) {
printf("EGL: Use driver for screen: %s\n", name);
/* XXX probe hardware here to determine which driver to open */
/* driverName = "something"; */
}
else if (name[0] == '!') {
/* use specified driver name */
driverName = name + 1;
printf("EGL: Use driver named %s\n", driverName);
}
else {
/* Maybe display was returned by XOpenDisplay? */
printf("EGL: can't parse display pointer\n");
}
drv = _eglOpenDriver(dpy, driverName);
dpy->Driver = drv;
return drv;
}
/**
* Open/load the named driver and call its bootstrap function: _eglMain().
* \return new _EGLDriver object.
*/
_EGLDriver *
_eglOpenDriver(_EGLDisplay *dpy, const char *driverName)
{
void *lib;
char driverFilename[1000];
/* XXX also prepend a directory path??? */
sprintf(driverFilename, "%sdriver.so", driverName);
#if 1
lib = dlopen(driverFilename, RTLD_NOW);
if (lib) {
_EGLDriver *drv;
_EGLMain_t mainFunc;
mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
if (!mainFunc) {
fprintf(stderr, "_eglMain not found in %s", (char *) driverFilename);
dlclose(lib);
return NULL;
}
drv = mainFunc(dpy);
if (!drv) {
dlclose(lib);
return NULL;
}
drv->LibHandle = lib;
drv->Display = dpy;
return drv;
}
else {
fprintf(stderr, "EGLdebug: Error opening %s: %s\n",
driverFilename, dlerror());
return NULL;
}
#else
/* use built-in driver */
return _eglDefaultMain(d);
#endif
}
EGLBoolean
_eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy)
{
void *handle = drv->LibHandle;
EGLBoolean b;
fprintf(stderr, "EGL debug: Closing driver\n");
/*
* XXX check for currently bound context/surfaces and delete them?
*/
b = drv->Terminate(drv, dpy);
dlclose(handle);
return b;
}
/**
* Given a display handle, return the _EGLDriver for that display.
*/
_EGLDriver *
_eglLookupDriver(EGLDisplay dpy)
{
_EGLDisplay *d = _eglLookupDisplay(dpy);
if (d)
return d->Driver;
else
return NULL;
}
/**
* Plug all the available fallback routines into the given driver's
* dispatch table.
*/
void
_eglInitDriverFallbacks(_EGLDriver *drv)
{
/* If a pointer is set to NULL, then the device driver _really_ has
* to implement it.
*/
drv->Initialize = NULL;
drv->Terminate = NULL;
drv->GetConfigs = _eglGetConfigs;
drv->ChooseConfig = _eglChooseConfig;
drv->GetConfigAttrib = _eglGetConfigAttrib;
drv->CreateContext = _eglCreateContext;
drv->DestroyContext = _eglDestroyContext;
drv->MakeCurrent = _eglMakeCurrent;
drv->QueryContext = _eglQueryContext;
drv->CreateWindowSurface = _eglCreateWindowSurface;
drv->CreatePixmapSurface = _eglCreatePixmapSurface;
drv->CreatePbufferSurface = _eglCreatePbufferSurface;
drv->DestroySurface = _eglDestroySurface;
drv->QuerySurface = _eglQuerySurface;
drv->SurfaceAttrib = _eglSurfaceAttrib;
drv->BindTexImage = _eglBindTexImage;
drv->ReleaseTexImage = _eglReleaseTexImage;
drv->SwapInterval = _eglSwapInterval;
drv->SwapBuffers = _eglSwapBuffers;
drv->CopyBuffers = _eglCopyBuffers;
drv->QueryString = _eglQueryString;
drv->WaitGL = _eglWaitGL;
drv->WaitNative = _eglWaitNative;
/* EGL_MESA_screen */
drv->GetModesMESA = _eglGetModesMESA;
drv->GetModeAttribMESA = _eglGetModeAttribMESA;
}
const char *
_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
{
(void) drv;
(void) dpy;
switch (name) {
case EGL_VENDOR:
return "Mesa Project";
case EGL_VERSION:
return "1.0";
case EGL_EXTENSIONS:
return "";
default:
_eglError(EGL_BAD_PARAMETER, "eglQueryString");
return NULL;
}
}
EGLBoolean
_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy)
{
/* just a placeholder */
(void) drv;
(void) dpy;
return EGL_TRUE;
}
EGLBoolean
_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine)
{
/* just a placeholder */
(void) drv;
(void) dpy;
(void) engine;
return EGL_TRUE;
}

141
src/egl/main/egldriver.h Normal file
View File

@ -0,0 +1,141 @@
#ifndef EGLDRIVER_INCLUDED
#define EGLDRIVER_INCLUDED
#include "egltypedefs.h"
/* driver funcs */
typedef EGLBoolean (*Initialize_t)(_EGLDriver *, EGLDisplay dpy, EGLint *major, EGLint *minor);
typedef EGLBoolean (*Terminate_t)(_EGLDriver *, EGLDisplay dpy);
/* config funcs */
typedef EGLBoolean (*GetConfigs_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
typedef EGLBoolean (*ChooseConfig_t)(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
typedef EGLBoolean (*GetConfigAttrib_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
/* context funcs */
typedef EGLContext (*CreateContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
typedef EGLBoolean (*DestroyContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx);
typedef EGLBoolean (*MakeCurrent_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
typedef EGLBoolean (*QueryContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
/* surface funcs */
typedef EGLSurface (*CreateWindowSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
typedef EGLSurface (*CreatePixmapSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list);
typedef EGLSurface (*CreatePbufferSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
typedef EGLBoolean (*DestroySurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface);
typedef EGLBoolean (*QuerySurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
typedef EGLBoolean (*SurfaceAttrib_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
typedef EGLBoolean (*BindTexImage_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
typedef EGLBoolean (*ReleaseTexImage_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
typedef EGLBoolean (*SwapInterval_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint interval);
typedef EGLBoolean (*SwapBuffers_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);
typedef EGLBoolean (*CopyBuffers_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target);
/* misc funcs */
typedef const char *(*QueryString_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint name);
typedef EGLBoolean (*WaitGL_t)(_EGLDriver *drv, EGLDisplay dpy);
typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint engine);
/* EGL_MESA_screen extension */
typedef EGLBoolean (*ChooseModeMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
typedef EGLBoolean (*GetModesMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode);
typedef EGLBoolean (*GetModeAttribMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
/**
* Base class for device drivers.
*/
struct _egl_driver
{
EGLBoolean Initialized; /* set by driver after initialized */
void *LibHandle; /* dlopen handle */
_EGLDisplay *Display;
int ABIversion;
int APImajor, APIminor; /* returned through eglInitialize */
/*
* The API dispatcher jumps through these functions
*/
Initialize_t Initialize;
Terminate_t Terminate;
GetConfigs_t GetConfigs;
ChooseConfig_t ChooseConfig;
GetConfigAttrib_t GetConfigAttrib;
CreateContext_t CreateContext;
DestroyContext_t DestroyContext;
MakeCurrent_t MakeCurrent;
QueryContext_t QueryContext;
CreateWindowSurface_t CreateWindowSurface;
CreatePixmapSurface_t CreatePixmapSurface;
CreatePbufferSurface_t CreatePbufferSurface;
DestroySurface_t DestroySurface;
QuerySurface_t QuerySurface;
SurfaceAttrib_t SurfaceAttrib;
BindTexImage_t BindTexImage;
ReleaseTexImage_t ReleaseTexImage;
SwapInterval_t SwapInterval;
SwapBuffers_t SwapBuffers;
CopyBuffers_t CopyBuffers;
QueryString_t QueryString;
WaitGL_t WaitGL;
WaitNative_t WaitNative;
/* EGL_MESA_screen extension */
ChooseModeMESA_t ChooseModeMESA;
GetModesMESA_t GetModesMESA;
GetModeAttribMESA_t GetModeAttribMESA;
};
extern _EGLDriver *
_eglDefaultMain(NativeDisplayType d);
extern _EGLDriver *
_eglChooseDriver(EGLDisplay dpy);
extern _EGLDriver *
_eglOpenDriver(_EGLDisplay *dpy, const char *driverName);
extern EGLBoolean
_eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy);
extern _EGLDriver *
_eglLookupDriver(EGLDisplay d);
extern void
_eglInitDriverFallbacks(_EGLDriver *drv);
extern const char *
_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name);
extern EGLBoolean
_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy);
extern EGLBoolean
_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine);
#endif /* EGLDRIVER_INCLUDED */

51
src/egl/main/eglglobals.c Normal file
View File

@ -0,0 +1,51 @@
#include <stdio.h>
#include "eglglobals.h"
struct _egl_global _eglGlobal = { EGL_FALSE };
/**
* Init the fields in the _eglGlobal struct
* May be safely called more than once.
*/
void
_eglInitGlobals(void)
{
if (!_eglGlobal.Initialized) {
_eglGlobal.Displays = _eglNewHashTable();
_eglGlobal.Contexts = _eglNewHashTable();
_eglGlobal.Surfaces = _eglNewHashTable();
_eglGlobal.CurrentContext = EGL_NO_CONTEXT;
_eglGlobal.LastError = EGL_SUCCESS;
_eglGlobal.Initialized = EGL_TRUE;
}
}
/**
* Should call this via an atexit handler.
*/
void
_eglDestroyGlobals(void)
{
/* XXX TODO walk over table entries, deleting each */
_eglDeleteHashTable(_eglGlobal.Displays);
_eglDeleteHashTable(_eglGlobal.Contexts);
_eglDeleteHashTable(_eglGlobal.Surfaces);
}
/**
* Record EGL error code.
*/
void
_eglError(EGLint errCode, const char *msg)
{
if (_eglGlobal.LastError == EGL_SUCCESS) {
_eglGlobal.LastError = errCode;
/* XXX temporary */
fprintf(stderr, "EGL Error 0x%x in %s\n", errCode, msg);
}
}

38
src/egl/main/eglglobals.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef EGLGLOBALS_INCLUDED
#define EGLGLOBALS_INCLUDED
#include "egltypedefs.h"
#include "eglhash.h"
struct _egl_global
{
EGLBoolean Initialized;
_EGLHashtable *Displays;
_EGLHashtable *Contexts;
_EGLHashtable *Surfaces;
EGLint LastError;
/* XXX this should be per-thread someday */
_EGLContext *CurrentContext;
};
extern struct _egl_global _eglGlobal;
extern void
_eglInitGlobals(void);
extern void
_eglDestroyGlobals(void);
extern void
_eglError(EGLint errCode, const char *msg);
#endif /* EGLGLOBALS_INCLUDED */

347
src/egl/main/eglhash.c Normal file
View File

@ -0,0 +1,347 @@
/**
* \file hash.c
* Generic hash table.
*
* This code taken from Mesa and adapted.
*/
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "eglhash.h"
#define TABLE_SIZE 1023 /**< Size of lookup table/array */
#define HASH_FUNC(K) ((K) % TABLE_SIZE)
/*
* Unfinished mutex stuff
*/
typedef int _EGLMutex;
static void
_eglInitMutex(_EGLMutex m)
{
}
static void
_eglDestroyMutex(_EGLMutex m)
{
}
static void
_eglLockMutex(_EGLMutex m)
{
}
static void
_eglUnlockMutex(_EGLMutex m)
{
}
typedef struct _egl_hashentry _EGLHashentry;
struct _egl_hashentry
{
EGLuint Key; /**< the entry's key */
void *Data; /**< the entry's data */
_EGLHashentry *Next; /**< pointer to next entry */
};
struct _egl_hashtable
{
_EGLHashentry *Table[TABLE_SIZE]; /**< the lookup table */
EGLuint MaxKey; /**< highest key inserted so far */
_EGLMutex Mutex; /**< mutual exclusion lock */
};
/**
* Create a new hash table.
*
* \return pointer to a new, empty hash table.
*/
_EGLHashtable *
_eglNewHashTable(void)
{
_EGLHashtable *table = (_EGLHashtable *) calloc(1, sizeof(_EGLHashtable));
if (table) {
_eglInitMutex(table->Mutex);
table->MaxKey = 1;
}
return table;
}
/**
* Delete a hash table.
* Frees each entry on the hash table and then the hash table structure itself.
* Note that the caller should have already traversed the table and deleted
* the objects in the table (i.e. We don't free the entries' data pointer).
*
* \param table the hash table to delete.
*/
void
_eglDeleteHashTable(_EGLHashtable *table)
{
EGLuint i;
assert(table);
for (i = 0; i < TABLE_SIZE; i++) {
_EGLHashentry *entry = table->Table[i];
while (entry) {
_EGLHashentry *next = entry->Next;
free(entry);
entry = next;
}
}
_eglDestroyMutex(table->Mutex);
free(table);
}
/**
* Lookup an entry in the hash table.
*
* \param table the hash table.
* \param key the key.
*
* \return pointer to user's data or NULL if key not in table
*/
void *
_eglHashLookup(const _EGLHashtable *table, EGLuint key)
{
EGLuint pos;
const _EGLHashentry *entry;
assert(table);
if (!key)
return NULL;
pos = HASH_FUNC(key);
entry = table->Table[pos];
while (entry) {
if (entry->Key == key) {
return entry->Data;
}
entry = entry->Next;
}
return NULL;
}
/**
* Insert a key/pointer pair into the hash table.
* If an entry with this key already exists we'll replace the existing entry.
*
* \param table the hash table.
* \param key the key (not zero).
* \param data pointer to user data.
*/
void
_eglHashInsert(_EGLHashtable *table, EGLuint key, void *data)
{
/* search for existing entry with this key */
EGLuint pos;
_EGLHashentry *entry;
assert(table);
assert(key);
_eglLockMutex(table->Mutex);
if (key > table->MaxKey)
table->MaxKey = key;
pos = HASH_FUNC(key);
entry = table->Table[pos];
while (entry) {
if (entry->Key == key) {
/* replace entry's data */
entry->Data = data;
_eglUnlockMutex(table->Mutex);
return;
}
entry = entry->Next;
}
/* alloc and insert new table entry */
entry = (_EGLHashentry *) malloc(sizeof(_EGLHashentry));
entry->Key = key;
entry->Data = data;
entry->Next = table->Table[pos];
table->Table[pos] = entry;
_eglUnlockMutex(table->Mutex);
}
/**
* Remove an entry from the hash table.
*
* \param table the hash table.
* \param key key of entry to remove.
*
* While holding the hash table's lock, searches the entry with the matching
* key and unlinks it.
*/
void
_eglHashRemove(_EGLHashtable *table, EGLuint key)
{
EGLuint pos;
_EGLHashentry *entry, *prev;
assert(table);
assert(key);
_eglLockMutex(table->Mutex);
pos = HASH_FUNC(key);
prev = NULL;
entry = table->Table[pos];
while (entry) {
if (entry->Key == key) {
/* found it! */
if (prev) {
prev->Next = entry->Next;
}
else {
table->Table[pos] = entry->Next;
}
free(entry);
_eglUnlockMutex(table->Mutex);
return;
}
prev = entry;
entry = entry->Next;
}
_eglUnlockMutex(table->Mutex);
}
/**
* Get the key of the "first" entry in the hash table.
*
* This is used in the course of deleting all display lists when
* a context is destroyed.
*
* \param table the hash table
*
* \return key for the "first" entry in the hash table.
*
* While holding the lock, walks through all table positions until finding
* the first entry of the first non-empty one.
*/
EGLuint
_eglHashFirstEntry(_EGLHashtable *table)
{
EGLuint pos;
assert(table);
_eglLockMutex(table->Mutex);
for (pos = 0; pos < TABLE_SIZE; pos++) {
if (table->Table[pos]) {
_eglUnlockMutex(table->Mutex);
return table->Table[pos]->Key;
}
}
_eglUnlockMutex(table->Mutex);
return 0;
}
/**
* Given a hash table key, return the next key. This is used to walk
* over all entries in the table. Note that the keys returned during
* walking won't be in any particular order.
* \return next hash key or 0 if end of table.
*/
EGLuint
_eglHashNextEntry(const _EGLHashtable *table, EGLuint key)
{
const _EGLHashentry *entry;
EGLuint pos;
assert(table);
assert(key);
/* Find the entry with given key */
pos = HASH_FUNC(key);
entry = table->Table[pos];
while (entry) {
if (entry->Key == key) {
break;
}
entry = entry->Next;
}
if (!entry) {
/* the key was not found, we can't find next entry */
return 0;
}
if (entry->Next) {
/* return next in linked list */
return entry->Next->Key;
}
else {
/* look for next non-empty table slot */
pos++;
while (pos < TABLE_SIZE) {
if (table->Table[pos]) {
return table->Table[pos]->Key;
}
pos++;
}
return 0;
}
}
/**
* Dump contents of hash table for debugging.
*
* \param table the hash table.
*/
void
_eglHashPrint(const _EGLHashtable *table)
{
EGLuint i;
assert(table);
for (i = 0; i < TABLE_SIZE; i++) {
const _EGLHashentry *entry = table->Table[i];
while (entry) {
printf("%u %p\n", entry->Key, entry->Data);
entry = entry->Next;
}
}
}
/**
* Return a new, unused hash key.
*/
EGLuint
_eglHashGenKey(_EGLHashtable *table)
{
EGLuint k;
_eglLockMutex(table->Mutex);
k = table->MaxKey;
table->MaxKey++;
_eglUnlockMutex(table->Mutex);
return k;
}

39
src/egl/main/eglhash.h Normal file
View File

@ -0,0 +1,39 @@
/**
* \file eglhash.h
* Generic hash table.
*/
#ifndef EGLHASH_INCLUDED
#define EGLHASH_INCLUDED
/* XXX move this? */
typedef unsigned int EGLuint;
typedef struct _egl_hashtable _EGLHashtable;
extern _EGLHashtable *_eglNewHashTable(void);
extern void _eglDeleteHashTable(_EGLHashtable *table);
extern void *_eglHashLookup(const _EGLHashtable *table, EGLuint key);
extern void _eglHashInsert(_EGLHashtable *table, EGLuint key, void *data);
extern void _eglHashRemove(_EGLHashtable *table, EGLuint key);
extern EGLuint _eglHashFirstEntry(_EGLHashtable *table);
extern EGLuint _eglHashNextEntry(const _EGLHashtable *table, EGLuint key);
extern void _eglHashPrint(const _EGLHashtable *table);
extern EGLuint _eglHashGenKey(_EGLHashtable *table);
extern void _egltest_hash_functions(void);
#endif /* EGLHASH_INCLUDED */

130
src/egl/main/eglmode.c Normal file
View File

@ -0,0 +1,130 @@
#include "egldisplay.h"
#include "egldriver.h"
#include "eglmode.h"
#include "eglglobals.h"
#include "eglscreen.h"
#define MIN2(A, B) (((A) < (B)) ? (A) : (B))
_EGLMode *
_eglLookupMode(EGLDisplay dpy, EGLModeMESA mode)
{
const _EGLDisplay *disp = _eglLookupDisplay(dpy);
EGLint scrnum;
for (scrnum = 0; scrnum < disp->NumScreens; scrnum++) {
const _EGLScreen *scrn = disp->Screens + scrnum;
EGLint i;
for (i = 0; i < scrn->NumModes; i++) {
if (scrn->Modes[i].Handle == mode) {
return scrn->Modes + i;
}
}
}
return NULL;
}
/**
* Search for the EGLMode that best matches the given attribute list.
*/
EGLBoolean
_eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number,
const EGLint *attrib_list, EGLModeMESA *modes,
EGLint modes_size, EGLint *num_modes)
{
EGLint i;
/* XXX incomplete */
for (i = 0; attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
case EGL_WIDTH:
i++;
break;
case EGL_HEIGHT:
i++;
break;
case EGL_REFRESH_RATE_MESA:
i++;
break;
#if 0
case EGL_STEREO_MESA:
i++;
break;
#endif
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglChooseMode");
return EGL_FALSE;
}
}
return EGL_TRUE;
}
/**
* Return all possible modes for the given screen
*/
EGLBoolean
_eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number,
EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes)
{
_EGLScreen *scrn = _eglLookupScreen(dpy, screen_number);
EGLint i;
if (!scrn) {
_eglError(EGL_BAD_SCREEN_MESA, "eglGetModes");
return EGL_FALSE;
}
*num_modes = MIN2(modes_size, scrn->NumModes);
for (i = 0; i < *num_modes; i++) {
modes[i] = scrn->Modes[i].Handle;
}
return EGL_TRUE;
}
/**
* Query an attribute of a mode.
*/
EGLBoolean
_eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy,
EGLModeMESA mode, EGLint attribute, EGLint *value)
{
_EGLMode *m = _eglLookupMode(dpy, mode);
switch (attribute) {
case EGL_MODE_ID_MESA:
*value = m->Handle;
break;
case EGL_WIDTH:
*value = m->Width;
break;
case EGL_HEIGHT:
*value = m->Height;
break;
#if 0
case EGL_DEPTH_MESA:
*value = m->Depth;
break;
#endif
case EGL_REFRESH_RATE_MESA:
*value = m->RefreshRate;
break;
#if 0
case EGL_STEREO_MESA:
*value = m->Stereo;
break;
#endif
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglGetModeAttrib");
return EGL_FALSE;
}
return EGL_TRUE;
}

41
src/egl/main/eglmode.h Normal file
View File

@ -0,0 +1,41 @@
#ifndef EGLMODE_INCLUDED
#define EGLMODE_INCLUDED
#include "egltypedefs.h"
struct _egl_mode
{
EGLConfig Handle; /* the public/opaque handle which names this mode */
EGLint Width, Height; /* size in pixels */
EGLint Depth; /* bits per pixel */
EGLint RefreshRate; /* rate * 1000.0 */
EGLBoolean Stereo;
/* Other possible attributes */
/* interlaced */
/* external sync */
};
extern _EGLMode *
_eglLookupMode(EGLDisplay dpy, EGLModeMESA mode);
extern EGLBoolean
_eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number,
const EGLint *attrib_list, EGLModeMESA *modes,
EGLint modes_size, EGLint *num_modes);
extern EGLBoolean
_eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number,
EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
extern EGLBoolean
_eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode,
EGLint attribute, EGLint *value);
#endif /* EGLMODE_INCLUDED */

259
src/egl/main/eglscreen.c Normal file
View File

@ -0,0 +1,259 @@
/*
* Ideas for screen management extension to EGL.
*
* Each EGLDisplay has one or more screens (CRTs, Flat Panels, etc).
* The number of screens can be queried with eglQueryDisplay(EGL_SCREEN_COUNT).
*
* A new kind of EGLSurface is possible- one which can be directly scanned
* out on a screen. Such a surface is created with eglCreateScreenSurface().
*
* To actually display a screen surface on a screen, the eglShowSurface()
* function is called.
*
*/
#include <assert.h>
#include <stdlib.h>
#include "egldisplay.h"
#include "eglglobals.h"
#include "eglmode.h"
#include "eglsurface.h"
#include "eglscreen.h"
_EGLScreen *
_eglLookupScreen(EGLDisplay dpy, GLint screenNumber)
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
if (!disp || screenNumber < 0 || screenNumber >= disp->NumScreens) {
return NULL;
}
else {
return disp->Screens + screenNumber;
}
}
/**
* Create a drawing surface which can be directly displayed on a screen.
*/
EGLSurface
_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
{
_EGLSurface *surf;
EGLint width = 0, height = 0;
EGLint i;
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;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreateScreenSurfaceMESA");
return EGL_NO_SURFACE;
}
}
if (width <= 0 || height <= 0) {
_eglError(EGL_BAD_ATTRIBUTE,
"eglCreateScreenSurfaceMESA(width or height)");
return EGL_NO_SURFACE;
}
surf = (_EGLSurface *) malloc(sizeof(_EGLSurface));
_eglInitSurface(surf);
surf->Width = width;
surf->Height = height;
surf->Type = EGL_SCREEN_BIT_MESA;
/* insert into hash table */
_eglSaveSurface(surf);
assert(surf->Handle);
return surf->Handle;
}
/**
* Show the given surface on the named screen.
* If surface is EGL_NO_SURFACE, disable the screen's output.
*
* This is just a placeholder function; drivers will always override
* this with code that _really_ shows the surface.
*/
EGLBoolean
_eglShowSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number,
EGLSurface surface)
{
_EGLScreen *scrn = _eglLookupScreen(dpy, screen_number);
_EGLMode *mode;
if (!scrn) {
_eglError(EGL_BAD_SCREEN_MESA, "eglShowSurfaceMESA");
return EGL_FALSE;
}
/*
* XXX: Check if the surface's configuration is compatible with the
* current screen mode.
*/
mode = scrn->CurrentMode;
if (mode == EGL_NO_MODE_MESA) {
_eglError(EGL_BAD_MODE_MESA, "eglShowSurfaceMESA(no current mode)");
return EGL_FALSE;
}
if (surface == EGL_NO_SURFACE) {
scrn->CurrentSurface = NULL;
}
else {
_EGLSurface *surf = _eglLookupSurface(surface);
if (!surf || surf->Type != EGL_SCREEN_BIT_MESA) {
_eglError(EGL_BAD_SURFACE, "eglShowSurfaceMESA");
return EGL_FALSE;
}
if (surf->Width < mode->Width || surf->Height < mode->Height) {
_eglError(EGL_BAD_SURFACE,
"eglShowSurfaceMESA(surface smaller than screen size)");
return EGL_FALSE;
}
scrn->CurrentSurface = surf;
}
return EGL_TRUE;
}
/**
* Set a screen's current display mode.
* Note: mode = EGL_NO_MODE is valid (turns off the screen)
*
* This is just a placeholder function; drivers will always override
* this with code that _really_ sets the mode.
*/
EGLBoolean
_eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number,
EGLModeMESA mode)
{
_EGLScreen *scrn = _eglLookupScreen(dpy, screen_number);
if (!scrn) {
_eglError(EGL_BAD_SCREEN_MESA, "eglScreenModeMESA");
return EGL_FALSE;
}
scrn->CurrentMode = _eglLookupMode(dpy, mode);
return EGL_TRUE;
}
/**
* Set a screen's surface origin.
*/
EGLBoolean
_eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy,
EGLint screen_number, EGLint x, EGLint y)
{
_EGLScreen *scrn = _eglLookupScreen(dpy, screen_number);
if (!scrn) {
_eglError(EGL_BAD_SCREEN_MESA, "eglScreenPositionMESA");
return EGL_FALSE;
}
scrn->OriginX = x;
scrn->OriginY = y;
return EGL_TRUE;
}
EGLBoolean
_eglQueryDisplayMESA(_EGLDriver *drv, EGLDisplay dpy,
EGLint attribute, EGLint *value)
{
const _EGLDisplay *display = _eglLookupDisplay(dpy);
switch (attribute) {
case EGL_SCREEN_COUNT_MESA:
*value = display->NumScreens;
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglQueryDisplayMESA");
return EGL_FALSE;
}
return EGL_TRUE;
}
/**
* Query a screen's current surface.
*/
EGLBoolean
_eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
EGLint screen_number, EGLSurface *surface)
{
const _EGLScreen *scrn = _eglLookupScreen(dpy, screen_number);
if (scrn->CurrentSurface)
*surface = scrn->CurrentSurface->Handle;
else
*surface = EGL_NO_SURFACE;
return EGL_TRUE;
}
/**
* Query a screen's current mode.
*/
EGLBoolean
_eglQueryScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number,
EGLModeMESA *mode)
{
const _EGLScreen *scrn = _eglLookupScreen(dpy, screen_number);
if (scrn->CurrentMode)
*mode = scrn->CurrentMode->Handle;
else
*mode = EGL_NO_MODE_MESA;
return EGL_TRUE;
}
EGLBoolean
_eglQueryScreenMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number,
EGLint attribute, EGLint *value)
{
const _EGLScreen *scrn = _eglLookupScreen(dpy, screen_number);
if (!scrn) {
_eglError(EGL_BAD_SCREEN_MESA, "eglQueryScreenMESA");
return EGL_FALSE;
}
switch (attribute) {
case EGL_SCREEN_POSITION_MESA:
value[0] = scrn->OriginX;
value[1] = scrn->OriginY;
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglQueryScreenMESA");
return EGL_FALSE;
}
return EGL_TRUE;
}
void
_eglDeleteScreen(_EGLScreen *scrn)
{
free(scrn->Modes);
free(scrn);
}

61
src/egl/main/eglscreen.h Normal file
View File

@ -0,0 +1,61 @@
#ifndef EGLSCREEN_INCLUDED
#define EGLSCREEN_INCLUDED
/* NOTE: there is no public EGLScreen type, we refers to screens with
* an integer.
*/
struct _egl_screen
{
_EGLMode *CurrentMode;
_EGLSurface *CurrentSurface;
EGLint OriginX, OriginY;
EGLint NumModes;
_EGLMode *Modes; /* array [NumModes] */
};
extern _EGLScreen *
_eglLookupScreen(EGLDisplay dpy, GLint screenNumber);
extern EGLSurface
_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
extern EGLBoolean
_eglShowSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen, EGLSurface surface);
extern EGLBoolean
_eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number, EGLModeMESA mode);
extern EGLBoolean
_eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number, EGLint x, EGLint y);
extern EGLBoolean
_eglQueryDisplayMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint attribute, EGLint *value);
extern EGLBoolean
_eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
EGLint screen_number, EGLSurface *surface);
extern EGLBoolean
_eglQueryScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number, EGLModeMESA *mode);
extern EGLBoolean
_eglQueryScreenMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint screen_number, EGLint attribute, EGLint *value);
extern void
_eglDeleteScreen(_EGLScreen *scrn);
#endif /* EGLSCREEN_INCLUDED */

246
src/egl/main/eglsurface.c Normal file
View File

@ -0,0 +1,246 @@
/**
* 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;
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;
}

96
src/egl/main/eglsurface.h Normal file
View File

@ -0,0 +1,96 @@
#ifndef EGLSURFACE_INCLUDED
#define EGLSURFACE_INCLUDED
#include "egltypedefs.h"
/**
* "Base" class for device driver surfaces.
*/
struct _egl_surface
{
EGLSurface Handle; /* The public/opaque handle which names this object */
_EGLConfig *Config;
/* May need reference counting here */
EGLBoolean IsBound;
EGLBoolean DeletePending;
EGLint Type; /* one of EGL_WINDOW_BIT, EGL_PIXMAP_BIT or EGL_PBUFFER_BIT */
EGLint Width, Height;
EGLint TextureFormat, TextureTarget;
EGLint MipmapTexture, MipmapLevel;
EGLint SwapInterval;
/* If type == EGL_SCREEN_BIT: */
EGLint VisibleRefCount; /* number of screens I'm displayed on */
};
extern void
_eglInitSurface(_EGLSurface *surf);
extern void
_eglSaveSurface(_EGLSurface *surf);
extern void
_eglRemoveSurface(_EGLSurface *surf);
extern _EGLSurface *
_eglLookupSurface(EGLSurface surf);
extern _EGLSurface *
_eglGetCurrentSurface(EGLint readdraw);
extern EGLBoolean
_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);
extern EGLBoolean
_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target);
extern EGLBoolean
_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
extern EGLSurface
_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
extern EGLSurface
_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list);
extern EGLSurface
_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
extern EGLBoolean
_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface);
extern EGLBoolean
_eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
extern EGLBoolean
_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
extern EGLBoolean
_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
extern EGLBoolean
_eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval);
#endif /* EGLSURFACE_INCLUDED */

View File

@ -0,0 +1,28 @@
#ifndef EGLTYPEDEFS_INCLUDED
#define EGLTYPEDEFS_INCLUDED
#include <GL/egl.h>
typedef struct _egl_config _EGLConfig;
typedef struct _egl_context _EGLContext;
typedef struct _egl_display _EGLDisplay;
typedef struct _egl_driver _EGLDriver;
typedef struct _egl_mode _EGLMode;
typedef struct _egl_screen _EGLScreen;
typedef struct _egl_surface _EGLSurface;
typedef void (*_EGLProc)();
typedef _EGLDriver *(*_EGLMain_t)(_EGLDisplay *dpy);
#endif /* EGLTYPEDEFS_INCLUDED */