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