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