egl: Allow a prioritized list of default drivers
authorKristian Høgsberg <krh@bitplanet.net>
Thu, 13 May 2010 20:06:29 +0000 (16:06 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Thu, 13 May 2010 20:14:07 +0000 (16:14 -0400)
When there is no user driver or any matching display drivers we fall
back to the default driver.  This patch lets us have a list of default
drivers instead of just one.  The drivers are loaded in turn and we
attempt to initialize the display.  If it fails we unload the driver
and move on to the next one.

Compared to the display driver mechanism, this avoids loading a number
of drivers and then only using one.  Also, we call Initialize to see
if the driver will work instead of relying on Probe.  To know for sure
that a driver will work, Probe really have to do a full Initialize, so
we will just use Initialize directly.

src/egl/main/eglapi.c
src/egl/main/eglconfig.c
src/egl/main/egldefines.h
src/egl/main/egldriver.c
src/egl/main/egldriver.h
src/egl/main/eglglobals.c

index 647be652207ec060755a4abf70dfa7fe6e59de7b..f57dda88833ea77b2341711f348a163e48a141f0 100644 (file)
@@ -272,13 +272,15 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
       if (!drv) {
          _eglPreloadDrivers();
          drv = _eglMatchDriver(disp);
-         if (!drv)
-            RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
+        /* Initialize the particular display now */
+        if (drv && !drv->API.Initialize(drv, disp, &major_int, &minor_int))
+           RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
       }
-
-      /* Initialize the particular display now */
-      if (!drv->API.Initialize(drv, disp, &major_int, &minor_int))
-         RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
+      if (!drv)
+        /* Load and initialize the first default driver that works */
+        drv = _eglLoadDefaultDriver(disp, &major_int, &minor_int);
+      if (!drv)
+        RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
 
       disp->APImajor = major_int;
       disp->APIminor = minor_int;
index 21d13cba904972ad77d33d2eafeacf288052ff71..47513a4edb29556c4d2956e9606f2072d7b5194d 100644 (file)
@@ -13,7 +13,6 @@
 
 
 #define MIN2(A, B)  (((A) < (B)) ? (A) : (B))
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 
 
 /**
index 8fc2301b795d0ad29775a78937bd9eb084e6fd47..4ecd4c1420c060e1fe08cb7c9e0f9b60ccf3e1c9 100644 (file)
@@ -40,6 +40,7 @@
 
 #define _EGL_VENDOR_STRING "Mesa Project"
 
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 
 
 #endif /* EGLDEFINES_INCLUDED */
index 2913ce2ece987de3f55462313e6540e41d1ba5ca..566554d51dc8bbe2127f554a6074c62cda3c9369 100644 (file)
@@ -36,7 +36,9 @@
 
 
 /* XXX Need to decide how to do dynamic name lookup on Windows */
-static const char DefaultDriverName[] = "TBD";
+static const char DefaultDriverNames[] = {
+   "TBD",
+};
 
 typedef HMODULE lib_handle;
 
@@ -63,7 +65,10 @@ library_suffix(void)
 #elif defined(_EGL_PLATFORM_POSIX)
 
 
-static const char DefaultDriverName[] = "egl_glx";
+static const char *DefaultDriverNames[] = {
+   "egl_dri2",
+   "egl_glx"
+};
 
 typedef void * lib_handle;
 
@@ -487,17 +492,6 @@ _eglPreloadDisplayDrivers(void)
 }
 
 
-/**
- * Preload the default driver.
- */
-static EGLBoolean
-_eglPreloadDefaultDriver(void)
-{
-   return (_eglPreloadForEach(_eglGetSearchPath(),
-            _eglLoaderFile, (void *) DefaultDriverName) > 0);
-}
-
-
 /**
  * Preload drivers.
  *
@@ -519,15 +513,13 @@ _eglPreloadDrivers(void)
    }
 
    loaded = (_eglPreloadUserDriver() ||
-             _eglPreloadDisplayDrivers() ||
-             _eglPreloadDefaultDriver());
+             _eglPreloadDisplayDrivers());
 
    _eglUnlockMutex(_eglGlobal.Mutex);
 
    return loaded;
 }
 
-
 /**
  * Unload preloaded drivers.
  */
@@ -558,6 +550,30 @@ _eglUnloadDrivers(void)
    _eglGlobal.NumDrivers = 0;
 }
 
+_EGLDriver *
+_eglLoadDefaultDriver(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+   _EGLDriver *drv = NULL;
+   int i;
+
+   _eglLockMutex(_eglGlobal.Mutex);
+
+   for (i = 0; i < ARRAY_SIZE(DefaultDriverNames); i++) {
+      _eglPreloadForEach(_eglGetSearchPath(),
+                        _eglLoaderFile, (void *) DefaultDriverNames[i]);
+      if (_eglGlobal.NumDrivers == 0)
+        continue;
+      drv = _eglGlobal.Drivers[0];
+      if (drv->API.Initialize(drv, dpy, major, minor))
+        break;
+      _eglUnloadDrivers();
+   }      
+
+   _eglUnlockMutex(_eglGlobal.Mutex);
+
+   return drv;
+}
+
 
 /**
  * Plug all the available fallback routines into the given driver's
index 28b79562f80e37d53a40f840e672fcc57cd7daf8..8b34c43b924dcba4873dbf479ea163cbd1b9815d 100644 (file)
@@ -84,6 +84,10 @@ extern void
 _eglUnloadDrivers(void);
 
 
+extern _EGLDriver *
+_eglLoadDefaultDriver(EGLDisplay dpy, EGLint *major, EGLint *minor);
+
+
 PUBLIC void
 _eglInitDriverFallbacks(_EGLDriver *drv);
 
index 5182b18e226f0e9443abf8dcc5dfc569ab62e141..e63819e08a20ad4625196731ca868515c5387e65 100644 (file)
@@ -6,9 +6,6 @@
 #include "eglmutex.h"
 
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-
-
 static _EGL_DECLARE_MUTEX(_eglGlobalMutex);
 struct _egl_global _eglGlobal =
 {