Mesa (master): st/egl: Add event support to the native display interface.

Chia-I Wu olv at kemper.freedesktop.org
Fri Mar 5 03:33:34 UTC 2010


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

Author: Chia-I Wu <olv at lunarg.com>
Date:   Sun Feb 21 10:58:22 2010 +0800

st/egl: Add event support to the native display interface.

There is only invalid_surface event right now.  When EGL receives the
event, it sets the force_validate flag of the context binding to the
surface.  This helps skip an unnecessary check.

---

 src/gallium/state_trackers/egl/common/egl_g3d.c    |   23 ++++++++++++++++-
 src/gallium/state_trackers/egl/common/native.h     |   27 +++++++++++++++++++-
 src/gallium/state_trackers/egl/kms/native_kms.c    |   13 +++++++--
 src/gallium/state_trackers/egl/kms/native_kms.h    |    2 +
 src/gallium/state_trackers/egl/x11/native_dri2.c   |   20 ++++++++++++--
 src/gallium/state_trackers/egl/x11/native_x11.c    |    7 +++--
 src/gallium/state_trackers/egl/x11/native_x11.h    |    8 ++++-
 src/gallium/state_trackers/egl/x11/native_ximage.c |   20 ++++++++++++++-
 8 files changed, 106 insertions(+), 14 deletions(-)

diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index 04268c7..ddb1ef1 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -531,6 +531,24 @@ egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private)
    egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base);
 }
 
+static void
+egl_g3d_invalid_surface(struct native_display *ndpy,
+                        struct native_surface *nsurf,
+                        unsigned int seq_num)
+{
+   /* XXX not thread safe? */
+   struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
+   struct egl_g3d_context *gctx = egl_g3d_context(gsurf->base.CurrentContext);
+
+   /* set force_validate to skip an unnecessary check */
+   if (gctx)
+      gctx->force_validate = TRUE;
+}
+
+static struct native_event_handler egl_g3d_native_event_handler = {
+   .invalid_surface = egl_g3d_invalid_surface
+};
+
 static EGLBoolean
 egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
 {
@@ -575,12 +593,14 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
    }
    dpy->DriverData = gdpy;
 
-   gdpy->native = native_create_display(dpy->NativeDisplay);
+   gdpy->native = native_create_display(dpy->NativeDisplay,
+         &egl_g3d_native_event_handler);
    if (!gdpy->native) {
       _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
       goto fail;
    }
 
+   gdpy->native->user_data = (void *) dpy;
    gdpy->native->screen->flush_frontbuffer = egl_g3d_flush_frontbuffer;
    gdpy->native->screen->update_buffer = egl_g3d_update_buffer;
 
@@ -776,6 +796,7 @@ egl_g3d_create_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
       return NULL;
    }
 
+   nsurf->user_data = &gsurf->base;
    gsurf->native = nsurf;
 
    gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER) ?
diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h
index 4f97585..1bf2804 100644
--- a/src/gallium/state_trackers/egl/common/native.h
+++ b/src/gallium/state_trackers/egl/common/native.h
@@ -69,6 +69,11 @@ struct native_probe {
 };
 
 struct native_surface {
+   /**
+    * Available for caller's use.
+    */
+   void *user_data;
+
    void (*destroy)(struct native_surface *nsurf);
 
    /**
@@ -143,6 +148,11 @@ struct native_display {
     */
    struct pipe_screen *screen;
 
+   /**
+    * Available for caller's use.
+    */
+   void *user_data;
+
    void (*destroy)(struct native_display *ndpy);
 
    /**
@@ -239,6 +249,20 @@ struct native_display_modeset {
 };
 
 /**
+ * The handler for events that a native display may generate.  The events are
+ * generated asynchronously and the handler may be called by any thread at any
+ * time.
+ */
+struct native_event_handler {
+   /**
+    * This function is called when a surface needs to be validated.
+    */
+   void (*invalid_surface)(struct native_display *ndpy,
+                           struct native_surface *nsurf,
+                           unsigned int seq_num);
+};
+
+/**
  * Test whether an attachment is set in the mask.
  */
 static INLINE boolean
@@ -267,6 +291,7 @@ const char *
 native_get_name(void);
 
 struct native_display *
-native_create_display(EGLNativeDisplayType dpy);
+native_create_display(EGLNativeDisplayType dpy,
+                      struct native_event_handler *handler);
 
 #endif /* _NATIVE_H_ */
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c
index aedf3d4..90c82ea 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl/kms/native_kms.c
@@ -201,6 +201,8 @@ kms_surface_swap_buffers(struct native_surface *nsurf)
 
    /* the front/back textures are swapped */
    ksurf->sequence_number++;
+   kdpy->event_handler->invalid_surface(&kdpy->base,
+         &ksurf->base, ksurf->sequence_number);
 
    return TRUE;
 }
