diff options
26 files changed, 556 insertions, 424 deletions
diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile index e117f15d93..9e9e479e7e 100644 --- a/src/gallium/state_trackers/egl/Makefile +++ b/src/gallium/state_trackers/egl/Makefile @@ -5,14 +5,12 @@ common_INCLUDES = \ -I. \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/auxiliary \ - -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/egl/main \ -I$(TOP)/include common_SOURCES = $(wildcard common/*.c) common_OBJECTS = $(common_SOURCES:.c=.o) - x11_INCLUDES = \ -I$(TOP)/src/gallium/drivers \ -I$(TOP)/src/glx \ @@ -31,7 +29,7 @@ kms_SOURCES = $(wildcard kms/*.c) kms_OBJECTS = $(kms_SOURCES:.c=.o) -fbdev_INCLUDES = -I$(TOP)/src/gallium/winsys/sw -I$(TOP)/src/gallium/drivers +fbdev_INCLUDES = -I$(TOP)/src/gallium/winsys/sw fbdev_SOURCES = $(wildcard fbdev/*.c) fbdev_OBJECTS = $(fbdev_SOURCES:.c=.o) @@ -40,7 +38,7 @@ ALL_INCLUDES = $(common_INCLUDES) $(x11_INCLUDES) $(kms_INCLUDES) $(fbdev_INCLUD ALL_SOURCES = $(common_SOURCES) $(x11_SOURCES) $(kms_SOURCES) $(fbdev_SOURCES) EGL_OBJECTS = $(common_OBJECTS) -EGL_CPPFLAGS = $(common_INCLUDES) -DST_MODULE_PREFIX=\"st_\" +EGL_CPPFLAGS = $(common_INCLUDES) # add backends ifneq ($(findstring x11, $(EGL_PLATFORMS)),) diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index 36354dd42e..494d6dd8b6 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -35,34 +35,10 @@ #include "egl_g3d.h" #include "egl_g3d_api.h" #include "egl_g3d_st.h" +#include "egl_g3d_loader.h" #include "native.h" /** - * Initialize the state trackers. - */ -static void -egl_g3d_init_st(_EGLDriver *drv) -{ - struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); - EGLint i; - - /* already initialized */ - if (gdrv->api_mask) - return; - - egl_g3d_init_st_apis(gdrv->stapis); - for (i = 0; i < ST_API_COUNT; i++) { - if (gdrv->stapis[i]) - gdrv->api_mask |= egl_g3d_st_api_bit(i); - } - - if (gdrv->api_mask) - _eglLog(_EGL_DEBUG, "Driver API mask: 0x%x", gdrv->api_mask); - else - _eglLog(_EGL_WARNING, "No supported client API"); -} - -/** * Get the native platform. */ static const struct native_platform * @@ -323,7 +299,6 @@ egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const struct native_config *nconf, enum pipe_format depth_stencil_format) { - struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); struct egl_g3d_config *gconf = egl_g3d_config(conf); EGLint buffer_mask, api_mask; EGLBoolean valid; @@ -347,7 +322,7 @@ egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy, gconf->stvis.render_buffer = (buffer_mask & ST_ATTACHMENT_BACK_LEFT_MASK) ? ST_ATTACHMENT_BACK_LEFT : ST_ATTACHMENT_FRONT_LEFT; - api_mask = gdrv->api_mask;; + api_mask = dpy->ClientAPIsMask; /* this is required by EGL, not by OpenGL ES */ if (nconf->window_bit && gconf->stvis.render_buffer != ST_ATTACHMENT_BACK_LEFT) @@ -472,8 +447,26 @@ egl_g3d_invalid_surface(struct native_display *ndpy, gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi); } +static struct pipe_screen * +egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd) +{ + _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data; + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + return gdpy->loader->create_drm_screen(name, fd); +} + +static struct pipe_screen * +egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws) +{ + _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data; + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + return gdpy->loader->create_sw_screen(ws); +} + static struct native_event_handler egl_g3d_native_event_handler = { - egl_g3d_invalid_surface + egl_g3d_invalid_surface, + egl_g3d_new_drm_screen, + egl_g3d_new_sw_screen }; static EGLBoolean @@ -529,20 +522,25 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, _eglError(EGL_BAD_ALLOC, "eglInitialize"); goto fail; } + gdpy->loader = gdrv->loader; dpy->DriverData = gdpy; _eglLog(_EGL_INFO, "use %s for display %p", nplat->name, dpy->PlatformDisplay); gdpy->native = nplat->create_display(dpy->PlatformDisplay, - &egl_g3d_native_event_handler); + &egl_g3d_native_event_handler, (void *) dpy); if (!gdpy->native) { _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)"); goto fail; } - gdpy->native->user_data = (void *) dpy; - - egl_g3d_init_st(&gdrv->base); - dpy->ClientAPIsMask = gdrv->api_mask; + if (gdpy->loader->api_mask & (1 << ST_API_OPENGL)) + dpy->ClientAPIsMask |= EGL_OPENGL_BIT; + if (gdpy->loader->api_mask & (1 << ST_API_OPENGL_ES1)) + dpy->ClientAPIsMask |= EGL_OPENGL_ES_BIT; + if (gdpy->loader->api_mask & (1 << ST_API_OPENGL_ES2)) + dpy->ClientAPIsMask |= EGL_OPENGL_ES2_BIT; + if (gdpy->loader->api_mask & (1 << ST_API_OPENVG)) + dpy->ClientAPIsMask |= EGL_OPENVG_BIT; gdpy->smapi = egl_g3d_create_st_manager(dpy); if (!gdpy->smapi) { @@ -583,22 +581,15 @@ static _EGLProc egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname) { struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); - _EGLProc proc; - EGLint i; + struct st_api *stapi = NULL; - /* in case this is called before a display is initialized */ - egl_g3d_init_st(&gdrv->base); - - for (i = 0; i < ST_API_COUNT; i++) { - struct st_api *stapi = gdrv->stapis[i]; - if (stapi) { - proc = (_EGLProc) stapi->get_proc_address(stapi, procname); - if (proc) - return proc; - } - } + if (procname && procname[0] == 'v' && procname[1] == 'g') + stapi = gdrv->loader->get_st_api(ST_API_OPENVG); + else if (procname && procname[0] == 'g' && procname[1] == 'l') + stapi = gdrv->loader->guess_gl_api(); - return (_EGLProc) NULL; + return (_EGLProc) ((stapi) ? + stapi->get_proc_address(stapi, procname) : NULL); } static EGLint @@ -628,18 +619,8 @@ egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy) return score; } -static void -egl_g3d_unload(_EGLDriver *drv) -{ - struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); - - egl_g3d_destroy_st_apis(); - egl_g3d_destroy_probe(drv, NULL); - FREE(gdrv); -} - _EGLDriver * -_eglMain(const char *args) +egl_g3d_create_driver(const struct egl_g3d_loader *loader) { struct egl_g3d_driver *gdrv; @@ -647,17 +628,28 @@ _eglMain(const char *args) if (!gdrv) return NULL; + gdrv->loader = loader; + egl_g3d_init_driver_api(&gdrv->base); gdrv->base.API.Initialize = egl_g3d_initialize; gdrv->base.API.Terminate = egl_g3d_terminate; gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address; - gdrv->base.Name = "Gallium"; gdrv->base.Probe = egl_g3d_probe; - gdrv->base.Unload = egl_g3d_unload; /* the key is " EGL G3D" */ gdrv->probe_key = 0x0E61063D; + /* to be filled by the caller */ + gdrv->base.Name = NULL; + gdrv->base.Unload = NULL; + return &gdrv->base; } + +void +egl_g3d_destroy_driver(_EGLDriver *drv) +{ + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); + FREE(gdrv); +} diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h index a498dcf6f6..d9ecb208e0 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.h +++ b/src/gallium/state_trackers/egl/common/egl_g3d.h @@ -41,12 +41,11 @@ #include "native.h" #include "egl_g3d_st.h" +#include "egl_g3d_loader.h" struct egl_g3d_driver { _EGLDriver base; - struct st_api *stapis[ST_API_COUNT]; - EGLint api_mask; - + const struct egl_g3d_loader *loader; const struct native_platform *platforms[_EGL_NUM_PLATFORMS]; EGLint probe_key; }; @@ -54,6 +53,7 @@ struct egl_g3d_driver { struct egl_g3d_display { struct native_display *native; + const struct egl_g3d_loader *loader; struct st_manager *smapi; struct pipe_context *pipe; }; diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c index 255a1fb730..308fa96d99 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c @@ -35,6 +35,7 @@ #include "egl_g3d_api.h" #include "egl_g3d_image.h" #include "egl_g3d_st.h" +#include "egl_g3d_loader.h" #include "native.h" /** @@ -44,7 +45,6 @@ static struct st_api * egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx) { struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); - struct st_api *stapi; EGLint idx = -1; switch (ctx->ClientAPI) { @@ -73,8 +73,7 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx) break; } - stapi = (idx >= 0) ? gdrv->stapis[idx] : NULL; - return stapi; + return (idx >= 0) ? gdrv->loader->get_st_api(idx) : NULL; } static _EGLContext * diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_loader.h b/src/gallium/state_trackers/egl/common/egl_g3d_loader.h new file mode 100644 index 0000000000..c9141f8ad4 --- /dev/null +++ b/src/gallium/state_trackers/egl/common/egl_g3d_loader.h @@ -0,0 +1,54 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Chia-I Wu <olv@lunarg.com> + */ + +#ifndef _EGL_G3D_LOADER_H_ +#define _EGL_G3D_LOADER_H_ + +#include "pipe/p_compiler.h" +#include "state_tracker/st_api.h" +#include "egltypedefs.h" + +struct pipe_screen; +struct sw_winsys; + +struct egl_g3d_loader { + uint api_mask; + struct st_api *(*get_st_api)(enum st_api_type api); + struct st_api *(*guess_gl_api)(void); + + struct pipe_screen *(*create_drm_screen)(const char *name, int fd); + struct pipe_screen *(*create_sw_screen)(struct sw_winsys *ws); +}; + +_EGLDriver * +egl_g3d_create_driver(const struct egl_g3d_loader *loader); + +void +egl_g3d_destroy_driver(_EGLDriver *drv); + +#endif /* _EGL_G3D_LOADER_H_ */ diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c index 0668f5c91a..05cdb0d421 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c @@ -49,173 +49,6 @@ egl_g3d_st_manager(struct st_manager *smapi) return (struct egl_g3d_st_manager *) smapi; } -static struct egl_g3d_st_module { - const char *filename; - struct util_dl_library *lib; - struct st_api *stapi; -} egl_g3d_st_modules[ST_API_COUNT]; - -static EGLBoolean -egl_g3d_search_path_callback(const char *dir, size_t len, void *callback_data) -{ - struct egl_g3d_st_module *stmod = - (struct egl_g3d_st_module *) callback_data; - char path[1024]; - int ret; - - if (!len) { - stmod->lib = util_dl_open(stmod->filename); - return !(stmod->lib); - } - - ret = util_snprintf(path, sizeof(path), - "%.*s/%s", len, dir, stmod->filename); - if (ret > 0 && ret < sizeof(path)) - stmod->lib = util_dl_open(path); - - return !(stmod->lib); -} - -static boolean -egl_g3d_load_st_module(struct egl_g3d_st_module *stmod, - const char *filename, const char *procname) -{ - struct st_api *(*create_api)(void); - - stmod->filename = filename; - if (stmod->filename) - _eglSearchPathForEach(egl_g3d_search_path_callback, (void *) stmod); - else - stmod->lib = util_dl_open(NULL); - - if (stmod->lib) { - create_api = (struct st_api *(*)(void)) - util_dl_get_proc_address(stmod->lib, procname); - if (create_api) - stmod->stapi = create_api(); - - if (!stmod->stapi) { - util_dl_close(stmod->lib); - stmod->lib = NULL; - } - } - - if (stmod->stapi) { - return TRUE; - } - else { - stmod->filename = NULL; - return FALSE; - } -} - -#ifdef PIPE_OS_WINDOWS -#define ST_MODULE_SUFFIX ".dll" -#else -#define ST_MODULE_SUFFIX ".so" -#endif - -void -egl_g3d_init_st_apis(struct st_api *stapis[ST_API_COUNT]) -{ - const char *skip_checks[ST_API_COUNT], *symbols[ST_API_COUNT]; - const char *filenames[ST_API_COUNT][4]; - struct util_dl_library *self; - int num_needed = 0, api; - - self = util_dl_open(NULL); - - /* collect the necessary data for loading modules */ - for (api = 0; api < ST_API_COUNT; api++) { - int count = 0; - - switch (api) { - case ST_API_OPENGL: - skip_checks[api] = "glColor4d"; - symbols[api] = ST_CREATE_OPENGL_SYMBOL; - filenames[api][count++] = ST_MODULE_PREFIX "GL" ST_MODULE_SUFFIX; - break; - case ST_API_OPENGL_ES1: - skip_checks[api] = "glColor4x"; - symbols[api] = ST_CREATE_OPENGL_ES1_SYMBOL; - filenames[api][count++] = ST_MODULE_PREFIX "GLESv1_CM" ST_MODULE_SUFFIX; - filenames[api][count++] = ST_MODULE_PREFIX "GL" ST_MODULE_SUFFIX; - break; - case ST_API_OPENGL_ES2: - skip_checks[api] = "glShaderBinary"; - symbols[api] = ST_CREATE_OPENGL_ES2_SYMBOL; - filenames[api][count++] = ST_MODULE_PREFIX "GLESv2" ST_MODULE_SUFFIX; - filenames[api][count++] = ST_MODULE_PREFIX "GL" ST_MODULE_SUFFIX; - break; - case ST_API_OPENVG: - skip_checks[api] = "vgClear"; - symbols[api] = ST_CREATE_OPENVG_SYMBOL; - filenames[api][count++]= ST_MODULE_PREFIX "OpenVG" ST_MODULE_SUFFIX; - break; - default: - assert(!"Unknown API Type\n"); - skip_checks[api] = NULL; - symbols[api] = NULL; - break; - } - filenames[api][count++]= NULL; - assert(count < Elements(filenames[api])); - - /* heuristicically decide if the module is needed */ - if (!self || !skip_checks[api] || - util_dl_get_proc_address(self, skip_checks[api])) { - /* unset so the module is not skipped */ - skip_checks[api] = NULL; - num_needed++; - } - } - /* mark all moudles needed if we wrongly decided that none is needed */ - if (!num_needed) - memset(skip_checks, 0, sizeof(skip_checks)); - - if (self) - util_dl_close(self); - - for (api = 0; api < ST_API_COUNT; api++) { - struct egl_g3d_st_module *stmod = &egl_g3d_st_modules[api]; - const char **p; - - /* skip the module */ - if (skip_checks[api]) - continue; - - /* try all filenames, including NULL */ - for (p = filenames[api]; *p; p++) { - if (egl_g3d_load_st_module(stmod, *p, symbols[api])) - break; - } - if (!stmod->stapi) - egl_g3d_load_st_module(stmod, NULL, symbols[api]); - - stapis[api] = stmod->stapi; - } -} - -void -egl_g3d_destroy_st_apis(void) -{ - int api; - - for (api = 0; api < ST_API_COUNT; api++) { - struct egl_g3d_st_module *stmod = &egl_g3d_st_modules[api]; - - if (stmod->stapi) { - stmod->stapi->destroy(stmod->stapi); - stmod->stapi = NULL; - } - if (stmod->lib) { - util_dl_close(stmod->lib); - stmod->lib = NULL; - } - stmod->filename = NULL; - } -} - static boolean egl_g3d_st_manager_get_egl_image(struct st_manager *smapi, struct st_context_iface *stctx, diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.h b/src/gallium/state_trackers/egl/common/egl_g3d_st.h index ee53799b02..aa25cc042d 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_st.h +++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.h @@ -33,12 +33,6 @@ #include "state_tracker/st_api.h" #include "egltypedefs.h" -void -egl_g3d_init_st_apis(struct st_api *stapis[ST_API_COUNT]); - -void -egl_g3d_destroy_st_apis(void); - struct st_manager * egl_g3d_create_st_manager(_EGLDisplay *dpy); diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h index c4d23bf541..7e84d74ea7 100644 --- a/src/gallium/state_trackers/egl/common/native.h +++ b/src/gallium/state_trackers/egl/common/native.h @@ -32,6 +32,7 @@ #include "pipe/p_screen.h" #include "pipe/p_context.h" #include "pipe/p_state.h" +#include "state_tracker/sw_winsys.h" #include "native_probe.h" #include "native_modeset.h" @@ -196,6 +197,11 @@ struct native_event_handler { void (*invalid_surface)(struct native_display *ndpy, struct native_surface *nsurf, unsigned int seq_num); + + struct pipe_screen *(*new_drm_screen)(struct native_display *ndpy, + const char *name, int fd); + struct pipe_screen *(*new_sw_screen)(struct native_display *ndpy, + struct sw_winsys *ws); }; /** @@ -225,7 +231,8 @@ struct native_platform { enum native_probe_result (*get_probe_result)(struct native_probe *nprobe); struct native_display *(*create_display)(void *dpy, - struct native_event_handler *handler); + struct native_event_handler *handler, + void *user_data); }; const struct native_platform * diff --git a/src/gallium/state_trackers/egl/common/native_helper.c b/src/gallium/state_trackers/egl/common/native_helper.c index 206817ed66..7832b2b693 100644 --- a/src/gallium/state_trackers/egl/common/native_helper.c +++ b/src/gallium/state_trackers/egl/common/native_helper.c @@ -31,9 +31,6 @@ #include "pipe/p_screen.h" #include "pipe/p_context.h" #include "pipe/p_state.h" -#include "softpipe/sp_public.h" -#include "llvmpipe/lp_public.h" -#include "target-helpers/wrap_screen.h" #include "native_helper.h" @@ -236,18 +233,3 @@ resource_surface_present(struct resource_surface *rsurf, return TRUE; } - -struct pipe_screen * -native_create_sw_screen(struct sw_winsys *ws) -{ - struct pipe_screen *screen = NULL; - -#if defined(GALLIUM_LLVMPIPE) - if (!screen && !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE)) - screen = llvmpipe_create_screen(ws); -#endif - if (!screen) - screen = softpipe_create_screen(ws); - - return (screen) ? gallium_wrap_screen(screen) : NULL; -} diff --git a/src/gallium/state_trackers/egl/common/native_helper.h b/src/gallium/state_trackers/egl/common/native_helper.h index bdb9629466..d1569ac3ea 100644 --- a/src/gallium/state_trackers/egl/common/native_helper.h +++ b/src/gallium/state_trackers/egl/common/native_helper.h @@ -69,6 +69,3 @@ boolean resource_surface_present(struct resource_surface *rsurf, enum native_attachment which, void *winsys_drawable_handle); - -struct pipe_screen * -native_create_sw_screen(struct sw_winsys *ws); diff --git a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c index c0bc7b2462..7c276c22f8 100644 --- a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c +++ b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c @@ -386,8 +386,10 @@ fbdev_display_init(struct native_display *ndpy) return FALSE; ws = fbdev_create_sw_winsys(fbdpy->fd, fbdpy->config.color_format); - if (ws) - fbdpy->base.screen = native_create_sw_screen(ws); + if (ws) { + fbdpy->base.screen = + fbdpy->event_handler->new_sw_screen(&fbdpy->base, ws); + } if (fbdpy->base.screen) { if (!fbdpy->base.screen->is_format_supported(fbdpy->base.screen, @@ -402,7 +404,8 @@ fbdev_display_init(struct native_display *ndpy) } static struct native_display * -fbdev_display_create(int fd, struct native_event_handler *event_handler) +fbdev_display_create(int fd, struct native_event_handler *event_handler, + void *user_data) { struct fbdev_display *fbdpy; @@ -412,6 +415,7 @@ fbdev_display_create(int fd, struct native_event_handler *event_handler) fbdpy->fd = fd; fbdpy->event_handler = event_handler; + fbdpy->base.user_data = user_data; if (!fbdev_display_init(&fbdpy->base)) { FREE(fbdpy); @@ -428,7 +432,8 @@ fbdev_display_create(int fd, struct native_event_handler *event_handler) } static struct native_display * -native_create_display(void *dpy, struct native_event_handler *event_handler) +native_create_display(void *dpy, struct native_event_handler *event_handler, + void *user_data) { struct native_display *ndpy; int fd; @@ -443,7 +448,7 @@ native_create_display(void *dpy, struct native_event_handler *event_handler) if (fd < 0) return NULL; - ndpy = fbdev_display_create(fd, event_handler); + ndpy = fbdev_display_create(fd, event_handler, user_data); if (!ndpy) close(fd); diff --git a/src/gallium/state_trackers/egl/gdi/native_gdi.c b/src/gallium/state_trackers/egl/gdi/native_gdi.c index 4ec229a3f2..ed955c4132 100644 --- a/src/gallium/state_trackers/egl/gdi/native_gdi.c +++ b/src/gallium/state_trackers/egl/gdi/native_gdi.c @@ -343,10 +343,11 @@ gdi_display_destroy(struct native_display *ndpy) } static struct native_display * -gdi_create_display(HDC hDC, struct pipe_screen *screen, - struct native_event_handler *event_handler) +gdi_create_display(HDC hDC, struct native_event_handler *event_handler, + void *user_data) { struct gdi_display *gdpy; + struct sw_winsys *winsys; gdpy = CALLOC_STRUCT(gdi_display); if (!gdpy) @@ -354,8 +355,21 @@ gdi_create_display(HDC hDC, struct pipe_screen *screen, gdpy->hDC = hDC; gdpy->event_handler = event_handler; + gdpy->base.user_data = user_data; + + winsys = gdi_create_sw_winsys(); + if (!winsys) { + FREE(gdpy); + return NULL; + } - gdpy->base.screen = screen; + gdpy->base.screen = gdpy->event_handler->create_sw_screen(winsys); + if (!gdpy->base.screen) { + if (winsys->destroy) + winsys->destroy(winsys); + FREE(gdpy); + return NULL; + } gdpy->base.destroy = gdi_display_destroy; gdpy->base.get_param = gdi_display_get_param; @@ -367,23 +381,10 @@ gdi_create_display(HDC hDC, struct pipe_screen *screen, } static struct native_display * -native_create_display(void *dpy, struct native_event_handler *event_handler) +native_create_display(void *dpy, struct native_event_handler *event_handler, + void *user_data) { - struct sw_winsys *winsys; - struct pipe_screen *screen; - - winsys = gdi_create_sw_winsys(); - if (!winsys) - return NULL; - - screen = native_create_sw_screen(winsys); - if (!screen) { - if (winsys->destroy) - winsys->destroy(winsys); - return NULL; - } - - return gdi_create_display((HDC) dpy, screen, event_handler); + return gdi_create_display((HDC) dpy, event_handler, user_data); } static const struct native_platform gdi_platform = { diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c index dd4ea71140..5833d27a25 100644 --- a/src/gallium/state_trackers/egl/kms/native_kms.c +++ b/src/gallium/state_trackers/egl/kms/native_kms.c @@ -23,6 +23,10 @@ * DEALINGS IN THE SOFTWARE. */ +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + #include "pipe/p_screen.h" #include "pipe/p_context.h" #include "util/u_debug.h" @@ -33,7 +37,6 @@ #include "egllog.h" #include "native_kms.h" -#include "state_tracker/drm_driver.h" static boolean kms_surface_validate(struct native_surface *nsurf, uint attachment_mask, @@ -656,7 +659,7 @@ kms_display_destroy(struct native_display *ndpy) kdpy->base.screen->destroy(kdpy->base.screen); if (kdpy->fd >= 0) - drmClose(kdpy->fd); + close(kdpy->fd); FREE(kdpy); } @@ -668,50 +671,23 @@ static boolean kms_display_init_screen(struct native_display *ndpy) { struct kms_display *kdpy = kms_display(ndpy); - int fd; - - fd = kdpy->fd; - if (fd >= 0) { - drmVersionPtr version = drmGetVersion(fd); - if (!version || strcmp(version->name, driver_descriptor.driver_name)) { - if (version) { - _eglLog(_EGL_WARNING, "unknown driver name %s", version->name); - drmFreeVersion(version); - } - else { - _eglLog(_EGL_WARNING, "invalid fd %d", fd); - } - - return FALSE; - } + drmVersionPtr version; - drmFreeVersion(version); - } - else { - fd = drmOpen(driver_descriptor.driver_name, NULL); - } - - if (fd < 0) { - _eglLog(_EGL_WARNING, "failed to open DRM device"); + version = drmGetVersion(kdpy->fd); + if (!version) { + _eglLog(_EGL_WARNING, "invalid fd %d", kdpy->fd); return FALSE; } -#if 0 - if (drmSetMaster(fd)) { - _eglLog(_EGL_WARNING, "failed to become DRM master"); - return FALSE; - } -#endif + kdpy->base.screen = kdpy->event_handler->new_drm_screen(&kdpy->base, + version->name, kdpy->fd);; + drmFreeVersion(version); - kdpy->base.screen = driver_descriptor.create_screen(fd); if (!kdpy->base.screen) { _eglLog(_EGL_WARNING, "failed to create DRM screen"); - drmClose(fd); return FALSE; } - kdpy->fd = fd; - return TRUE; } @@ -723,7 +699,8 @@ static struct native_display_modeset kms_display_modeset = { }; static struct native_display * -kms_create_display(int fd, struct native_event_handler *event_handler) +kms_create_display(int fd, struct native_event_handler *event_handler, + void *user_data) { struct kms_display *kdpy; @@ -731,8 +708,10 @@ kms_create_display(int fd, struct native_event_handler *event_handler) if (!kdpy) return NULL; - kdpy->event_handler = event_handler; kdpy->fd = fd; + kdpy->event_handler = event_handler; + kdpy->base.user_data = user_data; + if (!kms_display_init_screen(&kdpy->base)) { kms_display_destroy(&kdpy->base); return NULL; @@ -769,39 +748,32 @@ kms_create_display(int fd, struct native_event_handler *event_handler) } static struct native_display * -native_create_display(void *dpy, struct native_event_handler *event_handler) +native_create_display(void *dpy, struct native_event_handler *event_handler, + void *user_data) { - struct native_display *ndpy; int fd; - /* well, this makes fd 0 being ignored */ - fd = (dpy) ? (int) pointer_to_intptr(dpy) : -1; - ndpy = kms_create_display(fd, event_handler); - - return ndpy; -} - -static void -kms_init_platform(struct native_platform *nplat) -{ - static char kms_name[32]; - - if (nplat->name) - return; - - util_snprintf(kms_name, sizeof(kms_name), "KMS/%s", driver_descriptor.name); + if (dpy) { + fd = dup((int) pointer_to_intptr(dpy)); + } + else { + fd = open("/dev/dri/card0", O_RDWR); + } + if (fd < 0) + return NULL; - nplat->name = kms_name; - nplat->create_probe = NULL; - nplat->get_probe_result = NULL; - nplat->create_display = native_create_display; + return kms_create_display(fd, event_handler, user_data); } -static struct native_platform kms_platform; +static const struct native_platform kms_platform = { + "KMS", /* name */ + NULL, /* create_probe */ + NULL, /* get_probe_result */ + native_create_display +}; const struct native_platform * native_get_kms_platform(void) { - kms_init_platform(&kms_platform); return &kms_platform; } diff --git a/src/gallium/state_trackers/egl/kms/native_kms.h b/src/gallium/state_trackers/egl/kms/native_kms.h index 14cf5a641a..cd8e4ff0b2 100644 --- a/src/gallium/state_trackers/egl/kms/native_kms.h +++ b/src/gallium/state_trackers/egl/kms/native_kms.h @@ -32,6 +32,7 @@ #include "pipe/p_compiler.h" #include "util/u_format.h" #include "pipe/p_state.h" +#include "state_tracker/drm_driver.h" #include "common/native.h" #include "common/native_helper.h" diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c index 7464354fe6..1bef59d864 100644 --- a/src/gallium/state_trackers/egl/x11/native_dri2.c +++ b/src/gallium/state_trackers/egl/x11/native_dri2.c @@ -692,7 +692,6 @@ static boolean dri2_display_init_screen(struct native_display *ndpy) { struct dri2_display *dri2dpy = dri2_display(ndpy); - const char *driver = driver_descriptor.name; int fd; if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) || @@ -703,19 +702,15 @@ dri2_display_init_screen(struct native_display *ndpy) dri2dpy->dri_driver = x11_screen_probe_dri2(dri2dpy->xscr, &dri2dpy->dri_major, &dri2dpy->dri_minor); - if (!dri2dpy->dri_driver || !driver || - strcmp(dri2dpy->dri_driver, driver) != 0) { - _eglLog(_EGL_WARNING, "Driver mismatch: %s != %s", - dri2dpy->dri_driver, driver); - return FALSE; - } fd = x11_screen_enable_dri2(dri2dpy->xscr, dri2_display_invalidate_buffers, &dri2dpy->base); if (fd < 0) return FALSE; - dri2dpy->base.screen = driver_descriptor.create_screen(fd); + dri2dpy->base.screen = + dri2dpy->event_handler->new_drm_screen(&dri2dpy->base, + dri2dpy->dri_driver, fd); if (!dri2dpy->base.screen) { _eglLog(_EGL_WARNING, "failed to create DRM screen"); return FALSE; @@ -739,7 +734,8 @@ dri2_display_hash_table_compare(void *key1, void *key2) struct native_display * x11_create_dri2_display(Display *dpy, - struct native_event_handler *event_handler) + struct native_event_handler *event_handler, + void *user_data) { struct dri2_display *dri2dpy; @@ -748,6 +744,7 @@ x11_create_dri2_display(Display *dpy, return NULL; dri2dpy->event_handler = event_handler; + dri2dpy->base.user_data = user_data; dri2dpy->dpy = dpy; if (!dri2dpy->dpy) { diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c index 7eec563bdf..f0519405d3 100644 --- a/src/gallium/state_trackers/egl/x11/native_x11.c +++ b/src/gallium/state_trackers/egl/x11/native_x11.c @@ -23,7 +23,6 @@ * DEALINGS IN THE SOFTWARE. */ -#include <string.h> #include "util/u_debug.h" #include "util/u_memory.h" #include "util/u_string.h" @@ -107,50 +106,38 @@ x11_get_probe_result(struct native_probe *nprobe) } static struct native_display * -native_create_display(void *dpy, struct native_event_handler *event_handler) +native_create_display(void *dpy, struct native_event_handler *event_handler, + void *user_data) { struct native_display *ndpy = NULL; boolean force_sw; force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE); - if (!driver_descriptor.create_screen) - force_sw = TRUE; - if (!force_sw) { - ndpy = x11_create_dri2_display((Display *) dpy, event_handler); + ndpy = x11_create_dri2_display((Display *) dpy, + event_handler, user_data); } if (!ndpy) { EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING; _eglLog(level, "use software fallback"); - ndpy = x11_create_ximage_display((Display *) dpy, event_handler); + ndpy = x11_create_ximage_display((Display *) dpy, + event_handler, user_data); } return ndpy; } -static void -x11_init_platform(struct native_platform *nplat) -{ - static char x11_name[32]; - - if (nplat->name) - return; - - util_snprintf(x11_name, sizeof(x11_name), "X11/%s", driver_descriptor.name); - - nplat->name = x11_name; - nplat->create_probe = x11_create_probe; - nplat->get_probe_result = x11_get_probe_result; - nplat->create_display = native_create_display; -} - -static struct native_platform x11_platform; +static const struct native_platform x11_platform = { + "X11", /* name */ + x11_create_probe, + x11_get_probe_result, + native_create_display +}; const struct native_platform * native_get_x11_platform(void) { - x11_init_platform(&x11_platform); return &x11_platform; } diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h index a1c32c3455..0b47837e1b 100644 --- a/src/gallium/state_trackers/egl/x11/native_x11.h +++ b/src/gallium/state_trackers/egl/x11/native_x11.h @@ -30,10 +30,12 @@ struct native_display * x11_create_ximage_display(Display *dpy, - struct native_event_handler *event_handler); + struct native_event_handler *event_handler, + void *user_data); struct native_display * x11_create_dri2_display(Display *dpy, - struct native_event_handler *event_handler); + struct native_event_handler *event_handler, + void *user_data); #endif /* _NATIVE_X11_H_ */ diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c index ee10a04cfb..4b32f6e36e 100644 --- a/src/gallium/state_trackers/egl/x11/native_ximage.c +++ b/src/gallium/state_trackers/egl/x11/native_ximage.c @@ -442,7 +442,8 @@ ximage_display_destroy(struct native_display *ndpy) struct native_display * x11_create_ximage_display(Display *dpy, - struct native_event_handler *event_handler) + struct native_event_handler *event_handler, + void *user_data) { struct ximage_display *xdpy; struct sw_winsys *winsys = NULL; @@ -462,6 +463,7 @@ x11_create_ximage_display(Display *dpy, } xdpy->event_handler = event_handler; + xdpy->base.user_data = user_data; xdpy->xscr_number = DefaultScreen(xdpy->dpy); xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number); @@ -472,7 +474,8 @@ x11_create_ximage_display(Display *dpy, if (!winsys) goto fail; - xdpy->base.screen = native_create_sw_screen(winsys); + xdpy->base.screen = + xdpy->event_handler->new_sw_screen(&xdpy->base, winsys); if (!xdpy->base.screen) goto fail; diff --git a/src/gallium/targets/egl/Makefile b/src/gallium/targets/egl/Makefile index 364a31dc45..80f9c60559 100644 --- a/src/gallium/targets/egl/Makefile +++ b/src/gallium/targets/egl/Makefile @@ -15,6 +15,9 @@ TOP = ../../../.. include $(TOP)/configs/current +ST_PREFIX := st_ +PIPE_PREFIX := egl_gallium_ + common_CPPFLAGS := \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/gallium/drivers \ @@ -30,7 +33,8 @@ common_LIBS := \ # EGL driver egl_CPPFLAGS := \ -I$(TOP)/src/gallium/state_trackers/egl \ - -I$(TOP)/src/egl/main + -I$(TOP)/src/egl/main \ + -DST_PREFIX=\"$(ST_PREFIX)\" egl_SYS := -lm -ldl -lEGL egl_LIBS := \ $(TOP)/src/gallium/state_trackers/egl/libegl.a \ @@ -47,6 +51,22 @@ ifneq ($(findstring fbdev, $(EGL_PLATFORMS)),) egl_LIBS += $(TOP)/src/gallium/winsys/sw/fbdev/libfbdev.a endif +# EGL_RENDERABLE_TYPE is a compile time attribute +egl_CPPFLAGS += $(API_DEFINES) +ifneq ($(filter $(GL_LIB), $(EGL_CLIENT_APIS)),) +egl_CPPFLAGS += -DFEATURE_GL=1 +endif +ifneq ($(filter $(GLESv1_CM_LIB), $(EGL_CLIENT_APIS)),) +egl_CPPFLAGS += -DFEATURE_ES1=1 +endif +ifneq ($(filter $(GLESv2_LIB), $(EGL_CLIENT_APIS)),) +egl_CPPFLAGS += -DFEATURE_ES2=1 +endif +ifneq ($(filter $(VG_LIB), $(EGL_CLIENT_APIS)),) +egl_CPPFLAGS += -DFEATURE_VG=1 +endif +egl_CPPFLAGS := $(sort $(egl_CPPFLAGS)) + # LLVM ifeq ($(MESA_LLVM),1) common_SYS += $(LLVM_LIBS) @@ -136,10 +156,10 @@ ifneq ($(findstring svga,$(GALLIUM_WINSYS_DIRS)),) OUTPUTS += vmwgfx endif OUTPUTS += swrast -OUTPUTS := $(addprefix egl_gallium_, $(OUTPUTS)) +OUTPUTS := $(addprefix $(PIPE_PREFIX), $(OUTPUTS)) # state trackers -OUTPUTS += $(addprefix st_, $(EGL_CLIENT_APIS)) +OUTPUTS += $(addprefix $(ST_PREFIX), $(EGL_CLIENT_APIS)) OUTPUTS := $(addsuffix .so, $(OUTPUTS)) OUTPUTS := $(addprefix $(OUTPUT_PATH)/, $(OUTPUTS)) @@ -148,7 +168,7 @@ default: $(OUTPUTS) define mklib-egl $(MKLIB) -o $(notdir $@) -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \ - -install $(OUTPUT_PATH) $(MKLIB_OPTIONS) $< \ + -install $(OUTPUT_PATH) $(MKLIB_OPTIONS) $< egl.o \ -Wl,--start-group $(common_LIBS) $(egl_LIBS) $($(1)_LIBS) -Wl,--end-group \ $(common_SYS) $(egl_SYS) $($(1)_SYS) endef @@ -161,37 +181,40 @@ $(MKLIB) -o $(notdir $@) -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \ endef # EGL drivers -$(OUTPUT_PATH)/egl_gallium_i915.so: pipe_i915.o $(egl_LIBS) $(i915_LIBS) +$(OUTPUT_PATH)/$(PIPE_PREFIX)i915.so: pipe_i915.o egl.o $(egl_LIBS) $(i915_LIBS) $(call mklib-egl,i915) -$(OUTPUT_PATH)/egl_gallium_i965.so: pipe_i965.o $(egl_LIBS) $(i965_LIBS) +$(OUTPUT_PATH)/$(PIPE_PREFIX)i965.so: pipe_i965.o egl.o $(egl_LIBS) $(i965_LIBS) $(call mklib-egl,i965) -$(OUTPUT_PATH)/egl_gallium_nouveau.so: pipe_nouveau.o $(egl_LIBS) $(nouveau_LIBS) +$(OUTPUT_PATH)/$(PIPE_PREFIX)nouveau.so: pipe_nouveau.o egl.o $(egl_LIBS) $(nouveau_LIBS) $(call mklib-egl,nouveau) -$(OUTPUT_PATH)/egl_gallium_radeon.so: pipe_radeon.o $(egl_LIBS) $(radeon_LIBS) +$(OUTPUT_PATH)/$(PIPE_PREFIX)radeon.so: pipe_radeon.o egl.o $(egl_LIBS) $(radeon_LIBS) $(call mklib-egl,radeon) -$(OUTPUT_PATH)/egl_gallium_vmwgfx.so: pipe_vmwgfx.o $(egl_LIBS) $(vmwgfx_LIBS) +$(OUTPUT_PATH)/$(PIPE_PREFIX)vmwgfx.so: pipe_vmwgfx.o egl.o $(egl_LIBS) $(vmwgfx_LIBS) $(call mklib-egl,vmwgfx) -$(OUTPUT_PATH)/egl_gallium_swrast.so: pipe_swrast.o $(egl_LIBS) $(swrast_LIBS) +$(OUTPUT_PATH)/$(PIPE_PREFIX)swrast.so: pipe_swrast.o egl.o $(egl_LIBS) $(swrast_LIBS) $(call mklib-egl,swrast) # state trackers -$(OUTPUT_PATH)/st_$(GL_LIB).so: st_GL.o $(GL_LIBS) +$(OUTPUT_PATH)/$(ST_PREFIX)$(GL_LIB).so: st_GL.o $(GL_LIBS) $(call mklib,GL) -$(OUTPUT_PATH)/st_$(GLESv1_CM_LIB).so: st_GLESv1_CM.o $(GLESv1_CM_LIBS) +$(OUTPUT_PATH)/$(ST_PREFIX)$(GLESv1_CM_LIB).so: st_GLESv1_CM.o $(GLESv1_CM_LIBS) $(call mklib,GLESv1_CM) -$(OUTPUT_PATH)/st_$(GLESv2_LIB).so: st_GLESv2.o $(GLESv2_LIBS) +$(OUTPUT_PATH)/$(ST_PREFIX)$(GLESv2_LIB).so: st_GLESv2.o $(GLESv2_LIBS) $(call mklib,GLESv2) -$(OUTPUT_PATH)/st_$(VG_LIB).so: st_OpenVG.o $(OpenVG_LIBS) +$(OUTPUT_PATH)/$(ST_PREFIX)$(VG_LIB).so: st_OpenVG.o $(OpenVG_LIBS) $(call mklib,OpenVG) +egl.o: egl.c + $(CC) -c -o $@ $< $(common_CPPFLAGS) $(egl_CPPFLAGS) $(DEFINES) $(CFLAGS) + pipe_%.o: pipe_%.c $(CC) -c -o $@ $< $(common_CPPFLAGS) $($*_CPPFLAGS) $(DEFINES) $(CFLAGS) diff --git a/src/gallium/targets/egl/SConscript b/src/gallium/targets/egl/SConscript index c743c26cf6..f2bcb6e684 100644 --- a/src/gallium/targets/egl/SConscript +++ b/src/gallium/targets/egl/SConscript @@ -27,7 +27,7 @@ if env['platform'] == 'windows': egl_gallium_swrast = env.SharedLibrary( target ='egl_gallium_swrast', - source = 'pipe_swrast.c', + source = ['egl.c', 'pipe_swrast.c'], LIBS = st_egl_gdi + ws_gdi + drivers + gallium + egl + env['LIBS'], ) diff --git a/src/gallium/targets/egl/egl.c b/src/gallium/targets/egl/egl.c new file mode 100644 index 0000000000..831adf7c76 --- /dev/null +++ b/src/gallium/targets/egl/egl.c @@ -0,0 +1,305 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Chia-I Wu <olv@lunarg.com> + */ + +#include "util/u_debug.h" +#include "util/u_string.h" +#include "util/u_memory.h" +#include "util/u_dl.h" +#include "egldriver.h" +#include "egllog.h" + +#include "state_tracker/st_api.h" +#include "softpipe/sp_public.h" +#include "llvmpipe/lp_public.h" +#include "target-helpers/wrap_screen.h" +#include "common/egl_g3d_loader.h" +#include "state_tracker/drm_driver.h" + +struct egl_g3d_loader egl_g3d_loader; + +static struct st_module { + boolean initialized; + const char *name; + struct util_dl_library *lib; + struct st_api *stapi; +} st_modules[ST_API_COUNT]; + +static EGLBoolean +dlopen_st_module_cb(const char *dir, size_t len, void *callback_data) +{ + struct st_module *stmod = + (struct st_module *) callback_data; + char path[1024]; + int ret; + + if (len) { + ret = util_snprintf(path, sizeof(path), + "%.*s/" ST_PREFIX "%s" UTIL_DL_EXT, len, dir, stmod->name); + } + else { + ret = util_snprintf(path, sizeof(path), + ST_PREFIX "%s" UTIL_DL_EXT, stmod->name); + } + + if (ret > 0 && ret < sizeof(path)) { + stmod->lib = util_dl_open(path); + if (stmod->lib) + _eglLog(_EGL_DEBUG, "loaded %s", path); + } + + return !(stmod->lib); +} + +static boolean +load_st_module(struct st_module *stmod, + const char *name, const char *procname) +{ + struct st_api *(*create_api)(void); + + stmod->name = name; + if (stmod->name) + _eglSearchPathForEach(dlopen_st_module_cb, (void *) stmod); + else + stmod->lib = util_dl_open(NULL); + + if (stmod->lib) { + create_api = (struct st_api *(*)(void)) + util_dl_get_proc_address(stmod->lib, procname); + if (create_api) + stmod->stapi = create_api(); + + if (!stmod->stapi) { + util_dl_close(stmod->lib); + stmod->lib = NULL; + } + } + + if (!stmod->stapi) + stmod->name = NULL; + + return (stmod->stapi != NULL); +} + +static struct st_api * +get_st_api(enum st_api_type api) +{ + struct st_module *stmod = &st_modules[api]; + const char *names[8], *symbol; + int i, count = 0; + + if (stmod->initialized) + return stmod->stapi; + + switch (api) { + case ST_API_OPENGL: + symbol = ST_CREATE_OPENGL_SYMBOL; + names[count++] = "GL"; + break; + case ST_API_OPENGL_ES1: + symbol = ST_CREATE_OPENGL_ES1_SYMBOL; + names[count++] = "GLESv1_CM"; + names[count++] = "GL"; + break; + case ST_API_OPENGL_ES2: + symbol = ST_CREATE_OPENGL_ES2_SYMBOL; + names[count++] = "GLESv2"; + names[count++] = "GL"; + break; + case ST_API_OPENVG: + symbol = ST_CREATE_OPENVG_SYMBOL; + names[count++] = "OpenVG"; + break; + default: + symbol = NULL; + assert(!"Unknown API Type\n"); + break; + } + + /* NULL means the process itself */ + names[count++] = NULL; + + for (i = 0; i < count; i++) { + if (load_st_module(stmod, names[i], symbol)) + break; + } + + if (!stmod->stapi) { + EGLint level = (egl_g3d_loader.api_mask & (1 << api)) ? + _EGL_WARNING : _EGL_DEBUG; + _eglLog(level, "unable to load " ST_PREFIX "%s" UTIL_DL_EXT, names[0]); + } + + stmod->initialized = TRUE; + + return stmod->stapi; +} + +static struct st_api * +guess_gl_api(void) +{ + struct st_api *stapi; + int gl_apis[] = { + ST_API_OPENGL, + ST_API_OPENGL_ES1, + ST_API_OPENGL_ES2, + -1 + }; + int i, api = -1; + + /* determine the api from the loaded libraries */ + for (i = 0; gl_apis[i] != -1; i++) { + if (st_modules[gl_apis[i]].stapi) { + api = gl_apis[i]; + break; + } + } + /* determine the api from the linked libraries */ + if (api == -1) { + struct util_dl_library *self = util_dl_open(NULL); + + if (self) { + if (util_dl_get_proc_address(self, "glColor4d")) + api = ST_API_OPENGL; + else if (util_dl_get_proc_address(self, "glColor4x")) + api = ST_API_OPENGL_ES1; + else if (util_dl_get_proc_address(self, "glShaderBinary")) + api = ST_API_OPENGL_ES2; + util_dl_close(self); + } + } + + stapi = (api != -1) ? get_st_api(api) : NULL; + if (!stapi) { + for (i = 0; gl_apis[i] != -1; i++) { + api = gl_apis[i]; + stapi = get_st_api(api); + if (stapi) + break; + } + } + + return stapi; +} + +static struct pipe_screen * +create_drm_screen(const char *name, int fd) +{ + return (driver_descriptor.driver_name && name && + strcmp(driver_descriptor.driver_name, name) == 0) ? + driver_descriptor.create_screen(fd) : NULL; +} + +static struct pipe_screen * +create_sw_screen(struct sw_winsys *ws) +{ + struct pipe_screen *screen = NULL; + +#if defined(GALLIUM_LLVMPIPE) + if (!screen && !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE)) + screen = llvmpipe_create_screen(ws); +#endif + if (!screen) + screen = softpipe_create_screen(ws); + + return (screen) ? gallium_wrap_screen(screen) : NULL; +} + +static const struct egl_g3d_loader * +loader_init(void) +{ + uint api_mask = 0x0; + + /* TODO detect at runtime? */ +#if FEATURE_GL + api_mask |= 1 << ST_API_OPENGL; +#endif +#if FEATURE_ES1 + api_mask |= 1 << ST_API_OPENGL_ES1; +#endif +#if FEATURE_ES2 + api_mask |= 1 << ST_API_OPENGL_ES2; +#endif +#if FEATURE_VG + api_mask |= 1 << ST_API_OPENVG; +#endif + + egl_g3d_loader.api_mask = api_mask; + egl_g3d_loader.get_st_api = get_st_api; + egl_g3d_loader.guess_gl_api = guess_gl_api; + egl_g3d_loader.create_drm_screen = create_drm_screen; + egl_g3d_loader.create_sw_screen = create_sw_screen; + + return &egl_g3d_loader; +} + +static void +loader_fini(void) +{ + int i; + + for (i = 0; i < ST_API_COUNT; i++) { + struct st_module *stmod = &st_modules[i]; + + if (stmod->stapi) { + stmod->stapi->destroy(stmod->stapi); + stmod->stapi = NULL; + } + if (stmod->lib) { + util_dl_close(stmod->lib); + stmod->lib = NULL; + } + stmod->name = NULL; + stmod->initialized = FALSE; + } +} + +static void +egl_g3d_unload(_EGLDriver *drv) +{ + egl_g3d_destroy_driver(drv); + loader_fini(); +} + +_EGLDriver * +_eglMain(const char *args) +{ + const struct egl_g3d_loader *loader; + _EGLDriver *drv; + + loader = loader_init(); + drv = egl_g3d_create_driver(loader); + if (!drv) { + loader_fini(); + return NULL; + } + + drv->Name = "Gallium"; + drv->Unload = egl_g3d_unload; + + return drv; +} diff --git a/src/gallium/targets/egl/pipe_i965.c b/src/gallium/targets/egl/pipe_i965.c index d19c83a47d..cf96214e83 100644 --- a/src/gallium/targets/egl/pipe_i965.c +++ b/src/gallium/targets/egl/pipe_i965.c @@ -28,7 +28,3 @@ create_screen(int fd) } DRM_DRIVER_DESCRIPTOR("i965", "i965", create_screen) - -/* A poor man's --whole-archive for EGL drivers */ -void *_eglMain(void *); -void *_eglWholeArchive = (void *) _eglMain; diff --git a/src/gallium/targets/egl/pipe_nouveau.c b/src/gallium/targets/egl/pipe_nouveau.c index cf569ea62c..e725a4d9b7 100644 --- a/src/gallium/targets/egl/pipe_nouveau.c +++ b/src/gallium/targets/egl/pipe_nouveau.c @@ -18,7 +18,3 @@ create_screen(int fd) } DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen) - -/* A poor man's --whole-archive for EGL drivers */ -void *_eglMain(void *); -void *_eglWholeArchive = (void *) _eglMain; diff --git a/src/gallium/targets/egl/pipe_radeon.c b/src/gallium/targets/egl/pipe_radeon.c index ce07327b8f..5a0a8dc573 100644 --- a/src/gallium/targets/egl/pipe_radeon.c +++ b/src/gallium/targets/egl/pipe_radeon.c @@ -24,7 +24,3 @@ create_screen(int fd) } DRM_DRIVER_DESCRIPTOR("radeon", "radeon", create_screen) - -/* A poor man's --whole-archive for EGL drivers */ -void *_eglMain(void *); -void *_eglWholeArchive = (void *) _eglMain; diff --git a/src/gallium/targets/egl/pipe_swrast.c b/src/gallium/targets/egl/pipe_swrast.c index d8205c158e..1ad4e25a6e 100644 --- a/src/gallium/targets/egl/pipe_swrast.c +++ b/src/gallium/targets/egl/pipe_swrast.c @@ -2,7 +2,3 @@ #include "state_tracker/drm_driver.h" DRM_DRIVER_DESCRIPTOR("swrast", NULL, NULL) - -/* A poor man's --whole-archive for EGL drivers */ -void *_eglMain(void *); -void *_eglWholeArchive = (void *) _eglMain; diff --git a/src/gallium/targets/egl/pipe_vmwgfx.c b/src/gallium/targets/egl/pipe_vmwgfx.c index 4e9f51c5dc..15089d6db2 100644 --- a/src/gallium/targets/egl/pipe_vmwgfx.c +++ b/src/gallium/targets/egl/pipe_vmwgfx.c @@ -24,7 +24,3 @@ create_screen(int fd) } DRM_DRIVER_DESCRIPTOR("vmwgfx", "vmwgfx", create_screen) - -/* A poor man's --whole-archive for EGL drivers */ -void *_eglMain(void *); -void *_eglWholeArchive = (void *) _eglMain; |