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;  | 
