#include "wayland-drm-client-protocol.h"
/* XXX: Wayland/DRM support currently lives in Mesa libEGL.so.* library */
-#define LIBWAYLAND_DRM_NAME "libEGL.so.1"
+/* First try the soname of a glvnd enabled mesa build */
+#define LIBWAYLAND_DRM_NAME "libEGL_mesa.so.0"
+/* Then fallback to plain libEGL.so.1 (which might not be mesa) */
+#define LIBWAYLAND_DRM_NAME_FALLBACK "libEGL.so.1"
typedef struct va_wayland_drm_context {
struct va_wayland_context base;
void *handle;
struct wl_drm *drm;
+ struct wl_registry *registry;
void *drm_interface;
unsigned int is_authenticated : 1;
} VADisplayContextWaylandDRM;
drm_state->auth_type = VA_DRM_AUTH_CUSTOM;
}
+static void
+drm_handle_capabilities(void *data, struct wl_drm *wl_drm, uint32_t value)
+{
+ VADisplayContextP const pDisplayContext = data;
+ VADriverContextP const ctx = pDisplayContext->pDriverContext;
+ struct VADriverVTableWayland *vtable = ctx->vtable_wayland;
+
+ vtable->has_prime_sharing = !!(value & WL_DRM_CAPABILITY_PRIME);
+}
+
static const struct wl_drm_listener drm_listener = {
drm_handle_device,
drm_handle_format,
- drm_handle_authenticated
+ drm_handle_authenticated,
+ drm_handle_capabilities,
};
static VAStatus
VADriverContextP const ctx = pDisplayContext->pDriverContext;
struct va_wayland_drm_context * const wl_drm_ctx = pDisplayContext->opaque;
struct drm_state * const drm_state = ctx->drm_state;
+ struct VADriverVTableWayland *vtable = ctx->vtable_wayland;
+
+ vtable->has_prime_sharing = 0;
if (wl_drm_ctx->drm) {
wl_drm_destroy(wl_drm_ctx->drm);
}
wl_drm_ctx->is_authenticated = 0;
+ if (wl_drm_ctx->registry) {
+ wl_registry_destroy(wl_drm_ctx->registry);
+ wl_drm_ctx->registry = NULL;
+ }
+
if (wl_drm_ctx->handle) {
dlclose(wl_drm_ctx->handle);
wl_drm_ctx->handle = NULL;
}
}
+static void
+registry_handle_global(
+ void *data,
+ struct wl_registry *registry,
+ uint32_t id,
+ const char *interface,
+ uint32_t version
+)
+{
+ struct va_wayland_drm_context *wl_drm_ctx = data;
+
+ if (strcmp(interface, "wl_drm") == 0) {
+ wl_drm_ctx->drm =
+ wl_registry_bind(wl_drm_ctx->registry, id, wl_drm_ctx->drm_interface, 2);
+ }
+}
+
+static const struct wl_registry_listener registry_listener = {
+ registry_handle_global,
+ NULL,
+};
+
bool
va_wayland_drm_create(VADisplayContextP pDisplayContext)
{
VADriverContextP const ctx = pDisplayContext->pDriverContext;
struct va_wayland_drm_context *wl_drm_ctx;
struct drm_state *drm_state;
- uint32_t id;
+ struct VADriverVTableWayland *vtable = ctx->vtable_wayland;
wl_drm_ctx = malloc(sizeof(*wl_drm_ctx));
if (!wl_drm_ctx)
wl_drm_ctx->handle = NULL;
wl_drm_ctx->drm = NULL;
wl_drm_ctx->drm_interface = NULL;
+ wl_drm_ctx->registry = NULL;
wl_drm_ctx->is_authenticated = 0;
pDisplayContext->opaque = wl_drm_ctx;
pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName;
drm_state->fd = -1;
drm_state->auth_type = 0;
ctx->drm_state = drm_state;
+ vtable->has_prime_sharing = 0;
- id = wl_display_get_global(ctx->native_dpy, "wl_drm", 1);
- if (!id) {
- wl_display_roundtrip(ctx->native_dpy);
- id = wl_display_get_global(ctx->native_dpy, "wl_drm", 1);
- if (!id)
+ wl_drm_ctx->handle = dlopen(LIBWAYLAND_DRM_NAME, RTLD_LAZY|RTLD_LOCAL);
+ if (!wl_drm_ctx->handle) {
+ wl_drm_ctx->handle = dlopen(LIBWAYLAND_DRM_NAME_FALLBACK, RTLD_LAZY|RTLD_LOCAL);
+ if (!wl_drm_ctx->handle)
return false;
}
- wl_drm_ctx->handle = dlopen(LIBWAYLAND_DRM_NAME, RTLD_LAZY|RTLD_LOCAL);
- if (!wl_drm_ctx->handle)
- return false;
-
wl_drm_ctx->drm_interface =
dlsym(wl_drm_ctx->handle, "wl_drm_interface");
if (!wl_drm_ctx->drm_interface)
return false;
- wl_drm_ctx->drm =
- wl_display_bind(ctx->native_dpy, id, wl_drm_ctx->drm_interface);
+ wl_drm_ctx->registry = wl_display_get_registry(ctx->native_dpy);
+ wl_registry_add_listener(wl_drm_ctx->registry, ®istry_listener, wl_drm_ctx);
+ wl_display_roundtrip(ctx->native_dpy);
+
+ /* registry_handle_global should have been called by the
+ * wl_display_roundtrip above
+ */
+
if (!wl_drm_ctx->drm)
return false;