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