| 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. |