blob: cf588674f8aacf774b6d07d1b422789000968a44 [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 Vlad95e3b0d2019-11-11 15:24:25 +000075#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
117/**
118 * aspect ratio info taken from the drmModeModeInfo flag bits 19-22,
119 * which should be used to fill the aspect ratio field in weston_mode.
120 */
121#define DRM_MODE_FLAG_PIC_AR_BITS_POS 19
122#ifndef DRM_MODE_FLAG_PIC_AR_MASK
123#define DRM_MODE_FLAG_PIC_AR_MASK (0xF << DRM_MODE_FLAG_PIC_AR_BITS_POS)
124#endif
125
126/**
127 * Represents the values of an enum-type KMS property
128 */
129struct drm_property_enum_info {
130 const char *name; /**< name as string (static, not freed) */
131 bool valid; /**< true if value is supported; ignore if false */
132 uint64_t value; /**< raw value */
133};
134
135/**
136 * Holds information on a DRM property, including its ID and the enum
137 * values it holds.
138 *
139 * DRM properties are allocated dynamically, and maintained as DRM objects
140 * within the normal object ID space; they thus do not have a stable ID
141 * to refer to. This includes enum values, which must be referred to by
142 * integer values, but these are not stable.
143 *
144 * drm_property_info allows a cache to be maintained where Weston can use
145 * enum values internally to refer to properties, with the mapping to DRM
146 * ID values being maintained internally.
147 */
148struct drm_property_info {
149 const char *name; /**< name as string (static, not freed) */
150 uint32_t prop_id; /**< KMS property object ID */
Marius Vlad95e3b0d2019-11-11 15:24:25 +0000151 uint32_t flags;
Daniel Stonedd1bc502019-06-17 12:13:46 +0100152 unsigned int num_enum_values; /**< number of enum values */
153 struct drm_property_enum_info *enum_values; /**< array of enum values */
Marius Vlad95e3b0d2019-11-11 15:24:25 +0000154 unsigned int num_range_values;
155 uint64_t range_values[2];
Daniel Stonedd1bc502019-06-17 12:13:46 +0100156};
157
158/**
159 * List of properties attached to DRM planes
160 */
161enum wdrm_plane_property {
162 WDRM_PLANE_TYPE = 0,
163 WDRM_PLANE_SRC_X,
164 WDRM_PLANE_SRC_Y,
165 WDRM_PLANE_SRC_W,
166 WDRM_PLANE_SRC_H,
167 WDRM_PLANE_CRTC_X,
168 WDRM_PLANE_CRTC_Y,
169 WDRM_PLANE_CRTC_W,
170 WDRM_PLANE_CRTC_H,
171 WDRM_PLANE_FB_ID,
172 WDRM_PLANE_CRTC_ID,
173 WDRM_PLANE_IN_FORMATS,
174 WDRM_PLANE_IN_FENCE_FD,
175 WDRM_PLANE_FB_DAMAGE_CLIPS,
Marius Vlad95e3b0d2019-11-11 15:24:25 +0000176 WDRM_PLANE_ZPOS,
Daniel Stonedd1bc502019-06-17 12:13:46 +0100177 WDRM_PLANE__COUNT
178};
179
180/**
181 * Possible values for the WDRM_PLANE_TYPE property.
182 */
183enum wdrm_plane_type {
184 WDRM_PLANE_TYPE_PRIMARY = 0,
185 WDRM_PLANE_TYPE_CURSOR,
186 WDRM_PLANE_TYPE_OVERLAY,
187 WDRM_PLANE_TYPE__COUNT
188};
189
190/**
191 * List of properties attached to a DRM connector
192 */
193enum wdrm_connector_property {
194 WDRM_CONNECTOR_EDID = 0,
195 WDRM_CONNECTOR_DPMS,
196 WDRM_CONNECTOR_CRTC_ID,
197 WDRM_CONNECTOR_NON_DESKTOP,
Ankit Nautiyala344fe32019-05-14 18:36:08 +0530198 WDRM_CONNECTOR_CONTENT_PROTECTION,
199 WDRM_CONNECTOR_HDCP_CONTENT_TYPE,
Daniel Stonedd1bc502019-06-17 12:13:46 +0100200 WDRM_CONNECTOR__COUNT
201};
202
Ankit Nautiyala344fe32019-05-14 18:36:08 +0530203enum wdrm_content_protection_state {
204 WDRM_CONTENT_PROTECTION_UNDESIRED = 0,
205 WDRM_CONTENT_PROTECTION_DESIRED,
206 WDRM_CONTENT_PROTECTION_ENABLED,
207 WDRM_CONTENT_PROTECTION__COUNT
208};
209
210enum wdrm_hdcp_content_type {
211 WDRM_HDCP_CONTENT_TYPE0 = 0,
212 WDRM_HDCP_CONTENT_TYPE1,
213 WDRM_HDCP_CONTENT_TYPE__COUNT
214};
215
Daniel Stonedd1bc502019-06-17 12:13:46 +0100216enum wdrm_dpms_state {
217 WDRM_DPMS_STATE_OFF = 0,
218 WDRM_DPMS_STATE_ON,
219 WDRM_DPMS_STATE_STANDBY, /* unused */
220 WDRM_DPMS_STATE_SUSPEND, /* unused */
221 WDRM_DPMS_STATE__COUNT
222};
223
224/**
225 * List of properties attached to DRM CRTCs
226 */
227enum wdrm_crtc_property {
228 WDRM_CRTC_MODE_ID = 0,
229 WDRM_CRTC_ACTIVE,
230 WDRM_CRTC__COUNT
231};
232
233struct drm_backend {
234 struct weston_backend base;
235 struct weston_compositor *compositor;
236
237 struct udev *udev;
238 struct wl_event_source *drm_source;
239
240 struct udev_monitor *udev_monitor;
241 struct wl_event_source *udev_drm_source;
242
243 struct {
244 int id;
245 int fd;
246 char *filename;
247 dev_t devnum;
248 } drm;
249 struct gbm_device *gbm;
250 struct wl_listener session_listener;
251 uint32_t gbm_format;
252
253 /* we need these parameters in order to not fail drmModeAddFB2()
254 * due to out of bounds dimensions, and then mistakenly set
255 * sprites_are_broken:
256 */
257 int min_width, max_width;
258 int min_height, max_height;
259
260 struct wl_list plane_list;
261 int sprites_are_broken;
262 int sprites_hidden;
263
264 void *repaint_data;
265
266 bool state_invalid;
267
268 /* CRTC IDs not used by any enabled output. */
269 struct wl_array unused_crtcs;
270
271 int cursors_are_broken;
272
273 bool universal_planes;
274 bool atomic_modeset;
275
276 bool use_pixman;
277 bool use_pixman_shadow;
278
279 struct udev_input input;
280
281 int32_t cursor_width;
282 int32_t cursor_height;
283
284 uint32_t pageflip_timeout;
285
286 bool shutting_down;
287
288 bool aspect_ratio_supported;
289
290 bool fb_modifiers;
291
292 struct weston_log_scope *debug;
293};
294
295struct drm_mode {
296 struct weston_mode base;
297 drmModeModeInfo mode_info;
298 uint32_t blob_id;
299};
300
301enum drm_fb_type {
302 BUFFER_INVALID = 0, /**< never used */
303 BUFFER_CLIENT, /**< directly sourced from client */
304 BUFFER_DMABUF, /**< imported from linux_dmabuf client */
305 BUFFER_PIXMAN_DUMB, /**< internal Pixman rendering */
306 BUFFER_GBM_SURFACE, /**< internal EGL rendering */
307 BUFFER_CURSOR, /**< internal cursor buffer */
308};
309
310struct drm_fb {
311 enum drm_fb_type type;
312
313 int refcnt;
314
315 uint32_t fb_id, size;
316 uint32_t handles[4];
317 uint32_t strides[4];
318 uint32_t offsets[4];
319 int num_planes;
320 const struct pixel_format_info *format;
321 uint64_t modifier;
322 int width, height;
323 int fd;
324 struct weston_buffer_reference buffer_ref;
325 struct weston_buffer_release_reference buffer_release_ref;
326
327 /* Used by gbm fbs */
328 struct gbm_bo *bo;
329 struct gbm_surface *gbm_surface;
330
331 /* Used by dumb fbs */
332 void *map;
333};
334
335struct drm_edid {
336 char eisa_id[13];
337 char monitor_name[13];
338 char pnp_id[5];
339 char serial_number[13];
340};
341
342/**
343 * Pending state holds one or more drm_output_state structures, collected from
344 * performing repaint. This pending state is transient, and only lives between
345 * beginning a repaint group and flushing the results: after flush, each
346 * output state will complete and be retired separately.
347 */
348struct drm_pending_state {
349 struct drm_backend *backend;
350 struct wl_list output_list;
351};
352
353/*
354 * Output state holds the dynamic state for one Weston output, i.e. a KMS CRTC,
355 * plus >= 1 each of encoder/connector/plane. Since everything but the planes
356 * is currently statically assigned per-output, we mainly use this to track
357 * plane state.
358 *
359 * pending_state is set when the output state is owned by a pending_state,
360 * i.e. when it is being constructed and has not yet been applied. When the
361 * output state has been applied, the owning pending_state is freed.
362 */
363struct drm_output_state {
364 struct drm_pending_state *pending_state;
365 struct drm_output *output;
366 struct wl_list link;
367 enum dpms_enum dpms;
Ankit Nautiyala344fe32019-05-14 18:36:08 +0530368 enum weston_hdcp_protection protection;
Daniel Stonedd1bc502019-06-17 12:13:46 +0100369 struct wl_list plane_list;
370};
371
372/**
Marius Vlad95e3b0d2019-11-11 15:24:25 +0000373 * An instance of this class is created each time we believe we have a plane
374 * suitable to be used by a view as a direct scan-out. The list is initalized
375 * and populated locally.
376 */
377struct drm_plane_zpos {
378 struct drm_plane *plane;
379 struct wl_list link; /**< :candidate_plane_zpos_list */
380};
381
382/**
Daniel Stonedd1bc502019-06-17 12:13:46 +0100383 * Plane state holds the dynamic state for a plane: where it is positioned,
384 * and which buffer it is currently displaying.
385 *
386 * The plane state is owned by an output state, except when setting an initial
387 * state. See drm_output_state for notes on state object lifetime.
388 */
389struct drm_plane_state {
390 struct drm_plane *plane;
391 struct drm_output *output;
392 struct drm_output_state *output_state;
393
394 struct drm_fb *fb;
395
396 struct weston_view *ev; /**< maintained for drm_assign_planes only */
397
398 int32_t src_x, src_y;
399 uint32_t src_w, src_h;
400 int32_t dest_x, dest_y;
401 uint32_t dest_w, dest_h;
402
Marius Vlad95e3b0d2019-11-11 15:24:25 +0000403 uint64_t zpos;
404
Daniel Stonedd1bc502019-06-17 12:13:46 +0100405 bool complete;
406
407 /* We don't own the fd, so we shouldn't close it */
408 int in_fence_fd;
409
410 pixman_region32_t damage; /* damage to kernel */
411
412 struct wl_list link; /* drm_output_state::plane_list */
413};
414
415/**
416 * A plane represents one buffer, positioned within a CRTC, and stacked
417 * relative to other planes on the same CRTC.
418 *
419 * Each CRTC has a 'primary plane', which use used to display the classic
420 * framebuffer contents, as accessed through the legacy drmModeSetCrtc
421 * call (which combines setting the CRTC's actual physical mode, and the
422 * properties of the primary plane).
423 *
424 * The cursor plane also has its own alternate legacy API.
425 *
426 * Other planes are used opportunistically to display content we do not
427 * wish to blit into the primary plane. These non-primary/cursor planes
428 * are referred to as 'sprites'.
429 */
430struct drm_plane {
431 struct weston_plane base;
432
433 struct drm_backend *backend;
434
435 enum wdrm_plane_type type;
436
437 uint32_t possible_crtcs;
438 uint32_t plane_id;
439 uint32_t count_formats;
440
441 struct drm_property_info props[WDRM_PLANE__COUNT];
442
443 /* The last state submitted to the kernel for this plane. */
444 struct drm_plane_state *state_cur;
445
Marius Vlad95e3b0d2019-11-11 15:24:25 +0000446 uint64_t zpos_min;
447 uint64_t zpos_max;
448
Daniel Stonedd1bc502019-06-17 12:13:46 +0100449 struct wl_list link;
450
451 struct {
452 uint32_t format;
453 uint32_t count_modifiers;
454 uint64_t *modifiers;
455 } formats[];
456};
457
458struct drm_head {
459 struct weston_head base;
460 struct drm_backend *backend;
461
462 drmModeConnector *connector;
463 uint32_t connector_id;
464 struct drm_edid edid;
465
466 /* Holds the properties for the connector */
467 struct drm_property_info props_conn[WDRM_CONNECTOR__COUNT];
468
469 struct backlight *backlight;
470
471 drmModeModeInfo inherited_mode; /**< Original mode on the connector */
472 uint32_t inherited_crtc_id; /**< Original CRTC assignment */
473};
474
475struct drm_output {
476 struct weston_output base;
477 struct drm_backend *backend;
478
479 uint32_t crtc_id; /* object ID to pass to DRM functions */
480 int pipe; /* index of CRTC in resource array / bitmasks */
481
482 /* Holds the properties for the CRTC */
483 struct drm_property_info props_crtc[WDRM_CRTC__COUNT];
484
485 int page_flip_pending;
486 int atomic_complete_pending;
487 int destroy_pending;
488 int disable_pending;
489 int dpms_off_pending;
490
Stefan Agner974390a2019-07-08 00:42:05 +0200491 uint32_t gbm_cursor_handle[2];
Daniel Stonedd1bc502019-06-17 12:13:46 +0100492 struct drm_fb *gbm_cursor_fb[2];
493 struct drm_plane *cursor_plane;
494 struct weston_view *cursor_view;
495 int current_cursor;
496
497 struct gbm_surface *gbm_surface;
498 uint32_t gbm_format;
499 uint32_t gbm_bo_flags;
500
501 /* Plane being displayed directly on the CRTC */
502 struct drm_plane *scanout_plane;
503
504 /* The last state submitted to the kernel for this CRTC. */
505 struct drm_output_state *state_cur;
506 /* The previously-submitted state, where the hardware has not
507 * yet acknowledged completion of state_cur. */
508 struct drm_output_state *state_last;
509
510 struct drm_fb *dumb[2];
511 pixman_image_t *image[2];
512 int current_image;
513 pixman_region32_t previous_damage;
514
515 struct vaapi_recorder *recorder;
516 struct wl_listener recorder_frame_listener;
517
518 struct wl_event_source *pageflip_timer;
519
520 bool virtual;
521
522 submit_frame_cb virtual_submit_frame;
523};
524
525static inline struct drm_head *
526to_drm_head(struct weston_head *base)
527{
528 return container_of(base, struct drm_head, base);
529}
530
531static inline struct drm_output *
532to_drm_output(struct weston_output *base)
533{
534 return container_of(base, struct drm_output, base);
535}
536
537static inline struct drm_backend *
538to_drm_backend(struct weston_compositor *base)
539{
540 return container_of(base->backend, struct drm_backend, base);
541}
542
543static inline struct drm_mode *
544to_drm_mode(struct weston_mode *base)
545{
546 return container_of(base, struct drm_mode, base);
547}
Daniel Stonefbe6c1d2019-06-17 16:04:26 +0100548
Marius Vlad95e3b0d2019-11-11 15:24:25 +0000549static inline const char *
550drm_output_get_plane_type_name(struct drm_plane *p)
551{
552 switch (p->type) {
553 case WDRM_PLANE_TYPE_PRIMARY:
554 return "primary";
555 case WDRM_PLANE_TYPE_CURSOR:
556 return "cursor";
557 case WDRM_PLANE_TYPE_OVERLAY:
558 return "overlay";
559 default:
560 assert(0);
561 break;
562 }
563}
564
Daniel Stone4c2fc702019-06-18 11:12:07 +0100565struct drm_output *
566drm_output_find_by_crtc(struct drm_backend *b, uint32_t crtc_id);
567
568struct drm_head *
569drm_head_find_by_connector(struct drm_backend *backend, uint32_t connector_id);
570
Daniel Stone7580b3c2019-06-18 11:16:53 +0100571static inline bool
572drm_view_transform_supported(struct weston_view *ev, struct weston_output *output)
573{
574 struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
575
576 /* This will incorrectly disallow cases where the combination of
577 * buffer and view transformations match the output transform.
578 * Fixing this requires a full analysis of the transformation
579 * chain. */
580 if (ev->transform.enabled &&
581 ev->transform.matrix.type >= WESTON_MATRIX_TRANSFORM_ROTATE)
582 return false;
583
584 if (viewport->buffer.transform != output->transform)
585 return false;
586
587 return true;
588}
589
Daniel Stonefbe6c1d2019-06-17 16:04:26 +0100590int
591drm_mode_ensure_blob(struct drm_backend *backend, struct drm_mode *mode);
592
593struct drm_mode *
594drm_output_choose_mode(struct drm_output *output,
595 struct weston_mode *target_mode);
596void
597update_head_from_connector(struct drm_head *head,
598 drmModeObjectProperties *props);
599
600void
601drm_mode_list_destroy(struct drm_backend *backend, struct wl_list *mode_list);
602
603void
604drm_output_print_modes(struct drm_output *output);
605
606int
607drm_output_set_mode(struct weston_output *base,
608 enum weston_drm_backend_output_mode mode,
609 const char *modeline);
610
Daniel Stone4c2fc702019-06-18 11:12:07 +0100611void
612drm_property_info_populate(struct drm_backend *b,
613 const struct drm_property_info *src,
614 struct drm_property_info *info,
615 unsigned int num_infos,
616 drmModeObjectProperties *props);
Daniel Stonefbe6c1d2019-06-17 16:04:26 +0100617uint64_t
618drm_property_get_value(struct drm_property_info *info,
619 const drmModeObjectProperties *props,
620 uint64_t def);
Marius Vlad95e3b0d2019-11-11 15:24:25 +0000621uint64_t *
622drm_property_get_range_values(struct drm_property_info *info,
623 const drmModeObjectProperties *props);
Daniel Stone4c2fc702019-06-18 11:12:07 +0100624int
625drm_plane_populate_formats(struct drm_plane *plane, const drmModePlane *kplane,
626 const drmModeObjectProperties *props);
627void
628drm_property_info_free(struct drm_property_info *info, int num_props);
629
630extern struct drm_property_enum_info plane_type_enums[];
631extern const struct drm_property_info plane_props[];
632extern struct drm_property_enum_info dpms_state_enums[];
Ankit Nautiyala344fe32019-05-14 18:36:08 +0530633extern struct drm_property_enum_info content_protection_enums[];
634extern struct drm_property_enum_info hdcp_content_type_enums[];
Daniel Stone4c2fc702019-06-18 11:12:07 +0100635extern const struct drm_property_info connector_props[];
636extern const struct drm_property_info crtc_props[];
637
638int
639init_kms_caps(struct drm_backend *b);
640
641int
642drm_pending_state_test(struct drm_pending_state *pending_state);
643int
644drm_pending_state_apply(struct drm_pending_state *pending_state);
645int
646drm_pending_state_apply_sync(struct drm_pending_state *pending_state);
647
648void
649drm_output_set_gamma(struct weston_output *output_base,
650 uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b);
651
652void
653drm_output_update_msc(struct drm_output *output, unsigned int seq);
654void
655drm_output_update_complete(struct drm_output *output, uint32_t flags,
656 unsigned int sec, unsigned int usec);
657int
658on_drm_input(int fd, uint32_t mask, void *data);
659
660struct drm_plane_state *
661drm_output_state_get_existing_plane(struct drm_output_state *state_output,
662 struct drm_plane *plane);
663void
664drm_plane_state_free(struct drm_plane_state *state, bool force);
665void
666drm_output_state_free(struct drm_output_state *state);
667void
668drm_pending_state_free(struct drm_pending_state *pending_state);
Daniel Stone7580b3c2019-06-18 11:16:53 +0100669
670struct drm_fb *
671drm_fb_ref(struct drm_fb *fb);
672void
673drm_fb_unref(struct drm_fb *fb);
674
675struct drm_fb *
676drm_fb_create_dumb(struct drm_backend *b, int width, int height,
677 uint32_t format);
678struct drm_fb *
679drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
680 bool is_opaque, enum drm_fb_type type);
Daniel Stone6b466f22019-06-18 11:30:54 +0100681
Stefan Agnerccf24072019-07-09 22:02:00 +0200682#ifdef BUILD_DRM_GBM
683extern struct drm_fb *
684drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev);
685#else
686static inline struct drm_fb *
687drm_fb_get_from_view(struct drm_output_state *state, struct weston_view *ev)
688{
689 return NULL;
690}
691#endif
Daniel Stone6b466f22019-06-18 11:30:54 +0100692
693struct drm_pending_state *
694drm_pending_state_alloc(struct drm_backend *backend);
695void
696drm_pending_state_free(struct drm_pending_state *pending_state);
697struct drm_output_state *
698drm_pending_state_get_output(struct drm_pending_state *pending_state,
699 struct drm_output *output);
700
701
702/**
703 * Mode for drm_output_state_duplicate.
704 */
705enum drm_output_state_duplicate_mode {
706 DRM_OUTPUT_STATE_CLEAR_PLANES, /**< reset all planes to off */
707 DRM_OUTPUT_STATE_PRESERVE_PLANES, /**< preserve plane state */
708};
709
710struct drm_output_state *
711drm_output_state_alloc(struct drm_output *output,
712 struct drm_pending_state *pending_state);
713struct drm_output_state *
714drm_output_state_duplicate(struct drm_output_state *src,
715 struct drm_pending_state *pending_state,
716 enum drm_output_state_duplicate_mode plane_mode);
717void
718drm_output_state_free(struct drm_output_state *state);
719struct drm_plane_state *
720drm_output_state_get_plane(struct drm_output_state *state_output,
721 struct drm_plane *plane);
722struct drm_plane_state *
723drm_output_state_get_existing_plane(struct drm_output_state *state_output,
724 struct drm_plane *plane);
725
726
727
728struct drm_plane_state *
729drm_plane_state_alloc(struct drm_output_state *state_output,
730 struct drm_plane *plane);
731struct drm_plane_state *
732drm_plane_state_duplicate(struct drm_output_state *state_output,
733 struct drm_plane_state *src);
734void
735drm_plane_state_free(struct drm_plane_state *state, bool force);
736void
737drm_plane_state_put_back(struct drm_plane_state *state);
738bool
739drm_plane_state_coords_for_view(struct drm_plane_state *state,
Marius Vlad95e3b0d2019-11-11 15:24:25 +0000740 struct weston_view *ev, uint64_t zpos);
Daniel Stonee404b722019-06-22 18:40:31 +0100741
742void
743drm_assign_planes(struct weston_output *output_base, void *repaint_data);
744
745bool
746drm_plane_is_available(struct drm_plane *plane, struct drm_output *output);
Stefan Agner3654c672019-07-09 00:50:30 +0200747
748void
749drm_output_render(struct drm_output_state *state, pixman_region32_t *damage);
750
751int
752parse_gbm_format(const char *s, uint32_t default_value, uint32_t *gbm_format);
753
754extern struct gl_renderer_interface *gl_renderer;
755
756#ifdef BUILD_DRM_VIRTUAL
757extern int
758drm_backend_init_virtual_output_api(struct weston_compositor *compositor);
759#else
760inline static int
761drm_backend_init_virtual_output_api(struct weston_compositor *compositor)
762{
763 return 0;
764}
765#endif
766
Stefan Agnerccf24072019-07-09 22:02:00 +0200767#ifdef BUILD_DRM_GBM
768int
769init_egl(struct drm_backend *b);
770
Stefan Agner3654c672019-07-09 00:50:30 +0200771int
772drm_output_init_egl(struct drm_output *output, struct drm_backend *b);
Stefan Agnerccf24072019-07-09 22:02:00 +0200773
Stefan Agner3654c672019-07-09 00:50:30 +0200774void
775drm_output_fini_egl(struct drm_output *output);
776
Stefan Agnerccf24072019-07-09 22:02:00 +0200777struct drm_fb *
778drm_output_render_gl(struct drm_output_state *state, pixman_region32_t *damage);
779
780void
781renderer_switch_binding(struct weston_keyboard *keyboard,
782 const struct timespec *time, uint32_t key, void *data);
783#else
784inline static int
785init_egl(struct drm_backend *b)
786{
787 weston_log("Compiled without GBM/EGL support\n");
788 return -1;
789}
790
791inline static int
792drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
793{
794 return -1;
795}
796
797inline static void
798drm_output_fini_egl(struct drm_output *output)
799{
800}
801
802inline static struct drm_fb *
803drm_output_render_gl(struct drm_output_state *state, pixman_region32_t *damage)
804{
805 return NULL;
806}
807
808inline static void
809renderer_switch_binding(struct weston_keyboard *keyboard,
810 const struct timespec *time, uint32_t key, void *data)
811{
812 weston_log("Compiled without GBM/EGL support\n");
813}
814#endif