]>
Commit | Line | Data |
---|---|---|
650c5444 DH |
1 | /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ |
2 | ||
3 | /*** | |
4 | This file is part of systemd. | |
5 | ||
6 | Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com> | |
7 | ||
8 | systemd is free software; you can redistribute it and/or modify it | |
9 | under the terms of the GNU Lesser General Public License as published by | |
10 | the Free Software Foundation; either version 2.1 of the License, or | |
11 | (at your option) any later version. | |
12 | ||
13 | systemd is distributed in the hope that it will be useful, but | |
14 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | Lesser General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU Lesser General Public License | |
19 | along with systemd; If not, see <http://www.gnu.org/licenses/>. | |
20 | ***/ | |
21 | ||
22 | #pragma once | |
23 | ||
24 | #include <inttypes.h> | |
f22e0bce | 25 | #include <libudev.h> |
650c5444 DH |
26 | #include <stdbool.h> |
27 | #include <stdlib.h> | |
ce1daea1 TA |
28 | #include "sd-bus.h" |
29 | #include "sd-event.h" | |
650c5444 DH |
30 | #include "hashmap.h" |
31 | #include "list.h" | |
32 | #include "util.h" | |
ce1daea1 | 33 | #include "grdev.h" |
650c5444 DH |
34 | |
35 | typedef struct grdev_tile grdev_tile; | |
36 | typedef struct grdev_display_cache grdev_display_cache; | |
37 | ||
38 | typedef struct grdev_pipe_vtable grdev_pipe_vtable; | |
39 | typedef struct grdev_pipe grdev_pipe; | |
40 | typedef struct grdev_card_vtable grdev_card_vtable; | |
41 | typedef struct grdev_card grdev_card; | |
42 | ||
f22e0bce DH |
43 | /* |
44 | * DRM cards | |
45 | */ | |
46 | ||
47 | bool grdev_is_drm_card(grdev_card *card); | |
48 | grdev_card *grdev_find_drm_card(grdev_session *session, dev_t devnum); | |
49 | int grdev_drm_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud); | |
6221d249 | 50 | void grdev_drm_card_hotplug(grdev_card *card, struct udev_device *ud); |
f22e0bce | 51 | |
650c5444 DH |
52 | /* |
53 | * Displays | |
54 | */ | |
55 | ||
56 | enum { | |
57 | GRDEV_TILE_LEAF, | |
58 | GRDEV_TILE_NODE, | |
59 | GRDEV_TILE_CNT | |
60 | }; | |
61 | ||
62 | struct grdev_tile { | |
0508a4df | 63 | LIST_FIELDS(grdev_tile, children_by_node); |
650c5444 DH |
64 | grdev_tile *parent; |
65 | grdev_display *display; | |
66 | ||
67 | uint32_t x; | |
68 | uint32_t y; | |
69 | unsigned int rotate; | |
70 | unsigned int flip; | |
71 | uint32_t cache_w; | |
72 | uint32_t cache_h; | |
73 | ||
74 | unsigned int type; | |
75 | ||
76 | union { | |
77 | struct { | |
78 | grdev_pipe *pipe; | |
79 | } leaf; | |
80 | ||
81 | struct { | |
0508a4df | 82 | size_t n_children; |
650c5444 DH |
83 | LIST_HEAD(grdev_tile, child_list); |
84 | } node; | |
85 | }; | |
86 | }; | |
87 | ||
88 | int grdev_tile_new_leaf(grdev_tile **out, grdev_pipe *pipe); | |
89 | int grdev_tile_new_node(grdev_tile **out); | |
90 | grdev_tile *grdev_tile_free(grdev_tile *tile); | |
91 | ||
92 | DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_tile*, grdev_tile_free); | |
93 | ||
94 | struct grdev_display { | |
95 | grdev_session *session; | |
96 | char *name; | |
f2a15d86 | 97 | void *userdata; |
650c5444 DH |
98 | |
99 | size_t n_leafs; | |
100 | grdev_tile *tile; | |
101 | ||
102 | size_t n_pipes; | |
103 | size_t max_pipes; | |
104 | ||
105 | uint32_t width; | |
106 | uint32_t height; | |
107 | ||
108 | struct grdev_display_cache { | |
109 | grdev_pipe *pipe; | |
110 | grdev_display_target target; | |
111 | ||
112 | bool incomplete : 1; | |
113 | } *pipes; | |
114 | ||
115 | bool enabled : 1; | |
116 | bool public : 1; | |
117 | bool modified : 1; | |
118 | bool framed : 1; | |
119 | }; | |
120 | ||
121 | grdev_display *grdev_find_display(grdev_session *session, const char *name); | |
122 | ||
123 | int grdev_display_new(grdev_display **out, grdev_session *session, const char *name); | |
124 | grdev_display *grdev_display_free(grdev_display *display); | |
125 | ||
126 | DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_display*, grdev_display_free); | |
127 | ||
128 | /* | |
129 | * Pipes | |
130 | */ | |
131 | ||
132 | struct grdev_pipe_vtable { | |
133 | void (*free) (grdev_pipe *pipe); | |
134 | void (*enable) (grdev_pipe *pipe); | |
135 | void (*disable) (grdev_pipe *pipe); | |
136 | grdev_fb *(*target) (grdev_pipe *pipe); | |
137 | }; | |
138 | ||
139 | struct grdev_pipe { | |
140 | const grdev_pipe_vtable *vtable; | |
141 | grdev_card *card; | |
142 | char *name; | |
143 | ||
144 | grdev_tile *tile; | |
145 | grdev_display_cache *cache; | |
7b12a45b | 146 | sd_event_source *vsync_src; |
650c5444 DH |
147 | |
148 | uint32_t width; | |
149 | uint32_t height; | |
7b12a45b | 150 | uint32_t vrefresh; |
650c5444 DH |
151 | |
152 | size_t max_fbs; | |
153 | grdev_fb *front; | |
154 | grdev_fb *back; | |
155 | grdev_fb **fbs; | |
156 | ||
157 | bool enabled : 1; | |
158 | bool running : 1; | |
159 | bool flip : 1; | |
160 | bool flipping : 1; | |
161 | }; | |
162 | ||
163 | #define GRDEV_PIPE_INIT(_vtable, _card) ((grdev_pipe){ \ | |
164 | .vtable = (_vtable), \ | |
165 | .card = (_card), \ | |
166 | }) | |
167 | ||
168 | grdev_pipe *grdev_find_pipe(grdev_card *card, const char *name); | |
169 | ||
170 | int grdev_pipe_add(grdev_pipe *pipe, const char *name, size_t n_fbs); | |
171 | grdev_pipe *grdev_pipe_free(grdev_pipe *pipe); | |
172 | ||
173 | DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_pipe*, grdev_pipe_free); | |
174 | ||
175 | void grdev_pipe_ready(grdev_pipe *pipe, bool running); | |
176 | void grdev_pipe_frame(grdev_pipe *pipe); | |
7b12a45b | 177 | void grdev_pipe_schedule(grdev_pipe *pipe, uint64_t frames); |
650c5444 DH |
178 | |
179 | /* | |
180 | * Cards | |
181 | */ | |
182 | ||
183 | struct grdev_card_vtable { | |
184 | void (*free) (grdev_card *card); | |
185 | void (*enable) (grdev_card *card); | |
186 | void (*disable) (grdev_card *card); | |
187 | void (*commit) (grdev_card *card); | |
188 | void (*restore) (grdev_card *card); | |
189 | }; | |
190 | ||
191 | struct grdev_card { | |
192 | const grdev_card_vtable *vtable; | |
193 | grdev_session *session; | |
194 | char *name; | |
195 | ||
196 | Hashmap *pipe_map; | |
197 | ||
198 | bool enabled : 1; | |
199 | bool modified : 1; | |
200 | }; | |
201 | ||
202 | #define GRDEV_CARD_INIT(_vtable, _session) ((grdev_card){ \ | |
203 | .vtable = (_vtable), \ | |
204 | .session = (_session), \ | |
205 | }) | |
206 | ||
207 | grdev_card *grdev_find_card(grdev_session *session, const char *name); | |
208 | ||
209 | int grdev_card_add(grdev_card *card, const char *name); | |
210 | grdev_card *grdev_card_free(grdev_card *card); | |
211 | ||
212 | DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_card*, grdev_card_free); | |
213 | ||
214 | /* | |
215 | * Sessions | |
216 | */ | |
217 | ||
218 | struct grdev_session { | |
219 | grdev_context *context; | |
220 | char *name; | |
221 | char *path; | |
222 | grdev_event_fn event_fn; | |
223 | void *userdata; | |
224 | ||
225 | unsigned long n_pins; | |
226 | ||
227 | Hashmap *card_map; | |
228 | Hashmap *display_map; | |
229 | ||
230 | bool custom : 1; | |
231 | bool managed : 1; | |
232 | bool enabled : 1; | |
233 | bool modified : 1; | |
234 | }; | |
235 | ||
236 | grdev_session *grdev_session_pin(grdev_session *session); | |
237 | grdev_session *grdev_session_unpin(grdev_session *session); | |
238 | ||
239 | DEFINE_TRIVIAL_CLEANUP_FUNC(grdev_session*, grdev_session_unpin); | |
240 | ||
241 | /* | |
242 | * Contexts | |
243 | */ | |
244 | ||
245 | struct grdev_context { | |
246 | unsigned long ref; | |
247 | sd_event *event; | |
248 | sd_bus *sysbus; | |
249 | ||
250 | Hashmap *session_map; | |
251 | }; |