diff options
Diffstat (limited to 'src/egl')
28 files changed, 612 insertions, 757 deletions
diff --git a/src/egl/drivers/Makefile.template b/src/egl/drivers/Makefile.template new file mode 100644 index 0000000000..02a65b094a --- /dev/null +++ b/src/egl/drivers/Makefile.template @@ -0,0 +1,51 @@ +# src/egl/drivers/Makefile.template +# +# Drivers should define +# +# EGL_DRIVER, the driver name +# EGL_SOURCES, the driver sources +# EGL_INCLUDES, the include pathes +# EGL_CFLAGS, additional CFLAGS +# EGL_LIBS, additional LIBS +# +# before including this template. +# + + +EGL_DRIVER_PATH = $(TOP)/$(LIB_DIR)/$(EGL_DRIVER) +EGL_OBJECTS = $(EGL_SOURCES:.c=.o) + + +default: depend $(EGL_DRIVER_PATH) + +$(EGL_DRIVER_PATH): $(EGL_DRIVER) + $(INSTALL) $< $(TOP)/$(LIB_DIR) + +$(EGL_DRIVER): $(EGL_OBJECTS) Makefile $(TOP)/src/egl/drivers/Makefile.template + @$(MKLIB) -o $(EGL_DRIVER) -noprefix \ + -linker '$(CC)' -ldflags '$(LDFLAGS)' \ + -L$(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ + $(EGL_OBJECTS) $(EGL_LIBS) + +.c.o: + $(CC) -c $(EGL_INCLUDES) $(CFLAGS) $(EGL_CFLAGS) $< -o $@ + + +install: $(EGL_DRIVER_PATH) + $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) + $(MINSTALL) $(EGL_DRIVER_PATH) $(DESTDIR)$(INSTALL_LIB_DIR) + +clean: + rm -f $(EGL_DRIVER) + rm -f $(EGL_OBJECTS) + rm -f depend depend.bak + +depend: $(EGL_SOURCES) + @ echo "running $(MKDEP)" + @ rm -f depend + @ touch depend + $(MKDEP) $(MKDEP_OPTIONS) $(EGL_INCLUDES) $(EGL_SOURCES) \ + >/dev/null 2>/dev/null + +sinclude depend +# DO NOT DELETE diff --git a/src/egl/drivers/demo/Makefile b/src/egl/drivers/demo/Makefile deleted file mode 100644 index 444dfb35bd..0000000000 --- a/src/egl/drivers/demo/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# src/egl/drivers/demo/Makefile - -TOP = ../../../.. -include $(TOP)/configs/current - - -INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/egl/main $(X11_INCLUDES) - - -SOURCES = demo.c - -OBJECTS = $(SOURCES:.c=.o) - - -.c.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ - - - -default: $(TOP)/$(LIB_DIR)/demodriver.so - - -$(TOP)/$(LIB_DIR)/demodriver.so: $(OBJECTS) - $(MKLIB) -o demodriver.so -noprefix -linker '$(CC)' \ - -ldflags '$(LDFLAGS)' -install $(TOP)/$(LIB_DIR) \ - $(OBJECTS) - -install: - -clean: - -rm -f *.o - -rm -f *.so diff --git a/src/egl/drivers/demo/demo.c b/src/egl/drivers/demo/demo.c deleted file mode 100644 index 0933c0bdaa..0000000000 --- a/src/egl/drivers/demo/demo.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * 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 */ - unsigned 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 */ - unsigned DemoStuff; -} DemoSurface; - - -/** - * Demo driver-specific context class derived from _EGLContext - */ -typedef struct demo_context -{ - _EGLContext Base; /* base class/object */ - unsigned DemoStuff; -} DemoContext; - - - -static EGLBoolean -demoInitialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor) -{ - _EGLScreen *scrn; - EGLint i; - - /* Create a screen */ - scrn = calloc(1, sizeof(*scrn)); - _eglAddScreen(disp, scrn); - - /* Create the screen's modes - silly example */ - _eglAddNewMode(scrn, 1600, 1200, 72 * 1000, "1600x1200-72"); - _eglAddNewMode(scrn, 1280, 1024, 72 * 1000, "1280x1024-70"); - _eglAddNewMode(scrn, 1280, 1024, 70 * 1000, "1280x1024-70"); - _eglAddNewMode(scrn, 1024, 768, 72 * 1000, "1024x768-72"); - - /* Create the display's visual configs - silly example */ - for (i = 0; i < 4; i++) { - _EGLConfig *config = calloc(1, sizeof(_EGLConfig)); - _eglInitConfig(config, i + 1); - _eglSetConfigAttrib(config, EGL_RED_SIZE, 8); - _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8); - _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8); - _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8); - _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32); - if (i & 1) { - _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 32); - } - if (i & 2) { - _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8); - } - _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, - (EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT)); - _eglAddConfig(disp, config); - } - - /* enable supported extensions */ - disp->Extensions.MESA_screen_surface = EGL_TRUE; - disp->Extensions.MESA_copy_context = EGL_TRUE; - - *major = 1; - *minor = 0; - - return EGL_TRUE; -} - - -static EGLBoolean -demoTerminate(_EGLDriver *drv, _EGLDisplay *dpy) -{ - /*DemoDriver *demo = DEMO_DRIVER(dpy);*/ - return EGL_TRUE; -} - - -static DemoContext * -LookupDemoContext(_EGLContext *c) -{ - return (DemoContext *) c; -} - - -static DemoSurface * -LookupDemoSurface(_EGLSurface *s) -{ - return (DemoSurface *) s; -} - - -static _EGLContext * -demoCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list) -{ - DemoContext *c; - int i; - - 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 NULL; - } - } - - c = (DemoContext *) calloc(1, sizeof(DemoContext)); - if (!c) - return NULL; - - _eglInitContext(drv, &c->Base, conf, attrib_list); - c->DemoStuff = 1; - printf("demoCreateContext\n"); - - return &c->Base; -} - - -static _EGLSurface * -demoCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, 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 NULL; - } - } - printf("eglCreateWindowSurface()\n"); - /* XXX unfinished */ - - return NULL; -} - - -static _EGLSurface * -demoCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list) -{ - EGLint 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, "eglCreatePixmapSurface"); - return NULL; - } - } - - if (GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE) == 0) { - _eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface"); - return NULL; - } - - printf("eglCreatePixmapSurface()\n"); - return NULL; -} - - -static _EGLSurface * -demoCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - const EGLint *attrib_list) -{ - DemoSurface *surf = (DemoSurface *) calloc(1, sizeof(DemoSurface)); - - if (!surf) - return NULL; - - if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT, - conf, attrib_list)) { - free(surf); - return NULL; - } - - /* a real driver would allocate the pbuffer memory here */ - - return &surf->Base; -} - - -static EGLBoolean -demoDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface) -{ - DemoSurface *fs = LookupDemoSurface(surface); - if (!_eglIsSurfaceBound(&fs->Base)) - free(fs); - return EGL_TRUE; -} - - -static EGLBoolean -demoDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context) -{ - DemoContext *fc = LookupDemoContext(context); - if (!_eglIsContextBound(&fc->Base)) - free(fc); - return EGL_TRUE; -} - - -static EGLBoolean -demoMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *drawSurf, _EGLSurface *readSurf, _EGLContext *ctx) -{ - /*DemoDriver *demo = DEMO_DRIVER(dpy);*/ - EGLBoolean b; - - b = _eglMakeCurrent(drv, dpy, drawSurf, readSurf, ctx); - 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 void -demoUnload(_EGLDriver *drv) -{ - free(drv); -} - - -/** - * The bootstrap function. Return a new DemoDriver object and - * plug in API functions. - */ -_EGLDriver * -_eglMain(const char *args) -{ - 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.API.Initialize = demoInitialize; - demo->Base.API.Terminate = demoTerminate; - demo->Base.API.CreateContext = demoCreateContext; - demo->Base.API.MakeCurrent = demoMakeCurrent; - demo->Base.API.CreateWindowSurface = demoCreateWindowSurface; - demo->Base.API.CreatePixmapSurface = demoCreatePixmapSurface; - demo->Base.API.CreatePbufferSurface = demoCreatePbufferSurface; - demo->Base.API.DestroySurface = demoDestroySurface; - demo->Base.API.DestroyContext = demoDestroyContext; - - demo->Base.Name = "egl/demo"; - demo->Base.Unload = demoUnload; - - return &demo->Base; -} diff --git a/src/egl/drivers/dri/egldri.c b/src/egl/drivers/dri/egldri.c index 9e400be624..ca6821dad0 100644 --- a/src/egl/drivers/dri/egldri.c +++ b/src/egl/drivers/dri/egldri.c @@ -675,13 +675,13 @@ __eglCreateContextWithConfig(__DRInativeDisplay* ndpy, int screen, drm_context_t * hHWContext) { __DRIscreen *pDRIScreen; - __DRIscreenPrivate *psp; + __DRIscreen *psp; pDRIScreen = __eglFindDRIScreen(ndpy, screen); if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { return GL_FALSE; } - psp = (__DRIscreenPrivate *) pDRIScreen->private; + psp = (__DRIscreen *) pDRIScreen->private; if (psp->fd) { if (drmCreateContext(psp->fd, hHWContext)) { _eglLog(_EGL_WARNING, "drmCreateContext failed."); @@ -691,14 +691,14 @@ __eglCreateContextWithConfig(__DRInativeDisplay* ndpy, int screen, } #if 0 __DRIscreen *pDRIScreen; - __DRIscreenPrivate *psp; + __DRIscreen *psp; pDRIScreen = __glXFindDRIScreen(dpy, screen); if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { return GL_FALSE; } - psp = (__DRIscreenPrivate *) pDRIScreen->private; + psp = (__DRIscreen *) pDRIScreen->private; if (psp->fd) { if (drmCreateContext(psp->fd, hHWContext)) { @@ -716,13 +716,13 @@ static GLboolean __eglDestroyContext( __DRInativeDisplay * ndpy, int screen, __DRIid context ) { __DRIscreen *pDRIScreen; - __DRIscreenPrivate *psp; + __DRIscreen *psp; pDRIScreen = __eglFindDRIScreen(ndpy, screen); if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { return GL_FALSE; } - psp = (__DRIscreenPrivate *) pDRIScreen->private; + psp = (__DRIscreen *) pDRIScreen->private; if (psp->fd) drmDestroyContext(psp->fd, context); @@ -735,13 +735,13 @@ __eglCreateDrawable(__DRInativeDisplay * ndpy, int screen, __DRIid drawable, drm_drawable_t * hHWDrawable) { __DRIscreen *pDRIScreen; - __DRIscreenPrivate *psp; + __DRIscreen *psp; pDRIScreen = __eglFindDRIScreen(ndpy, screen); if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { return GL_FALSE; } - psp = (__DRIscreenPrivate *) pDRIScreen->private; + psp = (__DRIscreen *) pDRIScreen->private; if (psp->fd) { if (drmCreateDrawable(psp->fd, hHWDrawable)) { _eglLog(_EGL_WARNING, "drmCreateDrawable failed."); @@ -756,13 +756,13 @@ static GLboolean __eglDestroyDrawable( __DRInativeDisplay * ndpy, int screen, __DRIid drawable ) { __DRIscreen *pDRIScreen; - __DRIscreenPrivate *psp; + __DRIscreen *psp; pDRIScreen = __eglFindDRIScreen(ndpy, screen); if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { return GL_FALSE; } - psp = (__DRIscreenPrivate *) pDRIScreen->private; + psp = (__DRIscreen *) pDRIScreen->private; if (psp->fd) drmDestroyDrawable(psp->fd, drawable); @@ -778,7 +778,7 @@ __eglGetDrawableInfo(__DRInativeDisplay * ndpy, int screen, __DRIid drawable, int* numBackClipRects, drm_clip_rect_t ** pBackClipRects ) { __DRIscreen *pDRIScreen; - __DRIscreenPrivate *psp; + __DRIscreen *psp; driSurface *surf = Lookup_driSurface((EGLSurface) drawable); pDRIScreen = __eglFindDRIScreen(ndpy, screen); @@ -786,7 +786,7 @@ __eglGetDrawableInfo(__DRInativeDisplay * ndpy, int screen, __DRIid drawable, if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) { return GL_FALSE; } - psp = (__DRIscreenPrivate *) pDRIScreen->private; + psp = (__DRIscreen *) pDRIScreen->private; *X = 0; *Y = 0; *W = surf->Base.Width; @@ -807,7 +807,7 @@ __eglGetDrawableInfo(__DRInativeDisplay * ndpy, int screen, __DRIid drawable, GLXDrawable drawable = (GLXDrawable) draw; drm_clip_rect_t * cliprect; Display* display = (Display*)dpy; - __DRIcontextPrivate *pcp = (__DRIcontextPrivate *)CurrentContext->driContext.private; + __DRIcontext *pcp = (__DRIcontext *)CurrentContext->driContext.private; if (drawable == 0) { return GL_FALSE; } diff --git a/src/egl/drivers/glx/Makefile b/src/egl/drivers/glx/Makefile index 20ef0352ad..634638f538 100644 --- a/src/egl/drivers/glx/Makefile +++ b/src/egl/drivers/glx/Makefile @@ -1,77 +1,16 @@ # src/egl/drivers/glx/Makefile -# Build XEGL DRI driver loader library: egl_glx.so - - TOP = ../../../.. include $(TOP)/configs/current +EGL_DRIVER = egl_glx.so +EGL_SOURCES = egl_glx.c -EXTRA_DEFINES = -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" - -DRIVER_NAME = egl_glx.so - - -INCLUDE_DIRS = \ - -I. \ - -I/usr/include \ - $(shell pkg-config --cflags-only-I libdrm) \ +EGL_INCLUDES = \ -I$(TOP)/include \ - -I$(TOP)/include/GL/internal \ - -I$(TOP)/src/mesa/glapi \ - -I$(TOP)/src/mesa/drivers/dri/common \ - -I$(TOP)/src/mesa/main \ - -I$(TOP)/src/mesa \ - -I$(TOP)/src/egl/main \ - -I$(TOP)/src/glx/x11 - -SOURCES = egl_glx.c - -OBJECTS = $(SOURCES:.c=.o) - -DRM_LIB = `pkg-config --libs libdrm` - -MISC_LIBS = -ldl -lXext -lGL - - -.c.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(EXTRA_DEFINES) $< -o $@ - - -.PHONY: library - - -default: depend library Makefile - - -library: $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) - - -# Make the egl_glx.so library -$(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(OBJECTS) - $(TOP)/bin/mklib -o $(DRIVER_NAME) \ - -noprefix \ - -major 1 -minor 0 \ - -L$(TOP)/$(LIB_DIR) \ - -install $(TOP)/$(LIB_DIR) \ - $(OBJECTS) $(DRM_LIB) $(MISC_LIBS) - -install: - $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) - $(MINSTALL) $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) $(DESTDIR)$(INSTALL_LIB_DIR) - -clean: - rm -f *.o - rm -f *.so - rm -f depend depend.bak - + -I$(TOP)/src/egl/main -depend: $(SOURCES) $(HEADERS) - @ echo "running $(MKDEP)" - @ rm -f depend - @ touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \ - $(SOURCES) $(HEADERS) >/dev/null 2>/dev/null +EGL_CFLAGS = +EGL_LIBS = -lX11 -lGL -include depend -# DO NOT DELETE +include ../Makefile.template diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c index 96292b0e9e..6d2815888b 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -54,13 +54,6 @@ #error "GL/glx.h must be equal to or greater than GLX 1.4" #endif -/* - * report OpenGL ES bits because apps usually forget to specify - * EGL_RENDERABLE_TYPE when choosing configs - */ -#define GLX_EGL_APIS (EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT) - - /** subclass of _EGLDriver */ struct GLX_egl_driver { @@ -244,7 +237,7 @@ convert_fbconfig(Display *dpy, GLXFBConfig fbconfig, GLX_conf->double_buffered = (mode.doubleBufferMode != 0); return _eglConfigFromContextModesRec(&GLX_conf->Base, &mode, - GLX_EGL_APIS, GLX_EGL_APIS); + EGL_OPENGL_BIT, EGL_OPENGL_BIT); } @@ -364,7 +357,7 @@ convert_visual(Display *dpy, XVisualInfo *vinfo, GLX_conf->double_buffered = (mode.doubleBufferMode != 0); return _eglConfigFromContextModesRec(&GLX_conf->Base, &mode, - GLX_EGL_APIS, GLX_EGL_APIS); + EGL_OPENGL_BIT, EGL_OPENGL_BIT); } @@ -559,7 +552,7 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp, } disp->DriverData = (void *) GLX_dpy; - disp->ClientAPIsMask = GLX_EGL_APIS; + disp->ClientAPIsMask = EGL_OPENGL_BIT; /* we're supporting EGL 1.4 */ *major = 1; @@ -899,7 +892,7 @@ GLX_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) * Called from eglGetProcAddress() via drv->API.GetProcAddress(). */ static _EGLProc -GLX_eglGetProcAddress(const char *procname) +GLX_eglGetProcAddress(_EGLDriver *drv, const char *procname) { return (_EGLProc) glXGetProcAddress((const GLubyte *) procname); } diff --git a/src/egl/drivers/xdri/Makefile b/src/egl/drivers/xdri/Makefile index 4c1fc9071c..9120620dc5 100644 --- a/src/egl/drivers/xdri/Makefile +++ b/src/egl/drivers/xdri/Makefile @@ -1,78 +1,28 @@ # src/egl/drivers/xdri/Makefile -# Build XEGL DRI driver loader library: egl_xdri.so - - TOP = ../../../.. include $(TOP)/configs/current +EGL_DRIVER = egl_xdri.so -DRIVER_NAME = egl_xdri.so - - -INCLUDE_DIRS = \ - -I. \ - -I/usr/include \ +# steal sources from GLX +GLX_SOURCES = dri_common.c XF86dri.c dri2.c dri2_glx.c dri_glx.c drisw_glx.c +GLX_SOURCES := $(addprefix ../../../glx/x11/,$(GLX_SOURCES)) +GLX_INCLUDES = \ $(shell pkg-config --cflags-only-I libdrm) \ - -I$(TOP)/include \ -I$(TOP)/include/GL/internal \ - -I$(TOP)/src/mesa \ + -I$(TOP)/src/glx/x11 \ -I$(TOP)/src/mesa/glapi \ - -I$(TOP)/src/egl/main \ - -I$(TOP)/src/glx/x11 - -HEADERS = glxinit.h driinit.h -SOURCES = egl_xdri.c glxinit.c driinit.c - -DRI_SOURCES = dri_common.c XF86dri.c dri2.c dri2_glx.c dri_glx.c -DRI_SOURCES := $(addprefix ../../../glx/x11/,$(DRI_SOURCES)) - -SOURCES += $(DRI_SOURCES) - -OBJECTS = $(SOURCES:.c=.o) - -DRM_LIB = `pkg-config --libs libdrm` - -CFLAGS += -DGLX_DIRECT_RENDERING - -.c.o: - $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@ - - -.PHONY: library - - -default: depend library Makefile - - -library: $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) - - -# Make the egl_xdri.so library -$(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(OBJECTS) - $(TOP)/bin/mklib -o $(DRIVER_NAME) \ - -noprefix \ - -major 1 -minor 0 \ - -L$(TOP)/$(LIB_DIR) \ - -install $(TOP)/$(LIB_DIR) \ - $(OBJECTS) $(DRM_LIB) $(GL_LIB_DEPS) - -install: - $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) - $(MINSTALL) $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) $(DESTDIR)$(INSTALL_LIB_DIR) - -clean: - rm -f *.o - rm -f *.so - rm -f depend depend.bak + -I$(TOP)/src/mesa +GLX_CFLAGS = -DGLX_DIRECT_RENDERING +EGL_SOURCES = egl_xdri.c glxinit.c driinit.c $(GLX_SOURCES) +EGL_INCLUDES = \ + -I$(TOP)/include \ + -I$(TOP)/src/egl/main \ + $(GLX_INCLUDES) -depend: $(SOURCES) $(HEADERS) - @ echo "running $(MKDEP)" - @ rm -f depend - @ touch depend - $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \ - $(SOURCES) $(HEADERS) >/dev/null 2>/dev/null +EGL_CFLAGS = $(GLX_CFLAGS) +EGL_LIBS = -lX11 -lGL -include depend -# DO NOT DELETE +include ../Makefile.template diff --git a/src/egl/drivers/xdri/driinit.c b/src/egl/drivers/xdri/driinit.c index 12da1bcd24..3e54f0bd4d 100644 --- a/src/egl/drivers/xdri/driinit.c +++ b/src/egl/drivers/xdri/driinit.c @@ -2,6 +2,7 @@ * DRI initialization. The DRI loaders are defined in src/glx/x11/. */ +#include <stdlib.h> #include <sys/time.h> #include "glxclient.h" @@ -42,18 +43,26 @@ __glXEnableDirectExtension(__GLXscreenConfigs * psc, const char *name) _X_HIDDEN __GLXDRIdisplay * __driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version) { - __GLXDRIdisplay *driDisplay; + __GLXDRIdisplay *driDisplay = NULL; int ver = 0; + char *env; + int force_sw; + + env = getenv("EGL_SOFTWARE"); + force_sw = (env && *env != '0'); /* try DRI2 first */ - driDisplay = dri2CreateDisplay(dpyPriv->dpy); - if (driDisplay) { - /* fill in the required field */ - dpyPriv->dri2Display = driDisplay; - ver = 2; + if (!force_sw) { + driDisplay = dri2CreateDisplay(dpyPriv->dpy); + if (driDisplay) { + /* fill in the required field */ + dpyPriv->dri2Display = driDisplay; + ver = 2; + } } - else { - /* try DRI */ + + /* and then DRI */ + if (!force_sw && !driDisplay) { driDisplay = driCreateDisplay(dpyPriv->dpy); if (driDisplay) { dpyPriv->driDisplay = driDisplay; @@ -61,6 +70,15 @@ __driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version) } } + /* and then DRISW */ + if (!driDisplay) { + driDisplay = driswCreateDisplay(dpyPriv->dpy); + if (driDisplay) { + dpyPriv->driDisplay = driDisplay; + ver = 0; + } + } + if (version) *version = ver; return driDisplay; diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c index d2affc66dd..b133939155 100644 --- a/src/egl/drivers/xdri/egl_xdri.c +++ b/src/egl/drivers/xdri/egl_xdri.c @@ -62,6 +62,7 @@ struct xdri_egl_driver { _EGLDriver Base; /**< base class */ + void (*FlushCurrentContext)(void); }; @@ -71,6 +72,7 @@ struct xdri_egl_display Display *dpy; __GLXdisplayPrivate *dpyPriv; __GLXDRIdisplay *driDisplay; + int driVersion; __GLXscreenConfigs *psc; EGLint scr; @@ -167,14 +169,10 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) static EGLBoolean convert_config(_EGLConfig *conf, EGLint id, const __GLcontextModes *m) { - static const EGLint all_apis = (EGL_OPENGL_ES_BIT | - EGL_OPENGL_ES2_BIT | - EGL_OPENVG_BIT | - EGL_OPENGL_BIT); EGLint val; _eglInitConfig(conf, id); - if (!_eglConfigFromContextModesRec(conf, m, all_apis, all_apis)) + if (!_eglConfigFromContextModesRec(conf, m, EGL_OPENGL_BIT, EGL_OPENGL_BIT)) return EGL_FALSE; if (m->doubleBufferMode) { @@ -215,6 +213,7 @@ convert_config(_EGLConfig *conf, EGLint id, const __GLcontextModes *m) static EGLint create_configs(_EGLDisplay *disp, const __GLcontextModes *m, EGLint first_id) { + struct xdri_egl_display *xdri_dpy = lookup_display(disp); int id = first_id; for (; m; m = m->next) { @@ -224,8 +223,15 @@ create_configs(_EGLDisplay *disp, const __GLcontextModes *m, EGLint first_id) if (!convert_config(&conf, id, m)) continue; - - rb = (m->doubleBufferMode) ? EGL_BACK_BUFFER : EGL_SINGLE_BUFFER; + if (m->doubleBufferMode) { + rb = EGL_BACK_BUFFER; + } + else { + /* ignore single-buffered mode for DRISW */ + if (xdri_dpy->driVersion == 0) + continue; + rb = EGL_SINGLE_BUFFER; + } xdri_conf = CALLOC_STRUCT(xdri_egl_config); if (xdri_conf) { @@ -275,7 +281,7 @@ xdri_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy, return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } - driDisplay = __driCreateDisplay(dpyPriv, NULL); + driDisplay = __driCreateDisplay(dpyPriv, &xdri_dpy->driVersion); if (!driDisplay) { _eglLog(_EGL_WARNING, "failed to create DRI display"); free(xdri_dpy); @@ -297,16 +303,13 @@ xdri_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy, return _eglError(EGL_NOT_INITIALIZED, "eglInitialize"); } + dpy->DriverData = xdri_dpy; + dpy->ClientAPIsMask = EGL_OPENGL_BIT; + /* add visuals and fbconfigs */ first_id = create_configs(dpy, psc->visuals, first_id); create_configs(dpy, psc->configs, first_id); - dpy->DriverData = xdri_dpy; - dpy->ClientAPIsMask = (EGL_OPENGL_BIT | - EGL_OPENGL_ES_BIT | - EGL_OPENGL_ES2_BIT | - EGL_OPENVG_BIT); - /* we're supporting EGL 1.4 */ *minor = 1; *major = 4; @@ -342,7 +345,6 @@ xdri_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy) } xdri_dpy->driDisplay->destroyDisplay(xdri_dpy->driDisplay); - __glXRelease(xdri_dpy->dpyPriv); free(xdri_dpy); dpy->DriverData = NULL; @@ -355,7 +357,7 @@ xdri_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy) * Called from eglGetProcAddress() via drv->API.GetProcAddress(). */ static _EGLProc -xdri_eglGetProcAddress(const char *procname) +xdri_eglGetProcAddress(_EGLDriver *drv, const char *procname) { /* the symbol is defined in libGL.so */ return (_EGLProc) _glapi_get_proc_address(procname); @@ -441,13 +443,23 @@ static EGLBoolean xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d, _EGLSurface *r, _EGLContext *context) { + struct xdri_egl_driver *xdri_driver = xdri_egl_driver(drv); struct xdri_egl_context *xdri_ctx = lookup_context(context); struct xdri_egl_surface *draw = lookup_surface(d); struct xdri_egl_surface *read = lookup_surface(r); + _EGLContext *old = _eglGetCurrentContext(); + + /* an unlinked context will be invalid after context switch */ + if (!_eglIsContextLinked(old)) + old = NULL; if (!_eglMakeCurrent(drv, dpy, d, r, context)) return EGL_FALSE; + /* flush before context switch */ + if (old && old != context && xdri_driver->FlushCurrentContext) + xdri_driver->FlushCurrentContext(); + /* the symbol is defined in libGL.so */ _glapi_check_multithread(); @@ -458,12 +470,9 @@ xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d, return EGL_FALSE; } } - else { - _EGLContext *old = _eglGetCurrentContext(); - if (old) { - xdri_ctx = lookup_context(old); - xdri_ctx->driContext->unbindContext(xdri_ctx->driContext); - } + else if (old) { + xdri_ctx = lookup_context(old); + xdri_ctx->driContext->unbindContext(xdri_ctx->driContext); } return EGL_TRUE; @@ -559,10 +568,16 @@ xdri_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, static EGLBoolean xdri_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw) { + struct xdri_egl_driver *xdri_driver = xdri_egl_driver(drv); struct xdri_egl_display *xdri_dpy = lookup_display(dpy); struct xdri_egl_surface *xdri_surf = lookup_surface(draw); - xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable); + /* swapBuffers does not flush commands */ + if (draw == _eglGetCurrentSurface(EGL_DRAW) && + xdri_driver->FlushCurrentContext) + xdri_driver->FlushCurrentContext(); + + xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable, 0, 0, 0); return EGL_TRUE; } @@ -606,5 +621,9 @@ _eglMain(const char *args) xdri_drv->Base.Name = "X/DRI"; xdri_drv->Base.Unload = xdri_Unload; + /* we need a way to flush commands */ + xdri_drv->FlushCurrentContext = + (void (*)(void)) xdri_eglGetProcAddress(&xdri_drv->Base, "glFlush"); + return &xdri_drv->Base; } diff --git a/src/egl/drivers/xdri/glxinit.c b/src/egl/drivers/xdri/glxinit.c index 7775009394..5c0fbc6b3c 100644 --- a/src/egl/drivers/xdri/glxinit.c +++ b/src/egl/drivers/xdri/glxinit.c @@ -1,8 +1,10 @@ /** * GLX initialization. Code based on glxext.c, glx_query.c, and - * glcontextmodes.c under src/glx/x11/. The major difference is that no DRI - * related code here. + * glcontextmodes.c under src/glx/x11/. The major difference is that DRI + * related code is stripped out. * + * If the maintenance of this file takes too much time, we should consider + * refactoring glxext.c. */ #include <assert.h> @@ -31,7 +33,26 @@ typedef struct GLXGenericGetString static char *__glXExtensionName = GLX_EXTENSION_NAME; static XExtensionInfo *__glXExtensionInfo = NULL; -static /* const */ XExtensionHooks __glXExtensionHooks = { NULL }; +static int +__glXCloseDisplay(Display * dpy, XExtCodes * codes) +{ + return XextRemoveDisplay(__glXExtensionInfo, dpy); +} + +static /* const */ XExtensionHooks __glXExtensionHooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + __glXCloseDisplay, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + static XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, __glXExtensionName, &__glXExtensionHooks, @@ -180,6 +201,30 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv) priv->screenConfigs = NULL; } +/* +** Release the private memory referred to in a display private +** structure. The caller will free the extension structure. +*/ +static int +__glXFreeDisplayPrivate(XExtData * extension) +{ + __GLXdisplayPrivate *priv; + + priv = (__GLXdisplayPrivate *) extension->private_data; + FreeScreenConfigs(priv); + if (priv->serverGLXvendor) { + Xfree((char *) priv->serverGLXvendor); + priv->serverGLXvendor = 0x0; /* to protect against double free's */ + } + if (priv->serverGLXversion) { + Xfree((char *) priv->serverGLXversion); + priv->serverGLXversion = 0x0; /* to protect against double free's */ + } + + Xfree((char *) priv); + return 0; +} + /************************************************************************/ /* @@ -570,40 +615,40 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) return GL_TRUE; } -_X_HIDDEN void -__glXRelease(__GLXdisplayPrivate *dpyPriv) -{ - FreeScreenConfigs(dpyPriv); - - if (dpyPriv->serverGLXvendor) { - Xfree((char *) dpyPriv->serverGLXvendor); - dpyPriv->serverGLXvendor = NULL; - } - if (dpyPriv->serverGLXversion) { - Xfree((char *) dpyPriv->serverGLXversion); - dpyPriv->serverGLXversion = NULL; - } - - Xfree(dpyPriv); -} - _X_HIDDEN __GLXdisplayPrivate * __glXInitialize(Display * dpy) { XExtDisplayInfo *info = __glXFindDisplay(dpy); + XExtData **privList, *private, *found; __GLXdisplayPrivate *dpyPriv; + XEDataObject dataObj; int major, minor; if (!XextHasExtension(info)) return NULL; + /* See if a display private already exists. If so, return it */ + dataObj.display = dpy; + privList = XEHeadOfExtensionList(dataObj); + found = XFindOnExtensionList(privList, info->codes->extension); + if (found) + return (__GLXdisplayPrivate *) found->private_data; + /* See if the versions are compatible */ if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor)) return NULL; + /* + ** Allocate memory for all the pieces needed for this buffer. + */ + private = (XExtData *) Xmalloc(sizeof(XExtData)); + if (!private) + return NULL; dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate)); - if (!dpyPriv) + if (!dpyPriv) { + Xfree(private); return NULL; + } /* ** Init the display private and then read in the screen config @@ -619,8 +664,20 @@ __glXInitialize(Display * dpy) if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) { Xfree(dpyPriv); + Xfree(private); return NULL; } + /* + ** Fill in the private structure. This is the actual structure that + ** hangs off of the Display structure. Our private structure is + ** referred to by this structure. Got that? + */ + private->number = info->codes->extension; + private->next = 0; + private->free_private = __glXFreeDisplayPrivate; + private->private_data = (char *) dpyPriv; + XAddToExtensionList(privList, private); + return dpyPriv; } diff --git a/src/egl/drivers/xdri/glxinit.h b/src/egl/drivers/xdri/glxinit.h index 57206e627b..1cc7c460fe 100644 --- a/src/egl/drivers/xdri/glxinit.h +++ b/src/egl/drivers/xdri/glxinit.h @@ -8,7 +8,4 @@ extern void _gl_context_modes_destroy(__GLcontextModes * modes); -extern void -__glXRelease(__GLXdisplayPrivate *dpyPriv); - #endif /* GLXINIT_INCLUDED */ diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile index c951b070f1..66f8f01b8e 100644 --- a/src/egl/main/Makefile +++ b/src/egl/main/Makefile @@ -4,7 +4,10 @@ TOP = ../../.. include $(TOP)/configs/current -INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi $(X11_INCLUDES) +EGL_MAJOR = 1 +EGL_MINOR = 0 + +INCLUDE_DIRS = -I$(TOP)/include HEADERS = \ eglcompiler.h \ @@ -43,9 +46,14 @@ SOURCES = \ OBJECTS = $(SOURCES:.c=.o) -# Undefined for now -LOCAL_CFLAGS = -D_EGL_PLATFORM_X=1 +# use dl*() to load drivers +LOCAL_CFLAGS = -D_EGL_PLATFORM_POSIX=1 + +EGL_DEFAULT_DISPLAY = $(word 1, $(EGL_DISPLAYS)) +LOCAL_CFLAGS += \ + -D_EGL_DEFAULT_DISPLAY=\"$(EGL_DEFAULT_DISPLAY)\" \ + -D_EGL_DRIVER_SEARCH_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" .c.o: $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@ @@ -56,21 +64,21 @@ default: depend library # EGL Library -library: $(TOP)/$(LIB_DIR)/libEGL.so +library: $(TOP)/$(LIB_DIR)/$(EGL_LIB_NAME) -$(TOP)/$(LIB_DIR)/libEGL.so: $(OBJECTS) - $(MKLIB) -o EGL -linker '$(CC)' -ldflags '$(LDFLAGS)' \ - -major 1 -minor 0 \ - -install $(TOP)/$(LIB_DIR) \ +$(TOP)/$(LIB_DIR)/$(EGL_LIB_NAME): $(OBJECTS) + $(MKLIB) -o $(EGL_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \ + -major $(EGL_MAJOR) -minor $(EGL_MINOR) \ + -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \ $(EGL_LIB_DEPS) $(OBJECTS) install: default $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR) - $(MINSTALL) $(TOP)/$(LIB_DIR)/libEGL.so* $(DESTDIR)$(INSTALL_LIB_DIR) + $(MINSTALL) $(TOP)/$(LIB_DIR)/$(EGL_LIB_GLOB) \ + $(DESTDIR)$(INSTALL_LIB_DIR) clean: - -rm -f *.o *.so* - -rm -f core.* + -rm -f *.o -rm -f depend depend.bak @@ -82,5 +90,5 @@ depend: $(SOURCES) $(HEADERS) $(SOURCES) $(HEADERS) > /dev/null 2>/dev/null -include depend +-include depend # DO NOT DELETE diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 14cc5fa613..6e8f444d7f 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -101,6 +101,8 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) drv = disp->Driver; if (!drv) { + _eglPreloadDrivers(); + drv = _eglOpenDriver(disp); if (!drv) return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__); @@ -710,13 +712,12 @@ void (* EGLAPIENTRY eglGetProcAddress(const char *procname))() } } - /* preload a driver if there isn't one */ - if (!_eglGlobal.NumDrivers) - _eglPreloadDriver(NULL); + _eglPreloadDrivers(); /* now loop over drivers to query their procs */ for (i = 0; i < _eglGlobal.NumDrivers; i++) { - _EGLProc p = _eglGlobal.Drivers[i]->API.GetProcAddress(procname); + _EGLDriver *drv = _eglGlobal.Drivers[i]; + _EGLProc p = drv->API.GetProcAddress(drv, procname); if (p) return p; } diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h index aa0abe3eb6..080f2155e3 100644 --- a/src/egl/main/eglapi.h +++ b/src/egl/main/eglapi.h @@ -44,7 +44,7 @@ typedef const char *(*QueryString_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint n typedef EGLBoolean (*WaitClient_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx); typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine); -typedef _EGLProc (*GetProcAddress_t)(const char *procname); +typedef _EGLProc (*GetProcAddress_t)(_EGLDriver *drv, const char *procname); diff --git a/src/egl/main/eglcompiler.h b/src/egl/main/eglcompiler.h index 6b639b75c6..d844fbb0ef 100644 --- a/src/egl/main/eglcompiler.h +++ b/src/egl/main/eglcompiler.h @@ -61,4 +61,33 @@ #endif +/** + * Function visibility + */ +#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303) \ + || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) +# define PUBLIC __attribute__((visibility("default"))) +#else +# define PUBLIC +#endif + +/** + * The __FUNCTION__ gcc variable is generally only used for debugging. + * If we're not using gcc, define __FUNCTION__ as a cpp symbol here. + * Don't define it if using a newer Windows compiler. + */ +#ifndef __FUNCTION__ +# if defined(__VMS) +# define __FUNCTION__ "VMS$NL:" +# elif ((!defined __GNUC__) || (__GNUC__ < 2)) && (!defined __xlC__) && \ + (!defined(_MSC_VER) || _MSC_VER < 1300) +# if (__STDC_VERSION__ >= 199901L) /* C99 */ || \ + (defined(__SUNPRO_C) && defined(__C99FEATURES__)) +# define __FUNCTION__ __func__ +# else +# define __FUNCTION__ "<unknown>" +# endif +# endif +#endif + #endif /* EGLCOMPILER_INCLUDED */ diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c index 31d69a7708..4d149603ae 100644 --- a/src/egl/main/eglconfig.c +++ b/src/egl/main/eglconfig.c @@ -324,6 +324,7 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) mask = EGL_PBUFFER_BIT | EGL_PIXMAP_BIT | EGL_WINDOW_BIT | + EGL_SCREEN_BIT_MESA | /* XXX should check the extension */ EGL_VG_COLORSPACE_LINEAR_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT | EGL_MULTISAMPLE_RESOLVE_BOX_BIT | diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h index 6b8a259984..799bf4ee24 100644 --- a/src/egl/main/eglconfig.h +++ b/src/egl/main/eglconfig.h @@ -91,11 +91,11 @@ _eglSetConfigAttrib(_EGLConfig *conf, EGLint attr, EGLint val) } -extern void +PUBLIC void _eglInitConfig(_EGLConfig *config, EGLint id); -extern EGLConfig +PUBLIC EGLConfig _eglAddConfig(_EGLDisplay *dpy, _EGLConfig *conf); @@ -144,24 +144,24 @@ _eglGetConfigHandle(_EGLConfig *conf) } -extern EGLBoolean +PUBLIC EGLBoolean _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching); -extern EGLBoolean +PUBLIC EGLBoolean _eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria); -extern EGLBoolean +PUBLIC EGLBoolean _eglParseConfigAttribList(_EGLConfig *conf, const EGLint *attrib_list); -extern EGLint +PUBLIC EGLint _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2, const _EGLConfig *criteria, EGLBoolean compare_id); -extern void +PUBLIC void _eglSortConfigs(const _EGLConfig **configs, EGLint count, EGLint (*compare)(const _EGLConfig *, const _EGLConfig *, void *), diff --git a/src/egl/main/eglconfigutil.h b/src/egl/main/eglconfigutil.h index 8c923ee206..9f8906dedb 100644 --- a/src/egl/main/eglconfigutil.h +++ b/src/egl/main/eglconfigutil.h @@ -7,16 +7,16 @@ #include "eglconfig.h" -extern void +PUBLIC void _eglConfigToContextModesRec(const _EGLConfig *config, __GLcontextModes *mode); -extern EGLBoolean +PUBLIC EGLBoolean _eglConfigFromContextModesRec(_EGLConfig *conf, const __GLcontextModes *m, EGLint conformant, EGLint renderable_type); -extern EGLBoolean +PUBLIC EGLBoolean _eglFillInConfigs( _EGLConfig *configs, EGLenum fb_format, EGLenum fb_type, const uint8_t * depth_bits, const uint8_t * stencil_bits, diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h index 45c7b4717b..cb9e3f4a89 100644 --- a/src/egl/main/eglcontext.h +++ b/src/egl/main/eglcontext.h @@ -30,7 +30,7 @@ struct _egl_context }; -extern EGLBoolean +PUBLIC EGLBoolean _eglInitContext(_EGLDriver *drv, _EGLContext *ctx, _EGLConfig *config, const EGLint *attrib_list); @@ -47,7 +47,7 @@ extern EGLBoolean _eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint attribute, EGLint *value); -extern EGLBoolean +PUBLIC EGLBoolean _eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx); diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h index 9503e0aba0..c4478b3891 100644 --- a/src/egl/main/eglcurrent.h +++ b/src/egl/main/eglcurrent.h @@ -60,7 +60,7 @@ _eglConvertApiFromIndex(EGLint idx) } -extern _EGLThreadInfo * +PUBLIC _EGLThreadInfo * _eglGetCurrentThread(void); @@ -72,19 +72,19 @@ extern EGLBoolean _eglIsCurrentThreadDummy(void); -extern _EGLContext * +PUBLIC _EGLContext * _eglGetCurrentContext(void); -extern _EGLDisplay * +PUBLIC _EGLDisplay * _eglGetCurrentDisplay(void); -extern _EGLSurface * +PUBLIC _EGLSurface * _eglGetCurrentSurface(EGLint readdraw); -extern EGLBoolean +PUBLIC EGLBoolean _eglError(EGLint errCode, const char *msg); diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c index 896d60dbe1..eb82af4884 100644 --- a/src/egl/main/egldisplay.c +++ b/src/egl/main/egldisplay.c @@ -40,36 +40,6 @@ _eglFiniDisplay(void) /** - * If the first character is '!' we interpret it as specific driver name - * (i.e. "!r200" or "!i830"). Whatever follows ':' is interpreted as - * arguments. - * - * The caller may free() the returned driver name. - */ -char * -_eglSplitDisplayString(const char *dpyString, const char **args) -{ - char *drv, *p; - - if (!dpyString || dpyString[0] != '!') - return NULL; - drv = _eglstrdup(dpyString + 1); - if (!drv) - return NULL; - - p = strchr(dpyString, ':'); - if (p) { - drv[p - dpyString] = '\0'; - p++; - } - if (args) - *args = p; - - return drv; -} - - -/** * Allocate a new _EGLDisplay object for the given nativeDisplay handle. * We'll also try to determine the device driver name at this time. * @@ -81,12 +51,6 @@ _eglNewDisplay(NativeDisplayType nativeDisplay) _EGLDisplay *dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay)); if (dpy) { dpy->NativeDisplay = nativeDisplay; - - dpy->DriverName = _eglPreloadDriver(dpy); - if (!dpy->DriverName) { - free(dpy); - return NULL; - } } return dpy; } diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index ea4e35a8b3..a69813196f 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -26,7 +26,6 @@ struct _egl_display EGLNativeDisplayType NativeDisplay; - const char *DriverName; _EGLDriver *Driver; void *DriverData; /* private to driver */ @@ -58,10 +57,6 @@ extern void _eglFiniDisplay(void); -extern char * -_eglSplitDisplayString(const char *dpyString, const char **args); - - extern _EGLDisplay * _eglNewDisplay(NativeDisplayType displayName); @@ -78,11 +73,11 @@ extern _EGLDisplay * _eglFindDisplay(NativeDisplayType nativeDisplay); -extern void +PUBLIC void _eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *dpy); -extern void +PUBLIC void _eglCleanupDisplay(_EGLDisplay *disp); diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c index 018b06d3be..f890df1bb1 100644 --- a/src/egl/main/egldriver.c +++ b/src/egl/main/egldriver.c @@ -20,8 +20,10 @@ #include "eglstring.h" #include "eglsurface.h" -#if defined(_EGL_PLATFORM_X) +#if defined(_EGL_PLATFORM_POSIX) #include <dlfcn.h> +#include <sys/types.h> +#include <dirent.h> #endif @@ -49,10 +51,17 @@ close_library(HMODULE lib) } -#elif defined(_EGL_PLATFORM_X) +static const char * +library_suffix(void) +{ + return "dll"; +} + +#elif defined(_EGL_PLATFORM_POSIX) -static const char DefaultDriverName[] = "egl_softpipe"; + +static const char DefaultDriverName[] = "egl_glx"; typedef void * lib_handle; @@ -68,6 +77,14 @@ close_library(void *lib) dlclose(lib); } + +static const char * +library_suffix(void) +{ + return "so"; +} + + #else /* _EGL_PLATFORM_NO_OS */ static const char DefaultDriverName[] = "builtin"; @@ -86,67 +103,21 @@ close_library(void *lib) } -#endif - - -/** - * Choose a driver for a given display. - * The caller may free() the returned strings. - */ -static char * -_eglChooseDriver(_EGLDisplay *dpy, char **argsRet) +static const char * +library_suffix(void) { - char *path = NULL; - const char *args = NULL; - const char *suffix = NULL; - const char *p; - - path = getenv("EGL_DRIVER"); - if (path) - path = _eglstrdup(path); - -#if defined(_EGL_PLATFORM_X) - if (!path && dpy && dpy->NativeDisplay) { - /* assume (wrongly!) that the native display is a display string */ - path = _eglSplitDisplayString((const char *) dpy->NativeDisplay, &args); - } - suffix = "so"; -#elif defined(_EGL_PLATFORM_WINDOWS) - suffix = "dll"; -#else /* _EGL_PLATFORM_NO_OS */ - if (path) { - /* force the use of the default driver */ - _eglLog(_EGL_DEBUG, "ignore EGL_DRIVER"); - free(path); - path = NULL; - } - suffix = NULL; -#endif - - if (!path) - path = _eglstrdup(DefaultDriverName); + return NULL; +} - /* append suffix if there isn't */ - p = strrchr(path, '.'); - if (!p && suffix) { - size_t len = strlen(path); - char *tmp = malloc(len + strlen(suffix) + 2); - if (tmp) { - memcpy(tmp, path, len); - tmp[len++] = '.'; - tmp[len] = '\0'; - strcat(tmp + len, suffix); - free(path); - path = tmp; - } - } +#endif - if (argsRet) - *argsRet = (args) ? _eglstrdup(args) : NULL; - return path; -} +#define NUM_PROBE_CACHE_SLOTS 8 +static struct { + EGLint keys[NUM_PROBE_CACHE_SLOTS]; + const void *values[NUM_PROBE_CACHE_SLOTS]; +} _eglProbeCache; /** @@ -168,7 +139,7 @@ _eglOpenLibrary(const char *driverPath, lib_handle *handle) /* XXX untested */ if (lib) mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain"); -#elif defined(_EGL_PLATFORM_X) +#elif defined(_EGL_PLATFORM_POSIX) if (lib) { mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain"); if (!mainFunc) @@ -208,11 +179,10 @@ _eglOpenLibrary(const char *driverPath, lib_handle *handle) /** - * Load the named driver. The path and args passed will be - * owned by the driver and freed. + * Load the named driver. */ static _EGLDriver * -_eglLoadDriver(char *path, char *args) +_eglLoadDriver(const char *path, const char *args) { _EGLMain_t mainFunc; lib_handle lib; @@ -234,8 +204,19 @@ _eglLoadDriver(char *path, char *args) drv->Name = "UNNAMED"; } - drv->Path = path; - drv->Args = args; + drv->Path = _eglstrdup(path); + drv->Args = (args) ? _eglstrdup(args) : NULL; + if (!drv->Path || (args && !drv->Args)) { + if (drv->Path) + free((char *) drv->Path); + if (drv->Args) + free((char *) drv->Args); + drv->Unload(drv); + if (lib) + close_library(lib); + return NULL; + } + drv->LibHandle = lib; return drv; @@ -244,93 +225,221 @@ _eglLoadDriver(char *path, char *args) /** * Match a display to a preloaded driver. + * + * The matching is done by finding the driver with the highest score. */ static _EGLDriver * _eglMatchDriver(_EGLDisplay *dpy) { - _EGLDriver *defaultDriver = NULL; - EGLint i; + _EGLDriver *best_drv = NULL; + EGLint best_score = -1, i; for (i = 0; i < _eglGlobal.NumDrivers; i++) { _EGLDriver *drv = _eglGlobal.Drivers[i]; - - /* display specifies a driver */ - if (dpy->DriverName) { - if (strcmp(dpy->DriverName, drv->Name) == 0) - return drv; - } - else if (drv->Probe) { - if (drv->Probe(drv, dpy)) - return drv; - } - else { - if (!defaultDriver) - defaultDriver = drv; + EGLint score; + + score = (drv->Probe) ? drv->Probe(drv, dpy) : 0; + if (score > best_score) { + if (best_drv) { + _eglLog(_EGL_DEBUG, "driver %s has higher score than %s", + drv->Name, best_drv->Name); + } + + best_drv = drv; + best_score = score; + /* perfect match */ + if (score >= 100) + break; } } - return defaultDriver; + return best_drv; } /** - * Load a driver and save it. + * Open a preloaded driver. */ -const char * -_eglPreloadDriver(_EGLDisplay *dpy) +_EGLDriver * +_eglOpenDriver(_EGLDisplay *dpy) { - char *path, *args; + _EGLDriver *drv = _eglMatchDriver(dpy); + return drv; +} + + +/** + * Close a preloaded driver. + */ +EGLBoolean +_eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy) +{ + return EGL_TRUE; +} + + +/** + * Preload a user driver. + * + * A user driver can be specified by EGL_DRIVER. + */ +static EGLBoolean +_eglPreloadUserDriver(void) +{ +#if defined(_EGL_PLATFORM_POSIX) || defined(_EGL_PLATFORM_WINDOWS) _EGLDriver *drv; - EGLint i; + char *env, *path; + const char *suffix, *p; - path = _eglChooseDriver(dpy, &args); - if (!path) - return NULL; + env = getenv("EGL_DRIVER"); + if (!env) + return EGL_FALSE; - for (i = 0; i < _eglGlobal.NumDrivers; i++) { - drv = _eglGlobal.Drivers[i]; - if (strcmp(drv->Path, path) == 0) { - _eglLog(_EGL_DEBUG, "Driver %s is already preloaded", - drv->Name); - free(path); - if (args) - free(args); - return drv->Name; + path = env; + suffix = library_suffix(); + + /* append suffix if there isn't */ + p = strrchr(path, '.'); + if (!p && suffix) { + size_t len = strlen(path); + char *tmp = malloc(len + strlen(suffix) + 2); + if (tmp) { + memcpy(tmp, path, len); + tmp[len++] = '.'; + tmp[len] = '\0'; + strcat(tmp + len, suffix); + + path = tmp; } } - drv = _eglLoadDriver(path, args); + drv = _eglLoadDriver(path, NULL); + if (path != env) + free(path); if (!drv) - return NULL; + return EGL_FALSE; _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv; - return drv->Name; + return EGL_TRUE; +#else /* _EGL_PLATFORM_POSIX || _EGL_PLATFORM_WINDOWS */ + return EGL_FALSE; +#endif } /** - * Open a preloaded driver. + * Preload display drivers. + * + * Display drivers are a set of drivers that support a certain display system. + * The display system may be specified by EGL_DISPLAY. + * + * FIXME This makes libEGL a memory hog if an user driver is not specified and + * there are many display drivers. */ -_EGLDriver * -_eglOpenDriver(_EGLDisplay *dpy) +static EGLBoolean +_eglPreloadDisplayDrivers(void) { - _EGLDriver *drv = _eglMatchDriver(dpy); - return drv; +#if defined(_EGL_PLATFORM_POSIX) + const char *dpy, *suffix; + char path[1024], prefix[32]; + DIR *dirp; + struct dirent *dirent; + + dpy = getenv("EGL_DISPLAY"); + if (!dpy || !dpy[0]) + dpy = _EGL_DEFAULT_DISPLAY; + if (!dpy || !dpy[0]) + return EGL_FALSE; + + snprintf(prefix, sizeof(prefix), "egl_%s_", dpy); + suffix = library_suffix(); + + dirp = opendir(_EGL_DRIVER_SEARCH_DIR); + if (!dirp) + return EGL_FALSE; + + while ((dirent = readdir(dirp))) { + _EGLDriver *drv; + const char *p; + + /* match the prefix */ + if (strncmp(dirent->d_name, prefix, strlen(prefix)) != 0) + continue; + + /* match the suffix */ + p = strrchr(dirent->d_name, '.'); + if ((p && !suffix) || (!p && suffix)) + continue; + else if (p && suffix && strcmp(p + 1, suffix) != 0) + continue; + + snprintf(path, sizeof(path), + _EGL_DRIVER_SEARCH_DIR"/%s", dirent->d_name); + + drv = _eglLoadDriver(path, NULL); + if (drv) + _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv; + } + + closedir(dirp); + + return (_eglGlobal.NumDrivers > 0); +#else /* _EGL_PLATFORM_POSIX */ + return EGL_FALSE; +#endif } /** - * Close a preloaded driver. + * Preload the default driver. */ -EGLBoolean -_eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy) +static EGLBoolean +_eglPreloadDefaultDriver(void) { + _EGLDriver *drv; + char path[1024]; + const char *suffix = library_suffix(); + + if (suffix) + snprintf(path, sizeof(path), "%s.%s", DefaultDriverName, suffix); + else + snprintf(path, sizeof(path), DefaultDriverName); + + drv = _eglLoadDriver(path, NULL); + if (!drv) + return EGL_FALSE; + + _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv; + return EGL_TRUE; } /** + * Preload drivers. + * + * This function loads the driver modules and creates the corresponding + * _EGLDriver objects. + */ +EGLBoolean +_eglPreloadDrivers(void) +{ + EGLBoolean loaded; + + /* already preloaded */ + if (_eglGlobal.NumDrivers) + return EGL_TRUE; + + loaded = (_eglPreloadUserDriver() || + _eglPreloadDisplayDrivers() || + _eglPreloadDefaultDriver()); + + return loaded; +} + + +/** * Unload preloaded drivers. */ void @@ -360,20 +469,6 @@ _eglUnloadDrivers(void) /** - * 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. */ @@ -447,7 +542,7 @@ _eglFindAPIs(void) const char *es2_libname = "libGLESv2.dll"; const char *gl_libname = "OpenGL32.dll"; const char *vg_libname = "libOpenVG.dll"; -#elif defined(_EGL_PLATFORM_X) +#elif defined(_EGL_PLATFORM_POSIX) const char *es1_libname = "libGLESv1_CM.so"; const char *es2_libname = "libGLESv2.so"; const char *gl_libname = "libGL.so"; @@ -481,3 +576,44 @@ _eglFindAPIs(void) return mask; } + + +/** + * Set the probe cache at the given key. + * + * A key, instead of a _EGLDriver, is used to allow the probe cache to be share + * by multiple drivers. + */ +void +_eglSetProbeCache(EGLint key, const void *val) +{ + EGLint idx; + + for (idx = 0; idx < NUM_PROBE_CACHE_SLOTS; idx++) { + if (!_eglProbeCache.keys[idx] || _eglProbeCache.keys[idx] == key) + break; + } + assert(key > 0); + assert(idx < NUM_PROBE_CACHE_SLOTS); + + _eglProbeCache.keys[idx] = key; + _eglProbeCache.values[idx] = val; +} + + +/** + * Return the probe cache at the given key. + */ +const void * +_eglGetProbeCache(EGLint key) +{ + EGLint idx; + + for (idx = 0; idx < NUM_PROBE_CACHE_SLOTS; idx++) { + if (!_eglProbeCache.keys[idx] || _eglProbeCache.keys[idx] == key) + break; + } + + return (idx < NUM_PROBE_CACHE_SLOTS && _eglProbeCache.keys[idx] == key) ? + _eglProbeCache.values[idx] : NULL; +} diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h index 6c848eb35e..d9d61297c1 100644 --- a/src/egl/main/egldriver.h +++ b/src/egl/main/egldriver.h @@ -16,20 +16,30 @@ struct _egl_driver const char *Args; /**< args to load this driver */ const char *Name; /**< name of this driver */ - /**< probe a display to see if it is supported */ - EGLBoolean (*Probe)(_EGLDriver *drv, _EGLDisplay *dpy); - /**< called before dlclose to release this driver */ + + /** + * Probe a display and return a score. + * + * Roughly, + * 50 means the driver supports the display; + * 90 means the driver can accelerate the display; + * 100 means a perfect match. + */ + EGLint (*Probe)(_EGLDriver *drv, _EGLDisplay *dpy); + + /** + * Release the driver resource. + * + * It is called before dlclose(). + */ void (*Unload)(_EGLDriver *drv); _EGLAPI API; /**< EGL API dispatch table */ }; -extern _EGLDriver *_eglMain(const char *args); - - -extern const char * -_eglPreloadDriver(_EGLDisplay *dpy); +PUBLIC _EGLDriver * +_eglMain(const char *args); extern _EGLDriver * @@ -40,20 +50,28 @@ extern EGLBoolean _eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy); -void -_eglUnloadDrivers(void); +extern EGLBoolean +_eglPreloadDrivers(void); -extern _EGLDriver * -_eglLookupDriver(EGLDisplay d); +extern void +_eglUnloadDrivers(void); -extern void +PUBLIC void _eglInitDriverFallbacks(_EGLDriver *drv); -extern EGLint +PUBLIC EGLint _eglFindAPIs(void); +PUBLIC void +_eglSetProbeCache(EGLint key, const void *val); + + +PUBLIC const void * +_eglGetProbeCache(EGLint key); + + #endif /* EGLDRIVER_INCLUDED */ diff --git a/src/egl/main/egllog.h b/src/egl/main/egllog.h index 83c8bb72a6..3a99bfea4b 100644 --- a/src/egl/main/egllog.h +++ b/src/egl/main/egllog.h @@ -12,15 +12,15 @@ typedef void (*_EGLLogProc)(EGLint level, const char *msg); -extern void +PUBLIC void _eglSetLogProc(_EGLLogProc logger); -extern void +PUBLIC void _eglSetLogLevel(EGLint level); -extern void +PUBLIC void _eglLog(EGLint level, const char *fmtStr, ...); diff --git a/src/egl/main/eglmode.h b/src/egl/main/eglmode.h index af7c2c56d3..a089a5e194 100644 --- a/src/egl/main/eglmode.h +++ b/src/egl/main/eglmode.h @@ -29,7 +29,7 @@ extern _EGLMode * _eglLookupMode(EGLModeMESA mode, _EGLDisplay *dpy); -extern _EGLMode * +PUBLIC _EGLMode * _eglAddNewMode(_EGLScreen *screen, EGLint width, EGLint height, EGLint refreshRate, const char *name); diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h index 8860a2aa7f..d52e5388c3 100644 --- a/src/egl/main/eglscreen.h +++ b/src/egl/main/eglscreen.h @@ -30,7 +30,7 @@ extern EGLScreenMESA _eglAllocScreenHandle(void); -extern void +PUBLIC void _eglInitScreen(_EGLScreen *screen); @@ -38,7 +38,7 @@ extern _EGLScreen * _eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *dpy); -extern void +PUBLIC void _eglAddScreen(_EGLDisplay *display, _EGLScreen *screen); @@ -83,7 +83,7 @@ extern void _eglDestroyScreenModes(_EGLScreen *scrn); -extern void +PUBLIC void _eglDestroyScreen(_EGLScreen *scrn); diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h index b75fa9c368..dacdf7e63c 100644 --- a/src/egl/main/eglsurface.h +++ b/src/egl/main/eglsurface.h @@ -40,7 +40,7 @@ struct _egl_surface }; -extern EGLBoolean +PUBLIC EGLBoolean _eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type, _EGLConfig *config, const EGLint *attrib_list); |