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