blob: 855baf1514e35159001334c8724d01bd51b5d9e2 [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
Stefan Agnerccf24072019-07-09 22:02:00 +020050#ifdef BUILD_DRM_GBM
Daniel Stonedd1bc502019-06-17 12:13:46 +010051#include <gbm.h>
Stefan Agnerccf24072019-07-09 22:02:00 +020052#endif
Daniel Stonedd1bc502019-06-17 12:13:46 +010053#include <libudev.h>
54
55#include <libweston/libweston.h>
56#include <libweston/backend-drm.h>
Marius Vladc901e892019-06-21 22:49:18 +030057#include <libweston/weston-log.h>
Daniel Stonedd1bc502019-06-17 12:13:46 +010058#include "shared/helpers.h"
59#include "libinput-seat.h"
Marius Vlade41c1bf2019-07-16 23:11:25 +030060#include "backend.h"
Marius Vlada72e3712019-07-10 13:46:39 +030061#include "libweston-internal.h"
Daniel Stonedd1bc502019-06-17 12:13:46 +010062
63#ifndef DRM_CLIENT_CAP_ASPECT_RATIO
64#define DRM_CLIENT_CAP_ASPECT_RATIO 4
65#endif
66
67#ifndef GBM_BO_USE_CURSOR
68#define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64
69#endif
70
71#ifndef GBM_BO_USE_LINEAR
72#define GBM_BO_USE_LINEAR (1 << 4)
73#endif
74
Marius Vladcdd6fa22019-08-29 20:42:00 +030075#ifndef DRM_PLANE_ZPOS_INVALID_PLANE
76#define DRM_PLANE_ZPOS_INVALID_PLANE 0xffffffffffffffffULL
77#endif
78
Daniel Stonedd1bc502019-06-17 12:13:46 +010079/**
80 * A small wrapper to print information into the 'drm-backend' debug scope.
81 *
82 * The following conventions are used to print variables:
83 *
84 * - fixed uint32_t values, including Weston object IDs such as weston_output
85 * IDs, DRM object IDs such as CRTCs or properties, and GBM/DRM formats:
86 * "%lu (0x%lx)" (unsigned long) value, (unsigned long) value
87 *
88 * - fixed uint64_t values, such as DRM property values (including object IDs
89 * when used as a value):
90 * "%llu (0x%llx)" (unsigned long long) value, (unsigned long long) value
91 *
92 * - non-fixed-width signed int:
93 * "%d" value
94 *
95 * - non-fixed-width unsigned int:
96 * "%u (0x%x)" value, value
97 *
98 * - non-fixed-width unsigned long:
99 * "%lu (0x%lx)" value, value
100 *
101 * Either the integer or hexadecimal forms may be omitted if it is known that
102 * one representation is not useful (e.g. width/height in hex are rarely what
103 * you want).
104 *
105 * This is to avoid implicit widening or narrowing when we use fixed-size
106 * types: uint32_t can be resolved by either unsigned int or unsigned long
107 * on a 32-bit system but only unsigned int on a 64-bit system, with uint64_t
108 * being unsigned long long on a 32-bit system and unsigned long on a 64-bit
109 * system. To avoid confusing side effects, we explicitly cast to the widest
110 * possible type and use a matching format specifier.
111 */
112#define drm_debug(b, ...) \
113 weston_log_scope_printf((b)->debug, __VA_ARGS__)
114
115#define MAX_CLONED_CONNECTORS 4
116
Stefan Agner723c6a12019-12-09 13:06:36 +0100117#ifndef DRM_MODE_PICTURE_ASPECT_64_27
118#define DRM_MODE_PICTURE_ASPECT_64_27 3
119#define DRM_MODE_FLAG_PIC_AR_64_27 \
120 (DRM_MODE_PICTURE_ASPECT_64_27<<19)
121#endif
122#ifndef DRM_MODE_PICTURE_ASPECT_256_135
123#define DRM_MODE_PICTURE_ASPECT_256_135 4
124#define DRM_MODE_FLAG_PIC_AR_256_135 \
125 (DRM_MODE_PICTURE_ASPECT_256_135<<19)
126#endif
127
128
Daniel Stonedd1bc502019-06-17 12:13:46 +0100129/**
Daniel Stonedd1bc502019-06-17 12:13:46 +0100130 * Represents the values of an enum-type KMS property
131 */
132struct drm_property_enum_info {
133 const char *name; /**< name as string (static, not freed) */
134 bool valid; /**< true if value is supported; ignore if false */
135 uint64_t value; /**< raw value */
136};
137
138/**
139 * Holds information on a DRM property, including its ID and the enum
140 * values it holds.
141 *
142 * DRM properties are allocated dynamically, and maintained as DRM objects
143 * within the normal object ID space; they thus do not have a stable ID
144 * to refer to. This includes enum values, which must be referred to by
145 * integer values, but these are not stable.
146 *
147 * drm_property_info allows a cache to be maintained where Weston can use
148 * enum values internally to refer to properties, with the mapping to DRM
149 * ID values being maintained internally.
150 */
151struct drm_property_info {
152 const char *name; /**< name as string (static, not freed) */
153 uint32_t prop_id; /**< KMS property object ID */
Marius Vlad1accffe2019-11-01 12:00:09 +0200154 uint32_t flags;
Daniel Stonedd1bc502019-06-17 12:13:46 +0100155 unsigned int num_enum_values; /**< number of enum values */
156 struct drm_property_enum_info *enum_values; /**< array of enum values */
Marius Vlad1accffe2019-11-01 12:00:09 +0200157 unsigned int num_range_values;
158 uint64_t range_values[2];
Daniel Stonedd1bc502019-06-17 12:13:46 +0100159};
160
161/**
162 * List of properties attached to DRM planes
163 */
164enum wdrm_plane_property {
165 WDRM_PLANE_TYPE = 0,
166 WDRM_PLANE_SRC_X,
167 WDRM_PLANE_SRC_Y,
168 WDRM_PLANE_SRC_W,
169 WDRM_PLANE_SRC_H,
170 WDRM_PLANE_CRTC_X,
171 WDRM_PLANE_CRTC_Y,
172 WDRM_PLANE_CRTC_W,
173 WDRM_PLANE_CRTC_H,
174 WDRM_PLANE_FB_ID,
175 WDRM_PLANE_CRTC_ID,
176 WDRM_PLANE_IN_FORMATS,
177 WDRM_PLANE_IN_FENCE_FD,
178 WDRM_PLANE_FB_DAMAGE_CLIPS,
Marius Vladcdd6fa22019-08-29 20:42:00 +0300179 WDRM_PLANE_ZPOS,
Daniel Stonedd1bc502019-06-17 12:13:46 +0100180 WDRM_PLANE__COUNT
181};
182
183/**
184 * Possible values for the WDRM_PLANE_TYPE property.
185 */
186enum wdrm_plane_type {
187 WDRM_PLANE_TYPE_PRIMARY = 0,
188 WDRM_PLANE_TYPE_CURSOR,
189 WDRM_PLANE_TYPE_OVERLAY,
190 WDRM_PLANE_TYPE__COUNT
191};
192
193/**
194 * List of properties attached to a DRM connector
195 */
196enum wdrm_connector_property {
197 WDRM_CONNECTOR_EDID = 0,
198 WDRM_CONNECTOR_DPMS,
199 WDRM_CONNECTOR_CRTC_ID,
200 WDRM_CONNECTOR_NON_DESKTOP,
Ankit Nautiyala344fe32019-05-14 18:36:08 +0530201 WDRM_CONNECTOR_CONTENT_PROTECTION,
202 WDRM_CONNECTOR_HDCP_CONTENT_TYPE,
Lucas Stach72e7a1e2019-11-25 23:31:57 +0000203 WDRM_CONNECTOR_PANEL_ORIENTATION,
Daniel Stonedd1bc502019-06-17 12:13:46 +0100204 WDRM_CONNECTOR__COUNT
205};
206
Ankit Nautiyala344fe32019-05-14 18:36:08 +0530207enum wdrm_content_protection_state {
208 WDRM_CONTENT_PROTECTION_UNDESIRED = 0,
209 WDRM_CONTENT_PROTECTION_DESIRED,
210 WDRM_CONTENT_PROTECTION_ENABLED,
211 WDRM_CONTENT_PROTECTION__COUNT
212};
213
214enum wdrm_hdcp_content_type {
215 WDRM_HDCP_CONTENT_TYPE0 = 0,
216 WDRM_HDCP_CONTENT_TYPE1,
217 WDRM_HDCP_CONTENT_TYPE__COUNT
218};
219
Daniel Stonedd1bc502019-06-17 12:13:46 +0100220enum wdrm_dpms_state {
221 WDRM_DPMS_STATE_OFF = 0,
222 WDRM_DPMS_STATE_ON,
223 WDRM_DPMS_STATE_STANDBY, /* unused */
224 WDRM_DPMS_STATE_SUSPEND, /* unused */
225 WDRM_DPMS_STATE__COUNT
226};
227
Lucas Stach72e7a1e2019-11-25 23:31:57 +0000228enum wdrm_panel_orientation {
229 WDRM_PANEL_ORIENTATION_NORMAL = 0,
230 WDRM_PANEL_ORIENTATION_UPSIDE_DOWN,
231 WDRM_PANEL_ORIENTATION_LEFT_SIDE_UP,
232 WDRM_PANEL_ORIENTATION_RIGHT_SIDE_UP,
233 WDRM_PANEL_ORIENTATION__COUNT
234};
235
Daniel Stonedd1bc502019-06-17 12:13:46 +0100236/**
237 * List of properties attached to DRM CRTCs
238 */
239enum wdrm_crtc_property {
240 WDRM_CRTC_MODE_ID = 0,
241 WDRM_CRTC_ACTIVE,
242 WDRM_CRTC__COUNT
243};
244
245struct drm_backend {
246 struct weston_backend base;
247 struct weston_compositor *compositor;
248
249 struct udev *udev;
250 struct wl_event_source *drm_source;
251
252 struct udev_monitor *udev_monitor;
253 struct wl_event_source *udev_drm_source;
254
255 struct {
256 int id;
257 int fd;
258 char *filename;
259 dev_t devnum;
260 } drm;
261 struct gbm_device *gbm;
262 struct wl_listener session_listener;
263 uint32_t gbm_format;
264
265 /* we need these parameters in order to not fail drmModeAddFB2()
266 * due to out of bounds dimensions, and then mistakenly set
267 * sprites_are_broken:
268 */
269 int min_width, max_width;
270 int min_height, max_height;
271
272 struct wl_list plane_list;
Daniel Stonedd1bc502019-06-17 12:13:46 +0100273
274 void *repaint_data;
275
276 bool state_invalid;
277
278 /* CRTC IDs not used by any enabled output. */
279 struct wl_array unused_crtcs;
280
Emmanuel Gil Peyrot1b3ad092019-12-09 02:50:55 +0100281 bool sprites_are_broken;
282 bool cursors_are_broken;
Daniel Stonedd1bc502019-06-17 12:13:46 +0100283
284 bool universal_planes;
285 bool atomic_modeset;
286
287 bool use_pixman;
288 bool use_pixman_shadow;
289
290 struct udev_input input;
291
292 int32_t cursor_width;
293 int32_t cursor_height;
294
295 uint32_t pageflip_timeout;
296
297 bool shutting_down;
298
299 bool aspect_ratio_supported;
300
301 bool fb_modifiers;
302
303 struct weston_log_scope *debug;
304};
305
306struct drm_mode {
307 struct weston_mode base;
308 drmModeModeInfo mode_info;
309 uint32_t blob_id;
310};
311
312enum drm_fb_type {
313 BUFFER_INVALID = 0, /**< never used */
314 BUFFER_CLIENT, /**< directly sourced from client */
315 BUFFER_DMABUF, /**< imported from linux_dmabuf client */
316 BUFFER_PIXMAN_DUMB, /**< internal Pixman rendering */
317 BUFFER_GBM_SURFACE, /**< internal EGL rendering */
318 BUFFER_CURSOR, /**< internal cursor buffer */
319};
320
321struct drm_fb {
322 enum drm_fb_type type;
323
324 int refcnt;
325
326 uint32_t fb_id, size;
327 uint32_t handles[4];
328 uint32_t strides[4];
329 uint32_t offsets[4];
330 int num_planes;
331 const struct pixel_format_info *format;
332 uint64_t modifier;
333 int width, height;
334 int fd;
335 struct weston_buffer_reference buffer_ref;
336 struct weston_buffer_release_reference buffer_release_ref;
337
338 /* Used by gbm fbs */
339 struct gbm_bo *bo;
340 struct gbm_surface *gbm_surface;
341
342 /* Used by dumb fbs */
343 void *map;
344};
345
346struct drm_edid {
347 char eisa_id[13];
348 char monitor_name[13];
349 char pnp_id[5];
350 char serial_number[13];
351};
352
353/**
354 * Pending state holds one or more drm_output_state structures, collected from
355 * performing repaint. This pending state is transient, and only lives between
356 * beginning a repaint group and flushing the results: after flush, each
357 * output state will complete and be retired separately.
358 */
359struct drm_pending_state {
360 struct drm_backend *backend;
361 struct wl_list output_list;
362};
363
364/*
365 * Output state holds the dynamic state for one Weston output, i.e. a KMS CRTC,
366 * plus >= 1 each of encoder/connector/plane. Since everything but the planes
367 * is currently statically assigned per-output, we mainly use this to track
368 * plane state.
369 *
370 * pending_state is set when the output state is owned by a pending_state,
371 * i.e. when it is being constructed and has not yet been applied. When the
372 * output state has been applied, the owning pending_state is freed.
373 */
374struct drm_output_state {
375 struct drm_pending_state *pending_state;
376 struct drm_output *output;
377 struct wl_list link;
378 enum dpms_enum dpms;
Ankit Nautiyala344fe32019-05-14 18:36:08 +0530379 enum weston_hdcp_protection protection;
Daniel Stonedd1bc502019-06-17 12:13:46 +0100380 struct wl_list plane_list;
381};
382
383/**
Marius Vlad2538aac2019-10-14 11:05:30 +0300384 * An instance of this class is created each time we believe we have a plane
385 * suitable to be used by a view as a direct scan-out. The list is initalized
386 * and populated locally.
387 */
388struct drm_plane_zpos {
389 struct drm_plane *plane;
390 struct wl_list link; /**< :candidate_plane_zpos_list */
391};
392
393/**
Daniel Stonedd1bc502019-06-17 12:13:46 +0100394 * Plane state holds the dynamic state for a plane: where it is positioned,
395 * and which buffer it is currently displaying.
396 *
397 * The plane state is owned by an output state, except when setting an initial
398 * state. See drm_output_state for notes on state object lifetime.
399 */
400struct drm_plane_state {
401 struct drm_plane *plane;
402 struct drm_output *output;
403 struct drm_output_state *output_state;
404
405 struct drm_fb *fb;
406
407 struct weston_view *ev; /**< maintained for drm_assign_planes only */
408
409 int32_t src_x, src_y;
410 uint32_t src_w, src_h;
411 int32_t dest_x, dest_y;
412 uint32_t dest_w, dest_h;
413
Marius Vladcdd6fa22019-08-29 20:42:00 +0300414 uint64_t zpos;
415
Daniel Stonedd1bc502019-06-17 12:13:46 +0100416 bool complete;
417
418 /* We don't own the fd, so we shouldn't close it */
419 int in_fence_fd;
420
421 pixman_region32_t damage; /* damage to kernel */
422
423 struct wl_list link; /* drm_output_state::plane_list */
424};
425
426/**
427 * A plane represents one buffer, positioned within a CRTC, and stacked
428 * relative to other planes on the same CRTC.
429 *
430 * Each CRTC has a 'primary plane', which use used to display the classic
431 * framebuffer contents, as accessed through the legacy drmModeSetCrtc
432 * call (which combines setting the CRTC's actual physical mode, and the
433 * properties of the primary plane).
434 *
435 * The cursor plane also has its own alternate legacy API.
436 *
437 * Other planes are used opportunistically to display content we do not
438 * wish to blit into the primary plane. These non-primary/cursor planes
439 * are referred to as 'sprites'.
440 */
441struct drm_plane {
442 struct weston_plane base;
443
444 struct drm_backend *backend;
445
446 enum wdrm_plane_type type;
447
448 uint32_t possible_crtcs;
449 uint32_t plane_id;
450 uint32_t count_formats;
451
452 struct drm_property_info props[WDRM_PLANE__COUNT];
453
454 /* The last state submitted to the kernel for this plane. */
455 struct drm_plane_state *state_cur;
456
Marius Vladcdd6fa22019-08-29 20:42:00 +0300457 uint64_t zpos_min;
458 uint64_t zpos_max;
459
Daniel Stonedd1bc502019-06-17 12:13:46 +0100460 struct wl_list link;
461
462 struct {
463 uint32_t format;
464 uint32_t count_modifiers;
465 uint64_t *modifiers;
466 } formats[];
467};
468
469struct drm_head {
470 struct weston_head base;
471 struct drm_backend *backend;
472
473 drmModeConnector *connector;
474 uint32_t connector_id;
475 struct drm_edid edid;
476
477 /* Holds the properties for the connector */
478 struct drm_property_info props_conn[WDRM_CONNECTOR__COUNT];
479
480 struct backlight *backlight;
481
482 drmModeModeInfo inherited_mode; /**< Original mode on the connector */
483 uint32_t inherited_crtc_id; /**< Original CRTC assignment */
484};
485
486struct drm_output {
487 struct weston_output base;
488 struct drm_backend *backend;
489
490 uint32_t crtc_id; /* object ID to pass to DRM functions */
491 int pipe; /* index of CRTC in resource array / bitmasks */
492
493 /* Holds the properties for the CRTC */
494 struct drm_property_info props_crtc[WDRM_CRTC__COUNT];
495
Emmanuel Gil Peyrot1b3ad092019-12-09 02:50:55 +0100496 bool page_flip_pending;
497 bool atomic_complete_pending;
498 bool destroy_pending;
499 bool disable_pending;
500 bool dpms_off_pending;
Daniel Stonedd1bc502019-06-17 12:13:46 +0100501
Stefan Agner974390a2019-07-08 00:42:05 +0200502 uint32_t gbm_cursor_handle[2];
Daniel Stonedd1bc502019-06-17 12:13:46 +0100503 struct drm_fb *gbm_cursor_fb[2];
504 struct drm_plane *cursor_plane;
505 struct weston_view *cursor_view;
506 int current_cursor;
507
508 struct gbm_surface *gbm_surface;
509 uint32_t gbm_format;
510 uint32_t gbm_bo_flags;
511
512 /* Plane being displayed directly on the CRTC */
513 struct drm_plane *scanout_plane;
514
515 /* The last state submitted to the kernel for this CRTC. */
516 struct drm_output_state *state_cur;
517 /* The previously-submitted state, where the hardware has not
518 * yet acknowledged completion of state_cur. */
519 struct drm_output_state *state_last;
520
521 struct drm_fb *dumb[2];
522 pixman_image_t *image[2];
523 int current_image;
524 pixman_region32_t previous_damage;
525
526 struct vaapi_recorder *recorder;
527 struct wl_listener recorder_frame_listener;
528
529 struct wl_event_source *pageflip_timer;
530
531 bool virtual;
532
533 submit_frame_cb virtual_submit_frame;
534};
535
536static inline struct drm_head *
537to_drm_head(struct weston_head *base)
538{
539 return container_of(base, struct drm_head, base);
540}
541
542static inline struct drm_output *
543to_drm_output(struct weston_output *base)
544{
545 return container_of(base, struct drm_output, base);
546}
547
548static inline struct drm_backend *
549to_drm_backend(struct weston_compositor *base)
550{
551 return container_of(base->backend, struct drm_backend, base);
552}
553
554static inline struct drm_mode *
555to_drm_mode(struct weston_mode *base)
556{
557 return container_of(base, struct drm_mode, base);
558}
Daniel Stonefbe6c1d2019-06-17 16:04:26 +0100559
Marius Vlad3dea57a2019-09-27 20:45:41 +0300560static inline const char *
561drm_output_get_plane_type_name(struct drm_plane *p)
562{
563 switch (p->type) {
564 case WDRM_PLANE_TYPE_PRIMARY:
565 return "primary";
566 case WDRM_PLANE_TYPE_CURSOR:
567 return "cursor";
568 case WDRM_PLANE_TYPE_OVERLAY:
569 return "overlay";
570 default:
571 assert(0);
572 break;
573 }
574}
575
Daniel Stone4c2fc702019-06-18 11:12:07 +0100576struct drm_output *
577drm_output_find_by_crtc(struct drm_backend *b, uint32_t crtc_id);
578
579struct drm_head *
580drm_head_find_by_connector(struct drm_backend *backend, uint32_t connector_id);
581
Daniel Stone7580b3c2019-06-18 11:16:53 +0100582static inline bool
583drm_view_transform_supported(struct weston_view *ev, struct weston_output *output)
584{
585 struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
586
587 /* This will incorrectly disallow cases where the combination of
588 * buffer and view transformations match the output transform.
589 * Fixing this requires a full analysis of the transformation
590 * chain. */
591 if (ev->transform.enabled &&
592 ev->transform.matrix.type >= WESTON_MATRIX_TRANSFORM_ROTATE)
593 return false;
594
595 if (viewport->buffer.transform != output->transform)
596 return false;
597
598 return true;
599}
600
Daniel Stonefbe6c1d2019-06-17 16:04:26 +0100601int
602drm_mode_ensure_blob(struct drm_backend *backend, struct drm_mode *mode);
603
604struct drm_mode *
605drm_output_choose_mode(struct drm_output *output,
606 struct weston_mode *target_mode);
607void
608update_head_from_connector(struct drm_head *head,
609 drmModeObjectProperties *props);
610
611void
612drm_mode_list_destroy(struct drm_backend *backend, struct wl_list *mode_list);
613
614void
615drm_output_print_modes(struct drm_output *output);
616
617int
618drm_output_set_mode(struct weston_output *base,
619 enum weston_drm_backend_output_mode mode,
620 const char *modeline);
621
Daniel Stone4c2fc702019-06-18 11:12:07 +0100622void
623drm_property_info_populate(struct drm_backend *b,
624 const struct drm_property_info *src,
625 struct drm_property_info *info,
626 unsigned int num_infos,
627 drmModeObjectProperties *props);
Daniel Stonefbe6c1d2019-06-17 16:04:26 +0100628uint64_t
629drm_property_get_value(struct drm_property_info *info,
630 const drmModeObjectProperties *props,
631 uint64_t def);
Marius Vlad1accffe2019-11-01 12:00:09 +0200632uint64_t *
633drm_property_get_range_values(struct drm_property_info *info,
634 const drmModeObjectProperties *props);
Daniel Stone4c2fc702019-06-18 11:12:07 +0100635int
636drm_plane_populate_formats(struct drm_plane *plane, const drmModePlane *kplane,
637 const drmModeObjectProperties *props);
638void
639drm_property_info_free(struct drm_property_info *info, int num_props);
640
641extern struct drm_property_enum_info plane_type_enums[];
642extern const struct drm_property_info plane_props[];
643extern struct drm_property_enum_info dpms_state_enums[];
Ankit Nautiyala344fe32019-05-14 18:36:08 +0530644extern struct drm_property_enum_info content_protection_enums[];
645extern struct drm_property_enum_info hdcp_content_type_enums[];
Daniel Stone4c2fc702019-06-18 11:12:07 +0100646extern const struct drm_property_info connector_props[];
647extern const struct drm_property_info crtc_props[];
648
649int
650init_kms_caps(struct drm_backend *b);
651
652int
653drm_pending_state_test(struct drm_pending_state *pending_state);
654int
655drm_pending_state_apply(struct drm_pending_state *pending_state);
656int
657drm_pending_state_apply_sync(struct drm_pending_state *pending_state);
658
659void
660drm_output_set_gamma(struct weston_output *output_base,
661 uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b);
662
663void
664drm_output_update_msc(struct drm_output *output, unsigned int seq);
665void
666drm_output_update_complete(struct drm_output *output, uint32_t flags,
667 unsigned int sec, unsigned int usec);
668int
669on_drm_input(int fd, uint32_t mask, void *data);
670
671struct drm_plane_state *
672drm_output_state_get_existing_plane(struct drm_output_state *state_output,
673 struct drm_plane *plane);
674void
675drm_plane_state_free(struct drm_plane_state *state, bool force);
676void
677drm_output_state_free(struct drm_output_state *state);
678void
679drm_pending_state_free(struct drm_pending_state *pending_state);
Daniel Stone7580b3c2019-06-18 11:16:53 +0100680
681struct drm_fb *
682drm_fb_ref(struct drm_fb *fb);
683void
684drm_fb_unref(struct drm_fb *fb);
685
686struct drm_fb *
687drm_fb_create_dumb(struct drm_backend *b, int width, int height,
688 uint32_t format);
689struct drm_fb *
690drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
691 bool is_opaque, enum drm_fb_type type);
Daniel Stone6b466f22019-06-18 11:30:54 +0100692
Stefan Agnerccf24072019-07-09 22:02:00 +0200693#ifdef BUILD_DRM_GBM
694extern struct drm_fb *
695drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev);
Marius Vlad81bada52019-11-11 00:27:17 +0200696extern bool
697drm_can_scanout_dmabuf(struct weston_compositor *ec,
698 struct linux_dmabuf_buffer *dmabuf);
Stefan Agnerccf24072019-07-09 22:02:00 +0200699#else
700static inline struct drm_fb *
701drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev)
702{
703 return NULL;
704}
Marius Vlad81bada52019-11-11 00:27:17 +0200705static inline bool
706drm_can_scanout_dmabuf(struct weston_compositor *ec,
707 struct linux_dmabuf_buffer *dmabuf)
708{
709 return false;
710}
Stefan Agnerccf24072019-07-09 22:02:00 +0200711#endif
Daniel Stone6b466f22019-06-18 11:30:54 +0100712
713struct drm_pending_state *
714drm_pending_state_alloc(struct drm_backend *backend);
715void
716drm_pending_state_free(struct drm_pending_state *pending_state);
717struct drm_output_state *
718drm_pending_state_get_output(struct drm_pending_state *pending_state,
719 struct drm_output *output);
720
721
722/**
723 * Mode for drm_output_state_duplicate.
724 */
725enum drm_output_state_duplicate_mode {
726 DRM_OUTPUT_STATE_CLEAR_PLANES, /**< reset all planes to off */
727 DRM_OUTPUT_STATE_PRESERVE_PLANES, /**< preserve plane state */
728};
729
730struct drm_output_state *
731drm_output_state_alloc(struct drm_output *output,
732 struct drm_pending_state *pending_state);
733struct drm_output_state *
734drm_output_state_duplicate(struct drm_output_state *src,
735 struct drm_pending_state *pending_state,
736 enum drm_output_state_duplicate_mode plane_mode);
737void
738drm_output_state_free(struct drm_output_state *state);
739struct drm_plane_state *
740drm_output_state_get_plane(struct drm_output_state *state_output,
741 struct drm_plane *plane);
742struct drm_plane_state *
743drm_output_state_get_existing_plane(struct drm_output_state *state_output,
744 struct drm_plane *plane);
745
746
747
748struct drm_plane_state *
749drm_plane_state_alloc(struct drm_output_state *state_output,
750 struct drm_plane *plane);
751struct drm_plane_state *
752drm_plane_state_duplicate(struct drm_output_state *state_output,
753 struct drm_plane_state *src);
754void
755drm_plane_state_free(struct drm_plane_state *state, bool force);
756void
757drm_plane_state_put_back(struct drm_plane_state *state);
758bool
759drm_plane_state_coords_for_view(struct drm_plane_state *state,
Marius Vlad2538aac2019-10-14 11:05:30 +0300760 struct weston_view *ev, uint64_t zpos);
Daniel Stonee404b722019-06-22 18:40:31 +0100761
762void
763drm_assign_planes(struct weston_output *output_base, void *repaint_data);
764
765bool
766drm_plane_is_available(struct drm_plane *plane, struct drm_output *output);
Stefan Agner3654c672019-07-09 00:50:30 +0200767
768void
769drm_output_render(struct drm_output_state *state, pixman_region32_t *damage);
770
771int
772parse_gbm_format(const char *s, uint32_t default_value, uint32_t *gbm_format);
773
774extern struct gl_renderer_interface *gl_renderer;
775
776#ifdef BUILD_DRM_VIRTUAL
777extern int
778drm_backend_init_virtual_output_api(struct weston_compositor *compositor);
779#else
780inline static int
781drm_backend_init_virtual_output_api(struct weston_compositor *compositor)
782{
783 return 0;
784}
785#endif
786
Stefan Agnerccf24072019-07-09 22:02:00 +0200787#ifdef BUILD_DRM_GBM
788int
789init_egl(struct drm_backend *b);
790
Stefan Agner3654c672019-07-09 00:50:30 +0200791int
792drm_output_init_egl(struct drm_output *output, struct drm_backend *b);
Stefan Agnerccf24072019-07-09 22:02:00 +0200793
Stefan Agner3654c672019-07-09 00:50:30 +0200794void
795drm_output_fini_egl(struct drm_output *output);
796
Stefan Agnerccf24072019-07-09 22:02:00 +0200797struct drm_fb *
798drm_output_render_gl(struct drm_output_state *state, pixman_region32_t *damage);
799
800void
801renderer_switch_binding(struct weston_keyboard *keyboard,
802 const struct timespec *time, uint32_t key, void *data);
803#else
804inline static int
805init_egl(struct drm_backend *b)
806{
807 weston_log("Compiled without GBM/EGL support\n");
808 return -1;
809}
810
811inline static int
812drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
813{
814 return -1;
815}
816
817inline static void
818drm_output_fini_egl(struct drm_output *output)
819{
820}
821
822inline static struct drm_fb *
823drm_output_render_gl(struct drm_output_state *state, pixman_region32_t *damage)
824{
825 return NULL;
826}
827
828inline static void
829renderer_switch_binding(struct weston_keyboard *keyboard,
830 const struct timespec *time, uint32_t key, void *data)
831{
832 weston_log("Compiled without GBM/EGL support\n");
833}
834#endif