@@ -762,7 +764,9 @@ static struct native_display_modeset kms_display_modeset = {
 };
 
 static struct native_display *
-kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api)
+kms_create_display(EGLNativeDisplayType dpy,
+                   struct native_event_handler *event_handler,
+                   struct drm_api *api)
 {
    struct kms_display *kdpy;
 
@@ -770,6 +774,8 @@ kms_create_display(EGLNativeDisplayType dpy, struct drm_api *api)
    if (!kdpy)
       return NULL;
 
+   kdpy->event_handler = event_handler;
+
    kdpy->api = api;
    if (!kdpy->api) {
       _eglLog(_EGL_WARNING, "failed to create DRM API");
@@ -845,7 +851,8 @@ native_get_name(void)
 }
 
 struct native_display *
-native_create_display(EGLNativeDisplayType dpy)
+native_create_display(EGLNativeDisplayType dpy,
+                      struct native_event_handler *event_handler)
 {
    struct native_display *ndpy = NULL;
 
@@ -853,7 +860,7 @@ native_create_display(EGLNativeDisplayType dpy)
       drm_api = drm_api_create();
 
    if (drm_api)
-      ndpy = kms_create_display(dpy, drm_api);
+      ndpy = kms_create_display(dpy, event_handler, drm_api);
 
    return ndpy;
 }
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.h b/src/gallium/state_trackers/egl/kms/native_kms.h
index 095186e..f9cbcb1 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.h
+++ b/src/gallium/state_trackers/egl/kms/native_kms.h
@@ -53,6 +53,8 @@ struct kms_crtc {
 struct kms_display {
    struct native_display base;
 
+   struct native_event_handler *event_handler;
+
    int fd;
    struct drm_api *api;
    drmModeResPtr resources;
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index 74d3d10..858033e 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -48,6 +48,8 @@ struct dri2_display {
    Display *dpy;
    boolean own_dpy;
 
+   struct native_event_handler *event_handler;
+
    struct drm_api *api;
    struct x11_screen *xscr;
    int xscr_number;
@@ -324,8 +326,11 @@ dri2_surface_flush_frontbuffer(struct native_surface *nsurf)
             DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
 
    /* force buffers to be updated in next validation call */
-   if (!dri2_surface_receive_events(&dri2surf->base))
+   if (!dri2_surface_receive_events(&dri2surf->base)) {
       dri2surf->server_stamp++;
+      dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
+            &dri2surf->base, dri2surf->server_stamp);
+   }
 
    return TRUE;
 }
@@ -353,8 +358,11 @@ dri2_surface_swap_buffers(struct native_surface *nsurf)
             DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
 
    /* force buffers to be updated in next validation call */
-   if (!dri2_surface_receive_events(&dri2surf->base))
+   if (!dri2_surface_receive_events(&dri2surf->base)) {
       dri2surf->server_stamp++;
+      dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
+            &dri2surf->base, dri2surf->server_stamp);
+   }
 
    return TRUE;
 }
