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