File: libliftoff.h

package info (click to toggle)
libliftoff 0.5.0-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 352 kB
  • sloc: ansic: 5,432; makefile: 3
file content (234 lines) | stat: -rw-r--r-- 6,369 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#ifndef LIFTOFF_H
#define LIFTOFF_H

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <xf86drmMode.h>

struct liftoff_device;
struct liftoff_output;
struct liftoff_layer;
struct liftoff_plane;

/**
 * Initialize libliftoff for a DRM node.
 *
 * The node is expected to have DRM_CLIENT_CAP_ATOMIC enabled. libliftoff takes
 * ownership of the file descriptor.
 */
struct liftoff_device *
liftoff_device_create(int drm_fd);

/**
 * Destroy a libliftoff device.
 *
 * The caller is expected to destroy the outputs and layers explicitly.
 */
void
liftoff_device_destroy(struct liftoff_device *device);

/**
 * Register all available hardware planes to be managed by the libliftoff
 * device.
 *
 * Users should call this function if they don't manually set any plane property
 * and instead use libliftoff layers.
 *
 * Zero is returned on success, negative errno on error.
 */
int
liftoff_device_register_all_planes(struct liftoff_device *device);

/**
 * Register a hardware plane to be managed by the libliftoff device.
 *
 * Users should call this function for each plane they don't want to manually
 * manage. Registering the same plane twice is an error.
 */
struct liftoff_plane *
liftoff_plane_create(struct liftoff_device *device, uint32_t plane_id);

/**
 * Unregister a hardware plane.
 */
void
liftoff_plane_destroy(struct liftoff_plane *plane);

/**
 * Obtain the object ID of the plane.
 */
uint32_t
liftoff_plane_get_id(struct liftoff_plane *plane);

/**
 * Options for liftoff_output_apply().
 */
struct liftoff_output_apply_options {
	/* Timeout in nanoseconds. If zero, a default timeout is used. */
	int64_t timeout_ns;
};

/**
 * Build a layer to plane mapping and append the plane configuration to req.
 *
 * Callers are expected to commit req afterwards and can figure out which
 * layers need composition via liftoff_layer_needs_composition().
 *
 * flags is the atomic commit flags the caller intends to use. If options is
 * NULL, defaults are used.
 *
 * Zero is returned on success, negative errno on error.
 */
int
liftoff_output_apply(struct liftoff_output *output, drmModeAtomicReq *req,
		     uint32_t flags,
		     const struct liftoff_output_apply_options *options);

/**
 * Make the device manage a CRTC's planes.
 *
 * The returned output allows callers to attach layers.
 */
struct liftoff_output *
liftoff_output_create(struct liftoff_device *device, uint32_t crtc_id);

/**
 * Destroy a libliftoff output.
 *
 * The caller is expected to destroy the output's layers explicitly.
 */
void
liftoff_output_destroy(struct liftoff_output *output);

/**
 * Indicate on which layer composition can take place.
 *
 * Users should be able to blend layers that haven't been mapped to a plane to
 * this layer. The composition layer won't be used if all other layers have been
 * mapped to a plane. There is at most one composition layer per output.
 */
void
liftoff_output_set_composition_layer(struct liftoff_output *output,
				     struct liftoff_layer *layer);

/**
 * Check whether this output needs composition.
 *
 * An output doesn't need composition if all visible layers could be mapped to a
 * plane. In other words, if an output needs composition, at least one layer
 * will return true when liftoff_layer_needs_composition() is called.
 */
bool
liftoff_output_needs_composition(struct liftoff_output *output);

/**
 * Create a new layer on an output.
 *
 * A layer is a virtual plane. Users can create as many layers as they want and
 * set any KMS property on them, without any constraint. libliftoff will try
 * to map layers to hardware planes on a best-effort basis. The user will need
 * to manually handle layers that couldn't be mapped to a plane.
 */
struct liftoff_layer *
liftoff_layer_create(struct liftoff_output *output);

/**
 * Destroy a layer.
 */
void
liftoff_layer_destroy(struct liftoff_layer *layer);

/**
 * Set a property on the layer.
 *
 * Any plane property can be set (except CRTC_ID). If none of the planes support
 * the property, the layer won't be mapped to any plane.
 *
 * Setting a zero FB_ID disables the layer.
 *
 * Zero is returned on success, negative errno on error.
 */
int
liftoff_layer_set_property(struct liftoff_layer *layer, const char *name,
			   uint64_t value);

/**
 * Unset a property on the layer.
 */
void
liftoff_layer_unset_property(struct liftoff_layer *layer, const char *name);

/**
 * Force composition on this layer.
 *
 * This unsets any previous FB_ID value. To switch back to direct scan-out, set
 * FB_ID again.
 *
 * This can be used when no KMS FB ID is available for this layer but it still
 * needs to be displayed (e.g. the buffer cannot be imported in KMS).
 */
void
liftoff_layer_set_fb_composited(struct liftoff_layer *layer);

/**
 * Check whether this layer needs composition.
 *
 * A layer needs composition if it's visible and if it couldn't be mapped to a
 * plane.
 */
bool
liftoff_layer_needs_composition(struct liftoff_layer *layer);

/**
 * Retrieve the plane mapped to this layer.
 *
 * NULL is returned if no plane is mapped.
 */
struct liftoff_plane *
liftoff_layer_get_plane(struct liftoff_layer *layer);

/**
 * Check whether a plane is a candidate for this layer.
 *
 * A plane is a candidate if it could potentially be used for the layer with
 * a buffer with the same size. The buffer may need to be re-allocated with
 * formats and modifiers accepted by the plane.
 *
 * This can be used to implemented a feedback loop: if a layer isn't mapped to
 * a plane, loop over the candidate planes, and re-allocate the layer's FB
 * according to the IN_FORMATS property.
 */
bool
liftoff_layer_is_candidate_plane(struct liftoff_layer *layer,
				 struct liftoff_plane *plane);

enum liftoff_log_priority {
	LIFTOFF_SILENT,
	LIFTOFF_ERROR,
	LIFTOFF_DEBUG,
};

typedef void (*liftoff_log_handler)(enum liftoff_log_priority priority,
				    const char *fmt, va_list args);

/**
 * Set libliftoff's log priority.
 *
 * Only messages with a priority higher than the provided priority will be
 * logged. The default priority is LIFTOFF_ERROR.
 */
void
liftoff_log_set_priority(enum liftoff_log_priority priority);

/**
 * Set libliftoff's log handler.
 *
 * The default handler prints messages to stderr. NULL restores the default
 * handler.
 */
void
liftoff_log_set_handler(liftoff_log_handler handler);

#endif