commit a1aae65

Michael Forney  ·  2013-09-11 22:00:09 +0000 UTC
parent 69d8430
drm: Use our own wl_drm implementation based on wld
13 files changed,  +477, -160
+1, -1
1@@ -2,5 +2,5 @@
2 
3 ACLOCAL_AMFLAGS = -I m4
4 
5-SUBDIRS = launch libswc
6+SUBDIRS = launch protocol libswc
7 
+6, -1
 1@@ -29,10 +29,15 @@ PKG_CHECK_MODULES([intelbatch], [intelbatch])
 2 PKG_CHECK_MODULES([gbm], [gbm])
 3 PKG_CHECK_MODULES([egl], [egl])
 4 PKG_CHECK_MODULES([pixman], [pixman-1])
 5+PKG_CHECK_MODULES([wld], [wld])
 6 
 7 PKG_CHECK_MODULES([wayland_client], [wayland-client])
 8 dnl }}}
 9 
10-AC_CONFIG_FILES([Makefile libswc/Makefile launch/Makefile])
11+dnl Wayland protocol
12+AC_SUBST(PROTOCOL_DIR, ['$(top_builddir)/protocol'])
13+WAYLAND_SCANNER_RULES(['$(top_srcdir)/protocol'])
14+
15+AC_CONFIG_FILES([Makefile libswc/Makefile launch/Makefile protocol/Makefile])
16 AC_OUTPUT
17 
+4, -3
 1@@ -1,6 +1,6 @@
 2 # swc: libswc/Makefile.am
 3 
 4-AM_CPPFLAGS = -I$(top_srcdir)
 5+AM_CPPFLAGS = -I$(top_srcdir) -I$(PROTOCOL_DIR)
 6 AM_CFLAGS = $(pixman_CFLAGS) $(drm_CFLAGS) $(intelbatch_CFLAGS)
 7 
 8 lib_LTLIBRARIES = libswc.la
 9@@ -27,10 +27,11 @@ libswc_la_SOURCES = \
10     evdev_device.c evdev_device.h \
11     xkb.c xkb.h \
12     drm.c drm.h \
13-    egl.c egl.h
14+    drm_buffer.c drm_buffer.h \
15+    $(PROTOCOL_DIR)/wayland-drm-protocol.c
16 
17 libswc_la_LIBADD = $(wayland_server_LIBS) $(udev_LIBS) $(xkbcommon_LIBS) \
18                    $(drm_LIBS) $(drm_intel_LIBS) $(gbm_LIBS) $(egl_LIBS) \
19-                   $(pixman_LIBS) $(intelbatch_LIBS) \
20+                   $(pixman_LIBS) $(intelbatch_LIBS) $(wld_LIBS) \
21                    ../launch/liblaunch-protocol.la
22 
+2, -19
 1@@ -346,24 +346,11 @@ bool swc_compositor_initialize(struct swc_compositor * compositor,
 2         goto error_drm;
 3     }
 4 
 5-    if (!swc_egl_initialize(&compositor->egl, compositor->gbm))
 6-    {
 7-        printf("could not initialize egl\n");
 8-        goto error_gbm;
 9-    }
