Mesa (master): st/egl_g3d: Add support for probe to native displays.

Chia-I Wu olv at kemper.freedesktop.org
Wed Jan 20 10:18:04 UTC 2010


Module: Mesa
Branch: master
Commit: 11f4360f2e915f236558da22efe5bdabd81446f3
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=11f4360f2e915f236558da22efe5bdabd81446f3

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Wed Jan 20 15:52:50 2010 +0800

st/egl_g3d: Add support for probe to native displays.

The functions can be used to check if a display is supported without
creating a struct native_display.  It uses a probe object that can be
shared across drivers.

---

 src/gallium/state_trackers/egl_g3d/common/native.h |   37 ++++++++++
 .../state_trackers/egl_g3d/kms/native_kms.c        |   12 +++
 .../state_trackers/egl_g3d/x11/native_x11.c        |   76 ++++++++++++++++++++
 .../state_trackers/egl_g3d/x11/x11_screen.c        |   25 +++++--
 .../state_trackers/egl_g3d/x11/x11_screen.h        |    3 +
 5 files changed, 146 insertions(+), 7 deletions(-)

diff --git a/src/gallium/state_trackers/egl_g3d/common/native.h b/src/gallium/state_trackers/egl_g3d/common/native.h
index f374f2e..72a9cec 100644
--- a/src/gallium/state_trackers/egl_g3d/common/native.h
+++ b/src/gallium/state_trackers/egl_g3d/common/native.h
@@ -47,6 +47,27 @@ enum native_attachment {
    NUM_NATIVE_ATTACHMENTS
 };
 
+/**
+ * Enumerations for probe results.
+ */
+enum native_probe_result {
+   NATIVE_PROBE_UNKNOWN,
+   NATIVE_PROBE_FALLBACK,
+   NATIVE_PROBE_SUPPORTED,
+   NATIVE_PROBE_EXACT,
+};
+
+/**
+ * A probe object for display probe.
+ */
+struct native_probe {
+   int magic;
+   EGLNativeDisplayType display;
+   void *data;
+
+   void (*destroy)(struct native_probe *nprobe);
+};
+
 struct native_surface {
    void (*destroy)(struct native_surface *nsurf);
 
@@ -231,6 +252,22 @@ native_attachment_mask_test(uint mask, enum native_attachment att)
    return !!(mask & (1 << att));
 }
 
+/**
+ * Return a probe object for the given display.
+ *
+ * Note that the returned object may be cached and used by different native
+ * display modules.  It allows fast probing when multiple modules probe the
+ * same display.
+ */
+struct native_probe *
+native_create_probe(EGLNativeDisplayType dpy);
+
+/**
+ * Probe the probe object.
+ */
+enum native_probe_result
+native_get_probe_result(struct native_probe *nprobe);
+
 const char *
 native_get_name(void);
 
diff --git a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c b/src/gallium/state_trackers/egl_g3d/kms/native_kms.c
index dc66436..d5baf2c 100644
--- a/src/gallium/state_trackers/egl_g3d/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl_g3d/kms/native_kms.c
@@ -820,6 +820,18 @@ kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api)
    return &kdpy->base;
 }
 
+struct native_probe *
+native_create_probe(EGLNativeDisplayType dpy)
+{
+   return NULL;
+}
+
+enum native_probe_result
+native_get_probe_result(struct native_probe *nprobe)
+{
+   return NATIVE_PROBE_UNKNOWN;
+}
+
 /* the api is destroyed with the native display */
 static struct drm_api *drm_api;
 
diff --git a/src/gallium/state_trackers/egl_g3d/x11/native_x11.c b/src/gallium/state_trackers/egl_g3d/x11/native_x11.c
index 583ce3d..695ab88 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/native_x11.c
+++ b/src/gallium/state_trackers/egl_g3d/x11/native_x11.c
@@ -24,13 +24,89 @@
 
 #include <string.h>
 #include "util/u_debug.h"
+#include "util/u_memory.h"
 #include "state_tracker/drm_api.h"
 #include "egllog.h"
 
 #include "native_x11.h"
+#include "x11_screen.h"
+
+#define X11_PROBE_MAGIC 0x11980BE /* "X11PROBE" */
 
 static struct drm_api *api;
 
