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