blob: 33e6637b59f49c421b789fc0aa8120d81d30c4f4 [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"
58
59#ifndef DRM_CLIENT_CAP_ASPECT_RATIO
60#define DRM_CLIENT_CAP_ASPECT_RATIO 4
61#endif
62
63#ifndef GBM_BO_USE_CURSOR
64#define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64
65#endif
66
67#ifndef GBM_BO_USE_LINEAR
68#define GBM_BO_USE_LINEAR (1 << 4)
69#endif
70
71/**
72 * A small wrapper to print information into the 'drm-backend' debug scope.
73 *
74 * The following conventions are used to print variables:
75 *
76 * - fixed uint32_t values, including Weston object IDs such as weston_output
77 * IDs, DRM object IDs such as CRTCs or properties, and GBM/DRM formats:
78 * "%lu (0x%lx)" (unsigned long) value, (unsigned long) value
79 *
80 * - fixed uint64_t values, such as DRM property values (including object IDs
81 * when used as a value):
82 * "%llu (0x%llx)" (unsigned long long) value, (unsigned long long) value
83 *
84 * - non-fixed-width signed int:
85 * "%d" value
86 *
87 * - non-fixed-width unsigned int:
88 * "%u (0x%x)" value, value
89 *
90 * - non-fixed-width unsigned long:
91 * "%lu (0x%lx)" value, value
92 *
93 * Either the integer or hexadecimal forms may be omitted if it is known that
94 * one representation is not useful (e.g. width/height in hex are rarely what
95 * you want).
96 *
97 * This is to avoid implicit widening or narrowing when we use fixed-size
98 * types: uint32_t can be resolved by either unsigned int or unsigned long
99 * on a 32-bit system but only unsigned int on a 64-bit system, with uint64_t
100 * being unsigned long long on a 32-bit system and unsigned long on a 64-bit
101 * system. To avoid confusing side effects, we explicitly cast to the widest
102 * possible type and use a matching format specifier.
103 */
104#define drm_debug(b, ...) \
105 weston_log_scope_printf((b)->debug, __VA_ARGS__)
106
107#define MAX_CLONED_CONNECTORS 4
108
109/**
110 * aspect ratio info taken from the drmModeModeInfo flag bits 19-22,
111 * which should be used to fill the aspect ratio field in weston_mode.
112 */
113#define DRM_MODE_FLAG_PIC_AR_BITS_POS 19
114#ifndef DRM_MODE_FLAG_PIC_AR_MASK
115#define DRM_MODE_FLAG_PIC_AR_MASK (0xF << DRM_MODE_FLAG_PIC_AR_BITS_POS)
116#endif
117
118/**
119 * Represents the values of an enum-type KMS property
120 */
121struct drm_property_enum_info {
122 const char *name; /**< name as string (static, not freed) */
123 bool valid; /**< true if value is supported; ignore if false */
124 uint64_t value; /**< raw value */
125};
126
127/**
128 * Holds information on a DRM property, including its ID and the enum
129 * values it holds.
130 *
131 * DRM properties are allocated dynamically, and maintained as DRM objects
132 * within the normal object ID space; they thus do not have a stable ID
133 * to refer to. This includes enum values, which must be referred to by
134 * integer values, but these are not stable.
135 *
136 * drm_property_info allows a cache to be maintained where Weston can use
137 * enum values internally to refer to properties, with the mapping to DRM
138 * ID values being maintained internally.
139 */
140struct drm_property_info {
141 const char *name; /**< name as string (static, not freed) */
142 uint32_t prop_id; /**< KMS property object ID */
143 unsigned int num_enum_values; /**< number of enum values */
144 struct drm_property_enum_info *enum_values; /**< array of enum values */
145};
146
147/**
148 * List of properties attached to DRM planes
149 */
150enum wdrm_plane_property {
151 WDRM_PLANE_TYPE = 0,
152 WDRM_PLANE_SRC_X,
153 WDRM_PLANE_SRC_Y,
154 WDRM_PLANE_SRC_W,
155 WDRM_PLANE_SRC_H,
156 WDRM_PLANE_CRTC_X,
157 WDRM_PLANE_CRTC_Y,
158 WDRM_PLANE_CRTC_W,
159 WDRM_PLANE_CRTC_H,
160 WDRM_PLANE_FB_ID,
161 WDRM_PLANE_CRTC_ID,
162 WDRM_PLANE_IN_FORMATS,
163 WDRM_PLANE_IN_FENCE_FD,
164 WDRM_PLANE_FB_DAMAGE_CLIPS,
165 WDRM_PLANE__COUNT
166};
167
168/**
169 * Possible values for the WDRM_PLANE_TYPE property.
170 */
171enum wdrm_plane_type {
172 WDRM_PLANE_TYPE_PRIMARY = 0,
173 WDRM_PLANE_TYPE_CURSOR,
174 WDRM_PLANE_TYPE_OVERLAY,
175 WDRM_PLANE_TYPE__COUNT
176};
177
178/**
179 * List of properties attached to a DRM connector
180 */
181enum wdrm_connector_property {
182 WDRM_CONNECTOR_EDID = 0,
183 WDRM_CONNECTOR_DPMS,
184 WDRM_CONNECTOR_CRTC_ID,
185 WDRM_CONNECTOR_NON_DESKTOP,
186 WDRM_CONNECTOR__COUNT
187};
188
189enum wdrm_dpms_state {
190 WDRM_DPMS_STATE_OFF = 0,
191 WDRM_DPMS_STATE_ON,
192 WDRM_DPMS_STATE_STANDBY, /* unused */
193 WDRM_DPMS_STATE_SUSPEND, /* unused */
194 WDRM_DPMS_STATE__COUNT
195};
196
197/**
198 * List of properties attached to DRM CRTCs
199 */
200enum wdrm_crtc_property {
201 WDRM_CRTC_MODE_ID = 0,
202 WDRM_CRTC_ACTIVE,
203 WDRM_CRTC__COUNT
204};
205
206struct drm_backend {
207 struct weston_backend base;
208 struct weston_compositor *compositor;
209
210 struct udev *udev;
211 struct wl_event_source *drm_source;
212
213 struct udev_monitor *udev_monitor;
214 struct wl_event_source *udev_drm_source;
215
216 struct {
217 int id;
218 int fd;
219 char *filename;
220 dev_t devnum;
221 } drm;
222 struct gbm_device *gbm;
223 struct wl_listener session_listener;
224 uint32_t gbm_format;
225
226 /* we need these parameters in order to not fail drmModeAddFB2()
227 * due to out of bounds dimensions, and then mistakenly set
228 * sprites_are_broken:
229 */
230 int min_width, max_width;
231 int min_height, max_height;
232
233 struct wl_list plane_list;
234 int sprites_are_broken;
235 int sprites_hidden;
236
237 void *repaint_data;
238
239 bool state_invalid;
240
241 /* CRTC IDs not used by any enabled output. */
242 struct wl_array unused_crtcs;
243
244 int cursors_are_broken;
245
246 bool universal_planes;
247 bool atomic_modeset;
248
249 bool use_pixman;
250 bool use_pixman_shadow;
251
252 struct udev_input input;
253
254 int32_t cursor_width;
255 int32_t cursor_height;
256
257 uint32_t pageflip_timeout;
258
259 bool shutting_down;
260
261 bool aspect_ratio_supported;
262
263 bool fb_modifiers;
264
265 struct weston_log_scope *debug;
266};
267
268struct drm_mode {
269 struct weston_mode base;
270 drmModeModeInfo mode_info;
271 uint32_t blob_id;
272};
273
274enum drm_fb_type {
275 BUFFER_INVALID = 0, /**< never used */
276 BUFFER_CLIENT, /**< directly sourced from client */
277 BUFFER_DMABUF, /**< imported from linux_dmabuf client */
278 BUFFER_PIXMAN_DUMB, /**< internal Pixman rendering */
279 BUFFER_GBM_SURFACE, /**< internal EGL rendering */
280 BUFFER_CURSOR, /**< internal cursor buffer */
281};
282
283struct drm_fb {
284 enum drm_fb_type type;
285
286 int refcnt;
287
288 uint32_t fb_id, size;
289 uint32_t handles[4];
290 uint32_t strides[4];
291 uint32_t offsets[4];
292 int num_planes;
293 const struct pixel_format_info *format;
294 uint64_t modifier;
295 int width, height;
296 int fd;
297 struct weston_buffer_reference buffer_ref;
298 struct weston_buffer_release_reference buffer_release_ref;
299
300 /* Used by gbm fbs */
301 struct gbm_bo *bo;
302 struct gbm_surface *gbm_surface;
303
304 /* Used by dumb fbs */
305 void *map;
306};
307
308struct drm_edid {
309 char eisa_id[13];
310 char monitor_name[13];
311 char pnp_id[5];
312 char serial_number[13];
313};
314
315/**
316 * Pending state holds one or more drm_output_state structures, collected from
317 * performing repaint. This pending state is transient, and only lives between
318 * beginning a repaint group and flushing the results: after flush, each
319 * output state will complete and be retired separately.
320 */
321struct drm_pending_state {
322 struct drm_backend *backend;
323 struct wl_list output_list;
324};
325
326/*
327 * Output state holds the dynamic state for one Weston output, i.e. a KMS CRTC,
328 * plus >= 1 each of encoder/connector/plane. Since everything but the planes
329 * is currently statically assigned per-output, we mainly use this to track
330 * plane state.
331 *
332 * pending_state is set when the output state is owned by a pending_state,
333 * i.e. when it is being constructed and has not yet been applied. When the
334 * output state has been applied, the owning pending_state is freed.
335 */
336struct drm_output_state {
337 struct drm_pending_state *pending_state;
338 struct drm_output *output;
339 struct wl_list link;
340 enum dpms_enum dpms;
341 struct wl_list plane_list;
342};
343
344/**
345 * Plane state holds the dynamic state for a plane: where it is positioned,
346 * and which buffer it is currently displaying.
347 *
348 * The plane state is owned by an output state, except when setting an initial
349 * state. See drm_output_state for notes on state object lifetime.
350 */
351struct drm_plane_state {
352 struct drm_plane *plane;
353 struct drm_output *output;
354 struct drm_output_state *output_state;
355
356 struct drm_fb *fb;
357
358 struct weston_view *ev; /**< maintained for drm_assign_planes only */
359
360 int32_t src_x, src_y;
361 uint32_t src_w, src_h;
362 int32_t dest_x, dest_y;
363 uint32_t dest_w, dest_h;
364
365 bool complete;
366
367 /* We don't own the fd, so we shouldn't close it */
368 int in_fence_fd;
369
370 pixman_region32_t damage; /* damage to kernel */
371
372 struct wl_list link; /* drm_output_state::plane_list */
373};
374
375/**
376 * A plane represents one buffer, positioned within a CRTC, and stacked
377 * relative to other planes on the same CRTC.
378 *
379 * Each CRTC has a 'primary plane', which use used to display the classic
380 * framebuffer contents, as accessed through the legacy drmModeSetCrtc
381 * call (which combines setting the CRTC's actual physical mode, and the
382 * properties of the primary plane).
383 *
384 * The cursor plane also has its own alternate legacy API.
385 *
386 * Other planes are used opportunistically to display content we do not
387 * wish to blit into the primary plane. These non-primary/cursor planes
388 * are referred to as 'sprites'.
389 */
390struct drm_plane {
391 struct weston_plane base;
392
393 struct drm_backend *backend;
394
395 enum wdrm_plane_type type;
396
397 uint32_t possible_crtcs;
398 uint32_t plane_id;
399 uint32_t count_formats;
400
401 struct drm_property_info props[WDRM_PLANE__COUNT];
402
403 /* The last state submitted to the kernel for this plane. */
404 struct drm_plane_state *state_cur;
405
406 struct wl_list link;
407
408 struct {
409 uint32_t format;
410 uint32_t count_modifiers;
411 uint64_t *modifiers;
412 } formats[];
413};
414
415struct drm_head {
416 struct weston_head base;
417 struct drm_backend *backend;
418
419 drmModeConnector *connector;
420 uint32_t connector_id;
421 struct drm_edid edid;
422
423 /* Holds the properties for the connector */
424 struct drm_property_info props_conn[WDRM_CONNECTOR__COUNT];
425
426 struct backlight *backlight;
427
428 drmModeModeInfo inherited_mode; /**< Original mode on the connector */
429 uint32_t inherited_crtc_id; /**< Original CRTC assignment */
430};
431
432struct drm_output {
433 struct weston_output base;
434 struct drm_backend *backend;
435
436 uint32_t crtc_id; /* object ID to pass to DRM functions */
437 int pipe; /* index of CRTC in resource array / bitmasks */
438
439 /* Holds the properties for the CRTC */
440 struct drm_property_info props_crtc[WDRM_CRTC__COUNT];
441
442 int page_flip_pending;
443 int atomic_complete_pending;
444 int destroy_pending;
445 int disable_pending;
446 int dpms_off_pending;
447
448 struct drm_fb *gbm_cursor_fb[2];
449 struct drm_plane *cursor_plane;
450 struct weston_view *cursor_view;
451 int current_cursor;
452
453 struct gbm_surface *gbm_surface;
454 uint32_t gbm_format;
455 uint32_t gbm_bo_flags;
456
457 /* Plane being displayed directly on the CRTC */
458 struct drm_plane *scanout_plane;
459
460 /* The last state submitted to the kernel for this CRTC. */
461 struct drm_output_state *state_cur;
462 /* The previously-submitted state, where the hardware has not
463 * yet acknowledged completion of state_cur. */
464 struct drm_output_state *state_last;
465
466 struct drm_fb *dumb[2];
467 pixman_image_t *image[2];
468 int current_image;
469 pixman_region32_t previous_damage;
470
471 struct vaapi_recorder *recorder;
472 struct wl_listener recorder_frame_listener;
473
474 struct wl_event_source *pageflip_timer;
475
476 bool virtual;
477
478 submit_frame_cb virtual_submit_frame;
479};
480
481static inline struct drm_head *
482to_drm_head(struct weston_head *base)
483{
484 return container_of(base, struct drm_head, base);
485}
486
487static inline struct drm_output *
488to_drm_output(struct weston_output *base)
489{
490 return container_of(base, struct drm_output, base);
491}
492
493static inline struct drm_backend *
494to_drm_backend(struct weston_compositor *base)
495{
496 return container_of(base->backend, struct drm_backend, base);
497}
498
499static inline struct drm_mode *
500to_drm_mode(struct weston_mode *base)
501{
502 return container_of(base, struct drm_mode, base);
503}
Daniel Stonefbe6c1d2019-06-17 16:04:26 +0100504
Daniel Stone4c2fc702019-06-18 11:12:07 +0100505struct drm_output *
506drm_output_find_by_crtc(struct drm_backend *b, uint32_t crtc_id);
507
508struct drm_head *
509drm_head_find_by_connector(struct drm_backend *backend, uint32_t connector_id);
510
Daniel Stonefbe6c1d2019-06-17 16:04:26 +0100511int
512drm_mode_ensure_blob(struct drm_backend *backend, struct drm_mode *mode);
513
514struct drm_mode *
515drm_output_choose_mode(struct drm_output *output,
516 struct weston_mode *target_mode);
517void
518update_head_from_connector(struct drm_head *head,
519 drmModeObjectProperties *props);
520
521void
522drm_mode_list_destroy(struct drm_backend *backend, struct wl_list *mode_list);
523
524void
525drm_output_print_modes(struct drm_output *output);
526
527int
528drm_output_set_mode(struct weston_output *base,
529 enum weston_drm_backend_output_mode mode,
530 const char *modeline);
531
Daniel Stone4c2fc702019-06-18 11:12:07 +0100532void
533drm_property_info_populate(struct drm_backend *b,
534 const struct drm_property_info *src,
535 struct drm_property_info *info,
536 unsigned int num_infos,
537 drmModeObjectProperties *props);
Daniel Stonefbe6c1d2019-06-17 16:04:26 +0100538uint64_t
539drm_property_get_value(struct drm_property_info *info,
540 const drmModeObjectProperties *props,
541 uint64_t def);
Daniel Stone4c2fc702019-06-18 11:12:07 +0100542int
543drm_plane_populate_formats(struct drm_plane *plane, const drmModePlane *kplane,
544 const drmModeObjectProperties *props);
545void
546drm_property_info_free(struct drm_property_info *info, int num_props);
547
548extern struct drm_property_enum_info plane_type_enums[];
549extern const struct drm_property_info plane_props[];
550extern struct drm_property_enum_info dpms_state_enums[];
551extern const struct drm_property_info connector_props[];
552extern const struct drm_property_info crtc_props[];
553
554int
555init_kms_caps(struct drm_backend *b);
556
557int
558drm_pending_state_test(struct drm_pending_state *pending_state);
559int
560drm_pending_state_apply(struct drm_pending_state *pending_state);
561int
562drm_pending_state_apply_sync(struct drm_pending_state *pending_state);
563
564void
565drm_output_set_gamma(struct weston_output *output_base,
566 uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b);
567
568void
569drm_output_update_msc(struct drm_output *output, unsigned int seq);
570void
571drm_output_update_complete(struct drm_output *output, uint32_t flags,
572 unsigned int sec, unsigned int usec);
573int
574on_drm_input(int fd, uint32_t mask, void *data);
575
576struct drm_plane_state *
577drm_output_state_get_existing_plane(struct drm_output_state *state_output,
578 struct drm_plane *plane);
579void
580drm_plane_state_free(struct drm_plane_state *state, bool force);
581void
582drm_output_state_free(struct drm_output_state *state);
583void
584drm_pending_state_free(struct drm_pending_state *pending_state);