+static void
+x11_probe_destroy(struct native_probe *nprobe)
+{
+   if (nprobe->data)
+      free(nprobe->data);
+   free(nprobe);
+}
+
+struct native_probe *
+native_create_probe(EGLNativeDisplayType dpy)
+{
+   struct native_probe *nprobe;
+   struct x11_screen *xscr;
+   int scr;
+   const char *driver_name = NULL;
+   Display *xdpy;
+
+   nprobe = CALLOC_STRUCT(native_probe);
+   if (!nprobe)
+      return NULL;
+
+   xdpy = dpy;
+   if (!xdpy) {
+      xdpy = XOpenDisplay(NULL);
+      if (!xdpy) {
+         free(nprobe);
+         return NULL;
+      }
+   }
+
+   scr = DefaultScreen(xdpy);
+   xscr = x11_screen_create(xdpy, scr);
+   if (xscr) {
+      if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) {
+         driver_name = x11_screen_probe_dri2(xscr);
+         nprobe->data = strdup(driver_name);
+      }
+
+      x11_screen_destroy(xscr);
+   }
+
+   if (xdpy != dpy)
+      XCloseDisplay(xdpy);
+
+   nprobe->magic = X11_PROBE_MAGIC;
+   nprobe->display = dpy;
+
+   nprobe->destroy = x11_probe_destroy;
+
+   return nprobe;
+}
+
+enum native_probe_result
+native_get_probe_result(struct native_probe *nprobe)
+{
+   if (!nprobe || nprobe->magic != X11_PROBE_MAGIC)
+      return NATIVE_PROBE_UNKNOWN;
+
+   if (!api)
+      api = drm_api_create();
+
+   /* this is a software driver */
+   if (!api)
+      return NATIVE_PROBE_SUPPORTED;
+
+   /* the display does not support DRI2 or the driver mismatches */
+   if (!nprobe->data || strcmp(api->name, (const char *) nprobe->data) != 0)
+      return NATIVE_PROBE_FALLBACK;
+
+   return NATIVE_PROBE_EXACT;
+}
+
 const char *
 native_get_name(void)
 {
diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c
index 4d68a88..fef7878 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c
+++ b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.c
@@ -250,6 +250,22 @@ x11_screen_is_driver_equal(struct x11_screen *xscr, const char *driver)
 }
 
 /**
+ * Probe the screen for the DRI2 driver name.
+ */
+const char *
+x11_screen_probe_dri2(struct x11_screen *xscr)
+{
+   /* get the driver name and the device name */
+   if (!xscr->dri_driver) {
+      if (!DRI2Connect(xscr->dpy, RootWindow(xscr->dpy, xscr->number),
+               &xscr->dri_driver, &xscr->dri_device))
+         xscr->dri_driver = xscr->dri_device = NULL;
+   }
+
+   return xscr->dri_driver;
+}
+
+/**
  * Enable DRI2 and returns the file descriptor of the DRM device.  The file
  * descriptor will be closed automatically when the screen is destoryed.
  */
@@ -261,13 +277,8 @@ x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver)
       drm_magic_t magic;
 
       /* get the driver name and the device name first */
-      if (!xscr->dri_driver) {
-         if (!DRI2Connect(xscr->dpy, RootWindow(xscr->dpy, xscr->number),
-                  &xscr->dri_driver, &xscr->dri_device)) {
-            xscr->dri_driver = xscr->dri_device = NULL;
-            return -1;
-         }
-      }
+      if (!x11_screen_probe_dri2(xscr))
+         return -1;
 
       if (!x11_screen_is_driver_equal(xscr, driver)) {
          _eglLog(_EGL_WARNING, "Driver mismatch: %s != %s",
diff --git a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h
index bf48218..5432858 100644
--- a/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h
+++ b/src/gallium/state_trackers/egl_g3d/x11/x11_screen.h
@@ -70,6 +70,9 @@ x11_screen_get_glx_configs(struct x11_screen *xscr);
 const __GLcontextModes *
 x11_screen_get_glx_visuals(struct x11_screen *xscr);
 
+const char *
+x11_screen_probe_dri2(struct x11_screen *xscr);
+
 int
 x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver);
 




More information about the mesa-commit mailing list