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