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