diff options
Diffstat (limited to 'src/egl/drivers')
-rw-r--r-- | src/egl/drivers/Makefile.template | 51 | ||||
-rw-r--r-- | src/egl/drivers/demo/Makefile | 32 | ||||
-rw-r--r-- | src/egl/drivers/demo/demo.c | 289 | ||||
-rw-r--r-- | src/egl/drivers/glx/Makefile | 75 | ||||
-rw-r--r-- | src/egl/drivers/glx/egl_glx.c | 109 | ||||
-rw-r--r-- | src/egl/drivers/xdri/Makefile | 82 | ||||
-rw-r--r-- | src/egl/drivers/xdri/driinit.c | 34 | ||||
-rw-r--r-- | src/egl/drivers/xdri/egl_xdri.c | 123 | ||||
-rw-r--r-- | src/egl/drivers/xdri/glxinit.c | 100 | ||||
-rw-r--r-- | src/egl/drivers/xdri/glxinit.h | 3 |
10 files changed, 317 insertions, 581 deletions
diff --git a/src/egl/drivers/Makefile.template b/src/egl/drivers/Makefile.template new file mode 100644 index 0000000000..e9a614ce62 --- /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)$(EGL_DRIVER_INSTALL_DIR) + $(MINSTALL) $(EGL_DRIVER_PATH) $(DESTDIR)$(EGL_DRIVER_INSTALL_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/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 7c6e8637a1..af653b86ee 100644 --- a/src/egl/drivers/glx/egl_glx.c +++ b/src/egl/drivers/glx/egl_glx.c @@ -43,7 +43,7 @@ #include "eglcontext.h" #include "egldisplay.h" #include "egldriver.h" -#include "eglglobals.h" +#include "eglcurrent.h" #include "egllog.h" #include "eglsurface.h" @@ -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 { @@ -110,6 +103,8 @@ struct GLX_egl_surface Drawable drawable; GLXDrawable glx_drawable; + + void (*destroy)(Display *, GLXDrawable); }; @@ -244,7 +239,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 +359,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 +554,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; @@ -638,6 +633,21 @@ GLX_eglCreateContext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, /** + * Destroy a surface. The display is allowed to be uninitialized. + */ +static void +destroy_surface(_EGLDisplay *disp, _EGLSurface *surf) +{ + struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf); + + if (GLX_surf->destroy) + GLX_surf->destroy(disp->NativeDisplay, GLX_surf->glx_drawable); + + free(GLX_surf); +} + + +/** * Called via eglMakeCurrent(), drv->API.MakeCurrent(). */ static EGLBoolean @@ -650,8 +660,10 @@ GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, struct GLX_egl_context *GLX_ctx = GLX_egl_context(ctx); GLXDrawable ddraw, rdraw; GLXContext cctx; + EGLBoolean ret = EGL_FALSE; - if (!_eglMakeCurrent(drv, disp, dsurf, rsurf, ctx)) + /* bind the new context and return the "orphaned" one */ + if (!_eglBindContext(&ctx, &dsurf, &rsurf)) return EGL_FALSE; ddraw = (GLX_dsurf) ? GLX_dsurf->glx_drawable : None; @@ -659,11 +671,21 @@ GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf, cctx = (GLX_ctx) ? GLX_ctx->context : NULL; if (GLX_dpy->have_make_current_read) - return glXMakeContextCurrent(GLX_dpy->dpy, ddraw, rdraw, cctx); + ret = glXMakeContextCurrent(GLX_dpy->dpy, ddraw, rdraw, cctx); else if (ddraw == rdraw) - return glXMakeCurrent(GLX_dpy->dpy, ddraw, cctx); + ret = glXMakeCurrent(GLX_dpy->dpy, ddraw, cctx); - return EGL_FALSE; + if (ret) { + if (dsurf && !_eglIsSurfaceLinked(dsurf)) + destroy_surface(disp, dsurf); + if (rsurf && rsurf != dsurf && !_eglIsSurfaceLinked(rsurf)) + destroy_surface(disp, rsurf); + } + else { + _eglBindContext(&ctx, &dsurf, &rsurf); + } + + return ret; } /** Get size of given window */ @@ -684,8 +706,9 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height) * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ static _EGLSurface * -GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, - NativeWindowType window, const EGLint *attrib_list) +GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, + _EGLConfig *conf, EGLNativeWindowType window, + const EGLint *attrib_list) { struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp); struct GLX_egl_surface *GLX_surf; @@ -718,6 +741,9 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, return NULL; } + if (GLX_dpy->have_1_3 && !GLX_dpy->glx_window_quirk) + GLX_surf->destroy = glXDestroyWindow; + get_drawable_size(GLX_dpy->dpy, window, &width, &height); GLX_surf->Base.Width = width; GLX_surf->Base.Height = height; @@ -726,8 +752,9 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, } static _EGLSurface * -GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, - NativePixmapType pixmap, const EGLint *attrib_list) +GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, + _EGLConfig *conf, EGLNativePixmapType pixmap, + const EGLint *attrib_list) { struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp); struct GLX_egl_surface *GLX_surf; @@ -774,6 +801,9 @@ GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, return NULL; } + GLX_surf->destroy = (GLX_dpy->have_1_3) ? + glXDestroyPixmap : glXDestroyGLXPixmap; + get_drawable_size(GLX_dpy->dpy, pixmap, &width, &height); GLX_surf->Base.Width = width; GLX_surf->Base.Height = height; @@ -838,47 +868,18 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp, return NULL; } + GLX_surf->destroy = (GLX_dpy->have_1_3) ? + glXDestroyPbuffer : GLX_dpy->glXDestroyGLXPbufferSGIX; + return &GLX_surf->Base; } + static EGLBoolean GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) { - struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp); - if (!_eglIsSurfaceBound(surf)) { - struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf); - - if (GLX_dpy->have_1_3) { - switch (surf->Type) { - case EGL_WINDOW_BIT: - if (!GLX_dpy->glx_window_quirk) - glXDestroyWindow(GLX_dpy->dpy, GLX_surf->glx_drawable); - break; - case EGL_PBUFFER_BIT: - glXDestroyPbuffer(GLX_dpy->dpy, GLX_surf->glx_drawable); - break; - case EGL_PIXMAP_BIT: - glXDestroyPixmap(GLX_dpy->dpy, GLX_surf->glx_drawable); - break; - default: - break; - } - } - else { - switch (surf->Type) { - case EGL_PBUFFER_BIT: - GLX_dpy->glXDestroyGLXPbufferSGIX(GLX_dpy->dpy, - GLX_surf->glx_drawable); - break; - case EGL_PIXMAP_BIT: - glXDestroyGLXPixmap(GLX_dpy->dpy, GLX_surf->glx_drawable); - break; - default: - break; - } - } - free(surf); - } + if (!_eglIsSurfaceBound(surf)) + destroy_surface(disp, surf); return EGL_TRUE; } 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 8425b3d11e..9c21576539 100644 --- a/src/egl/drivers/xdri/egl_xdri.c +++ b/src/egl/drivers/xdri/egl_xdri.c @@ -52,7 +52,7 @@ #include "eglcontext.h" #include "egldisplay.h" #include "egldriver.h" -#include "eglglobals.h" +#include "eglcurrent.h" #include "egllog.h" #include "eglsurface.h" @@ -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; @@ -417,19 +419,47 @@ xdri_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, } -static EGLBoolean -xdri_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) +/** + * Destroy a context. + */ +static void +destroy_context(_EGLDisplay *dpy, _EGLContext *ctx) { struct xdri_egl_display *xdri_dpy = lookup_display(dpy); struct xdri_egl_context *xdri_ctx = lookup_context(ctx); - if (!_eglIsContextBound(ctx)) { - xdri_ctx->driContext->destroyContext(xdri_ctx->driContext, - xdri_dpy->psc, xdri_dpy->dpy); - free(xdri_ctx->dummy_gc); - free(xdri_ctx); - } + /* FIXME a context might live longer than its display */ + if (!dpy->Initialized) + _eglLog(_EGL_FATAL, "destroy a context with an unitialized display"); + xdri_ctx->driContext->destroyContext(xdri_ctx->driContext, + xdri_dpy->psc, xdri_dpy->dpy); + free(xdri_ctx->dummy_gc); + free(xdri_ctx); +} + + +/** + * Destroy a surface. + */ +static void +destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf) +{ + struct xdri_egl_surface *xdri_surf = lookup_surface(surf); + + if (!dpy->Initialized) + _eglLog(_EGL_FATAL, "destroy a surface with an unitialized display"); + + xdri_surf->driDrawable->destroyDrawable(xdri_surf->driDrawable); + free(xdri_surf); +} + + +static EGLBoolean +xdri_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) +{ + if (!_eglIsContextBound(ctx)) + destroy_context(dpy, ctx); return EGL_TRUE; } @@ -441,13 +471,19 @@ 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); - if (!_eglMakeCurrent(drv, dpy, d, r, context)) + /* bind the new context and return the "orphaned" one */ + if (!_eglBindContext(&context, &d, &r)) return EGL_FALSE; + /* flush before context switch */ + if (context && xdri_driver->FlushCurrentContext) + xdri_driver->FlushCurrentContext(); + /* the symbol is defined in libGL.so */ _glapi_check_multithread(); @@ -458,14 +494,18 @@ 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 (context) { + xdri_ctx = lookup_context(context); + xdri_ctx->driContext->unbindContext(xdri_ctx->driContext); } + if (context && !_eglIsContextLinked(context)) + destroy_context(dpy, context); + if (d && !_eglIsSurfaceLinked(d)) + destroy_surface(dpy, d); + if (r && r != d && !_eglIsSurfaceLinked(r)) + destroy_surface(dpy, r); + return EGL_TRUE; } @@ -475,7 +515,8 @@ xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d, */ static _EGLSurface * xdri_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, - NativeWindowType window, const EGLint *attrib_list) + EGLNativeWindowType window, + const EGLint *attrib_list) { struct xdri_egl_display *xdri_dpy = lookup_display(dpy); struct xdri_egl_config *xdri_config = lookup_config(conf); @@ -529,13 +570,8 @@ xdri_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf static EGLBoolean xdri_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface) { - struct xdri_egl_surface *xdri_surf = lookup_surface(surface); - - if (!_eglIsSurfaceBound(&xdri_surf->Base)) { - xdri_surf->driDrawable->destroyDrawable(xdri_surf->driDrawable); - free(xdri_surf); - } - + if (!_eglIsSurfaceBound(surface)) + destroy_surface(dpy, surface); return EGL_TRUE; } @@ -559,9 +595,14 @@ 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); + /* swapBuffers does not flush commands */ + if (draw->CurrentContext && xdri_driver->FlushCurrentContext) + xdri_driver->FlushCurrentContext(); + xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable, 0, 0, 0); return EGL_TRUE; @@ -606,5 +647,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..ba6132788a 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,8 +33,26 @@ typedef struct GLXGenericGetString static char *__glXExtensionName = GLX_EXTENSION_NAME; static XExtensionInfo *__glXExtensionInfo = NULL; -static /* const */ XExtensionHooks __glXExtensionHooks = { NULL }; -static +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 */ +}; + XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, __glXExtensionName, &__glXExtensionHooks, __GLX_NUMBER_EVENTS, NULL) @@ -180,6 +200,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 +614,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 +663,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 */ |