@@ -737,7 +745,10 @@ dri2_display_invalidate_buffers(struct x11_screen *xscr, Drawable drawable,
       return;
 
    dri2surf = dri2_surface(nsurf);
+
    dri2surf->server_stamp++;
+   dri2dpy->event_handler->invalid_surface(&dri2dpy->base,
+         &dri2surf->base, dri2surf->server_stamp);
 }
 
 /**
@@ -796,7 +807,9 @@ dri2_display_hash_table_compare(void *key1, void *key2)
 }
 
 struct native_display *
-x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api)
+x11_create_dri2_display(EGLNativeDisplayType dpy,
+                        struct native_event_handler *event_handler,
+                        struct drm_api *api)
 {
    struct dri2_display *dri2dpy;
 
@@ -804,6 +817,7 @@ x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api)
    if (!dri2dpy)
       return NULL;
 
+   dri2dpy->event_handler = event_handler;
    dri2dpy->api = api;
 
    dri2dpy->dpy = dpy;
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c
index 3add95d..7b4fe63 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.c
+++ b/src/gallium/state_trackers/egl/x11/native_x11.c
@@ -126,7 +126,8 @@ native_get_name(void)
 }
 
 struct native_display *
-native_create_display(EGLNativeDisplayType dpy)
+native_create_display(EGLNativeDisplayType dpy,
+                      struct native_event_handler *event_handler)
 {
    struct native_display *ndpy = NULL;
    boolean force_sw;
@@ -136,7 +137,7 @@ native_create_display(EGLNativeDisplayType dpy)
 
    force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
    if (api && !force_sw) {
-      ndpy = x11_create_dri2_display(dpy, api);
+      ndpy = x11_create_dri2_display(dpy, event_handler, api);
    }
 
    if (!ndpy) {
@@ -150,7 +151,7 @@ native_create_display(EGLNativeDisplayType dpy)
        */
       use_shm = FALSE;
       _eglLog(level, "use software%s fallback", (use_shm) ? " (SHM)" : "");
-      ndpy = x11_create_ximage_display(dpy, use_shm);
+      ndpy = x11_create_ximage_display(dpy, event_handler, use_shm);
    }
 
    return ndpy;
diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h
index 622ddac..8c6a7d9 100644
--- a/src/gallium/state_trackers/egl/x11/native_x11.h
+++ b/src/gallium/state_trackers/egl/x11/native_x11.h
@@ -29,9 +29,13 @@
 #include "common/native.h"
 
 struct native_display *
-x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm);
+x11_create_ximage_display(EGLNativeDisplayType dpy,
+                          struct native_event_handler *event_handler,
+                          boolean use_xshm);
 
 struct native_display *
-x11_create_dri2_display(EGLNativeDisplayType dpy, struct drm_api *api);
+x11_create_dri2_display(EGLNativeDisplayType dpy,
+                        struct native_event_handler *event_handler,
+                        struct drm_api *api);
 
 #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 a8633b1..5e0270c 100644
--- a/src/gallium/state_trackers/egl/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
@@ -56,6 +56,8 @@ struct ximage_display {
    struct x11_screen *xscr;
    int xscr_number;
 
+   struct native_event_handler *event_handler;
+
    boolean use_xshm;
 
    struct pipe_winsys *winsys;
@@ -228,6 +230,16 @@ ximage_surface_update_geometry(struct native_surface *nsurf)
    return updated;
 }
 
+static void
+ximage_surface_notify_invalid(struct native_surface *nsurf)
+{
+   struct ximage_surface *xsurf = ximage_surface(nsurf);
+   struct ximage_display *xdpy = xsurf->xdpy;
+
+   xdpy->event_handler->invalid_surface(&xdpy->base,
+         &xsurf->base, xsurf->server_stamp);
+}
+
 /**
  * Update the buffers of the surface.  It is a slow function due to the
  * round-trip to the server.
@@ -339,6 +351,7 @@ ximage_surface_flush_frontbuffer(struct native_surface *nsurf)
          NATIVE_ATTACHMENT_FRONT_LEFT);
    /* force buffers to be updated in next validation call */
    xsurf->server_stamp++;
+   ximage_surface_notify_invalid(&xsurf->base);
 
    return ret;
 }
@@ -354,6 +367,7 @@ ximage_surface_swap_buffers(struct native_surface *nsurf)
    ret = ximage_surface_draw_buffer(nsurf, NATIVE_ATTACHMENT_BACK_LEFT);
    /* force buffers to be updated in next validation call */
    xsurf->server_stamp++;
+   ximage_surface_notify_invalid(&xsurf->base);
 
    xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT];
    xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT];
@@ -703,7 +717,9 @@ ximage_display_destroy(struct native_display *ndpy)
 }
 
 struct native_display *
-x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm)
+x11_create_ximage_display(EGLNativeDisplayType dpy,
+                          struct native_event_handler *event_handler,
+                          boolean use_xshm)
 {
    struct ximage_display *xdpy;
 
@@ -728,6 +744,8 @@ x11_create_ximage_display(EGLNativeDisplayType dpy, boolean use_xshm)
       return NULL;
    }
 
+   xdpy->event_handler = event_handler;
+
    xdpy->use_xshm =
       (use_xshm && x11_screen_support(xdpy->xscr, X11_SCREEN_EXTENSION_XSHM));
 




More information about the mesa-commit mailing list