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