X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fwinsys%2Fegl_xlib%2Fegl_xlib.c;h=1d9bac3871c8462c70183242fada9c7771dc1719;hb=a1306f4ef6f83a86d03720641f3cdc5e13485fa6;hp=ed7eab50ddab5d2244802ab9ceff580b7f35e68a;hpb=2f2cf461c57974abd89e4917945cc8ae6a67a72e;p=mesa.git diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index ed7eab50dda..1d9bac3871c 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -33,6 +33,7 @@ #include +#include #include #include "pipe/p_compiler.h" @@ -40,6 +41,7 @@ #include "pipe/p_state.h" #include "pipe/internal/p_winsys_screen.h" #include "util/u_memory.h" +#include "util/u_math.h" #include "softpipe/sp_winsys.h" #include "softpipe/sp_texture.h" @@ -61,6 +63,14 @@ struct xlib_egl_driver { _EGLDriver Base; /**< base class */ + EGLint apis; +}; + + +/** driver data of _EGLDisplay */ +struct xlib_egl_display +{ + Display *Dpy; struct pipe_winsys *winsys; struct pipe_screen *screen; @@ -94,6 +104,12 @@ struct xlib_egl_surface }; +static void +flush_frontbuffer(struct pipe_winsys *pws, + struct pipe_surface *psurf, + void *context_private); + + /** cast wrapper */ static INLINE struct xlib_egl_driver * xlib_egl_driver(_EGLDriver *drv) @@ -102,6 +118,13 @@ xlib_egl_driver(_EGLDriver *drv) } +static INLINE struct xlib_egl_display * +xlib_egl_display(_EGLDisplay *dpy) +{ + return (struct xlib_egl_display *) dpy->DriverData; +} + + static INLINE struct xlib_egl_surface * lookup_surface(_EGLSurface *surf) { @@ -116,22 +139,11 @@ lookup_context(_EGLContext *ctx) } -static unsigned int -bitcount(unsigned int n) -{ - unsigned int bits; - for (bits = 0; n > 0; n = n >> 1) { - bits += (n & 1); - } - return bits; -} - - /** * Create the EGLConfigs. (one per X visual) */ static void -create_configs(_EGLDriver *drv, _EGLDisplay *disp) +create_configs(struct xlib_egl_display *xdpy, _EGLDisplay *disp) { static const EGLint all_apis = (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT | @@ -141,8 +153,8 @@ create_configs(_EGLDriver *drv, _EGLDisplay *disp) int num_visuals, i; /* get list of all X visuals, create an EGL config for each */ - visTemplate.screen = DefaultScreen(disp->Xdpy); - visInfo = XGetVisualInfo(disp->Xdpy, VisualScreenMask, + visTemplate.screen = DefaultScreen(xdpy->Dpy); + visInfo = XGetVisualInfo(xdpy->Dpy, VisualScreenMask, &visTemplate, &num_visuals); if (!visInfo) { printf("egl_xlib.c: couldn't get any X visuals\n"); @@ -152,9 +164,9 @@ create_configs(_EGLDriver *drv, _EGLDisplay *disp) for (i = 0; i < num_visuals; i++) { _EGLConfig *config = calloc(1, sizeof(_EGLConfig)); int id = i + 1; - int rbits = bitcount(visInfo[i].red_mask); - int gbits = bitcount(visInfo[i].green_mask); - int bbits = bitcount(visInfo[i].blue_mask); + int rbits = util_bitcount(visInfo[i].red_mask); + int gbits = util_bitcount(visInfo[i].green_mask); + int bbits = util_bitcount(visInfo[i].blue_mask); int abits = bbits == 8 ? 8 : 0; int zbits = 24; int sbits = 8; @@ -184,6 +196,8 @@ create_configs(_EGLDriver *drv, _EGLDisplay *disp) _eglAddConfig(disp, config); } + + XFree(visInfo); } @@ -192,15 +206,46 @@ create_configs(_EGLDriver *drv, _EGLDisplay *disp) */ static EGLBoolean xlib_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy, - EGLint *minor, EGLint *major) + EGLint *major, EGLint *minor) { - create_configs(drv, dpy); + struct xlib_egl_driver *xdrv = xlib_egl_driver(drv); + struct xlib_egl_display *xdpy; + + xdpy = CALLOC_STRUCT(xlib_egl_display); + if (!xdpy) + return _eglError(EGL_BAD_ALLOC, "eglInitialize"); + + xdpy->Dpy = (Display *) dpy->NativeDisplay; + if (!xdpy->Dpy) { + xdpy->Dpy = XOpenDisplay(NULL); + if (!xdpy->Dpy) { + free(xdpy); + return EGL_FALSE; + } + } + + /* create winsys and pipe screen */ + xdpy->winsys = create_sw_winsys(); + if (!xdpy->winsys) { + free(xdpy); + return _eglError(EGL_BAD_ALLOC, "eglInitialize"); + } + xdpy->winsys->flush_frontbuffer = flush_frontbuffer; + xdpy->screen = softpipe_create_screen(xdpy->winsys); + if (!xdpy->screen) { + free(xdpy->winsys); + free(xdpy); + return _eglError(EGL_BAD_ALLOC, "eglInitialize"); + } + + dpy->DriverData = (void *) xdpy; + dpy->ClientAPIsMask = xdrv->apis; - drv->Initialized = EGL_TRUE; + create_configs(xdpy, dpy); /* we're supporting EGL 1.4 */ - *minor = 1; - *major = 4; + *major = 1; + *minor = 4; return EGL_TRUE; } @@ -212,12 +257,24 @@ xlib_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy, static EGLBoolean xlib_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy) { + struct xlib_egl_display *xdpy = xlib_egl_display(dpy); + + _eglReleaseDisplayResources(drv, dpy); + _eglCleanupDisplay(dpy); + + xdpy->screen->destroy(xdpy->screen); + free(xdpy->winsys); + + if (!dpy->NativeDisplay) + XCloseDisplay(xdpy->Dpy); + free(xdpy); + return EGL_TRUE; } static _EGLProc -xlib_eglGetProcAddress(const char *procname) +xlib_eglGetProcAddress(_EGLDriver *drv, const char *procname) { return (_EGLProc) st_get_proc_address(procname); } @@ -343,7 +400,7 @@ static _EGLContext * xlib_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list) { - struct xlib_egl_driver *xdrv = xlib_egl_driver(drv); + struct xlib_egl_display *xdpy = xlib_egl_display(dpy); struct xlib_egl_context *ctx; struct st_context *share_ctx = NULL; /* XXX fix */ __GLcontextModes visual; @@ -367,7 +424,7 @@ xlib_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, /* fall-through */ case EGL_OPENGL_API: /* create a softpipe context */ - ctx->pipe = softpipe_create(xdrv->screen); + ctx->pipe = softpipe_create(xdpy->screen); /* Now do xlib / state tracker inits here */ _eglConfigToContextModesRec(conf, &visual); ctx->Context = st_create_context(ctx->pipe, &visual, share_ctx); @@ -415,14 +472,19 @@ xlib_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, struct xlib_egl_context *context = lookup_context(ctx); struct xlib_egl_surface *draw_surf = lookup_surface(draw); struct xlib_egl_surface *read_surf = lookup_surface(read); - struct st_context *oldctx = st_get_current(); + struct st_context *oldcontext = NULL; + _EGLContext *oldctx; + + oldctx = _eglGetCurrentContext(); + if (oldctx && _eglIsContextLinked(oldctx)) + oldcontext = st_get_current(); if (!_eglMakeCurrent(drv, dpy, draw, read, ctx)) return EGL_FALSE; /* Flush before switching context. Check client API? */ - if (oldctx) - st_flush(oldctx, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); + if (oldcontext) + st_flush(oldcontext, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); st_make_current((context ? context->Context : NULL), (draw_surf ? draw_surf->Framebuffer : NULL), (read_surf ? read_surf->Framebuffer : NULL)); @@ -480,7 +542,7 @@ static _EGLSurface * xlib_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list) { - struct xlib_egl_driver *xdrv = xlib_egl_driver(drv); + struct xlib_egl_display *xdpy = xlib_egl_display(disp); struct xlib_egl_surface *surf; __GLcontextModes visual; uint width, height; @@ -500,10 +562,10 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf * Now init the Xlib and gallium stuff */ surf->Win = (Window) window; /* The X window ID */ - surf->Dpy = disp->Xdpy; /* The X display */ + surf->Dpy = xdpy->Dpy; /* The X display */ surf->Gc = XCreateGC(surf->Dpy, surf->Win, 0, NULL); - surf->winsys = xdrv->winsys; + surf->winsys = xdpy->winsys; _eglConfigToContextModesRec(conf, &visual); get_drawable_size(surf->Dpy, surf->Win, &width, &height); @@ -530,7 +592,7 @@ static _EGLSurface * xlib_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, const EGLint *attrib_list) { - struct xlib_egl_driver *xdrv = xlib_egl_driver(drv); + struct xlib_egl_display *xdpy = xlib_egl_display(disp); struct xlib_egl_surface *surf; __GLcontextModes visual; uint width, height; @@ -575,7 +637,7 @@ xlib_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *con return NULL; } - surf->winsys = xdrv->winsys; + surf->winsys = xdpy->winsys; _eglConfigToContextModesRec(conf, &visual); @@ -689,24 +751,18 @@ xlib_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, static EGLBoolean xlib_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw) { - /* error checking step: */ - if (!_eglSwapBuffers(drv, dpy, draw)) - return EGL_FALSE; + struct xlib_egl_surface *xsurf = lookup_surface(draw); + struct pipe_winsys *pws = xsurf->winsys; + struct pipe_surface *psurf; - { - struct xlib_egl_surface *xsurf = lookup_surface(draw); - struct pipe_winsys *pws = xsurf->winsys; - struct pipe_surface *psurf; + st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT, + &psurf); - st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT, - &psurf); + st_notify_swapbuffers(xsurf->Framebuffer); - st_notify_swapbuffers(xsurf->Framebuffer); + display_surface(pws, psurf, xsurf); - display_surface(pws, psurf, xsurf); - - check_and_update_buffer_size(xsurf); - } + check_and_update_buffer_size(xsurf); return EGL_TRUE; } @@ -744,12 +800,20 @@ find_supported_apis(void) } +static void +xlib_Unload(_EGLDriver *drv) +{ + struct xlib_egl_driver *xdrv = xlib_egl_driver(drv); + free(xdrv); +} + + /** * This is the main entrypoint into the driver. * Called by libEGL to instantiate an _EGLDriver object. */ _EGLDriver * -_eglMain(_EGLDisplay *dpy, const char *args) +_eglMain(const char *args) { struct xlib_egl_driver *xdrv; @@ -759,10 +823,6 @@ _eglMain(_EGLDisplay *dpy, const char *args) if (!xdrv) return NULL; - if (!dpy->Xdpy) { - dpy->Xdpy = XOpenDisplay(NULL); - } - _eglInitDriverFallbacks(&xdrv->Base); xdrv->Base.API.Initialize = xlib_eglInitialize; xdrv->Base.API.Terminate = xlib_eglTerminate; @@ -777,22 +837,17 @@ _eglMain(_EGLDisplay *dpy, const char *args) xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent; xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers; - xdrv->Base.ClientAPIsMask = find_supported_apis(); - if (xdrv->Base.ClientAPIsMask == 0x0) { + xdrv->apis = find_supported_apis(); + if (xdrv->apis == 0x0) { /* the app isn't directly linked with any EGL-supprted APIs * (such as libGLESv2.so) so use an EGL utility to see what * APIs might be loaded dynamically on this system. */ - xdrv->Base.ClientAPIsMask = _eglFindAPIs(); - } + xdrv->apis = _eglFindAPIs(); + } xdrv->Base.Name = "Xlib/softpipe"; - - /* create one winsys and use it for all contexts/surfaces */ - xdrv->winsys = create_sw_winsys(); - xdrv->winsys->flush_frontbuffer = flush_frontbuffer; - - xdrv->screen = softpipe_create_screen(xdrv->winsys); + xdrv->Base.Unload = xlib_Unload; return &xdrv->Base; }