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