blob: 403ae2d2c3d3207f2a2741a5526d6550592e8247 [file] [log] [blame]
Daniel Stonedd1bc502019-06-17 12:13:46 +01001/*
2 * Copyright © 2008-2011 Kristian Høgsberg
3 * Copyright © 2011 Intel Corporation
4 * Copyright © 2017, 2018 Collabora, Ltd.
5 * Copyright © 2017, 2018 General Electric Company
6 * Copyright (c) 2018 DisplayLink (UK) Ltd.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining
9 * a copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial
18 * portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
24 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * SOFTWARE.
28 */
29
30#include "config.h"
31
32#include <errno.h>
33#include <stdint.h>
34#include <stdlib.h>
35#include <ctype.h>
36#include <string.h>
37#include <fcntl.h>
38#include <unistd.h>
39#include <linux/input.h>
40#include <linux/vt.h>
41#include <assert.h>
42#include <sys/mman.h>
43#include <time.h>
44
45
46#include <xf86drm.h>
47#include <xf86drmMode.h>
48#include <drm_fourcc.h>
49
50#include <gbm.h>
51#include <libudev.h>
52
53#include <libweston/libweston.h>
54#include <libweston/backend-drm.h>
55#include <libweston/weston-debug.h>
56#include "shared/helpers.h"
57#include "libinput-seat.h"
Marius Vlada72e3712019-07-10 13:46:39 +030058#include "libweston-internal.h"
Daniel Stonedd1bc502019-06-17 12:13:46 +010059
60#ifndef DRM_CLIENT_CAP_ASPECT_RATIO
61#define DRM_CLIENT_CAP_ASPECT_RATIO 4
62#endif
63
64#ifndef GBM_BO_USE_CURSOR
65#define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64
66#endif
67
68#ifndef GBM_BO_USE_LINEAR
69#define GBM_BO_USE_LINEAR (1 << 4)
70#endif
71
72/**
73 * A small wrapper to print information into the 'drm-backend' debug scope.
74 *
75 * The following conventions are used to print variables:
76 *
77 * - fixed uint32_t values, including Weston object IDs such as weston_output
78 * IDs, DRM object IDs such as CRTCs or properties, and GBM/DRM formats:
79 * "%lu (0x%lx)" (unsigned long) value, (unsigned long) value
80 *
81 * - fixed uint64_t values, such as DRM property values (including object IDs
82 * when used as a value):
83 * "%llu (0x%llx)" (unsigned long long) value, (unsigned long long) value
84 *
85 * - non-fixed-width signed int:
86 * "%d" value
87 *
88 * - non-fixed-width unsigned int:
89 * "%u (0x%x)" value, value
90 *
91 * - non-fixed-width unsigned long:
92 * "%lu (0x%lx)" value, value
93 *
94 * Either the integer or hexadecimal forms may be omitted if it is known that
95 * one representation is not useful (e.g. width/height in hex are rarely what
96 * you want).
97 *
98 * This is to avoid implicit widening or narrowing when we use fixed-size
99 * types: uint32_t can be resolved by either unsigned int or unsigned long
100 * on a 32-bit system but only unsigned int on a 64-bit system, with uint64_t
101 * being unsigned long long on a 32-bit system and unsigned long on a 64-bit
102 * system. To avoid confusing side effects, we explicitly cast to the widest
103 * possible type and use a matching format specifier.
104 */
105#define drm_debug(b, ...) \
106 weston_log_scope_printf((b)->debug, __VA_ARGS__)
107
108#define MAX_CLONED_CONNECTORS 4
109
110/**
111 * aspect ratio info taken from the drmModeModeInfo flag bits 19-22,
112 * which should be used to fill the aspect ratio field in weston_mode.
113 */
114#define DRM_MODE_FLAG_PIC_AR_BITS_POS 19
115#ifndef DRM_MODE_FLAG_PIC_AR_MASK
116#define DRM_MODE_FLAG_PIC_AR_MASK (0xF << DRM_MODE_FLAG_PIC_AR_BITS_POS)
117#endif
118
119/**
120 * Represents the values of an enum-type KMS property
121 */
122struct drm_property_enum_info {
123 const char *name; /**< name as string (static, not freed) */
124 bool valid; /**< true if value is supported; ignore if false */
125 uint64_t value; /**< raw value */
126};
127
128/**
129 * Holds information on a DRM property, including its ID and the enum
130 * values it holds.
131 *
132 * DRM properties are allocated dynamically, and maintained as DRM objects
133 * within the normal object ID space; they thus do not have a stable ID
134 * to refer to. This includes enum values, which must be referred to by
135 * integer values, but these are not stable.
136 *
137 * drm_property_info allows a cache to be maintained where Weston can use
138 * enum values internally to refer to properties, with the mapping to DRM
139 * ID values being maintained internally.
140 */
141struct drm_property_info {
142 const char *name; /**< name as string (static, not freed) */
143 uint32_t prop_id; /**< KMS property object ID */
144 unsigned int num_enum_values; /**< number of enum values */
145 struct drm_property_enum_info *enum_values; /**< array of enum values */
146};
147
148/**
149 * List of properties attached to DRM planes
150 */
151enum wdrm_plane_property {
152 WDRM_PLANE_TYPE = 0,
153 WDRM_PLANE_SRC_X,
154 WDRM_PLANE_SRC_Y,
155 WDRM_PLANE_SRC_W,
156 WDRM_PLANE_SRC_H,
157 WDRM_PLANE_CRTC_X,
158 WDRM_PLANE_CRTC_Y,
159 WDRM_PLANE_CRTC_W,
160 WDRM_PLANE_CRTC_H,
161 WDRM_PLANE_FB_ID,
162 WDRM_PLANE_CRTC_ID,
163 WDRM_PLANE_IN_FORMATS,
164 WDRM_PLANE_IN_FENCE_FD,
165 WDRM_PLANE_FB_DAMAGE_CLIPS,
166 WDRM_PLANE__COUNT
167};
168
169/**
170 * Possible values for the WDRM_PLANE_TYPE property.
171 */
172enum wdrm_plane_type {
173 WDRM_PLANE_TYPE_PRIMARY = 0,
174 WDRM_PLANE_TYPE_CURSOR,
175 WDRM_PLANE_TYPE_OVERLAY,
176 WDRM_PLANE_TYPE__COUNT
177};
178
179/**
180 * List of properties attached to a DRM connector
181 */
182enum wdrm_connector_property {
183 WDRM_CONNECTOR_EDID = 0,
184 WDRM_CONNECTOR_DPMS,
185 WDRM_CONNECTOR_CRTC_ID,
186 WDRM_CONNECTOR_NON_DESKTOP,
187 WDRM_CONNECTOR__COUNT
188};
189
190enum wdrm_dpms_state {
191 WDRM_DPMS_STATE_OFF = 0,
192 WDRM_DPMS_STATE_ON,
193 WDRM_DPMS_STATE_STANDBY, /* unused */
194 WDRM_DPMS_STATE_SUSPEND, /* unused */
195 WDRM_DPMS_STATE__COUNT
196};
197
198/**
199 * List of properties attached to DRM CRTCs
200 */
201enum wdrm_crtc_property {
202 WDRM_CRTC_MODE_ID = 0,
203 WDRM_CRTC_ACTIVE,
204 WDRM_CRTC__COUNT
205};
206
207struct drm_backend {
208 struct weston_backend base;
209 struct weston_compositor *compositor;
210
211 struct udev *udev;
212 struct wl_event_source *drm_source;
213
214 struct udev_monitor *udev_monitor;
215 struct wl_event_source *udev_drm_source;
216
217 struct {
218 int id;
219 int fd;
220 char *filename;
221 dev_t devnum;
222 } drm;
223 struct gbm_device *gbm;
224 struct wl_listener session_listener;
225 uint32_t gbm_format;
226
227 /* we need these parameters in order to not fail drmModeAddFB2()
228 * due to out of bounds dimensions, and then mistakenly set
229 * sprites_are_broken:
230 */
231 int min_width, max_width;
232 int min_height, max_height;
233
234 struct wl_list plane_list;
235 int sprites_are_broken;
236 int sprites_hidden;
237
238 void *repaint_data;
239
240 bool state_invalid;
241
242 /* CRTC IDs not used by any enabled output. */
243 struct wl_array unused_crtcs;
244
245 int cursors_are_broken;
246
247 bool universal_planes;
248 bool atomic_modeset;
249
250 bool use_pixman;
251 bool use_pixman_shadow;
252
253 struct udev_input input;
254
255 int32_t cursor_width;
256 int32_t cursor_height;
257
258 uint32_t pageflip_timeout;
259
260 bool shutting_down;
261
262 bool aspect_ratio_supported;
263
264 bool fb_modifiers;
265
266 struct weston_log_scope *debug;
267};
268
269struct drm_mode {
270 struct weston_mode base;
271 drmModeModeInfo mode_info;
272 uint32_t blob_id;
273};
274
275enum drm_fb_type {
276 BUFFER_INVALID = 0, /**< never used */
277 BUFFER_CLIENT, /**< directly sourced from client */
278 BUFFER_DMABUF, /**< imported from linux_dmabuf client */
279 BUFFER_PIXMAN_DUMB, /**< internal Pixman rendering */
280 BUFFER_GBM_SURFACE, /**< internal EGL rendering */
281 BUFFER_CURSOR, /**< internal cursor buffer */
282};
283
284struct drm_fb {
285 enum drm_fb_type type;
286
287 int refcnt;
288
289 uint32_t fb_id, size;
290 uint32_t handles[4];
291 uint32_t strides[4];
292 uint32_t offsets[4];
293 int num_planes;
294 const struct pixel_format_info *format;
295 uint64_t modifier;
296 int width, height;
297 int fd;
298 struct weston_buffer_reference buffer_ref;
299 struct weston_buffer_release_reference buffer_release_ref;
300
301 /* Used by gbm fbs */
302 struct gbm_bo *bo;
303 struct gbm_surface *gbm_surface;
304
305 /* Used by dumb fbs */
306 void *map;
307};
308
309struct drm_edid {
310 char eisa_id[13];
311 char monitor_name[13];
312 char pnp_id[5];
313 char serial_number[13];
314};
315
316/**
317 * Pending state holds one or more drm_output_state structures, collected from
318 * performing repaint. This pending state is transient, and only lives between
319 * beginning a repaint group and flushing the results: after flush, each
320 * output state will complete and be retired separately.
321 */
322struct drm_pending_state {
323 struct drm_backend *backend;
324 struct wl_list output_list;
325};
326
327/*
328 * Output state holds the dynamic state for one Weston output, i.e. a KMS CRTC,
329 * plus >= 1 each of encoder/connector/plane. Since everything but the planes
330 * is currently statically assigned per-output, we mainly use this to track
331 * plane state.
332 *
333 * pending_state is set when the output state is owned by a pending_state,
334 * i.e. when it is being constructed and has not yet been applied. When the
335 * output state has been applied, the owning pending_state is freed.
336 */
337struct drm_output_state {
338 struct drm_pending_state *pending_state;
339 struct drm_output *output;
340 struct wl_list link;
341 enum dpms_enum dpms;
342 struct wl_list plane_list;
343};
344
345/**
346 * Plane state holds the dynamic state for a plane: where it is positioned,
347 * and which buffer it is currently displaying.
348 *
349 * The plane state is owned by an output state, except when setting an initial
350 * state. See drm_output_state for notes on state object lifetime.
351 */
352struct drm_plane_state {
353 struct drm_plane *plane;
354 struct drm_output *output;
355 struct drm_output_state *output_state;
356
357 struct drm_fb *fb;
358
359 struct weston_view *ev; /**< maintained for drm_assign_planes only */
360
361 int32_t src_x, src_y;
362 uint32_t src_w, src_h;
363 int32_t dest_x, dest_y;
364 uint32_t dest_w, dest_h;
365
366 bool complete;
367
368 /* We don't own the fd, so we shouldn't close it */
369 int in_fence_fd;
370
371 pixman_region32_t damage; /* damage to kernel */
372
373 struct wl_list link; /* drm_output_state::plane_list */
374};
375
376/**
377 * A plane represents one buffer, positioned within a CRTC, and stacked
378 * relative to other planes on the same CRTC.
379 *
380 * Each CRTC has a 'primary plane', which use used to display the classic
381 * framebuffer contents, as accessed through the legacy drmModeSetCrtc
382 * call (which combines setting the CRTC's actual physical mode, and the
383 * properties of the primary plane).
384 *
385 * The cursor plane also has its own alternate legacy API.
386 *
387 * Other planes are used opportunistically to display content we do not
388 * wish to blit into the primary plane. These non-primary/cursor planes
389 * are referred to as 'sprites'.
390 */
391struct drm_plane {
392 struct weston_plane base;
393
394 struct drm_backend *backend;
395
396 enum wdrm_plane_type type;
397
398 uint32_t possible_crtcs;
399 uint32_t plane_id;
400 uint32_t count_formats;
401
402 struct drm_property_info props[WDRM_PLANE__COUNT];
403
404 /* The last state submitted to the kernel for this plane. */
405 struct drm_plane_state *state_cur;
406
407 struct wl_list link;
408
409 struct {
410 uint32_t format;
411 uint32_t count_modifiers;
412 uint64_t *modifiers;
413 } formats[];
414};
415
416struct drm_head {
417 struct weston_head base;
418 struct drm_backend *backend;
419
420 drmModeConnector *connector;
421 uint32_t connector_id;
422 struct drm_edid edid;
423
424 /* Holds the properties for the connector */
425 struct drm_property_info props_conn[WDRM_CONNECTOR__COUNT];
426
427 struct backlight *backlight;
428
429 drmModeModeInfo inherited_mode; /**< Original mode on the connector */
430 uint32_t inherited_crtc_id; /**< Original CRTC assignment */
431};
432
433struct drm_output {
434 struct weston_output base;
435 struct drm_backend *backend;
436
437 uint32_t crtc_id; /* object ID to pass to DRM functions */
438 int pipe; /* index of CRTC in resource array / bitmasks */
439
440 /* Holds the properties for the CRTC */
441 struct drm_property_info props_crtc[WDRM_CRTC__COUNT];
442
443 int page_flip_pending;
444 int atomic_complete_pending;
445 int destroy_pending;
446 int disable_pending;
447 int dpms_off_pending;
448
Stefan Agner974390a2019-07-08 00:42:05 +0200449 uint32_t gbm_cursor_handle[2];
Daniel Stonedd1bc502019-06-17 12:13:46 +0100450 struct drm_fb *gbm_cursor_fb[2];
451 struct drm_plane *cursor_plane;
452 struct weston_view *cursor_view;
453 int current_cursor;
454
455 struct gbm_surface *gbm_surface;
456 uint32_t gbm_format;
457 uint32_t gbm_bo_flags;
458
459 /* Plane being displayed directly on the CRTC */
460 struct drm_plane *scanout_plane;
461
462 /* The last state submitted to the kernel for this CRTC. */
463 struct drm_output_state *state_cur;
464 /* The previously-submitted state, where the hardware has not
465 * yet acknowledged completion of state_cur. */
466 struct drm_output_state *state_last;
467
468 struct drm_fb *dumb[2];
469 pixman_image_t *image[2];
470 int current_image;
471 pixman_region32_t previous_damage;
472
473 struct vaapi_recorder *recorder;
474 struct wl_listener recorder_frame_listener;
475
476 struct wl_event_source *pageflip_timer;
477
478 bool virtual;
479
480 submit_frame_cb virtual_submit_frame;
481};
482
483static inline struct drm_head *
484to_drm_head(struct weston_head *base)
485{
486 return container_of(base, struct drm_head, base);
487}
488
489static inline struct drm_output *
490to_drm_output(struct weston_output *base)
491{
492 return container_of(base, struct drm_output, base);
493}
494
495static inline struct drm_backend *
496to_drm_backend(struct weston_compositor *base)
497{
498 return container_of(base->backend, struct drm_backend, base);
499}
500
501static inline struct drm_mode *
502to_drm_mode(struct weston_mode *base)
503{
504 return container_of(base, struct drm_mode, base);
505}
Daniel Stonefbe6c1d2019-06-17 16:04:26 +0100506
Daniel Stone4c2fc702019-06-18 11:12:07 +0100507struct drm_output *
508drm_output_find_by_crtc(struct drm_backend *b, uint32_t crtc_id);
509
510struct drm_head *
511drm_head_find_by_connector(struct drm_backend *backend, uint32_t connector_id);
512
Daniel Stone7580b3c2019-06-18 11:16:53 +0100513static inline bool
514drm_view_transform_supported(struct weston_view *ev, struct weston_output *output)
515{
516 struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
517
518 /* This will incorrectly disallow cases where the combination of
519 * buffer and view transformations match the output transform.
520 * Fixing this requires a full analysis of the transformation
521 * chain. */
522 if (ev->transform.enabled &&
523 ev->transform.matrix.type >= WESTON_MATRIX_TRANSFORM_ROTATE)
524 return false;
525
526 if (viewport->buffer.transform != output->transform)
527 return false;
528
529 return true;
530}
531
Daniel Stonefbe6c1d2019-06-17 16:04:26 +0100532int
533drm_mode_ensure_blob(struct drm_backend *backend, struct drm_mode *mode);
534
535struct drm_mode *
536drm_output_choose_mode(struct drm_output *output,
537 struct weston_mode *target_mode);
538void
539update_head_from_connector(struct drm_head *head,
540 drmModeObjectProperties *props);
541
542void
543drm_mode_list_destroy(struct drm_backend *backend, struct wl_list *mode_list);
544
545void
546drm_output_print_modes(struct drm_output *output);
547
548int
549drm_output_set_mode(struct weston_output *base,
550 enum weston_drm_backend_output_mode mode,
551 const char *modeline);
552
Daniel Stone4c2fc702019-06-18 11:12:07 +0100553void
554drm_property_info_populate(struct drm_backend *b,
555 const struct drm_property_info *src,
556 struct drm_property_info *info,
557 unsigned int num_infos,
558 drmModeObjectProperties *props);
Daniel Stonefbe6c1d2019-06-17 16:04:26 +0100559uint64_t
560drm_property_get_value(struct drm_property_info *info,
561 const drmModeObjectProperties *props,
562 uint64_t def);
Daniel Stone4c2fc702019-06-18 11:12:07 +0100563int
564drm_plane_populate_formats(struct drm_plane *plane, const drmModePlane *kplane,
565 const drmModeObjectProperties *props);
566void
567drm_property_info_free(struct drm_property_info *info, int num_props);
568
569extern struct drm_property_enum_info plane_type_enums[];
570extern const struct drm_property_info plane_props[];
571extern struct drm_property_enum_info dpms_state_enums[];
572extern const struct drm_property_info connector_props[];
573extern const struct drm_property_info crtc_props[];
574
575int
576init_kms_caps(struct drm_backend *b);
577
578int
579drm_pending_state_test(struct drm_pending_state *pending_state);
580int
581drm_pending_state_apply(struct drm_pending_state *pending_state);
582int
583drm_pending_state_apply_sync(struct drm_pending_state *pending_state);
584
585void
586drm_output_set_gamma(struct weston_output *output_base,
587 uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b);
588
589void
590drm_output_update_msc(struct drm_output *output, unsigned int seq);
591void
592drm_output_update_complete(struct drm_output *output, uint32_t flags,
593 unsigned int sec, unsigned int usec);
594int
595on_drm_input(int fd, uint32_t mask, void *data);
596
597struct drm_plane_state *
598drm_output_state_get_existing_plane(struct drm_output_state *state_output,
599 struct drm_plane *plane);
600void
601drm_plane_state_free(struct drm_plane_state *state, bool force);
602void
603drm_output_state_free(struct drm_output_state *state);
604void
605drm_pending_state_free(struct drm_pending_state *pending_state);
Daniel Stone7580b3c2019-06-18 11:16:53 +0100606
607struct drm_fb *
608drm_fb_ref(struct drm_fb *fb);
609void
610drm_fb_unref(struct drm_fb *fb);
611
612struct drm_fb *
613drm_fb_create_dumb(struct drm_backend *b, int width, int height,
614 uint32_t format);
615struct drm_fb *
616drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
617 bool is_opaque, enum drm_fb_type type);
618struct drm_fb *
619drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev);
Daniel Stone6b466f22019-06-18 11:30:54 +0100620
621
622struct drm_pending_state *
623drm_pending_state_alloc(struct drm_backend *backend);
624void
625drm_pending_state_free(struct drm_pending_state *pending_state);
626struct drm_output_state *
627drm_pending_state_get_output(struct drm_pending_state *pending_state,
628 struct drm_output *output);
629
630
631/**
632 * Mode for drm_output_state_duplicate.
633 */
634enum drm_output_state_duplicate_mode {
635 DRM_OUTPUT_STATE_CLEAR_PLANES, /**< reset all planes to off */
636 DRM_OUTPUT_STATE_PRESERVE_PLANES, /**< preserve plane state */
637};
638
639struct drm_output_state *
640drm_output_state_alloc(struct drm_output *output,
641 struct drm_pending_state *pending_state);
642struct drm_output_state *
643drm_output_state_duplicate(struct drm_output_state *src,
644 struct drm_pending_state *pending_state,
645 enum drm_output_state_duplicate_mode plane_mode);
646void
647drm_output_state_free(struct drm_output_state *state);
648struct drm_plane_state *
649drm_output_state_get_plane(struct drm_output_state *state_output,
650 struct drm_plane *plane);
651struct drm_plane_state *
652drm_output_state_get_existing_plane(struct drm_output_state *state_output,
653 struct drm_plane *plane);
654
655
656
657struct drm_plane_state *
658drm_plane_state_alloc(struct drm_output_state *state_output,
659 struct drm_plane *plane);
660struct drm_plane_state *
661drm_plane_state_duplicate(struct drm_output_state *state_output,
662 struct drm_plane_state *src);
663void
664drm_plane_state_free(struct drm_plane_state *state, bool force);
665void
666drm_plane_state_put_back(struct drm_plane_state *state);
667bool
668drm_plane_state_coords_for_view(struct drm_plane_state *state,
669 struct weston_view *ev);
Daniel Stonee404b722019-06-22 18:40:31 +0100670
671void
672drm_assign_planes(struct weston_output *output_base, void *repaint_data);
673
674bool
675drm_plane_is_available(struct drm_plane *plane, struct drm_output *output);