egl: Add EGL_WL_bind_wayland_display
This commit is contained in:

committed by
Kristian Høgsberg

parent
654adaabc9
commit
6b369c4c7c
@@ -1587,7 +1587,7 @@ yes)
|
|||||||
GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/fbdev"
|
GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/fbdev"
|
||||||
fi
|
fi
|
||||||
if test "$plat" = "wayland"; then
|
if test "$plat" = "wayland"; then
|
||||||
PKG_CHECK_MODULES([WAYLAND], [wayland-client],, \
|
PKG_CHECK_MODULES([WAYLAND], [wayland-client wayland-server],, \
|
||||||
[AC_MSG_ERROR([cannot find libwayland-client])])
|
[AC_MSG_ERROR([cannot find libwayland-client])])
|
||||||
WAYLAND_EGL_LIB_DEPS="$WAYLAND_LIBS $LIBDRM_LIBS"
|
WAYLAND_EGL_LIB_DEPS="$WAYLAND_LIBS $LIBDRM_LIBS"
|
||||||
fi
|
fi
|
||||||
|
92
docs/WL_bind_wayland_display.spec
Normal file
92
docs/WL_bind_wayland_display.spec
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
Name
|
||||||
|
|
||||||
|
WL_bind_wayland_display
|
||||||
|
|
||||||
|
Name Strings
|
||||||
|
|
||||||
|
EGL_WL_bind_wayland_display
|
||||||
|
|
||||||
|
Contact
|
||||||
|
|
||||||
|
Kristian Høgsberg <krh@bitplanet.net>
|
||||||
|
Benjamin Franzke <benjaminfranzke@googlemail.com>
|
||||||
|
|
||||||
|
Status
|
||||||
|
|
||||||
|
Proposal
|
||||||
|
|
||||||
|
Version
|
||||||
|
|
||||||
|
Version 1, March 1, 2011
|
||||||
|
|
||||||
|
Number
|
||||||
|
|
||||||
|
EGL Extension #not assigned
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
|
||||||
|
Reguires EGL 1.4 or later. This extension is written against the
|
||||||
|
wording of the EGL 1.4 specification.
|
||||||
|
|
||||||
|
EGL_KHR_base_image is required.
|
||||||
|
|
||||||
|
Overview
|
||||||
|
|
||||||
|
This extension provides entry points for binding and unbinding the
|
||||||
|
wl_display of a Wayland compositor to an EGLDisplay. Binding a
|
||||||
|
wl_display means that the EGL implementation should provide one or
|
||||||
|
more interfaces in the Wayland protocol to allow clients to create
|
||||||
|
wl_buffer objects. On the server side, this extension also
|
||||||
|
provides a new target for eglCreateImageKHR, to create an EGLImage
|
||||||
|
from a wl_buffer
|
||||||
|
|
||||||
|
Adding a implementation specific wayland interface, allows the
|
||||||
|
EGL implementation to define specific wayland requests and events,
|
||||||
|
needed for buffer sharing in a EGL wayland platform.
|
||||||
|
|
||||||
|
IP Status
|
||||||
|
|
||||||
|
Open-source; freely implementable.
|
||||||
|
|
||||||
|
New Procedures and Functions
|
||||||
|
|
||||||
|
EGLBoolean eglBindWaylandDisplayWL(EGLDisplay dpy,
|
||||||
|
struct wl_display *display);
|
||||||
|
|
||||||
|
EGLBoolean eglUnbindWaylandDisplayWL(EGLDisplay dpy,
|
||||||
|
struct wl_display *display);
|
||||||
|
|
||||||
|
New Tokens
|
||||||
|
|
||||||
|
Accepted as <target> in eglCreateImageKHR
|
||||||
|
|
||||||
|
EGL_WAYLAND_BUFFER_WL 0x31D5
|
||||||
|
|
||||||
|
Additions to the EGL 1.4 Specification:
|
||||||
|
|
||||||
|
To bind a server side wl_display to an EGLDisplay, call
|
||||||
|
|
||||||
|
EGLBoolean eglBindWaylandDisplayWL(EGLDisplay dpy,
|
||||||
|
struct wl_display *display);
|
||||||
|
|
||||||
|
To unbind a server side wl_display from an EGLDisplay, call
|
||||||
|
|
||||||
|
EGLBoolean eglUnbindWaylandDisplayWL(EGLDisplay dpy,
|
||||||
|
struct wl_display *display);
|
||||||
|
|
||||||
|
eglBindWaylandDisplayWL returns EGL_FALSE when there is already a
|
||||||
|
wl_display bound to EGLDisplay otherwise EGL_TRUE.
|
||||||
|
|
||||||
|
eglUnbindWaylandDisplayWL returns EGL_FALSE when there is no
|
||||||
|
wl_display bound to the EGLDisplay currently otherwise EGL_TRUE.
|
||||||
|
|
||||||
|
Import a wl_buffer by calling eglCreateImageKHR with
|
||||||
|
wl_buffer as EGLClientBuffer, EGL_WAYLAND_BUFFER_WL as the target,
|
||||||
|
and an empty attribute_list.
|
||||||
|
|
||||||
|
Issues
|
||||||
|
|
||||||
|
Revision History
|
||||||
|
|
||||||
|
Version 1, March 1, 2011
|
||||||
|
Initial draft (Benjamin Franzke)
|
@@ -143,6 +143,20 @@ typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESA) (EGLDisplay dpy, con
|
|||||||
typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESA) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
|
typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESA) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef EGL_WL_bind_wayland_display
|
||||||
|
#define EGL_WL_bind_wayland_display 1
|
||||||
|
|
||||||
|
#define EGL_WAYLAND_BUFFER_WL 0x31D5 /* eglCreateImageKHR target */
|
||||||
|
struct wl_display;
|
||||||
|
#ifdef EGL_EGLEXT_PROTOTYPES
|
||||||
|
EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
|
||||||
|
EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
|
||||||
|
#else
|
||||||
|
typedef EGLBoolean (EGLAPIENTRY PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
|
||||||
|
typedef EGLBoolean (EGLAPIENTRY PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */
|
#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */
|
||||||
#ifndef EGL_KHR_reusable_sync
|
#ifndef EGL_KHR_reusable_sync
|
||||||
#define EGL_KHR_reusable_sync 1
|
#define EGL_KHR_reusable_sync 1
|
||||||
|
@@ -3,12 +3,13 @@
|
|||||||
TOP = ../..
|
TOP = ../..
|
||||||
include $(TOP)/configs/current
|
include $(TOP)/configs/current
|
||||||
|
|
||||||
SUBDIRS = drivers main
|
SUBDIRS =
|
||||||
|
|
||||||
ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
|
ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
|
||||||
SUBDIRS += wayland
|
SUBDIRS += wayland
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
SUBDIRS += drivers main
|
||||||
|
|
||||||
default: subdirs
|
default: subdirs
|
||||||
|
|
||||||
|
@@ -27,8 +27,10 @@ endif
|
|||||||
ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
|
ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
|
||||||
EGL_SOURCES += platform_wayland.c
|
EGL_SOURCES += platform_wayland.c
|
||||||
EGL_INCLUDES += -DHAVE_WAYLAND_PLATFORM $(WAYLAND_CFLAGS) \
|
EGL_INCLUDES += -DHAVE_WAYLAND_PLATFORM $(WAYLAND_CFLAGS) \
|
||||||
-I$(TOP)/src/egl/wayland
|
-I$(TOP)/src/egl/wayland \
|
||||||
EGL_LIBS += $(WAYLAND_LIBS)
|
-I$(TOP)/src/egl/wayland/wayland-drm
|
||||||
|
EGL_LIBS += $(WAYLAND_LIBS) \
|
||||||
|
$(TOP)/src/egl/wayland/wayland-drm/libwayland-drm.a
|
||||||
endif
|
endif
|
||||||
|
|
||||||
include ../Makefile.template
|
include ../Makefile.template
|
||||||
|
@@ -915,6 +915,51 @@ dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx,
|
|||||||
return &dri2_img->base;
|
return &dri2_img->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static EGLBoolean
|
||||||
|
dri2_export_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img,
|
||||||
|
EGLint *name, EGLint *handle, EGLint *stride);
|
||||||
|
|
||||||
|
static _EGLImage *
|
||||||
|
dri2_reference_drm_image(_EGLDisplay *disp, _EGLContext *ctx,
|
||||||
|
_EGLImage *image, EGLint width, EGLint height)
|
||||||
|
{
|
||||||
|
EGLint attr_list[] = {
|
||||||
|
EGL_WIDTH, 0,
|
||||||
|
EGL_HEIGHT, 0,
|
||||||
|
EGL_DRM_BUFFER_STRIDE_MESA, 0,
|
||||||
|
EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
EGLint name, stride;
|
||||||
|
|
||||||
|
dri2_export_drm_image_mesa(disp->Driver, disp, image,
|
||||||
|
&name, NULL, &stride);
|
||||||
|
|
||||||
|
attr_list[1] = width;
|
||||||
|
attr_list[3] = height;
|
||||||
|
attr_list[5] = stride / 4;
|
||||||
|
|
||||||
|
return dri2_create_image_mesa_drm_buffer(disp, ctx,
|
||||||
|
(EGLClientBuffer)(intptr_t) name,
|
||||||
|
attr_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_WAYLAND_PLATFORM
|
||||||
|
static _EGLImage *
|
||||||
|
dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
|
||||||
|
EGLClientBuffer buffer,
|
||||||
|
const EGLint *attr_list)
|
||||||
|
{
|
||||||
|
struct wl_drm_buffer *wl_drm_buffer = (struct wl_drm_buffer *) buffer;
|
||||||
|
|
||||||
|
(void) attr_list;
|
||||||
|
|
||||||
|
return dri2_reference_drm_image(disp, ctx, wl_drm_buffer->image,
|
||||||
|
wl_drm_buffer->buffer.width,
|
||||||
|
wl_drm_buffer->buffer.height);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
_EGLImage *
|
_EGLImage *
|
||||||
dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
|
dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
|
||||||
_EGLContext *ctx, EGLenum target,
|
_EGLContext *ctx, EGLenum target,
|
||||||
@@ -927,6 +972,10 @@ dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
|
|||||||
return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list);
|
return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list);
|
||||||
case EGL_DRM_BUFFER_MESA:
|
case EGL_DRM_BUFFER_MESA:
|
||||||
return dri2_create_image_mesa_drm_buffer(disp, ctx, buffer, attr_list);
|
return dri2_create_image_mesa_drm_buffer(disp, ctx, buffer, attr_list);
|
||||||
|
#ifdef HAVE_WAYLAND_PLATFORM
|
||||||
|
case EGL_WAYLAND_BUFFER_WL:
|
||||||
|
return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attr_list);
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
_eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
|
_eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
|
||||||
return EGL_NO_IMAGE_KHR;
|
return EGL_NO_IMAGE_KHR;
|
||||||
@@ -1055,6 +1104,47 @@ dri2_export_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img,
|
|||||||
return EGL_TRUE;
|
return EGL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_WAYLAND_PLATFORM
|
||||||
|
static EGLBoolean
|
||||||
|
dri2_bind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp,
|
||||||
|
struct wl_display *wl_dpy)
|
||||||
|
{
|
||||||
|
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||||
|
|
||||||
|
(void) drv;
|
||||||
|
|
||||||
|
if (dri2_dpy->wl_server_drm)
|
||||||
|
return EGL_FALSE;
|
||||||
|
|
||||||
|
dri2_dpy->wl_server_drm =
|
||||||
|
wayland_drm_init(wl_dpy, disp,
|
||||||
|
dri2_dpy->authenticate,
|
||||||
|
dri2_dpy->device_name);
|
||||||
|
|
||||||
|
if (!dri2_dpy->wl_server_drm)
|
||||||
|
return EGL_FALSE;
|
||||||
|
|
||||||
|
return EGL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EGLBoolean
|
||||||
|
dri2_unbind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp,
|
||||||
|
struct wl_display *wl_dpy)
|
||||||
|
{
|
||||||
|
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||||
|
|
||||||
|
(void) drv;
|
||||||
|
|
||||||
|
if (!dri2_dpy->wl_server_drm)
|
||||||
|
return EGL_FALSE;
|
||||||
|
|
||||||
|
wayland_drm_destroy(dri2_dpy->wl_server_drm);
|
||||||
|
dri2_dpy->wl_server_drm = NULL;
|
||||||
|
|
||||||
|
return EGL_TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dri2_unload(_EGLDriver *drv)
|
dri2_unload(_EGLDriver *drv)
|
||||||
{
|
{
|
||||||
@@ -1140,6 +1230,10 @@ _EGL_MAIN(const char *args)
|
|||||||
dri2_drv->base.API.DestroyImageKHR = dri2_destroy_image_khr;
|
dri2_drv->base.API.DestroyImageKHR = dri2_destroy_image_khr;
|
||||||
dri2_drv->base.API.CreateDRMImageMESA = dri2_create_drm_image_mesa;
|
dri2_drv->base.API.CreateDRMImageMESA = dri2_create_drm_image_mesa;
|
||||||
dri2_drv->base.API.ExportDRMImageMESA = dri2_export_drm_image_mesa;
|
dri2_drv->base.API.ExportDRMImageMESA = dri2_export_drm_image_mesa;
|
||||||
|
#ifdef HAVE_WAYLAND_PLATFORM
|
||||||
|
dri2_drv->base.API.BindWaylandDisplayWL = dri2_bind_wayland_display_wl;
|
||||||
|
dri2_drv->base.API.UnbindWaylandDisplayWL = dri2_unbind_wayland_display_wl;
|
||||||
|
#endif
|
||||||
|
|
||||||
dri2_drv->base.Name = "DRI2";
|
dri2_drv->base.Name = "DRI2";
|
||||||
dri2_drv->base.Unload = dri2_unload;
|
dri2_drv->base.Unload = dri2_unload;
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_WAYLAND_PLATFORM
|
#ifdef HAVE_WAYLAND_PLATFORM
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
|
#include "wayland-drm.h"
|
||||||
#include "wayland-egl-priv.h"
|
#include "wayland-egl-priv.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -85,7 +86,10 @@ struct dri2_egl_display
|
|||||||
const __DRIextension *extensions[3];
|
const __DRIextension *extensions[3];
|
||||||
#ifdef HAVE_WAYLAND_PLATFORM
|
#ifdef HAVE_WAYLAND_PLATFORM
|
||||||
struct wl_egl_display *wl_dpy;
|
struct wl_egl_display *wl_dpy;
|
||||||
|
struct wl_drm *wl_server_drm;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int (*authenticate) (struct dri2_egl_display *dri_dpy, uint32_t id);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dri2_egl_context
|
struct dri2_egl_context
|
||||||
|
@@ -568,6 +568,39 @@ const struct dri2_driver_map driver_map[] = {
|
|||||||
{ 0x10de, "nouveau", NULL, -1 },
|
{ 0x10de, "nouveau", NULL, -1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static char *
|
||||||
|
dri2_get_device_name(int fd)
|
||||||
|
{
|
||||||
|
struct udev *udev;
|
||||||
|
struct udev_device *device;
|
||||||
|
struct stat buf;
|
||||||
|
char *device_name;
|
||||||
|
|
||||||
|
udev = udev_new();
|
||||||
|
if (fstat(fd, &buf) < 0) {
|
||||||
|
_eglLog(_EGL_WARNING, "EGL-DRI2: failed to stat fd %d", fd);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
|
||||||
|
if (device == NULL) {
|
||||||
|
_eglLog(_EGL_WARNING,
|
||||||
|
"EGL-DRI2: could not create udev device for fd %d", fd);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
device_name = udev_device_get_devnode(device);
|
||||||
|
if (!device_name)
|
||||||
|
goto out;
|
||||||
|
device_name = strdup(device_name);
|
||||||
|
|
||||||
|
out:
|
||||||
|
udev_device_unref(device);
|
||||||
|
udev_unref(udev);
|
||||||
|
|
||||||
|
return device_name;
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
dri2_get_driver_for_fd(int fd)
|
dri2_get_driver_for_fd(int fd)
|
||||||
{
|
{
|
||||||
@@ -629,6 +662,14 @@ dri2_get_driver_for_fd(int fd)
|
|||||||
return driver;
|
return driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dri2_drm_authenticate(_EGLDisplay *disp, uint32_t id)
|
||||||
|
{
|
||||||
|
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||||
|
|
||||||
|
return drmAuthMagic(dri2_dpy->fd, id);
|
||||||
|
}
|
||||||
|
|
||||||
EGLBoolean
|
EGLBoolean
|
||||||
dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
|
dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
|
||||||
{
|
{
|
||||||
@@ -648,8 +689,14 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
|
|||||||
if (dri2_dpy->driver_name == NULL)
|
if (dri2_dpy->driver_name == NULL)
|
||||||
return _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
|
return _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
|
||||||
|
|
||||||
if (!dri2_load_driver(disp))
|
dri2_dpy->device_name = dri2_get_device_name(dri2_dpy->fd);
|
||||||
|
if (dri2_dpy->device_name == NULL) {
|
||||||
|
_eglError(EGL_BAD_ALLOC, "DRI2: failed to get device name");
|
||||||
goto cleanup_driver_name;
|
goto cleanup_driver_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dri2_load_driver(disp))
|
||||||
|
goto cleanup_device_name;
|
||||||
|
|
||||||
dri2_dpy->extensions[0] = &image_lookup_extension.base;
|
dri2_dpy->extensions[0] = &image_lookup_extension.base;
|
||||||
dri2_dpy->extensions[1] = &use_invalidate.base;
|
dri2_dpy->extensions[1] = &use_invalidate.base;
|
||||||
@@ -666,6 +713,11 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
|
|||||||
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
|
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
|
||||||
disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
|
disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
|
||||||
|
|
||||||
|
#ifdef HAVE_WAYLAND_PLATFORM
|
||||||
|
disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
|
||||||
|
#endif
|
||||||
|
dri2_dpy->authenticate = dri2_drm_authenticate;
|
||||||
|
|
||||||
/* we're supporting EGL 1.4 */
|
/* we're supporting EGL 1.4 */
|
||||||
disp->VersionMajor = 1;
|
disp->VersionMajor = 1;
|
||||||
disp->VersionMinor = 4;
|
disp->VersionMinor = 4;
|
||||||
@@ -674,6 +726,8 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
|
|||||||
|
|
||||||
cleanup_driver:
|
cleanup_driver:
|
||||||
dlclose(dri2_dpy->driver);
|
dlclose(dri2_dpy->driver);
|
||||||
|
cleanup_device_name:
|
||||||
|
free(dri2_dpy->device_name);
|
||||||
cleanup_driver_name:
|
cleanup_driver_name:
|
||||||
free(dri2_dpy->driver_name);
|
free(dri2_dpy->driver_name);
|
||||||
|
|
||||||
|
@@ -35,6 +35,9 @@
|
|||||||
|
|
||||||
#include "egl_dri2.h"
|
#include "egl_dri2.h"
|
||||||
|
|
||||||
|
#include <wayland-client.h>
|
||||||
|
#include "wayland-drm-client-protocol.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sync_callback(void *data)
|
sync_callback(void *data)
|
||||||
{
|
{
|
||||||
@@ -561,6 +564,26 @@ dri2_wayland_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dri2_wayland_authenticate(_EGLDisplay *disp, uint32_t id)
|
||||||
|
{
|
||||||
|
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
dri2_dpy->wl_dpy->authenticated = false;
|
||||||
|
|
||||||
|
wl_drm_authenticate(dri2_dpy->wl_dpy->drm, id);
|
||||||
|
force_roundtrip(dri2_dpy->wl_dpy->display);
|
||||||
|
|
||||||
|
if (!dri2_dpy->wl_dpy->authenticated)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
/* reset authenticated */
|
||||||
|
dri2_dpy->wl_dpy->authenticated = true;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called via eglTerminate(), drv->API.Terminate().
|
* Called via eglTerminate(), drv->API.Terminate().
|
||||||
*/
|
*/
|
||||||
@@ -626,8 +649,14 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
|
|||||||
goto cleanup_fd;
|
goto cleanup_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dri2_load_driver(disp))
|
dri2_dpy->device_name = strdup(dri2_dpy->wl_dpy->device_name);
|
||||||
|
if (dri2_dpy->device_name == NULL) {
|
||||||
|
_eglError(EGL_BAD_ALLOC, "DRI2: failed to get device name");
|
||||||
goto cleanup_driver_name;
|
goto cleanup_driver_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dri2_load_driver(disp))
|
||||||
|
goto cleanup_device_name;
|
||||||
|
|
||||||
dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
|
dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
|
||||||
dri2_dpy->dri2_loader_extension.base.version = 3;
|
dri2_dpy->dri2_loader_extension.base.version = 3;
|
||||||
@@ -654,6 +683,9 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
|
|||||||
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
|
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
|
||||||
disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
|
disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
|
||||||
|
|
||||||
|
disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
|
||||||
|
dri2_dpy->authenticate = dri2_wayland_authenticate;
|
||||||
|
|
||||||
/* we're supporting EGL 1.4 */
|
/* we're supporting EGL 1.4 */
|
||||||
disp->VersionMajor = 1;
|
disp->VersionMajor = 1;
|
||||||
disp->VersionMinor = 4;
|
disp->VersionMinor = 4;
|
||||||
@@ -662,6 +694,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
|
|||||||
|
|
||||||
cleanup_driver:
|
cleanup_driver:
|
||||||
dlclose(dri2_dpy->driver);
|
dlclose(dri2_dpy->driver);
|
||||||
|
cleanup_device_name:
|
||||||
|
free(dri2_dpy->device_name);
|
||||||
cleanup_driver_name:
|
cleanup_driver_name:
|
||||||
free(dri2_dpy->driver_name);
|
free(dri2_dpy->driver_name);
|
||||||
cleanup_fd:
|
cleanup_fd:
|
||||||
|
@@ -543,12 +543,34 @@ dri2_connect(struct dri2_egl_display *dri2_dpy)
|
|||||||
return EGL_TRUE;
|
return EGL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EGLBoolean
|
static int
|
||||||
dri2_authenticate(struct dri2_egl_display *dri2_dpy)
|
dri2_x11_authenticate(_EGLDisplay *disp, uint32_t id)
|
||||||
{
|
{
|
||||||
|
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||||
xcb_dri2_authenticate_reply_t *authenticate;
|
xcb_dri2_authenticate_reply_t *authenticate;
|
||||||
xcb_dri2_authenticate_cookie_t authenticate_cookie;
|
xcb_dri2_authenticate_cookie_t authenticate_cookie;
|
||||||
xcb_screen_iterator_t s;
|
xcb_screen_iterator_t s;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
|
||||||
|
authenticate_cookie =
|
||||||
|
xcb_dri2_authenticate_unchecked(dri2_dpy->conn, s.data->root, id);
|
||||||
|
authenticate =
|
||||||
|
xcb_dri2_authenticate_reply(dri2_dpy->conn, authenticate_cookie, NULL);
|
||||||
|
|
||||||
|
if (authenticate == NULL || !authenticate->authenticated)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
if (authenticate)
|
||||||
|
free(authenticate);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EGLBoolean
|
||||||
|
dri2_authenticate(_EGLDisplay *disp)
|
||||||
|
{
|
||||||
|
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||||
drm_magic_t magic;
|
drm_magic_t magic;
|
||||||
|
|
||||||
if (drmGetMagic(dri2_dpy->fd, &magic)) {
|
if (drmGetMagic(dri2_dpy->fd, &magic)) {
|
||||||
@@ -556,19 +578,11 @@ dri2_authenticate(struct dri2_egl_display *dri2_dpy)
|
|||||||
return EGL_FALSE;
|
return EGL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
|
if (dri2_x11_authenticate(disp, magic) < 0) {
|
||||||
authenticate_cookie =
|
|
||||||
xcb_dri2_authenticate_unchecked(dri2_dpy->conn, s.data->root, magic);
|
|
||||||
authenticate =
|
|
||||||
xcb_dri2_authenticate_reply(dri2_dpy->conn, authenticate_cookie, NULL);
|
|
||||||
if (authenticate == NULL || !authenticate->authenticated) {
|
|
||||||
_eglLog(_EGL_WARNING, "DRI2: failed to authenticate");
|
_eglLog(_EGL_WARNING, "DRI2: failed to authenticate");
|
||||||
free(authenticate);
|
|
||||||
return EGL_FALSE;
|
return EGL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(authenticate);
|
|
||||||
|
|
||||||
return EGL_TRUE;
|
return EGL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -977,7 +991,7 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dri2_dpy->conn) {
|
if (dri2_dpy->conn) {
|
||||||
if (!dri2_authenticate(dri2_dpy))
|
if (!dri2_authenticate(disp))
|
||||||
goto cleanup_fd;
|
goto cleanup_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1016,6 +1030,11 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
|
|||||||
disp->Extensions.NOK_swap_region = EGL_TRUE;
|
disp->Extensions.NOK_swap_region = EGL_TRUE;
|
||||||
disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
|
disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
|
||||||
|
|
||||||
|
#ifdef HAVE_WAYLAND_PLATFORM
|
||||||
|
disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
|
||||||
|
#endif
|
||||||
|
dri2_dpy->authenticate = dri2_x11_authenticate;
|
||||||
|
|
||||||
/* we're supporting EGL 1.4 */
|
/* we're supporting EGL 1.4 */
|
||||||
disp->VersionMajor = 1;
|
disp->VersionMajor = 1;
|
||||||
disp->VersionMinor = 4;
|
disp->VersionMinor = 4;
|
||||||
|
@@ -58,6 +58,9 @@ LOCAL_LIBS =
|
|||||||
ifeq ($(filter dri2, $(EGL_DRIVERS_DIRS)),dri2)
|
ifeq ($(filter dri2, $(EGL_DRIVERS_DIRS)),dri2)
|
||||||
LOCAL_CFLAGS += -D_EGL_BUILT_IN_DRIVER_DRI2
|
LOCAL_CFLAGS += -D_EGL_BUILT_IN_DRIVER_DRI2
|
||||||
LOCAL_LIBS += $(TOP)/src/egl/drivers/dri2/libegl_dri2.a
|
LOCAL_LIBS += $(TOP)/src/egl/drivers/dri2/libegl_dri2.a
|
||||||
|
ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
|
||||||
|
LOCAL_LIBS += $(TOP)/src/egl/wayland/wayland-drm/libwayland-drm.a
|
||||||
|
endif
|
||||||
EGL_LIB_DEPS += $(XCB_DRI2_LIBS) $(LIBUDEV_LIBS) $(DLOPEN_LIBS) $(LIBDRM_LIB) $(WAYLAND_LIBS)
|
EGL_LIB_DEPS += $(XCB_DRI2_LIBS) $(LIBUDEV_LIBS) $(DLOPEN_LIBS) $(LIBDRM_LIB) $(WAYLAND_LIBS)
|
||||||
endif
|
endif
|
||||||
ifeq ($(filter glx, $(EGL_DRIVERS_DIRS)),glx)
|
ifeq ($(filter glx, $(EGL_DRIVERS_DIRS)),glx)
|
||||||
|
@@ -913,6 +913,10 @@ eglGetProcAddress(const char *procname)
|
|||||||
#ifdef EGL_MESA_drm_image
|
#ifdef EGL_MESA_drm_image
|
||||||
{ "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
|
{ "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
|
||||||
{ "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
|
{ "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
|
||||||
|
#endif
|
||||||
|
#ifdef EGL_WL_bind_display
|
||||||
|
{ "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
|
||||||
|
{ "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
|
||||||
#endif
|
#endif
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
@@ -1491,3 +1495,43 @@ eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef EGL_WL_bind_wayland_display
|
||||||
|
struct wl_display;
|
||||||
|
|
||||||
|
EGLBoolean EGLAPIENTRY
|
||||||
|
eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
|
||||||
|
{
|
||||||
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
||||||
|
_EGLDriver *drv;
|
||||||
|
EGLBoolean ret;
|
||||||
|
|
||||||
|
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
|
||||||
|
assert(disp->Extensions.WL_bind_wayland_display);
|
||||||
|
|
||||||
|
if (!display)
|
||||||
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
|
||||||
|
|
||||||
|
ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
|
||||||
|
|
||||||
|
RETURN_EGL_EVAL(disp, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLBoolean EGLAPIENTRY
|
||||||
|
eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
|
||||||
|
{
|
||||||
|
_EGLDisplay *disp = _eglLockDisplay(dpy);
|
||||||
|
_EGLDriver *drv;
|
||||||
|
EGLBoolean ret;
|
||||||
|
|
||||||
|
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
|
||||||
|
assert(disp->Extensions.WL_bind_wayland_display);
|
||||||
|
|
||||||
|
if (!display)
|
||||||
|
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
|
||||||
|
|
||||||
|
ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
|
||||||
|
|
||||||
|
RETURN_EGL_EVAL(disp, ret);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@@ -95,6 +95,12 @@ typedef _EGLImage *(*CreateDRMImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, c
|
|||||||
typedef EGLBoolean (*ExportDRMImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, EGLint *name, EGLint *handle, EGLint *stride);
|
typedef EGLBoolean (*ExportDRMImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, EGLint *name, EGLint *handle, EGLint *stride);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef EGL_WL_bind_wayland_display
|
||||||
|
struct wl_display;
|
||||||
|
typedef EGLBoolean (*BindWaylandDisplayWL_t)(_EGLDriver *drv, _EGLDisplay *disp, struct wl_display *display);
|
||||||
|
typedef EGLBoolean (*UnbindWaylandDisplayWL_t)(_EGLDriver *drv, _EGLDisplay *disp, struct wl_display *display);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The API dispatcher jumps through these functions
|
* The API dispatcher jumps through these functions
|
||||||
*/
|
*/
|
||||||
@@ -169,6 +175,11 @@ struct _egl_api
|
|||||||
CreateDRMImageMESA_t CreateDRMImageMESA;
|
CreateDRMImageMESA_t CreateDRMImageMESA;
|
||||||
ExportDRMImageMESA_t ExportDRMImageMESA;
|
ExportDRMImageMESA_t ExportDRMImageMESA;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef EGL_WL_bind_wayland_display
|
||||||
|
BindWaylandDisplayWL_t BindWaylandDisplayWL;
|
||||||
|
UnbindWaylandDisplayWL_t UnbindWaylandDisplayWL;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* EGLAPI_INCLUDED */
|
#endif /* EGLAPI_INCLUDED */
|
||||||
|
@@ -58,6 +58,8 @@ struct _egl_extensions
|
|||||||
EGLBoolean MESA_drm_display;
|
EGLBoolean MESA_drm_display;
|
||||||
EGLBoolean MESA_drm_image;
|
EGLBoolean MESA_drm_image;
|
||||||
|
|
||||||
|
EGLBoolean WL_bind_wayland_display;
|
||||||
|
|
||||||
EGLBoolean KHR_image_base;
|
EGLBoolean KHR_image_base;
|
||||||
EGLBoolean KHR_image_pixmap;
|
EGLBoolean KHR_image_pixmap;
|
||||||
EGLBoolean KHR_vg_parent_image;
|
EGLBoolean KHR_vg_parent_image;
|
||||||
|
@@ -89,6 +89,8 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
|
|||||||
_EGL_CHECK_EXTENSION(MESA_drm_display);
|
_EGL_CHECK_EXTENSION(MESA_drm_display);
|
||||||
_EGL_CHECK_EXTENSION(MESA_drm_image);
|
_EGL_CHECK_EXTENSION(MESA_drm_image);
|
||||||
|
|
||||||
|
_EGL_CHECK_EXTENSION(WL_bind_wayland_display);
|
||||||
|
|
||||||
_EGL_CHECK_EXTENSION(KHR_image_base);
|
_EGL_CHECK_EXTENSION(KHR_image_base);
|
||||||
_EGL_CHECK_EXTENSION(KHR_image_pixmap);
|
_EGL_CHECK_EXTENSION(KHR_image_pixmap);
|
||||||
if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap)
|
if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# src/egl/main/Makefile
|
# src/egl/wayland/Makefile
|
||||||
|
|
||||||
TOP = ../../..
|
TOP = ../../..
|
||||||
include $(TOP)/configs/current
|
include $(TOP)/configs/current
|
||||||
@@ -10,14 +10,20 @@ SOURCES = wayland-egl.c
|
|||||||
|
|
||||||
OBJECTS = $(SOURCES:.c=.o)
|
OBJECTS = $(SOURCES:.c=.o)
|
||||||
|
|
||||||
LOCAL_CFLAGS = -I$(TOP)/include/EGL $(LIBDRM_CFLAGS) $(WAYLAND_CFLAGS)
|
LOCAL_CFLAGS = -I$(TOP)/include/EGL \
|
||||||
|
-I$(TOP)/src/egl/wayland/wayland-drm \
|
||||||
|
$(LIBDRM_CFLAGS) \
|
||||||
|
$(WAYLAND_CFLAGS)
|
||||||
|
|
||||||
LOCAL_LIBS =
|
LOCAL_LIBS =
|
||||||
|
|
||||||
|
SUBDIRS = wayland-drm
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@
|
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
|
||||||
default: depend library
|
default: depend subdirs library
|
||||||
|
|
||||||
# wayland-egl Library
|
# wayland-egl Library
|
||||||
library: $(TOP)/$(LIB_DIR)/$(WAYLAND_EGL_LIB_NAME)
|
library: $(TOP)/$(LIB_DIR)/$(WAYLAND_EGL_LIB_NAME)
|
||||||
@@ -54,6 +60,12 @@ clean:
|
|||||||
-rm -f *.o
|
-rm -f *.o
|
||||||
-rm -f depend depend.bak
|
-rm -f depend depend.bak
|
||||||
|
|
||||||
|
subdirs:
|
||||||
|
@for dir in $(SUBDIRS) ; do \
|
||||||
|
if [ -d $$dir ] ; then \
|
||||||
|
(cd $$dir && $(MAKE)) || exit 1 ; \
|
||||||
|
fi \
|
||||||
|
done
|
||||||
|
|
||||||
depend: $(SOURCES) $(HEADERS)
|
depend: $(SOURCES) $(HEADERS)
|
||||||
@ echo "running $(MKDEP)"
|
@ echo "running $(MKDEP)"
|
||||||
|
3
src/egl/wayland/wayland-drm/.gitignore
vendored
Normal file
3
src/egl/wayland/wayland-drm/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
wayland-drm-client-protocol.h
|
||||||
|
wayland-drm-server-protocol.h
|
||||||
|
wayland-drm-protocol.c
|
45
src/egl/wayland/wayland-drm/Makefile
Normal file
45
src/egl/wayland/wayland-drm/Makefile
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# src/egl/wayland/wayland-drm/Makefile
|
||||||
|
|
||||||
|
TOP = ../../../..
|
||||||
|
include $(TOP)/configs/current
|
||||||
|
|
||||||
|
GEN_SOURCES = wayland-drm-protocol.c
|
||||||
|
|
||||||
|
GEN_HEADERS = wayland-drm-client-protocol.h wayland-drm-server-protocol.h
|
||||||
|
|
||||||
|
wayland_drm_SOURCES = wayland-drm.c $(GEN_SOURCES)
|
||||||
|
wayland_drm_OBJECTS = $(wayland_drm_SOURCES:.c=.o)
|
||||||
|
|
||||||
|
wayland_drm_INCLUDES = \
|
||||||
|
$(WAYLAND_CFLAGS) \
|
||||||
|
-I$(TOP)/src/egl/main
|
||||||
|
|
||||||
|
# Generate protocol sources
|
||||||
|
prefix=$(shell pkg-config --variable=prefix wayland-server)
|
||||||
|
exec_prefx=$(shell pkg-config --variable=exec_prefix wayland-server)
|
||||||
|
wayland_protocoldir = $(PWD)/protocol
|
||||||
|
wayland_scanner=$(exec_prefix)/bin/wayland-scanner
|
||||||
|
|
||||||
|
default: depend libwayland-drm.a $(GEN_SOURCES) $(GEN_HEADERS)
|
||||||
|
|
||||||
|
libwayland-drm.a: $(wayland_drm_OBJECTS) Makefile
|
||||||
|
$(MKLIB) -o wayland-drm -static $(wayland_drm_OBJECTS)
|
||||||
|
|
||||||
|
depend:
|
||||||
|
rm -f depend
|
||||||
|
touch depend
|
||||||
|
$(MKDEP) $(MKDEP_OPTIONS) $(wayland_drm_INCLUDES) $(wayland_drm_SOURCES) 2> /dev/null
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf libwayland-drm.a $(wayland_drm_OBJECTS) \
|
||||||
|
$(GEN_SOURCES) $(GEN_HEADERS)
|
||||||
|
|
||||||
|
install:
|
||||||
|
@echo -n ""
|
||||||
|
|
||||||
|
$(wayland_drm_OBJECTS): %.o: %.c $(GEN_HEADERS)
|
||||||
|
$(CC) -c $(wayland_drm_INCLUDES) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
include $(prefix)/share/aclocal/wayland-scanner.mk
|
||||||
|
|
||||||
|
sinclude depend
|
38
src/egl/wayland/wayland-drm/protocol/wayland-drm.xml
Normal file
38
src/egl/wayland/wayland-drm/protocol/wayland-drm.xml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="drm">
|
||||||
|
<!-- drm support. This object is created by the server and published
|
||||||
|
using the display's global event. -->
|
||||||
|
<interface name="drm" version="1">
|
||||||
|
<!-- Call this request with the magic received from drmGetMagic().
|
||||||
|
It will be passed on to the drmAuthMagic() or
|
||||||
|
DRIAuthConnection() call. This authentication must be
|
||||||
|
completed before create_buffer could be used. -->
|
||||||
|
<request name="authenticate">
|
||||||
|
<arg name="id" type="uint"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<!-- Create a wayland buffer for the named DRM buffer. The DRM
|
||||||
|
surface must have a name using the flink ioctl -->
|
||||||
|
<request name="create_buffer">
|
||||||
|
<arg name="id" type="new_id" interface="buffer"/>
|
||||||
|
<arg name="name" type="uint"/>
|
||||||
|
<arg name="width" type="int"/>
|
||||||
|
<arg name="height" type="int"/>
|
||||||
|
<arg name="stride" type="uint"/>
|
||||||
|
<arg name="visual" type="object" interface="visual"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<!-- Notification of the path of the drm device which is used by
|
||||||
|
the server. The client should use this device for creating
|
||||||
|
local buffers. Only buffers created from this device should
|
||||||
|
be be passed to the server using this drm object's
|
||||||
|
create_buffer request. -->
|
||||||
|
<event name="device">
|
||||||
|
<arg name="name" type="string"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<!-- Raised if the authenticate request succeeded -->
|
||||||
|
<event name="authenticated"/>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
</protocol>
|
203
src/egl/wayland/wayland-drm/wayland-drm.c
Normal file
203
src/egl/wayland/wayland-drm/wayland-drm.c
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2011 Kristian Høgsberg
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Kristian Høgsberg <krh@bitplanet.net>
|
||||||
|
* Benjamin Franzke <benjaminfranzke@googlemail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include <wayland-server.h>
|
||||||
|
#include "wayland-drm.h"
|
||||||
|
#include "wayland-drm-server-protocol.h"
|
||||||
|
|
||||||
|
#include "egldisplay.h"
|
||||||
|
#include "egldriver.h"
|
||||||
|
#include "eglimage.h"
|
||||||
|
#include "egltypedefs.h"
|
||||||
|
|
||||||
|
struct wl_drm {
|
||||||
|
struct wl_object object;
|
||||||
|
struct wl_display *display;
|
||||||
|
|
||||||
|
_EGLDisplay *edisp;
|
||||||
|
|
||||||
|
char *device_name;
|
||||||
|
authenticate_t authenticate;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
drm_buffer_damage(struct wl_buffer *buffer_base,
|
||||||
|
struct wl_surface *surface,
|
||||||
|
int32_t x, int32_t y, int32_t width, int32_t height)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
destroy_buffer(struct wl_resource *resource, struct wl_client *client)
|
||||||
|
{
|
||||||
|
struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) resource;
|
||||||
|
_EGLDriver *drv = buffer->drm->edisp->Driver;
|
||||||
|
|
||||||
|
drv->API.DestroyImageKHR(drv, buffer->drm->edisp, buffer->image);
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
buffer_destroy(struct wl_client *client, struct wl_buffer *buffer)
|
||||||
|
{
|
||||||
|
wl_resource_destroy(&buffer->resource, client);
|
||||||
|
}
|
||||||
|
|
||||||
|
const static struct wl_buffer_interface buffer_interface = {
|
||||||
|
buffer_destroy
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
drm_create_buffer(struct wl_client *client, struct wl_drm *drm,
|
||||||
|
uint32_t id, uint32_t name, int32_t width, int32_t height,
|
||||||
|
uint32_t stride, struct wl_visual *visual)
|
||||||
|
{
|
||||||
|
struct wl_drm_buffer *buffer;
|
||||||
|
EGLint attribs[] = {
|
||||||
|
EGL_WIDTH, 0,
|
||||||
|
EGL_HEIGHT, 0,
|
||||||
|
EGL_DRM_BUFFER_STRIDE_MESA, 0,
|
||||||
|
EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
_EGLDriver *drv = drm->edisp->Driver;
|
||||||
|
|
||||||
|
buffer = malloc(sizeof *buffer);
|
||||||
|
if (buffer == NULL) {
|
||||||
|
wl_client_post_no_memory(client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer->drm = drm;
|
||||||
|
buffer->buffer.compositor = NULL;
|
||||||
|
buffer->buffer.width = width;
|
||||||
|
buffer->buffer.height = height;
|
||||||
|
buffer->buffer.visual = visual;
|
||||||
|
buffer->buffer.attach = NULL;
|
||||||
|
buffer->buffer.damage = drm_buffer_damage;
|
||||||
|
|
||||||
|
if (visual->object.interface != &wl_visual_interface) {
|
||||||
|
/* FIXME: Define a real exception event instead of
|
||||||
|
* abusing this one */
|
||||||
|
wl_client_post_event(client,
|
||||||
|
(struct wl_object *) drm->display,
|
||||||
|
WL_DISPLAY_INVALID_OBJECT, 0);
|
||||||
|
fprintf(stderr, "invalid visual in create_buffer\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
attribs[1] = width;
|
||||||
|
attribs[3] = height;
|
||||||
|
attribs[5] = stride / 4;
|
||||||
|
buffer->image = drv->API.CreateImageKHR(drv, drm->edisp,
|
||||||
|
EGL_NO_CONTEXT,
|
||||||
|
EGL_DRM_BUFFER_MESA,
|
||||||
|
(EGLClientBuffer) (intptr_t) name,
|
||||||
|
attribs);
|
||||||
|
|
||||||
|
if (buffer->image == NULL) {
|
||||||
|
/* FIXME: Define a real exception event instead of
|
||||||
|
* abusing this one */
|
||||||
|
wl_client_post_event(client,
|
||||||
|
(struct wl_object *) drm->display,
|
||||||
|
WL_DISPLAY_INVALID_OBJECT, 0);
|
||||||
|
fprintf(stderr, "failed to create image for name %d\n", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer->buffer.resource.object.id = id;
|
||||||
|
buffer->buffer.resource.object.interface = &wl_buffer_interface;
|
||||||
|
buffer->buffer.resource.object.implementation = (void (**)(void))
|
||||||
|
&buffer_interface;
|
||||||
|
|
||||||
|
buffer->buffer.resource.destroy = destroy_buffer;
|
||||||
|
|
||||||
|
wl_client_add_resource(client, &buffer->buffer.resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drm_authenticate(struct wl_client *client,
|
||||||
|
struct wl_drm *drm, uint32_t id)
|
||||||
|
{
|
||||||
|
if (drm->authenticate(drm->edisp, id) < 0)
|
||||||
|
wl_client_post_event(client,
|
||||||
|
(struct wl_object *) drm->display,
|
||||||
|
WL_DISPLAY_INVALID_OBJECT, 0);
|
||||||
|
else
|
||||||
|
wl_client_post_event(client, &drm->object,
|
||||||
|
WL_DRM_AUTHENTICATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
const static struct wl_drm_interface drm_interface = {
|
||||||
|
drm_authenticate,
|
||||||
|
drm_create_buffer
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
post_drm_device(struct wl_client *client, struct wl_object *global)
|
||||||
|
{
|
||||||
|
struct wl_drm *drm = (struct wl_drm *) global;
|
||||||
|
|
||||||
|
wl_client_post_event(client, global, WL_DRM_DEVICE, drm->device_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_drm *
|
||||||
|
wayland_drm_init(struct wl_display *display, _EGLDisplay *disp,
|
||||||
|
authenticate_t authenticate, char *device_name)
|
||||||
|
{
|
||||||
|
struct wl_drm *drm;
|
||||||
|
|
||||||
|
drm = malloc(sizeof *drm);
|
||||||
|
|
||||||
|
drm->display = display;
|
||||||
|
drm->edisp = disp;
|
||||||
|
drm->authenticate = authenticate;
|
||||||
|
drm->device_name = strdup(device_name);
|
||||||
|
|
||||||
|
drm->object.interface = &wl_drm_interface;
|
||||||
|
drm->object.implementation = (void (**)(void)) &drm_interface;
|
||||||
|
wl_display_add_object(display, &drm->object);
|
||||||
|
wl_display_add_global(display, &drm->object, post_drm_device);
|
||||||
|
|
||||||
|
return drm;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wayland_drm_destroy(struct wl_drm *drm)
|
||||||
|
{
|
||||||
|
free(drm->device_name);
|
||||||
|
|
||||||
|
/* FIXME: need wl_display_del_{object,global} */
|
||||||
|
|
||||||
|
free(drm);
|
||||||
|
}
|
26
src/egl/wayland/wayland-drm/wayland-drm.h
Normal file
26
src/egl/wayland/wayland-drm/wayland-drm.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#ifndef WAYLAND_DRM_H
|
||||||
|
#define WAYLAND_DRM_H
|
||||||
|
|
||||||
|
#include "egldisplay.h"
|
||||||
|
#include "eglimage.h"
|
||||||
|
|
||||||
|
#include <wayland-server.h>
|
||||||
|
|
||||||
|
struct wl_drm;
|
||||||
|
|
||||||
|
typedef int (*authenticate_t) (_EGLDisplay *disp, uint32_t id);
|
||||||
|
|
||||||
|
struct wl_drm_buffer {
|
||||||
|
struct wl_buffer buffer;
|
||||||
|
struct wl_drm *drm;
|
||||||
|
_EGLImage *image;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wl_drm *
|
||||||
|
wayland_drm_init(struct wl_display *display, _EGLDisplay *disp,
|
||||||
|
authenticate_t authenticate, char *device_name);
|
||||||
|
|
||||||
|
void
|
||||||
|
wayland_drm_destroy(struct wl_drm *drm);
|
||||||
|
|
||||||
|
#endif
|
@@ -12,10 +12,10 @@
|
|||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
#include <xf86drm.h>
|
|
||||||
|
|
||||||
#include "wayland-egl.h"
|
#include "wayland-egl.h"
|
||||||
#include "wayland-egl-priv.h"
|
#include "wayland-egl-priv.h"
|
||||||
|
#include "wayland-drm-client-protocol.h"
|
||||||
|
#include <xf86drm.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
drm_handle_device(void *data, struct wl_drm *drm, const char *device)
|
drm_handle_device(void *data, struct wl_drm *drm, const char *device)
|
||||||
|
@@ -26,6 +26,7 @@ x11_OBJECTS = $(x11_SOURCES:.c=.o)
|
|||||||
wayland_INCLUDES = \
|
wayland_INCLUDES = \
|
||||||
-I$(TOP)/src/gallium/winsys \
|
-I$(TOP)/src/gallium/winsys \
|
||||||
-I$(TOP)/src/egl/wayland \
|
-I$(TOP)/src/egl/wayland \
|
||||||
|
-I$(TOP)/src/egl/wayland/wayland-drm \
|
||||||
$(shell pkg-config --cflags-only-I libdrm wayland-client)
|
$(shell pkg-config --cflags-only-I libdrm wayland-client)
|
||||||
|
|
||||||
wayland_SOURCES = $(wildcard wayland/*.c)
|
wayland_SOURCES = $(wildcard wayland/*.c)
|
||||||
|
@@ -41,6 +41,7 @@
|
|||||||
#include "radeon/drm/radeon_drm_public.h"
|
#include "radeon/drm/radeon_drm_public.h"
|
||||||
|
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
|
#include "wayland-drm-client-protocol.h"
|
||||||
#include "wayland-egl-priv.h"
|
#include "wayland-egl-priv.h"
|
||||||
|
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
|
Reference in New Issue
Block a user