launcher: Move rest of tty object into struct weston_launcher
[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->width ||
454             buffer->height != output->base.current->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, 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->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->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.scale;
982         y = (es->geometry.y - output->base.y) * output->base.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->width == target_mode->width && 
1104             output->base.current->height == target_mode->height &&
1105             (output->base.current->refresh == target_mode->refresh ||
1106              target_mode->refresh == 0))
1107                 return (struct drm_mode *)output->base.current;
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)
1155                 return 0;
1156
1157         output->base.current->flags = 0;
1158
1159         output->base.current = &drm_mode->base;
1160         output->base.current->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->width,
1443                                              output->base.current->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->width;
1481         int h = output->base.current->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 = &current->base;
1902         else if (configured)
1903                 output->base.current = &configured->base;
1904         else if (preferred)
1905                 output->base.current = &preferred->base;
1906         else if (current)
1907                 output->base.current = &current->base;
1908
1909         if (output->base.current == NULL) {
1910                 weston_log("no available modes for %s\n", output->base.name);
1911                 goto err_free;
1912         }
1913
1914         output->base.current->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.origin = output->base.current;
1948         output->base.start_repaint_loop = drm_output_start_repaint_loop;
1949         output->base.repaint = drm_output_repaint;
1950         output->base.destroy = drm_output_destroy;
1951         output->base.assign_planes = drm_assign_planes;
1952         output->base.set_dpms = drm_set_dpms;
1953         output->base.switch_mode = drm_output_switch_mode;
1954
1955         output->base.gamma_size = output->original_crtc->gamma_size;
1956         output->base.set_gamma = drm_output_set_gamma;
1957
1958         weston_plane_init(&output->cursor_plane, 0, 0);
1959         weston_plane_init(&output->fb_plane, 0, 0);
1960
1961         weston_compositor_stack_plane(&ec->base, &output->cursor_plane, NULL);
1962         weston_compositor_stack_plane(&ec->base, &output->fb_plane,
1963                                       &ec->base.primary_plane);
1964
1965         weston_log("Output %s, (connector %d, crtc %d)\n",
1966                    output->base.name, output->connector_id, output->crtc_id);
1967         wl_list_for_each(m, &output->base.mode_list, link)
1968                 weston_log_continue("  mode %dx%d@%.1f%s%s%s\n",
1969                                     m->width, m->height, m->refresh / 1000.0,
1970                                     m->flags & WL_OUTPUT_MODE_PREFERRED ?
1971                                     ", preferred" : "",
1972                                     m->flags & WL_OUTPUT_MODE_CURRENT ?
1973                                     ", current" : "",
1974                                     connector->count_modes == 0 ?
1975                                     ", built-in" : "");
1976
1977         return 0;
1978
1979 err_output:
1980         weston_output_destroy(&output->base);
1981 err_free:
1982         wl_list_for_each_safe(drm_mode, next, &output->base.mode_list,
1983                                                         base.link) {
1984                 wl_list_remove(&drm_mode->base.link);
1985                 free(drm_mode);
1986         }
1987
1988         drmModeFreeCrtc(output->original_crtc);
1989         ec->crtc_allocator &= ~(1 << output->crtc_id);
1990         ec->connector_allocator &= ~(1 << output->connector_id);
1991         free(output);
1992
1993         return -1;
1994 }
1995
1996 static void
1997 create_sprites(struct drm_compositor *ec)
1998 {
1999         struct drm_sprite *sprite;
2000         drmModePlaneRes *plane_res;
2001         drmModePlane *plane;
2002         uint32_t i;
2003
2004         plane_res = drmModeGetPlaneResources(ec->drm.fd);
2005         if (!plane_res) {
2006                 weston_log("failed to get plane resources: %s\n",
2007                         strerror(errno));
2008                 return;
2009         }
2010
2011         for (i = 0; i < plane_res->count_planes; i++) {
2012                 plane = drmModeGetPlane(ec->drm.fd, plane_res->planes[i]);
2013                 if (!plane)
2014                         continue;
2015
2016                 sprite = zalloc(sizeof(*sprite) + ((sizeof(uint32_t)) *
2017                                                    plane->count_formats));
2018                 if (!sprite) {
2019                         weston_log("%s: out of memory\n",
2020                                 __func__);
2021                         free(plane);
2022                         continue;
2023                 }
2024
2025                 sprite->possible_crtcs = plane->possible_crtcs;
2026                 sprite->plane_id = plane->plane_id;
2027                 sprite->current = NULL;
2028                 sprite->next = NULL;
2029                 sprite->compositor = ec;
2030                 sprite->count_formats = plane->count_formats;
2031                 memcpy(sprite->formats, plane->formats,
2032                        plane->count_formats * sizeof(plane->formats[0]));
2033                 drmModeFreePlane(plane);
2034                 weston_plane_init(&sprite->plane, 0, 0);
2035                 weston_compositor_stack_plane(&ec->base, &sprite->plane,
2036                                               &ec->base.primary_plane);
2037
2038                 wl_list_insert(&ec->sprite_list, &sprite->link);
2039         }
2040
2041         drmModeFreePlaneResources(plane_res);
2042 }
2043
2044 static void
2045 destroy_sprites(struct drm_compositor *compositor)
2046 {
2047         struct drm_sprite *sprite, *next;
2048         struct drm_output *output;
2049
2050         output = container_of(compositor->base.output_list.next,
2051                               struct drm_output, base.link);
2052
2053         wl_list_for_each_safe(sprite, next, &compositor->sprite_list, link) {
2054                 drmModeSetPlane(compositor->drm.fd,
2055                                 sprite->plane_id,
2056                                 output->crtc_id, 0, 0,
2057                                 0, 0, 0, 0, 0, 0, 0, 0);
2058                 drm_output_release_fb(output, sprite->current);
2059                 drm_output_release_fb(output, sprite->next);
2060                 weston_plane_release(&sprite->plane);
2061                 free(sprite);
2062         }
2063 }
2064
2065 static int
2066 create_outputs(struct drm_compositor *ec, uint32_t option_connector,
2067                struct udev_device *drm_device)
2068 {
2069         drmModeConnector *connector;
2070         drmModeRes *resources;
2071         int i;
2072         int x = 0, y = 0;
2073
2074         resources = drmModeGetResources(ec->drm.fd);
2075         if (!resources) {
2076                 weston_log("drmModeGetResources failed\n");
2077                 return -1;
2078         }
2079
2080         ec->crtcs = calloc(resources->count_crtcs, sizeof(uint32_t));
2081         if (!ec->crtcs) {
2082                 drmModeFreeResources(resources);
2083                 return -1;
2084         }
2085
2086         ec->min_width  = resources->min_width;
2087         ec->max_width  = resources->max_width;
2088         ec->min_height = resources->min_height;
2089         ec->max_height = resources->max_height;
2090
2091         ec->num_crtcs = resources->count_crtcs;
2092         memcpy(ec->crtcs, resources->crtcs, sizeof(uint32_t) * ec->num_crtcs);
2093
2094         for (i = 0; i < resources->count_connectors; i++) {
2095                 connector = drmModeGetConnector(ec->drm.fd,
2096                                                 resources->connectors[i]);
2097                 if (connector == NULL)
2098                         continue;
2099
2100                 if (connector->connection == DRM_MODE_CONNECTED &&
2101                     (option_connector == 0 ||
2102                      connector->connector_id == option_connector)) {
2103                         if (create_output_for_connector(ec, resources,
2104                                                         connector, x, y,
2105                                                         drm_device) < 0) {
2106                                 drmModeFreeConnector(connector);
2107                                 continue;
2108                         }
2109
2110                         x += container_of(ec->base.output_list.prev,
2111                                           struct weston_output,
2112                                           link)->width;
2113                 }
2114
2115                 drmModeFreeConnector(connector);
2116         }
2117
2118         if (wl_list_empty(&ec->base.output_list)) {
2119                 weston_log("No currently active connector found.\n");
2120                 drmModeFreeResources(resources);
2121                 return -1;
2122         }
2123
2124         drmModeFreeResources(resources);
2125
2126         return 0;
2127 }
2128
2129 static void
2130 update_outputs(struct drm_compositor *ec, struct udev_device *drm_device)
2131 {
2132         drmModeConnector *connector;
2133         drmModeRes *resources;
2134         struct drm_output *output, *next;
2135         int x = 0, y = 0;
2136         int x_offset = 0, y_offset = 0;
2137         uint32_t connected = 0, disconnects = 0;
2138         int i;
2139
2140         resources = drmModeGetResources(ec->drm.fd);
2141         if (!resources) {
2142                 weston_log("drmModeGetResources failed\n");
2143                 return;
2144         }
2145
2146         /* collect new connects */
2147         for (i = 0; i < resources->count_connectors; i++) {
2148                 int connector_id = resources->connectors[i];
2149
2150                 connector = drmModeGetConnector(ec->drm.fd, connector_id);
2151                 if (connector == NULL)
2152                         continue;
2153
2154                 if (connector->connection != DRM_MODE_CONNECTED) {
2155                         drmModeFreeConnector(connector);
2156                         continue;
2157                 }
2158
2159                 connected |= (1 << connector_id);
2160
2161                 if (!(ec->connector_allocator & (1 << connector_id))) {
2162                         struct weston_output *last =
2163                                 container_of(ec->base.output_list.prev,
2164                                              struct weston_output, link);
2165
2166                         /* XXX: not yet needed, we die with 0 outputs */
2167                         if (!wl_list_empty(&ec->base.output_list))
2168                                 x = last->x + last->width;
2169                         else
2170                                 x = 0;
2171                         y = 0;
2172                         create_output_for_connector(ec, resources,
2173                                                     connector, x, y,
2174                                                     drm_device);
2175                         weston_log("connector %d connected\n", connector_id);
2176
2177                 }
2178                 drmModeFreeConnector(connector);
2179         }
2180         drmModeFreeResources(resources);
2181
2182         disconnects = ec->connector_allocator & ~connected;
2183         if (disconnects) {
2184                 wl_list_for_each_safe(output, next, &ec->base.output_list,
2185                                       base.link) {
2186                         if (x_offset != 0 || y_offset != 0) {
2187                                 weston_output_move(&output->base,
2188                                                  output->base.x - x_offset,
2189                                                  output->base.y - y_offset);
2190                         }
2191
2192                         if (disconnects & (1 << output->connector_id)) {
2193                                 disconnects &= ~(1 << output->connector_id);
2194                                 weston_log("connector %d disconnected\n",
2195                                        output->connector_id);
2196                                 x_offset += output->base.width;
2197                                 drm_output_destroy(&output->base);
2198                         }
2199                 }
2200         }
2201
2202         /* FIXME: handle zero outputs, without terminating */   
2203         if (ec->connector_allocator == 0)
2204                 wl_display_terminate(ec->base.wl_display);
2205 }
2206
2207 static int
2208 udev_event_is_hotplug(struct drm_compositor *ec, struct udev_device *device)
2209 {
2210         const char *sysnum;
2211         const char *val;
2212
2213         sysnum = udev_device_get_sysnum(device);
2214         if (!sysnum || atoi(sysnum) != ec->drm.id)
2215                 return 0;
2216
2217         val = udev_device_get_property_value(device, "HOTPLUG");
2218         if (!val)
2219                 return 0;
2220
2221         return strcmp(val, "1") == 0;
2222 }
2223
2224 static int
2225 udev_drm_event(int fd, uint32_t mask, void *data)
2226 {
2227         struct drm_compositor *ec = data;
2228         struct udev_device *event;
2229
2230         event = udev_monitor_receive_device(ec->udev_monitor);
2231
2232         if (udev_event_is_hotplug(ec, event))
2233                 update_outputs(ec, event);
2234
2235         udev_device_unref(event);
2236
2237         return 1;
2238 }
2239
2240 static void
2241 drm_restore(struct weston_compositor *ec)
2242 {
2243         weston_launcher_restore(ec->launcher);
2244 }
2245
2246 static void
2247 drm_destroy(struct weston_compositor *ec)
2248 {
2249         struct drm_compositor *d = (struct drm_compositor *) ec;
2250
2251         udev_input_destroy(&d->input);
2252
2253         wl_event_source_remove(d->udev_drm_source);
2254         wl_event_source_remove(d->drm_source);
2255
2256         destroy_sprites(d);
2257
2258         weston_compositor_shutdown(ec);
2259
2260         ec->renderer->destroy(ec);
2261
2262         if (d->gbm)
2263                 gbm_device_destroy(d->gbm);
2264
2265         weston_launcher_destroy(d->base.launcher);
2266
2267         close(d->drm.fd);
2268
2269         free(d);
2270 }
2271
2272 static void
2273 drm_compositor_set_modes(struct drm_compositor *compositor)
2274 {
2275         struct drm_output *output;
2276         struct drm_mode *drm_mode;
2277         int ret;
2278
2279         wl_list_for_each(output, &compositor->base.output_list, base.link) {
2280                 if (!output->current) {
2281                         /* If something that would cause the output to
2282                          * switch mode happened while in another vt, we
2283                          * might not have a current drm_fb. In that case,
2284                          * schedule a repaint and let drm_output_repaint
2285                          * handle setting the mode. */
2286                         weston_output_schedule_repaint(&output->base);
2287                         continue;
2288                 }
2289
2290                 drm_mode = (struct drm_mode *) output->base.current;
2291                 ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id,
2292                                      output->current->fb_id, 0, 0,
2293                                      &output->connector_id, 1,
2294                                      &drm_mode->mode_info);
2295                 if (ret < 0) {
2296                         weston_log(
2297                                 "failed to set mode %dx%d for output at %d,%d: %m\n",
2298                                 drm_mode->base.width, drm_mode->base.height, 
2299                                 output->base.x, output->base.y);
2300                 }
2301         }
2302 }
2303
2304 static void
2305 session_notify(struct wl_listener *listener, void *data)
2306 {
2307         struct weston_compositor *compositor = data;
2308         struct drm_compositor *ec = data;
2309         struct drm_sprite *sprite;
2310         struct drm_output *output;
2311
2312         if (ec->base.session_active) {
2313                 weston_log("activating session\n");
2314                 compositor->focus = 1;
2315                 if (ec->base.launcher == NULL && drmSetMaster(ec->drm.fd)) {
2316                         weston_log("failed to set master: %m\n");
2317                         wl_display_terminate(compositor->wl_display);
2318                 }
2319                 compositor->state = ec->prev_state;
2320                 drm_compositor_set_modes(ec);
2321                 weston_compositor_damage_all(compositor);
2322                 udev_input_enable(&ec->input, ec->udev);
2323         } else {
2324                 weston_log("deactivating session\n");
2325                 udev_input_disable(&ec->input);
2326
2327                 compositor->focus = 0;
2328                 ec->prev_state = compositor->state;
2329                 weston_compositor_offscreen(compositor);
2330
2331                 /* If we have a repaint scheduled (either from a
2332                  * pending pageflip or the idle handler), make sure we
2333                  * cancel that so we don't try to pageflip when we're
2334                  * vt switched away.  The OFFSCREEN state will prevent
2335                  * further attemps at repainting.  When we switch
2336                  * back, we schedule a repaint, which will process
2337                  * pending frame callbacks. */
2338
2339                 wl_list_for_each(output, &ec->base.output_list, base.link) {
2340                         output->base.repaint_needed = 0;
2341                         drmModeSetCursor(ec->drm.fd, output->crtc_id, 0, 0, 0);
2342                 }
2343
2344                 output = container_of(ec->base.output_list.next,
2345                                       struct drm_output, base.link);
2346
2347                 wl_list_for_each(sprite, &ec->sprite_list, link)
2348                         drmModeSetPlane(ec->drm.fd,
2349                                         sprite->plane_id,
2350                                         output->crtc_id, 0, 0,
2351                                         0, 0, 0, 0, 0, 0, 0, 0);
2352
2353                 if (ec->base.launcher == NULL && drmDropMaster(ec->drm.fd) < 0)
2354                         weston_log("failed to drop master: %m\n");
2355         };
2356 }
2357
2358 static void
2359 switch_vt_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
2360 {
2361         struct weston_compositor *compositor = data;
2362
2363         weston_launcher_activate_vt(compositor->launcher, key - KEY_F1 + 1);
2364 }
2365
2366 /*
2367  * Find primary GPU
2368  * Some systems may have multiple DRM devices attached to a single seat. This
2369  * function loops over all devices and tries to find a PCI device with the
2370  * boot_vga sysfs attribute set to 1.
2371  * If no such device is found, the first DRM device reported by udev is used.
2372  */
2373 static struct udev_device*
2374 find_primary_gpu(struct drm_compositor *ec, const char *seat)
2375 {
2376         struct udev_enumerate *e;
2377         struct udev_list_entry *entry;
2378         const char *path, *device_seat, *id;
2379         struct udev_device *device, *drm_device, *pci;
2380
2381         e = udev_enumerate_new(ec->udev);
2382         udev_enumerate_add_match_subsystem(e, "drm");
2383         udev_enumerate_add_match_sysname(e, "card[0-9]*");
2384
2385         udev_enumerate_scan_devices(e);
2386         drm_device = NULL;
2387         udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
2388                 path = udev_list_entry_get_name(entry);
2389                 device = udev_device_new_from_syspath(ec->udev, path);
2390                 if (!device)
2391                         continue;
2392                 device_seat = udev_device_get_property_value(device, "ID_SEAT");
2393                 if (!device_seat)
2394                         device_seat = default_seat;
2395                 if (strcmp(device_seat, seat)) {
2396                         udev_device_unref(device);
2397                         continue;
2398                 }
2399
2400                 pci = udev_device_get_parent_with_subsystem_devtype(device,
2401                                                                 "pci", NULL);
2402                 if (pci) {
2403                         id = udev_device_get_sysattr_value(pci, "boot_vga");
2404                         if (id && !strcmp(id, "1")) {
2405                                 if (drm_device)
2406                                         udev_device_unref(drm_device);
2407                                 drm_device = device;
2408                                 break;
2409                         }
2410                 }
2411
2412                 if (!drm_device)
2413                         drm_device = device;
2414                 else
2415                         udev_device_unref(device);
2416         }
2417
2418         udev_enumerate_unref(e);
2419         return drm_device;
2420 }
2421
2422 static void
2423 planes_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data)
2424 {
2425         struct drm_compositor *c = data;
2426
2427         switch (key) {
2428         case KEY_C:
2429                 c->cursors_are_broken ^= 1;
2430                 break;
2431         case KEY_V:
2432                 c->sprites_are_broken ^= 1;
2433                 break;
2434         case KEY_O:
2435                 c->sprites_hidden ^= 1;
2436                 break;
2437         default:
2438                 break;
2439         }
2440 }
2441
2442 #ifdef BUILD_VAAPI_RECORDER
2443 static void
2444 recorder_frame_notify(struct wl_listener *listener, void *data)
2445 {
2446         struct drm_output *output;
2447         struct drm_compositor *c;
2448         int fd, ret;
2449
2450         output = container_of(listener, struct drm_output,
2451                               recorder_frame_listener);
2452         c = (struct drm_compositor *) output->base.compositor;
2453
2454         if (!output->recorder)
2455                 return;
2456
2457         ret = drmPrimeHandleToFD(c->drm.fd, output->current->handle,
2458                                  DRM_CLOEXEC, &fd);
2459         if (ret) {
2460                 weston_log("[libva recorder] "
2461                            "failed to create prime fd for front buffer\n");
2462                 return;
2463         }
2464
2465         vaapi_recorder_frame(output->recorder, fd, output->current->stride / 4);
2466 }
2467
2468 static void *
2469 create_recorder(struct drm_compositor *c, int width, int height,
2470                 const char *filename)
2471 {
2472         int fd;
2473         drm_magic_t magic;
2474
2475         fd = open(c->drm.filename, O_RDWR | O_CLOEXEC);
2476         if (fd < 0)
2477                 return NULL;
2478
2479         drmGetMagic(fd, &magic);
2480         drmAuthMagic(c->drm.fd, magic);
2481
2482         return vaapi_recorder_create(fd, width, height, filename);
2483 }
2484
2485 static void
2486 recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
2487                  void *data)
2488 {
2489         struct drm_compositor *c = data;
2490         struct drm_output *output;
2491         int width, height;
2492
2493         output = container_of(c->base.output_list.next,
2494                               struct drm_output, base.link);
2495
2496         if (!output->recorder) {
2497                 width = output->base.current->width;
2498                 height = output->base.current->height;
2499
2500                 output->recorder =
2501                         create_recorder(c, width, height, "capture.h264");
2502                 if (!output->recorder) {
2503                         weston_log("failed to create vaapi recorder\n");
2504                         return;
2505                 }
2506
2507                 output->base.disable_planes++;
2508
2509                 output->recorder_frame_listener.notify = recorder_frame_notify;
2510                 wl_signal_add(&output->base.frame_signal,
2511                               &output->recorder_frame_listener);
2512
2513                 weston_output_schedule_repaint(&output->base);
2514
2515                 weston_log("[libva recorder] initialized\n");
2516         } else {
2517                 vaapi_recorder_destroy(output->recorder);
2518                 output->recorder = NULL;
2519
2520                 output->base.disable_planes--;
2521
2522                 wl_list_remove(&output->recorder_frame_listener.link);
2523                 weston_log("[libva recorder] done\n");
2524         }
2525 }
2526 #else
2527 static void
2528 recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
2529                  void *data)
2530 {
2531         weston_log("Compiled without libva support\n");
2532 }
2533 #endif
2534
2535 static struct weston_compositor *
2536 drm_compositor_create(struct wl_display *display,
2537                       int connector, const char *seat_id, int tty, int pixman,
2538                       int *argc, char *argv[],
2539                       struct weston_config *config)
2540 {
2541         struct drm_compositor *ec;
2542         struct udev_device *drm_device;
2543         struct wl_event_loop *loop;
2544         const char *path;
2545         uint32_t key;
2546
2547         weston_log("initializing drm backend\n");
2548
2549         ec = zalloc(sizeof *ec);
2550         if (ec == NULL)
2551                 return NULL;
2552
2553         /* KMS support for sprites is not complete yet, so disable the
2554          * functionality for now. */
2555         ec->sprites_are_broken = 1;
2556
2557         ec->use_pixman = pixman;
2558
2559         if (weston_compositor_init(&ec->base, display, argc, argv,
2560                                    config) < 0) {
2561                 weston_log("%s failed\n", __func__);
2562                 goto err_base;
2563         }
2564
2565         /* Check if we run drm-backend using weston-launch */
2566         ec->base.launcher = weston_launcher_connect(&ec->base);
2567         if (ec->base.launcher == NULL) {
2568                 weston_log("fatal: drm backend should be run "
2569                            "using weston-launch binary or as root\n");
2570                 goto err_compositor;
2571         }
2572
2573         ec->udev = udev_new();
2574         if (ec->udev == NULL) {
2575                 weston_log("failed to initialize udev context\n");
2576                 goto err_launcher;
2577         }
2578
2579         ec->base.wl_display = display;
2580         ec->session_listener.notify = session_notify;
2581         wl_signal_add(&ec->base.session_signal, &ec->session_listener);
2582
2583         drm_device = find_primary_gpu(ec, seat_id);
2584         if (drm_device == NULL) {
2585                 weston_log("no drm device found\n");
2586                 goto err_udev;
2587         }
2588         path = udev_device_get_syspath(drm_device);
2589
2590         if (init_drm(ec, drm_device) < 0) {
2591                 weston_log("failed to initialize kms\n");
2592                 goto err_udev_dev;
2593         }
2594
2595         if (ec->use_pixman) {
2596                 if (init_pixman(ec) < 0) {
2597                         weston_log("failed to initialize pixman renderer\n");
2598                         goto err_udev_dev;
2599                 }
2600         } else {
2601                 if (init_egl(ec) < 0) {
2602                         weston_log("failed to initialize egl\n");
2603                         goto err_udev_dev;
2604                 }
2605         }
2606
2607         ec->base.destroy = drm_destroy;
2608         ec->base.restore = drm_restore;
2609
2610         ec->base.focus = 1;
2611
2612         ec->prev_state = WESTON_COMPOSITOR_ACTIVE;
2613
2614         for (key = KEY_F1; key < KEY_F9; key++)
2615                 weston_compositor_add_key_binding(&ec->base, key,
2616                                                   MODIFIER_CTRL | MODIFIER_ALT,
2617                                                   switch_vt_binding, ec);
2618
2619         wl_list_init(&ec->sprite_list);
2620         create_sprites(ec);
2621
2622         if (create_outputs(ec, connector, drm_device) < 0) {
2623                 weston_log("failed to create output for %s\n", path);
2624                 goto err_sprite;
2625         }
2626
2627         path = NULL;
2628
2629         if (udev_input_init(&ec->input, &ec->base, ec->udev, seat_id) < 0) {
2630                 weston_log("failed to create input devices\n");
2631                 goto err_sprite;
2632         }
2633
2634         loop = wl_display_get_event_loop(ec->base.wl_display);
2635         ec->drm_source =
2636                 wl_event_loop_add_fd(loop, ec->drm.fd,
2637                                      WL_EVENT_READABLE, on_drm_input, ec);
2638
2639         ec->udev_monitor = udev_monitor_new_from_netlink(ec->udev, "udev");
2640         if (ec->udev_monitor == NULL) {
2641                 weston_log("failed to intialize udev monitor\n");
2642                 goto err_drm_source;
2643         }
2644         udev_monitor_filter_add_match_subsystem_devtype(ec->udev_monitor,
2645                                                         "drm", NULL);
2646         ec->udev_drm_source =
2647                 wl_event_loop_add_fd(loop,
2648                                      udev_monitor_get_fd(ec->udev_monitor),
2649                                      WL_EVENT_READABLE, udev_drm_event, ec);
2650
2651         if (udev_monitor_enable_receiving(ec->udev_monitor) < 0) {
2652                 weston_log("failed to enable udev-monitor receiving\n");
2653                 goto err_udev_monitor;
2654         }
2655
2656         udev_device_unref(drm_device);
2657
2658         weston_compositor_add_debug_binding(&ec->base, KEY_O,
2659                                             planes_binding, ec);
2660         weston_compositor_add_debug_binding(&ec->base, KEY_C,
2661                                             planes_binding, ec);
2662         weston_compositor_add_debug_binding(&ec->base, KEY_V,
2663                                             planes_binding, ec);
2664         weston_compositor_add_debug_binding(&ec->base, KEY_Q,
2665                                             recorder_binding, ec);
2666
2667         return &ec->base;
2668
2669 err_udev_monitor:
2670         wl_event_source_remove(ec->udev_drm_source);
2671         udev_monitor_unref(ec->udev_monitor);
2672 err_drm_source:
2673         wl_event_source_remove(ec->drm_source);
2674         udev_input_destroy(&ec->input);
2675 err_sprite:
2676         ec->base.renderer->destroy(&ec->base);
2677         gbm_device_destroy(ec->gbm);
2678         destroy_sprites(ec);
2679 err_udev_dev:
2680         udev_device_unref(drm_device);
2681 err_launcher:
2682         weston_launcher_destroy(ec->base.launcher);
2683 err_udev:
2684         udev_unref(ec->udev);
2685 err_compositor:
2686         weston_compositor_shutdown(&ec->base);
2687 err_base:
2688         free(ec);
2689         return NULL;
2690 }
2691
2692 WL_EXPORT struct weston_compositor *
2693 backend_init(struct wl_display *display, int *argc, char *argv[],
2694              struct weston_config *config)
2695 {
2696         int connector = 0, tty = 0, use_pixman = 0;
2697         const char *seat_id = default_seat;
2698
2699         const struct weston_option drm_options[] = {
2700                 { WESTON_OPTION_INTEGER, "connector", 0, &connector },
2701                 { WESTON_OPTION_STRING, "seat", 0, &seat_id },
2702                 { WESTON_OPTION_INTEGER, "tty", 0, &tty },
2703                 { WESTON_OPTION_BOOLEAN, "current-mode", 0, &option_current_mode },
2704                 { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &use_pixman },
2705         };
2706
2707         parse_options(drm_options, ARRAY_LENGTH(drm_options), argc, argv);
2708
2709         return drm_compositor_create(display, connector, seat_id, tty, use_pixman,
2710                                      argc, argv, config);
2711 }