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