c34fc1c2311c1522f485d42b739479ed7b4c3144
[profile/ivi/weston-ivi-shell.git] / src / compositor-drm.c
1 /*
2  * Copyright © 2008-2011 Kristian Høgsberg
3  * Copyright © 2011 Intel Corporation
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and
6  * its documentation for any purpose is hereby granted without fee, provided
7  * that the above copyright notice appear in all copies and that both that
8  * copyright notice and this permission notice appear in supporting
9  * documentation, and that the name of the copyright holders not be used in
10  * advertising or publicity pertaining to distribution of the software
11  * without specific, written prior permission.  The copyright holders make
12  * no representations about the suitability of this software for any
13  * purpose.  It is provided "as is" without express or implied warranty.
14  *
15  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
20  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  */
23
24 #include "config.h"
25
26 #include <errno.h>
27 #include <stdlib.h>
28 #include <ctype.h>
29 #include <string.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <linux/input.h>
33 #include <linux/vt.h>
34 #include <assert.h>
35 #include <sys/mman.h>
36 #include <dlfcn.h>
37 #include <time.h>
38
39 #include <xf86drm.h>
40 #include <xf86drmMode.h>
41 #include <drm_fourcc.h>
42
43 #include <gbm.h>
44 #include <libbacklight.h>
45 #include <libudev.h>
46
47 #include "compositor.h"
48 #include "gl-renderer.h"
49 #include "pixman-renderer.h"
50 #include "udev-seat.h"
51 #include "launcher-util.h"
52 #include "vaapi-recorder.h"
53
54 #ifndef DRM_CAP_TIMESTAMP_MONOTONIC
55 #define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
56 #endif
57
58 static int option_current_mode = 0;
59
60 enum output_config {
61         OUTPUT_CONFIG_INVALID = 0,
62         OUTPUT_CONFIG_OFF,
63         OUTPUT_CONFIG_PREFERRED,
64         OUTPUT_CONFIG_CURRENT,
65         OUTPUT_CONFIG_MODE,
66         OUTPUT_CONFIG_MODELINE
67 };
68
69 struct drm_compositor {
70         struct weston_compositor base;
71
72         struct udev *udev;
73         struct wl_event_source *drm_source;
74
75         struct udev_monitor *udev_monitor;
76         struct wl_event_source *udev_drm_source;
77
78         struct {
79                 int id;
80                 int fd;
81                 char *filename;
82         } drm;
83         struct gbm_device *gbm;
84         uint32_t *crtcs;
85         int num_crtcs;
86         uint32_t crtc_allocator;
87         uint32_t connector_allocator;
88         struct wl_listener session_listener;
89         uint32_t format;
90
91         /* we need these parameters in order to not fail drmModeAddFB2()
92          * due to out of bounds dimensions, and then mistakenly set
93          * sprites_are_broken:
94          */
95         uint32_t min_width, max_width;
96         uint32_t min_height, max_height;
97         int no_addfb2;
98
99         struct wl_list sprite_list;
100         int sprites_are_broken;
101         int sprites_hidden;
102
103         int cursors_are_broken;
104
105         int use_pixman;
106
107         uint32_t prev_state;
108
109         clockid_t clock;
110         struct udev_input input;
111 };
112
113 struct drm_mode {
114         struct weston_mode base;
115         drmModeModeInfo mode_info;
116 };
117
118 struct drm_output;
119
120 struct drm_fb {
121         struct drm_output *output;
122         uint32_t fb_id, stride, handle, size;
123         int fd;
124         int is_client_buffer;
125         struct weston_buffer_reference buffer_ref;
126
127         /* Used by gbm fbs */
128         struct gbm_bo *bo;
129
130         /* Used by dumb fbs */
131         void *map;
132 };
133
134 struct drm_edid {
135         char eisa_id[13];
136         char monitor_name[13];
137         char pnp_id[5];
138         char serial_number[13];
139 };
140
141 struct drm_output {
142         struct weston_output   base;
143
144         uint32_t crtc_id;
145         int pipe;
146         uint32_t connector_id;
147         drmModeCrtcPtr original_crtc;
148         struct drm_edid edid;
149         drmModePropertyPtr dpms_prop;
150
151         int vblank_pending;
152         int page_flip_pending;
153         int destroy_pending;
154
155         struct gbm_surface *surface;
156         struct gbm_bo *cursor_bo[2];
157         struct weston_plane cursor_plane;
158         struct weston_plane fb_plane;
159         struct weston_view *cursor_view;
160         int current_cursor;
161         struct drm_fb *current, *next;
162         struct backlight *backlight;
163
164         struct drm_fb *dumb[2];
165         pixman_image_t *image[2];
166         int current_image;
167         pixman_region32_t previous_damage;
168
169         struct vaapi_recorder *recorder;
170         struct wl_listener recorder_frame_listener;
171 };
172
173 /*
174  * An output has a primary display plane plus zero or more sprites for
175  * blending display contents.
176  */
177 struct drm_sprite {
178         struct wl_list link;
179
180         struct weston_plane plane;
181
182         struct drm_fb *current, *next;
183         struct drm_output *output;
184         struct drm_compositor *compositor;
185
186         uint32_t possible_crtcs;
187         uint32_t plane_id;
188         uint32_t count_formats;
189
190         int32_t src_x, src_y;
191         uint32_t src_w, src_h;
192         uint32_t dest_x, dest_y;
193         uint32_t dest_w, dest_h;
194
195         uint32_t formats[];
196 };
197
198 struct drm_parameters {
199         int connector;
200         int tty;
201         int use_pixman;
202         const char *seat_id;
203 };
204
205 static struct gl_renderer_interface *gl_renderer;
206
207 static const char default_seat[] = "seat0";
208
209 static void
210 drm_output_set_cursor(struct drm_output *output);
211
212 static int
213 drm_sprite_crtc_supported(struct weston_output *output_base, uint32_t supported)
214 {
215         struct weston_compositor *ec = output_base->compositor;
216         struct drm_compositor *c =(struct drm_compositor *) ec;
217         struct drm_output *output = (struct drm_output *) output_base;
218         int crtc;
219
220         for (crtc = 0; crtc < c->num_crtcs; crtc++) {
221                 if (c->crtcs[crtc] != output->crtc_id)
222                         continue;
223
224                 if (supported & (1 << crtc))
225                         return -1;
226         }
227
228         return 0;
229 }
230
231 static void
232 drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
233 {
234         struct drm_fb *fb = data;
235         struct gbm_device *gbm = gbm_bo_get_device(bo);
236
237         if (fb->fb_id)
238                 drmModeRmFB(gbm_device_get_fd(gbm), fb->fb_id);
239
240         weston_buffer_reference(&fb->buffer_ref, NULL);
241
242         free(data);
243 }
244
245 static struct drm_fb *
246 drm_fb_create_dumb(struct drm_compositor *ec, unsigned width, unsigned height)
247 {
248         struct drm_fb *fb;
249         int ret;
250
251         struct drm_mode_create_dumb create_arg;
252         struct drm_mode_destroy_dumb destroy_arg;
253         struct drm_mode_map_dumb map_arg;
254
255         fb = zalloc(sizeof *fb);
256         if (!fb)
257                 return NULL;
258
259         memset(&create_arg, 0, sizeof create_arg);
260         create_arg.bpp = 32;
261         create_arg.width = width;
262         create_arg.height = height;
263
264         ret = drmIoctl(ec->drm.fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg);
265         if (ret)
266                 goto err_fb;
267
268         fb->handle = create_arg.handle;
269         fb->stride = create_arg.pitch;
270         fb->size = create_arg.size;
271         fb->fd = ec->drm.fd;
272
273         ret = drmModeAddFB(ec->drm.fd, width, height, 24, 32,
274                            fb->stride, fb->handle, &fb->fb_id);
275         if (ret)
276                 goto err_bo;
277
278         memset(&map_arg, 0, sizeof map_arg);
279         map_arg.handle = fb->handle;
280         ret = drmIoctl(fb->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_arg);
281         if (ret)
282                 goto err_add_fb;
283
284         fb->map = mmap(0, fb->size, PROT_WRITE,
285                        MAP_SHARED, ec->drm.fd, map_arg.offset);
286         if (fb->map == MAP_FAILED)
287                 goto err_add_fb;
288
289         return fb;
290
291 err_add_fb:
292         drmModeRmFB(ec->drm.fd, fb->fb_id);
293 err_bo:
294         memset(&destroy_arg, 0, sizeof(destroy_arg));
295         destroy_arg.handle = create_arg.handle;
296         drmIoctl(ec->drm.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
297 err_fb:
298         free(fb);
299         return NULL;
300 }
301
302 static void
303 drm_fb_destroy_dumb(struct drm_fb *fb)
304 {
305         struct drm_mode_destroy_dumb destroy_arg;
306
307         if (!fb->map)
308                 return;
309
310         if (fb->fb_id)
311                 drmModeRmFB(fb->fd, fb->fb_id);
312
313         weston_buffer_reference(&fb->buffer_ref, NULL);
314
315         munmap(fb->map, fb->size);
316
317         memset(&destroy_arg, 0, sizeof(destroy_arg));
318         destroy_arg.handle = fb->handle;
319         drmIoctl(fb->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
320
321         free(fb);
322 }
323
324 static struct drm_fb *
325 drm_fb_get_from_bo(struct gbm_bo *bo,
326                    struct drm_compositor *compositor, uint32_t format)
327 {
328         struct drm_fb *fb = gbm_bo_get_user_data(bo);
329         uint32_t width, height;
330         uint32_t handles[4], pitches[4], offsets[4];
331         int ret;
332
333         if (fb)
334                 return fb;
335
336         fb = calloc(1, sizeof *fb);
337         if (!fb)
338                 return NULL;
339
340         fb->bo = bo;
341
342         width = gbm_bo_get_width(bo);
343         height = gbm_bo_get_height(bo);
344         fb->stride = gbm_bo_get_stride(bo);
345         fb->handle = gbm_bo_get_handle(bo).u32;
346         fb->size = fb->stride * height;
347         fb->fd = compositor->drm.fd;
348
349         if (compositor->min_width > width || width > compositor->max_width ||
350             compositor->min_height > height ||
351             height > compositor->max_height) {
352                 weston_log("bo geometry out of bounds\n");
353                 goto err_free;
354         }
355
356         ret = -1;
357
358         if (format && !compositor->no_addfb2) {
359                 handles[0] = fb->handle;
360                 pitches[0] = fb->stride;
361                 offsets[0] = 0;
362
363                 ret = drmModeAddFB2(compositor->drm.fd, width, height,
364                                     format, handles, pitches, offsets,
365                                     &fb->fb_id, 0);
366                 if (ret) {
367                         weston_log("addfb2 failed: %m\n");
368                         compositor->no_addfb2 = 1;
369                         compositor->sprites_are_broken = 1;
370                 }
371         }
372
373         if (ret)
374                 ret = drmModeAddFB(compositor->drm.fd, width, height, 24, 32,
375                                    fb->stride, fb->handle, &fb->fb_id);
376
377         if (ret) {
378                 weston_log("failed to create kms fb: %m\n");
379                 goto err_free;
380         }
381
382         gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback);
383
384         return fb;
385
386 err_free:
387         free(fb);
388         return NULL;
389 }
390
391 static void
392 drm_fb_set_buffer(struct drm_fb *fb, struct weston_buffer *buffer)
393 {
394         assert(fb->buffer_ref.buffer == NULL);
395
396         fb->is_client_buffer = 1;
397
398         weston_buffer_reference(&fb->buffer_ref, buffer);
399 }
400
401 static void
402 drm_output_release_fb(struct drm_output *output, struct drm_fb *fb)
403 {
404         if (!fb)
405                 return;
406
407         if (fb->map &&
408             (fb != output->dumb[0] && fb != output->dumb[1])) {
409                 drm_fb_destroy_dumb(fb);
410         } else if (fb->bo) {
411                 if (fb->is_client_buffer)
412                         gbm_bo_destroy(fb->bo);
413                 else
414                         gbm_surface_release_buffer(output->surface,
415                                                    fb->bo);
416         }
417 }
418
419 static uint32_t
420 drm_output_check_scanout_format(struct drm_output *output,
421                                 struct weston_surface *es, struct gbm_bo *bo)
422 {
423         struct drm_compositor *c =
424                 (struct drm_compositor *) output->base.compositor;
425         uint32_t format;
426         pixman_region32_t r;
427
428         format = gbm_bo_get_format(bo);
429
430         if (format == GBM_FORMAT_ARGB8888) {
431                 /* We can scanout an ARGB buffer if the surface's
432                  * opaque region covers the whole output, but we have
433                  * to use XRGB as the KMS format code. */
434                 pixman_region32_init(&r);
435                 pixman_region32_subtract(&r, &output->base.region,
436                                          &es->opaque);
437
438                 if (!pixman_region32_not_empty(&r))
439                         format = GBM_FORMAT_XRGB8888;
440
441                 pixman_region32_fini(&r);
442         }
443
444         if (c->format == format)
445                 return format;
446
447         return 0;
448 }
449
450 static struct weston_plane *
451 drm_output_prepare_scanout_view(struct weston_output *_output,
452                                 struct weston_view *ev)
453 {
454         struct drm_output *output = (struct drm_output *) _output;
455         struct drm_compositor *c =
456                 (struct drm_compositor *) output->base.compositor;
457         struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
458         struct gbm_bo *bo;
459         uint32_t format;
460
461         if (ev->geometry.x != output->base.x ||
462             ev->geometry.y != output->base.y ||
463             buffer == NULL || c->gbm == NULL ||
464             buffer->width != output->base.current_mode->width ||
465             buffer->height != output->base.current_mode->height ||
466             output->base.transform != ev->surface->buffer_viewport.transform ||
467             ev->transform.enabled)
468                 return NULL;
469
470         bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
471                            buffer->resource, GBM_BO_USE_SCANOUT);
472
473         /* Unable to use the buffer for scanout */
474         if (!bo)
475                 return NULL;
476
477         format = drm_output_check_scanout_format(output, ev->surface, bo);
478         if (format == 0) {
479                 gbm_bo_destroy(bo);
480                 return NULL;
481         }
482
483         output->next = drm_fb_get_from_bo(bo, c, format);
484         if (!output->next) {
485                 gbm_bo_destroy(bo);
486                 return NULL;
487         }
488
489         drm_fb_set_buffer(output->next, buffer);
490
491         return &output->fb_plane;
492 }
493
494 static void
495 drm_output_render_gl(struct drm_output *output, pixman_region32_t *damage)
496 {
497         struct drm_compositor *c =
498                 (struct drm_compositor *) output->base.compositor;
499         struct gbm_bo *bo;
500
501         c->base.renderer->repaint_output(&output->base, damage);
502
503         bo = gbm_surface_lock_front_buffer(output->surface);
504         if (!bo) {
505                 weston_log("failed to lock front buffer: %m\n");
506                 return;
507         }
508
509         output->next = drm_fb_get_from_bo(bo, c, c->format);
510         if (!output->next) {
511                 weston_log("failed to get drm_fb for bo\n");
512                 gbm_surface_release_buffer(output->surface, bo);
513                 return;
514         }
515 }
516
517 static void
518 drm_output_render_pixman(struct drm_output *output, pixman_region32_t *damage)
519 {
520         struct weston_compositor *ec = output->base.compositor;
521         pixman_region32_t total_damage, previous_damage;
522
523         pixman_region32_init(&total_damage);
524         pixman_region32_init(&previous_damage);
525
526         pixman_region32_copy(&previous_damage, damage);
527
528         pixman_region32_union(&total_damage, damage, &output->previous_damage);
529         pixman_region32_copy(&output->previous_damage, &previous_damage);
530
531         output->current_image ^= 1;
532
533         output->next = output->dumb[output->current_image];
534         pixman_renderer_output_set_buffer(&output->base,
535                                           output->image[output->current_image]);
536
537         ec->renderer->repaint_output(&output->base, &total_damage);
538
539         pixman_region32_fini(&total_damage);
540         pixman_region32_fini(&previous_damage);
541 }
542
543 static void
544 drm_output_render(struct drm_output *output, pixman_region32_t *damage)
545 {
546         struct drm_compositor *c =
547                 (struct drm_compositor *) output->base.compositor;
548
549         if (c->use_pixman)
550                 drm_output_render_pixman(output, damage);
551         else
552                 drm_output_render_gl(output, damage);
553
554         pixman_region32_subtract(&c->base.primary_plane.damage,
555                                  &c->base.primary_plane.damage, damage);
556 }
557
558 static void
559 drm_output_set_gamma(struct weston_output *output_base,
560                      uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b)
561 {
562         int rc;
563         struct drm_output *output = (struct drm_output *) output_base;
564         struct drm_compositor *compositor = (struct drm_compositor *) output->base.compositor;
565
566         /* check */
567         if (output_base->gamma_size != size)
568                 return;
569         if (!output->original_crtc)
570                 return;
571
572         rc = drmModeCrtcSetGamma(compositor->drm.fd,
573                                  output->crtc_id,
574                                  size, r, g, b);
575         if (rc)
576                 weston_log("set gamma failed: %m\n");
577 }
578
579 static int
580 drm_output_repaint(struct weston_output *output_base,
581                    pixman_region32_t *damage)
582 {
583         struct drm_output *output = (struct drm_output *) output_base;
584         struct drm_compositor *compositor =
585                 (struct drm_compositor *) output->base.compositor;
586         struct drm_sprite *s;
587         struct drm_mode *mode;
588         int ret = 0;
589
590         if (output->destroy_pending)
591                 return -1;
592
593         if (!output->next)
594                 drm_output_render(output, damage);
595         if (!output->next)
596                 return -1;
597
598         mode = container_of(output->base.current_mode, struct drm_mode, base);
599         if (!output->current ||
600             output->current->stride != output->next->stride) {
601                 ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id,
602                                      output->next->fb_id, 0, 0,
603                                      &output->connector_id, 1,
604                                      &mode->mode_info);
605                 if (ret) {
606                         weston_log("set mode failed: %m\n");
607                         goto err_pageflip;
608                 }
609                 output_base->set_dpms(output_base, WESTON_DPMS_ON);
610         }
611
612         if (drmModePageFlip(compositor->drm.fd, output->crtc_id,
613                             output->next->fb_id,
614                             DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
615                 weston_log("queueing pageflip failed: %m\n");
616                 goto err_pageflip;
617         }
618
619         output->page_flip_pending = 1;
620
621         drm_output_set_cursor(output);
622
623         /*
624          * Now, update all the sprite surfaces
625          */
626         wl_list_for_each(s, &compositor->sprite_list, link) {
627                 uint32_t flags = 0, fb_id = 0;
628                 drmVBlank vbl = {
629                         .request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT,
630                         .request.sequence = 1,
631                 };
632
633                 if ((!s->current && !s->next) ||
634                     !drm_sprite_crtc_supported(output_base, s->possible_crtcs))
635                         continue;
636
637                 if (s->next && !compositor->sprites_hidden)
638                         fb_id = s->next->fb_id;
639
640                 ret = drmModeSetPlane(compositor->drm.fd, s->plane_id,
641                                       output->crtc_id, fb_id, flags,
642                                       s->dest_x, s->dest_y,
643                                       s->dest_w, s->dest_h,
644                                       s->src_x, s->src_y,
645                                       s->src_w, s->src_h);
646                 if (ret)
647                         weston_log("setplane failed: %d: %s\n",
648                                 ret, strerror(errno));
649
650                 if (output->pipe > 0)
651                         vbl.request.type |= DRM_VBLANK_SECONDARY;
652
653                 /*
654                  * Queue a vblank signal so we know when the surface
655                  * becomes active on the display or has been replaced.
656                  */
657                 vbl.request.signal = (unsigned long)s;
658                 ret = drmWaitVBlank(compositor->drm.fd, &vbl);
659                 if (ret) {
660                         weston_log("vblank event request failed: %d: %s\n",
661                                 ret, strerror(errno));
662                 }
663
664                 s->output = output;
665                 output->vblank_pending = 1;
666         }
667
668         return 0;
669
670 err_pageflip:
671         if (output->next) {
672                 drm_output_release_fb(output, output->next);
673                 output->next = NULL;
674         }
675
676         return -1;
677 }
678
679 static void
680 drm_output_start_repaint_loop(struct weston_output *output_base)
681 {
682         struct drm_output *output = (struct drm_output *) output_base;
683         struct drm_compositor *compositor = (struct drm_compositor *)
684                 output_base->compositor;
685         uint32_t fb_id;
686         uint32_t msec;
687         struct timespec ts;
688
689         if (output->destroy_pending)
690                 return;
691
692         if (!output->current) {
693                 /* We can't page flip if there's no mode set */
694                 goto finish_frame;
695         }
696
697         fb_id = output->current->fb_id;
698
699         if (drmModePageFlip(compositor->drm.fd, output->crtc_id, fb_id,
700                             DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
701                 weston_log("queueing pageflip failed: %m\n");
702                 goto finish_frame;
703         }
704
705         return;
706
707 finish_frame:
708         /* if we cannot page-flip, immediately finish frame */
709         clock_gettime(compositor->clock, &ts);
710         msec = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
711         weston_output_finish_frame(output_base, msec);
712 }
713
714 static void
715 vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec,
716                void *data)
717 {
718         struct drm_sprite *s = (struct drm_sprite *)data;
719         struct drm_output *output = s->output;
720         uint32_t msecs;
721
722         output->vblank_pending = 0;
723
724         drm_output_release_fb(output, s->current);
725         s->current = s->next;
726         s->next = NULL;
727
728         if (!output->page_flip_pending) {
729                 msecs = sec * 1000 + usec / 1000;
730                 weston_output_finish_frame(&output->base, msecs);
731         }
732 }
733
734 static void
735 drm_output_destroy(struct weston_output *output_base);
736
737 static void
738 page_flip_handler(int fd, unsigned int frame,
739                   unsigned int sec, unsigned int usec, void *data)
740 {
741         struct drm_output *output = (struct drm_output *) data;
742         uint32_t msecs;
743
744         /* We don't set page_flip_pending on start_repaint_loop, in that case
745          * we just want to page flip to the current buffer to get an accurate
746          * timestamp */
747         if (output->page_flip_pending) {
748                 drm_output_release_fb(output, output->current);
749                 output->current = output->next;
750                 output->next = NULL;
751         }
752
753         output->page_flip_pending = 0;
754
755         if (output->destroy_pending)
756                 drm_output_destroy(&output->base);
757         else if (!output->vblank_pending) {
758                 msecs = sec * 1000 + usec / 1000;
759                 weston_output_finish_frame(&output->base, msecs);
760
761                 /* We can't call this from frame_notify, because the output's
762                  * repaint needed flag is cleared just after that */
763                 if (output->recorder)
764                         weston_output_schedule_repaint(&output->base);
765         }
766 }
767
768 static uint32_t
769 drm_output_check_sprite_format(struct drm_sprite *s,
770                                struct weston_view *ev, struct gbm_bo *bo)
771 {
772         uint32_t i, format;
773
774         format = gbm_bo_get_format(bo);
775
776         if (format == GBM_FORMAT_ARGB8888) {
777                 pixman_region32_t r;
778
779                 pixman_region32_init_rect(&r, 0, 0,
780                                           ev->geometry.width,
781                                           ev->geometry.height);
782                 pixman_region32_subtract(&r, &r, &ev->surface->opaque);
783
784                 if (!pixman_region32_not_empty(&r))
785                         format = GBM_FORMAT_XRGB8888;
786
787                 pixman_region32_fini(&r);
788         }
789
790         for (i = 0; i < s->count_formats; i++)
791                 if (s->formats[i] == format)
792                         return format;
793
794         return 0;
795 }
796
797 static int
798 drm_view_transform_supported(struct weston_view *ev)
799 {
800         return !ev->transform.enabled ||
801                 (ev->transform.matrix.type < WESTON_MATRIX_TRANSFORM_ROTATE);
802 }
803
804 static struct weston_plane *
805 drm_output_prepare_overlay_view(struct weston_output *output_base,
806                                 struct weston_view *ev)
807 {
808         struct weston_compositor *ec = output_base->compositor;
809         struct drm_compositor *c =(struct drm_compositor *) ec;
810         struct drm_sprite *s;
811         int found = 0;
812         struct gbm_bo *bo;
813         pixman_region32_t dest_rect, src_rect;
814         pixman_box32_t *box, tbox;
815         uint32_t format;
816         wl_fixed_t sx1, sy1, sx2, sy2;
817
818         if (c->gbm == NULL)
819                 return NULL;
820
821         if (ev->surface->buffer_viewport.transform != output_base->transform)
822                 return NULL;
823
824         if (ev->surface->buffer_viewport.scale != output_base->current_scale)
825                 return NULL;
826
827         if (c->sprites_are_broken)
828                 return NULL;
829
830         if (ev->output_mask != (1u << output_base->id))
831                 return NULL;
832
833         if (ev->surface->buffer_ref.buffer == NULL)
834                 return NULL;
835
836         if (ev->alpha != 1.0f)
837                 return NULL;
838
839         if (wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource))
840                 return NULL;
841
842         if (!drm_view_transform_supported(ev))
843                 return NULL;
844
845         wl_list_for_each(s, &c->sprite_list, link) {
846                 if (!drm_sprite_crtc_supported(output_base, s->possible_crtcs))
847                         continue;
848
849                 if (!s->next) {
850                         found = 1;
851                         break;
852                 }
853         }
854
855         /* No sprites available */
856         if (!found)
857                 return NULL;
858
859         bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
860                            ev->surface->buffer_ref.buffer->resource,
861                            GBM_BO_USE_SCANOUT);
862         if (!bo)
863                 return NULL;
864
865         format = drm_output_check_sprite_format(s, ev, bo);
866         if (format == 0) {
867                 gbm_bo_destroy(bo);
868                 return NULL;
869         }
870
871         s->next = drm_fb_get_from_bo(bo, c, format);
872         if (!s->next) {
873                 gbm_bo_destroy(bo);
874                 return NULL;
875         }
876
877         drm_fb_set_buffer(s->next, ev->surface->buffer_ref.buffer);
878
879         box = pixman_region32_extents(&ev->transform.boundingbox);
880         s->plane.x = box->x1;
881         s->plane.y = box->y1;
882
883         /*
884          * Calculate the source & dest rects properly based on actual
885          * position (note the caller has called weston_surface_update_transform()
886          * for us already).
887          */
888         pixman_region32_init(&dest_rect);
889         pixman_region32_intersect(&dest_rect, &ev->transform.boundingbox,
890                                   &output_base->region);
891         pixman_region32_translate(&dest_rect, -output_base->x, -output_base->y);
892         box = pixman_region32_extents(&dest_rect);
893         tbox = weston_transformed_rect(output_base->width,
894                                        output_base->height,
895                                        output_base->transform,
896                                        output_base->current_scale,
897                                        *box);
898         s->dest_x = tbox.x1;
899         s->dest_y = tbox.y1;
900         s->dest_w = tbox.x2 - tbox.x1;
901         s->dest_h = tbox.y2 - tbox.y1;
902         pixman_region32_fini(&dest_rect);
903
904         pixman_region32_init(&src_rect);
905         pixman_region32_intersect(&src_rect, &ev->transform.boundingbox,
906                                   &output_base->region);
907         box = pixman_region32_extents(&src_rect);
908
909         weston_view_from_global_fixed(ev,
910                                       wl_fixed_from_int(box->x1),
911                                       wl_fixed_from_int(box->y1),
912                                       &sx1, &sy1);
913         weston_view_from_global_fixed(ev,
914                                       wl_fixed_from_int(box->x2),
915                                       wl_fixed_from_int(box->y2),
916                                       &sx2, &sy2);
917
918         if (sx1 < 0)
919                 sx1 = 0;
920         if (sy1 < 0)
921                 sy1 = 0;
922         if (sx2 > wl_fixed_from_int(ev->geometry.width))
923                 sx2 = wl_fixed_from_int(ev->geometry.width);
924         if (sy2 > wl_fixed_from_int(ev->geometry.height))
925                 sy2 = wl_fixed_from_int(ev->geometry.height);
926
927         tbox.x1 = sx1;
928         tbox.y1 = sy1;
929         tbox.x2 = sx2;
930         tbox.y2 = sy2;
931
932         tbox = weston_transformed_rect(wl_fixed_from_int(ev->geometry.width),
933                                        wl_fixed_from_int(ev->geometry.height),
934                                        ev->surface->buffer_viewport.transform,
935                                        ev->surface->buffer_viewport.scale,
936                                        tbox);
937
938         s->src_x = tbox.x1 << 8;
939         s->src_y = tbox.y1 << 8;
940         s->src_w = (tbox.x2 - tbox.x1) << 8;
941         s->src_h = (tbox.y2 - tbox.y1) << 8;
942         pixman_region32_fini(&src_rect);
943
944         return &s->plane;
945 }
946
947 static struct weston_plane *
948 drm_output_prepare_cursor_view(struct weston_output *output_base,
949                                struct weston_view *ev)
950 {
951         struct drm_compositor *c =
952                 (struct drm_compositor *) output_base->compositor;
953         struct drm_output *output = (struct drm_output *) output_base;
954
955         if (c->gbm == NULL)
956                 return NULL;
957         if (output->base.transform != WL_OUTPUT_TRANSFORM_NORMAL)
958                 return NULL;
959         if (output->cursor_view)
960                 return NULL;
961         if (ev->output_mask != (1u << output_base->id))
962                 return NULL;
963         if (c->cursors_are_broken)
964                 return NULL;
965         if (ev->surface->buffer_ref.buffer == NULL ||
966             !wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource) ||
967             ev->geometry.width > 64 || ev->geometry.height > 64)
968                 return NULL;
969
970         output->cursor_view = ev;
971
972         return &output->cursor_plane;
973 }
974
975 static void
976 drm_output_set_cursor(struct drm_output *output)
977 {
978         struct weston_view *ev = output->cursor_view;
979         struct weston_buffer *buffer;
980         struct drm_compositor *c =
981                 (struct drm_compositor *) output->base.compositor;
982         EGLint handle, stride;
983         struct gbm_bo *bo;
984         uint32_t buf[64 * 64];
985         unsigned char *s;
986         int i, x, y;
987
988         output->cursor_view = NULL;
989         if (ev == NULL) {
990                 drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0);
991                 return;
992         }
993
994         buffer = ev->surface->buffer_ref.buffer;
995
996         if (buffer &&
997             pixman_region32_not_empty(&output->cursor_plane.damage)) {
998                 pixman_region32_fini(&output->cursor_plane.damage);
999                 pixman_region32_init(&output->cursor_plane.damage);
1000                 output->current_cursor ^= 1;
1001                 bo = output->cursor_bo[output->current_cursor];
1002                 memset(buf, 0, sizeof buf);
1003                 stride = wl_shm_buffer_get_stride(buffer->shm_buffer);
1004                 s = wl_shm_buffer_get_data(buffer->shm_buffer);
1005                 wl_shm_buffer_begin_access(buffer->shm_buffer);
1006                 for (i = 0; i < ev->geometry.height; i++)
1007                         memcpy(buf + i * 64, s + i * stride,
1008                                ev->geometry.width * 4);
1009                 wl_shm_buffer_end_access(buffer->shm_buffer);
1010
1011                 if (gbm_bo_write(bo, buf, sizeof buf) < 0)
1012                         weston_log("failed update cursor: %m\n");
1013
1014                 handle = gbm_bo_get_handle(bo).s32;
1015                 if (drmModeSetCursor(c->drm.fd,
1016                                      output->crtc_id, handle, 64, 64)) {
1017                         weston_log("failed to set cursor: %m\n");
1018                         c->cursors_are_broken = 1;
1019                 }
1020         }
1021
1022         x = (ev->geometry.x - output->base.x) * output->base.current_scale;
1023         y = (ev->geometry.y - output->base.y) * output->base.current_scale;
1024         if (output->cursor_plane.x != x || output->cursor_plane.y != y) {
1025                 if (drmModeMoveCursor(c->drm.fd, output->crtc_id, x, y)) {
1026                         weston_log("failed to move cursor: %m\n");
1027                         c->cursors_are_broken = 1;
1028                 }
1029
1030                 output->cursor_plane.x = x;
1031                 output->cursor_plane.y = y;
1032         }
1033 }
1034
1035 static void
1036 drm_assign_planes(struct weston_output *output)
1037 {
1038         struct drm_compositor *c =
1039                 (struct drm_compositor *) output->compositor;
1040         struct weston_view *ev, *next;
1041         pixman_region32_t overlap, surface_overlap;
1042         struct weston_plane *primary, *next_plane;
1043
1044         /*
1045          * Find a surface for each sprite in the output using some heuristics:
1046          * 1) size
1047          * 2) frequency of update
1048          * 3) opacity (though some hw might support alpha blending)
1049          * 4) clipping (this can be fixed with color keys)
1050          *
1051          * The idea is to save on blitting since this should save power.
1052          * If we can get a large video surface on the sprite for example,
1053          * the main display surface may not need to update at all, and
1054          * the client buffer can be used directly for the sprite surface
1055          * as we do for flipping full screen surfaces.
1056          */
1057         pixman_region32_init(&overlap);
1058         primary = &c->base.primary_plane;
1059
1060         wl_list_for_each_safe(ev, next, &c->base.view_list, link) {
1061                 struct weston_surface *es = ev->surface;
1062
1063                 /* Test whether this buffer can ever go into a plane:
1064                  * non-shm, or small enough to be a cursor.
1065                  *
1066                  * Also, keep a reference when using the pixman renderer.
1067                  * That makes it possible to do a seamless switch to the GL
1068                  * renderer and since the pixman renderer keeps a reference
1069                  * to the buffer anyway, there is no side effects.
1070                  */
1071                 if (c->use_pixman ||
1072                     (es->buffer_ref.buffer &&
1073                     (!wl_shm_buffer_get(es->buffer_ref.buffer->resource) ||
1074                      (ev->geometry.width <= 64 && ev->geometry.height <= 64))))
1075                         es->keep_buffer = 1;
1076                 else
1077                         es->keep_buffer = 0;
1078
1079                 pixman_region32_init(&surface_overlap);
1080                 pixman_region32_intersect(&surface_overlap, &overlap,
1081                                           &ev->transform.boundingbox);
1082
1083                 next_plane = NULL;
1084                 if (pixman_region32_not_empty(&surface_overlap))
1085                         next_plane = primary;
1086                 if (next_plane == NULL)
1087                         next_plane = drm_output_prepare_cursor_view(output, ev);
1088                 if (next_plane == NULL)
1089                         next_plane = drm_output_prepare_scanout_view(output, ev);
1090                 if (next_plane == NULL)
1091                         next_plane = drm_output_prepare_overlay_view(output, ev);
1092                 if (next_plane == NULL)
1093                         next_plane = primary;
1094                 weston_view_move_to_plane(ev, next_plane);
1095                 if (next_plane == primary)
1096                         pixman_region32_union(&overlap, &overlap,
1097                                               &ev->transform.boundingbox);
1098
1099                 pixman_region32_fini(&surface_overlap);
1100         }
1101         pixman_region32_fini(&overlap);
1102 }
1103
1104 static void
1105 drm_output_fini_pixman(struct drm_output *output);
1106
1107 static void
1108 drm_output_destroy(struct weston_output *output_base)
1109 {
1110         struct drm_output *output = (struct drm_output *) output_base;
1111         struct drm_compositor *c =
1112                 (struct drm_compositor *) output->base.compositor;
1113         drmModeCrtcPtr origcrtc = output->original_crtc;
1114
1115         if (output->page_flip_pending) {
1116                 output->destroy_pending = 1;
1117                 weston_log("destroy output while page flip pending\n");
1118                 return;
1119         }
1120
1121         if (output->backlight)
1122                 backlight_destroy(output->backlight);
1123
1124         drmModeFreeProperty(output->dpms_prop);
1125
1126         /* Turn off hardware cursor */
1127         drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0);
1128
1129         /* Restore original CRTC state */
1130         drmModeSetCrtc(c->drm.fd, origcrtc->crtc_id, origcrtc->buffer_id,
1131                        origcrtc->x, origcrtc->y,
1132                        &output->connector_id, 1, &origcrtc->mode);
1133         drmModeFreeCrtc(origcrtc);
1134
1135         c->crtc_allocator &= ~(1 << output->crtc_id);
1136         c->connector_allocator &= ~(1 << output->connector_id);
1137
1138         if (c->use_pixman) {
1139                 drm_output_fini_pixman(output);
1140         } else {
1141                 gl_renderer->output_destroy(output_base);
1142                 gbm_surface_destroy(output->surface);
1143         }
1144
1145         weston_plane_release(&output->fb_plane);
1146         weston_plane_release(&output->cursor_plane);
1147
1148         weston_output_destroy(&output->base);
1149         wl_list_remove(&output->base.link);
1150
1151         free(output);
1152 }
1153
1154 static struct drm_mode *
1155 choose_mode (struct drm_output *output, struct weston_mode *target_mode)
1156 {
1157         struct drm_mode *tmp_mode = NULL, *mode;
1158
1159         if (output->base.current_mode->width == target_mode->width &&
1160             output->base.current_mode->height == target_mode->height &&
1161             (output->base.current_mode->refresh == target_mode->refresh ||
1162              target_mode->refresh == 0))
1163                 return (struct drm_mode *)output->base.current_mode;
1164
1165         wl_list_for_each(mode, &output->base.mode_list, base.link) {
1166                 if (mode->mode_info.hdisplay == target_mode->width &&
1167                     mode->mode_info.vdisplay == target_mode->height) {
1168                         if (mode->mode_info.vrefresh == target_mode->refresh || 
1169                             target_mode->refresh == 0) {
1170                                 return mode;
1171                         } else if (!tmp_mode) 
1172                                 tmp_mode = mode;
1173                 }
1174         }
1175
1176         return tmp_mode;
1177 }
1178
1179 static int
1180 drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec);
1181 static int
1182 drm_output_init_pixman(struct drm_output *output, struct drm_compositor *c);
1183
1184 static int
1185 drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mode)
1186 {
1187         struct drm_output *output;
1188         struct drm_mode *drm_mode;
1189         struct drm_compositor *ec;
1190
1191         if (output_base == NULL) {
1192                 weston_log("output is NULL.\n");
1193                 return -1;
1194         }
1195
1196         if (mode == NULL) {
1197                 weston_log("mode is NULL.\n");
1198                 return -1;
1199         }
1200
1201         ec = (struct drm_compositor *)output_base->compositor;
1202         output = (struct drm_output *)output_base;
1203         drm_mode  = choose_mode (output, mode);
1204
1205         if (!drm_mode) {
1206                 weston_log("%s, invalid resolution:%dx%d\n", __func__, mode->width, mode->height);
1207                 return -1;
1208         }
1209
1210         if (&drm_mode->base == output->base.current_mode)
1211                 return 0;
1212
1213         output->base.current_mode->flags = 0;
1214
1215         output->base.current_mode = &drm_mode->base;
1216         output->base.current_mode->flags =
1217                 WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
1218
1219         /* reset rendering stuff. */
1220         drm_output_release_fb(output, output->current);
1221         drm_output_release_fb(output, output->next);
1222         output->current = output->next = NULL;
1223
1224         if (ec->use_pixman) {
1225                 drm_output_fini_pixman(output);
1226                 if (drm_output_init_pixman(output, ec) < 0) {
1227                         weston_log("failed to init output pixman state with "
1228                                    "new mode\n");
1229                         return -1;
1230                 }
1231         } else {
1232                 gl_renderer->output_destroy(&output->base);
1233                 gbm_surface_destroy(output->surface);
1234
1235                 if (drm_output_init_egl(output, ec) < 0) {
1236                         weston_log("failed to init output egl state with "
1237                                    "new mode");
1238                         return -1;
1239                 }
1240         }
1241
1242         return 0;
1243 }
1244
1245 static int
1246 on_drm_input(int fd, uint32_t mask, void *data)
1247 {
1248         drmEventContext evctx;
1249
1250         memset(&evctx, 0, sizeof evctx);
1251         evctx.version = DRM_EVENT_CONTEXT_VERSION;
1252         evctx.page_flip_handler = page_flip_handler;
1253         evctx.vblank_handler = vblank_handler;
1254         drmHandleEvent(fd, &evctx);
1255
1256         return 1;
1257 }
1258
1259 static int
1260 init_drm(struct drm_compositor *ec, struct udev_device *device)
1261 {
1262         const char *filename, *sysnum;
1263         uint64_t cap;
1264         int fd, ret;
1265
1266         sysnum = udev_device_get_sysnum(device);
1267         if (sysnum)
1268                 ec->drm.id = atoi(sysnum);
1269         if (!sysnum || ec->drm.id < 0) {
1270                 weston_log("cannot get device sysnum\n");
1271                 return -1;
1272         }
1273
1274         filename = udev_device_get_devnode(device);
1275         fd = weston_launcher_open(ec->base.launcher, filename, O_RDWR);
1276         if (fd < 0) {
1277                 /* Probably permissions error */
1278                 weston_log("couldn't open %s, skipping\n",
1279                         udev_device_get_devnode(device));
1280                 return -1;
1281         }
1282
1283         weston_log("using %s\n", filename);
1284
1285         ec->drm.fd = fd;
1286         ec->drm.filename = strdup(filename);
1287
1288         ret = drmGetCap(fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap);
1289         if (ret == 0 && cap == 1)
1290                 ec->clock = CLOCK_MONOTONIC;
1291         else
1292                 ec->clock = CLOCK_REALTIME;
1293
1294         return 0;
1295 }
1296
1297 static struct gbm_device *
1298 create_gbm_device(int fd)
1299 {
1300         struct gbm_device *gbm;
1301
1302         gl_renderer = weston_load_module("gl-renderer.so",
1303                                          "gl_renderer_interface");
1304         if (!gl_renderer)
1305                 return NULL;
1306
1307         /* GBM will load a dri driver, but even though they need symbols from
1308          * libglapi, in some version of Mesa they are not linked to it. Since
1309          * only the gl-renderer module links to it, the call above won't make
1310          * these symbols globally available, and loading the DRI driver fails.
1311          * Workaround this by dlopen()'ing libglapi with RTLD_GLOBAL. */
1312         dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL);
1313
1314         gbm = gbm_create_device(fd);
1315
1316         return gbm;
1317 }
1318
1319 static int
1320 drm_compositor_create_gl_renderer(struct drm_compositor *ec)
1321 {
1322         EGLint format;
1323
1324         format = ec->format;
1325         if (gl_renderer->create(&ec->base, ec->gbm,
1326                                gl_renderer->opaque_attribs, &format) < 0) {
1327                 return -1;
1328         }
1329
1330         return 0;
1331 }
1332
1333 static int
1334 init_egl(struct drm_compositor *ec)
1335 {
1336         ec->gbm = create_gbm_device(ec->drm.fd);
1337
1338         if (!ec->gbm)
1339                 return -1;
1340
1341         if (drm_compositor_create_gl_renderer(ec) < 0) {
1342                 gbm_device_destroy(ec->gbm);
1343                 return -1;
1344         }
1345
1346         return 0;
1347 }
1348
1349 static int
1350 init_pixman(struct drm_compositor *ec)
1351 {
1352         return pixman_renderer_init(&ec->base);
1353 }
1354
1355 static struct drm_mode *
1356 drm_output_add_mode(struct drm_output *output, drmModeModeInfo *info)
1357 {
1358         struct drm_mode *mode;
1359         uint64_t refresh;
1360
1361         mode = malloc(sizeof *mode);
1362         if (mode == NULL)
1363                 return NULL;
1364
1365         mode->base.flags = 0;
1366         mode->base.width = info->hdisplay;
1367         mode->base.height = info->vdisplay;
1368
1369         /* Calculate higher precision (mHz) refresh rate */
1370         refresh = (info->clock * 1000000LL / info->htotal +
1371                    info->vtotal / 2) / info->vtotal;
1372
1373         if (info->flags & DRM_MODE_FLAG_INTERLACE)
1374                 refresh *= 2;
1375         if (info->flags & DRM_MODE_FLAG_DBLSCAN)
1376                 refresh /= 2;
1377         if (info->vscan > 1)
1378             refresh /= info->vscan;
1379
1380         mode->base.refresh = refresh;
1381         mode->mode_info = *info;
1382
1383         if (info->type & DRM_MODE_TYPE_PREFERRED)
1384                 mode->base.flags |= WL_OUTPUT_MODE_PREFERRED;
1385
1386         wl_list_insert(output->base.mode_list.prev, &mode->base.link);
1387
1388         return mode;
1389 }
1390
1391 static int
1392 drm_subpixel_to_wayland(int drm_value)
1393 {
1394         switch (drm_value) {
1395         default:
1396         case DRM_MODE_SUBPIXEL_UNKNOWN:
1397                 return WL_OUTPUT_SUBPIXEL_UNKNOWN;
1398         case DRM_MODE_SUBPIXEL_NONE:
1399                 return WL_OUTPUT_SUBPIXEL_NONE;
1400         case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB:
1401                 return WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB;
1402         case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR:
1403                 return WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR;
1404         case DRM_MODE_SUBPIXEL_VERTICAL_RGB:
1405                 return WL_OUTPUT_SUBPIXEL_VERTICAL_RGB;
1406         case DRM_MODE_SUBPIXEL_VERTICAL_BGR:
1407                 return WL_OUTPUT_SUBPIXEL_VERTICAL_BGR;
1408         }
1409 }
1410
1411 /* returns a value between 0-255 range, where higher is brighter */
1412 static uint32_t
1413 drm_get_backlight(struct drm_output *output)
1414 {
1415         long brightness, max_brightness, norm;
1416
1417         brightness = backlight_get_brightness(output->backlight);
1418         max_brightness = backlight_get_max_brightness(output->backlight);
1419
1420         /* convert it on a scale of 0 to 255 */
1421         norm = (brightness * 255)/(max_brightness);
1422
1423         return (uint32_t) norm;
1424 }
1425
1426 /* values accepted are between 0-255 range */
1427 static void
1428 drm_set_backlight(struct weston_output *output_base, uint32_t value)
1429 {
1430         struct drm_output *output = (struct drm_output *) output_base;
1431         long max_brightness, new_brightness;
1432
1433         if (!output->backlight)
1434                 return;
1435
1436         if (value > 255)
1437                 return;
1438
1439         max_brightness = backlight_get_max_brightness(output->backlight);
1440
1441         /* get denormalized value */
1442         new_brightness = (value * max_brightness) / 255;
1443
1444         backlight_set_brightness(output->backlight, new_brightness);
1445 }
1446
1447 static drmModePropertyPtr
1448 drm_get_prop(int fd, drmModeConnectorPtr connector, const char *name)
1449 {
1450         drmModePropertyPtr props;
1451         int i;
1452
1453         for (i = 0; i < connector->count_props; i++) {
1454                 props = drmModeGetProperty(fd, connector->props[i]);
1455                 if (!props)
1456                         continue;
1457
1458                 if (!strcmp(props->name, name))
1459                         return props;
1460
1461                 drmModeFreeProperty(props);
1462         }
1463
1464         return NULL;
1465 }
1466
1467 static void
1468 drm_set_dpms(struct weston_output *output_base, enum dpms_enum level)
1469 {
1470         struct drm_output *output = (struct drm_output *) output_base;
1471         struct weston_compositor *ec = output_base->compositor;
1472         struct drm_compositor *c = (struct drm_compositor *) ec;
1473
1474         if (!output->dpms_prop)
1475                 return;
1476
1477         drmModeConnectorSetProperty(c->drm.fd, output->connector_id,
1478                                     output->dpms_prop->prop_id, level);
1479 }
1480
1481 static const char *connector_type_names[] = {
1482         "None",
1483         "VGA",
1484         "DVI",
1485         "DVI",
1486         "DVI",
1487         "Composite",
1488         "TV",
1489         "LVDS",
1490         "CTV",
1491         "DIN",
1492         "DP",
1493         "HDMI",
1494         "HDMI",
1495         "TV",
1496         "eDP",
1497 };
1498
1499 static int
1500 find_crtc_for_connector(struct drm_compositor *ec,
1501                         drmModeRes *resources, drmModeConnector *connector)
1502 {
1503         drmModeEncoder *encoder;
1504         uint32_t possible_crtcs;
1505         int i, j;
1506
1507         for (j = 0; j < connector->count_encoders; j++) {
1508                 encoder = drmModeGetEncoder(ec->drm.fd, connector->encoders[j]);
1509                 if (encoder == NULL) {
1510                         weston_log("Failed to get encoder.\n");
1511                         return -1;
1512                 }
1513                 possible_crtcs = encoder->possible_crtcs;
1514                 drmModeFreeEncoder(encoder);
1515
1516                 for (i = 0; i < resources->count_crtcs; i++) {
1517                         if (possible_crtcs & (1 << i) &&
1518                             !(ec->crtc_allocator & (1 << resources->crtcs[i])))
1519                                 return i;
1520                 }
1521         }
1522
1523         return -1;
1524 }
1525
1526 /* Init output state that depends on gl or gbm */
1527 static int
1528 drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec)
1529 {
1530         int i, flags;
1531
1532         output->surface = gbm_surface_create(ec->gbm,
1533                                              output->base.current_mode->width,
1534                                              output->base.current_mode->height,
1535                                              ec->format,
1536                                              GBM_BO_USE_SCANOUT |
1537                                              GBM_BO_USE_RENDERING);
1538         if (!output->surface) {
1539                 weston_log("failed to create gbm surface\n");
1540                 return -1;
1541         }
1542
1543         if (gl_renderer->output_create(&output->base, output->surface) < 0) {
1544                 weston_log("failed to create gl renderer output state\n");
1545                 gbm_surface_destroy(output->surface);
1546                 return -1;
1547         }
1548
1549         flags = GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE;
1550
1551         for (i = 0; i < 2; i++) {
1552                 if (output->cursor_bo[i])
1553                         continue;
1554
1555                 output->cursor_bo[i] =
1556                         gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888,
1557                                       flags);
1558         }
1559
1560         if (output->cursor_bo[0] == NULL || output->cursor_bo[1] == NULL) {
1561                 weston_log("cursor buffers unavailable, using gl cursors\n");
1562                 ec->cursors_are_broken = 1;
1563         }
1564
1565         return 0;
1566 }
1567
1568 static int
1569 drm_output_init_pixman(struct drm_output *output, struct drm_compositor *c)
1570 {
1571         int w = output->base.current_mode->width;
1572         int h = output->base.current_mode->height;
1573         unsigned int i;
1574
1575         /* FIXME error checking */
1576
1577         for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
1578                 output->dumb[i] = drm_fb_create_dumb(c, w, h);
1579                 if (!output->dumb[i])
1580                         goto err;
1581
1582                 output->image[i] =
1583                         pixman_image_create_bits(PIXMAN_x8r8g8b8, w, h,
1584                                                  output->dumb[i]->map,
1585                                                  output->dumb[i]->stride);
1586                 if (!output->image[i])
1587                         goto err;
1588         }
1589
1590         if (pixman_renderer_output_create(&output->base) < 0)
1591                 goto err;
1592
1593         pixman_region32_init_rect(&output->previous_damage,
1594                                   output->base.x, output->base.y, output->base.width, output->base.height);
1595
1596         return 0;
1597
1598 err:
1599         for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
1600                 if (output->dumb[i])
1601                         drm_fb_destroy_dumb(output->dumb[i]);
1602                 if (output->image[i])
1603                         pixman_image_unref(output->image[i]);
1604
1605                 output->dumb[i] = NULL;
1606                 output->image[i] = NULL;
1607         }
1608
1609         return -1;
1610 }
1611
1612 static void
1613 drm_output_fini_pixman(struct drm_output *output)
1614 {
1615         unsigned int i;
1616
1617         pixman_renderer_output_destroy(&output->base);
1618         pixman_region32_fini(&output->previous_damage);
1619
1620         for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
1621                 drm_fb_destroy_dumb(output->dumb[i]);
1622                 pixman_image_unref(output->image[i]);
1623                 output->dumb[i] = NULL;
1624                 output->image[i] = NULL;
1625         }
1626 }
1627
1628 static void
1629 edid_parse_string(const uint8_t *data, char text[])
1630 {
1631         int i;
1632         int replaced = 0;
1633
1634         /* this is always 12 bytes, but we can't guarantee it's null
1635          * terminated or not junk. */
1636         strncpy(text, (const char *) data, 12);
1637
1638         /* remove insane chars */
1639         for (i = 0; text[i] != '\0'; i++) {
1640                 if (text[i] == '\n' ||
1641                     text[i] == '\r') {
1642                         text[i] = '\0';
1643                         break;
1644                 }
1645         }
1646
1647         /* ensure string is printable */
1648         for (i = 0; text[i] != '\0'; i++) {
1649                 if (!isprint(text[i])) {
1650                         text[i] = '-';
1651                         replaced++;
1652                 }
1653         }
1654
1655         /* if the string is random junk, ignore the string */
1656         if (replaced > 4)
1657                 text[0] = '\0';
1658 }
1659
1660 #define EDID_DESCRIPTOR_ALPHANUMERIC_DATA_STRING        0xfe
1661 #define EDID_DESCRIPTOR_DISPLAY_PRODUCT_NAME            0xfc
1662 #define EDID_DESCRIPTOR_DISPLAY_PRODUCT_SERIAL_NUMBER   0xff
1663 #define EDID_OFFSET_DATA_BLOCKS                         0x36
1664 #define EDID_OFFSET_LAST_BLOCK                          0x6c
1665 #define EDID_OFFSET_PNPID                               0x08
1666 #define EDID_OFFSET_SERIAL                              0x0c
1667
1668 static int
1669 edid_parse(struct drm_edid *edid, const uint8_t *data, size_t length)
1670 {
1671         int i;
1672         uint32_t serial_number;
1673
1674         /* check header */
1675         if (length < 128)
1676                 return -1;
1677         if (data[0] != 0x00 || data[1] != 0xff)
1678                 return -1;
1679
1680         /* decode the PNP ID from three 5 bit words packed into 2 bytes
1681          * /--08--\/--09--\
1682          * 7654321076543210
1683          * |\---/\---/\---/
1684          * R  C1   C2   C3 */
1685         edid->pnp_id[0] = 'A' + ((data[EDID_OFFSET_PNPID + 0] & 0x7c) / 4) - 1;
1686         edid->pnp_id[1] = 'A' + ((data[EDID_OFFSET_PNPID + 0] & 0x3) * 8) + ((data[EDID_OFFSET_PNPID + 1] & 0xe0) / 32) - 1;
1687         edid->pnp_id[2] = 'A' + (data[EDID_OFFSET_PNPID + 1] & 0x1f) - 1;
1688         edid->pnp_id[3] = '\0';
1689
1690         /* maybe there isn't a ASCII serial number descriptor, so use this instead */
1691         serial_number = (uint32_t) data[EDID_OFFSET_SERIAL + 0];
1692         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 1] * 0x100;
1693         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 2] * 0x10000;
1694         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 3] * 0x1000000;
1695         if (serial_number > 0)
1696                 sprintf(edid->serial_number, "%lu", (unsigned long) serial_number);
1697
1698         /* parse EDID data */
1699         for (i = EDID_OFFSET_DATA_BLOCKS;
1700              i <= EDID_OFFSET_LAST_BLOCK;
1701              i += 18) {
1702                 /* ignore pixel clock data */
1703                 if (data[i] != 0)
1704                         continue;
1705                 if (data[i+2] != 0)
1706                         continue;
1707
1708                 /* any useful blocks? */
1709                 if (data[i+3] == EDID_DESCRIPTOR_DISPLAY_PRODUCT_NAME) {
1710                         edid_parse_string(&data[i+5],
1711                                           edid->monitor_name);
1712                 } else if (data[i+3] == EDID_DESCRIPTOR_DISPLAY_PRODUCT_SERIAL_NUMBER) {
1713                         edid_parse_string(&data[i+5],
1714                                           edid->serial_number);
1715                 } else if (data[i+3] == EDID_DESCRIPTOR_ALPHANUMERIC_DATA_STRING) {
1716                         edid_parse_string(&data[i+5],
1717                                           edid->eisa_id);
1718                 }
1719         }
1720         return 0;
1721 }
1722
1723 static void
1724 find_and_parse_output_edid(struct drm_compositor *ec,
1725                            struct drm_output *output,
1726                            drmModeConnector *connector)
1727 {
1728         drmModePropertyBlobPtr edid_blob = NULL;
1729         drmModePropertyPtr property;
1730         int i;
1731         int rc;
1732
1733         for (i = 0; i < connector->count_props && !edid_blob; i++) {
1734                 property = drmModeGetProperty(ec->drm.fd, connector->props[i]);
1735                 if (!property)
1736                         continue;
1737                 if ((property->flags & DRM_MODE_PROP_BLOB) &&
1738                     !strcmp(property->name, "EDID")) {
1739                         edid_blob = drmModeGetPropertyBlob(ec->drm.fd,
1740                                                            connector->prop_values[i]);
1741                 }
1742                 drmModeFreeProperty(property);
1743         }
1744         if (!edid_blob)
1745                 return;
1746
1747         rc = edid_parse(&output->edid,
1748                         edid_blob->data,
1749                         edid_blob->length);
1750         if (!rc) {
1751                 weston_log("EDID data '%s', '%s', '%s'\n",
1752                            output->edid.pnp_id,
1753                            output->edid.monitor_name,
1754                            output->edid.serial_number);
1755                 if (output->edid.pnp_id[0] != '\0')
1756                         output->base.make = output->edid.pnp_id;
1757                 if (output->edid.monitor_name[0] != '\0')
1758                         output->base.model = output->edid.monitor_name;
1759                 if (output->edid.serial_number[0] != '\0')
1760                         output->base.serial_number = output->edid.serial_number;
1761         }
1762         drmModeFreePropertyBlob(edid_blob);
1763 }
1764
1765
1766
1767 static int
1768 parse_modeline(const char *s, drmModeModeInfo *mode)
1769 {
1770         char hsync[16];
1771         char vsync[16];
1772         float fclock;
1773
1774         mode->type = DRM_MODE_TYPE_USERDEF;
1775         mode->hskew = 0;
1776         mode->vscan = 0;
1777         mode->vrefresh = 0;
1778         mode->flags = 0;
1779
1780         if (sscanf(s, "%f %hd %hd %hd %hd %hd %hd %hd %hd %15s %15s",
1781                    &fclock,
1782                    &mode->hdisplay,
1783                    &mode->hsync_start,
1784                    &mode->hsync_end,
1785                    &mode->htotal,
1786                    &mode->vdisplay,
1787                    &mode->vsync_start,
1788                    &mode->vsync_end,
1789                    &mode->vtotal, hsync, vsync) != 11)
1790                 return -1;
1791
1792         mode->clock = fclock * 1000;
1793         if (strcmp(hsync, "+hsync") == 0)
1794                 mode->flags |= DRM_MODE_FLAG_PHSYNC;
1795         else if (strcmp(hsync, "-hsync") == 0)
1796                 mode->flags |= DRM_MODE_FLAG_NHSYNC;
1797         else
1798                 return -1;
1799
1800         if (strcmp(vsync, "+vsync") == 0)
1801                 mode->flags |= DRM_MODE_FLAG_PVSYNC;
1802         else if (strcmp(vsync, "-vsync") == 0)
1803                 mode->flags |= DRM_MODE_FLAG_NVSYNC;
1804         else
1805                 return -1;
1806
1807         return 0;
1808 }
1809
1810 static uint32_t
1811 parse_transform(const char *transform, const char *output_name)
1812 {
1813         static const struct { const char *name; uint32_t token; } names[] = {
1814                 { "normal",     WL_OUTPUT_TRANSFORM_NORMAL },
1815                 { "90",         WL_OUTPUT_TRANSFORM_90 },
1816                 { "180",        WL_OUTPUT_TRANSFORM_180 },
1817                 { "270",        WL_OUTPUT_TRANSFORM_270 },
1818                 { "flipped",    WL_OUTPUT_TRANSFORM_FLIPPED },
1819                 { "flipped-90", WL_OUTPUT_TRANSFORM_FLIPPED_90 },
1820                 { "flipped-180", WL_OUTPUT_TRANSFORM_FLIPPED_180 },
1821                 { "flipped-270", WL_OUTPUT_TRANSFORM_FLIPPED_270 },
1822         };
1823         unsigned int i;
1824
1825         for (i = 0; i < ARRAY_LENGTH(names); i++)
1826                 if (strcmp(names[i].name, transform) == 0)
1827                         return names[i].token;
1828
1829         weston_log("Invalid transform \"%s\" for output %s\n",
1830                    transform, output_name);
1831
1832         return WL_OUTPUT_TRANSFORM_NORMAL;
1833 }
1834
1835 static void
1836 setup_output_seat_constraint(struct drm_compositor *ec,
1837                              struct weston_output *output,
1838                              const char *s)
1839 {
1840         if (strcmp(s, "") != 0) {
1841                 struct udev_seat *seat;
1842
1843                 seat = udev_seat_get_named(&ec->base, s);
1844                 if (seat)
1845                         seat->base.output = output;
1846
1847                 if (seat && seat->base.pointer)
1848                         weston_pointer_clamp(seat->base.pointer,
1849                                              &seat->base.pointer->x,
1850                                              &seat->base.pointer->y);
1851         }
1852 }
1853
1854 static int
1855 create_output_for_connector(struct drm_compositor *ec,
1856                             drmModeRes *resources,
1857                             drmModeConnector *connector,
1858                             int x, int y, struct udev_device *drm_device)
1859 {
1860         struct drm_output *output;
1861         struct drm_mode *drm_mode, *next, *preferred, *current, *configured;
1862         struct weston_mode *m;
1863         struct weston_config_section *section;
1864         drmModeEncoder *encoder;
1865         drmModeModeInfo crtc_mode, modeline;
1866         drmModeCrtc *crtc;
1867         int i, width, height, scale;
1868         char name[32], *s;
1869         const char *type_name;
1870         enum output_config config;
1871         uint32_t transform;
1872
1873         i = find_crtc_for_connector(ec, resources, connector);
1874         if (i < 0) {
1875                 weston_log("No usable crtc/encoder pair for connector.\n");
1876                 return -1;
1877         }
1878
1879         output = zalloc(sizeof *output);
1880         if (output == NULL)
1881                 return -1;
1882
1883         output->base.subpixel = drm_subpixel_to_wayland(connector->subpixel);
1884         output->base.make = "unknown";
1885         output->base.model = "unknown";
1886         output->base.serial_number = "unknown";
1887         wl_list_init(&output->base.mode_list);
1888
1889         if (connector->connector_type < ARRAY_LENGTH(connector_type_names))
1890                 type_name = connector_type_names[connector->connector_type];
1891         else
1892                 type_name = "UNKNOWN";
1893         snprintf(name, 32, "%s%d", type_name, connector->connector_type_id);
1894         output->base.name = strdup(name);
1895
1896         section = weston_config_get_section(ec->base.config, "output", "name",
1897                                             output->base.name);
1898         weston_config_section_get_string(section, "mode", &s, "preferred");
1899         if (strcmp(s, "off") == 0)
1900                 config = OUTPUT_CONFIG_OFF;
1901         else if (strcmp(s, "preferred") == 0)
1902                 config = OUTPUT_CONFIG_PREFERRED;
1903         else if (strcmp(s, "current") == 0)
1904                 config = OUTPUT_CONFIG_CURRENT;
1905         else if (sscanf(s, "%dx%d", &width, &height) == 2)
1906                 config = OUTPUT_CONFIG_MODE;
1907         else if (parse_modeline(s, &modeline) == 0)
1908                 config = OUTPUT_CONFIG_MODELINE;
1909         else {
1910                 weston_log("Invalid mode \"%s\" for output %s\n",
1911                            s, output->base.name);
1912                 config = OUTPUT_CONFIG_PREFERRED;
1913         }
1914         free(s);
1915
1916         weston_config_section_get_int(section, "scale", &scale, 1);
1917         weston_config_section_get_string(section, "transform", &s, "normal");
1918         transform = parse_transform(s, output->base.name);
1919         free(s);
1920
1921         weston_config_section_get_string(section, "seat", &s, "");
1922         setup_output_seat_constraint(ec, &output->base, s);
1923         free(s);
1924
1925         output->crtc_id = resources->crtcs[i];
1926         output->pipe = i;
1927         ec->crtc_allocator |= (1 << output->crtc_id);
1928         output->connector_id = connector->connector_id;
1929         ec->connector_allocator |= (1 << output->connector_id);
1930
1931         output->original_crtc = drmModeGetCrtc(ec->drm.fd, output->crtc_id);
1932         output->dpms_prop = drm_get_prop(ec->drm.fd, connector, "DPMS");
1933
1934         /* Get the current mode on the crtc that's currently driving
1935          * this connector. */
1936         encoder = drmModeGetEncoder(ec->drm.fd, connector->encoder_id);
1937         memset(&crtc_mode, 0, sizeof crtc_mode);
1938         if (encoder != NULL) {
1939                 crtc = drmModeGetCrtc(ec->drm.fd, encoder->crtc_id);
1940                 drmModeFreeEncoder(encoder);
1941                 if (crtc == NULL)
1942                         goto err_free;
1943                 if (crtc->mode_valid)
1944                         crtc_mode = crtc->mode;
1945                 drmModeFreeCrtc(crtc);
1946         }
1947
1948         for (i = 0; i < connector->count_modes; i++) {
1949                 drm_mode = drm_output_add_mode(output, &connector->modes[i]);
1950                 if (!drm_mode)
1951                         goto err_free;
1952         }
1953
1954         if (config == OUTPUT_CONFIG_OFF) {
1955                 weston_log("Disabling output %s\n", output->base.name);
1956                 drmModeSetCrtc(ec->drm.fd, output->crtc_id,
1957                                0, 0, 0, 0, 0, NULL);
1958                 goto err_free;
1959         }
1960
1961         preferred = NULL;
1962         current = NULL;
1963         configured = NULL;
1964
1965         wl_list_for_each_reverse(drm_mode, &output->base.mode_list, base.link) {
1966                 if (config == OUTPUT_CONFIG_MODE &&
1967                     width == drm_mode->base.width &&
1968                     height == drm_mode->base.height)
1969                         configured = drm_mode;
1970                 if (!memcmp(&crtc_mode, &drm_mode->mode_info, sizeof crtc_mode))
1971                         current = drm_mode;
1972                 if (drm_mode->base.flags & WL_OUTPUT_MODE_PREFERRED)
1973                         preferred = drm_mode;
1974         }
1975
1976         if (config == OUTPUT_CONFIG_MODELINE) {
1977                 configured = drm_output_add_mode(output, &modeline);
1978                 if (!configured)
1979                         goto err_free;
1980         }
1981
1982         if (current == NULL && crtc_mode.clock != 0) {
1983                 current = drm_output_add_mode(output, &crtc_mode);
1984                 if (!current)
1985                         goto err_free;
1986         }
1987
1988         if (config == OUTPUT_CONFIG_CURRENT)
1989                 configured = current;
1990
1991         if (option_current_mode && current)
1992                 output->base.current_mode = &current->base;
1993         else if (configured)
1994                 output->base.current_mode = &configured->base;
1995         else if (preferred)
1996                 output->base.current_mode = &preferred->base;
1997         else if (current)
1998                 output->base.current_mode = &current->base;
1999
2000         if (output->base.current_mode == NULL) {
2001                 weston_log("no available modes for %s\n", output->base.name);
2002                 goto err_free;
2003         }
2004
2005         output->base.current_mode->flags |= WL_OUTPUT_MODE_CURRENT;
2006
2007         weston_output_init(&output->base, &ec->base, x, y,
2008                            connector->mmWidth, connector->mmHeight,
2009                            transform, scale);
2010
2011         if (ec->use_pixman) {
2012                 if (drm_output_init_pixman(output, ec) < 0) {
2013                         weston_log("Failed to init output pixman state\n");
2014                         goto err_output;
2015                 }
2016         } else if (drm_output_init_egl(output, ec) < 0) {
2017                 weston_log("Failed to init output gl state\n");
2018                 goto err_output;
2019         }
2020
2021         output->backlight = backlight_init(drm_device,
2022                                            connector->connector_type);
2023         if (output->backlight) {
2024                 weston_log("Initialized backlight, device %s\n",
2025                            output->backlight->path);
2026                 output->base.set_backlight = drm_set_backlight;
2027                 output->base.backlight_current = drm_get_backlight(output);
2028         } else {
2029                 weston_log("Failed to initialize backlight\n");
2030         }
2031
2032         wl_list_insert(ec->base.output_list.prev, &output->base.link);
2033
2034         find_and_parse_output_edid(ec, output, connector);
2035         if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
2036                 output->base.connection_internal = 1;
2037
2038         output->base.start_repaint_loop = drm_output_start_repaint_loop;
2039         output->base.repaint = drm_output_repaint;
2040         output->base.destroy = drm_output_destroy;
2041         output->base.assign_planes = drm_assign_planes;
2042         output->base.set_dpms = drm_set_dpms;
2043         output->base.switch_mode = drm_output_switch_mode;
2044
2045         output->base.gamma_size = output->original_crtc->gamma_size;
2046         output->base.set_gamma = drm_output_set_gamma;
2047
2048         weston_plane_init(&output->cursor_plane, &ec->base, 0, 0);
2049         weston_plane_init(&output->fb_plane, &ec->base, 0, 0);
2050
2051         weston_compositor_stack_plane(&ec->base, &output->cursor_plane, NULL);
2052         weston_compositor_stack_plane(&ec->base, &output->fb_plane,
2053                                       &ec->base.primary_plane);
2054
2055         weston_log("Output %s, (connector %d, crtc %d)\n",
2056                    output->base.name, output->connector_id, output->crtc_id);
2057         wl_list_for_each(m, &output->base.mode_list, link)
2058                 weston_log_continue("  mode %dx%d@%.1f%s%s%s\n",
2059                                     m->width, m->height, m->refresh / 1000.0,
2060                                     m->flags & WL_OUTPUT_MODE_PREFERRED ?
2061                                     ", preferred" : "",
2062                                     m->flags & WL_OUTPUT_MODE_CURRENT ?
2063                                     ", current" : "",
2064                                     connector->count_modes == 0 ?
2065                                     ", built-in" : "");
2066
2067         return 0;
2068
2069 err_output:
2070         weston_output_destroy(&output->base);
2071 err_free:
2072         wl_list_for_each_safe(drm_mode, next, &output->base.mode_list,
2073                                                         base.link) {
2074                 wl_list_remove(&drm_mode->base.link);
2075                 free(drm_mode);
2076         }
2077
2078         drmModeFreeCrtc(output->original_crtc);
2079         ec->crtc_allocator &= ~(1 << output->crtc_id);
2080         ec->connector_allocator &= ~(1 << output->connector_id);
2081         free(output);
2082
2083         return -1;
2084 }
2085
2086 static void
2087 create_sprites(struct drm_compositor *ec)
2088 {
2089         struct drm_sprite *sprite;
2090         drmModePlaneRes *plane_res;
2091         drmModePlane *plane;
2092         uint32_t i;
2093
2094         plane_res = drmModeGetPlaneResources(ec->drm.fd);
2095         if (!plane_res) {
2096                 weston_log("failed to get plane resources: %s\n",
2097                         strerror(errno));
2098                 return;
2099         }
2100
2101         for (i = 0; i < plane_res->count_planes; i++) {
2102                 plane = drmModeGetPlane(ec->drm.fd, plane_res->planes[i]);
2103                 if (!plane)
2104                         continue;
2105
2106                 sprite = zalloc(sizeof(*sprite) + ((sizeof(uint32_t)) *
2107                                                    plane->count_formats));
2108                 if (!sprite) {
2109                         weston_log("%s: out of memory\n",
2110                                 __func__);
2111                         free(plane);
2112                         continue;
2113                 }
2114
2115                 sprite->possible_crtcs = plane->possible_crtcs;
2116                 sprite->plane_id = plane->plane_id;
2117                 sprite->current = NULL;
2118                 sprite->next = NULL;
2119                 sprite->compositor = ec;
2120                 sprite->count_formats = plane->count_formats;
2121                 memcpy(sprite->formats, plane->formats,
2122                        plane->count_formats * sizeof(plane->formats[0]));
2123                 drmModeFreePlane(plane);
2124                 weston_plane_init(&sprite->plane, &ec->base, 0, 0);
2125                 weston_compositor_stack_plane(&ec->base, &sprite->plane,
2126                                               &ec->base.primary_plane);
2127
2128                 wl_list_insert(&ec->sprite_list, &sprite->link);
2129         }
2130
2131         drmModeFreePlaneResources(plane_res);
2132 }
2133
2134 static void
2135 destroy_sprites(struct drm_compositor *compositor)
2136 {
2137         struct drm_sprite *sprite, *next;
2138         struct drm_output *output;
2139
2140         output = container_of(compositor->base.output_list.next,
2141                               struct drm_output, base.link);
2142
2143         wl_list_for_each_safe(sprite, next, &compositor->sprite_list, link) {
2144                 drmModeSetPlane(compositor->drm.fd,
2145                                 sprite->plane_id,
2146                                 output->crtc_id, 0, 0,
2147                                 0, 0, 0, 0, 0, 0, 0, 0);
2148                 drm_output_release_fb(output, sprite->current);
2149                 drm_output_release_fb(output, sprite->next);
2150                 weston_plane_release(&sprite->plane);
2151                 free(sprite);
2152         }
2153 }
2154
2155 static int
2156 create_outputs(struct drm_compositor *ec, uint32_t option_connector,
2157                struct udev_device *drm_device)
2158 {
2159         drmModeConnector *connector;
2160         drmModeRes *resources;
2161         int i;
2162         int x = 0, y = 0;
2163
2164         resources = drmModeGetResources(ec->drm.fd);
2165         if (!resources) {
2166                 weston_log("drmModeGetResources failed\n");
2167                 return -1;
2168         }
2169
2170         ec->crtcs = calloc(resources->count_crtcs, sizeof(uint32_t));
2171         if (!ec->crtcs) {
2172                 drmModeFreeResources(resources);
2173                 return -1;
2174         }
2175
2176         ec->min_width  = resources->min_width;
2177         ec->max_width  = resources->max_width;
2178         ec->min_height = resources->min_height;
2179         ec->max_height = resources->max_height;
2180
2181         ec->num_crtcs = resources->count_crtcs;
2182         memcpy(ec->crtcs, resources->crtcs, sizeof(uint32_t) * ec->num_crtcs);
2183
2184         for (i = 0; i < resources->count_connectors; i++) {
2185                 connector = drmModeGetConnector(ec->drm.fd,
2186                                                 resources->connectors[i]);
2187                 if (connector == NULL)
2188                         continue;
2189
2190                 if (connector->connection == DRM_MODE_CONNECTED &&
2191                     (option_connector == 0 ||
2192                      connector->connector_id == option_connector)) {
2193                         if (create_output_for_connector(ec, resources,
2194                                                         connector, x, y,
2195                                                         drm_device) < 0) {
2196                                 drmModeFreeConnector(connector);
2197                                 continue;
2198                         }
2199
2200                         x += container_of(ec->base.output_list.prev,
2201                                           struct weston_output,
2202                                           link)->width;
2203                 }
2204
2205                 drmModeFreeConnector(connector);
2206         }
2207
2208         if (wl_list_empty(&ec->base.output_list)) {
2209                 weston_log("No currently active connector found.\n");
2210                 drmModeFreeResources(resources);
2211                 return -1;
2212         }
2213
2214         drmModeFreeResources(resources);
2215
2216         return 0;
2217 }
2218
2219 static void
2220 update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
2221 {
2222         drmModeConnector *connector;
2223         drmModeRes *resources;
2224         struct drm_output *output, *next;
2225         int x = 0, y = 0;
2226         int x_offset = 0, y_offset = 0;
2227         uint32_t connected = 0, disconnects = 0;
2228         int i;
2229
2230         resources = drmModeGetResources(ec->drm.fd);
2231         if (!resources) {
2232                 weston_log("drmModeGetResources failed\n");
2233                 return;
2234         }
2235
2236         /* collect new connects */
2237         for (i = 0; i < resources->count_connectors; i++) {
2238                 int connector_id = resources->connectors[i];
2239
2240                 connector = drmModeGetConnector(ec->drm.fd, connector_id);
2241                 if (connector == NULL)
2242                         continue;
2243
2244                 if (connector->connection != DRM_MODE_CONNECTED) {
2245                         drmModeFreeConnector(connector);
2246                         continue;
2247                 }
2248
2249                 connected |= (1 << connector_id);
2250
2251                 if (!(ec->connector_allocator & (1 << connector_id))) {
2252                         struct weston_output *last =
2253                                 container_of(ec->base.output_list.prev,
2254                                              struct weston_output, link);
2255
2256                         /* XXX: not yet needed, we die with 0 outputs */
2257                         if (!wl_list_empty(&ec->base.output_list))
2258                                 x = last->x + last->width;
2259                         else
2260                                 x = 0;
2261                         y = 0;
2262                         create_output_for_connector(ec, resources,
2263                                                     connector, x, y,
2264                                                     drm_device);
2265                         weston_log("connector %d connected\n", connector_id);
2266
2267                 }
2268                 drmModeFreeConnector(connector);
2269         }
2270         drmModeFreeResources(resources);
2271
2272         disconnects = ec->connector_allocator & ~connected;
2273         if (disconnects) {
2274                 wl_list_for_each_safe(output, next, &ec->base.output_list,
2275                                       base.link) {
2276                         if (x_offset != 0 || y_offset != 0) {
2277                                 weston_output_move(&output->base,
2278                                                  output->base.x - x_offset,
2279                                                  output->base.y - y_offset);
2280                         }
2281
2282                         if (disconnects & (1 << output->connector_id)) {
2283                                 disconnects &= ~(1 << output->connector_id);
2284                                 weston_log("connector %d disconnected\n",
2285                                        output->connector_id);
2286                                 x_offset += output->base.width;
2287                                 drm_output_destroy(&output->base);
2288                         }
2289                 }
2290         }
2291
2292         /* FIXME: handle zero outputs, without terminating */   
2293         if (ec->connector_allocator == 0)
2294                 wl_display_terminate(ec->base.wl_display);
2295 }
2296
2297 static int
2298 udev_event_is_hotplug(struct drm_compositor *ec, struct udev_device *device)
2299 {
2300         const char *sysnum;
2301         const char *val;
2302
2303         sysnum = udev_device_get_sysnum(device);
2304         if (!sysnum || atoi(sysnum) != ec->drm.id)
2305                 return 0;
2306
2307         val = udev_device_get_property_value(device, "HOTPLUG");
2308         if (!val)
2309                 return 0;
2310
2311         return strcmp(val, "1") == 0;
2312 }
2313
2314 static int
2315 udev_drm_event(int fd, uint32_t mask, void *data)
2316 {
2317         struct drm_compositor *ec = data;
2318         struct udev_device *event;
2319
2320         event = udev_monitor_receive_device(ec->udev_monitor);
2321
2322         if (udev_event_is_hotplug(ec, event))
2323                 update_outputs(ec, event);
2324
2325         udev_device_unref(event);
2326
2327         return 1;
2328 }
2329
2330 static void
2331 drm_restore(struct weston_compositor *ec)
2332 {
2333         weston_launcher_restore(ec->launcher);
2334 }
2335
2336 static void
2337 drm_destroy(struct weston_compositor *ec)
2338 {
2339         struct drm_compositor *d = (struct drm_compositor *) ec;
2340
2341         udev_input_destroy(&d->input);
2342
2343         wl_event_source_remove(d->udev_drm_source);
2344         wl_event_source_remove(d->drm_source);
2345
2346         destroy_sprites(d);
2347
2348         ec->renderer->destroy(ec);
2349
2350         weston_compositor_shutdown(ec);
2351
2352         if (d->gbm)
2353                 gbm_device_destroy(d->gbm);
2354
2355         weston_launcher_destroy(d->base.launcher);
2356
2357         close(d->drm.fd);
2358
2359         free(d);
2360 }
2361
2362 static void
2363 drm_compositor_set_modes(struct drm_compositor *compositor)
2364 {
2365         struct drm_output *output;
2366         struct drm_mode *drm_mode;
2367         int ret;
2368
2369         wl_list_for_each(output, &compositor->base.output_list, base.link) {
2370                 if (!output->current) {
2371                         /* If something that would cause the output to
2372                          * switch mode happened while in another vt, we
2373                          * might not have a current drm_fb. In that case,
2374                          * schedule a repaint and let drm_output_repaint
2375                          * handle setting the mode. */
2376                         weston_output_schedule_repaint(&output->base);
2377                         continue;
2378                 }
2379
2380                 drm_mode = (struct drm_mode *) output->base.current_mode;
2381                 ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id,
2382                                      output->current->fb_id, 0, 0,
2383                                      &output->connector_id, 1,
2384                                      &drm_mode->mode_info);
2385                 if (ret < 0) {
2386                         weston_log(
2387                                 "failed to set mode %dx%d for output at %d,%d: %m\n",
2388                                 drm_mode->base.width, drm_mode->base.height, 
2389                                 output->base.x, output->base.y);
2390                 }
2391         }
2392 }
2393
2394 static void
2395 session_notify(struct wl_listener *listener, void *data)
2396 {
2397         struct weston_compositor *compositor = data;
2398         struct drm_compositor *ec = data;
2399         struct drm_sprite *sprite;
2400         struct drm_output *output;
2401
2402         if (ec->base.session_active) {
2403                 weston_log("activating session\n");
2404                 compositor->state = ec->prev_state;
2405                 drm_compositor_set_modes(ec);
2406                 weston_compositor_damage_all(compositor);
2407                 udev_input_enable(&ec->input, ec->udev);
2408         } else {
2409                 weston_log("deactivating session\n");
2410                 udev_input_disable(&ec->input);
2411
2412                 ec->prev_state = compositor->state;
2413                 weston_compositor_offscreen(compositor);
2414
2415                 /* If we have a repaint scheduled (either from a
2416                  * pending pageflip or the idle handler), make sure we
2417                  * cancel that so we don't try to pageflip when we're
2418                  * vt switched away.  The OFFSCREEN state will prevent
2419                  * further attemps at repainting.  When we switch
2420                  * back, we schedule a repaint, which will process
2421                  * pending frame callbacks. */
2422
2423                 wl_list_for_each(output, &ec->base.output_list, base.link) {
2424                         output->base.repaint_needed = 0;
2425                         drmModeSetCursor(ec->drm.fd, output->crtc_id, 0, 0, 0);
2426                 }
2427
2428                 output = container_of(ec->base.output_list.next,
2429                                       struct drm_output, base.link);
2430
2431                 wl_list_for_each(sprite, &ec->sprite_list, link)
2432                         drmModeSetPlane(ec->drm.fd,
2433                                         sprite->plane_id,
2434                                         output->crtc_id, 0, 0,
2435                                         0, 0, 0, 0, 0, 0, 0, 0);
2436         };
2437 }
2438
2439 static void
2440 switch_vt_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
2441 {
2442         struct weston_compositor *compositor = data;
2443
2444         weston_launcher_activate_vt(compositor->launcher, key - KEY_F1 + 1);
2445 }
2446
2447 /*
2448  * Find primary GPU
2449  * Some systems may have multiple DRM devices attached to a single seat. This
2450  * function loops over all devices and tries to find a PCI device with the
2451  * boot_vga sysfs attribute set to 1.
2452  * If no such device is found, the first DRM device reported by udev is used.
2453  */
2454 static struct udev_device*
2455 find_primary_gpu(struct drm_compositor *ec, const char *seat)
2456 {
2457         struct udev_enumerate *e;
2458         struct udev_list_entry *entry;
2459         const char *path, *device_seat, *id;
2460         struct udev_device *device, *drm_device, *pci;
2461
2462         e = udev_enumerate_new(ec->udev);
2463         udev_enumerate_add_match_subsystem(e, "drm");
2464         udev_enumerate_add_match_sysname(e, "card[0-9]*");
2465
2466         udev_enumerate_scan_devices(e);
2467         drm_device = NULL;
2468         udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
2469                 path = udev_list_entry_get_name(entry);
2470                 device = udev_device_new_from_syspath(ec->udev, path);
2471                 if (!device)
2472                         continue;
2473                 device_seat = udev_device_get_property_value(device, "ID_SEAT");
2474                 if (!device_seat)
2475                         device_seat = default_seat;
2476                 if (strcmp(device_seat, seat)) {
2477                         udev_device_unref(device);
2478                         continue;
2479                 }
2480
2481                 pci = udev_device_get_parent_with_subsystem_devtype(device,
2482                                                                 "pci", NULL);
2483                 if (pci) {
2484                         id = udev_device_get_sysattr_value(pci, "boot_vga");
2485                         if (id && !strcmp(id, "1")) {
2486                                 if (drm_device)
2487                                         udev_device_unref(drm_device);
2488                                 drm_device = device;
2489                                 break;
2490                         }
2491                 }
2492
2493                 if (!drm_device)
2494                         drm_device = device;
2495                 else
2496                         udev_device_unref(device);
2497         }
2498
2499         udev_enumerate_unref(e);
2500         return drm_device;
2501 }
2502
2503 static void
2504 planes_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
2505 {
2506         struct drm_compositor *c = data;
2507
2508         switch (key) {
2509         case KEY_C:
2510                 c->cursors_are_broken ^= 1;
2511                 break;
2512         case KEY_V:
2513                 c->sprites_are_broken ^= 1;
2514                 break;
2515         case KEY_O:
2516                 c->sprites_hidden ^= 1;
2517                 break;
2518         default:
2519                 break;
2520         }
2521 }
2522
2523 #ifdef BUILD_VAAPI_RECORDER
2524 static void
2525 recorder_frame_notify(struct wl_listener *listener, void *data)
2526 {
2527         struct drm_output *output;
2528         struct drm_compositor *c;
2529         int fd, ret;
2530
2531         output = container_of(listener, struct drm_output,
2532                               recorder_frame_listener);
2533         c = (struct drm_compositor *) output->base.compositor;
2534
2535         if (!output->recorder)
2536                 return;
2537
2538         ret = drmPrimeHandleToFD(c->drm.fd, output->current->handle,
2539                                  DRM_CLOEXEC, &fd);
2540         if (ret) {
2541                 weston_log("[libva recorder] "
2542                            "failed to create prime fd for front buffer\n");
2543                 return;
2544         }
2545
2546         vaapi_recorder_frame(output->recorder, fd, output->current->stride / 4);
2547 }
2548
2549 static void *
2550 create_recorder(struct drm_compositor *c, int width, int height,
2551                 const char *filename)
2552 {
2553         int fd;
2554         drm_magic_t magic;
2555
2556         fd = open(c->drm.filename, O_RDWR | O_CLOEXEC);
2557         if (fd < 0)
2558                 return NULL;
2559
2560         drmGetMagic(fd, &magic);
2561         drmAuthMagic(c->drm.fd, magic);
2562
2563         return vaapi_recorder_create(fd, width, height, filename);
2564 }
2565
2566 static void
2567 recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
2568                  void *data)
2569 {
2570         struct drm_compositor *c = data;
2571         struct drm_output *output;
2572         int width, height;
2573
2574         output = container_of(c->base.output_list.next,
2575                               struct drm_output, base.link);
2576
2577         if (!output->recorder) {
2578                 width = output->base.current_mode->width;
2579                 height = output->base.current_mode->height;
2580
2581                 output->recorder =
2582                         create_recorder(c, width, height, "capture.h264");
2583                 if (!output->recorder) {
2584                         weston_log("failed to create vaapi recorder\n");
2585                         return;
2586                 }
2587
2588                 output->base.disable_planes++;
2589
2590                 output->recorder_frame_listener.notify = recorder_frame_notify;
2591                 wl_signal_add(&output->base.frame_signal,
2592                               &output->recorder_frame_listener);
2593
2594                 weston_output_schedule_repaint(&output->base);
2595
2596                 weston_log("[libva recorder] initialized\n");
2597         } else {
2598                 vaapi_recorder_destroy(output->recorder);
2599                 output->recorder = NULL;
2600
2601                 output->base.disable_planes--;
2602
2603                 wl_list_remove(&output->recorder_frame_listener.link);
2604                 weston_log("[libva recorder] done\n");
2605         }
2606 }
2607 #else
2608 static void
2609 recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
2610                  void *data)
2611 {
2612         weston_log("Compiled without libva support\n");
2613 }
2614 #endif
2615
2616 static void
2617 switch_to_gl_renderer(struct drm_compositor *c)
2618 {
2619         struct drm_output *output;
2620
2621         if (!c->use_pixman)
2622                 return;
2623
2624         weston_log("Switching to GL renderer\n");
2625
2626         c->gbm = create_gbm_device(c->drm.fd);
2627         if (!c->gbm) {
2628                 weston_log("Failed to create gbm device. "
2629                            "Aborting renderer switch\n");
2630                 return;
2631         }
2632
2633         wl_list_for_each(output, &c->base.output_list, base.link)
2634                 pixman_renderer_output_destroy(&output->base);
2635
2636         c->base.renderer->destroy(&c->base);
2637
2638         if (drm_compositor_create_gl_renderer(c) < 0) {
2639                 gbm_device_destroy(c->gbm);
2640                 weston_log("Failed to create GL renderer. Quitting.\n");
2641                 /* FIXME: we need a function to shutdown cleanly */
2642                 assert(0);
2643         }
2644
2645         wl_list_for_each(output, &c->base.output_list, base.link)
2646                 drm_output_init_egl(output, c);
2647
2648         c->use_pixman = 0;
2649 }
2650
2651 static void
2652 renderer_switch_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
2653                         void *data)
2654 {
2655         struct drm_compositor *c = (struct drm_compositor *) seat->compositor;
2656
2657         switch_to_gl_renderer(c);
2658 }
2659
2660 static struct weston_compositor *
2661 drm_compositor_create(struct wl_display *display,
2662                       struct drm_parameters *param,
2663                       int *argc, char *argv[],
2664                       struct weston_config *config)
2665 {
2666         struct drm_compositor *ec;
2667         struct weston_config_section *section;
2668         struct udev_device *drm_device;
2669         struct wl_event_loop *loop;
2670         const char *path;
2671         char *s;
2672         uint32_t key;
2673
2674         weston_log("initializing drm backend\n");
2675
2676         ec = zalloc(sizeof *ec);
2677         if (ec == NULL)
2678                 return NULL;
2679
2680         /* KMS support for sprites is not complete yet, so disable the
2681          * functionality for now. */
2682         ec->sprites_are_broken = 1;
2683
2684         section = weston_config_get_section(config, "core", NULL, NULL);
2685         weston_config_section_get_string(section,
2686                                          "gbm-format", &s, "xrgb8888");
2687         if (strcmp(s, "xrgb8888") == 0)
2688                 ec->format = GBM_FORMAT_XRGB8888;
2689         else if (strcmp(s, "rgb565") == 0)
2690                 ec->format = GBM_FORMAT_RGB565;
2691         else if (strcmp(s, "xrgb2101010") == 0)
2692                 ec->format = GBM_FORMAT_XRGB2101010;
2693         else {
2694                 weston_log("fatal: unrecognized pixel format: %s\n", s);
2695                 free(s);
2696                 goto err_base;
2697         }
2698         free(s);
2699
2700         ec->use_pixman = param->use_pixman;
2701
2702         if (weston_compositor_init(&ec->base, display, argc, argv,
2703                                    config) < 0) {
2704                 weston_log("%s failed\n", __func__);
2705                 goto err_base;
2706         }
2707
2708         /* Check if we run drm-backend using weston-launch */
2709         ec->base.launcher = weston_launcher_connect(&ec->base, param->tty,
2710                                                     param->seat_id);
2711         if (ec->base.launcher == NULL) {
2712                 weston_log("fatal: drm backend should be run "
2713                            "using weston-launch binary or as root\n");
2714                 goto err_compositor;
2715         }
2716
2717         ec->udev = udev_new();
2718         if (ec->udev == NULL) {
2719                 weston_log("failed to initialize udev context\n");
2720                 goto err_launcher;
2721         }
2722
2723         ec->base.wl_display = display;
2724         ec->session_listener.notify = session_notify;
2725         wl_signal_add(&ec->base.session_signal, &ec->session_listener);
2726
2727         drm_device = find_primary_gpu(ec, param->seat_id);
2728         if (drm_device == NULL) {
2729                 weston_log("no drm device found\n");
2730                 goto err_udev;
2731         }
2732         path = udev_device_get_syspath(drm_device);
2733
2734         if (init_drm(ec, drm_device) < 0) {
2735                 weston_log("failed to initialize kms\n");
2736                 goto err_udev_dev;
2737         }
2738
2739         if (ec->use_pixman) {
2740                 if (init_pixman(ec) < 0) {
2741                         weston_log("failed to initialize pixman renderer\n");
2742                         goto err_udev_dev;
2743                 }
2744         } else {
2745                 if (init_egl(ec) < 0) {
2746                         weston_log("failed to initialize egl\n");
2747                         goto err_udev_dev;
2748                 }
2749         }
2750
2751         ec->base.destroy = drm_destroy;
2752         ec->base.restore = drm_restore;
2753
2754         ec->prev_state = WESTON_COMPOSITOR_ACTIVE;
2755
2756         for (key = KEY_F1; key < KEY_F9; key++)
2757                 weston_compositor_add_key_binding(&ec->base, key,
2758                                                   MODIFIER_CTRL | MODIFIER_ALT,
2759                                                   switch_vt_binding, ec);
2760
2761         wl_list_init(&ec->sprite_list);
2762         create_sprites(ec);
2763
2764         if (create_outputs(ec, param->connector, drm_device) < 0) {
2765                 weston_log("failed to create output for %s\n", path);
2766                 goto err_sprite;
2767         }
2768
2769         path = NULL;
2770
2771         if (udev_input_init(&ec->input,
2772                             &ec->base, ec->udev, param->seat_id) < 0) {
2773                 weston_log("failed to create input devices\n");
2774                 goto err_sprite;
2775         }
2776
2777         loop = wl_display_get_event_loop(ec->base.wl_display);
2778         ec->drm_source =
2779                 wl_event_loop_add_fd(loop, ec->drm.fd,
2780                                      WL_EVENT_READABLE, on_drm_input, ec);
2781
2782         ec->udev_monitor = udev_monitor_new_from_netlink(ec->udev, "udev");
2783         if (ec->udev_monitor == NULL) {
2784                 weston_log("failed to intialize udev monitor\n");
2785                 goto err_drm_source;
2786         }
2787         udev_monitor_filter_add_match_subsystem_devtype(ec->udev_monitor,
2788                                                         "drm", NULL);
2789         ec->udev_drm_source =
2790                 wl_event_loop_add_fd(loop,
2791                                      udev_monitor_get_fd(ec->udev_monitor),
2792                                      WL_EVENT_READABLE, udev_drm_event, ec);
2793
2794         if (udev_monitor_enable_receiving(ec->udev_monitor) < 0) {
2795                 weston_log("failed to enable udev-monitor receiving\n");
2796                 goto err_udev_monitor;
2797         }
2798
2799         udev_device_unref(drm_device);
2800
2801         weston_compositor_add_debug_binding(&ec->base, KEY_O,
2802                                             planes_binding, ec);
2803         weston_compositor_add_debug_binding(&ec->base, KEY_C,
2804                                             planes_binding, ec);
2805         weston_compositor_add_debug_binding(&ec->base, KEY_V,
2806                                             planes_binding, ec);
2807         weston_compositor_add_debug_binding(&ec->base, KEY_Q,
2808                                             recorder_binding, ec);
2809         weston_compositor_add_debug_binding(&ec->base, KEY_W,
2810                                             renderer_switch_binding, ec);
2811
2812         return &ec->base;
2813
2814 err_udev_monitor:
2815         wl_event_source_remove(ec->udev_drm_source);
2816         udev_monitor_unref(ec->udev_monitor);
2817 err_drm_source:
2818         wl_event_source_remove(ec->drm_source);
2819         udev_input_destroy(&ec->input);
2820 err_sprite:
2821         ec->base.renderer->destroy(&ec->base);
2822         gbm_device_destroy(ec->gbm);
2823         destroy_sprites(ec);
2824 err_udev_dev:
2825         udev_device_unref(drm_device);
2826 err_launcher:
2827         weston_launcher_destroy(ec->base.launcher);
2828 err_udev:
2829         udev_unref(ec->udev);
2830 err_compositor:
2831         weston_compositor_shutdown(&ec->base);
2832 err_base:
2833         free(ec);
2834         return NULL;
2835 }
2836
2837 WL_EXPORT struct weston_compositor *
2838 backend_init(struct wl_display *display, int *argc, char *argv[],
2839              struct weston_config *config)
2840 {
2841         struct drm_parameters param = { 0, };
2842
2843         const struct weston_option drm_options[] = {
2844                 { WESTON_OPTION_INTEGER, "connector", 0, &param.connector },
2845                 { WESTON_OPTION_STRING, "seat", 0, &param.seat_id },
2846                 { WESTON_OPTION_INTEGER, "tty", 0, &param.tty },
2847                 { WESTON_OPTION_BOOLEAN, "current-mode", 0, &option_current_mode },
2848                 { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &param.use_pixman },
2849         };
2850
2851         param.seat_id = default_seat;
2852
2853         parse_options(drm_options, ARRAY_LENGTH(drm_options), argc, argv);
2854
2855         return drm_compositor_create(display, &param, argc, argv, config);
2856 }