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