source: mainline/uspace/lib/graph/graph.h@ bf22cb78

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since bf22cb78 was 508b0df1, checked in by Jiří Zárevúcky <jiri.zarevucky@…>, 7 years ago

Remove uspace <atomic.h>, use <stdatomic.h> instead

  • Property mode set to 100644
File size: 14.0 KB
Line 
1/*
2 * Copyright (c) 2011 Petr Koupy
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup graph
30 * @{
31 */
32/**
33 * @file
34 */
35
36#ifndef GRAPH_GRAPH_H_
37#define GRAPH_GRAPH_H_
38
39#include <stdbool.h>
40#include <loc.h>
41#include <async.h>
42#include <stdatomic.h>
43#include <refcount.h>
44#include <fibril_synch.h>
45#include <adt/list.h>
46#include <io/mode.h>
47#include <io/pixelmap.h>
48#include <ipc/graph.h>
49
50struct visualizer;
51struct renderer;
52
53typedef struct {
54 /**
55 * Device driver shall allocate any necessary internal structures
56 * specific for a claimed visualizer.
57 */
58 errno_t (*claim)(struct visualizer *vs);
59
60 /**
61 * Device driver shall deallocate any necessary internal structures
62 * specific for a claimed visualizer. Driver shall also check whether
63 * the mode is set and if so it shall change its internal state
64 * accordingly (e.g. deallocate frame buffers).
65 */
66 errno_t (*yield)(struct visualizer *vs);
67
68 /**
69 * Device driver shall first try to claim all resources required for
70 * a new mode (e.g. allocate new framebuffers) and only if successful
71 * it shall free resources for the old mode. Although such behaviour
72 * might not be always possible, it is preferable since libgraph tries to
73 * keep current mode functional if the new mode cannot be set (for any
74 * reason). If it is convenient for the device driver (e.g. for better
75 * optimization), the pointer to the handle_damage operation can be
76 * changed at this point.
77 */
78 errno_t (*change_mode)(struct visualizer *vs, vslmode_t new_mode);
79
80 /**
81 * Device driver shall render the cells from damaged region into its
82 * internal framebuffer. In case the driver use multi-buffering, it
83 * shall also switch internal buffers (e.g. by pageflip). Offsets
84 * are intended to support basic vertical and horizontal scrolling on
85 * the shared backbuffer (i.e. when reading from backbuffer, the offsets
86 * shall be added to the coordinates and if necessary the result shall be
87 * wrapped around the edge of the backbuffer).
88 */
89 errno_t (*handle_damage)(struct visualizer *vs,
90 sysarg_t x, sysarg_t y, sysarg_t width, sysarg_t height,
91 sysarg_t x_offset, sysarg_t y_offset);
92
93 /**
94 * Upper layers of the graphic stack might report inactivity. In such
95 * case, device driver might enable power saving mode on the device
96 * corresponding to the visualizer.
97 */
98 errno_t (*suspend)(struct visualizer *vs);
99
100 /**
101 * When upper layers detect activity on suspended visualizer, device
102 * driver shall disable power saving mode on the corresponding device.
103 */
104 errno_t (*wakeup)(struct visualizer *vs);
105} visualizer_ops_t;
106
107/**
108 * Represents final output device (e.g. monitor connected to the port
109 * on the graphic adapter, serial console, local/remote virtual monitor).
110 */
111typedef struct visualizer {
112 /**
113 * Link to the list of all visualizers belonging to the graphic device.
114 * Field is fully managed by libgraph.
115 */
116 link_t link;
117
118 /**
119 * When reference count equals 1, visualizer is claimed by a client,
120 * when equals 0, visualizer is not claimed. At the time, visualizer
121 * can be claimed only by a single client.
122 * Field is fully managed by libgraph.
123 */
124 atomic_flag claimed;
125
126 /**
127 * Visualizer ID assigned by some particular registration service
128 * in the system (either location service or device manager). Intended
129 * for cleanup duties (e.g. unregistering visualizer).
130 * If the visualizer is registered through libgraph functions, then the
131 * field is fully managed by libgraph. Otherwise, it is a driver
132 * responsibility to set and update this field.
133 */
134 sysarg_t reg_svc_handle;
135
136 /**
137 * Visualizer ID in the client context. When client gets notified by
138 * libgraph about some event, it can use this identification to lookup
139 * data structures corresponding to a particular visualizer (e.g. viewports
140 * in the compositor).
141 * Field is fully managed by libgraph. It is assigned when the visualizer
142 * gets claimed and is valid until it is yielded.
143 */
144 sysarg_t client_side_handle;
145
146 /**
147 * Callback session to the client. Established by libgraph during initial
148 * phase of client connection. Can be used to notify client about
149 * external asynchronous changes to the output device state
150 * (e.g. monitor gets disconnected from the graphic adapter, virtual
151 * monitor is terminated by the user, pivot monitor is rotated by 90
152 * degrees, virtual monitor is resized by the user).
153 * Field is fully managed by libgraph. Device driver can use it indirectly
154 * through notification functions.
155 */
156 async_sess_t *notif_sess;
157
158 /**
159 * Mutex protecting the mode list and default mode index. This is required
160 * for the case when device driver might asynchronously update these
161 * upon the request from the final output device (e.g. to change mode
162 * dimensions when virtual monitor is resized).
163 * Both device driver and libgraph must lock on this mutex when accessing
164 * modes list or default mode index.
165 */
166 fibril_mutex_t mode_mtx;
167
168 /**
169 * List of all modes that can be set by this visualizer. List is populated
170 * by device driver when creating a new visualizer or when handling the
171 * request from the final output device to change the available modes.
172 * When this happens, the device driver is expected to increment version
173 * numbers in the modified modes. Modes in the list typically represent
174 * the intersection of modes supported by device driver (graphic adapter)
175 * and final output device (e.g. monitor).
176 * Field is fully managed by device driver, libgraph reads it with locked
177 * mutex.
178 */
179 list_t modes;
180
181 /**
182 * Index of the default mode. Might come in handy to the clients that are
183 * not able to enumerate modes and present the choice to the user
184 * (either the client does not have such functionality or the client is
185 * bootstraping without any preliminary knowledge). Device driver shall
186 * maintain this field at the same time when it is doing any changes to the
187 * mode list.
188 * Field is fully managed by device driver, libgraph reads it with locked
189 * mutex.
190 */
191 sysarg_t def_mode_idx;
192
193 /**
194 * Copy of the currently established mode. It is read by both libgraph and
195 * device driver when deallocating resources for the current mode. Device
196 * driver can also read it to properly interpret the cell type and its
197 * internal structures when handling the damage.
198 * Field is fully managed by libgraph, can be read by device driver.
199 */
200 vslmode_t cur_mode;
201
202 /**
203 * Determines whether the visualizer is currently set to some mode or not,
204 * that is whether cur_mode field contains up-to-date data.
205 * Field is fully managed by libgraph, can be read by device driver.
206 */
207 bool mode_set;
208
209 /**
210 * Device driver function pointers.
211 * Field is fully managed by device driver, libgraph invokes driver's
212 * functions through it.
213 */
214 visualizer_ops_t ops;
215
216 /**
217 * Backbuffer shared with the client. Sharing is established by libgraph.
218 * Device driver reads the cells when handling damage. Cells shall be
219 * interpreted according to the currently set mode.
220 * Field is fully managed by libgraph, can be read by device driver.
221 */
222 pixelmap_t cells;
223
224 /**
225 * Device driver context, completely opaque to the libgraph. Intended to
226 * contain pointers to frontbuffers or information representing the
227 * final output device (e.g. hardware port for physical monitor).
228 * Field is fully managed by device driver.
229 */
230 void *dev_ctx;
231} visualizer_t;
232
233typedef struct {
234 // TODO
235 int dummy;
236} renderer_ops_t;
237
238/**
239 * NOTE: Following description is just a result of brainstorming on how the
240 * driver of real physical graphic accelerator could be supported by
241 * libgraph.
242 *
243 * Renderer represents the hardware graphic accelerator. If the device driver
244 * handles more than one physical accelerator (e.g. graphic cards connected in
245 * SLI mode or single graphic card with two GPUs), it is up to the driver
246 * whether the load balancing will be exposed to the clients (that is the
247 * driver will provide multiple renderers) or not (just a single renderer
248 * handling the load balancing internally).
249 *
250 * At runtime, renderer is represented by scheduling thread and multiple
251 * connection fibrils handling client requests. For each client, there is
252 * command queue, condition variable and device context. Connection fibril puts
253 * the command into the command queue and blocks on the condition variable.
254 * Scheduling thread decides what client to serve, switches corresponding device
255 * context into the accelerator, consumes the command from the command queue and
256 * executes it on the accelerator. When the command execution is finished, the
257 * condition variable si signalled and the connection fibril answers the client.
258 *
259 * Operations that are not implemented in the hardware of the accelerator might
260 * be carried out by worker threads managed by scheduling thread. If the
261 * accelerator physical memory is mapped to the address space of the driver, it
262 * could be extended by allowing scheduling thread to page out the memory and
263 * to handle the page faults.
264 *
265 * NOTE: It is not entirely clear which parts should be implemented in libgraph
266 * and which in the device driver. As a rough sketch, the connection
267 * fibril routine, command queue and memory paging should be handled
268 * by libgraph. The scheduling thread and device context should be
269 * provided by device driver.
270 */
271typedef struct renderer {
272 // TODO
273 link_t link;
274
275 atomic_refcount_t ref_cnt;
276
277 sysarg_t reg_svc_handle;
278
279 renderer_ops_t ops;
280} renderer_t;
281
282/*----------------------------------------------------------------------------*/
283
284/**
285 * Fill in the basic visualizer structure. The device driver shall take the
286 * created torso and to complete it by adding its specific structures
287 * (device context, modes).
288 */
289extern void graph_init_visualizer(visualizer_t *);
290
291extern void graph_init_renderer(renderer_t *);
292
293/*----------------------------------------------------------------------------*/
294
295/*
296 * NOTE: All functions in this section are intended to be used only by various
297 * driver emulators (e.g. compositor client containing emulated driver
298 * to render the framebuffer of other compositor or console server).
299 * Driver of the physical hardware shall instead use similar functions
300 * from libdrv.
301 */
302
303/**
304 * Allocate the visualizer so it can be initialized.
305 */
306extern visualizer_t *graph_alloc_visualizer(void);
307
308/**
309 * Register the completely prepared visualizer to the location service and
310 * add it to the driver visualizer list. After the registration, the visualizer
311 * is considered ready to handle client connection. Since visualizer
312 * list is guarded by the mutex, visualizers might be added even after the
313 * initialialization of the device driver.
314 */
315extern errno_t graph_register_visualizer(visualizer_t *);
316
317/**
318 * Retrieve the visualizer from the visualizer list according to its
319 * service ID.
320 */
321extern visualizer_t *graph_get_visualizer(sysarg_t);
322
323/**
324 * Unregister the visualizer from the location service and remove it
325 * from the driver visualizer list. Function shall be called by device driver
326 * before deallocating the resources for the visualizer.
327 */
328extern errno_t graph_unregister_visualizer(visualizer_t *);
329
330/**
331 * Destroy the rest of the visualizer. Device driver shall call this function
332 * only after it has unregistered the visualizer and deallocated all the
333 * resources for which the driver is responsible.
334 */
335extern void graph_destroy_visualizer(visualizer_t *);
336
337extern renderer_t *graph_alloc_renderer(void);
338extern errno_t graph_register_renderer(renderer_t *);
339extern renderer_t *graph_get_renderer(sysarg_t);
340extern errno_t graph_unregister_renderer(renderer_t *);
341extern void graph_destroy_renderer(renderer_t *);
342
343/*----------------------------------------------------------------------------*/
344
345/**
346 * Device driver can call this function to notify the client through the
347 * callback connection that the visualizer with a specified service ID should
348 * be switched to the mode with the given index.
349 */
350extern errno_t graph_notify_mode_change(async_sess_t *, sysarg_t, sysarg_t);
351
352/**
353 * Device driver can call this function to notify the client through the
354 * callback connection that the visualizer with a specified service ID has
355 * lost its output device (e.g. virtual monitor was closed by a user).
356 */
357extern errno_t graph_notify_disconnect(async_sess_t *, sysarg_t);
358
359/*----------------------------------------------------------------------------*/
360
361/** Shall be registered to libdrv by physical device driver. */
362extern void graph_visualizer_connection(visualizer_t *, ipc_call_t *, void *);
363
364/** Shall be registered to libdrv by physical device driver. */
365extern void graph_renderer_connection(renderer_t *, ipc_call_t *, void *);
366
367/** Shall be registered to location service by emulated device driver. */
368extern void graph_client_connection(ipc_call_t *, void *);
369
370#endif
371
372/** @}
373 */
Note: See TracBrowser for help on using the repository browser.