source: mainline/uspace/lib/graph/graph.h@ 4621d23

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 4621d23 was 984a9ba, checked in by Martin Decky <martin@…>, 7 years ago

do not expose the call capability handler from the async framework

Keep the call capability handler encapsulated within the async framework
and do not expose it explicitly via its API. Use the pointer to
ipc_call_t as the sole object identifying an IPC call in the code that
uses the async framework.

This plugs a major leak in the abstraction and also simplifies both the
async framework (slightly) and all IPC servers.

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