Mesa (9.2): wayland: Don' t rely on static variable for identifying wl_drm buffers

Kristian Høgsberg krh at kemper.freedesktop.org
Thu Oct 24 21:02:07 UTC 2013


Module: Mesa
Branch: 9.2
Commit: 7ab2b8c4c4607817c91946dcba943b29f1bd1895
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7ab2b8c4c4607817c91946dcba943b29f1bd1895

Author: Kristian Høgsberg <krh at bitplanet.net>
Date:   Thu Sep 26 12:25:11 2013 -0700

wayland: Don't rely on static variable for identifying wl_drm buffers

Now that libEGL has been fixed to not leak all kinds of symbols, gbm
links to its own copy of the libwayland-drm.a helper library.  That means
we can't rely on comparing the addresses of a static vtable symbol in that
library to determine if a wl_buffer is a wl_drm_buffer.  Instead, we
move the vtable into the wl_drm struct and use that for comparing.

Backported from 360a141f24a9d00891665b7fedb77ffb116944ca.

https://bugs.freedesktop.org/show_bug.cgi?id=69437

Cc: 9.2 <mesa-stable at lists.freedesktop.org>

---

 src/egl/drivers/dri2/egl_dri2.c                    |   10 ++++++++--
 src/egl/wayland/wayland-drm/wayland-drm.c          |   12 +++++-------
 src/egl/wayland/wayland-drm/wayland-drm.h          |    2 +-
 src/gallium/state_trackers/egl/common/native.h     |    4 ++++
 .../egl/common/native_wayland_drm_bufmgr_helper.c  |    2 +-
 src/gallium/state_trackers/egl/drm/native_drm.c    |   18 ++++++++++--------
 src/gallium/state_trackers/egl/drm/native_drm.h    |    8 --------
 .../state_trackers/egl/wayland/native_drm.c        |    2 +-
 src/gallium/state_trackers/egl/x11/native_dri2.c   |    2 +-
 src/gbm/backends/dri/gbm_dri.c                     |    5 ++++-
 src/gbm/backends/dri/gbm_driint.h                  |    2 ++
 11 files changed, 37 insertions(+), 30 deletions(-)

diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 52fcb3f..a8584b7 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1203,7 +1203,7 @@ dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
    EGLint err;
    int32_t plane;
 
-   if (!wayland_buffer_is_drm(&buffer->buffer))
+   if (!wayland_buffer_is_drm(dri2_dpy->wl_server_drm, &buffer->buffer))
        return NULL;
 
    err = _eglParseImageAttribList(&attrs, disp, attr_list);
@@ -1585,6 +1585,11 @@ dri2_bind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp,
    if (!dri2_dpy->wl_server_drm)
 	   return EGL_FALSE;
 
+#ifdef HAVE_DRM_PLATFORM
+   if (dri2_dpy->gbm_dri)
+      dri2_dpy->gbm_dri->wl_drm = dri2_dpy->wl_server_drm;
+#endif
+
    return EGL_TRUE;
 }
 
@@ -1611,9 +1616,10 @@ dri2_query_wayland_buffer_wl(_EGLDriver *drv, _EGLDisplay *disp,
                              EGLint attribute, EGLint *value)
 {
    struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) _buffer;
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
    const struct wl_drm_components_descriptor *format;
 
-   if (!wayland_buffer_is_drm(&buffer->buffer))
+   if (!wayland_buffer_is_drm(dri2_dpy->wl_server_drm, &buffer->buffer))
       return EGL_FALSE;
 
    format = buffer->driver_format;
diff --git a/src/egl/wayland/wayland-drm/wayland-drm.c b/src/egl/wayland/wayland-drm/wayland-drm.c
index 7e2073a..0fbc35b 100644
--- a/src/egl/wayland/wayland-drm/wayland-drm.c
+++ b/src/egl/wayland/wayland-drm/wayland-drm.c
@@ -45,6 +45,7 @@ struct wl_drm {
         uint32_t flags;
 
 	struct wayland_drm_callbacks *callbacks;
+        struct wl_buffer_interface buffer_interface;
 };
 
 static void
@@ -63,10 +64,6 @@ buffer_destroy(struct wl_client *client, struct wl_resource *resource)
 	wl_resource_destroy(resource);
 }
 
