launcher: add logind backend
[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
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                 uint32_t msec;
686
687                 clock_gettime(compositor->clock, &ts);
688                 msec = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
689                 weston_output_finish_frame(output_base, msec);
690                 return;
691         }
692
693         fb_id = output->current->fb_id;
694
695         if (drmModePageFlip(compositor->drm.fd, output->crtc_id, fb_id,
696                             DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {
697                 weston_log("queueing pageflip failed: %m\n");
698                 return;
699         }
700 }
701
702 static void
703 vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec,
704                void *data)
705 {
706         struct drm_sprite *s = (struct drm_sprite *)data;
707         struct drm_output *output = s->output;
708         uint32_t msecs;
709
710         output->vblank_pending = 0;
711
712         drm_output_release_fb(output, s->current);
713         s->current = s->next;
714         s->next = NULL;
715
716         if (!output->page_flip_pending) {
717                 msecs = sec * 1000 + usec / 1000;
718                 weston_output_finish_frame(&output->base, msecs);
719         }
720 }
721
722 static void
723 drm_output_destroy(struct weston_output *output_base);
724
725 static void
726 page_flip_handler(int fd, unsigned int frame,
727                   unsigned int sec, unsigned int usec, void *data)
728 {
729         struct drm_output *output = (struct drm_output *) data;
730         uint32_t msecs;
731
732         /* We don't set page_flip_pending on start_repaint_loop, in that case
733          * we just want to page flip to the current buffer to get an accurate
734          * timestamp */
735         if (output->page_flip_pending) {
736                 drm_output_release_fb(output, output->current);
737                 output->current = output->next;
738                 output->next = NULL;
739         }
740
741         output->page_flip_pending = 0;
742
743         if (output->destroy_pending)
744                 drm_output_destroy(&output->base);
745         else if (!output->vblank_pending) {
746                 msecs = sec * 1000 + usec / 1000;
747                 weston_output_finish_frame(&output->base, msecs);
748
749                 /* We can't call this from frame_notify, because the output's
750                  * repaint needed flag is cleared just after that */
751                 if (output->recorder)
752                         weston_output_schedule_repaint(&output->base);
753         }
754 }
755
756 static uint32_t
757 drm_output_check_sprite_format(struct drm_sprite *s,
758                                struct weston_surface *es, struct gbm_bo *bo)
759 {
760         uint32_t i, format;
761
762         format = gbm_bo_get_format(bo);
763
764         if (format == GBM_FORMAT_ARGB8888) {
765                 pixman_region32_t r;
766
767                 pixman_region32_init_rect(&r, 0, 0,
768                                           es->geometry.width,
769                                           es->geometry.height);
770                 pixman_region32_subtract(&r, &r, &es->opaque);
771
772                 if (!pixman_region32_not_empty(&r))
773                         format = GBM_FORMAT_XRGB8888;
774
775                 pixman_region32_fini(&r);
776         }
777
778         for (i = 0; i < s->count_formats; i++)
779                 if (s->formats[i] == format)
780                         return format;
781
782         return 0;
783 }
784
785 static int
786 drm_surface_transform_supported(struct weston_surface *es)
787 {
788         return !es->transform.enabled ||
789                 (es->transform.matrix.type < WESTON_MATRIX_TRANSFORM_ROTATE);
790 }
791
792 static struct weston_plane *
793 drm_output_prepare_overlay_surface(struct weston_output *output_base,
794                                    struct weston_surface *es)
795 {
796         struct weston_compositor *ec = output_base->compositor;
797         struct drm_compositor *c =(struct drm_compositor *) ec;
798         struct drm_sprite *s;
799         int found = 0;
800         struct gbm_bo *bo;
801         pixman_region32_t dest_rect, src_rect;
802         pixman_box32_t *box, tbox;
803         uint32_t format;
804         wl_fixed_t sx1, sy1, sx2, sy2;
805
806         if (c->gbm == NULL)
807                 return NULL;
808
809         if (es->buffer_transform != output_base->transform)
810                 return NULL;
811
812         if (es->buffer_scale != output_base->current_scale)
813                 return NULL;
814
815         if (c->sprites_are_broken)
816                 return NULL;
817
818         if (es->output_mask != (1u << output_base->id))
819                 return NULL;
820
821         if (es->buffer_ref.buffer == NULL)
822                 return NULL;
823
824         if (es->alpha != 1.0f)
825                 return NULL;
826
827         if (wl_shm_buffer_get(es->buffer_ref.buffer->resource))
828                 return NULL;
829
830         if (!drm_surface_transform_supported(es))
831                 return NULL;
832
833         wl_list_for_each(s, &c->sprite_list, link) {
834                 if (!drm_sprite_crtc_supported(output_base, s->possible_crtcs))
835                         continue;
836
837                 if (!s->next) {
838                         found = 1;
839                         break;
840                 }
841         }
842
843         /* No sprites available */
844         if (!found)
845                 return NULL;
846
847         bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
848                            es->buffer_ref.buffer->resource,
849                            GBM_BO_USE_SCANOUT);
850         if (!bo)
851                 return NULL;
852
853         format = drm_output_check_sprite_format(s, es, bo);
854         if (format == 0) {
855                 gbm_bo_destroy(bo);
856                 return NULL;
857         }
858
859         s->next = drm_fb_get_from_bo(bo, c, format);
860         if (!s->next) {
861                 gbm_bo_destroy(bo);
862                 return NULL;
863         }
864
865         drm_fb_set_buffer(s->next, es->buffer_ref.buffer);
866
867         box = pixman_region32_extents(&es->transform.boundingbox);
868         s->plane.x = box->x1;
869         s->plane.y = box->y1;
870
871         /*
872          * Calculate the source & dest rects properly based on actual
873          * position (note the caller has called weston_surface_update_transform()
874          * for us already).
875          */
876         pixman_region32_init(&dest_rect);
877         pixman_region32_intersect(&dest_rect, &es->transform.boundingbox,
878                                   &output_base->region);
879         pixman_region32_translate(&dest_rect, -output_base->x, -output_base->y);
880         box = pixman_region32_extents(&dest_rect);
881         tbox = weston_transformed_rect(output_base->width,
882                                        output_base->height,
883                                        output_base->transform,
884                                        output_base->current_scale,
885                                        *box);
886         s->dest_x = tbox.x1;
887         s->dest_y = tbox.y1;
888         s->dest_w = tbox.x2 - tbox.x1;
889         s->dest_h = tbox.y2 - tbox.y1;
890         pixman_region32_fini(&dest_rect);
891
892         pixman_region32_init(&src_rect);
893         pixman_region32_intersect(&src_rect, &es->transform.boundingbox,
894                                   &output_base->region);
895         box = pixman_region32_extents(&src_rect);
896
897         weston_surface_from_global_fixed(es,
898                                          wl_fixed_from_int(box->x1),
899                                          wl_fixed_from_int(box->y1),
900                                          &sx1, &sy1);
901         weston_surface_from_global_fixed(es,
902                                          wl_fixed_from_int(box->x2),
903                                          wl_fixed_from_int(box->y2),
904                                          &sx2, &sy2);
905
906         if (sx1 < 0)
907                 sx1 = 0;
908         if (sy1 < 0)
909                 sy1 = 0;
910         if (sx2 > wl_fixed_from_int(es->geometry.width))
911                 sx2 = wl_fixed_from_int(es->geometry.width);
912         if (sy2 > wl_fixed_from_int(es->geometry.height))
913                 sy2 = wl_fixed_from_int(es->geometry.height);
914
915         tbox.x1 = sx1;
916         tbox.y1 = sy1;
917         tbox.x2 = sx2;
918         tbox.y2 = sy2;
919
920         tbox = weston_transformed_rect(wl_fixed_from_int(es->geometry.width),
921                                        wl_fixed_from_int(es->geometry.height),
922                                        es->buffer_transform, es->buffer_scale, tbox);
923
924         s->src_x = tbox.x1 << 8;
925         s->src_y = tbox.y1 << 8;
926         s->src_w = (tbox.x2 - tbox.x1) << 8;
927         s->src_h = (tbox.y2 - tbox.y1) << 8;
928         pixman_region32_fini(&src_rect);
929
930         return &s->plane;
931 }
932
933 static struct weston_plane *
934 drm_output_prepare_cursor_surface(struct weston_output *output_base,
935                                   struct weston_surface *es)
936 {
937         struct drm_compositor *c =
938                 (struct drm_compositor *) output_base->compositor;
939         struct drm_output *output = (struct drm_output *) output_base;
940
941         if (c->gbm == NULL)
942                 return NULL;
943         if (output->base.transform != WL_OUTPUT_TRANSFORM_NORMAL)
944                 return NULL;
945         if (output->cursor_surface)
946                 return NULL;
947         if (es->output_mask != (1u << output_base->id))
948                 return NULL;
949         if (c->cursors_are_broken)
950                 return NULL;
951         if (es->buffer_ref.buffer == NULL ||
952             !wl_shm_buffer_get(es->buffer_ref.buffer->resource) ||
953             es->geometry.width > 64 || es->geometry.height > 64)
954                 return NULL;
955
956         output->cursor_surface = es;
957
958         return &output->cursor_plane;
959 }
960
961 static void
962 drm_output_set_cursor(struct drm_output *output)
963 {
964         struct weston_surface *es = output->cursor_surface;
965         struct drm_compositor *c =
966                 (struct drm_compositor *) output->base.compositor;
967         EGLint handle, stride;
968         struct gbm_bo *bo;
969         uint32_t buf[64 * 64];
970         unsigned char *s;
971         int i, x, y;
972
973         output->cursor_surface = NULL;
974         if (es == NULL) {
975                 drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0);
976                 return;
977         }
978
979         if (es->buffer_ref.buffer &&
980             pixman_region32_not_empty(&output->cursor_plane.damage)) {
981                 pixman_region32_fini(&output->cursor_plane.damage);
982                 pixman_region32_init(&output->cursor_plane.damage);
983                 output->current_cursor ^= 1;
984                 bo = output->cursor_bo[output->current_cursor];
985                 memset(buf, 0, sizeof buf);
986                 stride = wl_shm_buffer_get_stride(es->buffer_ref.buffer->shm_buffer);
987                 s = wl_shm_buffer_get_data(es->buffer_ref.buffer->shm_buffer);
988                 for (i = 0; i < es->geometry.height; i++)
989                         memcpy(buf + i * 64, s + i * stride,
990                                es->geometry.width * 4);
991
992                 if (gbm_bo_write(bo, buf, sizeof buf) < 0)
993                         weston_log("failed update cursor: %m\n");
994
995                 handle = gbm_bo_get_handle(bo).s32;
996                 if (drmModeSetCursor(c->drm.fd,
997                                      output->crtc_id, handle, 64, 64)) {
998                         weston_log("failed to set cursor: %m\n");
999                         c->cursors_are_broken = 1;
1000                 }
1001         }
1002
1003         x = (es->geometry.x - output->base.x) * output->base.current_scale;
1004         y = (es->geometry.y - output->base.y) * output->base.current_scale;
1005         if (output->cursor_plane.x != x || output->cursor_plane.y != y) {
1006                 if (drmModeMoveCursor(c->drm.fd, output->crtc_id, x, y)) {
1007                         weston_log("failed to move cursor: %m\n");
1008                         c->cursors_are_broken = 1;
1009                 }
1010
1011                 output->cursor_plane.x = x;
1012                 output->cursor_plane.y = y;
1013         }
1014 }
1015
1016 static void
1017 drm_assign_planes(struct weston_output *output)
1018 {
1019         struct drm_compositor *c =
1020                 (struct drm_compositor *) output->compositor;
1021         struct weston_surface *es, *next;
1022         pixman_region32_t overlap, surface_overlap;
1023         struct weston_plane *primary, *next_plane;
1024
1025         /*
1026          * Find a surface for each sprite in the output using some heuristics:
1027          * 1) size
1028          * 2) frequency of update
1029          * 3) opacity (though some hw might support alpha blending)
1030          * 4) clipping (this can be fixed with color keys)
1031          *
1032          * The idea is to save on blitting since this should save power.
1033          * If we can get a large video surface on the sprite for example,
1034          * the main display surface may not need to update at all, and
1035          * the client buffer can be used directly for the sprite surface
1036          * as we do for flipping full screen surfaces.
1037          */
1038         pixman_region32_init(&overlap);
1039         primary = &c->base.primary_plane;
1040         wl_list_for_each_safe(es, next, &c->base.surface_list, link) {
1041                 /* test whether this buffer can ever go into a plane:
1042                  * non-shm, or small enough to be a cursor
1043                  */
1044                 if ((es->buffer_ref.buffer &&
1045                      !wl_shm_buffer_get(es->buffer_ref.buffer->resource)) ||
1046                     (es->geometry.width <= 64 && es->geometry.height <= 64))
1047                         es->keep_buffer = 1;
1048                 else
1049                         es->keep_buffer = 0;
1050
1051                 pixman_region32_init(&surface_overlap);
1052                 pixman_region32_intersect(&surface_overlap, &overlap,
1053                                           &es->transform.boundingbox);
1054
1055                 next_plane = NULL;
1056                 if (pixman_region32_not_empty(&surface_overlap))
1057                         next_plane = primary;
1058                 if (next_plane == NULL)
1059                         next_plane = drm_output_prepare_cursor_surface(output, es);
1060                 if (next_plane == NULL)
1061                         next_plane = drm_output_prepare_scanout_surface(output, es);
1062                 if (next_plane == NULL)
1063                         next_plane = drm_output_prepare_overlay_surface(output, es);
1064                 if (next_plane == NULL)
1065                         next_plane = primary;
1066                 weston_surface_move_to_plane(es, next_plane);
1067                 if (next_plane == primary)
1068                         pixman_region32_union(&overlap, &overlap,
1069                                               &es->transform.boundingbox);
1070
1071                 pixman_region32_fini(&surface_overlap);
1072         }
1073         pixman_region32_fini(&overlap);
1074 }
1075
1076 static void
1077 drm_output_fini_pixman(struct drm_output *output);
1078
1079 static void
1080 drm_output_destroy(struct weston_output *output_base)
1081 {
1082         struct drm_output *output = (struct drm_output *) output_base;
1083         struct drm_compositor *c =
1084                 (struct drm_compositor *) output->base.compositor;
1085         drmModeCrtcPtr origcrtc = output->original_crtc;
1086
1087         if (output->page_flip_pending) {
1088                 output->destroy_pending = 1;
1089                 weston_log("destroy output while page flip pending\n");
1090                 return;
1091         }
1092
1093         if (output->backlight)
1094                 backlight_destroy(output->backlight);
1095
1096         drmModeFreeProperty(output->dpms_prop);
1097
1098         /* Turn off hardware cursor */
1099         drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0);
1100
1101         /* Restore original CRTC state */
1102         drmModeSetCrtc(c->drm.fd, origcrtc->crtc_id, origcrtc->buffer_id,
1103                        origcrtc->x, origcrtc->y,
1104                        &output->connector_id, 1, &origcrtc->mode);
1105         drmModeFreeCrtc(origcrtc);
1106
1107         c->crtc_allocator &= ~(1 << output->crtc_id);
1108         c->connector_allocator &= ~(1 << output->connector_id);
1109
1110         if (c->use_pixman) {
1111                 drm_output_fini_pixman(output);
1112         } else {
1113                 gl_renderer->output_destroy(output_base);
1114                 gbm_surface_destroy(output->surface);
1115         }
1116
1117         weston_plane_release(&output->fb_plane);
1118         weston_plane_release(&output->cursor_plane);
1119
1120         weston_output_destroy(&output->base);
1121         wl_list_remove(&output->base.link);
1122
1123         free(output);
1124 }
1125
1126 static struct drm_mode *
1127 choose_mode (struct drm_output *output, struct weston_mode *target_mode)
1128 {
1129         struct drm_mode *tmp_mode = NULL, *mode;
1130
1131         if (output->base.current_mode->width == target_mode->width &&
1132             output->base.current_mode->height == target_mode->height &&
1133             (output->base.current_mode->refresh == target_mode->refresh ||
1134              target_mode->refresh == 0))
1135                 return (struct drm_mode *)output->base.current_mode;
1136
1137         wl_list_for_each(mode, &output->base.mode_list, base.link) {
1138                 if (mode->mode_info.hdisplay == target_mode->width &&
1139                     mode->mode_info.vdisplay == target_mode->height) {
1140                         if (mode->mode_info.vrefresh == target_mode->refresh || 
1141                             target_mode->refresh == 0) {
1142                                 return mode;
1143                         } else if (!tmp_mode) 
1144                                 tmp_mode = mode;
1145                 }
1146         }
1147
1148         return tmp_mode;
1149 }
1150
1151 static int
1152 drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec);
1153 static int
1154 drm_output_init_pixman(struct drm_output *output, struct drm_compositor *c);
1155
1156 static int
1157 drm_output_switch_mode(struct weston_output *output_base, struct weston_mode *mode)
1158 {
1159         struct drm_output *output;
1160         struct drm_mode *drm_mode;
1161         struct drm_compositor *ec;
1162
1163         if (output_base == NULL) {
1164                 weston_log("output is NULL.\n");
1165                 return -1;
1166         }
1167
1168         if (mode == NULL) {
1169                 weston_log("mode is NULL.\n");
1170                 return -1;
1171         }
1172
1173         ec = (struct drm_compositor *)output_base->compositor;
1174         output = (struct drm_output *)output_base;
1175         drm_mode  = choose_mode (output, mode);
1176
1177         if (!drm_mode) {
1178                 weston_log("%s, invalid resolution:%dx%d\n", __func__, mode->width, mode->height);
1179                 return -1;
1180         }
1181
1182         if (&drm_mode->base == output->base.current_mode)
1183                 return 0;
1184
1185         output->base.current_mode->flags = 0;
1186
1187         output->base.current_mode = &drm_mode->base;
1188         output->base.current_mode->flags =
1189                 WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
1190
1191         /* reset rendering stuff. */
1192         drm_output_release_fb(output, output->current);
1193         drm_output_release_fb(output, output->next);
1194         output->current = output->next = NULL;
1195
1196         if (ec->use_pixman) {
1197                 drm_output_fini_pixman(output);
1198                 if (drm_output_init_pixman(output, ec) < 0) {
1199                         weston_log("failed to init output pixman state with "
1200                                    "new mode\n");
1201                         return -1;
1202                 }
1203         } else {
1204                 gl_renderer->output_destroy(&output->base);
1205                 gbm_surface_destroy(output->surface);
1206
1207                 if (drm_output_init_egl(output, ec) < 0) {
1208                         weston_log("failed to init output egl state with "
1209                                    "new mode");
1210                         return -1;
1211                 }
1212         }
1213
1214         return 0;
1215 }
1216
1217 static int
1218 on_drm_input(int fd, uint32_t mask, void *data)
1219 {
1220         drmEventContext evctx;
1221
1222         memset(&evctx, 0, sizeof evctx);
1223         evctx.version = DRM_EVENT_CONTEXT_VERSION;
1224         evctx.page_flip_handler = page_flip_handler;
1225         evctx.vblank_handler = vblank_handler;
1226         drmHandleEvent(fd, &evctx);
1227
1228         return 1;
1229 }
1230
1231 static int
1232 init_drm(struct drm_compositor *ec, struct udev_device *device)
1233 {
1234         const char *filename, *sysnum;
1235         uint64_t cap;
1236         int fd, ret;
1237
1238         sysnum = udev_device_get_sysnum(device);
1239         if (sysnum)
1240                 ec->drm.id = atoi(sysnum);
1241         if (!sysnum || ec->drm.id < 0) {
1242                 weston_log("cannot get device sysnum\n");
1243                 return -1;
1244         }
1245
1246         filename = udev_device_get_devnode(device);
1247         fd = weston_launcher_open(ec->base.launcher, filename, O_RDWR);
1248         if (fd < 0) {
1249                 /* Probably permissions error */
1250                 weston_log("couldn't open %s, skipping\n",
1251                         udev_device_get_devnode(device));
1252                 return -1;
1253         }
1254
1255         weston_log("using %s\n", filename);
1256
1257         ec->drm.fd = fd;
1258         ec->drm.filename = strdup(filename);
1259
1260         ret = drmGetCap(fd, DRM_CAP_TIMESTAMP_MONOTONIC, &cap);
1261         if (ret == 0 && cap == 1)
1262                 ec->clock = CLOCK_MONOTONIC;
1263         else
1264                 ec->clock = CLOCK_REALTIME;
1265
1266         return 0;
1267 }
1268
1269 static int
1270 init_egl(struct drm_compositor *ec)
1271 {
1272         EGLint format;
1273
1274         gl_renderer = weston_load_module("gl-renderer.so",
1275                                          "gl_renderer_interface");
1276         if (!gl_renderer)
1277                 return -1;
1278
1279         /* GBM will load a dri driver, but even though they need symbols from
1280          * libglapi, in some version of Mesa they are not linked to it. Since
1281          * only the gl-renderer module links to it, the call above won't make
1282          * these symbols globally available, and loading the DRI driver fails.
1283          * Workaround this by dlopen()'ing libglapi with RTLD_GLOBAL. */
1284         dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL);
1285
1286         ec->gbm = gbm_create_device(ec->drm.fd);
1287
1288         if (!ec->gbm)
1289                 return -1;
1290
1291         format = ec->format;
1292         if (gl_renderer->create(&ec->base, ec->gbm,
1293                                gl_renderer->opaque_attribs, &format) < 0) {
1294                 gbm_device_destroy(ec->gbm);
1295                 return -1;
1296         }
1297
1298         return 0;
1299 }
1300
1301 static int
1302 init_pixman(struct drm_compositor *ec)
1303 {
1304         return pixman_renderer_init(&ec->base);
1305 }
1306
1307 static struct drm_mode *
1308 drm_output_add_mode(struct drm_output *output, drmModeModeInfo *info)
1309 {
1310         struct drm_mode *mode;
1311         uint64_t refresh;
1312
1313         mode = malloc(sizeof *mode);
1314         if (mode == NULL)
1315                 return NULL;
1316
1317         mode->base.flags = 0;
1318         mode->base.width = info->hdisplay;
1319         mode->base.height = info->vdisplay;
1320
1321         /* Calculate higher precision (mHz) refresh rate */
1322         refresh = (info->clock * 1000000LL / info->htotal +
1323                    info->vtotal / 2) / info->vtotal;
1324
1325         if (info->flags & DRM_MODE_FLAG_INTERLACE)
1326                 refresh *= 2;
1327         if (info->flags & DRM_MODE_FLAG_DBLSCAN)
1328                 refresh /= 2;
1329         if (info->vscan > 1)
1330             refresh /= info->vscan;
1331
1332         mode->base.refresh = refresh;
1333         mode->mode_info = *info;
1334
1335         if (info->type & DRM_MODE_TYPE_PREFERRED)
1336                 mode->base.flags |= WL_OUTPUT_MODE_PREFERRED;
1337
1338         wl_list_insert(output->base.mode_list.prev, &mode->base.link);
1339
1340         return mode;
1341 }
1342
1343 static int
1344 drm_subpixel_to_wayland(int drm_value)
1345 {
1346         switch (drm_value) {
1347         default:
1348         case DRM_MODE_SUBPIXEL_UNKNOWN:
1349                 return WL_OUTPUT_SUBPIXEL_UNKNOWN;
1350         case DRM_MODE_SUBPIXEL_NONE:
1351                 return WL_OUTPUT_SUBPIXEL_NONE;
1352         case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB:
1353                 return WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB;
1354         case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR:
1355                 return WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR;
1356         case DRM_MODE_SUBPIXEL_VERTICAL_RGB:
1357                 return WL_OUTPUT_SUBPIXEL_VERTICAL_RGB;
1358         case DRM_MODE_SUBPIXEL_VERTICAL_BGR:
1359                 return WL_OUTPUT_SUBPIXEL_VERTICAL_BGR;
1360         }
1361 }
1362
1363 /* returns a value between 0-255 range, where higher is brighter */
1364 static uint32_t
1365 drm_get_backlight(struct drm_output *output)
1366 {
1367         long brightness, max_brightness, norm;
1368
1369         brightness = backlight_get_brightness(output->backlight);
1370         max_brightness = backlight_get_max_brightness(output->backlight);
1371
1372         /* convert it on a scale of 0 to 255 */
1373         norm = (brightness * 255)/(max_brightness);
1374
1375         return (uint32_t) norm;
1376 }
1377
1378 /* values accepted are between 0-255 range */
1379 static void
1380 drm_set_backlight(struct weston_output *output_base, uint32_t value)
1381 {
1382         struct drm_output *output = (struct drm_output *) output_base;
1383         long max_brightness, new_brightness;
1384
1385         if (!output->backlight)
1386                 return;
1387
1388         if (value > 255)
1389                 return;
1390
1391         max_brightness = backlight_get_max_brightness(output->backlight);
1392
1393         /* get denormalized value */
1394         new_brightness = (value * max_brightness) / 255;
1395
1396         backlight_set_brightness(output->backlight, new_brightness);
1397 }
1398
1399 static drmModePropertyPtr
1400 drm_get_prop(int fd, drmModeConnectorPtr connector, const char *name)
1401 {
1402         drmModePropertyPtr props;
1403         int i;
1404
1405         for (i = 0; i < connector->count_props; i++) {
1406                 props = drmModeGetProperty(fd, connector->props[i]);
1407                 if (!props)
1408                         continue;
1409
1410                 if (!strcmp(props->name, name))
1411                         return props;
1412
1413                 drmModeFreeProperty(props);
1414         }
1415
1416         return NULL;
1417 }
1418
1419 static void
1420 drm_set_dpms(struct weston_output *output_base, enum dpms_enum level)
1421 {
1422         struct drm_output *output = (struct drm_output *) output_base;
1423         struct weston_compositor *ec = output_base->compositor;
1424         struct drm_compositor *c = (struct drm_compositor *) ec;
1425
1426         if (!output->dpms_prop)
1427                 return;
1428
1429         drmModeConnectorSetProperty(c->drm.fd, output->connector_id,
1430                                     output->dpms_prop->prop_id, level);
1431 }
1432
1433 static const char *connector_type_names[] = {
1434         "None",
1435         "VGA",
1436         "DVI",
1437         "DVI",
1438         "DVI",
1439         "Composite",
1440         "TV",
1441         "LVDS",
1442         "CTV",
1443         "DIN",
1444         "DP",
1445         "HDMI",
1446         "HDMI",
1447         "TV",
1448         "eDP",
1449 };
1450
1451 static int
1452 find_crtc_for_connector(struct drm_compositor *ec,
1453                         drmModeRes *resources, drmModeConnector *connector)
1454 {
1455         drmModeEncoder *encoder;
1456         uint32_t possible_crtcs;
1457         int i, j;
1458
1459         for (j = 0; j < connector->count_encoders; j++) {
1460                 encoder = drmModeGetEncoder(ec->drm.fd, connector->encoders[j]);
1461                 if (encoder == NULL) {
1462                         weston_log("Failed to get encoder.\n");
1463                         return -1;
1464                 }
1465                 possible_crtcs = encoder->possible_crtcs;
1466                 drmModeFreeEncoder(encoder);
1467
1468                 for (i = 0; i < resources->count_crtcs; i++) {
1469                         if (possible_crtcs & (1 << i) &&
1470                             !(ec->crtc_allocator & (1 << resources->crtcs[i])))
1471                                 return i;
1472                 }
1473         }
1474
1475         return -1;
1476 }
1477
1478 /* Init output state that depends on gl or gbm */
1479 static int
1480 drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec)
1481 {
1482         int i, flags;
1483
1484         output->surface = gbm_surface_create(ec->gbm,
1485                                              output->base.current_mode->width,
1486                                              output->base.current_mode->height,
1487                                              ec->format,
1488                                              GBM_BO_USE_SCANOUT |
1489                                              GBM_BO_USE_RENDERING);
1490         if (!output->surface) {
1491                 weston_log("failed to create gbm surface\n");
1492                 return -1;
1493         }
1494
1495         if (gl_renderer->output_create(&output->base, output->surface) < 0) {
1496                 weston_log("failed to create gl renderer output state\n");
1497                 gbm_surface_destroy(output->surface);
1498                 return -1;
1499         }
1500
1501         flags = GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE;
1502
1503         for (i = 0; i < 2; i++) {
1504                 if (output->cursor_bo[i])
1505                         continue;
1506
1507                 output->cursor_bo[i] =
1508                         gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888,
1509                                       flags);
1510         }
1511
1512         if (output->cursor_bo[0] == NULL || output->cursor_bo[1] == NULL) {
1513                 weston_log("cursor buffers unavailable, using gl cursors\n");
1514                 ec->cursors_are_broken = 1;
1515         }
1516
1517         return 0;
1518 }
1519
1520 static int
1521 drm_output_init_pixman(struct drm_output *output, struct drm_compositor *c)
1522 {
1523         int w = output->base.current_mode->width;
1524         int h = output->base.current_mode->height;
1525         unsigned int i;
1526
1527         /* FIXME error checking */
1528
1529         for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
1530                 output->dumb[i] = drm_fb_create_dumb(c, w, h);
1531                 if (!output->dumb[i])
1532                         goto err;
1533
1534                 output->image[i] =
1535                         pixman_image_create_bits(PIXMAN_x8r8g8b8, w, h,
1536                                                  output->dumb[i]->map,
1537                                                  output->dumb[i]->stride);
1538                 if (!output->image[i])
1539                         goto err;
1540         }
1541
1542         if (pixman_renderer_output_create(&output->base) < 0)
1543                 goto err;
1544
1545         pixman_region32_init_rect(&output->previous_damage,
1546                                   output->base.x, output->base.y, output->base.width, output->base.height);
1547
1548         return 0;
1549
1550 err:
1551         for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
1552                 if (output->dumb[i])
1553                         drm_fb_destroy_dumb(output->dumb[i]);
1554                 if (output->image[i])
1555                         pixman_image_unref(output->image[i]);
1556
1557                 output->dumb[i] = NULL;
1558                 output->image[i] = NULL;
1559         }
1560
1561         return -1;
1562 }
1563
1564 static void
1565 drm_output_fini_pixman(struct drm_output *output)
1566 {
1567         unsigned int i;
1568
1569         pixman_renderer_output_destroy(&output->base);
1570         pixman_region32_fini(&output->previous_damage);
1571
1572         for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
1573                 drm_fb_destroy_dumb(output->dumb[i]);
1574                 pixman_image_unref(output->image[i]);
1575                 output->dumb[i] = NULL;
1576                 output->image[i] = NULL;
1577         }
1578 }
1579
1580 static void
1581 edid_parse_string(const uint8_t *data, char text[])
1582 {
1583         int i;
1584         int replaced = 0;
1585
1586         /* this is always 12 bytes, but we can't guarantee it's null
1587          * terminated or not junk. */
1588         strncpy(text, (const char *) data, 12);
1589
1590         /* remove insane chars */
1591         for (i = 0; text[i] != '\0'; i++) {
1592                 if (text[i] == '\n' ||
1593                     text[i] == '\r') {
1594                         text[i] = '\0';
1595                         break;
1596                 }
1597         }
1598
1599         /* ensure string is printable */
1600         for (i = 0; text[i] != '\0'; i++) {
1601                 if (!isprint(text[i])) {
1602                         text[i] = '-';
1603                         replaced++;
1604                 }
1605         }
1606
1607         /* if the string is random junk, ignore the string */
1608         if (replaced > 4)
1609                 text[0] = '\0';
1610 }
1611
1612 #define EDID_DESCRIPTOR_ALPHANUMERIC_DATA_STRING        0xfe
1613 #define EDID_DESCRIPTOR_DISPLAY_PRODUCT_NAME            0xfc
1614 #define EDID_DESCRIPTOR_DISPLAY_PRODUCT_SERIAL_NUMBER   0xff
1615 #define EDID_OFFSET_DATA_BLOCKS                         0x36
1616 #define EDID_OFFSET_LAST_BLOCK                          0x6c
1617 #define EDID_OFFSET_PNPID                               0x08
1618 #define EDID_OFFSET_SERIAL                              0x0c
1619
1620 static int
1621 edid_parse(struct drm_edid *edid, const uint8_t *data, size_t length)
1622 {
1623         int i;
1624         uint32_t serial_number;
1625
1626         /* check header */
1627         if (length < 128)
1628                 return -1;
1629         if (data[0] != 0x00 || data[1] != 0xff)
1630                 return -1;
1631
1632         /* decode the PNP ID from three 5 bit words packed into 2 bytes
1633          * /--08--\/--09--\
1634          * 7654321076543210
1635          * |\---/\---/\---/
1636          * R  C1   C2   C3 */
1637         edid->pnp_id[0] = 'A' + ((data[EDID_OFFSET_PNPID + 0] & 0x7c) / 4) - 1;
1638         edid->pnp_id[1] = 'A' + ((data[EDID_OFFSET_PNPID + 0] & 0x3) * 8) + ((data[EDID_OFFSET_PNPID + 1] & 0xe0) / 32) - 1;
1639         edid->pnp_id[2] = 'A' + (data[EDID_OFFSET_PNPID + 1] & 0x1f) - 1;
1640         edid->pnp_id[3] = '\0';
1641
1642         /* maybe there isn't a ASCII serial number descriptor, so use this instead */
1643         serial_number = (uint32_t) data[EDID_OFFSET_SERIAL + 0];
1644         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 1] * 0x100;
1645         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 2] * 0x10000;
1646         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 3] * 0x1000000;
1647         if (serial_number > 0)
1648                 sprintf(edid->serial_number, "%lu", (unsigned long) serial_number);
1649
1650         /* parse EDID data */
1651         for (i = EDID_OFFSET_DATA_BLOCKS;
1652              i <= EDID_OFFSET_LAST_BLOCK;
1653              i += 18) {
1654                 /* ignore pixel clock data */
1655                 if (data[i] != 0)
1656                         continue;
1657                 if (data[i+2] != 0)
1658                         continue;
1659
1660                 /* any useful blocks? */
1661                 if (data[i+3] == EDID_DESCRIPTOR_DISPLAY_PRODUCT_NAME) {
1662                         edid_parse_string(&data[i+5],
1663                                           edid->monitor_name);
1664                 } else if (data[i+3] == EDID_DESCRIPTOR_DISPLAY_PRODUCT_SERIAL_NUMBER) {
1665                         edid_parse_string(&data[i+5],
1666                                           edid->serial_number);
1667                 } else if (data[i+3] == EDID_DESCRIPTOR_ALPHANUMERIC_DATA_STRING) {
1668                         edid_parse_string(&data[i+5],
1669                                           edid->eisa_id);
1670                 }
1671         }
1672         return 0;
1673 }
1674
1675 static void
1676 find_and_parse_output_edid(struct drm_compositor *ec,
1677                            struct drm_output *output,
1678                            drmModeConnector *connector)
1679 {
1680         drmModePropertyBlobPtr edid_blob = NULL;
1681         drmModePropertyPtr property;
1682         int i;
1683         int rc;
1684
1685         for (i = 0; i < connector->count_props && !edid_blob; i++) {
1686                 property = drmModeGetProperty(ec->drm.fd, connector->props[i]);
1687                 if (!property)
1688                         continue;
1689                 if ((property->flags & DRM_MODE_PROP_BLOB) &&
1690                     !strcmp(property->name, "EDID")) {
1691                         edid_blob = drmModeGetPropertyBlob(ec->drm.fd,
1692                                                            connector->prop_values[i]);
1693                 }
1694                 drmModeFreeProperty(property);
1695         }
1696         if (!edid_blob)
1697                 return;
1698
1699         rc = edid_parse(&output->edid,
1700                         edid_blob->data,
1701                         edid_blob->length);
1702         if (!rc) {
1703                 weston_log("EDID data '%s', '%s', '%s'\n",
1704                            output->edid.pnp_id,
1705                            output->edid.monitor_name,
1706                            output->edid.serial_number);
1707                 if (output->edid.pnp_id[0] != '\0')
1708                         output->base.make = output->edid.pnp_id;
1709                 if (output->edid.monitor_name[0] != '\0')
1710                         output->base.model = output->edid.monitor_name;
1711                 if (output->edid.serial_number[0] != '\0')
1712                         output->base.serial_number = output->edid.serial_number;
1713         }
1714         drmModeFreePropertyBlob(edid_blob);
1715 }
1716
1717
1718
1719 static int
1720 parse_modeline(const char *s, drmModeModeInfo *mode)
1721 {
1722         char hsync[16];
1723         char vsync[16];
1724         float fclock;
1725
1726         mode->type = DRM_MODE_TYPE_USERDEF;
1727         mode->hskew = 0;
1728         mode->vscan = 0;
1729         mode->vrefresh = 0;
1730         mode->flags = 0;
1731
1732         if (sscanf(s, "%f %hd %hd %hd %hd %hd %hd %hd %hd %15s %15s",
1733                    &fclock,
1734                    &mode->hdisplay,
1735                    &mode->hsync_start,
1736                    &mode->hsync_end,
1737                    &mode->htotal,
1738                    &mode->vdisplay,
1739                    &mode->vsync_start,
1740                    &mode->vsync_end,
1741                    &mode->vtotal, hsync, vsync) != 11)
1742                 return -1;
1743
1744         mode->clock = fclock * 1000;
1745         if (strcmp(hsync, "+hsync") == 0)
1746                 mode->flags |= DRM_MODE_FLAG_PHSYNC;
1747         else if (strcmp(hsync, "-hsync") == 0)
1748                 mode->flags |= DRM_MODE_FLAG_NHSYNC;
1749         else
1750                 return -1;
1751
1752         if (strcmp(vsync, "+vsync") == 0)
1753                 mode->flags |= DRM_MODE_FLAG_PVSYNC;
1754         else if (strcmp(vsync, "-vsync") == 0)
1755                 mode->flags |= DRM_MODE_FLAG_NVSYNC;
1756         else
1757                 return -1;
1758
1759         return 0;
1760 }
1761
1762 static uint32_t
1763 parse_transform(const char *transform, const char *output_name)
1764 {
1765         static const struct { const char *name; uint32_t token; } names[] = {
1766                 { "normal",     WL_OUTPUT_TRANSFORM_NORMAL },
1767                 { "90",         WL_OUTPUT_TRANSFORM_90 },
1768                 { "180",        WL_OUTPUT_TRANSFORM_180 },
1769                 { "270",        WL_OUTPUT_TRANSFORM_270 },
1770                 { "flipped",    WL_OUTPUT_TRANSFORM_FLIPPED },
1771                 { "flipped-90", WL_OUTPUT_TRANSFORM_FLIPPED_90 },
1772                 { "flipped-180", WL_OUTPUT_TRANSFORM_FLIPPED_180 },
1773                 { "flipped-270", WL_OUTPUT_TRANSFORM_FLIPPED_270 },
1774         };
1775         unsigned int i;
1776
1777         for (i = 0; i < ARRAY_LENGTH(names); i++)
1778                 if (strcmp(names[i].name, transform) == 0)
1779                         return names[i].token;
1780
1781         weston_log("Invalid transform \"%s\" for output %s\n",
1782                    transform, output_name);
1783
1784         return WL_OUTPUT_TRANSFORM_NORMAL;
1785 }
1786
1787 static void
1788 setup_output_seat_constraint(struct drm_compositor *ec,
1789                              struct weston_output *output,
1790                              const char *s)
1791 {
1792         if (strcmp(s, "") != 0) {
1793                 struct udev_seat *seat;
1794
1795                 seat = udev_seat_get_named(&ec->base, s);
1796                 if (seat)
1797                         seat->base.output = output;
1798
1799                 if (seat && seat->base.pointer)
1800                         weston_pointer_clamp(seat->base.pointer,
1801                                              &seat->base.pointer->x,
1802                                              &seat->base.pointer->y);
1803         }
1804 }
1805
1806 static int
1807 create_output_for_connector(struct drm_compositor *ec,
1808                             drmModeRes *resources,
1809                             drmModeConnector *connector,
1810                             int x, int y, struct udev_device *drm_device)
1811 {
1812         struct drm_output *output;
1813         struct drm_mode *drm_mode, *next, *preferred, *current, *configured;
1814         struct weston_mode *m;
1815         struct weston_config_section *section;
1816         drmModeEncoder *encoder;
1817         drmModeModeInfo crtc_mode, modeline;
1818         drmModeCrtc *crtc;
1819         int i, width, height, scale;
1820         char name[32], *s;
1821         const char *type_name;
1822         enum output_config config;
1823         uint32_t transform;
1824
1825         i = find_crtc_for_connector(ec, resources, connector);
1826         if (i < 0) {
1827                 weston_log("No usable crtc/encoder pair for connector.\n");
1828                 return -1;
1829         }
1830
1831         output = zalloc(sizeof *output);
1832         if (output == NULL)
1833                 return -1;
1834
1835         output->base.subpixel = drm_subpixel_to_wayland(connector->subpixel);
1836         output->base.make = "unknown";
1837         output->base.model = "unknown";
1838         output->base.serial_number = "unknown";
1839         wl_list_init(&output->base.mode_list);
1840
1841         if (connector->connector_type < ARRAY_LENGTH(connector_type_names))
1842                 type_name = connector_type_names[connector->connector_type];
1843         else
1844                 type_name = "UNKNOWN";
1845         snprintf(name, 32, "%s%d", type_name, connector->connector_type_id);
1846         output->base.name = strdup(name);
1847
1848         section = weston_config_get_section(ec->base.config, "output", "name",
1849                                             output->base.name);
1850         weston_config_section_get_string(section, "mode", &s, "preferred");
1851         if (strcmp(s, "off") == 0)
1852                 config = OUTPUT_CONFIG_OFF;
1853         else if (strcmp(s, "preferred") == 0)
1854                 config = OUTPUT_CONFIG_PREFERRED;
1855         else if (strcmp(s, "current") == 0)
1856                 config = OUTPUT_CONFIG_CURRENT;
1857         else if (sscanf(s, "%dx%d", &width, &height) == 2)
1858                 config = OUTPUT_CONFIG_MODE;
1859         else if (parse_modeline(s, &modeline) == 0)
1860                 config = OUTPUT_CONFIG_MODELINE;
1861         else {
1862                 weston_log("Invalid mode \"%s\" for output %s\n",
1863                            s, output->base.name);
1864                 config = OUTPUT_CONFIG_PREFERRED;
1865         }
1866         free(s);
1867
1868         weston_config_section_get_int(section, "scale", &scale, 1);
1869         weston_config_section_get_string(section, "transform", &s, "normal");
1870         transform = parse_transform(s, output->base.name);
1871         free(s);
1872
1873         weston_config_section_get_string(section, "seat", &s, "");
1874         setup_output_seat_constraint(ec, &output->base, s);
1875         free(s);
1876
1877         output->crtc_id = resources->crtcs[i];
1878         output->pipe = i;
1879         ec->crtc_allocator |= (1 << output->crtc_id);
1880         output->connector_id = connector->connector_id;
1881         ec->connector_allocator |= (1 << output->connector_id);
1882
1883         output->original_crtc = drmModeGetCrtc(ec->drm.fd, output->crtc_id);
1884         output->dpms_prop = drm_get_prop(ec->drm.fd, connector, "DPMS");
1885
1886         /* Get the current mode on the crtc that's currently driving
1887          * this connector. */
1888         encoder = drmModeGetEncoder(ec->drm.fd, connector->encoder_id);
1889         memset(&crtc_mode, 0, sizeof crtc_mode);
1890         if (encoder != NULL) {
1891                 crtc = drmModeGetCrtc(ec->drm.fd, encoder->crtc_id);
1892                 drmModeFreeEncoder(encoder);
1893                 if (crtc == NULL)
1894                         goto err_free;
1895                 if (crtc->mode_valid)
1896                         crtc_mode = crtc->mode;
1897                 drmModeFreeCrtc(crtc);
1898         }
1899
1900         for (i = 0; i < connector->count_modes; i++) {
1901                 drm_mode = drm_output_add_mode(output, &connector->modes[i]);
1902                 if (!drm_mode)
1903                         goto err_free;
1904         }
1905
1906         if (config == OUTPUT_CONFIG_OFF) {
1907                 weston_log("Disabling output %s\n", output->base.name);
1908                 drmModeSetCrtc(ec->drm.fd, output->crtc_id,
1909                                0, 0, 0, 0, 0, NULL);
1910                 goto err_free;
1911         }
1912
1913         preferred = NULL;
1914         current = NULL;
1915         configured = NULL;
1916
1917         wl_list_for_each_reverse(drm_mode, &output->base.mode_list, base.link) {
1918                 if (config == OUTPUT_CONFIG_MODE &&
1919                     width == drm_mode->base.width &&
1920                     height == drm_mode->base.height)
1921                         configured = drm_mode;
1922                 if (!memcmp(&crtc_mode, &drm_mode->mode_info, sizeof crtc_mode))
1923                         current = drm_mode;
1924                 if (drm_mode->base.flags & WL_OUTPUT_MODE_PREFERRED)
1925                         preferred = drm_mode;
1926         }
1927
1928         if (config == OUTPUT_CONFIG_MODELINE) {
1929                 configured = drm_output_add_mode(output, &modeline);
1930                 if (!configured)
1931                         goto err_free;
1932         }
1933
1934         if (current == NULL && crtc_mode.clock != 0) {
1935                 current = drm_output_add_mode(output, &crtc_mode);
1936                 if (!current)
1937                         goto err_free;
1938         }
1939
1940         if (config == OUTPUT_CONFIG_CURRENT)
1941                 configured = current;
1942
1943         if (option_current_mode && current)
1944                 output->base.current_mode = &current->base;
1945         else if (configured)
1946                 output->base.current_mode = &configured->base;
1947         else if (preferred)
1948                 output->base.current_mode = &preferred->base;
1949         else if (current)
1950                 output->base.current_mode = &current->base;
1951
1952         if (output->base.current_mode == NULL) {
1953                 weston_log("no available modes for %s\n", output->base.name);
1954                 goto err_free;
1955         }
1956
1957         output->base.current_mode->flags |= WL_OUTPUT_MODE_CURRENT;
1958
1959         weston_output_init(&output->base, &ec->base, x, y,
1960                            connector->mmWidth, connector->mmHeight,
1961                            transform, scale);
1962
1963         if (ec->use_pixman) {
1964                 if (drm_output_init_pixman(output, ec) < 0) {
1965                         weston_log("Failed to init output pixman state\n");
1966                         goto err_output;
1967                 }
1968         } else if (drm_output_init_egl(output, ec) < 0) {
1969                 weston_log("Failed to init output gl state\n");
1970                 goto err_output;
1971         }
1972
1973         output->backlight = backlight_init(drm_device,
1974                                            connector->connector_type);
1975         if (output->backlight) {
1976                 weston_log("Initialized backlight, device %s\n",
1977                            output->backlight->path);
1978                 output->base.set_backlight = drm_set_backlight;
1979                 output->base.backlight_current = drm_get_backlight(output);
1980         } else {
1981                 weston_log("Failed to initialize backlight\n");
1982         }
1983
1984         wl_list_insert(ec->base.output_list.prev, &output->base.link);
1985
1986         find_and_parse_output_edid(ec, output, connector);
1987         if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
1988                 output->base.connection_internal = 1;
1989
1990         output->base.start_repaint_loop = drm_output_start_repaint_loop;
1991         output->base.repaint = drm_output_repaint;
1992         output->base.destroy = drm_output_destroy;
1993         output->base.assign_planes = drm_assign_planes;
1994         output->base.set_dpms = drm_set_dpms;
1995         output->base.switch_mode = drm_output_switch_mode;
1996
1997         output->base.gamma_size = output->original_crtc->gamma_size;
1998         output->base.set_gamma = drm_output_set_gamma;
1999
2000         weston_plane_init(&output->cursor_plane, 0, 0);
2001         weston_plane_init(&output->fb_plane, 0, 0);
2002
2003         weston_compositor_stack_plane(&ec->base, &output->cursor_plane, NULL);
2004         weston_compositor_stack_plane(&ec->base, &output->fb_plane,
2005                                       &ec->base.primary_plane);
2006
2007         weston_log("Output %s, (connector %d, crtc %d)\n",
2008                    output->base.name, output->connector_id, output->crtc_id);
2009         wl_list_for_each(m, &output->base.mode_list, link)
2010                 weston_log_continue("  mode %dx%d@%.1f%s%s%s\n",
2011                                     m->width, m->height, m->refresh / 1000.0,
2012                                     m->flags & WL_OUTPUT_MODE_PREFERRED ?
2013                                     ", preferred" : "",
2014                                     m->flags & WL_OUTPUT_MODE_CURRENT ?
2015                                     ", current" : "",
2016                                     connector->count_modes == 0 ?
2017                                     ", built-in" : "");
2018
2019         return 0;
2020
2021 err_output:
2022         weston_output_destroy(&output->base);
2023 err_free:
2024         wl_list_for_each_safe(drm_mode, next, &output->base.mode_list,
2025                                                         base.link) {
2026                 wl_list_remove(&drm_mode->base.link);
2027                 free(drm_mode);
2028         }
2029
2030         drmModeFreeCrtc(output->original_crtc);
2031         ec->crtc_allocator &= ~(1 << output->crtc_id);
2032         ec->connector_allocator &= ~(1 << output->connector_id);
2033         free(output);
2034
2035         return -1;
2036 }
2037
2038 static void
2039 create_sprites(struct drm_compositor *ec)
2040 {
2041         struct drm_sprite *sprite;
2042         drmModePlaneRes *plane_res;
2043         drmModePlane *plane;
2044         uint32_t i;
2045
2046         plane_res = drmModeGetPlaneResources(ec->drm.fd);
2047         if (!plane_res) {
2048                 weston_log("failed to get plane resources: %s\n",
2049                         strerror(errno));
2050                 return;
2051         }
2052
2053         for (i = 0; i < plane_res->count_planes; i++) {
2054                 plane = drmModeGetPlane(ec->drm.fd, plane_res->planes[i]);
2055                 if (!plane)
2056                         continue;
2057
2058                 sprite = zalloc(sizeof(*sprite) + ((sizeof(uint32_t)) *
2059                                                    plane->count_formats));
2060                 if (!sprite) {
2061                         weston_log("%s: out of memory\n",
2062                                 __func__);
2063                         free(plane);
2064                         continue;
2065                 }
2066
2067                 sprite->possible_crtcs = plane->possible_crtcs;
2068                 sprite->plane_id = plane->plane_id;
2069                 sprite->current = NULL;
2070                 sprite->next = NULL;
2071                 sprite->compositor = ec;
2072                 sprite->count_formats = plane->count_formats;
2073                 memcpy(sprite->formats, plane->formats,
2074                        plane->count_formats * sizeof(plane->formats[0]));
2075                 drmModeFreePlane(plane);
2076                 weston_plane_init(&sprite->plane, 0, 0);
2077                 weston_compositor_stack_plane(&ec->base, &sprite->plane,
2078                                               &ec->base.primary_plane);
2079
2080                 wl_list_insert(&ec->sprite_list, &sprite->link);
2081         }
2082
2083         drmModeFreePlaneResources(plane_res);
2084 }
2085
2086 static void
2087 destroy_sprites(struct drm_compositor *compositor)
2088 {
2089         struct drm_sprite *sprite, *next;
2090         struct drm_output *output;
2091
2092         output = container_of(compositor->base.output_list.next,
2093                               struct drm_output, base.link);
2094
2095         wl_list_for_each_safe(sprite, next, &compositor->sprite_list, link) {
2096                 drmModeSetPlane(compositor->drm.fd,
2097                                 sprite->plane_id,
2098                                 output->crtc_id, 0, 0,
2099                                 0, 0, 0, 0, 0, 0, 0, 0);
2100                 drm_output_release_fb(output, sprite->current);
2101                 drm_output_release_fb(output, sprite->next);
2102                 weston_plane_release(&sprite->plane);
2103                 free(sprite);
2104         }
2105 }
2106
2107 static int
2108 create_outputs(struct drm_compositor *ec, uint32_t option_connector,
2109                struct udev_device *drm_device)
2110 {
2111         drmModeConnector *connector;
2112         drmModeRes *resources;
2113         int i;
2114         int x = 0, y = 0;
2115
2116         resources = drmModeGetResources(ec->drm.fd);
2117         if (!resources) {
2118                 weston_log("drmModeGetResources failed\n");
2119                 return -1;
2120         }
2121
2122         ec->crtcs = calloc(resources->count_crtcs, sizeof(uint32_t));
2123         if (!ec->crtcs) {
2124                 drmModeFreeResources(resources);
2125                 return -1;
2126         }
2127
2128         ec->min_width  = resources->min_width;
2129         ec->max_width  = resources->max_width;
2130         ec->min_height = resources->min_height;
2131         ec->max_height = resources->max_height;
2132
2133         ec->num_crtcs = resources->count_crtcs;
2134         memcpy(ec->crtcs, resources->crtcs, sizeof(uint32_t) * ec->num_crtcs);
2135
2136         for (i = 0; i < resources->count_connectors; i++) {
2137                 connector = drmModeGetConnector(ec->drm.fd,
2138                                                 resources->connectors[i]);
2139                 if (connector == NULL)
2140                         continue;
2141
2142                 if (connector->connection == DRM_MODE_CONNECTED &&
2143                     (option_connector == 0 ||
2144                      connector->connector_id == option_connector)) {
2145                         if (create_output_for_connector(ec, resources,
2146                                                         connector, x, y,
2147                                                         drm_device) < 0) {
2148                                 drmModeFreeConnector(connector);
2149                                 continue;
2150                         }
2151
2152                         x += container_of(ec->base.output_list.prev,
2153                                           struct weston_output,
2154                                           link)->width;
2155                 }
2156
2157                 drmModeFreeConnector(connector);
2158         }
2159
2160         if (wl_list_empty(&ec->base.output_list)) {
2161                 weston_log("No currently active connector found.\n");
2162                 drmModeFreeResources(resources);
2163                 return -1;
2164         }
2165
2166         drmModeFreeResources(resources);
2167
2168         return 0;
2169 }
2170
2171 static void
2172 update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
2173 {
2174         drmModeConnector *connector;
2175         drmModeRes *resources;
2176         struct drm_output *output, *next;
2177         int x = 0, y = 0;
2178         int x_offset = 0, y_offset = 0;
2179         uint32_t connected = 0, disconnects = 0;
2180         int i;
2181
2182         resources = drmModeGetResources(ec->drm.fd);
2183         if (!resources) {
2184                 weston_log("drmModeGetResources failed\n");
2185                 return;
2186         }
2187
2188         /* collect new connects */
2189         for (i = 0; i < resources->count_connectors; i++) {
2190                 int connector_id = resources->connectors[i];
2191
2192                 connector = drmModeGetConnector(ec->drm.fd, connector_id);
2193                 if (connector == NULL)
2194                         continue;
2195
2196                 if (connector->connection != DRM_MODE_CONNECTED) {
2197                         drmModeFreeConnector(connector);
2198                         continue;
2199                 }
2200
2201                 connected |= (1 << connector_id);
2202
2203                 if (!(ec->connector_allocator & (1 << connector_id))) {
2204                         struct weston_output *last =
2205                                 container_of(ec->base.output_list.prev,
2206                                              struct weston_output, link);
2207
2208                         /* XXX: not yet needed, we die with 0 outputs */
2209                         if (!wl_list_empty(&ec->base.output_list))
2210                                 x = last->x + last->width;
2211                         else
2212                                 x = 0;
2213                         y = 0;
2214                         create_output_for_connector(ec, resources,
2215                                                     connector, x, y,
2216                                                     drm_device);
2217                         weston_log("connector %d connected\n", connector_id);
2218
2219                 }
2220                 drmModeFreeConnector(connector);
2221         }
2222         drmModeFreeResources(resources);
2223
2224         disconnects = ec->connector_allocator & ~connected;
2225         if (disconnects) {
2226                 wl_list_for_each_safe(output, next, &ec->base.output_list,
2227                                       base.link) {
2228                         if (x_offset != 0 || y_offset != 0) {
2229                                 weston_output_move(&output->base,
2230                                                  output->base.x - x_offset,
2231                                                  output->base.y - y_offset);
2232                         }
2233
2234                         if (disconnects & (1 << output->connector_id)) {
2235                                 disconnects &= ~(1 << output->connector_id);
2236                                 weston_log("connector %d disconnected\n",
2237                                        output->connector_id);
2238                                 x_offset += output->base.width;
2239                                 drm_output_destroy(&output->base);
2240                         }
2241                 }
2242         }
2243
2244         /* FIXME: handle zero outputs, without terminating */   
2245         if (ec->connector_allocator == 0)
2246                 wl_display_terminate(ec->base.wl_display);
2247 }
2248
2249 static int
2250 udev_event_is_hotplug(struct drm_compositor *ec, struct udev_device *device)
2251 {
2252         const char *sysnum;
2253         const char *val;
2254
2255         sysnum = udev_device_get_sysnum(device);
2256         if (!sysnum || atoi(sysnum) != ec->drm.id)
2257                 return 0;
2258
2259         val = udev_device_get_property_value(device, "HOTPLUG");
2260         if (!val)
2261                 return 0;
2262
2263         return strcmp(val, "1") == 0;
2264 }
2265
2266 static int
2267 udev_drm_event(int fd, uint32_t mask, void *data)
2268 {
2269         struct drm_compositor *ec = data;
2270         struct udev_device *event;
2271
2272         event = udev_monitor_receive_device(ec->udev_monitor);
2273
2274         if (udev_event_is_hotplug(ec, event))
2275                 update_outputs(ec, event);
2276
2277         udev_device_unref(event);
2278
2279         return 1;
2280 }
2281
2282 static void
2283 drm_restore(struct weston_compositor *ec)
2284 {
2285         weston_launcher_restore(ec->launcher);
2286 }
2287
2288 static void
2289 drm_destroy(struct weston_compositor *ec)
2290 {
2291         struct drm_compositor *d = (struct drm_compositor *) ec;
2292
2293         udev_input_destroy(&d->input);
2294
2295         wl_event_source_remove(d->udev_drm_source);
2296         wl_event_source_remove(d->drm_source);
2297
2298         destroy_sprites(d);
2299
2300         weston_compositor_shutdown(ec);
2301
2302         ec->renderer->destroy(ec);
2303
2304         if (d->gbm)
2305                 gbm_device_destroy(d->gbm);
2306
2307         weston_launcher_destroy(d->base.launcher);
2308
2309         close(d->drm.fd);
2310
2311         free(d);
2312 }
2313
2314 static void
2315 drm_compositor_set_modes(struct drm_compositor *compositor)
2316 {
2317         struct drm_output *output;
2318         struct drm_mode *drm_mode;
2319         int ret;
2320
2321         wl_list_for_each(output, &compositor->base.output_list, base.link) {
2322                 if (!output->current) {
2323                         /* If something that would cause the output to
2324                          * switch mode happened while in another vt, we
2325                          * might not have a current drm_fb. In that case,
2326                          * schedule a repaint and let drm_output_repaint
2327                          * handle setting the mode. */
2328                         weston_output_schedule_repaint(&output->base);
2329                         continue;
2330                 }
2331
2332                 drm_mode = (struct drm_mode *) output->base.current_mode;
2333                 ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id,
2334                                      output->current->fb_id, 0, 0,
2335                                      &output->connector_id, 1,
2336                                      &drm_mode->mode_info);
2337                 if (ret < 0) {
2338                         weston_log(
2339                                 "failed to set mode %dx%d for output at %d,%d: %m\n",
2340                                 drm_mode->base.width, drm_mode->base.height, 
2341                                 output->base.x, output->base.y);
2342                 }
2343         }
2344 }
2345
2346 static void
2347 session_notify(struct wl_listener *listener, void *data)
2348 {
2349         struct weston_compositor *compositor = data;
2350         struct drm_compositor *ec = data;
2351         struct drm_sprite *sprite;
2352         struct drm_output *output;
2353
2354         if (ec->base.session_active) {
2355                 weston_log("activating session\n");
2356                 compositor->focus = 1;
2357                 if (ec->base.launcher == NULL && drmSetMaster(ec->drm.fd)) {
2358                         weston_log("failed to set master: %m\n");
2359                         wl_display_terminate(compositor->wl_display);
2360                 }
2361                 compositor->state = ec->prev_state;
2362                 drm_compositor_set_modes(ec);
2363                 weston_compositor_damage_all(compositor);
2364                 udev_input_enable(&ec->input, ec->udev);
2365         } else {
2366                 weston_log("deactivating session\n");
2367                 udev_input_disable(&ec->input);
2368
2369                 compositor->focus = 0;
2370                 ec->prev_state = compositor->state;
2371                 weston_compositor_offscreen(compositor);
2372
2373                 /* If we have a repaint scheduled (either from a
2374                  * pending pageflip or the idle handler), make sure we
2375                  * cancel that so we don't try to pageflip when we're
2376                  * vt switched away.  The OFFSCREEN state will prevent
2377                  * further attemps at repainting.  When we switch
2378                  * back, we schedule a repaint, which will process
2379                  * pending frame callbacks. */
2380
2381                 wl_list_for_each(output, &ec->base.output_list, base.link) {
2382                         output->base.repaint_needed = 0;
2383                         drmModeSetCursor(ec->drm.fd, output->crtc_id, 0, 0, 0);
2384                 }
2385
2386                 output = container_of(ec->base.output_list.next,
2387                                       struct drm_output, base.link);
2388
2389                 wl_list_for_each(sprite, &ec->sprite_list, link)
2390                         drmModeSetPlane(ec->drm.fd,
2391                                         sprite->plane_id,
2392                                         output->crtc_id, 0, 0,
2393                                         0, 0, 0, 0, 0, 0, 0, 0);
2394
2395                 if (ec->base.launcher == NULL && drmDropMaster(ec->drm.fd) < 0)
2396                         weston_log("failed to drop master: %m\n");
2397         };
2398 }
2399
2400 static void
2401 switch_vt_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
2402 {
2403         struct weston_compositor *compositor = data;
2404
2405         weston_launcher_activate_vt(compositor->launcher, key - KEY_F1 + 1);
2406 }
2407
2408 /*
2409  * Find primary GPU
2410  * Some systems may have multiple DRM devices attached to a single seat. This
2411  * function loops over all devices and tries to find a PCI device with the
2412  * boot_vga sysfs attribute set to 1.
2413  * If no such device is found, the first DRM device reported by udev is used.
2414  */
2415 static struct udev_device*
2416 find_primary_gpu(struct drm_compositor *ec, const char *seat)
2417 {
2418         struct udev_enumerate *e;
2419         struct udev_list_entry *entry;
2420         const char *path, *device_seat, *id;
2421         struct udev_device *device, *drm_device, *pci;
2422
2423         e = udev_enumerate_new(ec->udev);
2424         udev_enumerate_add_match_subsystem(e, "drm");
2425         udev_enumerate_add_match_sysname(e, "card[0-9]*");
2426
2427         udev_enumerate_scan_devices(e);
2428         drm_device = NULL;
2429         udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
2430                 path = udev_list_entry_get_name(entry);
2431                 device = udev_device_new_from_syspath(ec->udev, path);
2432                 if (!device)
2433                         continue;
2434                 device_seat = udev_device_get_property_value(device, "ID_SEAT");
2435                 if (!device_seat)
2436                         device_seat = default_seat;
2437                 if (strcmp(device_seat, seat)) {
2438                         udev_device_unref(device);
2439                         continue;
2440                 }
2441
2442                 pci = udev_device_get_parent_with_subsystem_devtype(device,
2443                                                                 "pci", NULL);
2444                 if (pci) {
2445                         id = udev_device_get_sysattr_value(pci, "boot_vga");
2446                         if (id && !strcmp(id, "1")) {
2447                                 if (drm_device)
2448                                         udev_device_unref(drm_device);
2449                                 drm_device = device;
2450                                 break;
2451                         }
2452                 }
2453
2454                 if (!drm_device)
2455                         drm_device = device;
2456                 else
2457                         udev_device_unref(device);
2458         }
2459
2460         udev_enumerate_unref(e);
2461         return drm_device;
2462 }
2463
2464 static void
2465 planes_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
2466 {
2467         struct drm_compositor *c = data;
2468
2469         switch (key) {
2470         case KEY_C:
2471                 c->cursors_are_broken ^= 1;
2472                 break;
2473         case KEY_V:
2474                 c->sprites_are_broken ^= 1;
2475                 break;
2476         case KEY_O:
2477                 c->sprites_hidden ^= 1;
2478                 break;
2479         default:
2480                 break;
2481         }
2482 }
2483
2484 #ifdef BUILD_VAAPI_RECORDER
2485 static void
2486 recorder_frame_notify(struct wl_listener *listener, void *data)
2487 {
2488         struct drm_output *output;
2489         struct drm_compositor *c;
2490         int fd, ret;
2491
2492         output = container_of(listener, struct drm_output,
2493                               recorder_frame_listener);
2494         c = (struct drm_compositor *) output->base.compositor;
2495
2496         if (!output->recorder)
2497                 return;
2498
2499         ret = drmPrimeHandleToFD(c->drm.fd, output->current->handle,
2500                                  DRM_CLOEXEC, &fd);
2501         if (ret) {
2502                 weston_log("[libva recorder] "
2503                            "failed to create prime fd for front buffer\n");
2504                 return;
2505         }
2506
2507         vaapi_recorder_frame(output->recorder, fd, output->current->stride / 4);
2508 }
2509
2510 static void *
2511 create_recorder(struct drm_compositor *c, int width, int height,
2512                 const char *filename)
2513 {
2514         int fd;
2515         drm_magic_t magic;
2516
2517         fd = open(c->drm.filename, O_RDWR | O_CLOEXEC);
2518         if (fd < 0)
2519                 return NULL;
2520
2521         drmGetMagic(fd, &magic);
2522         drmAuthMagic(c->drm.fd, magic);
2523
2524         return vaapi_recorder_create(fd, width, height, filename);
2525 }
2526
2527 static void
2528 recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
2529                  void *data)
2530 {
2531         struct drm_compositor *c = data;
2532         struct drm_output *output;
2533         int width, height;
2534
2535         output = container_of(c->base.output_list.next,
2536                               struct drm_output, base.link);
2537
2538         if (!output->recorder) {
2539                 width = output->base.current_mode->width;
2540                 height = output->base.current_mode->height;
2541
2542                 output->recorder =
2543                         create_recorder(c, width, height, "capture.h264");
2544                 if (!output->recorder) {
2545                         weston_log("failed to create vaapi recorder\n");
2546                         return;
2547                 }
2548
2549                 output->base.disable_planes++;
2550
2551                 output->recorder_frame_listener.notify = recorder_frame_notify;
2552                 wl_signal_add(&output->base.frame_signal,
2553                               &output->recorder_frame_listener);
2554
2555                 weston_output_schedule_repaint(&output->base);
2556
2557                 weston_log("[libva recorder] initialized\n");
2558         } else {
2559                 vaapi_recorder_destroy(output->recorder);
2560                 output->recorder = NULL;
2561
2562                 output->base.disable_planes--;
2563
2564                 wl_list_remove(&output->recorder_frame_listener.link);
2565                 weston_log("[libva recorder] done\n");
2566         }
2567 }
2568 #else
2569 static void
2570 recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
2571                  void *data)
2572 {
2573         weston_log("Compiled without libva support\n");
2574 }
2575 #endif
2576
2577 static struct weston_compositor *
2578 drm_compositor_create(struct wl_display *display,
2579                       struct drm_parameters *param,
2580                       int *argc, char *argv[],
2581                       struct weston_config *config)
2582 {
2583         struct drm_compositor *ec;
2584         struct weston_config_section *section;
2585         struct udev_device *drm_device;
2586         struct wl_event_loop *loop;
2587         const char *path;
2588         char *s;
2589         uint32_t key;
2590
2591         weston_log("initializing drm backend\n");
2592
2593         ec = zalloc(sizeof *ec);
2594         if (ec == NULL)
2595                 return NULL;
2596
2597         /* KMS support for sprites is not complete yet, so disable the
2598          * functionality for now. */
2599         ec->sprites_are_broken = 1;
2600
2601         section = weston_config_get_section(config, "core", NULL, NULL);
2602         weston_config_section_get_string(section,
2603                                          "gbm-format", &s, "xrgb8888");
2604         if (strcmp(s, "xrgb8888") == 0)
2605                 ec->format = GBM_FORMAT_XRGB8888;
2606         else if (strcmp(s, "rgb565") == 0)
2607                 ec->format = GBM_FORMAT_RGB565;
2608         else if (strcmp(s, "xrgb2101010") == 0)
2609                 ec->format = GBM_FORMAT_XRGB2101010;
2610         else {
2611                 weston_log("fatal: unrecognized pixel format: %s\n", s);
2612                 free(s);
2613                 goto err_base;
2614         }
2615         free(s);
2616
2617         ec->use_pixman = param->use_pixman;
2618
2619         if (weston_compositor_init(&ec->base, display, argc, argv,
2620                                    config) < 0) {
2621                 weston_log("%s failed\n", __func__);
2622                 goto err_base;
2623         }
2624
2625         /* Check if we run drm-backend using weston-launch */
2626         ec->base.launcher = weston_launcher_connect(&ec->base, param->tty,
2627                                                     param->seat_id);
2628         if (ec->base.launcher == NULL) {
2629                 weston_log("fatal: drm backend should be run "
2630                            "using weston-launch binary or as root\n");
2631                 goto err_compositor;
2632         }
2633
2634         ec->udev = udev_new();
2635         if (ec->udev == NULL) {
2636                 weston_log("failed to initialize udev context\n");
2637                 goto err_launcher;
2638         }
2639
2640         ec->base.wl_display = display;
2641         ec->session_listener.notify = session_notify;
2642         wl_signal_add(&ec->base.session_signal, &ec->session_listener);
2643
2644         drm_device = find_primary_gpu(ec, param->seat_id);
2645         if (drm_device == NULL) {
2646                 weston_log("no drm device found\n");
2647                 goto err_udev;
2648         }
2649         path = udev_device_get_syspath(drm_device);
2650
2651         if (init_drm(ec, drm_device) < 0) {
2652                 weston_log("failed to initialize kms\n");
2653                 goto err_udev_dev;
2654         }
2655
2656         if (ec->use_pixman) {
2657                 if (init_pixman(ec) < 0) {
2658                         weston_log("failed to initialize pixman renderer\n");
2659                         goto err_udev_dev;
2660                 }
2661         } else {
2662                 if (init_egl(ec) < 0) {
2663                         weston_log("failed to initialize egl\n");
2664                         goto err_udev_dev;
2665                 }
2666         }
2667
2668         ec->base.destroy = drm_destroy;
2669         ec->base.restore = drm_restore;
2670
2671         ec->base.focus = 1;
2672
2673         ec->prev_state = WESTON_COMPOSITOR_ACTIVE;
2674
2675         for (key = KEY_F1; key < KEY_F9; key++)
2676                 weston_compositor_add_key_binding(&ec->base, key,
2677                                                   MODIFIER_CTRL | MODIFIER_ALT,
2678                                                   switch_vt_binding, ec);
2679
2680         wl_list_init(&ec->sprite_list);
2681         create_sprites(ec);
2682
2683         if (create_outputs(ec, param->connector, drm_device) < 0) {
2684                 weston_log("failed to create output for %s\n", path);
2685                 goto err_sprite;
2686         }
2687
2688         path = NULL;
2689
2690         if (udev_input_init(&ec->input,
2691                             &ec->base, ec->udev, param->seat_id) < 0) {
2692                 weston_log("failed to create input devices\n");
2693                 goto err_sprite;
2694         }
2695
2696         loop = wl_display_get_event_loop(ec->base.wl_display);
2697         ec->drm_source =
2698                 wl_event_loop_add_fd(loop, ec->drm.fd,
2699                                      WL_EVENT_READABLE, on_drm_input, ec);
2700
2701         ec->udev_monitor = udev_monitor_new_from_netlink(ec->udev, "udev");
2702         if (ec->udev_monitor == NULL) {
2703                 weston_log("failed to intialize udev monitor\n");
2704                 goto err_drm_source;
2705         }
2706         udev_monitor_filter_add_match_subsystem_devtype(ec->udev_monitor,
2707                                                         "drm", NULL);
2708         ec->udev_drm_source =
2709                 wl_event_loop_add_fd(loop,
2710                                      udev_monitor_get_fd(ec->udev_monitor),
2711                                      WL_EVENT_READABLE, udev_drm_event, ec);
2712
2713         if (udev_monitor_enable_receiving(ec->udev_monitor) < 0) {
2714                 weston_log("failed to enable udev-monitor receiving\n");
2715                 goto err_udev_monitor;
2716         }
2717
2718         udev_device_unref(drm_device);
2719
2720         weston_compositor_add_debug_binding(&ec->base, KEY_O,
2721                                             planes_binding, ec);
2722         weston_compositor_add_debug_binding(&ec->base, KEY_C,
2723                                             planes_binding, ec);
2724         weston_compositor_add_debug_binding(&ec->base, KEY_V,
2725                                             planes_binding, ec);
2726         weston_compositor_add_debug_binding(&ec->base, KEY_Q,
2727                                             recorder_binding, ec);
2728
2729         return &ec->base;
2730
2731 err_udev_monitor:
2732         wl_event_source_remove(ec->udev_drm_source);
2733         udev_monitor_unref(ec->udev_monitor);
2734 err_drm_source:
2735         wl_event_source_remove(ec->drm_source);
2736         udev_input_destroy(&ec->input);
2737 err_sprite:
2738         ec->base.renderer->destroy(&ec->base);
2739         gbm_device_destroy(ec->gbm);
2740         destroy_sprites(ec);
2741 err_udev_dev:
2742         udev_device_unref(drm_device);
2743 err_launcher:
2744         weston_launcher_destroy(ec->base.launcher);
2745 err_udev:
2746         udev_unref(ec->udev);
2747 err_compositor:
2748         weston_compositor_shutdown(&ec->base);
2749 err_base:
2750         free(ec);
2751         return NULL;
2752 }
2753
2754 WL_EXPORT struct weston_compositor *
2755 backend_init(struct wl_display *display, int *argc, char *argv[],
2756              struct weston_config *config)
2757 {
2758         struct drm_parameters param = { 0, };
2759
2760         const struct weston_option drm_options[] = {
2761                 { WESTON_OPTION_INTEGER, "connector", 0, &param.connector },
2762                 { WESTON_OPTION_STRING, "seat", 0, &param.seat_id },
2763                 { WESTON_OPTION_INTEGER, "tty", 0, &param.tty },
2764                 { WESTON_OPTION_BOOLEAN, "current-mode", 0, &option_current_mode },
2765                 { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &param.use_pixman },
2766         };
2767
2768         param.seat_id = default_seat;
2769
2770         parse_options(drm_options, ARRAY_LENGTH(drm_options), argc, argv);
2771
2772         return drm_compositor_create(display, &param, argc, argv, config);
2773 }