st/egl: Add dri2InvalidateBuffers.
authorChia-I Wu <olv@lunarg.com>
Wed, 17 Feb 2010 15:11:31 +0000 (23:11 +0800)
committerChia-I Wu <olv@lunarg.com>
Thu, 25 Feb 2010 13:29:36 +0000 (21:29 +0800)
src/glx/dri2.c will call dri2InvalidateBuffers when
DRI2_InvalidateBuffers event is received.  This fixes a missing symbol
error, and paves the way for event-based validation.

src/gallium/state_trackers/egl/x11/native_dri2.c
src/gallium/state_trackers/egl/x11/native_x11.c
src/gallium/state_trackers/egl/x11/x11_screen.c
src/gallium/state_trackers/egl/x11/x11_screen.h

index dbd1a64..feae025 100644 (file)
@@ -50,6 +50,8 @@ struct dri2_display {
    struct drm_api *api;
    struct x11_screen *xscr;
    int xscr_number;
+   const char *dri_driver;
+   int dri_major, dri_minor;
 
    struct dri2_config *configs;
    int num_configs;
@@ -681,7 +683,16 @@ dri2_display_init_screen(struct native_display *ndpy)
       return FALSE;
    }
 
-   fd = x11_screen_enable_dri2(dri2dpy->xscr, driver);
+   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, dri2dpy->api->name);
+      return FALSE;
+   }
+
+   fd = x11_screen_enable_dri2(dri2dpy->xscr, NULL, NULL);
    if (fd < 0)
       return FALSE;
 
index 55f0d4d..3add95d 100644 (file)
@@ -70,7 +70,7 @@ native_create_probe(EGLNativeDisplayType dpy)
    xscr = x11_screen_create(xdpy, scr);
    if (xscr) {
       if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) {
-         driver_name = x11_screen_probe_dri2(xscr);
+         driver_name = x11_screen_probe_dri2(xscr, NULL, NULL);
          if (driver_name)
             nprobe->data = strdup(driver_name);
       }
index d72bfc9..f409611 100644 (file)
@@ -39,6 +39,9 @@
 #include "glxinit.h"
 
 struct x11_screen {
+   /* dummy base class */
+   struct __GLXDRIdisplayRec base;
+
    Display *dpy;
    int number;
 
@@ -53,6 +56,9 @@ struct x11_screen {
    char *dri_device;
    int dri_fd;
 
+   x11_drawable_invalidate_buffers dri_invalidate_buffers;
+   void *dri_user_data;
+
    XVisualInfo *visuals;
    int num_visuals;
 
@@ -98,6 +104,8 @@ x11_screen_destroy(struct x11_screen *xscr)
       Xfree(xscr->dri_device);
 
    /* xscr->glx_dpy will be destroyed with the X display */
+   if (xscr->glx_dpy)
+      xscr->glx_dpy->dri2Display = NULL;
 
    if (xscr->visuals)
       XFree(xscr->visuals);
@@ -247,24 +255,25 @@ x11_screen_get_glx_visuals(struct x11_screen *xscr)
       : NULL;
 }
 
-static boolean
-x11_screen_is_driver_equal(struct x11_screen *xscr, const char *driver)
-{
-   return (strcmp(xscr->dri_driver, driver) == 0);
-}
-
 /**
  * Probe the screen for the DRI2 driver name.
  */
 const char *
-x11_screen_probe_dri2(struct x11_screen *xscr)
+x11_screen_probe_dri2(struct x11_screen *xscr, int *major, int *minor)
 {
+   if (!x11_screen_init_dri2(xscr))
+      return NULL;
+
    /* 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;
    }
+   if (major)
+      *major = xscr->dri_major;
+   if (minor)
+      *minor = xscr->dri_minor;
 
    return xscr->dri_driver;
 }
@@ -274,21 +283,17 @@ x11_screen_probe_dri2(struct x11_screen *xscr)
  * descriptor will be closed automatically when the screen is destoryed.
  */
 int
-x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver)
+x11_screen_enable_dri2(struct x11_screen *xscr,
+                       x11_drawable_invalidate_buffers invalidate_buffers,
+                       void *user_data)
 {
    if (xscr->dri_fd < 0) {
       int fd;
       drm_magic_t magic;
 
       /* get the driver name and the device name first */
-      if (!x11_screen_probe_dri2(xscr))
-         return -1;
-
-      if (!x11_screen_is_driver_equal(xscr, driver)) {
-         _eglLog(_EGL_WARNING, "Driver mismatch: %s != %s",
-               xscr->dri_driver, driver);
+      if (!x11_screen_probe_dri2(xscr, NULL, NULL))
          return -1;
-      }
 
       fd = open(xscr->dri_device, O_RDWR);
       if (fd < 0) {
@@ -310,6 +315,22 @@ x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver)
          return -1;
       }
 
+      if (!x11_screen_init_glx(xscr)) {
+         _eglLog(_EGL_WARNING, "failed to initialize GLX");
+         close(fd);
+         return -1;
+      }
+      if (xscr->glx_dpy->dri2Display) {
+         _eglLog(_EGL_WARNING,
+               "display is already managed by another x11 screen");
+         close(fd);
+         return -1;
+      }
+
+      xscr->glx_dpy->dri2Display = (__GLXDRIdisplay *) xscr;
+      xscr->dri_invalidate_buffers = invalidate_buffers;
+      xscr->dri_user_data = user_data;
+
       xscr->dri_fd = fd;
    }
 
@@ -451,3 +472,20 @@ x11_context_modes_count(const __GLcontextModes *modes)
       count++;
    return count;
 }
+
+/**
+ * This is called from src/glx/dri2.c.
+ */
+void
+dri2InvalidateBuffers(Display *dpy, XID drawable)
+{
+   __GLXdisplayPrivate *priv = __glXInitialize(dpy);
+   struct x11_screen *xscr = NULL;
+
+   if (priv && priv->dri2Display)
+      xscr = (struct x11_screen *) priv->dri2Display;
+   if (!xscr || !xscr->dri_invalidate_buffers)
+      return;
+
+   xscr->dri_invalidate_buffers(xscr, drawable, xscr->dri_user_data);
+}
index 5432858..37e8d5a 100644 (file)
@@ -48,6 +48,10 @@ struct x11_drawable_buffer {
 
 struct x11_screen;
 
+typedef void (*x11_drawable_invalidate_buffers)(struct x11_screen *xscr,
+                                                Drawable drawable,
+                                                void *user_data);
+
 struct x11_screen *
 x11_screen_create(Display *dpy, int screen);
 
@@ -71,10 +75,12 @@ const __GLcontextModes *
 x11_screen_get_glx_visuals(struct x11_screen *xscr);
 
 const char *
-x11_screen_probe_dri2(struct x11_screen *xscr);
+x11_screen_probe_dri2(struct x11_screen *xscr, int *major, int *minor);
 
 int
-x11_screen_enable_dri2(struct x11_screen *xscr, const char *driver);
+x11_screen_enable_dri2(struct x11_screen *xscr,
+                       x11_drawable_invalidate_buffers invalidate_buffers,
+                       void *user_data);
 
 __GLcontextModes *
 x11_context_modes_create(unsigned count);