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