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