initial EGL code
This commit is contained in:
parent
a661654a33
commit
adbff7e977
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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 */
|
|
@ -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;
|
||||||
|
}
|
|
@ -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 */
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
|
@ -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;
|
||||||
|
}
|
|
@ -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 */
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 */
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
|
@ -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;
|
||||||
|
}
|
|
@ -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 */
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
|
@ -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 */
|
Loading…
Reference in New Issue