10-
11-    if (!swc_egl_bind_display(&compositor->egl, compositor->display))
12-    {
13-        printf("could not bind egl display\n");
14-        swc_egl_finish(&compositor->egl);
15-        goto error_gbm;
16-    }
17-
18     if (!swc_renderer_initialize(&compositor->renderer, &compositor->drm,
19                                  compositor->gbm))
20     {
21         printf("could not initialize renderer\n");
22-        goto error_egl;
23+        goto error_gbm;
24     }
25 
26     outputs = swc_drm_create_outputs(&compositor->drm);
27@@ -400,9 +387,6 @@ bool swc_compositor_initialize(struct swc_compositor * compositor,
28 
29   error_renderer:
30     swc_renderer_finalize(&compositor->renderer);
31-  error_egl:
32-    swc_egl_unbind_display(&compositor->egl, compositor->display);
33-    swc_egl_finish(&compositor->egl);
34   error_gbm:
35     gbm_device_destroy(compositor->gbm);
36   error_drm:
37@@ -431,8 +415,6 @@ void swc_compositor_finish(struct swc_compositor * compositor)
38         free(output);
39     }
40 
41-    swc_egl_unbind_display(&compositor->egl, compositor->display);
42-    swc_egl_finish(&compositor->egl);
43     gbm_device_destroy(compositor->gbm);
44     swc_drm_finish(&compositor->drm);
45     swc_seat_finish(&compositor->seat);
46@@ -450,6 +432,7 @@ void swc_compositor_add_globals(struct swc_compositor * compositor,
47 
48     swc_data_device_manager_add_globals(display);
49     swc_seat_add_globals(&compositor->seat, display);
50+    swc_drm_add_globals(&compositor->drm, display);
51 
52     wl_list_for_each(output, &compositor->outputs, link)
53     {
+0, -2
 1@@ -6,7 +6,6 @@
 2 #include "drm.h"
 3 #include "tty.h"
 4 #include "seat.h"
 5-#include "egl.h"
 6 #include "binding.h"
 7 #include "renderer.h"
 8 
 9@@ -20,7 +19,6 @@ struct swc_compositor
10     struct swc_tty tty;
11     struct swc_seat seat;
12     struct swc_drm drm;
13-    struct swc_egl egl;
14     struct swc_renderer renderer;
15 
16     struct wl_list outputs;
+151, -23
  1@@ -1,3 +1,31 @@
  2+/* swc: drm.c
  3+ *
  4+ * Copyright (c) 2013 Michael Forney
  5+ *
  6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
  7+ * of this software and associated documentation files (the "Software"), to deal
  8+ * in the Software without restriction, including without limitation the rights
  9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10+ * copies of the Software, and to permit persons to whom the Software is
 11+ * furnished to do so, subject to the following conditions:
 12+ *
 13+ * The above copyright notice and this permission notice shall be included in
 14+ * all copies or substantial portions of the Software.
 15+ *
 16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 22+ * SOFTWARE.
 23+ */
 24+
 25+#include "drm.h"
 26+#include "drm_buffer.h"
 27+#include "output.h"
 28+#include "event.h"
 29+
 30 #include <stdio.h>
 31 #include <stdlib.h>
 32 #include <string.h>
 33@@ -6,15 +34,103 @@
 34 #include <libudev.h>
 35 #include <libdrm/drm.h>
 36 #include <xf86drm.h>
 37-#include <libdrm/i915_drm.h>
 38-#include <libdrm/intel_bufmgr.h>
 39-#include <intelbatch/batch.h>
 40-//#include <xf86drmMode.h>
 41+#include <wld/wld.h>
 42+#include <wld/drm.h>
 43 #include <wayland-util.h>
 44+#include <wayland-drm-server-protocol.h>
 45 
 46-#include "drm.h"
 47-#include "output.h"
 48-#include "event.h"
 49+static void authenticate(struct wl_client * client,
 50+                         struct wl_resource * resource, uint32_t magic)
 51+{
 52+    struct swc_drm * drm = wl_resource_get_user_data(resource);
 53+    int ret;
 54+
 55+    if ((ret = drmAuthMagic(drm->fd, magic)) == 0)
 56+        wl_drm_send_authenticated(resource);
 57+    else
 58+    {
 59+        wl_resource_post_error(resource, WL_DRM_ERROR_AUTHENTICATE_FAIL,
 60+                               "drmAuthMagic failed: %d\n", ret);
 61+    }
 62+}
 63+
 64+static void create_buffer(struct wl_client * client,
 65+                          struct wl_resource * resource, uint32_t id,
 66+                          uint32_t name, int32_t width, int32_t height,
 67+                          uint32_t stride, uint32_t format)
 68+{
 69+    struct swc_drm * drm = wl_resource_get_user_data(resource);
 70+    struct wld_drawable * drawable;
 71+    struct swc_drm_buffer * buffer;
 72+
 73+    drawable = wld_drm_import_gem(drm->context, width, height, format,
 74+                                  name, stride);
 75+
 76+    if (!drawable)
 77+        goto error0;
 78+
 79+    buffer = swc_drm_buffer_new(client, id, drawable);
 80+
 81+    if (!buffer)
 82+        goto error1;
 83+
 84+    return;
 85+
 86+  error1:
 87+    wld_destroy_drawable(drawable);
 88+  error0:
 89+    wl_resource_post_no_memory(resource);
 90+}
 91+
 92+static void create_planar_buffer(struct wl_client * client,
 93+                                 struct wl_resource * resource, uint32_t id,
 94+                                 uint32_t name, int32_t width, int32_t height,
 95+                                 uint32_t format,
 96+                                 int32_t offset0, int32_t stride0,
 97+                                 int32_t offset1, int32_t stride1,
 98+                                 int32_t offset2, int32_t stride2)
 99+{
100+    wl_resource_post_error(resource, WL_DRM_ERROR_INVALID_FORMAT,
101+                           "planar buffers are not supported\n");
102+}
103+
104+static void create_prime_buffer(struct wl_client * client,
105+                                struct wl_resource * resource, uint32_t id,
106+                                int32_t fd, int32_t width, int32_t height,
107+                                uint32_t format,
108+                                int32_t offset0, int32_t stride0,
109+                                int32_t offset1, int32_t stride1,
110+                                int32_t offset2, int32_t stride2)
111+{
112+    struct swc_drm * drm = wl_resource_get_user_data(resource);
113+    struct wld_drawable * drawable;
114+    struct swc_drm_buffer * buffer;
115+
116+    drawable = wld_drm_import(drm->context, width, height, format, fd, stride0);
117+    close(fd);
118+
119+    if (!drawable)
120+        goto error0;
121+
122+    buffer = swc_drm_buffer_new(client, id, drawable);
123+
124+    if (!buffer)
125+        goto error1;
126+
127+    return;
128+
129+  error1:
130+    wld_destroy_drawable(drawable);
131+  error0:
132+    wl_resource_post_no_memory(resource);
133+}
134+
135+static const struct wl_drm_interface drm_implementation = {
136+        .authenticate = &authenticate,
137+        .create_buffer = &create_buffer,
138+        .create_planar_buffer = &create_planar_buffer,
139+        .create_prime_buffer = &create_prime_buffer
140+};
141 
142 static struct udev_device * find_primary_drm_device(struct udev * udev,
143                                                     const char * seat)
144@@ -192,8 +308,8 @@ bool swc_drm_initialize(struct swc_drm * drm, struct udev * udev,
145 
146     printf("sysnum: %s\n", sysnum);
147 
148-    device_path = udev_device_get_devnode(drm_device);
149-    drm->fd = open(device_path, O_RDWR | O_CLOEXEC);
150+    drm->path = strdup(udev_device_get_devnode(drm_device));
151+    drm->fd = open(drm->path, O_RDWR | O_CLOEXEC);
152 
153     if (drm->fd == -1)
154     {
155@@ -207,23 +323,10 @@ bool swc_drm_initialize(struct swc_drm * drm, struct udev * udev,
156         goto error_fd;
157     }
158 
159-    drm->bufmgr = drm_intel_bufmgr_gem_init(drm->fd, INTEL_MAX_COMMANDS << 2);
160-
161-    if (!drm->bufmgr)
162-    {
163-        printf("could not create bufmgr\n");
164-        goto error_wld;
165-    }
166-
167-    //drm_intel_bufmgr_set_debug(drm->bufmgr, true);
168-    drm_intel_bufmgr_gem_enable_fenced_relocs(drm->bufmgr);
169-
170     udev_device_unref(drm_device);
171 
172     return true;
173 
174-  error_wld:
175-    wld_drm_destroy_context(drm->context);
176   error_fd:
177     close(drm->fd);
178   error_device:
179@@ -235,7 +338,7 @@ bool swc_drm_initialize(struct swc_drm * drm, struct udev * udev,
180 void swc_drm_finish(struct swc_drm * drm)
181 {
182     wld_drm_destroy_context(drm->context);
183-    drm_intel_bufmgr_destroy(drm->bufmgr);
184+    free(drm->path);
185     close(drm->fd);
186 }
187 
188@@ -246,6 +349,31 @@ void swc_drm_add_event_sources(struct swc_drm * drm,
189                                        &handle_data, NULL);
190 }
191 
192+static void bind_drm(struct wl_client * client, void * data, uint32_t version,
193+                     uint32_t id)
194+{
195+    struct swc_drm * drm = data;
196+    struct wl_resource * resource;
197+
198+    if (version >= 2)
199+        version = 2;
200+
201+    resource = wl_resource_create(client, &wl_drm_interface, version, id);
202+    wl_resource_set_implementation(resource, &drm_implementation, drm, NULL);
203+
204+    if (version >= 2)
205+        wl_drm_send_capabilities(resource, WL_DRM_CAPABILITY_PRIME);
206+
207+    wl_drm_send_device(resource, drm->path);
208+    wl_drm_send_format(resource, WL_DRM_FORMAT_XRGB8888);
209+    wl_drm_send_format(resource, WL_DRM_FORMAT_ARGB8888);
210+}
211+
212+void swc_drm_add_globals(struct swc_drm * drm, struct wl_display * display)
213+{
214+    wl_global_create(display, &wl_drm_interface, 2, drm, &bind_drm);
215+}
216+
217 void swc_drm_set_master(struct swc_drm * drm)
218 {
219     printf("setting drm master\n");
+3, -0
 1@@ -19,6 +19,7 @@ struct swc_drm
 2 {
 3     int fd;
 4     uint32_t id;
 5+    char * path;
 6 
 7     drm_intel_bufmgr * bufmgr;
 8     struct wld_drm_context * context;
 9@@ -38,6 +39,8 @@ void swc_drm_finish(struct swc_drm * drm);
10 void swc_drm_add_event_sources(struct swc_drm * drm,
11                                struct wl_event_loop * event_loop);
12 
13+void swc_drm_add_globals(struct swc_drm * drm, struct wl_display * display);
14+
15 void swc_drm_set_master(struct swc_drm * drm);
16 
17 void swc_drm_drop_master(struct swc_drm * drm);
+76, -0
 1@@ -0,0 +1,76 @@
 2+/* swc: drm_buffer.c
 3+ *
 4+ * Copyright (c) 2013 Michael Forney
 5+ *
 6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
 7+ * of this software and associated documentation files (the "Software"), to deal
 8+ * in the Software without restriction, including without limitation the rights
 9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+ * SOFTWARE.
23+ */
24+
25+#include "drm_buffer.h"
26+
27+#include <stdlib.h>
28+#include <wayland-server.h>
29+#include <wayland-drm-server-protocol.h>
30+#include <wld/wld.h>
31+
32+static void destroy(struct wl_client * client, struct wl_resource * resource)
33+{
34+    wl_resource_destroy(resource);
35+}
36+
37+static const struct wl_buffer_interface drm_buffer_implementation = {
38+    .destroy = &destroy
39+};
40+
41+static void buffer_destroy(struct wl_resource * resource)
42+{
43+    struct swc_drm_buffer * buffer = wl_resource_get_user_data(resource);
44+
45+    wld_destroy_drawable(buffer->drawable);
46+    free(buffer);
47+}
48+
49+struct swc_drm_buffer * swc_drm_buffer_new
50+    (struct wl_client * client, uint32_t id, struct wld_drawable * drawable)
51+{
52+    struct swc_drm_buffer * buffer;
53+
54+    buffer = malloc(sizeof *buffer);
55+
56+    if (!buffer)
57+        return NULL;
58+
59+    buffer->resource = wl_resource_create(client, &wl_buffer_interface, 1, id);
60+    wl_resource_set_implementation(buffer->resource, &drm_buffer_implementation,
61+                                   buffer, &buffer_destroy);
62+    buffer->drawable = drawable;
63+
64+    return buffer;
65+}
66+
67+struct swc_drm_buffer * swc_drm_buffer_get(struct wl_resource * resource)
68+{
69+    if (wl_resource_instance_of(resource, &wl_buffer_interface,
70+                                &drm_buffer_implementation))
71+    {
72+        return wl_resource_get_user_data(resource);
73+    }
74+    else
75+        return NULL;
76+}
77+
+44, -0
 1@@ -0,0 +1,44 @@
 2+/* swc: drm_buffer.h
 3+ *
 4+ * Copyright (c) 2013 Michael Forney
 5+ *
 6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
 7+ * of this software and associated documentation files (the "Software"), to deal
 8+ * in the Software without restriction, including without limitation the rights
 9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+ * SOFTWARE.
23+ */
24+
25+#ifndef SWC_DRM_BUFFER_H
26+#define SWC_DRM_BUFFER_H 1
27+
28+#include <stdint.h>
29+
30+struct wl_resource;
31+struct wl_client;
32+
33+struct swc_drm_buffer
34+{
35+    struct wl_resource * resource;
36+    struct wld_drawable * drawable;
37+};
38+
39+struct swc_drm_buffer * swc_drm_buffer_new
40+    (struct wl_client * client, uint32_t id, struct wld_drawable * drawable);
41+
42+struct swc_drm_buffer * swc_drm_buffer_get(struct wl_resource * resource);
43+
44+#endif
45+
+0, -86
 1@@ -1,86 +0,0 @@
 2-#include "egl.h"
 3-
 4-#include <stdio.h>
 5-#include <string.h>
 6-
 7-#define EGL_EGLEXT_PROTOTYPES
 8-#include <EGL/eglext.h>
 9-#undef EGL_EGLEXT_PROTOTYPES
10-
11-bool swc_egl_initialize(struct swc_egl * egl, struct gbm_device * gbm)
12-{
13-    const char * extensions;
14-
15-    egl->display = eglGetDisplay(gbm);
16-
17-    if (egl->display == NULL)
18-    {
19-        printf("could not create egl display\n");
20-        goto error_base;
21-    }
22-
23-    if (!eglInitialize(egl->display, NULL, NULL))
24-    {
25-        printf("could not initialize egl display\n");
26-        goto error_base;
27-    }
28-
29-#if EGL_WL_bind_wayland_display
30-    extensions = eglQueryString(egl->display, EGL_EXTENSIONS);
31-
32-    if (!extensions)
33-    {
34-        printf("could not query EGL extensions\n");
35-        goto error_display;
36-    }
37-
38-    if (strstr(extensions, "EGL_WL_bind_wayland_display"))
39-        egl->has_bind_wayland_display = true;
40-    else
41-    {
42-        printf("warning: headers claim EGL_WL_bind_wayland_display exists, "
43-               "but it is not in the queried extension list\n");
44-        egl->has_bind_wayland_display = false;
45-    }
46-#else
47-    printf("don't have EGL_WL_bind_wayland_display extension\n");
48-    egl->has_bind_wayland_display = false;
49-#endif
50-
51-    return true;
52-
53-  error_display:
54-    eglTerminate(egl->display);
55-    eglReleaseThread();
56-  error_base:
57-    return false;
58-}
59-
60-void swc_egl_finish(struct swc_egl * egl)
61-{
62-    eglTerminate(egl->display);
63-    eglReleaseThread();
64-}
65-
66-bool swc_egl_bind_display(struct swc_egl * egl, struct wl_display * display)
67-{
68-#if EGL_WL_bind_wayland_display
69-    if (egl->has_bind_wayland_display)
70-        return eglBindWaylandDisplayWL(egl->display, display);
71-#endif
72-
73-    /* If we don't have this extension, just continue normally. */
74-    return true;
75-}
76-
77-bool swc_egl_unbind_display(struct swc_egl * egl, struct wl_display * display)
78-{
79-#if EGL_WL_bind_wayland_display
80-    if (egl->has_bind_wayland_display)
81-        return eglUnbindWaylandDisplayWL(egl->display, display);
82-#endif
83-
84-    /* If we don't have this extension, just continue normally. */
85-    return true;
86-}
87-
+0, -25
 1@@ -1,25 +0,0 @@
 2-#ifndef SWC_EGL_H
 3-#define SWC_EGL_H 1
 4-
 5-#include <stdlib.h>
 6-#include <stdbool.h>
 7-#include <wayland-server.h>
 8-#include <gbm.h>
 9-#include <EGL/egl.h>
10-
11-struct swc_egl
12-{
13-    EGLDisplay display;
14-    bool has_bind_wayland_display;
15-};
16-
17-bool swc_egl_initialize(struct swc_egl * egl, struct gbm_device * gbm);
18-
19-void swc_egl_finish(struct swc_egl * egl);
20-
21-bool swc_egl_bind_display(struct swc_egl * egl, struct wl_display * display);
22-
23-bool swc_egl_unbind_display(struct swc_egl * egl, struct wl_display * display);
24-
25-#endif
26-
+8, -0
1@@ -0,0 +1,8 @@
2+# wld: protocol/Makefile.am
3+
4+BUILT_SOURCES = wayland-drm-protocol.c wayland-drm-server-protocol.h
5+CLEANFILES = $(BUILT_SOURCES)
6+
7+@wayland_scanner_rules@
8+
9+
+182, -0
  1@@ -0,0 +1,182 @@
  2+<?xml version="1.0" encoding="UTF-8"?>
  3+<protocol name="drm">
  4+
  5+  <copyright>
  6+    Copyright © 2008-2011 Kristian Høgsberg
  7+    Copyright © 2010-2011 Intel Corporation
  8+
  9+    Permission to use, copy, modify, distribute, and sell this
 10+    software and its documentation for any purpose is hereby granted
 11+    without fee, provided that\n the above copyright notice appear in
 12+    all copies and that both that copyright notice and this permission
 13+    notice appear in supporting documentation, and that the name of
 14+    the copyright holders not be used in advertising or publicity
 15+    pertaining to distribution of the software without specific,
 16+    written prior permission.  The copyright holders make no
 17+    representations about the suitability of this software for any
 18+    purpose.  It is provided "as is" without express or implied
 19+    warranty.
 20+
 21+    THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
 22+    SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 23+    FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
 24+    SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 25+    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 26+    AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 27+    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 28+    THIS SOFTWARE.
 29+  </copyright>
 30+
 31+  <!-- drm support. This object is created by the server and published
 32+       using the display's global event. -->
 33+  <interface name="wl_drm" version="2">
 34+    <enum name="error">
 35+      <entry name="authenticate_fail" value="0"/>
 36+      <entry name="invalid_format" value="1"/>
 37+      <entry name="invalid_name" value="2"/>
 38+    </enum>
 39+
 40+    <enum name="format">
 41+      <!-- The drm format codes match the #defines in drm_fourcc.h.
 42+           The formats actually supported by the compositor will be
 43+           reported by the format event. -->
 44+      <entry name="c8" value="0x20203843"/>
 45+      <entry name="rgb332" value="0x38424752"/>
 46+      <entry name="bgr233" value="0x38524742"/>
 47+      <entry name="xrgb4444" value="0x32315258"/>
 48+      <entry name="xbgr4444" value="0x32314258"/>
 49+      <entry name="rgbx4444" value="0x32315852"/>
 50+      <entry name="bgrx4444" value="0x32315842"/>
 51+      <entry name="argb4444" value="0x32315241"/>
 52+      <entry name="abgr4444" value="0x32314241"/>
 53+      <entry name="rgba4444" value="0x32314152"/>
 54+      <entry name="bgra4444" value="0x32314142"/>
 55+      <entry name="xrgb1555" value="0x35315258"/>
 56+      <entry name="xbgr1555" value="0x35314258"/>
 57+      <entry name="rgbx5551" value="0x35315852"/>
 58+      <entry name="bgrx5551" value="0x35315842"/>
 59+      <entry name="argb1555" value="0x35315241"/>
 60+      <entry name="abgr1555" value="0x35314241"/>
 61+      <entry name="rgba5551" value="0x35314152"/>
 62+      <entry name="bgra5551" value="0x35314142"/>
 63+      <entry name="rgb565" value="0x36314752"/>
 64+      <entry name="bgr565" value="0x36314742"/>
 65+      <entry name="rgb888" value="0x34324752"/>
 66+      <entry name="bgr888" value="0x34324742"/>
 67+      <entry name="xrgb8888" value="0x34325258"/>
 68+      <entry name="xbgr8888" value="0x34324258"/>
 69+      <entry name="rgbx8888" value="0x34325852"/>
 70+      <entry name="bgrx8888" value="0x34325842"/>
 71+      <entry name="argb8888" value="0x34325241"/>
 72+      <entry name="abgr8888" value="0x34324241"/>
 73+      <entry name="rgba8888" value="0x34324152"/>
 74+      <entry name="bgra8888" value="0x34324142"/>
 75+      <entry name="xrgb2101010" value="0x30335258"/>
 76+      <entry name="xbgr2101010" value="0x30334258"/>
 77+      <entry name="rgbx1010102" value="0x30335852"/>
 78+      <entry name="bgrx1010102" value="0x30335842"/>
 79+      <entry name="argb2101010" value="0x30335241"/>
 80+      <entry name="abgr2101010" value="0x30334241"/>
 81+      <entry name="rgba1010102" value="0x30334152"/>
 82+      <entry name="bgra1010102" value="0x30334142"/>
 83+      <entry name="yuyv" value="0x56595559"/>
 84+      <entry name="yvyu" value="0x55595659"/>
 85+      <entry name="uyvy" value="0x59565955"/>
 86+      <entry name="vyuy" value="0x59555956"/>
 87+      <entry name="ayuv" value="0x56555941"/>
 88+      <entry name="nv12" value="0x3231564e"/>
 89+      <entry name="nv21" value="0x3132564e"/>
 90+      <entry name="nv16" value="0x3631564e"/>
 91+      <entry name="nv61" value="0x3136564e"/>
 92+      <entry name="yuv410" value="0x39565559"/>
 93+      <entry name="yvu410" value="0x39555659"/>
 94+      <entry name="yuv411" value="0x31315559"/>
 95+      <entry name="yvu411" value="0x31315659"/>
 96+      <entry name="yuv420" value="0x32315559"/>
 97+      <entry name="yvu420" value="0x32315659"/>
 98+      <entry name="yuv422" value="0x36315559"/>
 99+      <entry name="yvu422" value="0x36315659"/>
100+      <entry name="yuv444" value="0x34325559"/>
101+      <entry name="yvu444" value="0x34325659"/>
102+    </enum>
103+
104+    <!-- Call this request with the magic received from drmGetMagic().
105+         It will be passed on to the drmAuthMagic() or
106+         DRIAuthConnection() call.  This authentication must be
107+         completed before create_buffer could be used. -->
108+    <request name="authenticate">
109+      <arg name="id" type="uint"/>
110+    </request>
111+
112+    <!-- Create a wayland buffer for the named DRM buffer.  The DRM
113+         surface must have a name using the flink ioctl -->
114+    <request name="create_buffer">
115+      <arg name="id" type="new_id" interface="wl_buffer"/>
116+      <arg name="name" type="uint"/>
117+      <arg name="width" type="int"/>
118+      <arg name="height" type="int"/>
119+      <arg name="stride" type="uint"/>
120+      <arg name="format" type="uint"/>
121+    </request>
122+
123+    <!-- Create a wayland buffer for the named DRM buffer.  The DRM
124+         surface must have a name using the flink ioctl -->
125+    <request name="create_planar_buffer">
126+      <arg name="id" type="new_id" interface="wl_buffer"/>
127+      <arg name="name" type="uint"/>
128+      <arg name="width" type="int"/>
129+      <arg name="height" type="int"/>
130+      <arg name="format" type="uint"/>
131+      <arg name="offset0" type="int"/>
132+      <arg name="stride0" type="int"/>
133+      <arg name="offset1" type="int"/>
134+      <arg name="stride1" type="int"/>
135+      <arg name="offset2" type="int"/>
136+      <arg name="stride2" type="int"/>
137+    </request>
138+
139+    <!-- Create a wayland buffer for the prime fd.  Use for regular and planar
140+         buffers.  Pass 0 for offset and stride for unused planes. -->
141+    <request name="create_prime_buffer" since="2">
142+      <arg name="id" type="new_id" interface="wl_buffer"/>
143+      <arg name="name" type="fd"/>
144+      <arg name="width" type="int"/>
145+      <arg name="height" type="int"/>
146+      <arg name="format" type="uint"/>
147+      <arg name="offset0" type="int"/>
148+      <arg name="stride0" type="int"/>
149+      <arg name="offset1" type="int"/>
150+      <arg name="stride1" type="int"/>
151+      <arg name="offset2" type="int"/>
152+      <arg name="stride2" type="int"/>
153+    </request>
154+
155+    <!-- Notification of the path of the drm device which is used by
156+         the server.  The client should use this device for creating
157+         local buffers.  Only buffers created from this device should
158+         be be passed to the server using this drm object's
159+         create_buffer request. -->
160+    <event name="device">
161+      <arg name="name" type="string"/>
162+    </event>
163+
164+    <event name="format">
165+      <arg name="format" type="uint"/>
166+    </event>
167+
168+    <!-- Raised if the authenticate request succeeded -->
169+    <event name="authenticated"/>
170+
171+    <enum name="capability" since="2">
172+      <description summary="wl_drm capability bitmask">
173+        Bitmask of capabilities.
174+      </description>
175+      <entry name="prime" value="1" summary="wl_drm prime available"/>
176+    </enum>
177+
178+    <event name="capabilities">
179+      <arg name="value" type="uint"/>
180+    </event>
181+  </interface>
182+
183+</protocol>