compositor-drm: fix EGL format type
[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         EGLint format;
1264
1265         ec->gbm = gbm_create_device(ec->drm.fd);
1266
1267         if (!ec->gbm)
1268                 return -1;
1269
1270         format = ec->format;
1271         if (gl_renderer_create(&ec->base, ec->gbm,
1272                                gl_renderer_opaque_attribs, &format) < 0) {
1273                 gbm_device_destroy(ec->gbm);
1274                 return -1;
1275         }
1276
1277         return 0;
1278 }
1279
1280 static int
1281 init_pixman(struct drm_compositor *ec)
1282 {
1283         return pixman_renderer_init(&ec->base);
1284 }
1285
1286 static struct drm_mode *
1287 drm_output_add_mode(struct drm_output *output, drmModeModeInfo *info)
1288 {
1289         struct drm_mode *mode;
1290         uint64_t refresh;
1291
1292         mode = malloc(sizeof *mode);
1293         if (mode == NULL)
1294                 return NULL;
1295
1296         mode->base.flags = 0;
1297         mode->base.width = info->hdisplay;
1298         mode->base.height = info->vdisplay;
1299
1300         /* Calculate higher precision (mHz) refresh rate */
1301         refresh = (info->clock * 1000000LL / info->htotal +
1302                    info->vtotal / 2) / info->vtotal;
1303
1304         if (info->flags & DRM_MODE_FLAG_INTERLACE)
1305                 refresh *= 2;
1306         if (info->flags & DRM_MODE_FLAG_DBLSCAN)
1307                 refresh /= 2;
1308         if (info->vscan > 1)
1309             refresh /= info->vscan;
1310
1311         mode->base.refresh = refresh;
1312         mode->mode_info = *info;
1313
1314         if (info->type & DRM_MODE_TYPE_PREFERRED)
1315                 mode->base.flags |= WL_OUTPUT_MODE_PREFERRED;
1316
1317         wl_list_insert(output->base.mode_list.prev, &mode->base.link);
1318
1319         return mode;
1320 }
1321
1322 static int
1323 drm_subpixel_to_wayland(int drm_value)
1324 {
1325         switch (drm_value) {
1326         default:
1327         case DRM_MODE_SUBPIXEL_UNKNOWN:
1328                 return WL_OUTPUT_SUBPIXEL_UNKNOWN;
1329         case DRM_MODE_SUBPIXEL_NONE:
1330                 return WL_OUTPUT_SUBPIXEL_NONE;
1331         case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB:
1332                 return WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB;
1333         case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR:
1334                 return WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR;
1335         case DRM_MODE_SUBPIXEL_VERTICAL_RGB:
1336                 return WL_OUTPUT_SUBPIXEL_VERTICAL_RGB;
1337         case DRM_MODE_SUBPIXEL_VERTICAL_BGR:
1338                 return WL_OUTPUT_SUBPIXEL_VERTICAL_BGR;
1339         }
1340 }
1341
1342 /* returns a value between 0-255 range, where higher is brighter */
1343 static uint32_t
1344 drm_get_backlight(struct drm_output *output)
1345 {
1346         long brightness, max_brightness, norm;
1347
1348         brightness = backlight_get_brightness(output->backlight);
1349         max_brightness = backlight_get_max_brightness(output->backlight);
1350
1351         /* convert it on a scale of 0 to 255 */
1352         norm = (brightness * 255)/(max_brightness);
1353
1354         return (uint32_t) norm;
1355 }
1356
1357 /* values accepted are between 0-255 range */
1358 static void
1359 drm_set_backlight(struct weston_output *output_base, uint32_t value)
1360 {
1361         struct drm_output *output = (struct drm_output *) output_base;
1362         long max_brightness, new_brightness;
1363
1364         if (!output->backlight)
1365                 return;
1366
1367         if (value > 255)
1368                 return;
1369
1370         max_brightness = backlight_get_max_brightness(output->backlight);
1371
1372         /* get denormalized value */
1373         new_brightness = (value * max_brightness) / 255;
1374
1375         backlight_set_brightness(output->backlight, new_brightness);
1376 }
1377
1378 static drmModePropertyPtr
1379 drm_get_prop(int fd, drmModeConnectorPtr connector, const char *name)
1380 {
1381         drmModePropertyPtr props;
1382         int i;
1383
1384         for (i = 0; i < connector->count_props; i++) {
1385                 props = drmModeGetProperty(fd, connector->props[i]);
1386                 if (!props)
1387                         continue;
1388
1389                 if (!strcmp(props->name, name))
1390                         return props;
1391
1392                 drmModeFreeProperty(props);
1393         }
1394
1395         return NULL;
1396 }
1397
1398 static void
1399 drm_set_dpms(struct weston_output *output_base, enum dpms_enum level)
1400 {
1401         struct drm_output *output = (struct drm_output *) output_base;
1402         struct weston_compositor *ec = output_base->compositor;
1403         struct drm_compositor *c = (struct drm_compositor *) ec;
1404
1405         if (!output->dpms_prop)
1406                 return;
1407
1408         drmModeConnectorSetProperty(c->drm.fd, output->connector_id,
1409                                     output->dpms_prop->prop_id, level);
1410 }
1411
1412 static const char *connector_type_names[] = {
1413         "None",
1414         "VGA",
1415         "DVI",
1416         "DVI",
1417         "DVI",
1418         "Composite",
1419         "TV",
1420         "LVDS",
1421         "CTV",
1422         "DIN",
1423         "DP",
1424         "HDMI",
1425         "HDMI",
1426         "TV",
1427         "eDP",
1428 };
1429
1430 static int
1431 find_crtc_for_connector(struct drm_compositor *ec,
1432                         drmModeRes *resources, drmModeConnector *connector)
1433 {
1434         drmModeEncoder *encoder;
1435         uint32_t possible_crtcs;
1436         int i, j;
1437
1438         for (j = 0; j < connector->count_encoders; j++) {
1439                 encoder = drmModeGetEncoder(ec->drm.fd, connector->encoders[j]);
1440                 if (encoder == NULL) {
1441                         weston_log("Failed to get encoder.\n");
1442                         return -1;
1443                 }
1444                 possible_crtcs = encoder->possible_crtcs;
1445                 drmModeFreeEncoder(encoder);
1446
1447                 for (i = 0; i < resources->count_crtcs; i++) {
1448                         if (possible_crtcs & (1 << i) &&
1449                             !(ec->crtc_allocator & (1 << resources->crtcs[i])))
1450                                 return i;
1451                 }
1452         }
1453
1454         return -1;
1455 }
1456
1457 /* Init output state that depends on gl or gbm */
1458 static int
1459 drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec)
1460 {
1461         int i, flags;
1462
1463         output->surface = gbm_surface_create(ec->gbm,
1464                                              output->base.current_mode->width,
1465                                              output->base.current_mode->height,
1466                                              ec->format,
1467                                              GBM_BO_USE_SCANOUT |
1468                                              GBM_BO_USE_RENDERING);
1469         if (!output->surface) {
1470                 weston_log("failed to create gbm surface\n");
1471                 return -1;
1472         }
1473
1474         if (gl_renderer_output_create(&output->base, output->surface) < 0) {
1475                 weston_log("failed to create gl renderer output state\n");
1476                 gbm_surface_destroy(output->surface);
1477                 return -1;
1478         }
1479
1480         flags = GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE;
1481
1482         for (i = 0; i < 2; i++) {
1483                 if (output->cursor_bo[i])
1484                         continue;
1485
1486                 output->cursor_bo[i] =
1487                         gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888,
1488                                       flags);
1489         }
1490
1491         if (output->cursor_bo[0] == NULL || output->cursor_bo[1] == NULL) {
1492                 weston_log("cursor buffers unavailable, using gl cursors\n");
1493                 ec->cursors_are_broken = 1;
1494         }
1495
1496         return 0;
1497 }
1498
1499 static int
1500 drm_output_init_pixman(struct drm_output *output, struct drm_compositor *c)
1501 {
1502         int w = output->base.current_mode->width;
1503         int h = output->base.current_mode->height;
1504         unsigned int i;
1505
1506         /* FIXME error checking */
1507
1508         for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
1509                 output->dumb[i] = drm_fb_create_dumb(c, w, h);
1510                 if (!output->dumb[i])
1511                         goto err;
1512
1513                 output->image[i] =
1514                         pixman_image_create_bits(PIXMAN_x8r8g8b8, w, h,
1515                                                  output->dumb[i]->map,
1516                                                  output->dumb[i]->stride);
1517                 if (!output->image[i])
1518                         goto err;
1519         }
1520
1521         if (pixman_renderer_output_create(&output->base) < 0)
1522                 goto err;
1523
1524         pixman_region32_init_rect(&output->previous_damage,
1525                                   output->base.x, output->base.y, output->base.width, output->base.height);
1526
1527         return 0;
1528
1529 err:
1530         for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
1531                 if (output->dumb[i])
1532                         drm_fb_destroy_dumb(output->dumb[i]);
1533                 if (output->image[i])
1534                         pixman_image_unref(output->image[i]);
1535
1536                 output->dumb[i] = NULL;
1537                 output->image[i] = NULL;
1538         }
1539
1540         return -1;
1541 }
1542
1543 static void
1544 drm_output_fini_pixman(struct drm_output *output)
1545 {
1546         unsigned int i;
1547
1548         pixman_renderer_output_destroy(&output->base);
1549         pixman_region32_fini(&output->previous_damage);
1550
1551         for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
1552                 drm_fb_destroy_dumb(output->dumb[i]);
1553                 pixman_image_unref(output->image[i]);
1554                 output->dumb[i] = NULL;
1555                 output->image[i] = NULL;
1556         }
1557 }
1558
1559 static void
1560 edid_parse_string(const uint8_t *data, char text[])
1561 {
1562         int i;
1563         int replaced = 0;
1564
1565         /* this is always 12 bytes, but we can't guarantee it's null
1566          * terminated or not junk. */
1567         strncpy(text, (const char *) data, 12);
1568
1569         /* remove insane chars */
1570         for (i = 0; text[i] != '\0'; i++) {
1571                 if (text[i] == '\n' ||
1572                     text[i] == '\r') {
1573                         text[i] = '\0';
1574                         break;
1575                 }
1576         }
1577
1578         /* ensure string is printable */
1579         for (i = 0; text[i] != '\0'; i++) {
1580                 if (!isprint(text[i])) {
1581                         text[i] = '-';
1582                         replaced++;
1583                 }
1584         }
1585
1586         /* if the string is random junk, ignore the string */
1587         if (replaced > 4)
1588                 text[0] = '\0';
1589 }
1590
1591 #define EDID_DESCRIPTOR_ALPHANUMERIC_DATA_STRING        0xfe
1592 #define EDID_DESCRIPTOR_DISPLAY_PRODUCT_NAME            0xfc
1593 #define EDID_DESCRIPTOR_DISPLAY_PRODUCT_SERIAL_NUMBER   0xff
1594 #define EDID_OFFSET_DATA_BLOCKS                         0x36
1595 #define EDID_OFFSET_LAST_BLOCK                          0x6c
1596 #define EDID_OFFSET_PNPID                               0x08
1597 #define EDID_OFFSET_SERIAL                              0x0c
1598
1599 static int
1600 edid_parse(struct drm_edid *edid, const uint8_t *data, size_t length)
1601 {
1602         int i;
1603         uint32_t serial_number;
1604
1605         /* check header */
1606         if (length < 128)
1607                 return -1;
1608         if (data[0] != 0x00 || data[1] != 0xff)
1609                 return -1;
1610
1611         /* decode the PNP ID from three 5 bit words packed into 2 bytes
1612          * /--08--\/--09--\
1613          * 7654321076543210
1614          * |\---/\---/\---/
1615          * R  C1   C2   C3 */
1616         edid->pnp_id[0] = 'A' + ((data[EDID_OFFSET_PNPID + 0] & 0x7c) / 4) - 1;
1617         edid->pnp_id[1] = 'A' + ((data[EDID_OFFSET_PNPID + 0] & 0x3) * 8) + ((data[EDID_OFFSET_PNPID + 1] & 0xe0) / 32) - 1;
1618         edid->pnp_id[2] = 'A' + (data[EDID_OFFSET_PNPID + 1] & 0x1f) - 1;
1619         edid->pnp_id[3] = '\0';
1620
1621         /* maybe there isn't a ASCII serial number descriptor, so use this instead */
1622         serial_number = (uint32_t) data[EDID_OFFSET_SERIAL + 0];
1623         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 1] * 0x100;
1624         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 2] * 0x10000;
1625         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 3] * 0x1000000;
1626         if (serial_number > 0)
1627                 sprintf(edid->serial_number, "%lu", (unsigned long) serial_number);
1628
1629         /* parse EDID data */
1630         for (i = EDID_OFFSET_DATA_BLOCKS;
1631              i <= EDID_OFFSET_LAST_BLOCK;
1632              i += 18) {
1633                 /* ignore pixel clock data */
1634                 if (data[i] != 0)
1635                         continue;
1636                 if (data[i+2] != 0)
1637                         continue;
1638
1639                 /* any useful blocks? */
1640                 if (data[i+3] == EDID_DESCRIPTOR_DISPLAY_PRODUCT_NAME) {
1641                         edid_parse_string(&data[i+5],
1642                                           edid->monitor_name);
1643                 } else if (data[i+3] == EDID_DESCRIPTOR_DISPLAY_PRODUCT_SERIAL_NUMBER) {
1644                         edid_parse_string(&data[i+5],
1645                                           edid->serial_number);
1646                 } else if (data[i+3] == EDID_DESCRIPTOR_ALPHANUMERIC_DATA_STRING) {
1647                         edid_parse_string(&data[i+5],
1648                                           edid->eisa_id);
1649                 }
1650         }
1651         return 0;
1652 }
1653
1654 static void
1655 find_and_parse_output_edid(struct drm_compositor *ec,
1656                            struct drm_output *output,
1657                            drmModeConnector *connector)
1658 {
1659         drmModePropertyBlobPtr edid_blob = NULL;
1660         drmModePropertyPtr property;
1661         int i;
1662         int rc;
1663
1664         for (i = 0; i < connector->count_props && !edid_blob; i++) {
1665                 property = drmModeGetProperty(ec->drm.fd, connector->props[i]);
1666                 if (!property)
1667                         continue;
1668                 if ((property->flags & DRM_MODE_PROP_BLOB) &&
1669                     !strcmp(property->name, "EDID")) {
1670                         edid_blob = drmModeGetPropertyBlob(ec->drm.fd,
1671                                                            connector->prop_values[i]);
1672                 }
1673                 drmModeFreeProperty(property);
1674         }
1675         if (!edid_blob)
1676                 return;
1677
1678         rc = edid_parse(&output->edid,
1679                         edid_blob->data,
1680                         edid_blob->length);
1681         if (!rc) {
1682                 weston_log("EDID data '%s', '%s', '%s'\n",
1683                            output->edid.pnp_id,
1684                            output->edid.monitor_name,
1685                            output->edid.serial_number);
1686                 if (output->edid.pnp_id[0] != '\0')
1687                         output->base.make = output->edid.pnp_id;
1688                 if (output->edid.monitor_name[0] != '\0')
1689                         output->base.model = output->edid.monitor_name;
1690                 if (output->edid.serial_number[0] != '\0')
1691                         output->base.serial_number = output->edid.serial_number;
1692         }
1693         drmModeFreePropertyBlob(edid_blob);
1694 }
1695
1696
1697
1698 static int
1699 parse_modeline(const char *s, drmModeModeInfo *mode)
1700 {
1701         char hsync[16];
1702         char vsync[16];
1703         float fclock;
1704
1705         mode->type = DRM_MODE_TYPE_USERDEF;
1706         mode->hskew = 0;
1707         mode->vscan = 0;
1708         mode->vrefresh = 0;
1709         mode->flags = 0;
1710
1711         if (sscanf(s, "%f %hd %hd %hd %hd %hd %hd %hd %hd %15s %15s",
1712                    &fclock,
1713                    &mode->hdisplay,
1714                    &mode->hsync_start,
1715                    &mode->hsync_end,
1716                    &mode->htotal,
1717                    &mode->vdisplay,
1718                    &mode->vsync_start,
1719                    &mode->vsync_end,
1720                    &mode->vtotal, hsync, vsync) != 11)
1721                 return -1;
1722
1723         mode->clock = fclock * 1000;
1724         if (strcmp(hsync, "+hsync") == 0)
1725                 mode->flags |= DRM_MODE_FLAG_PHSYNC;
1726         else if (strcmp(hsync, "-hsync") == 0)
1727                 mode->flags |= DRM_MODE_FLAG_NHSYNC;
1728         else
1729                 return -1;
1730
1731         if (strcmp(vsync, "+vsync") == 0)
1732                 mode->flags |= DRM_MODE_FLAG_PVSYNC;
1733         else if (strcmp(vsync, "-vsync") == 0)
1734                 mode->flags |= DRM_MODE_FLAG_NVSYNC;
1735         else
1736                 return -1;
1737
1738         return 0;
1739 }
1740
1741 static uint32_t
1742 parse_transform(const char *transform, const char *output_name)
1743 {
1744         static const struct { const char *name; uint32_t token; } names[] = {
1745                 { "normal",     WL_OUTPUT_TRANSFORM_NORMAL },
1746                 { "90",         WL_OUTPUT_TRANSFORM_90 },
1747                 { "180",        WL_OUTPUT_TRANSFORM_180 },
1748                 { "270",        WL_OUTPUT_TRANSFORM_270 },
1749                 { "flipped",    WL_OUTPUT_TRANSFORM_FLIPPED },
1750                 { "flipped-90", WL_OUTPUT_TRANSFORM_FLIPPED_90 },
1751                 { "flipped-180", WL_OUTPUT_TRANSFORM_FLIPPED_180 },
1752                 { "flipped-270", WL_OUTPUT_TRANSFORM_FLIPPED_270 },
1753         };
1754         unsigned int i;
1755
1756         for (i = 0; i < ARRAY_LENGTH(names); i++)
1757                 if (strcmp(names[i].name, transform) == 0)
1758                         return names[i].token;
1759
1760         weston_log("Invalid transform \"%s\" for output %s\n",
1761                    transform, output_name);
1762
1763         return WL_OUTPUT_TRANSFORM_NORMAL;
1764 }
1765
1766 static void
1767 setup_output_seat_constraint(struct drm_compositor *ec,
1768                              struct weston_output *output,
1769                              const char *s)
1770 {
1771         if (strcmp(s, "") != 0) {
1772                 struct udev_seat *seat;
1773
1774                 seat = udev_seat_get_named(&ec->base, s);
1775                 if (seat)
1776                         seat->base.output = output;
1777
1778                 if (seat && seat->base.pointer)
1779                         weston_pointer_clamp(seat->base.pointer,
1780                                              &seat->base.pointer->x,
1781                                              &seat->base.pointer->y);
1782         }
1783 }
1784
1785 static int
1786 create_output_for_connector(struct drm_compositor *ec,
1787                             drmModeRes *resources,
1788                             drmModeConnector *connector,
1789                             int x, int y, struct udev_device *drm_device)
1790 {
1791         struct drm_output *output;
1792         struct drm_mode *drm_mode, *next, *preferred, *current, *configured;
1793         struct weston_mode *m;
1794         struct weston_config_section *section;
1795         drmModeEncoder *encoder;
1796         drmModeModeInfo crtc_mode, modeline;
1797         drmModeCrtc *crtc;
1798         int i, width, height, scale;
1799         char name[32], *s;
1800         const char *type_name;
1801         enum output_config config;
1802         uint32_t transform;
1803
1804         i = find_crtc_for_connector(ec, resources, connector);
1805         if (i < 0) {
1806                 weston_log("No usable crtc/encoder pair for connector.\n");
1807                 return -1;
1808         }
1809
1810         output = zalloc(sizeof *output);
1811         if (output == NULL)
1812                 return -1;
1813
1814         output->base.subpixel = drm_subpixel_to_wayland(connector->subpixel);
1815         output->base.make = "unknown";
1816         output->base.model = "unknown";
1817         output->base.serial_number = "unknown";
1818         wl_list_init(&output->base.mode_list);
1819
1820         if (connector->connector_type < ARRAY_LENGTH(connector_type_names))
1821                 type_name = connector_type_names[connector->connector_type];
1822         else
1823                 type_name = "UNKNOWN";
1824         snprintf(name, 32, "%s%d", type_name, connector->connector_type_id);
1825         output->base.name = strdup(name);
1826
1827         section = weston_config_get_section(ec->base.config, "output", "name",
1828                                             output->base.name);
1829         weston_config_section_get_string(section, "mode", &s, "preferred");
1830         if (strcmp(s, "off") == 0)
1831                 config = OUTPUT_CONFIG_OFF;
1832         else if (strcmp(s, "preferred") == 0)
1833                 config = OUTPUT_CONFIG_PREFERRED;
1834         else if (strcmp(s, "current") == 0)
1835                 config = OUTPUT_CONFIG_CURRENT;
1836         else if (sscanf(s, "%dx%d", &width, &height) == 2)
1837                 config = OUTPUT_CONFIG_MODE;
1838         else if (parse_modeline(s, &modeline) == 0)
1839                 config = OUTPUT_CONFIG_MODELINE;
1840         else {
1841                 weston_log("Invalid mode \"%s\" for output %s\n",
1842                            s, output->base.name);
1843                 config = OUTPUT_CONFIG_PREFERRED;
1844         }
1845         free(s);
1846
1847         weston_config_section_get_int(section, "scale", &scale, 1);
1848         weston_config_section_get_string(section, "transform", &s, "normal");
1849         transform = parse_transform(s, output->base.name);
1850         free(s);
1851
1852         weston_config_section_get_string(section, "seat", &s, "");
1853         setup_output_seat_constraint(ec, &output->base, s);
1854         free(s);
1855
1856         output->crtc_id = resources->crtcs[i];
1857         output->pipe = i;
1858         ec->crtc_allocator |= (1 << output->crtc_id);
1859         output->connector_id = connector->connector_id;
1860         ec->connector_allocator |= (1 << output->connector_id);
1861
1862         output->original_crtc = drmModeGetCrtc(ec->drm.fd, output->crtc_id);
1863         output->dpms_prop = drm_get_prop(ec->drm.fd, connector, "DPMS");
1864
1865         /* Get the current mode on the crtc that's currently driving
1866          * this connector. */
1867         encoder = drmModeGetEncoder(ec->drm.fd, connector->encoder_id);
1868         memset(&crtc_mode, 0, sizeof crtc_mode);
1869         if (encoder != NULL) {
1870                 crtc = drmModeGetCrtc(ec->drm.fd, encoder->crtc_id);
1871                 drmModeFreeEncoder(encoder);
1872                 if (crtc == NULL)
1873                         goto err_free;
1874                 if (crtc->mode_valid)
1875                         crtc_mode = crtc->mode;
1876                 drmModeFreeCrtc(crtc);
1877         }
1878
1879         for (i = 0; i < connector->count_modes; i++) {
1880                 drm_mode = drm_output_add_mode(output, &connector->modes[i]);
1881                 if (!drm_mode)
1882                         goto err_free;
1883         }
1884
1885         if (config == OUTPUT_CONFIG_OFF) {
1886                 weston_log("Disabling output %s\n", output->base.name);
1887                 drmModeSetCrtc(ec->drm.fd, output->crtc_id,
1888                                0, 0, 0, 0, 0, NULL);
1889                 goto err_free;
1890         }
1891
1892         preferred = NULL;
1893         current = NULL;
1894         configured = NULL;
1895
1896         wl_list_for_each_reverse(drm_mode, &output->base.mode_list, base.link) {
1897                 if (config == OUTPUT_CONFIG_MODE &&
1898                     width == drm_mode->base.width &&
1899                     height == drm_mode->base.height)
1900                         configured = drm_mode;
1901                 if (!memcmp(&crtc_mode, &drm_mode->mode_info, sizeof crtc_mode))
1902                         current = drm_mode;
1903                 if (drm_mode->base.flags & WL_OUTPUT_MODE_PREFERRED)
1904                         preferred = drm_mode;
1905         }
1906
1907         if (config == OUTPUT_CONFIG_MODELINE) {
1908                 configured = drm_output_add_mode(output, &modeline);
1909                 if (!configured)
1910                         goto err_free;
1911         }
1912
1913         if (current == NULL && crtc_mode.clock != 0) {
1914                 current = drm_output_add_mode(output, &crtc_mode);
1915                 if (!current)
1916                         goto err_free;
1917         }
1918
1919         if (config == OUTPUT_CONFIG_CURRENT)
1920                 configured = current;
1921
1922         if (option_current_mode && current)
1923                 output->base.current_mode = &current->base;
1924         else if (configured)
1925                 output->base.current_mode = &configured->base;
1926         else if (preferred)
1927                 output->base.current_mode = &preferred->base;
1928         else if (current)
1929                 output->base.current_mode = &current->base;
1930
1931         if (output->base.current_mode == NULL) {
1932                 weston_log("no available modes for %s\n", output->base.name);
1933                 goto err_free;
1934         }
1935
1936         output->base.current_mode->flags |= WL_OUTPUT_MODE_CURRENT;
1937
1938         weston_output_init(&output->base, &ec->base, x, y,
1939                            connector->mmWidth, connector->mmHeight,
1940                            transform, scale);
1941
1942         if (ec->use_pixman) {
1943                 if (drm_output_init_pixman(output, ec) < 0) {
1944                         weston_log("Failed to init output pixman state\n");
1945                         goto err_output;
1946                 }
1947         } else if (drm_output_init_egl(output, ec) < 0) {
1948                 weston_log("Failed to init output gl state\n");
1949                 goto err_output;
1950         }
1951
1952         output->backlight = backlight_init(drm_device,
1953                                            connector->connector_type);
1954         if (output->backlight) {
1955                 weston_log("Initialized backlight, device %s\n",
1956                            output->backlight->path);
1957                 output->base.set_backlight = drm_set_backlight;
1958                 output->base.backlight_current = drm_get_backlight(output);
1959         } else {
1960                 weston_log("Failed to initialize backlight\n");
1961         }
1962
1963         wl_list_insert(ec->base.output_list.prev, &output->base.link);
1964
1965         find_and_parse_output_edid(ec, output, connector);
1966         if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
1967                 output->base.connection_internal = 1;
1968
1969         output->base.start_repaint_loop = drm_output_start_repaint_loop;
1970         output->base.repaint = drm_output_repaint;
1971         output->base.destroy = drm_output_destroy;
1972         output->base.assign_planes = drm_assign_planes;
1973         output->base.set_dpms = drm_set_dpms;
1974         output->base.switch_mode = drm_output_switch_mode;
1975
1976         output->base.gamma_size = output->original_crtc->gamma_size;
1977         output->base.set_gamma = drm_output_set_gamma;
1978
1979         weston_plane_init(&output->cursor_plane, 0, 0);
1980         weston_plane_init(&output->fb_plane, 0, 0);
1981
1982         weston_compositor_stack_plane(&ec->base, &output->cursor_plane, NULL);
1983         weston_compositor_stack_plane(&ec->base, &output->fb_plane,
1984                                       &ec->base.primary_plane);
1985
1986         weston_log("Output %s, (connector %d, crtc %d)\n",
1987                    output->base.name, output->connector_id, output->crtc_id);
1988         wl_list_for_each(m, &output->base.mode_list, link)
1989                 weston_log_continue("  mode %dx%d@%.1f%s%s%s\n",
1990                                     m->width, m->height, m->refresh / 1000.0,
1991                                     m->flags & WL_OUTPUT_MODE_PREFERRED ?
1992                                     ", preferred" : "",
1993                                     m->flags & WL_OUTPUT_MODE_CURRENT ?
1994                                     ", current" : "",
1995                                     connector->count_modes == 0 ?
1996                                     ", built-in" : "");
1997
1998         return 0;
1999
2000 err_output:
2001         weston_output_destroy(&output->base);
2002 err_free:
2003         wl_list_for_each_safe(drm_mode, next, &output->base.mode_list,
2004                                                         base.link) {
2005                 wl_list_remove(&drm_mode->base.link);
2006                 free(drm_mode);
2007         }
2008
2009         drmModeFreeCrtc(output->original_crtc);
2010         ec->crtc_allocator &= ~(1 << output->crtc_id);
2011         ec->connector_allocator &= ~(1 << output->connector_id);
2012         free(output);
2013
2014         return -1;
2015 }
2016
2017 static void
2018 create_sprites(struct drm_compositor *ec)
2019 {
2020         struct drm_sprite *sprite;
2021         drmModePlaneRes *plane_res;
2022         drmModePlane *plane;
2023         uint32_t i;
2024
2025         plane_res = drmModeGetPlaneResources(ec->drm.fd);
2026         if (!plane_res) {
2027                 weston_log("failed to get plane resources: %s\n",
2028                         strerror(errno));
2029                 return;
2030         }
2031
2032         for (i = 0; i < plane_res->count_planes; i++) {
2033                 plane = drmModeGetPlane(ec->drm.fd, plane_res->planes[i]);
2034                 if (!plane)
2035                         continue;
2036
2037                 sprite = zalloc(sizeof(*sprite) + ((sizeof(uint32_t)) *
2038                                                    plane->count_formats));
2039                 if (!sprite) {
2040                         weston_log("%s: out of memory\n",
2041                                 __func__);
2042                         free(plane);
2043                         continue;
2044                 }
2045
2046                 sprite->possible_crtcs = plane->possible_crtcs;
2047                 sprite->plane_id = plane->plane_id;
2048                 sprite->current = NULL;
2049                 sprite->next = NULL;
2050                 sprite->compositor = ec;
2051                 sprite->count_formats = plane->count_formats;
2052                 memcpy(sprite->formats, plane->formats,
2053                        plane->count_formats * sizeof(plane->formats[0]));
2054                 drmModeFreePlane(plane);
2055                 weston_plane_init(&sprite->plane, 0, 0);
2056                 weston_compositor_stack_plane(&ec->base, &sprite->plane,
2057                                               &ec->base.primary_plane);
2058
2059                 wl_list_insert(&ec->sprite_list, &sprite->link);
2060         }
2061
2062         drmModeFreePlaneResources(plane_res);
2063 }
2064
2065 static void
2066 destroy_sprites(struct drm_compositor *compositor)
2067 {
2068         struct drm_sprite *sprite, *next;
2069         struct drm_output *output;
2070
2071         output = container_of(compositor->base.output_list.next,
2072                               struct drm_output, base.link);
2073
2074         wl_list_for_each_safe(sprite, next, &compositor->sprite_list, link) {
2075                 drmModeSetPlane(compositor->drm.fd,
2076                                 sprite->plane_id,
2077                                 output->crtc_id, 0, 0,
2078                                 0, 0, 0, 0, 0, 0, 0, 0);
2079                 drm_output_release_fb(output, sprite->current);
2080                 drm_output_release_fb(output, sprite->next);
2081                 weston_plane_release(&sprite->plane);
2082                 free(sprite);
2083         }
2084 }
2085
2086 static int
2087 create_outputs(struct drm_compositor *ec, uint32_t option_connector,
2088                struct udev_device *drm_device)
2089 {
2090         drmModeConnector *connector;
2091         drmModeRes *resources;
2092         int i;
2093         int x = 0, y = 0;
2094
2095         resources = drmModeGetResources(ec->drm.fd);
2096         if (!resources) {
2097                 weston_log("drmModeGetResources failed\n");
2098                 return -1;
2099         }
2100
2101         ec->crtcs = calloc(resources->count_crtcs, sizeof(uint32_t));
2102         if (!ec->crtcs) {
2103                 drmModeFreeResources(resources);
2104                 return -1;
2105         }
2106
2107         ec->min_width  = resources->min_width;
2108         ec->max_width  = resources->max_width;
2109         ec->min_height = resources->min_height;
2110         ec->max_height = resources->max_height;
2111
2112         ec->num_crtcs = resources->count_crtcs;
2113         memcpy(ec->crtcs, resources->crtcs, sizeof(uint32_t) * ec->num_crtcs);
2114
2115         for (i = 0; i < resources->count_connectors; i++) {
2116                 connector = drmModeGetConnector(ec->drm.fd,
2117                                                 resources->connectors[i]);
2118                 if (connector == NULL)
2119                         continue;
2120
2121                 if (connector->connection == DRM_MODE_CONNECTED &&
2122                     (option_connector == 0 ||
2123                      connector->connector_id == option_connector)) {
2124                         if (create_output_for_connector(ec, resources,
2125                                                         connector, x, y,
2126                                                         drm_device) < 0) {
2127                                 drmModeFreeConnector(connector);
2128                                 continue;
2129                         }
2130
2131                         x += container_of(ec->base.output_list.prev,
2132                                           struct weston_output,
2133                                           link)->width;
2134                 }
2135
2136                 drmModeFreeConnector(connector);
2137         }
2138
2139         if (wl_list_empty(&ec->base.output_list)) {
2140                 weston_log("No currently active connector found.\n");
2141                 drmModeFreeResources(resources);
2142                 return -1;
2143         }
2144
2145         drmModeFreeResources(resources);
2146
2147         return 0;
2148 }
2149
2150 static void
2151 update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
2152 {
2153         drmModeConnector *connector;
2154         drmModeRes *resources;
2155         struct drm_output *output, *next;
2156         int x = 0, y = 0;
2157         int x_offset = 0, y_offset = 0;
2158         uint32_t connected = 0, disconnects = 0;
2159         int i;
2160
2161         resources = drmModeGetResources(ec->drm.fd);
2162         if (!resources) {
2163                 weston_log("drmModeGetResources failed\n");
2164                 return;
2165         }
2166
2167         /* collect new connects */
2168         for (i = 0; i < resources->count_connectors; i++) {
2169                 int connector_id = resources->connectors[i];
2170
2171                 connector = drmModeGetConnector(ec->drm.fd, connector_id);
2172                 if (connector == NULL)
2173                         continue;
2174
2175                 if (connector->connection != DRM_MODE_CONNECTED) {
2176                         drmModeFreeConnector(connector);
2177                         continue;
2178                 }
2179
2180                 connected |= (1 << connector_id);
2181
2182                 if (!(ec->connector_allocator & (1 << connector_id))) {
2183                         struct weston_output *last =
2184                                 container_of(ec->base.output_list.prev,
2185                                              struct weston_output, link);
2186
2187                         /* XXX: not yet needed, we die with 0 outputs */
2188                         if (!wl_list_empty(&ec->base.output_list))
2189                                 x = last->x + last->width;
2190                         else
2191                                 x = 0;
2192                         y = 0;
2193                         create_output_for_connector(ec, resources,
2194                                                     connector, x, y,
2195                                                     drm_device);
2196                         weston_log("connector %d connected\n", connector_id);
2197
2198                 }
2199                 drmModeFreeConnector(connector);
2200         }
2201         drmModeFreeResources(resources);
2202
2203         disconnects = ec->connector_allocator & ~connected;
2204         if (disconnects) {
2205                 wl_list_for_each_safe(output, next, &ec->base.output_list,
2206                                       base.link) {
2207                         if (x_offset != 0 || y_offset != 0) {
2208                                 weston_output_move(&output->base,
2209                                                  output->base.x - x_offset,
2210                                                  output->base.y - y_offset);
2211                         }
2212
2213                         if (disconnects & (1 << output->connector_id)) {
2214                                 disconnects &= ~(1 << output->connector_id);
2215                                 weston_log("connector %d disconnected\n",
2216                                        output->connector_id);
2217                                 x_offset += output->base.width;
2218                                 drm_output_destroy(&output->base);
2219                         }
2220                 }
2221         }
2222
2223         /* FIXME: handle zero outputs, without terminating */   
2224         if (ec->connector_allocator == 0)
2225                 wl_display_terminate(ec->base.wl_display);
2226 }
2227
2228 static int
2229 udev_event_is_hotplug(struct drm_compositor *ec, struct udev_device *device)
2230 {
2231         const char *sysnum;
2232         const char *val;
2233
2234         sysnum = udev_device_get_sysnum(device);
2235         if (!sysnum || atoi(sysnum) != ec->drm.id)
2236                 return 0;
2237
2238         val = udev_device_get_property_value(device, "HOTPLUG");
2239         if (!val)
2240                 return 0;
2241
2242         return strcmp(val, "1") == 0;
2243 }
2244
2245 static int
2246 udev_drm_event(int fd, uint32_t mask, void *data)
2247 {
2248         struct drm_compositor *ec = data;
2249         struct udev_device *event;
2250
2251         event = udev_monitor_receive_device(ec->udev_monitor);
2252
2253         if (udev_event_is_hotplug(ec, event))
2254                 update_outputs(ec, event);
2255
2256         udev_device_unref(event);
2257
2258         return 1;
2259 }
2260
2261 static void
2262 drm_restore(struct weston_compositor *ec)
2263 {
2264         weston_launcher_restore(ec->launcher);
2265 }
2266
2267 static void
2268 drm_destroy(struct weston_compositor *ec)
2269 {
2270         struct drm_compositor *d = (struct drm_compositor *) ec;
2271
2272         udev_input_destroy(&d->input);
2273
2274         wl_event_source_remove(d->udev_drm_source);
2275         wl_event_source_remove(d->drm_source);
2276
2277         destroy_sprites(d);
2278
2279         weston_compositor_shutdown(ec);
2280
2281         ec->renderer->destroy(ec);
2282
2283         if (d->gbm)
2284                 gbm_device_destroy(d->gbm);
2285
2286         weston_launcher_destroy(d->base.launcher);
2287
2288         close(d->drm.fd);
2289
2290         free(d);
2291 }
2292
2293 static void
2294 drm_compositor_set_modes(struct drm_compositor *compositor)
2295 {
2296         struct drm_output *output;
2297         struct drm_mode *drm_mode;
2298         int ret;
2299
2300         wl_list_for_each(output, &compositor->base.output_list, base.link) {
2301                 if (!output->current) {
2302                         /* If something that would cause the output to
2303                          * switch mode happened while in another vt, we
2304                          * might not have a current drm_fb. In that case,
2305                          * schedule a repaint and let drm_output_repaint
2306                          * handle setting the mode. */
2307                         weston_output_schedule_repaint(&output->base);
2308                         continue;
2309                 }
2310
2311                 drm_mode = (struct drm_mode *) output->base.current_mode;
2312                 ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id,
2313                                      output->current->fb_id, 0, 0,
2314                                      &output->connector_id, 1,
2315                                      &drm_mode->mode_info);
2316                 if (ret < 0) {
2317                         weston_log(
2318                                 "failed to set mode %dx%d for output at %d,%d: %m\n",
2319                                 drm_mode->base.width, drm_mode->base.height, 
2320                                 output->base.x, output->base.y);
2321                 }
2322         }
2323 }
2324
2325 static void
2326 session_notify(struct wl_listener *listener, void *data)
2327 {
2328         struct weston_compositor *compositor = data;
2329         struct drm_compositor *ec = data;
2330         struct drm_sprite *sprite;
2331         struct drm_output *output;
2332
2333         if (ec->base.session_active) {
2334                 weston_log("activating session\n");
2335                 compositor->focus = 1;
2336                 if (ec->base.launcher == NULL && drmSetMaster(ec->drm.fd)) {
2337                         weston_log("failed to set master: %m\n");
2338                         wl_display_terminate(compositor->wl_display);
2339                 }
2340                 compositor->state = ec->prev_state;
2341                 drm_compositor_set_modes(ec);
2342                 weston_compositor_damage_all(compositor);
2343                 udev_input_enable(&ec->input, ec->udev);
2344         } else {
2345                 weston_log("deactivating session\n");
2346                 udev_input_disable(&ec->input);
2347
2348                 compositor->focus = 0;
2349                 ec->prev_state = compositor->state;
2350                 weston_compositor_offscreen(compositor);
2351
2352                 /* If we have a repaint scheduled (either from a
2353                  * pending pageflip or the idle handler), make sure we
2354                  * cancel that so we don't try to pageflip when we're
2355                  * vt switched away.  The OFFSCREEN state will prevent
2356                  * further attemps at repainting.  When we switch
2357                  * back, we schedule a repaint, which will process
2358                  * pending frame callbacks. */
2359
2360                 wl_list_for_each(output, &ec->base.output_list, base.link) {
2361                         output->base.repaint_needed = 0;
2362                         drmModeSetCursor(ec->drm.fd, output->crtc_id, 0, 0, 0);
2363                 }
2364
2365                 output = container_of(ec->base.output_list.next,
2366                                       struct drm_output, base.link);
2367
2368                 wl_list_for_each(sprite, &ec->sprite_list, link)
2369                         drmModeSetPlane(ec->drm.fd,
2370                                         sprite->plane_id,
2371                                         output->crtc_id, 0, 0,
2372                                         0, 0, 0, 0, 0, 0, 0, 0);
2373
2374                 if (ec->base.launcher == NULL && drmDropMaster(ec->drm.fd) < 0)
2375                         weston_log("failed to drop master: %m\n");
2376         };
2377 }
2378
2379 static void
2380 switch_vt_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
2381 {
2382         struct weston_compositor *compositor = data;
2383
2384         weston_launcher_activate_vt(compositor->launcher, key - KEY_F1 + 1);
2385 }
2386
2387 /*
2388  * Find primary GPU
2389  * Some systems may have multiple DRM devices attached to a single seat. This
2390  * function loops over all devices and tries to find a PCI device with the
2391  * boot_vga sysfs attribute set to 1.
2392  * If no such device is found, the first DRM device reported by udev is used.
2393  */
2394 static struct udev_device*
2395 find_primary_gpu(struct drm_compositor *ec, const char *seat)
2396 {
2397         struct udev_enumerate *e;
2398         struct udev_list_entry *entry;
2399         const char *path, *device_seat, *id;
2400         struct udev_device *device, *drm_device, *pci;
2401
2402         e = udev_enumerate_new(ec->udev);
2403         udev_enumerate_add_match_subsystem(e, "drm");
2404         udev_enumerate_add_match_sysname(e, "card[0-9]*");
2405
2406         udev_enumerate_scan_devices(e);
2407         drm_device = NULL;
2408         udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
2409                 path = udev_list_entry_get_name(entry);
2410                 device = udev_device_new_from_syspath(ec->udev, path);
2411                 if (!device)
2412                         continue;
2413                 device_seat = udev_device_get_property_value(device, "ID_SEAT");
2414                 if (!device_seat)
2415                         device_seat = default_seat;
2416                 if (strcmp(device_seat, seat)) {
2417                         udev_device_unref(device);
2418                         continue;
2419                 }
2420
2421                 pci = udev_device_get_parent_with_subsystem_devtype(device,
2422                                                                 "pci", NULL);
2423                 if (pci) {
2424                         id = udev_device_get_sysattr_value(pci, "boot_vga");
2425                         if (id && !strcmp(id, "1")) {
2426                                 if (drm_device)
2427                                         udev_device_unref(drm_device);
2428                                 drm_device = device;
2429                                 break;
2430                         }
2431                 }
2432
2433                 if (!drm_device)
2434                         drm_device = device;
2435                 else
2436                         udev_device_unref(device);
2437         }
2438
2439         udev_enumerate_unref(e);
2440         return drm_device;
2441 }
2442
2443 static void
2444 planes_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
2445 {
2446         struct drm_compositor *c = data;
2447
2448         switch (key) {
2449         case KEY_C:
2450                 c->cursors_are_broken ^= 1;
2451                 break;
2452         case KEY_V:
2453                 c->sprites_are_broken ^= 1;
2454                 break;
2455         case KEY_O:
2456                 c->sprites_hidden ^= 1;
2457                 break;
2458         default:
2459                 break;
2460         }
2461 }
2462
2463 #ifdef BUILD_VAAPI_RECORDER
2464 static void
2465 recorder_frame_notify(struct wl_listener *listener, void *data)
2466 {
2467         struct drm_output *output;
2468         struct drm_compositor *c;
2469         int fd, ret;
2470
2471         output = container_of(listener, struct drm_output,
2472                               recorder_frame_listener);
2473         c = (struct drm_compositor *) output->base.compositor;
2474
2475         if (!output->recorder)
2476                 return;
2477
2478         ret = drmPrimeHandleToFD(c->drm.fd, output->current->handle,
2479                                  DRM_CLOEXEC, &fd);
2480         if (ret) {
2481                 weston_log("[libva recorder] "
2482                            "failed to create prime fd for front buffer\n");
2483                 return;
2484         }
2485
2486         vaapi_recorder_frame(output->recorder, fd, output->current->stride / 4);
2487 }
2488
2489 static void *
2490 create_recorder(struct drm_compositor *c, int width, int height,
2491                 const char *filename)
2492 {
2493         int fd;
2494         drm_magic_t magic;
2495
2496         fd = open(c->drm.filename, O_RDWR | O_CLOEXEC);
2497         if (fd < 0)
2498                 return NULL;
2499
2500         drmGetMagic(fd, &magic);
2501         drmAuthMagic(c->drm.fd, magic);
2502
2503         return vaapi_recorder_create(fd, width, height, filename);
2504 }
2505
2506 static void
2507 recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
2508                  void *data)
2509 {
2510         struct drm_compositor *c = data;
2511         struct drm_output *output;
2512         int width, height;
2513
2514         output = container_of(c->base.output_list.next,
2515                               struct drm_output, base.link);
2516
2517         if (!output->recorder) {
2518                 width = output->base.current_mode->width;
2519                 height = output->base.current_mode->height;
2520
2521                 output->recorder =
2522                         create_recorder(c, width, height, "capture.h264");
2523                 if (!output->recorder) {
2524                         weston_log("failed to create vaapi recorder\n");
2525                         return;
2526                 }
2527
2528                 output->base.disable_planes++;
2529
2530                 output->recorder_frame_listener.notify = recorder_frame_notify;
2531                 wl_signal_add(&output->base.frame_signal,
2532                               &output->recorder_frame_listener);
2533
2534                 weston_output_schedule_repaint(&output->base);
2535
2536                 weston_log("[libva recorder] initialized\n");
2537         } else {
2538                 vaapi_recorder_destroy(output->recorder);
2539                 output->recorder = NULL;
2540
2541                 output->base.disable_planes--;
2542
2543                 wl_list_remove(&output->recorder_frame_listener.link);
2544                 weston_log("[libva recorder] done\n");
2545         }
2546 }
2547 #else
2548 static void
2549 recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
2550                  void *data)
2551 {
2552         weston_log("Compiled without libva support\n");
2553 }
2554 #endif
2555
2556 static struct weston_compositor *
2557 drm_compositor_create(struct wl_display *display,
2558                       int connector, const char *seat_id, int tty, int pixman,
2559                       int *argc, char *argv[],
2560                       struct weston_config *config)
2561 {
2562         struct drm_compositor *ec;
2563         struct udev_device *drm_device;
2564         struct wl_event_loop *loop;
2565         const char *path;
2566         uint32_t key;
2567
2568         weston_log("initializing drm backend\n");
2569
2570         ec = zalloc(sizeof *ec);
2571         if (ec == NULL)
2572                 return NULL;
2573
2574         /* KMS support for sprites is not complete yet, so disable the
2575          * functionality for now. */
2576         ec->sprites_are_broken = 1;
2577         ec->format = GBM_FORMAT_XRGB8888;
2578         ec->use_pixman = pixman;
2579
2580         if (weston_compositor_init(&ec->base, display, argc, argv,
2581                                    config) < 0) {
2582                 weston_log("%s failed\n", __func__);
2583                 goto err_base;
2584         }
2585
2586         /* Check if we run drm-backend using weston-launch */
2587         ec->base.launcher = weston_launcher_connect(&ec->base, tty);
2588         if (ec->base.launcher == NULL) {
2589                 weston_log("fatal: drm backend should be run "
2590                            "using weston-launch binary or as root\n");
2591                 goto err_compositor;
2592         }
2593
2594         ec->udev = udev_new();
2595         if (ec->udev == NULL) {
2596                 weston_log("failed to initialize udev context\n");
2597                 goto err_launcher;
2598         }
2599
2600         ec->base.wl_display = display;
2601         ec->session_listener.notify = session_notify;
2602         wl_signal_add(&ec->base.session_signal, &ec->session_listener);
2603
2604         drm_device = find_primary_gpu(ec, seat_id);
2605         if (drm_device == NULL) {
2606                 weston_log("no drm device found\n");
2607                 goto err_udev;
2608         }
2609         path = udev_device_get_syspath(drm_device);
2610
2611         if (init_drm(ec, drm_device) < 0) {
2612                 weston_log("failed to initialize kms\n");
2613                 goto err_udev_dev;
2614         }
2615
2616         if (ec->use_pixman) {
2617                 if (init_pixman(ec) < 0) {
2618                         weston_log("failed to initialize pixman renderer\n");
2619                         goto err_udev_dev;
2620                 }
2621         } else {
2622                 if (init_egl(ec) < 0) {
2623                         weston_log("failed to initialize egl\n");
2624                         goto err_udev_dev;
2625                 }
2626         }
2627
2628         ec->base.destroy = drm_destroy;
2629         ec->base.restore = drm_restore;
2630
2631         ec->base.focus = 1;
2632
2633         ec->prev_state = WESTON_COMPOSITOR_ACTIVE;
2634
2635         for (key = KEY_F1; key < KEY_F9; key++)
2636                 weston_compositor_add_key_binding(&ec->base, key,
2637                                                   MODIFIER_CTRL | MODIFIER_ALT,
2638                                                   switch_vt_binding, ec);
2639
2640         wl_list_init(&ec->sprite_list);
2641         create_sprites(ec);
2642
2643         if (create_outputs(ec, connector, drm_device) < 0) {
2644                 weston_log("failed to create output for %s\n", path);
2645                 goto err_sprite;
2646         }
2647
2648         path = NULL;
2649
2650         if (udev_input_init(&ec->input, &ec->base, ec->udev, seat_id) < 0) {
2651                 weston_log("failed to create input devices\n");
2652                 goto err_sprite;
2653         }
2654
2655         loop = wl_display_get_event_loop(ec->base.wl_display);
2656         ec->drm_source =
2657                 wl_event_loop_add_fd(loop, ec->drm.fd,
2658                                      WL_EVENT_READABLE, on_drm_input, ec);
2659
2660         ec->udev_monitor = udev_monitor_new_from_netlink(ec->udev, "udev");
2661         if (ec->udev_monitor == NULL) {
2662                 weston_log("failed to intialize udev monitor\n");
2663                 goto err_drm_source;
2664         }
2665         udev_monitor_filter_add_match_subsystem_devtype(ec->udev_monitor,
2666                                                         "drm", NULL);
2667         ec->udev_drm_source =
2668                 wl_event_loop_add_fd(loop,
2669                                      udev_monitor_get_fd(ec->udev_monitor),
2670                                      WL_EVENT_READABLE, udev_drm_event, ec);
2671
2672         if (udev_monitor_enable_receiving(ec->udev_monitor) < 0) {
2673                 weston_log("failed to enable udev-monitor receiving\n");
2674                 goto err_udev_monitor;
2675         }
2676
2677         udev_device_unref(drm_device);
2678
2679         weston_compositor_add_debug_binding(&ec->base, KEY_O,
2680                                             planes_binding, ec);
2681         weston_compositor_add_debug_binding(&ec->base, KEY_C,
2682                                             planes_binding, ec);
2683         weston_compositor_add_debug_binding(&ec->base, KEY_V,
2684                                             planes_binding, ec);
2685         weston_compositor_add_debug_binding(&ec->base, KEY_Q,
2686                                             recorder_binding, ec);
2687
2688         return &ec->base;
2689
2690 err_udev_monitor:
2691         wl_event_source_remove(ec->udev_drm_source);
2692         udev_monitor_unref(ec->udev_monitor);
2693 err_drm_source:
2694         wl_event_source_remove(ec->drm_source);
2695         udev_input_destroy(&ec->input);
2696 err_sprite:
2697         ec->base.renderer->destroy(&ec->base);
2698         gbm_device_destroy(ec->gbm);
2699         destroy_sprites(ec);
2700 err_udev_dev:
2701         udev_device_unref(drm_device);
2702 err_launcher:
2703         weston_launcher_destroy(ec->base.launcher);
2704 err_udev:
2705         udev_unref(ec->udev);
2706 err_compositor:
2707         weston_compositor_shutdown(&ec->base);
2708 err_base:
2709         free(ec);
2710         return NULL;
2711 }
2712
2713 WL_EXPORT struct weston_compositor *
2714 backend_init(struct wl_display *display, int *argc, char *argv[],
2715              struct weston_config *config)
2716 {
2717         int connector = 0, tty = 0, use_pixman = 0;
2718         const char *seat_id = default_seat;
2719
2720         const struct weston_option drm_options[] = {
2721                 { WESTON_OPTION_INTEGER, "connector", 0, &connector },
2722                 { WESTON_OPTION_STRING, "seat", 0, &seat_id },
2723                 { WESTON_OPTION_INTEGER, "tty", 0, &tty },
2724                 { WESTON_OPTION_BOOLEAN, "current-mode", 0, &option_current_mode },
2725                 { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &use_pixman },
2726         };
2727
2728         parse_options(drm_options, ARRAY_LENGTH(drm_options), argc, argv);
2729
2730         return drm_compositor_create(display, connector, seat_id, tty, use_pixman,
2731                                      argc, argv, config);
2732 }