Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | Multi-monitor Mode Setting APIs |
2 | Keith Packard, <keithp@keithp.com | |
3 | 6 March 2007 | |
4 | ||
5 | 1. Introduction | |
6 | ||
7 | This document describes a set of mode setting APIs added in X server version | |
8 | 1.3 that support multiple monitors per card. These interfaces expose the | |
9 | underlying hardware CRTC and output concepts to the xf86 DDX layer so that | |
10 | the implementation of initial server setup and mode changes through | |
11 | extensions can be shared across drivers. In addition, these new interfaces | |
12 | support a new configuration mechanism as well which allows each monitor to | |
13 | be customized separately providing a consistent cross-driver configuration | |
14 | mechanism that supports the full range of output features. | |
15 | ||
16 | All of the code implementing this interface can be found in hw/xfree86/modes | |
17 | in the X server sources. | |
18 | ||
19 | 2. Overview | |
20 | ||
21 | This document describes both the driver API and the configuration data | |
22 | placed in xorg.conf; these are entirely separate as the driver has no | |
23 | interaction with the configuration information at all. Much of the structure | |
24 | here is cloned from the RandR extension version 1.2 additions which deal | |
25 | with the same kinds of information. | |
26 | ||
27 | 2.1 API overview | |
28 | ||
29 | The mode setting API is expressed through two new driver-visible objects, | |
30 | the 'CRTC' (xf86CrtcRec) and the 'Output' (xf86OutputRec). A CRTC refers to | |
31 | hardware within the video system that can scan a subset of the framebuffer | |
32 | and generate a video signal. An Output receives that signal and transmits it | |
33 | to a monitor, projector or other device. | |
34 | ||
35 | The xf86CrtcRec and xf86OutputRec contain a small amount of state data | |
36 | related to the object along with a pointer to a set of functions provided by | |
37 | the driver that manipulate the object in fairly simple ways. | |
38 | ||
39 | To emulate older behaviour, one of the outputs is picked as the 'compat' | |
40 | output; this output changes over time as outputs are detected and used, the | |
41 | goal is to always have one 'special' output which is used for operations | |
42 | which need a single defined monitor (like XFree86-VidModeExtension mode | |
43 | setting, RandR 1.1 mode setting, DDC property setting, etc.). | |
44 | ||
45 | 2.1.1 Output overview | |
46 | ||
47 | As outputs are connected to monitors, they hold a list of modes supported by | |
48 | the monitor. If the monitor and output support DDC, then the list of modes | |
49 | generally comes from the EDID data in the monitor. Otherwise, the server | |
50 | uses the standard VESA modes, pruned by monitor timing. If the configuration | |
51 | file doesn't contain monitor timing data, the server uses default timing | |
52 | information which supports 640x480, 800x600 and 1024x768 all with a 60Hz | |
53 | refresh rate. | |
54 | ||
55 | As hardware often limits possible configuration combinations, each output | |
56 | knows the set of CRTCs that it can be connected to as well as the set of | |
57 | other outputs which can be simutaneously connected to a CRTC. | |
58 | ||
59 | 2.1.2 CRTC overview | |
60 | ||
61 | CRTCs serve only to stream frame buffer data to outputs using a mode line. | |
62 | Ideally, they would not be presented to the user at all, and in fact the | |
63 | configuration file doesn't expose them. The RandR 1.2 protocol does, but the | |
64 | hope there is that client-side applications will hide them carefully away. | |
65 | ||
66 | Each crtc has an associated cursor, along with the current configuration. | |
67 | All of the data needed to determine valid configurations is contained within | |
68 | the Outputs. | |
69 | ||
70 | 2.2 Configuration overview | |
71 | ||
72 | As outputs drive monitors, the "Monitor" section has been repurposed to | |
73 | define their configuration. This provides for a bit more syntax than | |
74 | the large list of driver-specific options that were used in the past for | |
75 | similar configuration. | |
76 | ||
77 | However, the existing "Monitor" section referenced by the active "Screen" | |
78 | section no longer has any use at all; some sensible meaning for this | |
79 | parameter is needed now that a Screen can have multiple Monitors. | |
80 | ||
81 | 3. Public Functions | |
82 | ||
83 | 3.1 PreInit functions | |
84 | ||
85 | These functions should be used during the driver PreInit phase, they are | |
86 | arranged in the order they should be invoked. | |
87 | ||
88 | void | |
89 | xf86CrtcConfigInit (ScrnInfoPtr scrn | |
90 | const xf86CrtcConfigFuncsRec *funcs) | |
91 | ||
92 | This function allocates and initializes structures needed to track CRTC and | |
93 | Output state. | |
94 | ||
95 | void | |
96 | xf86CrtcSetSizeRange (ScrnInfoPtr scrn, | |
97 | int minWidth, int minHeight, | |
98 | int maxWidth, int maxHeight) | |
99 | ||
100 | This sets the range of screen sizes supported by the driver. | |
101 | ||
102 | xf86CrtcPtr | |
103 | xf86CrtcCreate (ScrnInfoPtr scrn, | |
104 | const xf86CrtcFuncsRec *funcs) | |
105 | ||
106 | Create one CRTC object. See the discussion below for a description of the | |
107 | contents of the xf86CrtcFuncsRec. Note that this is done in PreInit, so it | |
108 | should not be re-invoked at each server generation. Create one of these for | |
109 | each CRTC present in the hardware. | |
110 | ||
111 | xf86OutputPtr | |
112 | xf86OutputCreate (ScrnInfoPtr scrn, | |
113 | const xf86OutputFuncsRec *funcs, | |
114 | const char *name) | |
115 | ||
116 | Create one Output object. See the discussion below for a description of the | |
117 | contents of the xf86OutputFuncsRec. This is also called from PreInit and | |
118 | need not be re-invoked at each ScreenInit time. An Output should be created | |
119 | for every Output present in the hardware, not just for outputs which have | |
120 | detected monitors. | |
121 | ||
122 | Bool | |
123 | xf86OutputRename (xf86OutputPtr output, const char *name) | |
124 | ||
125 | If necessary, the name of an output can be changed after it is created using | |
126 | this function. | |
127 | ||
128 | Bool | |
129 | xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) | |
130 | ||
131 | Using the resources provided, and the configuration specified by the user, | |
132 | this function computes an initial configuration for the server. It tries to | |
133 | enable as much hardware as possible using some fairly simple heuristics. | |
134 | ||
135 | The 'canGrow' parameter indicates that the frame buffer does not have a fixed | |
136 | size. When the frame buffer has a fixed size, the configuration selects a | |
137 | 'reasonablely large' frame buffer so that common reconfiguration options are | |
138 | possible. For resizable frame buffers, the frame buffer is set to the smallest | |
139 | size that encloses the desired configuration. | |
140 | ||
141 | 3.2 ScreenInit functions | |
142 | ||
143 | These functions should be used during the driver ScreenInit phase. | |
144 | ||
145 | Bool | |
146 | xf86DiDGAInit (ScreenPtr screen, unsigned long dga_address) | |
147 | ||
148 | This function provides driver-independent accelerated DGA support for some | |
149 | of the DGA operations; using this, the driver can avoid needing to implement | |
150 | any of the rest of DGA. | |
151 | ||
152 | Bool | |
153 | xf86SaveScreen(ScreenPtr pScreen, int mode) | |
154 | ||
155 | Stick this in pScreen->SaveScreen and the core X screen saver will be | |
156 | implemented by disabling outputs and crtcs using their dpms functions. | |
157 | ||
158 | void | |
159 | xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags) | |
160 | ||
161 | Pass this function to xf86DPMSInit and all DPMS mode switching will be | |
162 | managed by using the dpms functions provided by the Outputs and CRTCs. | |
163 | ||
164 | Bool | |
165 | xf86CrtcScreenInit (ScreenPtr screen) | |
166 | ||
167 | This function completes the screen initialization process for the crtc and | |
168 | output objects. Call it near the end of the ScreenInit function, after the | |
169 | frame buffer and acceleration layers have been added. | |
170 | ||
171 | 3.3 EnterVT functions | |
172 | ||
173 | Functions used during EnterVT, or whenever the current configuration needs | |
174 | to be applied to the hardware. | |
175 | ||
176 | Bool | |
177 | xf86SetDesiredModes (ScrnInfoPtr scrn) | |
178 | ||
179 | xf86InitialConfiguration selects the desired configuration at PreInit time; | |
180 | when the server finally hits ScreenInit, xf86SetDesiredModes is used by the | |
181 | driver to take that configuration and apply it to the hardware. In addition, | |
182 | successful mode selection at other times updates the configuration that will | |
183 | be used by this function, so LeaveVT/EnterVT pairs can simply invoke this | |
184 | and return to the previous configuration. | |
185 | ||
186 | 3.4 SwitchMode functions | |
187 | ||
188 | Functions called from the pScrn->SwitchMode hook, which is used by the | |
189 | XFree86-VidModeExtension and the keypad mode switch commands. | |
190 | ||
191 | Bool | |
192 | xf86SetSingleMode (ScrnInfoPtr scrn, | |
193 | DisplayModePtr desired, | |
194 | Rotation rotation) | |
195 | ||
196 | This function applies the specified mode to all active outputs. Which is to | |
197 | say, it picks reasonable modes for all active outputs, attempting to get the | |
198 | screen to the specified size while not breaking anything that is currently | |
199 | working. | |
200 | ||
201 | 3.7 get_modes functions | |
202 | ||
203 | Functions called during output->get_modes to help build lists of modes | |
204 | ||
205 | xf86MonPtr | |
206 | xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) | |
207 | ||
208 | This returns the EDID data structure for the 'output' using the I2C bus | |
209 | 'pDDCBus'. This has no effect on 'output' itself. | |
210 | ||
211 | void | |
212 | xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon) | |
213 | ||
214 | Once the EDID data has been fetched, this call applies the EDID data to the | |
215 | output object, setting the physical size and also various properties, like | |
216 | the DDC root window property (when output is the 'compat' output), and the | |
217 | RandR 1.2 EDID output properties. | |
218 | ||
219 | DisplayModePtr | |
220 | xf86OutputGetEDIDModes (xf86OutputPtr output) | |
221 | ||
222 | Given an EDID data structure, this function computes a list of suitable | |
223 | modes. This function also applies a sequence of 'quirks' during this process | |
224 | so that the returned modes may not actually match the mode data present in | |
225 | the EDID data. | |
226 | ||
227 | 3.6 Other functions | |
228 | ||
229 | These remaining functions in the API can be used by the driver as needed. | |
230 | ||
231 | Bool | |
232 | xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, | |
233 | int x, int y) | |
234 | ||
235 | Applies a mode to a CRTC. All of the outputs which are currently using the | |
236 | specified CRTC are included in the mode setting process. 'x' and 'y' are the | |
237 | offset within the frame buffer that the crtc is placed at. No checking is | |
238 | done in this function to ensure that the mode is usable by the active | |
239 | outputs. | |
240 | ||
241 | void | |
242 | xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY) | |
243 | ||
244 | This discards the mode lists for all outputs, re-detects monitor presence | |
245 | and then acquires new mode lists for all monitors which are not disconnected. | |
246 | Monitor configuration data is used to modify the mode lists returned by the | |
247 | outputs. 'maxX' and 'maxY' limit the maximum size modes that will be | |
248 | returned. | |
249 | ||
250 | void | |
251 | xf86SetScrnInfoModes (ScrnInfoPtr pScrn) | |
252 | ||
253 | This copies the 'compat' output mode list into the pScrn modes list which is | |
254 | used by the XFree86-VidModeExtension and the keypad mode switching | |
255 | operations. The current 'desired' mode for the CRTC associated with the | |
256 | 'compat' output is placed first in this list to indicate the current mode. | |
257 | Usually, the driver won't need to call this function as | |
258 | xf86InitialConfiguration will do so automatically, as well as any RandR | |
259 | functions which reprobe for modes. However, if the driver reprobes for modes | |
260 | at other times using xf86ProbeOutputModes, this function needs to be called. | |
261 | ||
262 | Bool | |
263 | xf86DiDGAReInit (ScreenPtr pScreen) | |
264 | ||
265 | This is similar to xf86SetScrnInfoModes, but it applies the 'compat' output | |
266 | mode list to the set of modes advertised by the DGA extension; it needs to | |
267 | be called whenever xf86ProbeOutputModes is invoked. | |
268 | ||
269 | void | |
270 | xf86DisableUnusedFunctions(ScrnInfoPtr pScrn) | |
271 | ||
272 | After any sequence of calls using xf86CrtcSetMode, this function cleans up | |
273 | any leftover Output and CRTC objects by disabling them, saving power. It is | |
274 | safe to call this whenever the server is running as it only disables objects | |
275 | which are not currently in use. | |
276 | ||
277 | 4. CRTC operations | |
278 | ||
279 | 4.1 CRTC functions | |
280 | ||
281 | These functions provide an abstract interface for the CRTC object; most | |
282 | manipulation of the CRTC object is done through these functions. | |
283 | ||
284 | void | |
285 | crtc->funcs->dpms (xf86CrtcPtr crtc, int mode) | |
286 | ||
287 | Where 'mode' is one of DPMSModeOff, DPMSModeSuspend, DPMSModeStandby or | |
288 | DPMSModeOn. This requests that the crtc go to the specified power state. | |
289 | When changing power states, the output dpms functions are invoked before the | |
290 | crtc dpms functions. | |
291 | ||
292 | void | |
293 | crtc->funcs->save (xf86CrtcPtr crtc) | |
294 | ||
295 | void | |
296 | crtc->funcs->restore (xf86CrtcPtr crtc) | |
297 | ||
298 | Preserve/restore any register contents related to the CRTC. These are | |
299 | strictly a convenience for the driver writer; if the existing driver has | |
300 | fully operation save/restore functions, you need not place any additional | |
301 | code here. In particular, the server itself never uses this function. | |
302 | ||
303 | Bool | |
304 | crtc->funcs->lock (xf86CrtcPtr crtc) | |
305 | ||
306 | void | |
307 | crtc->funcs->unlock (xf86CrtcPtr crtc) | |
308 | ||
309 | These functions are invoked around mode setting operations; the intent is | |
310 | that DRI locking be done here to prevent DRI applications from manipulating | |
311 | the hardware while the server is busy changing the output configuration. If | |
312 | the lock function returns FALSE, the unlock function will not be invoked. | |
313 | ||
314 | Bool | |
315 | crtc->funcs->mode_fixup (xf86CrtcPtr crtc, | |
316 | DisplayModePtr mode, | |
317 | DisplayModePtr adjusted_mode) | |
318 | ||
319 | This call gives the CRTC a chance to see what mode will be set and to | |
320 | comment on the mode by changing 'adjusted_mode' as needed. This function | |
321 | shall not modify the state of the crtc hardware at all. If the CRTC cannot | |
322 | accept this mode, this function may return FALSE. | |
323 | ||
324 | void | |
325 | crtc->funcs->prepare (xf86CrtcPtr crtc) | |
326 | ||
327 | This call is made just before the mode is set to make the hardware ready for | |
328 | the operation. A usual function to perform here is to disable the crtc so | |
329 | that mode setting can occur with clocks turned off and outputs deactivated. | |
330 | ||
331 | void | |
332 | crtc->funcs->mode_set (xf86CrtcPtr crtc, | |
333 | DisplayModePtr mode, | |
334 | DisplayModePtr adjusted_mode) | |
335 | ||
336 | This function applies the specified mode (possibly adjusted by the CRTC | |
337 | and/or Outputs). | |
338 | ||
339 | void | |
340 | crtc->funcs->commit (xf86CrtcPtr crtc) | |
341 | ||
342 | Once the mode has been applied to the CRTC and Outputs, this function is | |
343 | invoked to let the hardware turn things back on. | |
344 | ||
345 | void | |
346 | crtc->funcs->gamma_set (xf86CrtcPtr crtc, CARD16 *red, | |
347 | CARD16 *green, CARD16 *blue, int size) | |
348 | ||
349 | This function adjusts the gamma ramps for the specified crtc. | |
350 | ||
351 | void * | |
352 | crtc->funcs->shadow_allocate (xf86CrtcPtr crtc, int width, int height) | |
353 | ||
354 | This function allocates frame buffer space for a shadow frame buffer. When | |
355 | allocated, the crtc must scan from the shadow instead of the main frame | |
356 | buffer. This is used for rotation. The address returned is passed to the | |
357 | shadow_create function. This function should return NULL on failure. | |
358 | ||
359 | PixmapPtr | |
360 | crtc->funcs->shadow_create (xf86CrtcPtr crtc, void *data, | |
361 | int width, int height) | |
362 | ||
363 | This function creates a pixmap object that will be used as a shadow of the | |
364 | main frame buffer for CRTCs which are rotated or reflected. 'data' is the | |
365 | value returned by shadow_allocate. | |
366 | ||
367 | void | |
368 | crtc->funcs->shadow_destroy (xf86CrtcPtr crtc, PixmapPtr pPixmap, | |
369 | void *data) | |
370 | ||
371 | Destroys any associated shadow objects. If pPixmap is NULL, then a pixmap | |
372 | was not created, but 'data' may still be non-NULL indicating that the shadow | |
373 | had been allocated. | |
374 | ||
375 | void | |
376 | crtc->funcs->destroy (xf86CrtcPtr crtc) | |
377 | ||
378 | When a CRTC is destroyed (which only happens in error cases), this function | |
379 | can clean up any driver-specific data. | |
380 | ||
381 | 4.2 CRTC fields | |
382 | ||
383 | The CRTC object is not opaque; there are several fields of interest to the | |
384 | driver writer. | |
385 | ||
386 | struct _xf86Crtc { | |
387 | /** | |
388 | * Associated ScrnInfo | |
389 | */ | |
390 | ScrnInfoPtr scrn; | |
391 | ||
392 | /** | |
393 | * Active state of this CRTC | |
394 | * | |
395 | * Set when this CRTC is driving one or more outputs | |
396 | */ | |
397 | Bool enabled; | |
398 | ||
399 | /** Track whether cursor is within CRTC range */ | |
400 | Bool cursorInRange; | |
401 | ||
402 | /** Track state of cursor associated with this CRTC */ | |
403 | Bool cursorShown; | |
404 | ||
405 | /** | |
406 | * Active mode | |
407 | * | |
408 | * This reflects the mode as set in the CRTC currently | |
409 | * It will be cleared when the VT is not active or | |
410 | * during server startup | |
411 | */ | |
412 | DisplayModeRec mode; | |
413 | Rotation rotation; | |
414 | PixmapPtr rotatedPixmap; | |
415 | void *rotatedData; | |
416 | ||
417 | /** | |
418 | * Position on screen | |
419 | * | |
420 | * Locates this CRTC within the frame buffer | |
421 | */ | |
422 | int x, y; | |
423 | ||
424 | /** | |
425 | * Desired mode | |
426 | * | |
427 | * This is set to the requested mode, independent of | |
428 | * whether the VT is active. In particular, it receives | |
429 | * the startup configured mode and saves the active mode | |
430 | * on VT switch. | |
431 | */ | |
432 | DisplayModeRec desiredMode; | |
433 | Rotation desiredRotation; | |
434 | int desiredX, desiredY; | |
435 | ||
436 | /** crtc-specific functions */ | |
437 | const xf86CrtcFuncsRec *funcs; | |
438 | ||
439 | /** | |
440 | * Driver private | |
441 | * | |
442 | * Holds driver-private information | |
443 | */ | |
444 | void *driver_private; | |
445 | #ifdef RANDR_12_INTERFACE | |
446 | /** | |
447 | * RandR crtc | |
448 | * | |
449 | * When RandR 1.2 is available, this | |
450 | * points at the associated crtc object | |
451 | */ | |
452 | RRCrtcPtr randr_crtc; | |
453 | #else | |
454 | void *randr_crtc; | |
455 | #endif | |
456 | }; | |
457 | ||
458 | ||
459 | 5. Output functions. | |
460 | ||
461 | 6. Configuration | |
462 | ||
463 | Because the configuration file syntax is fixed, | |
464 | this was done by creating new "Driver" section options that hook specific | |
465 | outputs to specific "Monitor" sections in the file. The option: | |
466 | section of the form: | |
467 | ||
468 | Option "monitor-VGA" "My VGA Monitor" | |
469 | ||
470 | connects the VGA output of this driver to the "Monitor" section with | |
471 | Identifier "My VGA Monitor". All of the usual monitor options can now be | |
472 | placed in that "Monitor" section and will be applied to the VGA output | |
473 | configuration. |