egl: Simplify driver matching.
authorChia-I Wu <olv@lunarg.com>
Wed, 12 Jan 2011 16:27:45 +0000 (00:27 +0800)
committerChia-I Wu <olv@lunarg.com>
Thu, 13 Jan 2011 10:10:38 +0000 (18:10 +0800)
Add initialization options that drv->API.Initialize should support.
Replace drv->Probe by TestOnly initialization option and simplify
_eglMatchDriver.

src/egl/drivers/dri2/egl_dri2.c
src/egl/drivers/glx/egl_glx.c
src/egl/main/egldisplay.h
src/egl/main/egldriver.c
src/egl/main/egldriver.h
src/gallium/state_trackers/egl/common/egl_g3d.c

index f6bca4abf72a4d9181e39235a5e314e1f4eddc6b..2e827f4f3e50b5a97d12e1ab1c313e73c043aea4 100644 (file)
@@ -1472,10 +1472,14 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp)
 {
    switch (disp->Platform) {
    case _EGL_PLATFORM_X11:
+      if (disp->Options.TestOnly)
+         return EGL_TRUE;
       return dri2_initialize_x11(drv, disp);
 
 #ifdef HAVE_LIBUDEV
    case _EGL_PLATFORM_DRM:
+      if (disp->Options.TestOnly)
+         return EGL_TRUE;
       return dri2_initialize_drm(drv, disp);
 #endif
 
index 84b04f7967e1153101750b13f749beb81a8e05ea..aecebae40c2e9650f9ab424d6227897d5963e959 100644 (file)
@@ -589,6 +589,9 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp)
    if (disp->Platform != _EGL_PLATFORM_X11)
       return EGL_FALSE;
 
+   if (disp->Options.TestOnly)
+      return EGL_TRUE;
+
    GLX_dpy = CALLOC_STRUCT(GLX_egl_display);
    if (!GLX_dpy)
       return _eglError(EGL_BAD_ALLOC, "eglInitialize");
index faeb29064782ab15799b0dc47358376f3e092a6f..b42760befabcf7f55520439a4f094e4ea0192bbd 100644 (file)
@@ -90,6 +90,11 @@ struct _egl_display
    _EGLDriver *Driver;        /**< Matched driver of the display */
    EGLBoolean Initialized;    /**< True if the display is initialized */
 
+   /* options that affect how the driver initializes the display */
+   struct {
+      EGLBoolean TestOnly;    /**< Driver should not set fields when true */
+   } Options;
+
    /* these fields are set by the driver during init */
    void *DriverData;          /**< Driver private data */
    EGLint VersionMajor;       /**< EGL major version */
index 1ae030db448cb6f990028fde984ff74629daeb3f..7baa24fbf8688b5f09a20f0c2dfe1f2bf4d12fb8 100644 (file)
@@ -525,100 +525,75 @@ _eglAddDrivers(void)
 
 
 /**
- * Match a display to a driver.  The display is initialized unless use_probe is
- * true.
- *
- * The matching is done by finding the first driver that can initialize the
- * display, or when use_probe is true, the driver with highest score.
+ * A helper function for _eglMatchDriver.  It finds the first driver that can
+ * initialize the display and return.
  */
-_EGLDriver *
-_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean use_probe)
+static _EGLDriver *
+_eglMatchAndInitialize(_EGLDisplay *dpy)
 {
-   _EGLModule *mod;
-   _EGLDriver *best_drv = NULL;
-   EGLint best_score = 0;
-   EGLint i;
-
-   _eglLockMutex(&_eglModuleMutex);
+   _EGLDriver *drv = NULL;
+   EGLint i = 0;
 
    if (!_eglAddDrivers()) {
-      _eglUnlockMutex(&_eglModuleMutex);
       _eglLog(_EGL_WARNING, "failed to find any driver");
-      return EGL_FALSE;
+      return NULL;
    }
 
-   /* match the loaded modules */
-   for (i = 0; i < _eglModules->Size; i++) {
-      mod = (_EGLModule *) _eglModules->Elements[i];
-      if (!mod->Driver)
-         break;
+   if (dpy->Driver) {
+      drv = dpy->Driver;
+      /* no re-matching? */
+      if (!drv->API.Initialize(drv, dpy))
+         drv = NULL;
+      return drv;
+   }
 
-      if (use_probe) {
-         EGLint score = (mod->Driver->Probe) ?
-            mod->Driver->Probe(mod->Driver, dpy) : 1;
-         if (score > best_score) {
-            best_drv = mod->Driver;
-            best_score = score;
-         }
+   while (i < _eglModules->Size) {
+      _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i];
+
+      if (!_eglLoadModule(mod)) {
+         /* remove invalid modules */
+         _eglEraseArray(_eglModules, i, _eglFreeModule);
+         continue;
+      }
+
+      if (mod->Driver->API.Initialize(mod->Driver, dpy)) {
+         drv = mod->Driver;
+         break;
       }
       else {
-         if (mod->Driver->API.Initialize(mod->Driver, dpy)) {
-            best_drv = mod->Driver;
-            best_score = 100;
-         }
+         i++;
       }
-      /* perfect match */
-      if (best_score >= 100)
-         break;
    }
 
-   /* load more modules */
-   if (!best_drv) {
-      EGLint first_unloaded = i;
+   return drv;
+}
 
-      while (i < _eglModules->Size) {
-         mod = (_EGLModule *) _eglModules->Elements[i];
-         assert(!mod->Driver);
 
-         if (!_eglLoadModule(mod)) {
-            /* remove invalid modules */
-            _eglEraseArray(_eglModules, i, _eglFreeModule);
-            continue;
-         }
+/**
+ * Match a display to a driver.  The display is initialized unless test_only is
+ * true.  The matching is done by finding the first driver that can initialize
+ * the display.
+ */
+_EGLDriver *
+_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only)
+{
+   _EGLDriver *best_drv;
 
-         if (use_probe) {
-            best_score = (mod->Driver->Probe) ?
-               mod->Driver->Probe(mod->Driver, dpy) : 1;
-         }
-         else {
-            if (mod->Driver->API.Initialize(mod->Driver, dpy))
-               best_score = 100;
-         }
+   assert(!dpy->Initialized);
 
-         if (best_score > 0) {
-            best_drv = mod->Driver;
-            /* loaded modules come before unloaded ones */
-            if (first_unloaded != i) {
-               void *tmp = _eglModules->Elements[i];
-               _eglModules->Elements[i] =
-                  _eglModules->Elements[first_unloaded];
-               _eglModules->Elements[first_unloaded] = tmp;
-            }
-            break;
-         }
-         else {
-            _eglUnloadModule(mod);
-            i++;
-         }
-      }
-   }
+   _eglLockMutex(&_eglModuleMutex);
+
+   /* set options */
+   dpy->Options.TestOnly = test_only;
+
+   best_drv = _eglMatchAndInitialize(dpy);
 
    _eglUnlockMutex(&_eglModuleMutex);
 
    if (best_drv) {
-      _eglLog(_EGL_DEBUG, "the best driver is %s (score %d)",
-            best_drv->Name, best_score);
-      if (!use_probe) {
+      _eglLog(_EGL_DEBUG, "the best driver is %s%s",
+            best_drv->Name, (test_only) ? " (test only) " : "");
+      if (!test_only) {
          dpy->Driver = best_drv;
          dpy->Initialized = EGL_TRUE;
       }
index d61775791939ea4c07210776074e4908ab112b84..3cde102d12d0392c836f7b2078606c5fa2ce7334 100644 (file)
@@ -43,16 +43,6 @@ struct _egl_driver
 {
    const char *Name;  /**< name of this driver */
 
-   /**
-    * Probe a display and return a score.
-    *
-    * Roughly,
-    *  50 means the driver supports the display;
-    *  90 means the driver can accelerate the display;
-    * 100 means a perfect match.
-    */
-   EGLint (*Probe)(_EGLDriver *drv, _EGLDisplay *dpy);
-
    /**
     * Release the driver resource.
     *
@@ -81,7 +71,7 @@ _eglMain(const char *args);
 
 
 extern _EGLDriver *
-_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean probe_only);
+_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only);
 
 
 extern __eglMustCastToProperFunctionPointerType
index 903547051720f624f1c53d480a2f0cb0a6a5837d..bad32ac6e4ca00eb051e0db9a1b803ec2efac471 100644 (file)
@@ -484,6 +484,9 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy)
    if (!nplat)
       return EGL_FALSE;
 
+   if (dpy->Options.TestOnly)
+      return EGL_TRUE;
+
    gdpy = CALLOC_STRUCT(egl_g3d_display);
    if (!gdpy) {
       _eglError(EGL_BAD_ALLOC, "eglInitialize");
@@ -572,12 +575,6 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
          stapi->get_proc_address(stapi, procname) : NULL);
 }
 
-static EGLint
-egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy)
-{
-   return (egl_g3d_get_platform(drv, dpy->Platform)) ? 90 : 0;
-}
-
 _EGLDriver *
 egl_g3d_create_driver(const struct egl_g3d_loader *loader)
 {
@@ -594,8 +591,6 @@ egl_g3d_create_driver(const struct egl_g3d_loader *loader)
    gdrv->base.API.Terminate = egl_g3d_terminate;
    gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address;
 
-   gdrv->base.Probe = egl_g3d_probe;
-
    /* to be filled by the caller */
    gdrv->base.Name = NULL;
    gdrv->base.Unload = NULL;