-const static struct wl_buffer_interface drm_buffer_interface = {
-	buffer_destroy
-};
-
 static void
 create_buffer(struct wl_client *client, struct wl_resource *resource,
               uint32_t id, uint32_t name, int fd,
@@ -107,7 +104,7 @@ create_buffer(struct wl_client *client, struct wl_resource *resource,
 	buffer->buffer.resource.object.id = id;
 	buffer->buffer.resource.object.interface = &wl_buffer_interface;
 	buffer->buffer.resource.object.implementation =
-		(void (**)(void)) &drm_buffer_interface;
+		(void (**)(void)) &drm->buffer_interface;
 	buffer->buffer.resource.data = buffer;
 
 	buffer->buffer.resource.destroy = destroy_buffer;
@@ -246,6 +243,7 @@ wayland_drm_init(struct wl_display *display, char *device_name,
 	drm->callbacks = callbacks;
 	drm->user_data = user_data;
         drm->flags = flags;
+        drm->buffer_interface.destroy = buffer_destroy;
 
 	wl_display_add_global(display, &wl_drm_interface, drm, bind_drm);
 
@@ -263,10 +261,10 @@ wayland_drm_uninit(struct wl_drm *drm)
 }
 
 int
-wayland_buffer_is_drm(struct wl_buffer *buffer)
+wayland_buffer_is_drm(struct wl_drm *drm, struct wl_buffer *buffer)
 {
 	return buffer->resource.object.implementation == 
-		(void (**)(void)) &drm_buffer_interface;
+		(void (**)(void)) &drm->buffer_interface;
 }
 
 uint32_t
diff --git a/src/egl/wayland/wayland-drm/wayland-drm.h b/src/egl/wayland/wayland-drm/wayland-drm.h
index 335073a..07ec29a 100644
--- a/src/egl/wayland/wayland-drm/wayland-drm.h
+++ b/src/egl/wayland/wayland-drm/wayland-drm.h
@@ -99,7 +99,7 @@ void
 wayland_drm_uninit(struct wl_drm *drm);
 
 int
-wayland_buffer_is_drm(struct wl_buffer *buffer);
+wayland_buffer_is_drm(struct wl_drm *drm, struct wl_buffer *buffer);
 
 uint32_t
 wayland_drm_buffer_get_format(struct wl_buffer *buffer_base);
diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h
index 431bd3f..f8e12f3 100644
--- a/src/gallium/state_trackers/egl/common/native.h
+++ b/src/gallium/state_trackers/egl/common/native.h
@@ -246,6 +246,10 @@ struct native_display {
    const struct native_display_buffer *buffer;
    const struct native_display_modeset *modeset;
    const struct native_display_wayland_bufmgr *wayland_bufmgr;
+
+#ifdef HAVE_WAYLAND_BACKEND
+   struct wl_drm *wl_server_drm; /* for EGL_WL_bind_wayland_display */
+#endif
 };
 
 /**
diff --git a/src/gallium/state_trackers/egl/common/native_wayland_drm_bufmgr_helper.c b/src/gallium/state_trackers/egl/common/native_wayland_drm_bufmgr_helper.c
index a9e7342..eca9c36 100644
--- a/src/gallium/state_trackers/egl/common/native_wayland_drm_bufmgr_helper.c
+++ b/src/gallium/state_trackers/egl/common/native_wayland_drm_bufmgr_helper.c
@@ -77,7 +77,7 @@ egl_g3d_wl_drm_common_query_buffer(struct native_display *ndpy,
    struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) _buffer;
    struct pipe_resource *resource = buffer->driver_buffer;
 
-   if (!wayland_buffer_is_drm(&buffer->buffer))
+   if (!wayland_buffer_is_drm(ndpy->wl_server_drm, &buffer->buffer))
       return EGL_FALSE;
 
    switch (attribute) {
diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c
index 03bfdda..2e9f388 100644
--- a/src/gallium/state_trackers/egl/drm/native_drm.c
+++ b/src/gallium/state_trackers/egl/drm/native_drm.c
@@ -39,6 +39,10 @@
 #include <libudev.h>
 #endif
 
+#ifdef HAVE_WAYLAND_BACKEND
+#include "common/native_wayland_drm_bufmgr_helper.h"
+#endif
+
 static boolean
 drm_display_is_format_supported(struct native_display *ndpy,
                                 enum pipe_format fmt, boolean is_color)
@@ -207,14 +211,14 @@ drm_display_bind_wayland_display(struct native_display *ndpy,
 {
    struct drm_display *drmdpy = drm_display(ndpy);
 
-   if (drmdpy->wl_server_drm)
+   if (ndpy->wl_server_drm)
       return FALSE;
 
-   drmdpy->wl_server_drm = wayland_drm_init(wl_dpy,
+   ndpy->wl_server_drm = wayland_drm_init(wl_dpy,
          drmdpy->device_name,
          &wl_drm_callbacks, ndpy, 0);
 
-   if (!drmdpy->wl_server_drm)
+   if (!ndpy->wl_server_drm)
       return FALSE;
    
    return TRUE;
@@ -224,13 +228,11 @@ static boolean
 drm_display_unbind_wayland_display(struct native_display *ndpy,
                                     struct wl_display *wl_dpy)
 {
-   struct drm_display *drmdpy = drm_display(ndpy);
-
-   if (!drmdpy->wl_server_drm)
+   if (!ndpy->wl_server_drm)
       return FALSE;
 
-   wayland_drm_uninit(drmdpy->wl_server_drm);
-   drmdpy->wl_server_drm = NULL;
+   wayland_drm_uninit(ndpy->wl_server_drm);
+   ndpy->wl_server_drm = NULL;
 
    return TRUE;
 }
diff --git a/src/gallium/state_trackers/egl/drm/native_drm.h b/src/gallium/state_trackers/egl/drm/native_drm.h
index 16a4251..1e9761b 100644
--- a/src/gallium/state_trackers/egl/drm/native_drm.h
+++ b/src/gallium/state_trackers/egl/drm/native_drm.h
@@ -36,10 +36,6 @@
 #include "common/native.h"
 #include "common/native_helper.h"
 
-#ifdef HAVE_WAYLAND_BACKEND
-#include "common/native_wayland_drm_bufmgr_helper.h"
-#endif
-
 #include "gbm_gallium_drmint.h"
 
 struct drm_config;
@@ -67,10 +63,6 @@ struct drm_display {
    struct drm_surface **shown_surfaces;
    /* save the original settings of the CRTCs */
    struct drm_crtc *saved_crtcs;
-
-#ifdef HAVE_WAYLAND_BACKEND
-   struct wl_drm *wl_server_drm; /* for EGL_WL_bind_wayland_display */
-#endif
 };
 
 struct drm_config {
diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c b/src/gallium/state_trackers/egl/wayland/native_drm.c
index fc8aac7..004177e 100644
--- a/src/gallium/state_trackers/egl/wayland/native_drm.c
+++ b/src/gallium/state_trackers/egl/wayland/native_drm.c
@@ -268,7 +268,7 @@ wayland_drm_display_bind_wayland_display(struct native_display *ndpy,
    if (drmdpy->wl_server_drm)
       return FALSE;
 
-   drmdpy->wl_server_drm =
+   ndpy->wl_server_drm =
       wayland_drm_init(wl_dpy, drmdpy->device_name,
                        &wl_drm_callbacks, ndpy, 0);
 
diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c
index 053044a..a315c95 100644
--- a/src/gallium/state_trackers/egl/x11/native_dri2.c
+++ b/src/gallium/state_trackers/egl/x11/native_dri2.c
@@ -858,7 +858,7 @@ dri2_display_bind_wayland_display(struct native_display *ndpy,
    if (dri2dpy->wl_server_drm)
       return FALSE;
 
-   dri2dpy->wl_server_drm = wayland_drm_init(wl_dpy,
+   ndpy->wl_server_drm = wayland_drm_init(wl_dpy,
          x11_screen_get_device_name(dri2dpy->xscr),
          &wl_drm_callbacks, ndpy, 0);
 
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
index a3a0530..c44cb48 100644
--- a/src/gbm/backends/dri/gbm_dri.c
+++ b/src/gbm/backends/dri/gbm_dri.c
@@ -376,7 +376,10 @@ gbm_dri_bo_import(struct gbm_device *gbm,
    {
       struct wl_drm_buffer *wb = (struct wl_drm_buffer *) buffer;
 
-      if (!wayland_buffer_is_drm(buffer))
+      if (dri->wl_drm == NULL)
+         return NULL;
+
+      if (!wayland_buffer_is_drm(dri->wl_drm, buffer))
          return NULL;
 
       image = wb->driver_buffer;
diff --git a/src/gbm/backends/dri/gbm_driint.h b/src/gbm/backends/dri/gbm_driint.h
index 18fc3c0..90d764f 100644
--- a/src/gbm/backends/dri/gbm_driint.h
+++ b/src/gbm/backends/dri/gbm_driint.h
@@ -66,6 +66,8 @@ struct gbm_dri_device {
 			     int *width, int *height,
 			     unsigned int *attachments, int count,
 			     int *out_count, void *data);
+
+   struct wl_drm *wl_drm;
 };
 
 struct gbm_dri_bo {




More information about the mesa-commit mailing list