dc90781865d53c9094458f3566ece51fc0e98b9b
[platform/upstream/weston.git] / libweston / compositor-drm.c
1 /*
2  * Copyright © 2008-2011 Kristian Høgsberg
3  * Copyright © 2011 Intel Corporation
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining
6  * a copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sublicense, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial
15  * portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26
27 #include "config.h"
28
29 #include <errno.h>
30 #include <stdint.h>
31 #include <stdlib.h>
32 #include <ctype.h>
33 #include <string.h>
34 #include <fcntl.h>
35 #include <unistd.h>
36 #include <linux/input.h>
37 #include <linux/vt.h>
38 #include <assert.h>
39 #include <sys/mman.h>
40 #include <dlfcn.h>
41 #include <time.h>
42
43 #include <xf86drm.h>
44 #include <xf86drmMode.h>
45 #include <drm_fourcc.h>
46
47 #include <gbm.h>
48 #include <libudev.h>
49
50 #include "compositor.h"
51 #include "compositor-drm.h"
52 #include "shared/helpers.h"
53 #include "shared/timespec-util.h"
54 #include "gl-renderer.h"
55 #include "weston-egl-ext.h"
56 #include "pixman-renderer.h"
57 #include "pixel-formats.h"
58 #include "libbacklight.h"
59 #include "libinput-seat.h"
60 #include "launcher-util.h"
61 #include "vaapi-recorder.h"
62 #include "presentation-time-server-protocol.h"
63 #include "linux-dmabuf.h"
64 #include "linux-dmabuf-unstable-v1-server-protocol.h"
65
66 #ifndef DRM_CAP_TIMESTAMP_MONOTONIC
67 #define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
68 #endif
69
70 #ifndef DRM_CLIENT_CAP_UNIVERSAL_PLANES
71 #define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
72 #endif
73
74 #ifndef DRM_CAP_CURSOR_WIDTH
75 #define DRM_CAP_CURSOR_WIDTH 0x8
76 #endif
77
78 #ifndef DRM_CAP_CURSOR_HEIGHT
79 #define DRM_CAP_CURSOR_HEIGHT 0x9
80 #endif
81
82 #ifndef GBM_BO_USE_CURSOR
83 #define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64
84 #endif
85
86 /**
87  * List of properties attached to DRM planes
88  */
89 enum wdrm_plane_property {
90         WDRM_PLANE_TYPE = 0,
91         WDRM_PLANE__COUNT
92 };
93
94 /**
95  * Possible values for the WDRM_PLANE_TYPE property.
96  */
97 enum wdrm_plane_type {
98         WDRM_PLANE_TYPE_PRIMARY = 0,
99         WDRM_PLANE_TYPE_CURSOR,
100         WDRM_PLANE_TYPE_OVERLAY,
101         WDRM_PLANE_TYPE__COUNT
102 };
103
104 /**
105  * List of properties attached to a DRM connector
106  */
107 enum wdrm_connector_property {
108         WDRM_CONNECTOR_EDID = 0,
109         WDRM_CONNECTOR_DPMS,
110         WDRM_CONNECTOR__COUNT
111 };
112
113 /**
114  * Represents the values of an enum-type KMS property
115  */
116 struct drm_property_enum_info {
117         const char *name; /**< name as string (static, not freed) */
118         bool valid; /**< true if value is supported; ignore if false */
119         uint64_t value; /**< raw value */
120 };
121
122 /**
123  * Holds information on a DRM property, including its ID and the enum
124  * values it holds.
125  *
126  * DRM properties are allocated dynamically, and maintained as DRM objects
127  * within the normal object ID space; they thus do not have a stable ID
128  * to refer to. This includes enum values, which must be referred to by
129  * integer values, but these are not stable.
130  *
131  * drm_property_info allows a cache to be maintained where Weston can use
132  * enum values internally to refer to properties, with the mapping to DRM
133  * ID values being maintained internally.
134  */
135 struct drm_property_info {
136         const char *name; /**< name as string (static, not freed) */
137         uint32_t prop_id; /**< KMS property object ID */
138         unsigned int num_enum_values; /**< number of enum values */
139         struct drm_property_enum_info *enum_values; /**< array of enum values */
140 };
141
142 struct drm_backend {
143         struct weston_backend base;
144         struct weston_compositor *compositor;
145
146         struct udev *udev;
147         struct wl_event_source *drm_source;
148
149         struct udev_monitor *udev_monitor;
150         struct wl_event_source *udev_drm_source;
151
152         struct {
153                 int id;
154                 int fd;
155                 char *filename;
156         } drm;
157         struct gbm_device *gbm;
158         struct wl_listener session_listener;
159         uint32_t gbm_format;
160
161         /* we need these parameters in order to not fail drmModeAddFB2()
162          * due to out of bounds dimensions, and then mistakenly set
163          * sprites_are_broken:
164          */
165         int min_width, max_width;
166         int min_height, max_height;
167         int no_addfb2;
168
169         struct wl_list plane_list;
170         int sprites_are_broken;
171         int sprites_hidden;
172
173         void *repaint_data;
174
175         int cursors_are_broken;
176
177         bool universal_planes;
178
179         int use_pixman;
180
181         struct udev_input input;
182
183         int32_t cursor_width;
184         int32_t cursor_height;
185
186         uint32_t pageflip_timeout;
187 };
188
189 struct drm_mode {
190         struct weston_mode base;
191         drmModeModeInfo mode_info;
192 };
193
194 enum drm_fb_type {
195         BUFFER_INVALID = 0, /**< never used */
196         BUFFER_CLIENT, /**< directly sourced from client */
197         BUFFER_PIXMAN_DUMB, /**< internal Pixman rendering */
198         BUFFER_GBM_SURFACE, /**< internal EGL rendering */
199         BUFFER_CURSOR, /**< internal cursor buffer */
200 };
201
202 struct drm_fb {
203         enum drm_fb_type type;
204
205         int refcnt;
206
207         uint32_t fb_id, stride, handle, size;
208         const struct pixel_format_info *format;
209         int width, height;
210         int fd;
211         struct weston_buffer_reference buffer_ref;
212
213         /* Used by gbm fbs */
214         struct gbm_bo *bo;
215         struct gbm_surface *gbm_surface;
216
217         /* Used by dumb fbs */
218         void *map;
219 };
220
221 struct drm_edid {
222         char eisa_id[13];
223         char monitor_name[13];
224         char pnp_id[5];
225         char serial_number[13];
226 };
227
228 /**
229  * Pending state holds one or more drm_output_state structures, collected from
230  * performing repaint. This pending state is transient, and only lives between
231  * beginning a repaint group and flushing the results: after flush, each
232  * output state will complete and be retired separately.
233  */
234 struct drm_pending_state {
235         struct drm_backend *backend;
236 };
237
238 /**
239  * A plane represents one buffer, positioned within a CRTC, and stacked
240  * relative to other planes on the same CRTC.
241  *
242  * Each CRTC has a 'primary plane', which use used to display the classic
243  * framebuffer contents, as accessed through the legacy drmModeSetCrtc
244  * call (which combines setting the CRTC's actual physical mode, and the
245  * properties of the primary plane).
246  *
247  * The cursor plane also has its own alternate legacy API.
248  *
249  * Other planes are used opportunistically to display content we do not
250  * wish to blit into the primary plane. These non-primary/cursor planes
251  * are referred to as 'sprites'.
252  */
253 struct drm_plane {
254         struct wl_list link;
255
256         struct weston_plane base;
257
258         struct drm_output *output;
259         struct drm_backend *backend;
260
261         enum wdrm_plane_type type;
262
263         uint32_t possible_crtcs;
264         uint32_t plane_id;
265         uint32_t count_formats;
266
267         struct drm_property_info props[WDRM_PLANE__COUNT];
268
269         /* The last framebuffer submitted to the kernel for this plane. */
270         struct drm_fb *fb_current;
271         /* The previously-submitted framebuffer, where the hardware has not
272          * yet acknowledged display of fb_current. */
273         struct drm_fb *fb_last;
274         /* Framebuffer we are going to submit to the kernel when the current
275          * repaint is flushed. */
276         struct drm_fb *fb_pending;
277
278         int32_t src_x, src_y;
279         uint32_t src_w, src_h;
280         uint32_t dest_x, dest_y;
281         uint32_t dest_w, dest_h;
282
283         uint32_t formats[];
284 };
285
286 struct drm_output {
287         struct weston_output base;
288         drmModeConnector *connector;
289
290         uint32_t crtc_id; /* object ID to pass to DRM functions */
291         int pipe; /* index of CRTC in resource array / bitmasks */
292         uint32_t connector_id;
293         drmModeCrtcPtr original_crtc;
294         struct drm_edid edid;
295
296         /* Holds the properties for the connector */
297         struct drm_property_info props_conn[WDRM_CONNECTOR__COUNT];
298
299         enum dpms_enum dpms;
300         struct backlight *backlight;
301
302         bool state_invalid;
303
304         int vblank_pending;
305         int page_flip_pending;
306         int destroy_pending;
307         int disable_pending;
308
309         struct drm_fb *gbm_cursor_fb[2];
310         struct weston_plane cursor_plane;
311         struct weston_view *cursor_view;
312         int current_cursor;
313
314         struct gbm_surface *gbm_surface;
315         uint32_t gbm_format;
316
317         /* Plane for a fullscreen direct scanout view */
318         struct weston_plane scanout_plane;
319
320         /* The last framebuffer submitted to the kernel for this CRTC. */
321         struct drm_fb *fb_current;
322         /* The previously-submitted framebuffer, where the hardware has not
323          * yet acknowledged display of fb_current. */
324         struct drm_fb *fb_last;
325         /* Framebuffer we are going to submit to the kernel when the current
326          * repaint is flushed. */
327         struct drm_fb *fb_pending;
328
329         struct drm_fb *dumb[2];
330         pixman_image_t *image[2];
331         int current_image;
332         pixman_region32_t previous_damage;
333
334         struct vaapi_recorder *recorder;
335         struct wl_listener recorder_frame_listener;
336
337         struct wl_event_source *pageflip_timer;
338 };
339
340 static struct gl_renderer_interface *gl_renderer;
341
342 static const char default_seat[] = "seat0";
343
344 static inline struct drm_output *
345 to_drm_output(struct weston_output *base)
346 {
347         return container_of(base, struct drm_output, base);
348 }
349
350 static inline struct drm_backend *
351 to_drm_backend(struct weston_compositor *base)
352 {
353         return container_of(base->backend, struct drm_backend, base);
354 }
355
356 static int
357 pageflip_timeout(void *data) {
358         /*
359          * Our timer just went off, that means we're not receiving drm
360          * page flip events anymore for that output. Let's gracefully exit
361          * weston with a return value so devs can debug what's going on.
362          */
363         struct drm_output *output = data;
364         struct weston_compositor *compositor = output->base.compositor;
365
366         weston_log("Pageflip timeout reached on output %s, your "
367                    "driver is probably buggy!  Exiting.\n",
368                    output->base.name);
369         weston_compositor_exit_with_code(compositor, EXIT_FAILURE);
370
371         return 0;
372 }
373
374 /* Creates the pageflip timer. Note that it isn't armed by default */
375 static int
376 drm_output_pageflip_timer_create(struct drm_output *output)
377 {
378         struct wl_event_loop *loop = NULL;
379         struct weston_compositor *ec = output->base.compositor;
380
381         loop = wl_display_get_event_loop(ec->wl_display);
382         assert(loop);
383         output->pageflip_timer = wl_event_loop_add_timer(loop,
384                                                          pageflip_timeout,
385                                                          output);
386
387         if (output->pageflip_timer == NULL) {
388                 weston_log("creating drm pageflip timer failed: %m\n");
389                 return -1;
390         }
391
392         return 0;
393 }
394
395 /**
396  * Get the current value of a KMS property
397  *
398  * Given a drmModeObjectGetProperties return, as well as the drm_property_info
399  * for the target property, return the current value of that property,
400  * with an optional default. If the property is a KMS enum type, the return
401  * value will be translated into the appropriate internal enum.
402  *
403  * If the property is not present, the default value will be returned.
404  *
405  * @param info Internal structure for property to look up
406  * @param props Raw KMS properties for the target object
407  * @param def Value to return if property is not found
408  */
409 static uint64_t
410 drm_property_get_value(struct drm_property_info *info,
411                        drmModeObjectPropertiesPtr props,
412                        uint64_t def)
413 {
414         unsigned int i;
415
416         if (info->prop_id == 0)
417                 return def;
418
419         for (i = 0; i < props->count_props; i++) {
420                 unsigned int j;
421
422                 if (props->props[i] != info->prop_id)
423                         continue;
424
425                 /* Simple (non-enum) types can return the value directly */
426                 if (info->num_enum_values == 0)
427                         return props->prop_values[i];
428
429                 /* Map from raw value to enum value */
430                 for (j = 0; j < info->num_enum_values; j++) {
431                         if (!info->enum_values[j].valid)
432                                 continue;
433                         if (info->enum_values[j].value != props->prop_values[i])
434                                 continue;
435
436                         return j;
437                 }
438
439                 /* We don't have a mapping for this enum; return default. */
440                 break;
441         }
442
443         return def;
444 }
445
446 /**
447  * Cache DRM property values
448  *
449  * Update a per-object array of drm_property_info structures, given the
450  * DRM properties of the object.
451  *
452  * Call this every time an object newly appears (note that only connectors
453  * can be hotplugged), the first time it is seen, or when its status changes
454  * in a way which invalidates the potential property values (currently, the
455  * only case for this is connector hotplug).
456  *
457  * This updates the property IDs and enum values within the drm_property_info
458  * array.
459  *
460  * DRM property enum values are dynamic at runtime; the user must query the
461  * property to find out the desired runtime value for a requested string
462  * name. Using the 'type' field on planes as an example, there is no single
463  * hardcoded constant for primary plane types; instead, the property must be
464  * queried at runtime to find the value associated with the string "Primary".
465  *
466  * This helper queries and caches the enum values, to allow us to use a set
467  * of compile-time-constant enums portably across various implementations.
468  * The values given in enum_names are searched for, and stored in the
469  * same-indexed field of the map array.
470  *
471  * @param b DRM backend object
472  * @param src DRM property info array to source from
473  * @param info DRM property info array to copy into
474  * @param num_infos Number of entries in the source array
475  * @param props DRM object properties for the object
476  */
477 static void
478 drm_property_info_populate(struct drm_backend *b,
479                            const struct drm_property_info *src,
480                            struct drm_property_info *info,
481                            unsigned int num_infos,
482                            drmModeObjectProperties *props)
483 {
484         drmModePropertyRes *prop;
485         unsigned i, j;
486
487         for (i = 0; i < num_infos; i++) {
488                 unsigned int j;
489
490                 info[i].name = src[i].name;
491                 info[i].prop_id = 0;
492                 info[i].num_enum_values = src[i].num_enum_values;
493
494                 if (src[i].num_enum_values == 0)
495                         continue;
496
497                 info[i].enum_values =
498                         malloc(src[i].num_enum_values *
499                                sizeof(*info[i].enum_values));
500                 assert(info[i].enum_values);
501                 for (j = 0; j < info[i].num_enum_values; j++) {
502                         info[i].enum_values[j].name = src[i].enum_values[j].name;
503                         info[i].enum_values[j].valid = false;
504                 }
505         }
506
507         for (i = 0; i < props->count_props; i++) {
508                 unsigned int k;
509
510                 prop = drmModeGetProperty(b->drm.fd, props->props[i]);
511                 if (!prop)
512                         continue;
513
514                 for (j = 0; j < num_infos; j++) {
515                         if (!strcmp(prop->name, info[j].name))
516                                 break;
517                 }
518
519                 /* We don't know/care about this property. */
520                 if (j == num_infos) {
521 #ifdef DEBUG
522                         weston_log("DRM debug: unrecognized property %u '%s'\n",
523                                    prop->prop_id, prop->name);
524 #endif
525                         drmModeFreeProperty(prop);
526                         continue;
527                 }
528
529                 if (info[j].num_enum_values == 0 &&
530                     (prop->flags & DRM_MODE_PROP_ENUM)) {
531                         weston_log("DRM: expected property %s to not be an"
532                                    " enum, but it is; ignoring\n", prop->name);
533                         drmModeFreeProperty(prop);
534                         continue;
535                 }
536
537                 info[j].prop_id = props->props[i];
538
539                 if (info[j].num_enum_values == 0) {
540                         drmModeFreeProperty(prop);
541                         continue;
542                 }
543
544                 if (!(prop->flags & DRM_MODE_PROP_ENUM)) {
545                         weston_log("DRM: expected property %s to be an enum,"
546                                    " but it is not; ignoring\n", prop->name);
547                         drmModeFreeProperty(prop);
548                         info[j].prop_id = 0;
549                         continue;
550                 }
551
552                 for (k = 0; k < info[j].num_enum_values; k++) {
553                         int l;
554
555                         for (l = 0; l < prop->count_enums; l++) {
556                                 if (!strcmp(prop->enums[l].name,
557                                             info[j].enum_values[k].name))
558                                         break;
559                         }
560
561                         if (l == prop->count_enums)
562                                 continue;
563
564                         info[j].enum_values[k].valid = true;
565                         info[j].enum_values[k].value = prop->enums[l].value;
566                 }
567
568                 drmModeFreeProperty(prop);
569         }
570
571 #ifdef DEBUG
572         for (i = 0; i < num_infos; i++) {
573                 if (info[i].prop_id == 0)
574                         weston_log("DRM warning: property '%s' missing\n",
575                                    info[i].name);
576         }
577 #endif
578 }
579
580 /**
581  * Free DRM property information
582  *
583  * Frees all memory associated with a DRM property info array.
584  *
585  * @param info DRM property info array
586  * @param num_props Number of entries in array to free
587  */
588 static void
589 drm_property_info_free(struct drm_property_info *info, int num_props)
590 {
591         int i;
592
593         for (i = 0; i < num_props; i++)
594                 free(info[i].enum_values);
595 }
596
597 static void
598 drm_output_set_cursor(struct drm_output *output);
599
600 static void
601 drm_output_update_msc(struct drm_output *output, unsigned int seq);
602
603 static int
604 drm_plane_crtc_supported(struct drm_output *output, struct drm_plane *plane)
605 {
606         return !!(plane->possible_crtcs & (1 << output->pipe));
607 }
608
609 static struct drm_output *
610 drm_output_find_by_crtc(struct drm_backend *b, uint32_t crtc_id)
611 {
612         struct drm_output *output;
613
614         wl_list_for_each(output, &b->compositor->output_list, base.link) {
615                 if (output->crtc_id == crtc_id)
616                         return output;
617         }
618
619         wl_list_for_each(output, &b->compositor->pending_output_list,
620                          base.link) {
621                 if (output->crtc_id == crtc_id)
622                         return output;
623         }
624
625         return NULL;
626 }
627
628 static struct drm_output *
629 drm_output_find_by_connector(struct drm_backend *b, uint32_t connector_id)
630 {
631         struct drm_output *output;
632
633         wl_list_for_each(output, &b->compositor->output_list, base.link) {
634                 if (output->connector_id == connector_id)
635                         return output;
636         }
637
638         wl_list_for_each(output, &b->compositor->pending_output_list,
639                          base.link) {
640                 if (output->connector_id == connector_id)
641                         return output;
642         }
643
644         return NULL;
645 }
646
647 static void
648 drm_fb_destroy(struct drm_fb *fb)
649 {
650         if (fb->fb_id != 0)
651                 drmModeRmFB(fb->fd, fb->fb_id);
652         weston_buffer_reference(&fb->buffer_ref, NULL);
653         free(fb);
654 }
655
656 static void
657 drm_fb_destroy_dumb(struct drm_fb *fb)
658 {
659         struct drm_mode_destroy_dumb destroy_arg;
660
661         assert(fb->type == BUFFER_PIXMAN_DUMB);
662
663         if (fb->map && fb->size > 0)
664                 munmap(fb->map, fb->size);
665
666         memset(&destroy_arg, 0, sizeof(destroy_arg));
667         destroy_arg.handle = fb->handle;
668         drmIoctl(fb->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
669
670         drm_fb_destroy(fb);
671 }
672
673 static void
674 drm_fb_destroy_gbm(struct gbm_bo *bo, void *data)
675 {
676         struct drm_fb *fb = data;
677
678         assert(fb->type == BUFFER_GBM_SURFACE || fb->type == BUFFER_CLIENT ||
679                fb->type == BUFFER_CURSOR);
680         drm_fb_destroy(fb);
681 }
682
683 static struct drm_fb *
684 drm_fb_create_dumb(struct drm_backend *b, int width, int height,
685                    uint32_t format)
686 {
687         struct drm_fb *fb;
688         int ret;
689
690         struct drm_mode_create_dumb create_arg;
691         struct drm_mode_destroy_dumb destroy_arg;
692         struct drm_mode_map_dumb map_arg;
693
694         fb = zalloc(sizeof *fb);
695         if (!fb)
696                 return NULL;
697
698         fb->refcnt = 1;
699
700         fb->format = pixel_format_get_info(format);
701         if (!fb->format) {
702                 weston_log("failed to look up format 0x%lx\n",
703                            (unsigned long) format);
704                 goto err_fb;
705         }
706
707         if (!fb->format->depth || !fb->format->bpp) {
708                 weston_log("format 0x%lx is not compatible with dumb buffers\n",
709                            (unsigned long) format);
710                 goto err_fb;
711         }
712
713         memset(&create_arg, 0, sizeof create_arg);
714         create_arg.bpp = fb->format->bpp;
715         create_arg.width = width;
716         create_arg.height = height;
717
718         ret = drmIoctl(b->drm.fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg);
719         if (ret)
720                 goto err_fb;
721
722         fb->type = BUFFER_PIXMAN_DUMB;
723         fb->handle = create_arg.handle;
724         fb->stride = create_arg.pitch;
725         fb->size = create_arg.size;
726         fb->width = width;
727         fb->height = height;
728         fb->fd = b->drm.fd;
729
730         ret = -1;
731
732         if (!b->no_addfb2) {
733                 uint32_t handles[4] = { 0 }, pitches[4] = { 0 }, offsets[4] = { 0 };
734
735                 handles[0] = fb->handle;
736                 pitches[0] = fb->stride;
737                 offsets[0] = 0;
738
739                 ret = drmModeAddFB2(b->drm.fd, width, height,
740                                     fb->format->format,
741                                     handles, pitches, offsets,
742                                     &fb->fb_id, 0);
743                 if (ret) {
744                         weston_log("addfb2 failed: %m\n");
745                         b->no_addfb2 = 1;
746                 }
747         }
748
749         if (ret) {
750                 ret = drmModeAddFB(b->drm.fd, width, height,
751                                    fb->format->depth, fb->format->bpp,
752                                    fb->stride, fb->handle, &fb->fb_id);
753         }
754
755         if (ret)
756                 goto err_bo;
757
758         memset(&map_arg, 0, sizeof map_arg);
759         map_arg.handle = fb->handle;
760         ret = drmIoctl(fb->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_arg);
761         if (ret)
762                 goto err_add_fb;
763
764         fb->map = mmap(NULL, fb->size, PROT_WRITE,
765                        MAP_SHARED, b->drm.fd, map_arg.offset);
766         if (fb->map == MAP_FAILED)
767                 goto err_add_fb;
768
769         return fb;
770
771 err_add_fb:
772         drmModeRmFB(b->drm.fd, fb->fb_id);
773 err_bo:
774         memset(&destroy_arg, 0, sizeof(destroy_arg));
775         destroy_arg.handle = create_arg.handle;
776         drmIoctl(b->drm.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
777 err_fb:
778         free(fb);
779         return NULL;
780 }
781
782 static struct drm_fb *
783 drm_fb_ref(struct drm_fb *fb)
784 {
785         fb->refcnt++;
786         return fb;
787 }
788
789 static struct drm_fb *
790 drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
791                    uint32_t format, enum drm_fb_type type)
792 {
793         struct drm_fb *fb = gbm_bo_get_user_data(bo);
794         uint32_t handles[4] = { 0 }, pitches[4] = { 0 }, offsets[4] = { 0 };
795         int ret;
796
797         if (fb) {
798                 assert(fb->type == type);
799                 return drm_fb_ref(fb);
800         }
801
802         fb = zalloc(sizeof *fb);
803         if (fb == NULL)
804                 return NULL;
805
806         fb->type = type;
807         fb->refcnt = 1;
808         fb->bo = bo;
809
810         fb->width = gbm_bo_get_width(bo);
811         fb->height = gbm_bo_get_height(bo);
812         fb->stride = gbm_bo_get_stride(bo);
813         fb->handle = gbm_bo_get_handle(bo).u32;
814         fb->format = pixel_format_get_info(format);
815         fb->size = fb->stride * fb->height;
816         fb->fd = backend->drm.fd;
817
818         if (!fb->format) {
819                 weston_log("couldn't look up format 0x%lx\n",
820                            (unsigned long) format);
821                 goto err_free;
822         }
823
824         if (backend->min_width > fb->width ||
825             fb->width > backend->max_width ||
826             backend->min_height > fb->height ||
827             fb->height > backend->max_height) {
828                 weston_log("bo geometry out of bounds\n");
829                 goto err_free;
830         }
831
832         ret = -1;
833
834         if (format && !backend->no_addfb2) {
835                 handles[0] = fb->handle;
836                 pitches[0] = fb->stride;
837                 offsets[0] = 0;
838
839                 ret = drmModeAddFB2(backend->drm.fd, fb->width, fb->height,
840                                     format, handles, pitches, offsets,
841                                     &fb->fb_id, 0);
842                 if (ret) {
843                         weston_log("addfb2 failed: %m\n");
844                         backend->no_addfb2 = 1;
845                         backend->sprites_are_broken = 1;
846                 }
847         }
848
849         if (ret && fb->format->depth && fb->format->bpp)
850                 ret = drmModeAddFB(backend->drm.fd, fb->width, fb->height,
851                                    fb->format->depth, fb->format->bpp,
852                                    fb->stride, fb->handle, &fb->fb_id);
853
854         if (ret) {
855                 weston_log("failed to create kms fb: %m\n");
856                 goto err_free;
857         }
858
859         gbm_bo_set_user_data(bo, fb, drm_fb_destroy_gbm);
860
861         return fb;
862
863 err_free:
864         free(fb);
865         return NULL;
866 }
867
868 static void
869 drm_fb_set_buffer(struct drm_fb *fb, struct weston_buffer *buffer)
870 {
871         assert(fb->buffer_ref.buffer == NULL);
872         assert(fb->type == BUFFER_CLIENT);
873         weston_buffer_reference(&fb->buffer_ref, buffer);
874 }
875
876 static void
877 drm_fb_unref(struct drm_fb *fb)
878 {
879         if (!fb)
880                 return;
881
882         assert(fb->refcnt > 0);
883         if (--fb->refcnt > 0)
884                 return;
885
886         switch (fb->type) {
887         case BUFFER_PIXMAN_DUMB:
888                 drm_fb_destroy_dumb(fb);
889                 break;
890         case BUFFER_CURSOR:
891         case BUFFER_CLIENT:
892                 gbm_bo_destroy(fb->bo);
893                 break;
894         case BUFFER_GBM_SURFACE:
895                 gbm_surface_release_buffer(fb->gbm_surface, fb->bo);
896                 break;
897         default:
898                 assert(NULL);
899                 break;
900         }
901 }
902
903 static int
904 drm_view_transform_supported(struct weston_view *ev)
905 {
906         return !ev->transform.enabled ||
907                 (ev->transform.matrix.type < WESTON_MATRIX_TRANSFORM_ROTATE);
908 }
909
910 /**
911  * Allocate a new drm_pending_state
912  *
913  * Allocate a new, empty, 'pending state' structure to be used across a
914  * repaint cycle or similar.
915  *
916  * @param backend DRM backend
917  * @returns Newly-allocated pending state structure
918  */
919 static struct drm_pending_state *
920 drm_pending_state_alloc(struct drm_backend *backend)
921 {
922         struct drm_pending_state *ret;
923
924         ret = calloc(1, sizeof(*ret));
925         if (!ret)
926                 return NULL;
927
928         ret->backend = backend;
929
930         return ret;
931 }
932
933 /**
934  * Free a drm_pending_state structure
935  *
936  * Frees a pending_state structure.
937  *
938  * @param pending_state Pending state structure to free
939  */
940 static void
941 drm_pending_state_free(struct drm_pending_state *pending_state)
942 {
943         if (!pending_state)
944                 return;
945
946         free(pending_state);
947 }
948
949 static uint32_t
950 drm_output_check_scanout_format(struct drm_output *output,
951                                 struct weston_surface *es, struct gbm_bo *bo)
952 {
953         uint32_t format;
954         pixman_region32_t r;
955
956         format = gbm_bo_get_format(bo);
957
958         if (format == GBM_FORMAT_ARGB8888) {
959                 /* We can scanout an ARGB buffer if the surface's
960                  * opaque region covers the whole output, but we have
961                  * to use XRGB as the KMS format code. */
962                 pixman_region32_init_rect(&r, 0, 0,
963                                           output->base.width,
964                                           output->base.height);
965                 pixman_region32_subtract(&r, &r, &es->opaque);
966
967                 if (!pixman_region32_not_empty(&r))
968                         format = GBM_FORMAT_XRGB8888;
969
970                 pixman_region32_fini(&r);
971         }
972
973         if (output->gbm_format == format)
974                 return format;
975
976         return 0;
977 }
978
979 static struct weston_plane *
980 drm_output_prepare_scanout_view(struct drm_output *output,
981                                 struct weston_view *ev)
982 {
983         struct drm_backend *b = to_drm_backend(output->base.compositor);
984         struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
985         struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
986         struct gbm_bo *bo;
987         uint32_t format;
988
989         /* Don't import buffers which span multiple outputs. */
990         if (ev->output_mask != (1u << output->base.id))
991                 return NULL;
992
993         /* We use GBM to import buffers. */
994         if (b->gbm == NULL)
995                 return NULL;
996
997         if (buffer == NULL)
998                 return NULL;
999         if (wl_shm_buffer_get(buffer->resource))
1000                 return NULL;
1001
1002         /* Make sure our view is exactly compatible with the output. */
1003         if (ev->geometry.x != output->base.x ||
1004             ev->geometry.y != output->base.y)
1005                 return NULL;
1006         if (buffer->width != output->base.current_mode->width ||
1007             buffer->height != output->base.current_mode->height)
1008                 return NULL;
1009
1010         if (ev->transform.enabled)
1011                 return NULL;
1012         if (ev->geometry.scissor_enabled)
1013                 return NULL;
1014         if (viewport->buffer.transform != output->base.transform)
1015                 return NULL;
1016         if (viewport->buffer.scale != output->base.current_scale)
1017                 return NULL;
1018         if (!drm_view_transform_supported(ev))
1019                 return NULL;
1020
1021         if (ev->alpha != 1.0f)
1022                 return NULL;
1023
1024         bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_WL_BUFFER,
1025                            buffer->resource, GBM_BO_USE_SCANOUT);
1026
1027         /* Unable to use the buffer for scanout */
1028         if (!bo)
1029                 return NULL;
1030
1031         format = drm_output_check_scanout_format(output, ev->surface, bo);
1032         if (format == 0) {
1033                 gbm_bo_destroy(bo);
1034                 return NULL;
1035         }
1036
1037         output->fb_pending = drm_fb_get_from_bo(bo, b, format, BUFFER_CLIENT);
1038         if (!output->fb_pending) {
1039                 gbm_bo_destroy(bo);
1040                 return NULL;
1041         }
1042
1043         drm_fb_set_buffer(output->fb_pending, buffer);
1044
1045         return &output->scanout_plane;
1046 }
1047
1048 static struct drm_fb *
1049 drm_output_render_gl(struct drm_output *output, pixman_region32_t *damage)
1050 {
1051         struct drm_backend *b = to_drm_backend(output->base.compositor);
1052         struct gbm_bo *bo;
1053         struct drm_fb *ret;
1054
1055         output->base.compositor->renderer->repaint_output(&output->base,
1056                                                           damage);
1057
1058         bo = gbm_surface_lock_front_buffer(output->gbm_surface);
1059         if (!bo) {
1060                 weston_log("failed to lock front buffer: %m\n");
1061                 return NULL;
1062         }
1063
1064         ret = drm_fb_get_from_bo(bo, b, output->gbm_format, BUFFER_GBM_SURFACE);
1065         if (!ret) {
1066                 weston_log("failed to get drm_fb for bo\n");
1067                 gbm_surface_release_buffer(output->gbm_surface, bo);
1068                 return NULL;
1069         }
1070         ret->gbm_surface = output->gbm_surface;
1071
1072         return ret;
1073 }
1074
1075 static struct drm_fb *
1076 drm_output_render_pixman(struct drm_output *output, pixman_region32_t *damage)
1077 {
1078         struct weston_compositor *ec = output->base.compositor;
1079         pixman_region32_t total_damage, previous_damage;
1080
1081         pixman_region32_init(&total_damage);
1082         pixman_region32_init(&previous_damage);
1083
1084         pixman_region32_copy(&previous_damage, damage);
1085
1086         pixman_region32_union(&total_damage, damage, &output->previous_damage);
1087         pixman_region32_copy(&output->previous_damage, &previous_damage);
1088
1089         output->current_image ^= 1;
1090
1091         pixman_renderer_output_set_buffer(&output->base,
1092                                           output->image[output->current_image]);
1093
1094         ec->renderer->repaint_output(&output->base, &total_damage);
1095
1096         pixman_region32_fini(&total_damage);
1097         pixman_region32_fini(&previous_damage);
1098
1099         return drm_fb_ref(output->dumb[output->current_image]);
1100 }
1101
1102 static void
1103 drm_output_render(struct drm_output *output, pixman_region32_t *damage)
1104 {
1105         struct weston_compositor *c = output->base.compositor;
1106         struct drm_backend *b = to_drm_backend(c);
1107         struct drm_fb *fb;
1108
1109         /* If we already have a client buffer promoted to scanout, then we don't
1110          * want to render. */
1111         if (output->fb_pending)
1112                 return;
1113
1114         if (b->use_pixman)
1115                 fb = drm_output_render_pixman(output, damage);
1116         else
1117                 fb = drm_output_render_gl(output, damage);
1118
1119         if (!fb)
1120                 return;
1121         output->fb_pending = fb;
1122
1123         pixman_region32_subtract(&c->primary_plane.damage,
1124                                  &c->primary_plane.damage, damage);
1125 }
1126
1127 static void
1128 drm_output_set_gamma(struct weston_output *output_base,
1129                      uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b)
1130 {
1131         int rc;
1132         struct drm_output *output = to_drm_output(output_base);
1133         struct drm_backend *backend =
1134                 to_drm_backend(output->base.compositor);
1135
1136         /* check */
1137         if (output_base->gamma_size != size)
1138                 return;
1139         if (!output->original_crtc)
1140                 return;
1141
1142         rc = drmModeCrtcSetGamma(backend->drm.fd,
1143                                  output->crtc_id,
1144                                  size, r, g, b);
1145         if (rc)
1146                 weston_log("set gamma failed: %m\n");
1147 }
1148
1149 /* Determine the type of vblank synchronization to use for the output.
1150  *
1151  * The pipe parameter indicates which CRTC is in use.  Knowing this, we
1152  * can determine which vblank sequence type to use for it.  Traditional
1153  * cards had only two CRTCs, with CRTC 0 using no special flags, and
1154  * CRTC 1 using DRM_VBLANK_SECONDARY.  The first bit of the pipe
1155  * parameter indicates this.
1156  *
1157  * Bits 1-5 of the pipe parameter are 5 bit wide pipe number between
1158  * 0-31.  If this is non-zero it indicates we're dealing with a
1159  * multi-gpu situation and we need to calculate the vblank sync
1160  * using DRM_BLANK_HIGH_CRTC_MASK.
1161  */
1162 static unsigned int
1163 drm_waitvblank_pipe(struct drm_output *output)
1164 {
1165         if (output->pipe > 1)
1166                 return (output->pipe << DRM_VBLANK_HIGH_CRTC_SHIFT) &
1167                                 DRM_VBLANK_HIGH_CRTC_MASK;
1168         else if (output->pipe > 0)
1169                 return DRM_VBLANK_SECONDARY;
1170         else
1171                 return 0;
1172 }
1173
1174 static int
1175 drm_output_repaint(struct weston_output *output_base,
1176                    pixman_region32_t *damage,
1177                    void *repaint_data)
1178 {
1179         struct drm_output *output = to_drm_output(output_base);
1180         struct drm_backend *backend =
1181                 to_drm_backend(output->base.compositor);
1182         struct drm_plane *p;
1183         struct drm_mode *mode;
1184         int ret = 0;
1185
1186         if (output->disable_pending || output->destroy_pending)
1187                 return -1;
1188
1189         assert(!output->fb_last);
1190
1191         /* If disable_planes is set then assign_planes() wasn't
1192          * called for this render, so we could still have a stale
1193          * cursor plane set up.
1194          */
1195         if (output->base.disable_planes) {
1196                 output->cursor_view = NULL;
1197                 output->cursor_plane.x = INT32_MIN;
1198                 output->cursor_plane.y = INT32_MIN;
1199         }
1200
1201         drm_output_render(output, damage);
1202         if (!output->fb_pending)
1203                 return -1;
1204
1205         mode = container_of(output->base.current_mode, struct drm_mode, base);
1206         if (output->state_invalid || !output->fb_current ||
1207             output->fb_current->stride != output->fb_pending->stride) {
1208                 ret = drmModeSetCrtc(backend->drm.fd, output->crtc_id,
1209                                      output->fb_pending->fb_id, 0, 0,
1210                                      &output->connector_id, 1,
1211                                      &mode->mode_info);
1212                 if (ret) {
1213                         weston_log("set mode failed: %m\n");
1214                         goto err_pageflip;
1215                 }
1216                 output_base->set_dpms(output_base, WESTON_DPMS_ON);
1217
1218                 output->state_invalid = false;
1219         }
1220
1221         if (drmModePageFlip(backend->drm.fd, output->crtc_id,
1222                             output->fb_pending->fb_id,
1223                             DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
1224                 weston_log("queueing pageflip failed: %m\n");
1225                 goto err_pageflip;
1226         }
1227
1228         output->fb_last = output->fb_current;
1229         output->fb_current = output->fb_pending;
1230         output->fb_pending = NULL;
1231
1232         assert(!output->page_flip_pending);
1233         output->page_flip_pending = 1;
1234
1235         if (output->pageflip_timer)
1236                 wl_event_source_timer_update(output->pageflip_timer,
1237                                              backend->pageflip_timeout);
1238
1239         drm_output_set_cursor(output);
1240
1241         /*
1242          * Now, update all the sprite surfaces
1243          */
1244         wl_list_for_each(p, &backend->plane_list, link) {
1245                 uint32_t flags = 0, fb_id = 0;
1246                 drmVBlank vbl = {
1247                         .request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT,
1248                         .request.sequence = 1,
1249                 };
1250
1251                 if (p->type != WDRM_PLANE_TYPE_OVERLAY)
1252                         continue;
1253
1254                 if ((!p->fb_current && !p->fb_pending) ||
1255                     !drm_plane_crtc_supported(output, p))
1256                         continue;
1257
1258                 if (p->fb_pending && !backend->sprites_hidden)
1259                         fb_id = p->fb_pending->fb_id;
1260
1261                 ret = drmModeSetPlane(backend->drm.fd, p->plane_id,
1262                                       output->crtc_id, fb_id, flags,
1263                                       p->dest_x, p->dest_y,
1264                                       p->dest_w, p->dest_h,
1265                                       p->src_x, p->src_y,
1266                                       p->src_w, p->src_h);
1267                 if (ret)
1268                         weston_log("setplane failed: %d: %s\n",
1269                                 ret, strerror(errno));
1270
1271                 vbl.request.type |= drm_waitvblank_pipe(output);
1272
1273                 /*
1274                  * Queue a vblank signal so we know when the surface
1275                  * becomes active on the display or has been replaced.
1276                  */
1277                 vbl.request.signal = (unsigned long) p;
1278                 ret = drmWaitVBlank(backend->drm.fd, &vbl);
1279                 if (ret) {
1280                         weston_log("vblank event request failed: %d: %s\n",
1281                                 ret, strerror(errno));
1282                 }
1283
1284                 p->output = output;
1285                 p->fb_last = p->fb_current;
1286                 p->fb_current = p->fb_pending;
1287                 p->fb_pending = NULL;
1288                 output->vblank_pending++;
1289         }
1290
1291         return 0;
1292
1293 err_pageflip:
1294         output->cursor_view = NULL;
1295         if (output->fb_pending) {
1296                 drm_fb_unref(output->fb_pending);
1297                 output->fb_pending = NULL;
1298         }
1299
1300         return -1;
1301 }
1302
1303 static void
1304 drm_output_start_repaint_loop(struct weston_output *output_base)
1305 {
1306         struct drm_output *output = to_drm_output(output_base);
1307         struct drm_backend *backend =
1308                 to_drm_backend(output_base->compositor);
1309         uint32_t fb_id;
1310         struct timespec ts, tnow;
1311         struct timespec vbl2now;
1312         int64_t refresh_nsec;
1313         int ret;
1314         drmVBlank vbl = {
1315                 .request.type = DRM_VBLANK_RELATIVE,
1316                 .request.sequence = 0,
1317                 .request.signal = 0,
1318         };
1319
1320         if (output->disable_pending || output->destroy_pending)
1321                 return;
1322
1323         if (!output->fb_current) {
1324                 /* We can't page flip if there's no mode set */
1325                 goto finish_frame;
1326         }
1327
1328         /* Need to smash all state in from scratch; current timings might not
1329          * be what we want, page flip might not work, etc.
1330          */
1331         if (output->state_invalid)
1332                 goto finish_frame;
1333
1334         /* Try to get current msc and timestamp via instant query */
1335         vbl.request.type |= drm_waitvblank_pipe(output);
1336         ret = drmWaitVBlank(backend->drm.fd, &vbl);
1337
1338         /* Error ret or zero timestamp means failure to get valid timestamp */
1339         if ((ret == 0) && (vbl.reply.tval_sec > 0 || vbl.reply.tval_usec > 0)) {
1340                 ts.tv_sec = vbl.reply.tval_sec;
1341                 ts.tv_nsec = vbl.reply.tval_usec * 1000;
1342
1343                 /* Valid timestamp for most recent vblank - not stale?
1344                  * Stale ts could happen on Linux 3.17+, so make sure it
1345                  * is not older than 1 refresh duration since now.
1346                  */
1347                 weston_compositor_read_presentation_clock(backend->compositor,
1348                                                           &tnow);
1349                 timespec_sub(&vbl2now, &tnow, &ts);
1350                 refresh_nsec =
1351                         millihz_to_nsec(output->base.current_mode->refresh);
1352                 if (timespec_to_nsec(&vbl2now) < refresh_nsec) {
1353                         drm_output_update_msc(output, vbl.reply.sequence);
1354                         weston_output_finish_frame(output_base, &ts,
1355                                                 WP_PRESENTATION_FEEDBACK_INVALID);
1356                         return;
1357                 }
1358         }
1359
1360         /* Immediate query didn't provide valid timestamp.
1361          * Use pageflip fallback.
1362          */
1363         fb_id = output->fb_current->fb_id;
1364
1365         assert(!output->page_flip_pending);
1366         assert(!output->fb_last);
1367
1368         if (drmModePageFlip(backend->drm.fd, output->crtc_id, fb_id,
1369                             DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
1370                 weston_log("queueing pageflip failed: %m\n");
1371                 goto finish_frame;
1372         }
1373
1374         if (output->pageflip_timer)
1375                 wl_event_source_timer_update(output->pageflip_timer,
1376                                              backend->pageflip_timeout);
1377
1378         output->fb_last = drm_fb_ref(output->fb_current);
1379         output->page_flip_pending = 1;
1380
1381         return;
1382
1383 finish_frame:
1384         /* if we cannot page-flip, immediately finish frame */
1385         weston_output_finish_frame(output_base, NULL,
1386                                    WP_PRESENTATION_FEEDBACK_INVALID);
1387 }
1388
1389 static void
1390 drm_output_update_msc(struct drm_output *output, unsigned int seq)
1391 {
1392         uint64_t msc_hi = output->base.msc >> 32;
1393
1394         if (seq < (output->base.msc & 0xffffffff))
1395                 msc_hi++;
1396
1397         output->base.msc = (msc_hi << 32) + seq;
1398 }
1399
1400 static void
1401 vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec,
1402                void *data)
1403 {
1404         struct drm_plane *s = (struct drm_plane *)data;
1405         struct drm_output *output = s->output;
1406         struct timespec ts;
1407         uint32_t flags = WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION |
1408                          WP_PRESENTATION_FEEDBACK_KIND_HW_CLOCK;
1409
1410         drm_output_update_msc(output, frame);
1411         output->vblank_pending--;
1412         assert(output->vblank_pending >= 0);
1413
1414         assert(s->fb_last || s->fb_current);
1415         drm_fb_unref(s->fb_last);
1416         s->fb_last = NULL;
1417
1418         if (!output->page_flip_pending && !output->vblank_pending) {
1419                 /* Stop the pageflip timer instead of rearming it here */
1420                 if (output->pageflip_timer)
1421                         wl_event_source_timer_update(output->pageflip_timer, 0);
1422
1423                 ts.tv_sec = sec;
1424                 ts.tv_nsec = usec * 1000;
1425                 weston_output_finish_frame(&output->base, &ts, flags);
1426         }
1427 }
1428
1429 static void
1430 drm_output_destroy(struct weston_output *base);
1431
1432 static void
1433 page_flip_handler(int fd, unsigned int frame,
1434                   unsigned int sec, unsigned int usec, void *data)
1435 {
1436         struct drm_output *output = data;
1437         struct timespec ts;
1438         uint32_t flags = WP_PRESENTATION_FEEDBACK_KIND_VSYNC |
1439                          WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION |
1440                          WP_PRESENTATION_FEEDBACK_KIND_HW_CLOCK;
1441
1442         drm_output_update_msc(output, frame);
1443
1444         assert(output->page_flip_pending);
1445         output->page_flip_pending = 0;
1446
1447         drm_fb_unref(output->fb_last);
1448         output->fb_last = NULL;
1449
1450         if (output->destroy_pending)
1451                 drm_output_destroy(&output->base);
1452         else if (output->disable_pending)
1453                 weston_output_disable(&output->base);
1454         else if (!output->vblank_pending) {
1455                 /* Stop the pageflip timer instead of rearming it here */
1456                 if (output->pageflip_timer)
1457                         wl_event_source_timer_update(output->pageflip_timer, 0);
1458
1459                 ts.tv_sec = sec;
1460                 ts.tv_nsec = usec * 1000;
1461                 weston_output_finish_frame(&output->base, &ts, flags);
1462
1463                 /* We can't call this from frame_notify, because the output's
1464                  * repaint needed flag is cleared just after that */
1465                 if (output->recorder)
1466                         weston_output_schedule_repaint(&output->base);
1467         }
1468 }
1469
1470 /**
1471  * Begin a new repaint cycle
1472  *
1473  * Called by the core compositor at the beginning of a repaint cycle.
1474  */
1475 static void *
1476 drm_repaint_begin(struct weston_compositor *compositor)
1477 {
1478         struct drm_backend *b = to_drm_backend(compositor);
1479         struct drm_pending_state *ret;
1480
1481         ret = drm_pending_state_alloc(b);
1482         b->repaint_data = ret;
1483
1484         return ret;
1485 }
1486
1487 /**
1488  * Flush a repaint set
1489  *
1490  * Called by the core compositor when a repaint cycle has been completed
1491  * and should be flushed.
1492  */
1493 static void
1494 drm_repaint_flush(struct weston_compositor *compositor, void *repaint_data)
1495 {
1496         struct drm_backend *b = to_drm_backend(compositor);
1497         struct drm_pending_state *pending_state = repaint_data;
1498
1499         drm_pending_state_free(pending_state);
1500         b->repaint_data = NULL;
1501 }
1502
1503 /**
1504  * Cancel a repaint set
1505  *
1506  * Called by the core compositor when a repaint has finished, so the data
1507  * held across the repaint cycle should be discarded.
1508  */
1509 static void
1510 drm_repaint_cancel(struct weston_compositor *compositor, void *repaint_data)
1511 {
1512         struct drm_backend *b = to_drm_backend(compositor);
1513         struct drm_pending_state *pending_state = repaint_data;
1514
1515         drm_pending_state_free(pending_state);
1516         b->repaint_data = NULL;
1517 }
1518
1519 static uint32_t
1520 drm_output_check_plane_format(struct drm_plane *p,
1521                                struct weston_view *ev, struct gbm_bo *bo)
1522 {
1523         uint32_t i, format;
1524
1525         format = gbm_bo_get_format(bo);
1526
1527         if (format == GBM_FORMAT_ARGB8888) {
1528                 pixman_region32_t r;
1529
1530                 pixman_region32_init_rect(&r, 0, 0,
1531                                           ev->surface->width,
1532                                           ev->surface->height);
1533                 pixman_region32_subtract(&r, &r, &ev->surface->opaque);
1534
1535                 if (!pixman_region32_not_empty(&r))
1536                         format = GBM_FORMAT_XRGB8888;
1537
1538                 pixman_region32_fini(&r);
1539         }
1540
1541         for (i = 0; i < p->count_formats; i++)
1542                 if (p->formats[i] == format)
1543                         return format;
1544
1545         return 0;
1546 }
1547
1548 static struct weston_plane *
1549 drm_output_prepare_overlay_view(struct drm_output *output,
1550                                 struct weston_view *ev)
1551 {
1552         struct weston_compositor *ec = output->base.compositor;
1553         struct drm_backend *b = to_drm_backend(ec);
1554         struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
1555         struct wl_resource *buffer_resource;
1556         struct drm_plane *p;
1557         struct linux_dmabuf_buffer *dmabuf;
1558         int found = 0;
1559         struct gbm_bo *bo;
1560         pixman_region32_t dest_rect, src_rect;
1561         pixman_box32_t *box, tbox;
1562         uint32_t format;
1563         wl_fixed_t sx1, sy1, sx2, sy2;
1564
1565         if (b->sprites_are_broken)
1566                 return NULL;
1567
1568         /* Don't import buffers which span multiple outputs. */
1569         if (ev->output_mask != (1u << output->base.id))
1570                 return NULL;
1571
1572         /* We can only import GBM buffers. */
1573         if (b->gbm == NULL)
1574                 return NULL;
1575
1576         if (ev->surface->buffer_ref.buffer == NULL)
1577                 return NULL;
1578         buffer_resource = ev->surface->buffer_ref.buffer->resource;
1579         if (wl_shm_buffer_get(buffer_resource))
1580                 return NULL;
1581
1582         if (viewport->buffer.transform != output->base.transform)
1583                 return NULL;
1584         if (viewport->buffer.scale != output->base.current_scale)
1585                 return NULL;
1586         if (!drm_view_transform_supported(ev))
1587                 return NULL;
1588
1589         if (ev->alpha != 1.0f)
1590                 return NULL;
1591
1592         wl_list_for_each(p, &b->plane_list, link) {
1593                 if (p->type != WDRM_PLANE_TYPE_OVERLAY)
1594                         continue;
1595
1596                 if (!drm_plane_crtc_supported(output, p))
1597                         continue;
1598
1599                 if (!p->fb_pending) {
1600                         found = 1;
1601                         break;
1602                 }
1603         }
1604
1605         /* No sprites available */
1606         if (!found)
1607                 return NULL;
1608
1609         if ((dmabuf = linux_dmabuf_buffer_get(buffer_resource))) {
1610 #ifdef HAVE_GBM_FD_IMPORT
1611                 /* XXX: TODO:
1612                  *
1613                  * Use AddFB2 directly, do not go via GBM.
1614                  * Add support for multiplanar formats.
1615                  * Both require refactoring in the DRM-backend to
1616                  * support a mix of gbm_bos and drmfbs.
1617                  */
1618                 struct gbm_import_fd_data gbm_dmabuf = {
1619                         .fd     = dmabuf->attributes.fd[0],
1620                         .width  = dmabuf->attributes.width,
1621                         .height = dmabuf->attributes.height,
1622                         .stride = dmabuf->attributes.stride[0],
1623                         .format = dmabuf->attributes.format
1624                 };
1625
1626                 /* XXX: TODO:
1627                  *
1628                  * Currently the buffer is rejected if any dmabuf attribute
1629                  * flag is set.  This keeps us from passing an inverted /
1630                  * interlaced / bottom-first buffer (or any other type that may
1631                  * be added in the future) through to an overlay.  Ultimately,
1632                  * these types of buffers should be handled through buffer
1633                  * transforms and not as spot-checks requiring specific
1634                  * knowledge. */
1635                 if (dmabuf->attributes.n_planes != 1 ||
1636                     dmabuf->attributes.offset[0] != 0 ||
1637                     dmabuf->attributes.flags)
1638                         return NULL;
1639
1640                 bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_FD, &gbm_dmabuf,
1641                                    GBM_BO_USE_SCANOUT);
1642 #else
1643                 return NULL;
1644 #endif
1645         } else {
1646                 bo = gbm_bo_import(b->gbm, GBM_BO_IMPORT_WL_BUFFER,
1647                                    buffer_resource, GBM_BO_USE_SCANOUT);
1648         }
1649         if (!bo)
1650                 return NULL;
1651
1652         format = drm_output_check_plane_format(p, ev, bo);
1653         if (format == 0) {
1654                 gbm_bo_destroy(bo);
1655                 return NULL;
1656         }
1657
1658         p->fb_pending = drm_fb_get_from_bo(bo, b, format, BUFFER_CLIENT);
1659         if (!p->fb_pending) {
1660                 gbm_bo_destroy(bo);
1661                 return NULL;
1662         }
1663
1664         drm_fb_set_buffer(p->fb_pending, ev->surface->buffer_ref.buffer);
1665
1666         box = pixman_region32_extents(&ev->transform.boundingbox);
1667         p->base.x = box->x1;
1668         p->base.y = box->y1;
1669
1670         /*
1671          * Calculate the source & dest rects properly based on actual
1672          * position (note the caller has called weston_view_update_transform()
1673          * for us already).
1674          */
1675         pixman_region32_init(&dest_rect);
1676         pixman_region32_intersect(&dest_rect, &ev->transform.boundingbox,
1677                                   &output->base.region);
1678         pixman_region32_translate(&dest_rect, -output->base.x, -output->base.y);
1679         box = pixman_region32_extents(&dest_rect);
1680         tbox = weston_transformed_rect(output->base.width,
1681                                        output->base.height,
1682                                        output->base.transform,
1683                                        output->base.current_scale,
1684                                        *box);
1685         p->dest_x = tbox.x1;
1686         p->dest_y = tbox.y1;
1687         p->dest_w = tbox.x2 - tbox.x1;
1688         p->dest_h = tbox.y2 - tbox.y1;
1689         pixman_region32_fini(&dest_rect);
1690
1691         pixman_region32_init(&src_rect);
1692         pixman_region32_intersect(&src_rect, &ev->transform.boundingbox,
1693                                   &output->base.region);
1694         box = pixman_region32_extents(&src_rect);
1695
1696         weston_view_from_global_fixed(ev,
1697                                       wl_fixed_from_int(box->x1),
1698                                       wl_fixed_from_int(box->y1),
1699                                       &sx1, &sy1);
1700         weston_view_from_global_fixed(ev,
1701                                       wl_fixed_from_int(box->x2),
1702                                       wl_fixed_from_int(box->y2),
1703                                       &sx2, &sy2);
1704
1705         if (sx1 < 0)
1706                 sx1 = 0;
1707         if (sy1 < 0)
1708                 sy1 = 0;
1709         if (sx2 > wl_fixed_from_int(ev->surface->width))
1710                 sx2 = wl_fixed_from_int(ev->surface->width);
1711         if (sy2 > wl_fixed_from_int(ev->surface->height))
1712                 sy2 = wl_fixed_from_int(ev->surface->height);
1713
1714         tbox.x1 = sx1;
1715         tbox.y1 = sy1;
1716         tbox.x2 = sx2;
1717         tbox.y2 = sy2;
1718
1719         tbox = weston_transformed_rect(wl_fixed_from_int(ev->surface->width),
1720                                        wl_fixed_from_int(ev->surface->height),
1721                                        viewport->buffer.transform,
1722                                        viewport->buffer.scale,
1723                                        tbox);
1724
1725         p->src_x = tbox.x1 << 8;
1726         p->src_y = tbox.y1 << 8;
1727         p->src_w = (tbox.x2 - tbox.x1) << 8;
1728         p->src_h = (tbox.y2 - tbox.y1) << 8;
1729         pixman_region32_fini(&src_rect);
1730
1731         return &p->base;
1732 }
1733
1734 static struct weston_plane *
1735 drm_output_prepare_cursor_view(struct drm_output *output,
1736                                struct weston_view *ev)
1737 {
1738         struct drm_backend *b = to_drm_backend(output->base.compositor);
1739         struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
1740         struct wl_shm_buffer *shmbuf;
1741         float x, y;
1742
1743         if (b->cursors_are_broken)
1744                 return NULL;
1745
1746         if (output->cursor_view)
1747                 return NULL;
1748
1749         /* Don't import buffers which span multiple outputs. */
1750         if (ev->output_mask != (1u << output->base.id))
1751                 return NULL;
1752
1753         /* We use GBM to import SHM buffers. */
1754         if (b->gbm == NULL)
1755                 return NULL;
1756
1757         if (ev->surface->buffer_ref.buffer == NULL)
1758                 return NULL;
1759         shmbuf = wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource);
1760         if (!shmbuf)
1761                 return NULL;
1762         if (wl_shm_buffer_get_format(shmbuf) != WL_SHM_FORMAT_ARGB8888)
1763                 return NULL;
1764
1765         if (output->base.transform != WL_OUTPUT_TRANSFORM_NORMAL)
1766                 return NULL;
1767         if (ev->transform.enabled &&
1768             (ev->transform.matrix.type > WESTON_MATRIX_TRANSFORM_TRANSLATE))
1769                 return NULL;
1770         if (viewport->buffer.scale != output->base.current_scale)
1771                 return NULL;
1772         if (ev->geometry.scissor_enabled)
1773                 return NULL;
1774
1775         if (ev->surface->width > b->cursor_width ||
1776             ev->surface->height > b->cursor_height)
1777                 return NULL;
1778
1779         output->cursor_view = ev;
1780         weston_view_to_global_float(ev, 0, 0, &x, &y);
1781         output->cursor_plane.x = x;
1782         output->cursor_plane.y = y;
1783
1784         return &output->cursor_plane;
1785 }
1786
1787 /**
1788  * Update the image for the current cursor surface
1789  *
1790  * @param b DRM backend structure
1791  * @param bo GBM buffer object to write into
1792  * @param ev View to use for cursor image
1793  */
1794 static void
1795 cursor_bo_update(struct drm_backend *b, struct gbm_bo *bo,
1796                  struct weston_view *ev)
1797 {
1798         struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
1799         uint32_t buf[b->cursor_width * b->cursor_height];
1800         int32_t stride;
1801         uint8_t *s;
1802         int i;
1803
1804         assert(buffer && buffer->shm_buffer);
1805         assert(buffer->shm_buffer == wl_shm_buffer_get(buffer->resource));
1806         assert(ev->surface->width <= b->cursor_width);
1807         assert(ev->surface->height <= b->cursor_height);
1808
1809         memset(buf, 0, sizeof buf);
1810         stride = wl_shm_buffer_get_stride(buffer->shm_buffer);
1811         s = wl_shm_buffer_get_data(buffer->shm_buffer);
1812
1813         wl_shm_buffer_begin_access(buffer->shm_buffer);
1814         for (i = 0; i < ev->surface->height; i++)
1815                 memcpy(buf + i * b->cursor_width,
1816                        s + i * stride,
1817                        ev->surface->width * 4);
1818         wl_shm_buffer_end_access(buffer->shm_buffer);
1819
1820         if (gbm_bo_write(bo, buf, sizeof buf) < 0)
1821                 weston_log("failed update cursor: %m\n");
1822 }
1823
1824 static void
1825 drm_output_set_cursor(struct drm_output *output)
1826 {
1827         struct weston_view *ev = output->cursor_view;
1828         struct drm_backend *b = to_drm_backend(output->base.compositor);
1829         EGLint handle;
1830         struct gbm_bo *bo;
1831         float x, y;
1832
1833         if (ev == NULL) {
1834                 drmModeSetCursor(b->drm.fd, output->crtc_id, 0, 0, 0);
1835                 return;
1836         }
1837
1838         if (pixman_region32_not_empty(&output->cursor_plane.damage)) {
1839                 pixman_region32_fini(&output->cursor_plane.damage);
1840                 pixman_region32_init(&output->cursor_plane.damage);
1841                 output->current_cursor ^= 1;
1842                 bo = output->gbm_cursor_fb[output->current_cursor]->bo;
1843
1844                 cursor_bo_update(b, bo, ev);
1845                 handle = gbm_bo_get_handle(bo).s32;
1846                 if (drmModeSetCursor(b->drm.fd, output->crtc_id, handle,
1847                                 b->cursor_width, b->cursor_height)) {
1848                         weston_log("failed to set cursor: %m\n");
1849                         b->cursors_are_broken = 1;
1850                 }
1851         }
1852
1853         x = (output->cursor_plane.x - output->base.x) *
1854                 output->base.current_scale;
1855         y = (output->cursor_plane.y - output->base.y) *
1856                 output->base.current_scale;
1857
1858         if (drmModeMoveCursor(b->drm.fd, output->crtc_id, x, y)) {
1859                 weston_log("failed to move cursor: %m\n");
1860                 b->cursors_are_broken = 1;
1861         }
1862 }
1863
1864 static void
1865 drm_assign_planes(struct weston_output *output_base, void *repaint_data)
1866 {
1867         struct drm_backend *b = to_drm_backend(output_base->compositor);
1868         struct drm_output *output = to_drm_output(output_base);
1869         struct weston_view *ev, *next;
1870         pixman_region32_t overlap, surface_overlap;
1871         struct weston_plane *primary, *next_plane;
1872
1873         /*
1874          * Find a surface for each sprite in the output using some heuristics:
1875          * 1) size
1876          * 2) frequency of update
1877          * 3) opacity (though some hw might support alpha blending)
1878          * 4) clipping (this can be fixed with color keys)
1879          *
1880          * The idea is to save on blitting since this should save power.
1881          * If we can get a large video surface on the sprite for example,
1882          * the main display surface may not need to update at all, and
1883          * the client buffer can be used directly for the sprite surface
1884          * as we do for flipping full screen surfaces.
1885          */
1886         pixman_region32_init(&overlap);
1887         primary = &output_base->compositor->primary_plane;
1888
1889         output->cursor_view = NULL;
1890         output->cursor_plane.x = INT32_MIN;
1891         output->cursor_plane.y = INT32_MIN;
1892
1893         wl_list_for_each_safe(ev, next, &output_base->compositor->view_list, link) {
1894                 struct weston_surface *es = ev->surface;
1895
1896                 /* Test whether this buffer can ever go into a plane:
1897                  * non-shm, or small enough to be a cursor.
1898                  *
1899                  * Also, keep a reference when using the pixman renderer.
1900                  * That makes it possible to do a seamless switch to the GL
1901                  * renderer and since the pixman renderer keeps a reference
1902                  * to the buffer anyway, there is no side effects.
1903                  */
1904                 if (b->use_pixman ||
1905                     (es->buffer_ref.buffer &&
1906                     (!wl_shm_buffer_get(es->buffer_ref.buffer->resource) ||
1907                      (ev->surface->width <= b->cursor_width &&
1908                       ev->surface->height <= b->cursor_height))))
1909                         es->keep_buffer = true;
1910                 else
1911                         es->keep_buffer = false;
1912
1913                 pixman_region32_init(&surface_overlap);
1914                 pixman_region32_intersect(&surface_overlap, &overlap,
1915                                           &ev->transform.boundingbox);
1916
1917                 next_plane = NULL;
1918                 if (pixman_region32_not_empty(&surface_overlap))
1919                         next_plane = primary;
1920                 if (next_plane == NULL)
1921                         next_plane = drm_output_prepare_cursor_view(output, ev);
1922                 if (next_plane == NULL)
1923                         next_plane = drm_output_prepare_scanout_view(output, ev);
1924                 if (next_plane == NULL)
1925                         next_plane = drm_output_prepare_overlay_view(output, ev);
1926                 if (next_plane == NULL)
1927                         next_plane = primary;
1928
1929                 weston_view_move_to_plane(ev, next_plane);
1930
1931                 if (next_plane == primary)
1932                         pixman_region32_union(&overlap, &overlap,
1933                                               &ev->transform.boundingbox);
1934
1935                 if (next_plane == primary ||
1936                     next_plane == &output->cursor_plane) {
1937                         /* cursor plane involves a copy */
1938                         ev->psf_flags = 0;
1939                 } else {
1940                         /* All other planes are a direct scanout of a
1941                          * single client buffer.
1942                          */
1943                         ev->psf_flags = WP_PRESENTATION_FEEDBACK_KIND_ZERO_COPY;
1944                 }
1945
1946                 pixman_region32_fini(&surface_overlap);
1947         }
1948         pixman_region32_fini(&overlap);
1949 }
1950
1951 /**
1952  * Find the closest-matching mode for a given target
1953  *
1954  * Given a target mode, find the most suitable mode amongst the output's
1955  * current mode list to use, preferring the current mode if possible, to
1956  * avoid an expensive mode switch.
1957  *
1958  * @param output DRM output
1959  * @param target_mode Mode to attempt to match
1960  * @returns Pointer to a mode from the output's mode list
1961  */
1962 static struct drm_mode *
1963 choose_mode (struct drm_output *output, struct weston_mode *target_mode)
1964 {
1965         struct drm_mode *tmp_mode = NULL, *mode;
1966
1967         if (output->base.current_mode->width == target_mode->width &&
1968             output->base.current_mode->height == target_mode->height &&
1969             (output->base.current_mode->refresh == target_mode->refresh ||
1970              target_mode->refresh == 0))
1971                 return (struct drm_mode *)output->base.current_mode;
1972
1973         wl_list_for_each(mode, &output->base.mode_list, base.link) {
1974                 if (mode->mode_info.hdisplay == target_mode->width &&
1975                     mode->mode_info.vdisplay == target_mode->height) {
1976                         if (mode->base.refresh == target_mode->refresh ||
1977                             target_mode->refresh == 0) {
1978                                 return mode;
1979                         } else if (!tmp_mode)
1980                                 tmp_mode = mode;
1981                 }
1982         }
1983
1984         return tmp_mode;
1985 }
1986
1987 static int
1988 drm_output_init_egl(struct drm_output *output, struct drm_backend *b);
1989 static void
1990 drm_output_fini_egl(struct drm_output *output);
1991 static int
1992 drm_output_init_pixman(struct drm_output *output, struct drm_backend *b);
1993 static void
1994 drm_output_fini_pixman(struct drm_output *output);
1995
1996 static int
1997 drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mode)
1998 {
1999         struct drm_output *output;
2000         struct drm_mode *drm_mode;
2001         struct drm_backend *b;
2002
2003         if (output_base == NULL) {
2004                 weston_log("output is NULL.\n");
2005                 return -1;
2006         }
2007
2008         if (mode == NULL) {
2009                 weston_log("mode is NULL.\n");
2010                 return -1;
2011         }
2012
2013         b = to_drm_backend(output_base->compositor);
2014         output = to_drm_output(output_base);
2015         drm_mode  = choose_mode (output, mode);
2016
2017         if (!drm_mode) {
2018                 weston_log("%s, invalid resolution:%dx%d\n", __func__, mode->width, mode->height);
2019                 return -1;
2020         }
2021
2022         if (&drm_mode->base == output->base.current_mode)
2023                 return 0;
2024
2025         output->base.current_mode->flags = 0;
2026
2027         output->base.current_mode = &drm_mode->base;
2028         output->base.current_mode->flags =
2029                 WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
2030
2031         /* XXX: This drops our current buffer too early, before we've started
2032          *      displaying it. Ideally this should be much more atomic and
2033          *      integrated with a full repaint cycle, rather than doing a
2034          *      sledgehammer modeswitch first, and only later showing new
2035          *      content.
2036          */
2037         drm_fb_unref(output->fb_current);
2038         assert(!output->fb_last);
2039         assert(!output->fb_pending);
2040         output->fb_last = output->fb_current = NULL;
2041
2042         if (b->use_pixman) {
2043                 drm_output_fini_pixman(output);
2044                 if (drm_output_init_pixman(output, b) < 0) {
2045                         weston_log("failed to init output pixman state with "
2046                                    "new mode\n");
2047                         return -1;
2048                 }
2049         } else {
2050                 drm_output_fini_egl(output);
2051                 if (drm_output_init_egl(output, b) < 0) {
2052                         weston_log("failed to init output egl state with "
2053                                    "new mode");
2054                         return -1;
2055                 }
2056         }
2057
2058         return 0;
2059 }
2060
2061 static int
2062 on_drm_input(int fd, uint32_t mask, void *data)
2063 {
2064         drmEventContext evctx;
2065
2066         memset(&evctx, 0, sizeof evctx);
2067         evctx.version = 2;
2068         evctx.page_flip_handler = page_flip_handler;
2069         evctx.vblank_handler = vblank_handler;
2070         drmHandleEvent(fd, &evctx);
2071
2072         return 1;
2073 }
2074
2075 static int
2076 init_kms_caps(struct drm_backend *b)
2077 {
2078         uint64_t cap;
2079         int ret;
2080         clockid_t clk_id;
2081
2082         weston_log("using %s\n", b->drm.filename);
2083
2084         ret = drmGetCap(b->drm.fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap);
2085         if (ret == 0 && cap == 1)
2086                 clk_id = CLOCK_MONOTONIC;
2087         else
2088                 clk_id = CLOCK_REALTIME;
2089
2090         if (weston_compositor_set_presentation_clock(b->compositor, clk_id) < 0) {
2091                 weston_log("Error: failed to set presentation clock %d.\n",
2092                            clk_id);
2093                 return -1;
2094         }
2095
2096         ret = drmGetCap(b->drm.fd, DRM_CAP_CURSOR_WIDTH, &cap);
2097         if (ret == 0)
2098                 b->cursor_width = cap;
2099         else
2100                 b->cursor_width = 64;
2101
2102         ret = drmGetCap(b->drm.fd, DRM_CAP_CURSOR_HEIGHT, &cap);
2103         if (ret == 0)
2104                 b->cursor_height = cap;
2105         else
2106                 b->cursor_height = 64;
2107
2108         ret = drmSetClientCap(b->drm.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
2109         b->universal_planes = (ret == 0);
2110         weston_log("DRM: %s universal planes\n",
2111                    b->universal_planes ? "supports" : "does not support");
2112
2113         return 0;
2114 }
2115
2116 static struct gbm_device *
2117 create_gbm_device(int fd)
2118 {
2119         struct gbm_device *gbm;
2120
2121         gl_renderer = weston_load_module("gl-renderer.so",
2122                                          "gl_renderer_interface");
2123         if (!gl_renderer)
2124                 return NULL;
2125
2126         /* GBM will load a dri driver, but even though they need symbols from
2127          * libglapi, in some version of Mesa they are not linked to it. Since
2128          * only the gl-renderer module links to it, the call above won't make
2129          * these symbols globally available, and loading the DRI driver fails.
2130          * Workaround this by dlopen()'ing libglapi with RTLD_GLOBAL. */
2131         dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL);
2132
2133         gbm = gbm_create_device(fd);
2134
2135         return gbm;
2136 }
2137
2138 /* When initializing EGL, if the preferred buffer format isn't available
2139  * we may be able to substitute an ARGB format for an XRGB one.
2140  *
2141  * This returns 0 if substitution isn't possible, but 0 might be a
2142  * legitimate format for other EGL platforms, so the caller is
2143  * responsible for checking for 0 before calling gl_renderer->create().
2144  *
2145  * This works around https://bugs.freedesktop.org/show_bug.cgi?id=89689
2146  * but it's entirely possible we'll see this again on other implementations.
2147  */
2148 static int
2149 fallback_format_for(uint32_t format)
2150 {
2151         switch (format) {
2152         case GBM_FORMAT_XRGB8888:
2153                 return GBM_FORMAT_ARGB8888;
2154         case GBM_FORMAT_XRGB2101010:
2155                 return GBM_FORMAT_ARGB2101010;
2156         default:
2157                 return 0;
2158         }
2159 }
2160
2161 static int
2162 drm_backend_create_gl_renderer(struct drm_backend *b)
2163 {
2164         EGLint format[3] = {
2165                 b->gbm_format,
2166                 fallback_format_for(b->gbm_format),
2167                 0,
2168         };
2169         int n_formats = 2;
2170
2171         if (format[1])
2172                 n_formats = 3;
2173         if (gl_renderer->display_create(b->compositor,
2174                                         EGL_PLATFORM_GBM_KHR,
2175                                         (void *)b->gbm,
2176                                         NULL,
2177                                         gl_renderer->opaque_attribs,
2178                                         format,
2179                                         n_formats) < 0) {
2180                 return -1;
2181         }
2182
2183         return 0;
2184 }
2185
2186 static int
2187 init_egl(struct drm_backend *b)
2188 {
2189         b->gbm = create_gbm_device(b->drm.fd);
2190
2191         if (!b->gbm)
2192                 return -1;
2193
2194         if (drm_backend_create_gl_renderer(b) < 0) {
2195                 gbm_device_destroy(b->gbm);
2196                 return -1;
2197         }
2198
2199         return 0;
2200 }
2201
2202 static int
2203 init_pixman(struct drm_backend *b)
2204 {
2205         return pixman_renderer_init(b->compositor);
2206 }
2207
2208 /**
2209  * Create a drm_plane for a hardware plane
2210  *
2211  * Creates one drm_plane structure for a hardware plane, and initialises its
2212  * properties and formats.
2213  *
2214  * This function does not add the plane to the list of usable planes in Weston
2215  * itself; the caller is responsible for this.
2216  *
2217  * Call drm_plane_destroy to clean up the plane.
2218  *
2219  * @param b DRM compositor backend
2220  * @param kplane DRM plane to create
2221  */
2222 static struct drm_plane *
2223 drm_plane_create(struct drm_backend *b, const drmModePlane *kplane)
2224 {
2225         struct drm_plane *plane;
2226         drmModeObjectProperties *props;
2227
2228         static struct drm_property_enum_info plane_type_enums[] = {
2229                 [WDRM_PLANE_TYPE_PRIMARY] = {
2230                         .name = "Primary",
2231                 },
2232                 [WDRM_PLANE_TYPE_OVERLAY] = {
2233                         .name = "Overlay",
2234                 },
2235                 [WDRM_PLANE_TYPE_CURSOR] = {
2236                         .name = "Cursor",
2237                 },
2238         };
2239         static const struct drm_property_info plane_props[] = {
2240                 [WDRM_PLANE_TYPE] = {
2241                         .name = "type",
2242                         .enum_values = plane_type_enums,
2243                         .num_enum_values = WDRM_PLANE_TYPE__COUNT,
2244                 },
2245         };
2246
2247         plane = zalloc(sizeof(*plane) + ((sizeof(uint32_t)) *
2248                                           kplane->count_formats));
2249         if (!plane) {
2250                 weston_log("%s: out of memory\n", __func__);
2251                 return NULL;
2252         }
2253
2254         plane->backend = b;
2255         plane->possible_crtcs = kplane->possible_crtcs;
2256         plane->plane_id = kplane->plane_id;
2257         plane->count_formats = kplane->count_formats;
2258         memcpy(plane->formats, kplane->formats,
2259                kplane->count_formats * sizeof(kplane->formats[0]));
2260
2261         props = drmModeObjectGetProperties(b->drm.fd, kplane->plane_id,
2262                                            DRM_MODE_OBJECT_PLANE);
2263         if (!props) {
2264                 weston_log("couldn't get plane properties\n");
2265                 free(plane);
2266                 return NULL;
2267         }
2268         drm_property_info_populate(b, plane_props, plane->props,
2269                                    WDRM_PLANE__COUNT, props);
2270         plane->type =
2271                 drm_property_get_value(&plane->props[WDRM_PLANE_TYPE],
2272                                        props,
2273                                        WDRM_PLANE_TYPE_OVERLAY);
2274         drmModeFreeObjectProperties(props);
2275
2276         weston_plane_init(&plane->base, b->compositor, 0, 0);
2277         wl_list_insert(&b->plane_list, &plane->link);
2278
2279         return plane;
2280 }
2281
2282 /**
2283  * Destroy one DRM plane
2284  *
2285  * Destroy a DRM plane, removing it from screen and releasing its retained
2286  * buffers in the process. The counterpart to drm_plane_create.
2287  *
2288  * @param plane Plane to deallocate (will be freed)
2289  */
2290 static void
2291 drm_plane_destroy(struct drm_plane *plane)
2292 {
2293         drmModeSetPlane(plane->backend->drm.fd, plane->plane_id, 0, 0, 0,
2294                         0, 0, 0, 0, 0, 0, 0, 0);
2295         assert(!plane->fb_last);
2296         assert(!plane->fb_pending);
2297         drm_property_info_free(plane->props, WDRM_PLANE__COUNT);
2298         drm_fb_unref(plane->fb_current);
2299         weston_plane_release(&plane->base);
2300         wl_list_remove(&plane->link);
2301         free(plane);
2302 }
2303
2304 /**
2305  * Initialise sprites (overlay planes)
2306  *
2307  * Walk the list of provided DRM planes, and add overlay planes.
2308  *
2309  * Call destroy_sprites to free these planes.
2310  *
2311  * @param b DRM compositor backend
2312  */
2313 static void
2314 create_sprites(struct drm_backend *b)
2315 {
2316         drmModePlaneRes *kplane_res;
2317         drmModePlane *kplane;
2318         struct drm_plane *drm_plane;
2319         uint32_t i;
2320
2321         kplane_res = drmModeGetPlaneResources(b->drm.fd);
2322         if (!kplane_res) {
2323                 weston_log("failed to get plane resources: %s\n",
2324                         strerror(errno));
2325                 return;
2326         }
2327
2328         for (i = 0; i < kplane_res->count_planes; i++) {
2329                 kplane = drmModeGetPlane(b->drm.fd, kplane_res->planes[i]);
2330                 if (!kplane)
2331                         continue;
2332
2333                 drm_plane = drm_plane_create(b, kplane);
2334                 drmModeFreePlane(kplane);
2335                 if (!drm_plane)
2336                         continue;
2337
2338                 if (drm_plane->type == WDRM_PLANE_TYPE_OVERLAY)
2339                         weston_compositor_stack_plane(b->compositor,
2340                                                       &drm_plane->base,
2341                                                       &b->compositor->primary_plane);
2342         }
2343
2344         drmModeFreePlaneResources(kplane_res);
2345 }
2346
2347 /**
2348  * Clean up sprites (overlay planes)
2349  *
2350  * The counterpart to create_sprites.
2351  *
2352  * @param b DRM compositor backend
2353  */
2354 static void
2355 destroy_sprites(struct drm_backend *b)
2356 {
2357         struct drm_plane *plane, *next;
2358
2359         wl_list_for_each_safe(plane, next, &b->plane_list, link)
2360                 drm_plane_destroy(plane);
2361 }
2362
2363 /**
2364  * Add a mode to output's mode list
2365  *
2366  * Copy the supplied DRM mode into a Weston mode structure, and add it to the
2367  * output's mode list.
2368  *
2369  * @param output DRM output to add mode to
2370  * @param info DRM mode structure to add
2371  * @returns Newly-allocated Weston/DRM mode structure
2372  */
2373 static struct drm_mode *
2374 drm_output_add_mode(struct drm_output *output, const drmModeModeInfo *info)
2375 {
2376         struct drm_mode *mode;
2377         uint64_t refresh;
2378
2379         mode = malloc(sizeof *mode);
2380         if (mode == NULL)
2381                 return NULL;
2382
2383         mode->base.flags = 0;
2384         mode->base.width = info->hdisplay;
2385         mode->base.height = info->vdisplay;
2386
2387         /* Calculate higher precision (mHz) refresh rate */
2388         refresh = (info->clock * 1000000LL / info->htotal +
2389                    info->vtotal / 2) / info->vtotal;
2390
2391         if (info->flags & DRM_MODE_FLAG_INTERLACE)
2392                 refresh *= 2;
2393         if (info->flags & DRM_MODE_FLAG_DBLSCAN)
2394                 refresh /= 2;
2395         if (info->vscan > 1)
2396             refresh /= info->vscan;
2397
2398         mode->base.refresh = refresh;
2399         mode->mode_info = *info;
2400
2401         if (info->type & DRM_MODE_TYPE_PREFERRED)
2402                 mode->base.flags |= WL_OUTPUT_MODE_PREFERRED;
2403
2404         wl_list_insert(output->base.mode_list.prev, &mode->base.link);
2405
2406         return mode;
2407 }
2408
2409 static int
2410 drm_subpixel_to_wayland(int drm_value)
2411 {
2412         switch (drm_value) {
2413         default:
2414         case DRM_MODE_SUBPIXEL_UNKNOWN:
2415                 return WL_OUTPUT_SUBPIXEL_UNKNOWN;
2416         case DRM_MODE_SUBPIXEL_NONE:
2417                 return WL_OUTPUT_SUBPIXEL_NONE;
2418         case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB:
2419                 return WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB;
2420         case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR:
2421                 return WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR;
2422         case DRM_MODE_SUBPIXEL_VERTICAL_RGB:
2423                 return WL_OUTPUT_SUBPIXEL_VERTICAL_RGB;
2424         case DRM_MODE_SUBPIXEL_VERTICAL_BGR:
2425                 return WL_OUTPUT_SUBPIXEL_VERTICAL_BGR;
2426         }
2427 }
2428
2429 /* returns a value between 0-255 range, where higher is brighter */
2430 static uint32_t
2431 drm_get_backlight(struct drm_output *output)
2432 {
2433         long brightness, max_brightness, norm;
2434
2435         brightness = backlight_get_brightness(output->backlight);
2436         max_brightness = backlight_get_max_brightness(output->backlight);
2437
2438         /* convert it on a scale of 0 to 255 */
2439         norm = (brightness * 255)/(max_brightness);
2440
2441         return (uint32_t) norm;
2442 }
2443
2444 /* values accepted are between 0-255 range */
2445 static void
2446 drm_set_backlight(struct weston_output *output_base, uint32_t value)
2447 {
2448         struct drm_output *output = to_drm_output(output_base);
2449         long max_brightness, new_brightness;
2450
2451         if (!output->backlight)
2452                 return;
2453
2454         if (value > 255)
2455                 return;
2456
2457         max_brightness = backlight_get_max_brightness(output->backlight);
2458
2459         /* get denormalized value */
2460         new_brightness = (value * max_brightness) / 255;
2461
2462         backlight_set_brightness(output->backlight, new_brightness);
2463 }
2464
2465 static void
2466 drm_set_dpms(struct weston_output *output_base, enum dpms_enum level)
2467 {
2468         struct drm_output *output = to_drm_output(output_base);
2469         struct weston_compositor *ec = output_base->compositor;
2470         struct drm_backend *b = to_drm_backend(ec);
2471         struct drm_property_info *prop =
2472                 &output->props_conn[WDRM_CONNECTOR_DPMS];
2473         int ret;
2474
2475         if (!prop->prop_id)
2476                 return;
2477
2478         ret = drmModeConnectorSetProperty(b->drm.fd, output->connector_id,
2479                                           prop->prop_id, level);
2480         if (ret) {
2481                 weston_log("DRM: DPMS: failed property set for %s\n",
2482                            output->base.name);
2483                 return;
2484         }
2485
2486         output->dpms = level;
2487 }
2488
2489 static const char * const connector_type_names[] = {
2490         [DRM_MODE_CONNECTOR_Unknown]     = "Unknown",
2491         [DRM_MODE_CONNECTOR_VGA]         = "VGA",
2492         [DRM_MODE_CONNECTOR_DVII]        = "DVI-I",
2493         [DRM_MODE_CONNECTOR_DVID]        = "DVI-D",
2494         [DRM_MODE_CONNECTOR_DVIA]        = "DVI-A",
2495         [DRM_MODE_CONNECTOR_Composite]   = "Composite",
2496         [DRM_MODE_CONNECTOR_SVIDEO]      = "SVIDEO",
2497         [DRM_MODE_CONNECTOR_LVDS]        = "LVDS",
2498         [DRM_MODE_CONNECTOR_Component]   = "Component",
2499         [DRM_MODE_CONNECTOR_9PinDIN]     = "DIN",
2500         [DRM_MODE_CONNECTOR_DisplayPort] = "DP",
2501         [DRM_MODE_CONNECTOR_HDMIA]       = "HDMI-A",
2502         [DRM_MODE_CONNECTOR_HDMIB]       = "HDMI-B",
2503         [DRM_MODE_CONNECTOR_TV]          = "TV",
2504         [DRM_MODE_CONNECTOR_eDP]         = "eDP",
2505 #ifdef DRM_MODE_CONNECTOR_DSI
2506         [DRM_MODE_CONNECTOR_VIRTUAL]     = "Virtual",
2507         [DRM_MODE_CONNECTOR_DSI]         = "DSI",
2508 #endif
2509 };
2510
2511 /** Create a name given a DRM connector
2512  *
2513  * \param con The DRM connector whose type and id form the name.
2514  * \return A newly allocate string, or NULL on error. Must be free()'d
2515  * after use.
2516  *
2517  * The name does not identify the DRM display device.
2518  */
2519 static char *
2520 make_connector_name(const drmModeConnector *con)
2521 {
2522         char *name;
2523         const char *type_name = NULL;
2524         int ret;
2525
2526         if (con->connector_type < ARRAY_LENGTH(connector_type_names))
2527                 type_name = connector_type_names[con->connector_type];
2528
2529         if (!type_name)
2530                 type_name = "UNNAMED";
2531
2532         ret = asprintf(&name, "%s-%d", type_name, con->connector_type_id);
2533         if (ret < 0)
2534                 return NULL;
2535
2536         return name;
2537 }
2538
2539 static int
2540 find_crtc_for_connector(struct drm_backend *b,
2541                         drmModeRes *resources, drmModeConnector *connector)
2542 {
2543         drmModeEncoder *encoder;
2544         int i, j;
2545         int ret = -1;
2546
2547         for (j = 0; j < connector->count_encoders; j++) {
2548                 uint32_t possible_crtcs, encoder_id, crtc_id;
2549
2550                 encoder = drmModeGetEncoder(b->drm.fd, connector->encoders[j]);
2551                 if (encoder == NULL) {
2552                         weston_log("Failed to get encoder.\n");
2553                         continue;
2554                 }
2555                 encoder_id = encoder->encoder_id;
2556                 possible_crtcs = encoder->possible_crtcs;
2557                 crtc_id = encoder->crtc_id;
2558                 drmModeFreeEncoder(encoder);
2559
2560                 for (i = 0; i < resources->count_crtcs; i++) {
2561                         if (!(possible_crtcs & (1 << i)))
2562                                 continue;
2563
2564                         if (drm_output_find_by_crtc(b, resources->crtcs[i]))
2565                                 continue;
2566
2567                         /* Try to preserve the existing
2568                          * CRTC -> encoder -> connector routing; it makes
2569                          * initialisation faster, and also since we have a
2570                          * very dumb picking algorithm, may preserve a better
2571                          * choice. */
2572                         if (!connector->encoder_id ||
2573                             (encoder_id == connector->encoder_id &&
2574                              crtc_id == resources->crtcs[i]))
2575                                 return i;
2576
2577                         ret = i;
2578                 }
2579         }
2580
2581         return ret;
2582 }
2583
2584 static void drm_output_fini_cursor_egl(struct drm_output *output)
2585 {
2586         unsigned int i;
2587
2588         for (i = 0; i < ARRAY_LENGTH(output->gbm_cursor_fb); i++) {
2589                 drm_fb_unref(output->gbm_cursor_fb[i]);
2590                 output->gbm_cursor_fb[i] = NULL;
2591         }
2592 }
2593
2594 static int
2595 drm_output_init_cursor_egl(struct drm_output *output, struct drm_backend *b)
2596 {
2597         unsigned int i;
2598
2599         for (i = 0; i < ARRAY_LENGTH(output->gbm_cursor_fb); i++) {
2600                 struct gbm_bo *bo;
2601
2602                 bo = gbm_bo_create(b->gbm, b->cursor_width, b->cursor_height,
2603                                    GBM_FORMAT_ARGB8888,
2604                                    GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
2605                 if (!bo)
2606                         goto err;
2607
2608                 output->gbm_cursor_fb[i] =
2609                         drm_fb_get_from_bo(bo, b, GBM_FORMAT_ARGB8888,
2610                                            BUFFER_CURSOR);
2611                 if (!output->gbm_cursor_fb[i]) {
2612                         gbm_bo_destroy(bo);
2613                         goto err;
2614                 }
2615         }
2616
2617         return 0;
2618
2619 err:
2620         weston_log("cursor buffers unavailable, using gl cursors\n");
2621         b->cursors_are_broken = 1;
2622         drm_output_fini_cursor_egl(output);
2623         return -1;
2624 }
2625
2626 /* Init output state that depends on gl or gbm */
2627 static int
2628 drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
2629 {
2630         EGLint format[2] = {
2631                 output->gbm_format,
2632                 fallback_format_for(output->gbm_format),
2633         };
2634         int n_formats = 1;
2635
2636         output->gbm_surface = gbm_surface_create(b->gbm,
2637                                              output->base.current_mode->width,
2638                                              output->base.current_mode->height,
2639                                              format[0],
2640                                              GBM_BO_USE_SCANOUT |
2641                                              GBM_BO_USE_RENDERING);
2642         if (!output->gbm_surface) {
2643                 weston_log("failed to create gbm surface\n");
2644                 return -1;
2645         }
2646
2647         if (format[1])
2648                 n_formats = 2;
2649         if (gl_renderer->output_window_create(&output->base,
2650                                               (EGLNativeWindowType)output->gbm_surface,
2651                                               output->gbm_surface,
2652                                               gl_renderer->opaque_attribs,
2653                                               format,
2654                                               n_formats) < 0) {
2655                 weston_log("failed to create gl renderer output state\n");
2656                 gbm_surface_destroy(output->gbm_surface);
2657                 return -1;
2658         }
2659
2660         drm_output_init_cursor_egl(output, b);
2661
2662         return 0;
2663 }
2664
2665 static void
2666 drm_output_fini_egl(struct drm_output *output)
2667 {
2668         gl_renderer->output_destroy(&output->base);
2669         gbm_surface_destroy(output->gbm_surface);
2670         drm_output_fini_cursor_egl(output);
2671 }
2672
2673 static int
2674 drm_output_init_pixman(struct drm_output *output, struct drm_backend *b)
2675 {
2676         int w = output->base.current_mode->width;
2677         int h = output->base.current_mode->height;
2678         uint32_t format = output->gbm_format;
2679         uint32_t pixman_format;
2680         unsigned int i;
2681
2682         switch (format) {
2683                 case GBM_FORMAT_XRGB8888:
2684                         pixman_format = PIXMAN_x8r8g8b8;
2685                         break;
2686                 case GBM_FORMAT_RGB565:
2687                         pixman_format = PIXMAN_r5g6b5;
2688                         break;
2689                 default:
2690                         weston_log("Unsupported pixman format 0x%x\n", format);
2691                         return -1;
2692         }
2693
2694         /* FIXME error checking */
2695         for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
2696                 output->dumb[i] = drm_fb_create_dumb(b, w, h, format);
2697                 if (!output->dumb[i])
2698                         goto err;
2699
2700                 output->image[i] =
2701                         pixman_image_create_bits(pixman_format, w, h,
2702                                                  output->dumb[i]->map,
2703                                                  output->dumb[i]->stride);
2704                 if (!output->image[i])
2705                         goto err;
2706         }
2707
2708         if (pixman_renderer_output_create(&output->base) < 0)
2709                 goto err;
2710
2711         pixman_region32_init_rect(&output->previous_damage,
2712                                   output->base.x, output->base.y, output->base.width, output->base.height);
2713
2714         return 0;
2715
2716 err:
2717         for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
2718                 if (output->dumb[i])
2719                         drm_fb_unref(output->dumb[i]);
2720                 if (output->image[i])
2721                         pixman_image_unref(output->image[i]);
2722
2723                 output->dumb[i] = NULL;
2724                 output->image[i] = NULL;
2725         }
2726
2727         return -1;
2728 }
2729
2730 static void
2731 drm_output_fini_pixman(struct drm_output *output)
2732 {
2733         unsigned int i;
2734
2735         pixman_renderer_output_destroy(&output->base);
2736         pixman_region32_fini(&output->previous_damage);
2737
2738         for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
2739                 pixman_image_unref(output->image[i]);
2740                 drm_fb_unref(output->dumb[i]);
2741                 output->dumb[i] = NULL;
2742                 output->image[i] = NULL;
2743         }
2744 }
2745
2746 static void
2747 edid_parse_string(const uint8_t *data, char text[])
2748 {
2749         int i;
2750         int replaced = 0;
2751
2752         /* this is always 12 bytes, but we can't guarantee it's null
2753          * terminated or not junk. */
2754         strncpy(text, (const char *) data, 12);
2755
2756         /* guarantee our new string is null-terminated */
2757         text[12] = '\0';
2758
2759         /* remove insane chars */
2760         for (i = 0; text[i] != '\0'; i++) {
2761                 if (text[i] == '\n' ||
2762                     text[i] == '\r') {
2763                         text[i] = '\0';
2764                         break;
2765                 }
2766         }
2767
2768         /* ensure string is printable */
2769         for (i = 0; text[i] != '\0'; i++) {
2770                 if (!isprint(text[i])) {
2771                         text[i] = '-';
2772                         replaced++;
2773                 }
2774         }
2775
2776         /* if the string is random junk, ignore the string */
2777         if (replaced > 4)
2778                 text[0] = '\0';
2779 }
2780
2781 #define EDID_DESCRIPTOR_ALPHANUMERIC_DATA_STRING        0xfe
2782 #define EDID_DESCRIPTOR_DISPLAY_PRODUCT_NAME            0xfc
2783 #define EDID_DESCRIPTOR_DISPLAY_PRODUCT_SERIAL_NUMBER   0xff
2784 #define EDID_OFFSET_DATA_BLOCKS                         0x36
2785 #define EDID_OFFSET_LAST_BLOCK                          0x6c
2786 #define EDID_OFFSET_PNPID                               0x08
2787 #define EDID_OFFSET_SERIAL                              0x0c
2788
2789 static int
2790 edid_parse(struct drm_edid *edid, const uint8_t *data, size_t length)
2791 {
2792         int i;
2793         uint32_t serial_number;
2794
2795         /* check header */
2796         if (length < 128)
2797                 return -1;
2798         if (data[0] != 0x00 || data[1] != 0xff)
2799                 return -1;
2800
2801         /* decode the PNP ID from three 5 bit words packed into 2 bytes
2802          * /--08--\/--09--\
2803          * 7654321076543210
2804          * |\---/\---/\---/
2805          * R  C1   C2   C3 */
2806         edid->pnp_id[0] = 'A' + ((data[EDID_OFFSET_PNPID + 0] & 0x7c) / 4) - 1;
2807         edid->pnp_id[1] = 'A' + ((data[EDID_OFFSET_PNPID + 0] & 0x3) * 8) + ((data[EDID_OFFSET_PNPID + 1] & 0xe0) / 32) - 1;
2808         edid->pnp_id[2] = 'A' + (data[EDID_OFFSET_PNPID + 1] & 0x1f) - 1;
2809         edid->pnp_id[3] = '\0';
2810
2811         /* maybe there isn't a ASCII serial number descriptor, so use this instead */
2812         serial_number = (uint32_t) data[EDID_OFFSET_SERIAL + 0];
2813         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 1] * 0x100;
2814         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 2] * 0x10000;
2815         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 3] * 0x1000000;
2816         if (serial_number > 0)
2817                 sprintf(edid->serial_number, "%lu", (unsigned long) serial_number);
2818
2819         /* parse EDID data */
2820         for (i = EDID_OFFSET_DATA_BLOCKS;
2821              i <= EDID_OFFSET_LAST_BLOCK;
2822              i += 18) {
2823                 /* ignore pixel clock data */
2824                 if (data[i] != 0)
2825                         continue;
2826                 if (data[i+2] != 0)
2827                         continue;
2828
2829                 /* any useful blocks? */
2830                 if (data[i+3] == EDID_DESCRIPTOR_DISPLAY_PRODUCT_NAME) {
2831                         edid_parse_string(&data[i+5],
2832                                           edid->monitor_name);
2833                 } else if (data[i+3] == EDID_DESCRIPTOR_DISPLAY_PRODUCT_SERIAL_NUMBER) {
2834                         edid_parse_string(&data[i+5],
2835                                           edid->serial_number);
2836                 } else if (data[i+3] == EDID_DESCRIPTOR_ALPHANUMERIC_DATA_STRING) {
2837                         edid_parse_string(&data[i+5],
2838                                           edid->eisa_id);
2839                 }
2840         }
2841         return 0;
2842 }
2843
2844 /** Parse monitor make, model and serial from EDID
2845  *
2846  * \param b The backend instance.
2847  * \param output The output whose \c drm_edid to fill in.
2848  * \param props The DRM connector properties to get the EDID from.
2849  * \param make[out] The monitor make (PNP ID).
2850  * \param model[out] The monitor model (name).
2851  * \param serial_number[out] The monitor serial number.
2852  *
2853  * Each of \c *make, \c *model and \c *serial_number are set only if the
2854  * information is found in the EDID. The pointers they are set to must not
2855  * be free()'d explicitly, instead they get implicitly freed when the
2856  * \c drm_output is destroyed.
2857  */
2858 static void
2859 find_and_parse_output_edid(struct drm_backend *b, struct drm_output *output,
2860                            drmModeObjectPropertiesPtr props,
2861                            const char **make,
2862                            const char **model,
2863                            const char **serial_number)
2864 {
2865         drmModePropertyBlobPtr edid_blob = NULL;
2866         uint32_t blob_id;
2867         int rc;
2868
2869         blob_id =
2870                 drm_property_get_value(&output->props_conn[WDRM_CONNECTOR_EDID],
2871                                        props, 0);
2872         if (!blob_id)
2873                 return;
2874
2875         edid_blob = drmModeGetPropertyBlob(b->drm.fd, blob_id);
2876         if (!edid_blob)
2877                 return;
2878
2879         rc = edid_parse(&output->edid,
2880                         edid_blob->data,
2881                         edid_blob->length);
2882         if (!rc) {
2883                 weston_log("EDID data '%s', '%s', '%s'\n",
2884                            output->edid.pnp_id,
2885                            output->edid.monitor_name,
2886                            output->edid.serial_number);
2887                 if (output->edid.pnp_id[0] != '\0')
2888                         *make = output->edid.pnp_id;
2889                 if (output->edid.monitor_name[0] != '\0')
2890                         *model = output->edid.monitor_name;
2891                 if (output->edid.serial_number[0] != '\0')
2892                         *serial_number = output->edid.serial_number;
2893         }
2894         drmModeFreePropertyBlob(edid_blob);
2895 }
2896
2897 static int
2898 parse_modeline(const char *s, drmModeModeInfo *mode)
2899 {
2900         char hsync[16];
2901         char vsync[16];
2902         float fclock;
2903
2904         mode->type = DRM_MODE_TYPE_USERDEF;
2905         mode->hskew = 0;
2906         mode->vscan = 0;
2907         mode->vrefresh = 0;
2908         mode->flags = 0;
2909
2910         if (sscanf(s, "%f %hd %hd %hd %hd %hd %hd %hd %hd %15s %15s",
2911                    &fclock,
2912                    &mode->hdisplay,
2913                    &mode->hsync_start,
2914                    &mode->hsync_end,
2915                    &mode->htotal,
2916                    &mode->vdisplay,
2917                    &mode->vsync_start,
2918                    &mode->vsync_end,
2919                    &mode->vtotal, hsync, vsync) != 11)
2920                 return -1;
2921
2922         mode->clock = fclock * 1000;
2923         if (strcmp(hsync, "+hsync") == 0)
2924                 mode->flags |= DRM_MODE_FLAG_PHSYNC;
2925         else if (strcmp(hsync, "-hsync") == 0)
2926                 mode->flags |= DRM_MODE_FLAG_NHSYNC;
2927         else
2928                 return -1;
2929
2930         if (strcmp(vsync, "+vsync") == 0)
2931                 mode->flags |= DRM_MODE_FLAG_PVSYNC;
2932         else if (strcmp(vsync, "-vsync") == 0)
2933                 mode->flags |= DRM_MODE_FLAG_NVSYNC;
2934         else
2935                 return -1;
2936
2937         snprintf(mode->name, sizeof mode->name, "%dx%d@%.3f",
2938                  mode->hdisplay, mode->vdisplay, fclock);
2939
2940         return 0;
2941 }
2942
2943 static void
2944 setup_output_seat_constraint(struct drm_backend *b,
2945                              struct weston_output *output,
2946                              const char *s)
2947 {
2948         if (strcmp(s, "") != 0) {
2949                 struct weston_pointer *pointer;
2950                 struct udev_seat *seat;
2951
2952                 seat = udev_seat_get_named(&b->input, s);
2953                 if (!seat)
2954                         return;
2955
2956                 seat->base.output = output;
2957
2958                 pointer = weston_seat_get_pointer(&seat->base);
2959                 if (pointer)
2960                         weston_pointer_clamp(pointer,
2961                                              &pointer->x,
2962                                              &pointer->y);
2963         }
2964 }
2965
2966 static int
2967 parse_gbm_format(const char *s, uint32_t default_value, uint32_t *gbm_format)
2968 {
2969         int ret = 0;
2970
2971         if (s == NULL)
2972                 *gbm_format = default_value;
2973         else if (strcmp(s, "xrgb8888") == 0)
2974                 *gbm_format = GBM_FORMAT_XRGB8888;
2975         else if (strcmp(s, "rgb565") == 0)
2976                 *gbm_format = GBM_FORMAT_RGB565;
2977         else if (strcmp(s, "xrgb2101010") == 0)
2978                 *gbm_format = GBM_FORMAT_XRGB2101010;
2979         else {
2980                 weston_log("fatal: unrecognized pixel format: %s\n", s);
2981                 ret = -1;
2982         }
2983
2984         return ret;
2985 }
2986
2987 /**
2988  * Choose suitable mode for an output
2989  *
2990  * Find the most suitable mode to use for initial setup (or reconfiguration on
2991  * hotplug etc) for a DRM output.
2992  *
2993  * @param output DRM output to choose mode for
2994  * @param kind Strategy and preference to use when choosing mode
2995  * @param width Desired width for this output
2996  * @param height Desired height for this output
2997  * @param current_mode Mode currently being displayed on this output
2998  * @param modeline Manually-entered mode (may be NULL)
2999  * @returns A mode from the output's mode list, or NULL if none available
3000  */
3001 static struct drm_mode *
3002 drm_output_choose_initial_mode(struct drm_backend *backend,
3003                                struct drm_output *output,
3004                                enum weston_drm_backend_output_mode mode,
3005                                const char *modeline,
3006                                const drmModeModeInfo *current_mode)
3007 {
3008         struct drm_mode *preferred = NULL;
3009         struct drm_mode *current = NULL;
3010         struct drm_mode *configured = NULL;
3011         struct drm_mode *best = NULL;
3012         struct drm_mode *drm_mode;
3013         drmModeModeInfo drm_modeline;
3014         int32_t width = 0;
3015         int32_t height = 0;
3016         uint32_t refresh = 0;
3017         int n;
3018
3019         if (mode == WESTON_DRM_BACKEND_OUTPUT_PREFERRED && modeline) {
3020                 n = sscanf(modeline, "%dx%d@%d", &width, &height, &refresh);
3021                 if (n != 2 && n != 3) {
3022                         width = -1;
3023
3024                         if (parse_modeline(modeline, &drm_modeline) == 0) {
3025                                 configured = drm_output_add_mode(output, &drm_modeline);
3026                                 if (!configured)
3027                                         return NULL;
3028                         } else {
3029                                 weston_log("Invalid modeline \"%s\" for output %s\n",
3030                                            modeline, output->base.name);
3031                         }
3032                 }
3033         }
3034
3035         wl_list_for_each_reverse(drm_mode, &output->base.mode_list, base.link) {
3036                 if (width == drm_mode->base.width &&
3037                     height == drm_mode->base.height &&
3038                     (refresh == 0 || refresh == drm_mode->mode_info.vrefresh))
3039                         configured = drm_mode;
3040
3041                 if (memcmp(current_mode, &drm_mode->mode_info,
3042                            sizeof *current_mode) == 0)
3043                         current = drm_mode;
3044
3045                 if (drm_mode->base.flags & WL_OUTPUT_MODE_PREFERRED)
3046                         preferred = drm_mode;
3047
3048                 best = drm_mode;
3049         }
3050
3051         if (current == NULL && current_mode->clock != 0) {
3052                 current = drm_output_add_mode(output, current_mode);
3053                 if (!current)
3054                         return NULL;
3055         }
3056
3057         if (mode == WESTON_DRM_BACKEND_OUTPUT_CURRENT)
3058                 configured = current;
3059
3060         if (configured)
3061                 return configured;
3062
3063         if (preferred)
3064                 return preferred;
3065
3066         if (current)
3067                 return current;
3068
3069         if (best)
3070                 return best;
3071
3072         weston_log("no available modes for %s\n", output->base.name);
3073         return NULL;
3074 }
3075
3076 static int
3077 connector_get_current_mode(drmModeConnector *connector, int drm_fd,
3078                            drmModeModeInfo *mode)
3079 {
3080         drmModeEncoder *encoder;
3081         drmModeCrtc *crtc;
3082
3083         /* Get the current mode on the crtc that's currently driving
3084          * this connector. */
3085         encoder = drmModeGetEncoder(drm_fd, connector->encoder_id);
3086         memset(mode, 0, sizeof *mode);
3087         if (encoder != NULL) {
3088                 crtc = drmModeGetCrtc(drm_fd, encoder->crtc_id);
3089                 drmModeFreeEncoder(encoder);
3090                 if (crtc == NULL)
3091                         return -1;
3092                 if (crtc->mode_valid)
3093                         *mode = crtc->mode;
3094                 drmModeFreeCrtc(crtc);
3095         }
3096
3097         return 0;
3098 }
3099
3100 static int
3101 drm_output_set_mode(struct weston_output *base,
3102                     enum weston_drm_backend_output_mode mode,
3103                     const char *modeline)
3104 {
3105         struct drm_output *output = to_drm_output(base);
3106         struct drm_backend *b = to_drm_backend(base->compositor);
3107
3108         struct drm_mode *current;
3109         drmModeModeInfo crtc_mode;
3110
3111         if (connector_get_current_mode(output->connector, b->drm.fd, &crtc_mode) < 0)
3112                 return -1;
3113
3114         current = drm_output_choose_initial_mode(b, output, mode, modeline, &crtc_mode);
3115         if (!current)
3116                 return -1;
3117
3118         output->base.current_mode = &current->base;
3119         output->base.current_mode->flags |= WL_OUTPUT_MODE_CURRENT;
3120
3121         /* Set native_ fields, so weston_output_mode_switch_to_native() works */
3122         output->base.native_mode = output->base.current_mode;
3123         output->base.native_scale = output->base.current_scale;
3124
3125         return 0;
3126 }
3127
3128 static void
3129 drm_output_set_gbm_format(struct weston_output *base,
3130                           const char *gbm_format)
3131 {
3132         struct drm_output *output = to_drm_output(base);
3133         struct drm_backend *b = to_drm_backend(base->compositor);
3134
3135         if (parse_gbm_format(gbm_format, b->gbm_format, &output->gbm_format) == -1)
3136                 output->gbm_format = b->gbm_format;
3137 }
3138
3139 static void
3140 drm_output_set_seat(struct weston_output *base,
3141                     const char *seat)
3142 {
3143         struct drm_output *output = to_drm_output(base);
3144         struct drm_backend *b = to_drm_backend(base->compositor);
3145
3146         setup_output_seat_constraint(b, &output->base,
3147                                      seat ? seat : "");
3148 }
3149
3150 static int
3151 drm_output_enable(struct weston_output *base)
3152 {
3153         struct drm_output *output = to_drm_output(base);
3154         struct drm_backend *b = to_drm_backend(base->compositor);
3155         struct weston_mode *m;
3156
3157         if (b->pageflip_timeout)
3158                 drm_output_pageflip_timer_create(output);
3159
3160         if (b->use_pixman) {
3161                 if (drm_output_init_pixman(output, b) < 0) {
3162                         weston_log("Failed to init output pixman state\n");
3163                         goto err;
3164                 }
3165         } else if (drm_output_init_egl(output, b) < 0) {
3166                 weston_log("Failed to init output gl state\n");
3167                 goto err;
3168         }
3169
3170         if (output->backlight) {
3171                 weston_log("Initialized backlight, device %s\n",
3172                            output->backlight->path);
3173                 output->base.set_backlight = drm_set_backlight;
3174                 output->base.backlight_current = drm_get_backlight(output);
3175         } else {
3176                 weston_log("Failed to initialize backlight\n");
3177         }
3178
3179         output->base.start_repaint_loop = drm_output_start_repaint_loop;
3180         output->base.repaint = drm_output_repaint;
3181         output->base.assign_planes = drm_assign_planes;
3182         output->base.set_dpms = drm_set_dpms;
3183         output->base.switch_mode = drm_output_switch_mode;
3184
3185         output->base.gamma_size = output->original_crtc->gamma_size;
3186         output->base.set_gamma = drm_output_set_gamma;
3187
3188         weston_plane_init(&output->cursor_plane, b->compositor,
3189                           INT32_MIN, INT32_MIN);
3190         weston_plane_init(&output->scanout_plane, b->compositor, 0, 0);
3191
3192         weston_compositor_stack_plane(b->compositor, &output->cursor_plane, NULL);
3193         weston_compositor_stack_plane(b->compositor, &output->scanout_plane,
3194                                       &b->compositor->primary_plane);
3195
3196         weston_log("Output %s, (connector %d, crtc %d)\n",
3197                    output->base.name, output->connector_id, output->crtc_id);
3198         wl_list_for_each(m, &output->base.mode_list, link)
3199                 weston_log_continue(STAMP_SPACE "mode %dx%d@%.1f%s%s%s\n",
3200                                     m->width, m->height, m->refresh / 1000.0,
3201                                     m->flags & WL_OUTPUT_MODE_PREFERRED ?
3202                                     ", preferred" : "",
3203                                     m->flags & WL_OUTPUT_MODE_CURRENT ?
3204                                     ", current" : "",
3205                                     output->connector->count_modes == 0 ?
3206                                     ", built-in" : "");
3207
3208         output->state_invalid = true;
3209
3210         return 0;
3211
3212 err:
3213         return -1;
3214 }
3215
3216 static void
3217 drm_output_deinit(struct weston_output *base)
3218 {
3219         struct drm_output *output = to_drm_output(base);
3220         struct drm_backend *b = to_drm_backend(base->compositor);
3221
3222         /* output->fb_last and output->fb_pending must not be set here;
3223          * destroy_pending/disable_pending exist to guarantee exactly this. */
3224         assert(!output->fb_last);
3225         assert(!output->fb_pending);
3226         drm_fb_unref(output->fb_current);
3227         output->fb_current = NULL;
3228
3229         if (b->use_pixman)
3230                 drm_output_fini_pixman(output);
3231         else
3232                 drm_output_fini_egl(output);
3233
3234         weston_plane_release(&output->scanout_plane);
3235         weston_plane_release(&output->cursor_plane);
3236
3237         /* Turn off hardware cursor */
3238         drmModeSetCursor(b->drm.fd, output->crtc_id, 0, 0, 0);
3239 }
3240
3241 static void
3242 drm_output_destroy(struct weston_output *base)
3243 {
3244         struct drm_output *output = to_drm_output(base);
3245         struct drm_backend *b = to_drm_backend(base->compositor);
3246         struct drm_mode *drm_mode, *next;
3247         drmModeCrtcPtr origcrtc = output->original_crtc;
3248
3249         if (output->page_flip_pending) {
3250                 output->destroy_pending = 1;
3251                 weston_log("destroy output while page flip pending\n");
3252                 return;
3253         }
3254
3255         if (output->base.enabled)
3256                 drm_output_deinit(&output->base);
3257
3258         wl_list_for_each_safe(drm_mode, next, &output->base.mode_list,
3259                               base.link) {
3260                 wl_list_remove(&drm_mode->base.link);
3261                 free(drm_mode);
3262         }
3263
3264         if (origcrtc) {
3265                 /* Restore original CRTC state */
3266                 drmModeSetCrtc(b->drm.fd, origcrtc->crtc_id, origcrtc->buffer_id,
3267                                origcrtc->x, origcrtc->y,
3268                                &output->connector_id, 1, &origcrtc->mode);
3269                 drmModeFreeCrtc(origcrtc);
3270         }
3271
3272         if (output->pageflip_timer)
3273                 wl_event_source_remove(output->pageflip_timer);
3274
3275         weston_output_release(&output->base);
3276
3277         drm_property_info_free(output->props_conn, WDRM_CONNECTOR__COUNT);
3278
3279         drmModeFreeConnector(output->connector);
3280
3281         if (output->backlight)
3282                 backlight_destroy(output->backlight);
3283
3284         free(output);
3285 }
3286
3287 static int
3288 drm_output_disable(struct weston_output *base)
3289 {
3290         struct drm_output *output = to_drm_output(base);
3291         struct drm_backend *b = to_drm_backend(base->compositor);
3292
3293         if (output->page_flip_pending) {
3294                 output->disable_pending = 1;
3295                 return -1;
3296         }
3297
3298         if (output->base.enabled)
3299                 drm_output_deinit(&output->base);
3300
3301         output->disable_pending = 0;
3302
3303         weston_log("Disabling output %s\n", output->base.name);
3304         drmModeSetCrtc(b->drm.fd, output->crtc_id,
3305                        0, 0, 0, 0, 0, NULL);
3306
3307         return 0;
3308 }
3309
3310 /**
3311  * Create a Weston output structure
3312  *
3313  * Given a DRM connector, create a matching drm_output structure and add it
3314  * to Weston's output list. It also takes ownership of the connector, which
3315  * is released when output is destroyed.
3316  *
3317  * @param b Weston backend structure
3318  * @param resources DRM resources for this device
3319  * @param connector DRM connector to use for this new output
3320  * @param drm_device udev device pointer
3321  * @returns 0 on success, or -1 on failure
3322  */
3323 static int
3324 create_output_for_connector(struct drm_backend *b,
3325                             drmModeRes *resources,
3326                             drmModeConnector *connector,
3327                             struct udev_device *drm_device)
3328 {
3329         struct drm_output *output;
3330         drmModeObjectPropertiesPtr props;
3331         struct drm_mode *drm_mode;
3332         char *name;
3333         const char *make = "unknown";
3334         const char *model = "unknown";
3335         const char *serial_number = "unknown";
3336         int i;
3337
3338         static const struct drm_property_info connector_props[] = {
3339                 [WDRM_CONNECTOR_EDID] = { .name = "EDID" },
3340                 [WDRM_CONNECTOR_DPMS] = { .name = "DPMS" },
3341         };
3342
3343         i = find_crtc_for_connector(b, resources, connector);
3344         if (i < 0) {
3345                 weston_log("No usable crtc/encoder pair for connector.\n");
3346                 goto err;
3347         }
3348
3349         output = zalloc(sizeof *output);
3350         if (output == NULL)
3351                 goto err;
3352
3353         output->connector = connector;
3354         output->crtc_id = resources->crtcs[i];
3355         output->pipe = i;
3356         output->connector_id = connector->connector_id;
3357
3358         output->backlight = backlight_init(drm_device,
3359                                            connector->connector_type);
3360
3361         output->original_crtc = drmModeGetCrtc(b->drm.fd, output->crtc_id);
3362
3363         name = make_connector_name(connector);
3364         weston_output_init(&output->base, b->compositor, name);
3365         free(name);
3366
3367         output->base.enable = drm_output_enable;
3368         output->base.destroy = drm_output_destroy;
3369         output->base.disable = drm_output_disable;
3370
3371         output->destroy_pending = 0;
3372         output->disable_pending = 0;
3373
3374         props = drmModeObjectGetProperties(b->drm.fd, connector->connector_id,
3375                                            DRM_MODE_OBJECT_CONNECTOR);
3376         if (!props) {
3377                 weston_log("failed to get connector properties\n");
3378                 goto err;
3379         }
3380         drm_property_info_populate(b, connector_props, output->props_conn,
3381                                    WDRM_CONNECTOR__COUNT, props);
3382         find_and_parse_output_edid(b, output, props,
3383                                    &make, &model, &serial_number);
3384         output->base.make = (char *)make;
3385         output->base.model = (char *)model;
3386         output->base.serial_number = (char *)serial_number;
3387         output->base.subpixel = drm_subpixel_to_wayland(output->connector->subpixel);
3388
3389         if (output->connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
3390             output->connector->connector_type == DRM_MODE_CONNECTOR_eDP)
3391                 output->base.connection_internal = true;
3392
3393         output->base.mm_width = output->connector->mmWidth;
3394         output->base.mm_height = output->connector->mmHeight;
3395
3396         drmModeFreeObjectProperties(props);
3397
3398         for (i = 0; i < output->connector->count_modes; i++) {
3399                 drm_mode = drm_output_add_mode(output, &output->connector->modes[i]);
3400                 if (!drm_mode) {
3401                         drm_output_destroy(&output->base);
3402                         return -1;
3403                 }
3404         }
3405
3406         weston_compositor_add_pending_output(&output->base, b->compositor);
3407
3408         return 0;
3409
3410 err:
3411         drmModeFreeConnector(connector);
3412
3413         return -1;
3414 }
3415
3416 static int
3417 create_outputs(struct drm_backend *b, struct udev_device *drm_device)
3418 {
3419         drmModeConnector *connector;
3420         drmModeRes *resources;
3421         int i;
3422
3423         resources = drmModeGetResources(b->drm.fd);
3424         if (!resources) {
3425                 weston_log("drmModeGetResources failed\n");
3426                 return -1;
3427         }
3428
3429         b->min_width  = resources->min_width;
3430         b->max_width  = resources->max_width;
3431         b->min_height = resources->min_height;
3432         b->max_height = resources->max_height;
3433
3434         for (i = 0; i < resources->count_connectors; i++) {
3435                 int ret;
3436
3437                 connector = drmModeGetConnector(b->drm.fd,
3438                                                 resources->connectors[i]);
3439                 if (connector == NULL)
3440                         continue;
3441
3442                 if (connector->connection == DRM_MODE_CONNECTED) {
3443                         ret = create_output_for_connector(b, resources,
3444                                                           connector, drm_device);
3445                         if (ret < 0)
3446                                 weston_log("failed to create new connector\n");
3447                 } else {
3448                         drmModeFreeConnector(connector);
3449                 }
3450         }
3451
3452         if (wl_list_empty(&b->compositor->output_list) &&
3453             wl_list_empty(&b->compositor->pending_output_list))
3454                 weston_log("No currently active connector found.\n");
3455
3456         drmModeFreeResources(resources);
3457
3458         return 0;
3459 }
3460
3461 static void
3462 update_outputs(struct drm_backend *b, struct udev_device *drm_device)
3463 {
3464         drmModeConnector *connector;
3465         drmModeRes *resources;
3466         struct drm_output *output, *next;
3467         uint32_t *connected;
3468         int i;
3469
3470         resources = drmModeGetResources(b->drm.fd);
3471         if (!resources) {
3472                 weston_log("drmModeGetResources failed\n");
3473                 return;
3474         }
3475
3476         connected = calloc(resources->count_connectors, sizeof(uint32_t));
3477         if (!connected) {
3478                 drmModeFreeResources(resources);
3479                 return;
3480         }
3481
3482         /* collect new connects */
3483         for (i = 0; i < resources->count_connectors; i++) {
3484                 uint32_t connector_id = resources->connectors[i];
3485
3486                 connector = drmModeGetConnector(b->drm.fd, connector_id);
3487                 if (connector == NULL)
3488                         continue;
3489
3490                 if (connector->connection != DRM_MODE_CONNECTED) {
3491                         drmModeFreeConnector(connector);
3492                         continue;
3493                 }
3494
3495                 connected[i] = connector_id;
3496
3497                 if (drm_output_find_by_connector(b, connector_id)) {
3498                         drmModeFreeConnector(connector);
3499                         continue;
3500                 }
3501
3502                 create_output_for_connector(b, resources,
3503                                             connector, drm_device);
3504                 weston_log("connector %d connected\n", connector_id);
3505         }
3506
3507         wl_list_for_each_safe(output, next, &b->compositor->output_list,
3508                               base.link) {
3509                 bool disconnected = true;
3510
3511                 for (i = 0; i < resources->count_connectors; i++) {
3512                         if (connected[i] == output->connector_id) {
3513                                 disconnected = false;
3514                                 break;
3515                         }
3516                 }
3517
3518                 if (!disconnected)
3519                         continue;
3520
3521                 weston_log("connector %d disconnected\n", output->connector_id);
3522                 drm_output_destroy(&output->base);
3523         }
3524
3525         wl_list_for_each_safe(output, next, &b->compositor->pending_output_list,
3526                               base.link) {
3527                 bool disconnected = true;
3528
3529                 for (i = 0; i < resources->count_connectors; i++) {
3530                         if (connected[i] == output->connector_id) {
3531                                 disconnected = false;
3532                                 break;
3533                         }
3534                 }
3535
3536                 if (!disconnected)
3537                         continue;
3538
3539                 weston_log("connector %d disconnected\n", output->connector_id);
3540                 drm_output_destroy(&output->base);
3541         }
3542
3543         free(connected);
3544         drmModeFreeResources(resources);
3545 }
3546
3547 static int
3548 udev_event_is_hotplug(struct drm_backend *b, struct udev_device *device)
3549 {
3550         const char *sysnum;
3551         const char *val;
3552
3553         sysnum = udev_device_get_sysnum(device);
3554         if (!sysnum || atoi(sysnum) != b->drm.id)
3555                 return 0;
3556
3557         val = udev_device_get_property_value(device, "HOTPLUG");
3558         if (!val)
3559                 return 0;
3560
3561         return strcmp(val, "1") == 0;
3562 }
3563
3564 static int
3565 udev_drm_event(int fd, uint32_t mask, void *data)
3566 {
3567         struct drm_backend *b = data;
3568         struct udev_device *event;
3569
3570         event = udev_monitor_receive_device(b->udev_monitor);
3571
3572         if (udev_event_is_hotplug(b, event))
3573                 update_outputs(b, event);
3574
3575         udev_device_unref(event);
3576
3577         return 1;
3578 }
3579
3580 static void
3581 drm_restore(struct weston_compositor *ec)
3582 {
3583         weston_launcher_restore(ec->launcher);
3584 }
3585
3586 static void
3587 drm_destroy(struct weston_compositor *ec)
3588 {
3589         struct drm_backend *b = to_drm_backend(ec);
3590
3591         udev_input_destroy(&b->input);
3592
3593         wl_event_source_remove(b->udev_drm_source);
3594         wl_event_source_remove(b->drm_source);
3595
3596         destroy_sprites(b);
3597
3598         weston_compositor_shutdown(ec);
3599
3600         if (b->gbm)
3601                 gbm_device_destroy(b->gbm);
3602
3603         udev_unref(b->udev);
3604
3605         weston_launcher_destroy(ec->launcher);
3606
3607         close(b->drm.fd);
3608         free(b);
3609 }
3610
3611 static void
3612 session_notify(struct wl_listener *listener, void *data)
3613 {
3614         struct weston_compositor *compositor = data;
3615         struct drm_backend *b = to_drm_backend(compositor);
3616         struct drm_plane *plane;
3617         struct drm_output *output;
3618
3619         if (compositor->session_active) {
3620                 weston_log("activating session\n");
3621                 weston_compositor_wake(compositor);
3622                 weston_compositor_damage_all(compositor);
3623
3624                 wl_list_for_each(output, &compositor->output_list, base.link)
3625                         output->state_invalid = true;
3626
3627                 udev_input_enable(&b->input);
3628         } else {
3629                 weston_log("deactivating session\n");
3630                 udev_input_disable(&b->input);
3631
3632                 weston_compositor_offscreen(compositor);
3633
3634                 /* If we have a repaint scheduled (either from a
3635                  * pending pageflip or the idle handler), make sure we
3636                  * cancel that so we don't try to pageflip when we're
3637                  * vt switched away.  The OFFSCREEN state will prevent
3638                  * further attempts at repainting.  When we switch
3639                  * back, we schedule a repaint, which will process
3640                  * pending frame callbacks. */
3641
3642                 wl_list_for_each(output, &compositor->output_list, base.link) {
3643                         output->base.repaint_needed = false;
3644                         drmModeSetCursor(b->drm.fd, output->crtc_id, 0, 0, 0);
3645                 }
3646
3647                 output = container_of(compositor->output_list.next,
3648                                       struct drm_output, base.link);
3649
3650                 wl_list_for_each(plane, &b->plane_list, link) {
3651                         if (plane->type != WDRM_PLANE_TYPE_OVERLAY)
3652                                 continue;
3653
3654                         drmModeSetPlane(b->drm.fd,
3655                                         plane->plane_id,
3656                                         output->crtc_id, 0, 0,
3657                                         0, 0, 0, 0, 0, 0, 0, 0);
3658                 }
3659         }
3660 }
3661
3662 /**
3663  * Determines whether or not a device is capable of modesetting. If successful,
3664  * sets b->drm.fd and b->drm.filename to the opened device.
3665  */
3666 static bool
3667 drm_device_is_kms(struct drm_backend *b, struct udev_device *device)
3668 {
3669         const char *filename = udev_device_get_devnode(device);
3670         const char *sysnum = udev_device_get_sysnum(device);
3671         drmModeRes *res;
3672         int id, fd;
3673
3674         if (!filename)
3675                 return false;
3676
3677         fd = weston_launcher_open(b->compositor->launcher, filename, O_RDWR);
3678         if (fd < 0)
3679                 return false;
3680
3681         res = drmModeGetResources(fd);
3682         if (!res)
3683                 goto out_fd;
3684
3685         if (res->count_crtcs <= 0 || res->count_connectors <= 0 ||
3686             res->count_encoders <= 0)
3687                 goto out_res;
3688
3689         if (sysnum)
3690                 id = atoi(sysnum);
3691         if (!sysnum || id < 0) {
3692                 weston_log("couldn't get sysnum for device %s\n", filename);
3693                 goto out_res;
3694         }
3695
3696         /* We can be called successfully on multiple devices; if we have,
3697          * clean up old entries. */
3698         if (b->drm.fd >= 0)
3699                 weston_launcher_close(b->compositor->launcher, b->drm.fd);
3700         free(b->drm.filename);
3701
3702         b->drm.fd = fd;
3703         b->drm.id = id;
3704         b->drm.filename = strdup(filename);
3705
3706         drmModeFreeResources(res);
3707
3708         return true;
3709
3710 out_res:
3711         drmModeFreeResources(res);
3712 out_fd:
3713         weston_launcher_close(b->compositor->launcher, fd);
3714         return false;
3715 }
3716
3717 /*
3718  * Find primary GPU
3719  * Some systems may have multiple DRM devices attached to a single seat. This
3720  * function loops over all devices and tries to find a PCI device with the
3721  * boot_vga sysfs attribute set to 1.
3722  * If no such device is found, the first DRM device reported by udev is used.
3723  * Devices are also vetted to make sure they are are capable of modesetting,
3724  * rather than pure render nodes (GPU with no display), or pure
3725  * memory-allocation devices (VGEM).
3726  */
3727 static struct udev_device*
3728 find_primary_gpu(struct drm_backend *b, const char *seat)
3729 {
3730         struct udev_enumerate *e;
3731         struct udev_list_entry *entry;
3732         const char *path, *device_seat, *id;
3733         struct udev_device *device, *drm_device, *pci;
3734
3735         e = udev_enumerate_new(b->udev);
3736         udev_enumerate_add_match_subsystem(e, "drm");
3737         udev_enumerate_add_match_sysname(e, "card[0-9]*");
3738
3739         udev_enumerate_scan_devices(e);
3740         drm_device = NULL;
3741         udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
3742                 bool is_boot_vga = false;
3743
3744                 path = udev_list_entry_get_name(entry);
3745                 device = udev_device_new_from_syspath(b->udev, path);
3746                 if (!device)
3747                         continue;
3748                 device_seat = udev_device_get_property_value(device, "ID_SEAT");
3749                 if (!device_seat)
3750                         device_seat = default_seat;
3751                 if (strcmp(device_seat, seat)) {
3752                         udev_device_unref(device);
3753                         continue;
3754                 }
3755
3756                 pci = udev_device_get_parent_with_subsystem_devtype(device,
3757                                                                 "pci", NULL);
3758                 if (pci) {
3759                         id = udev_device_get_sysattr_value(pci, "boot_vga");
3760                         if (id && !strcmp(id, "1"))
3761                                 is_boot_vga = true;
3762                 }
3763
3764                 /* If we already have a modesetting-capable device, and this
3765                  * device isn't our boot-VGA device, we aren't going to use
3766                  * it. */
3767                 if (!is_boot_vga && drm_device) {
3768                         udev_device_unref(device);
3769                         continue;
3770                 }
3771
3772                 /* Make sure this device is actually capable of modesetting;
3773                  * if this call succeeds, b->drm.{fd,filename} will be set,
3774                  * and any old values freed. */
3775                 if (!drm_device_is_kms(b, device)) {
3776                         udev_device_unref(device);
3777                         continue;
3778                 }
3779
3780                 /* There can only be one boot_vga device, and we try to use it
3781                  * at all costs. */
3782                 if (is_boot_vga) {
3783                         if (drm_device)
3784                                 udev_device_unref(drm_device);
3785                         drm_device = device;
3786                         break;
3787                 }
3788
3789                 /* Per the (!is_boot_vga && drm_device) test above, we only
3790                  * trump existing saved devices with boot-VGA devices, so if
3791                  * we end up here, this must be the first device we've seen. */
3792                 assert(!drm_device);
3793                 drm_device = device;
3794         }
3795
3796         /* If we're returning a device to use, we must have an open FD for
3797          * it. */
3798         assert(!!drm_device == (b->drm.fd >= 0));
3799
3800         udev_enumerate_unref(e);
3801         return drm_device;
3802 }
3803
3804 static void
3805 planes_binding(struct weston_keyboard *keyboard, uint32_t time, uint32_t key,
3806                void *data)
3807 {
3808         struct drm_backend *b = data;
3809
3810         switch (key) {
3811         case KEY_C:
3812                 b->cursors_are_broken ^= 1;
3813                 break;
3814         case KEY_V:
3815                 b->sprites_are_broken ^= 1;
3816                 break;
3817         case KEY_O:
3818                 b->sprites_hidden ^= 1;
3819                 break;
3820         default:
3821                 break;
3822         }
3823 }
3824
3825 #ifdef BUILD_VAAPI_RECORDER
3826 static void
3827 recorder_destroy(struct drm_output *output)
3828 {
3829         vaapi_recorder_destroy(output->recorder);
3830         output->recorder = NULL;
3831
3832         output->base.disable_planes--;
3833
3834         wl_list_remove(&output->recorder_frame_listener.link);
3835         weston_log("[libva recorder] done\n");
3836 }
3837
3838 static void
3839 recorder_frame_notify(struct wl_listener *listener, void *data)
3840 {
3841         struct drm_output *output;
3842         struct drm_backend *b;
3843         int fd, ret;
3844
3845         output = container_of(listener, struct drm_output,
3846                               recorder_frame_listener);
3847         b = to_drm_backend(output->base.compositor);
3848
3849         if (!output->recorder)
3850                 return;
3851
3852         ret = drmPrimeHandleToFD(b->drm.fd, output->fb_current->handle,
3853                                  DRM_CLOEXEC, &fd);
3854         if (ret) {
3855                 weston_log("[libva recorder] "
3856                            "failed to create prime fd for front buffer\n");
3857                 return;
3858         }
3859
3860         ret = vaapi_recorder_frame(output->recorder, fd,
3861                                    output->fb_current->stride);
3862         if (ret < 0) {
3863                 weston_log("[libva recorder] aborted: %m\n");
3864                 recorder_destroy(output);
3865         }
3866 }
3867
3868 static void *
3869 create_recorder(struct drm_backend *b, int width, int height,
3870                 const char *filename)
3871 {
3872         int fd;
3873         drm_magic_t magic;
3874
3875         fd = open(b->drm.filename, O_RDWR | O_CLOEXEC);
3876         if (fd < 0)
3877                 return NULL;
3878
3879         drmGetMagic(fd, &magic);
3880         drmAuthMagic(b->drm.fd, magic);
3881
3882         return vaapi_recorder_create(fd, width, height, filename);
3883 }
3884
3885 static void
3886 recorder_binding(struct weston_keyboard *keyboard, uint32_t time, uint32_t key,
3887                  void *data)
3888 {
3889         struct drm_backend *b = data;
3890         struct drm_output *output;
3891         int width, height;
3892
3893         output = container_of(b->compositor->output_list.next,
3894                               struct drm_output, base.link);
3895
3896         if (!output->recorder) {
3897                 if (output->gbm_format != GBM_FORMAT_XRGB8888) {
3898                         weston_log("failed to start vaapi recorder: "
3899                                    "output format not supported\n");
3900                         return;
3901                 }
3902
3903                 width = output->base.current_mode->width;
3904                 height = output->base.current_mode->height;
3905
3906                 output->recorder =
3907                         create_recorder(b, width, height, "capture.h264");
3908                 if (!output->recorder) {
3909                         weston_log("failed to create vaapi recorder\n");
3910                         return;
3911                 }
3912
3913                 output->base.disable_planes++;
3914
3915                 output->recorder_frame_listener.notify = recorder_frame_notify;
3916                 wl_signal_add(&output->base.frame_signal,
3917                               &output->recorder_frame_listener);
3918
3919                 weston_output_schedule_repaint(&output->base);
3920
3921                 weston_log("[libva recorder] initialized\n");
3922         } else {
3923                 recorder_destroy(output);
3924         }
3925 }
3926 #else
3927 static void
3928 recorder_binding(struct weston_keyboard *keyboard, uint32_t time, uint32_t key,
3929                  void *data)
3930 {
3931         weston_log("Compiled without libva support\n");
3932 }
3933 #endif
3934
3935 static void
3936 switch_to_gl_renderer(struct drm_backend *b)
3937 {
3938         struct drm_output *output;
3939         bool dmabuf_support_inited;
3940
3941         if (!b->use_pixman)
3942                 return;
3943
3944         dmabuf_support_inited = !!b->compositor->renderer->import_dmabuf;
3945
3946         weston_log("Switching to GL renderer\n");
3947
3948         b->gbm = create_gbm_device(b->drm.fd);
3949         if (!b->gbm) {
3950                 weston_log("Failed to create gbm device. "
3951                            "Aborting renderer switch\n");
3952                 return;
3953         }
3954
3955         wl_list_for_each(output, &b->compositor->output_list, base.link)
3956                 pixman_renderer_output_destroy(&output->base);
3957
3958         b->compositor->renderer->destroy(b->compositor);
3959
3960         if (drm_backend_create_gl_renderer(b) < 0) {
3961                 gbm_device_destroy(b->gbm);
3962                 weston_log("Failed to create GL renderer. Quitting.\n");
3963                 /* FIXME: we need a function to shutdown cleanly */
3964                 assert(0);
3965         }
3966
3967         wl_list_for_each(output, &b->compositor->output_list, base.link)
3968                 drm_output_init_egl(output, b);
3969
3970         b->use_pixman = 0;
3971
3972         if (!dmabuf_support_inited && b->compositor->renderer->import_dmabuf) {
3973                 if (linux_dmabuf_setup(b->compositor) < 0)
3974                         weston_log("Error: initializing dmabuf "
3975                                    "support failed.\n");
3976         }
3977 }
3978
3979 static void
3980 renderer_switch_binding(struct weston_keyboard *keyboard, uint32_t time,
3981                         uint32_t key, void *data)
3982 {
3983         struct drm_backend *b =
3984                 to_drm_backend(keyboard->seat->compositor);
3985
3986         switch_to_gl_renderer(b);
3987 }
3988
3989 static const struct weston_drm_output_api api = {
3990         drm_output_set_mode,
3991         drm_output_set_gbm_format,
3992         drm_output_set_seat,
3993 };
3994
3995 static struct drm_backend *
3996 drm_backend_create(struct weston_compositor *compositor,
3997                    struct weston_drm_backend_config *config)
3998 {
3999         struct drm_backend *b;
4000         struct udev_device *drm_device;
4001         struct wl_event_loop *loop;
4002         const char *seat_id = default_seat;
4003         int ret;
4004
4005         weston_log("initializing drm backend\n");
4006
4007         b = zalloc(sizeof *b);
4008         if (b == NULL)
4009                 return NULL;
4010
4011         b->drm.fd = -1;
4012
4013         /*
4014          * KMS support for hardware planes cannot properly synchronize
4015          * without nuclear page flip. Without nuclear/atomic, hw plane
4016          * and cursor plane updates would either tear or cause extra
4017          * waits for vblanks which means dropping the compositor framerate
4018          * to a fraction. For cursors, it's not so bad, so they are
4019          * enabled.
4020          *
4021          * These can be enabled again when nuclear/atomic support lands.
4022          */
4023         b->sprites_are_broken = 1;
4024         b->compositor = compositor;
4025         b->use_pixman = config->use_pixman;
4026         b->pageflip_timeout = config->pageflip_timeout;
4027
4028         compositor->backend = &b->base;
4029
4030         if (parse_gbm_format(config->gbm_format, GBM_FORMAT_XRGB8888, &b->gbm_format) < 0)
4031                 goto err_compositor;
4032
4033         if (config->seat_id)
4034                 seat_id = config->seat_id;
4035
4036         /* Check if we run drm-backend using weston-launch */
4037         compositor->launcher = weston_launcher_connect(compositor, config->tty,
4038                                                        seat_id, true);
4039         if (compositor->launcher == NULL) {
4040                 weston_log("fatal: drm backend should be run "
4041                            "using weston-launch binary or as root\n");
4042                 goto err_compositor;
4043         }
4044
4045         b->udev = udev_new();
4046         if (b->udev == NULL) {
4047                 weston_log("failed to initialize udev context\n");
4048                 goto err_launcher;
4049         }
4050
4051         b->session_listener.notify = session_notify;
4052         wl_signal_add(&compositor->session_signal, &b->session_listener);
4053
4054         drm_device = find_primary_gpu(b, seat_id);
4055         if (drm_device == NULL) {
4056                 weston_log("no drm device found\n");
4057                 goto err_udev;
4058         }
4059
4060         if (init_kms_caps(b) < 0) {
4061                 weston_log("failed to initialize kms\n");
4062                 goto err_udev_dev;
4063         }
4064
4065         if (b->use_pixman) {
4066                 if (init_pixman(b) < 0) {
4067                         weston_log("failed to initialize pixman renderer\n");
4068                         goto err_udev_dev;
4069                 }
4070         } else {
4071                 if (init_egl(b) < 0) {
4072                         weston_log("failed to initialize egl\n");
4073                         goto err_udev_dev;
4074                 }
4075         }
4076
4077         b->base.destroy = drm_destroy;
4078         b->base.restore = drm_restore;
4079         b->base.repaint_begin = drm_repaint_begin;
4080         b->base.repaint_flush = drm_repaint_flush;
4081         b->base.repaint_cancel = drm_repaint_cancel;
4082
4083         weston_setup_vt_switch_bindings(compositor);
4084
4085         wl_list_init(&b->plane_list);
4086         create_sprites(b);
4087
4088         if (udev_input_init(&b->input,
4089                             compositor, b->udev, seat_id,
4090                             config->configure_device) < 0) {
4091                 weston_log("failed to create input devices\n");
4092                 goto err_sprite;
4093         }
4094
4095         if (create_outputs(b, drm_device) < 0) {
4096                 weston_log("failed to create output for %s\n", b->drm.filename);
4097                 goto err_udev_input;
4098         }
4099
4100         /* A this point we have some idea of whether or not we have a working
4101          * cursor plane. */
4102         if (!b->cursors_are_broken)
4103                 compositor->capabilities |= WESTON_CAP_CURSOR_PLANE;
4104
4105         loop = wl_display_get_event_loop(compositor->wl_display);
4106         b->drm_source =
4107                 wl_event_loop_add_fd(loop, b->drm.fd,
4108                                      WL_EVENT_READABLE, on_drm_input, b);
4109
4110         b->udev_monitor = udev_monitor_new_from_netlink(b->udev, "udev");
4111         if (b->udev_monitor == NULL) {
4112                 weston_log("failed to initialize udev monitor\n");
4113                 goto err_drm_source;
4114         }
4115         udev_monitor_filter_add_match_subsystem_devtype(b->udev_monitor,
4116                                                         "drm", NULL);
4117         b->udev_drm_source =
4118                 wl_event_loop_add_fd(loop,
4119                                      udev_monitor_get_fd(b->udev_monitor),
4120                                      WL_EVENT_READABLE, udev_drm_event, b);
4121
4122         if (udev_monitor_enable_receiving(b->udev_monitor) < 0) {
4123                 weston_log("failed to enable udev-monitor receiving\n");
4124                 goto err_udev_monitor;
4125         }
4126
4127         udev_device_unref(drm_device);
4128
4129         weston_compositor_add_debug_binding(compositor, KEY_O,
4130                                             planes_binding, b);
4131         weston_compositor_add_debug_binding(compositor, KEY_C,
4132                                             planes_binding, b);
4133         weston_compositor_add_debug_binding(compositor, KEY_V,
4134                                             planes_binding, b);
4135         weston_compositor_add_debug_binding(compositor, KEY_Q,
4136                                             recorder_binding, b);
4137         weston_compositor_add_debug_binding(compositor, KEY_W,
4138                                             renderer_switch_binding, b);
4139
4140         if (compositor->renderer->import_dmabuf) {
4141                 if (linux_dmabuf_setup(compositor) < 0)
4142                         weston_log("Error: initializing dmabuf "
4143                                    "support failed.\n");
4144         }
4145
4146         ret = weston_plugin_api_register(compositor, WESTON_DRM_OUTPUT_API_NAME,
4147                                          &api, sizeof(api));
4148
4149         if (ret < 0) {
4150                 weston_log("Failed to register output API.\n");
4151                 goto err_udev_monitor;
4152         }
4153
4154         return b;
4155
4156 err_udev_monitor:
4157         wl_event_source_remove(b->udev_drm_source);
4158         udev_monitor_unref(b->udev_monitor);
4159 err_drm_source:
4160         wl_event_source_remove(b->drm_source);
4161 err_udev_input:
4162         udev_input_destroy(&b->input);
4163 err_sprite:
4164         if (b->gbm)
4165                 gbm_device_destroy(b->gbm);
4166         destroy_sprites(b);
4167 err_udev_dev:
4168         udev_device_unref(drm_device);
4169 err_launcher:
4170         weston_launcher_destroy(compositor->launcher);
4171 err_udev:
4172         udev_unref(b->udev);
4173 err_compositor:
4174         weston_compositor_shutdown(compositor);
4175         free(b);
4176         return NULL;
4177 }
4178
4179 static void
4180 config_init_to_defaults(struct weston_drm_backend_config *config)
4181 {
4182 }
4183
4184 WL_EXPORT int
4185 weston_backend_init(struct weston_compositor *compositor,
4186                     struct weston_backend_config *config_base)
4187 {
4188         struct drm_backend *b;
4189         struct weston_drm_backend_config config = {{ 0, }};
4190
4191         if (config_base == NULL ||
4192             config_base->struct_version != WESTON_DRM_BACKEND_CONFIG_VERSION ||
4193             config_base->struct_size > sizeof(struct weston_drm_backend_config)) {
4194                 weston_log("drm backend config structure is invalid\n");
4195                 return -1;
4196         }
4197
4198         config_init_to_defaults(&config);
4199         memcpy(&config, config_base, config_base->struct_size);
4200
4201         b = drm_backend_create(compositor, &config);
4202         if (b == NULL)
4203                 return -1;
4204
4205         return 0;
4206 }