| 1 | <?xml version="1.0" encoding="ISO-8859-1"?> |
| 2 | <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" |
| 3 | "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ |
| 4 | <!ENTITY % defs SYSTEM "/xserver/doc/xml/xserver.ent"> %defs; |
| 5 | ]> |
| 6 | |
| 7 | <article> |
| 8 | |
| 9 | <articleinfo> |
| 10 | <!-- Title information --> |
| 11 | <title>Distributed Multihead X design</title> |
| 12 | <authorgroup> |
| 13 | <author><firstname>Kevin E.</firstname><surname>Martin</surname></author> |
| 14 | <author><firstname>David H.</firstname><surname>Dawes</surname></author> |
| 15 | <author><firstname>Rickard E.</firstname><surname>Faith</surname></author> |
| 16 | </authorgroup> |
| 17 | <pubdate>29 June 2004 (created 25 July 2001)</pubdate> |
| 18 | <releaseinfo>X Server Version &xserver.version;</releaseinfo> |
| 19 | <abstract><para> |
| 20 | This document covers the motivation, background, design, and |
| 21 | implementation of the distributed multihead X (DMX) system. It |
| 22 | is a living document and describes the current design and |
| 23 | implementation details of the DMX system. As the project |
| 24 | progresses, this document will be continually updated to reflect |
| 25 | the changes in the code and/or design. <emphasis remap="it">Copyright 2001 by VA |
| 26 | Linux Systems, Inc., Fremont, California. Copyright 2001-2004 |
| 27 | by Red Hat, Inc., Raleigh, North Carolina</emphasis> |
| 28 | </para></abstract> |
| 29 | </articleinfo> |
| 30 | |
| 31 | <!-- Begin the document --> |
| 32 | <sect1> |
| 33 | <title>Introduction</title> |
| 34 | |
| 35 | <sect2> |
| 36 | <title>The Distributed Multihead X Server</title> |
| 37 | |
| 38 | <para>Current Open Source multihead solutions are limited to a single |
| 39 | physical machine. A single X server controls multiple display devices, |
| 40 | which can be arranged as independent heads or unified into a single |
| 41 | desktop (with Xinerama). These solutions are limited to the number of |
| 42 | physical devices that can co-exist in a single machine (e.g., due to the |
| 43 | number of AGP/PCI slots available for graphics cards). Thus, large |
| 44 | tiled displays are not currently possible. The work described in this |
| 45 | paper will eliminate the requirement that the display devices reside in |
| 46 | the same physical machine. This will be accomplished by developing a |
| 47 | front-end proxy X server that will control multiple back-end X servers |
| 48 | that make up the large display. |
| 49 | </para> |
| 50 | |
| 51 | <para>The overall structure of the distributed multihead X (DMX) project is |
| 52 | as follows: A single front-end X server will act as a proxy to a set of |
| 53 | back-end X servers, which handle all of the visible rendering. X |
| 54 | clients will connect to the front-end server just as they normally would |
| 55 | to a regular X server. The front-end server will present an abstracted |
| 56 | view to the client of a single large display. This will ensure that all |
| 57 | standard X clients will continue to operate without modification |
| 58 | (limited, as always, by the visuals and extensions provided by the X |
| 59 | server). Clients that are DMX-aware will be able to use an extension to |
| 60 | obtain information about the back-end servers (e.g., for placement of |
| 61 | pop-up windows, window alignments by the window manager, etc.). |
| 62 | </para> |
| 63 | |
| 64 | <para>The architecture of the DMX server is divided into two main sections: |
| 65 | input (e.g., mouse and keyboard events) and output (e.g., rendering and |
| 66 | windowing requests). Each of these are describe briefly below, and the |
| 67 | rest of this design document will describe them in greater detail. |
| 68 | </para> |
| 69 | |
| 70 | <para>The DMX server can receive input from three general types of input |
| 71 | devices: "local" devices that are physically attached to the machine on |
| 72 | which DMX is running, "backend" devices that are physically attached to |
| 73 | one or more of the back-end X servers (and that generate events via the |
| 74 | X protocol stream from the backend), and "console" devices that can be |
| 75 | abstracted from any non-back-end X server. Backend and console devices |
| 76 | are treated differently because the pointer device on the back-end X |
| 77 | server also controls the location of the hardware X cursor. Full |
| 78 | support for XInput extension devices is provided. |
| 79 | </para> |
| 80 | |
| 81 | <para>Rendering requests will be accepted by the front-end server; however, |
| 82 | rendering to visible windows will be broken down as needed and sent to |
| 83 | the appropriate back-end server(s) via X11 library calls for actual |
| 84 | rendering. The basic framework will follow a Xnest-style approach. GC |
| 85 | state will be managed in the front-end server and sent to the |
| 86 | appropriate back-end server(s) as required. Pixmap rendering will (at |
| 87 | least initially) be handled by the front-end X server. Windowing |
| 88 | requests (e.g., ordering, mapping, moving, etc.) will handled in the |
| 89 | front-end server. If the request requires a visible change, the |
| 90 | windowing operation will be translated into requests for the appropriate |
| 91 | back-end server(s). Window state will be mirrored in the back-end |
| 92 | server(s) as needed. |
| 93 | </para> |
| 94 | </sect2> |
| 95 | |
| 96 | <sect2> |
| 97 | <title>Layout of Paper</title> |
| 98 | |
| 99 | <para>The next section describes the general development plan that was |
| 100 | actually used for implementation. The final section discusses |
| 101 | outstanding issues at the conclusion of development. The first appendix |
| 102 | provides low-level technical detail that may be of interest to those |
| 103 | intimately familiar with the X server architecture. The final appendix |
| 104 | describes the four phases of development that were performed during the |
| 105 | first two years of development. |
| 106 | </para> |
| 107 | |
| 108 | <para>The final year of work was divided into 9 tasks that are not |
| 109 | described in specific sections of this document. The major tasks during |
| 110 | that time were the enhancement of the reconfiguration ability added in |
| 111 | Phase IV, addition of support for a dynamic number of back-end displays |
| 112 | (instead of a hard-coded limit), and the support for back-end display |
| 113 | and input removal and addition. This work is mentioned in this paper, |
| 114 | but is not covered in detail. |
| 115 | </para> |
| 116 | </sect2> |
| 117 | </sect1> |
| 118 | |
| 119 | <!-- ============================================================ --> |
| 120 | <sect1> |
| 121 | <title>Development plan</title> |
| 122 | |
| 123 | <para>This section describes the development plan from approximately June |
| 124 | 2001 through July 2003. |
| 125 | </para> |
| 126 | |
| 127 | <sect2> |
| 128 | <title>Bootstrap code</title> |
| 129 | |
| 130 | <para>To allow for rapid development of the DMX server by multiple |
| 131 | developers during the first development stage, the problem will be |
| 132 | broken down into three tasks: the overall DMX framework, back-end |
| 133 | rendering services and input device handling services. However, before |
| 134 | the work begins on these tasks, a simple framework that each developer |
| 135 | could use was implemented to bootstrap the development effort. This |
| 136 | framework renders to a single back-end server and provides dummy input |
| 137 | devices (i.e., the keyboard and mouse). The simple back-end rendering |
| 138 | service was implemented using the shadow framebuffer support currently |
| 139 | available in the XFree86 environment. |
| 140 | </para> |
| 141 | |
| 142 | <para>Using this bootstrapping framework, each developer has been able to |
| 143 | work on each of the tasks listed above independently as follows: the |
| 144 | framework will be extended to handle arbitrary back-end server |
| 145 | configurations; the back-end rendering services will be transitioned to |
| 146 | the more efficient Xnest-style implementation; and, an input device |
| 147 | framework to handle various input devices via the input extension will |
| 148 | be developed. |
| 149 | </para> |
| 150 | |
| 151 | <para>Status: The boot strap code is complete. <!-- August 2001 --> |
| 152 | </para> |
| 153 | |
| 154 | </sect2> |
| 155 | |
| 156 | <sect2> |
| 157 | <title>Input device handling</title> |
| 158 | |
| 159 | <para>An X server (including the front-end X server) requires two core |
| 160 | input devices -- a keyboard and a pointer (mouse). These core devices |
| 161 | are handled and required by the core X11 protocol. Additional types of |
| 162 | input devices may be attached and utilized via the XInput extension. |
| 163 | These are usually referred to as ``XInput extension devices'', |
| 164 | </para> |
| 165 | |
| 166 | <para>There are some options as to how the front-end X server gets its core |
| 167 | input devices: |
| 168 | |
| 169 | <orderedlist> |
| 170 | <listitem> |
| 171 | <para>Local Input. The physical input devices (e.g., keyboard and |
| 172 | mouse) can be attached directly to the front-end X server. In this |
| 173 | case, the keyboard and mouse on the machine running the front-end X |
| 174 | server will be used. The front-end will have drivers to read the |
| 175 | raw input from those devices and convert it into the required X |
| 176 | input events (e.g., key press/release, pointer button press/release, |
| 177 | pointer motion). The front-end keyboard driver will keep track of |
| 178 | keyboard properties such as key and modifier mappings, autorepeat |
| 179 | state, keyboard sound and led state. Similarly the front-end |
| 180 | pointer driver will keep track if pointer properties such as the |
| 181 | button mapping and movement acceleration parameters. With this |
| 182 | option, input is handled fully in the front-end X server, and the |
| 183 | back-end X servers are used in a display-only mode. This option was |
| 184 | implemented and works for a limited number of Linux-specific |
| 185 | devices. Adding additional local input devices for other |
| 186 | architectures is expected to be relatively simple. |
| 187 | </para> |
| 188 | |
| 189 | <para>The following options are available for implementing local input |
| 190 | devices: |
| 191 | |
| 192 | <orderedlist> |
| 193 | <listitem> |
| 194 | <para>The XFree86 X server has modular input drivers that could |
| 195 | be adapted for this purpose. The mouse driver supports a wide |
| 196 | range of mouse types and interfaces, as well as a range of |
| 197 | Operating System platforms. The keyboard driver in XFree86 is |
| 198 | not currently as modular as the mouse driver, but could be made |
| 199 | so. The XFree86 X server also has a range of other input |
| 200 | drivers for extended input devices such as tablets and touch |
| 201 | screens. Unfortunately, the XFree86 drivers are generally |
| 202 | complex, often simultaneously providing support for multiple |
| 203 | devices across multiple architectures; and rely so heavily on |
| 204 | XFree86-specific helper-functions, that this option was not |
| 205 | pursued. |
| 206 | </para> |
| 207 | </listitem> |
| 208 | |
| 209 | <listitem> |
| 210 | <para>The <command>kdrive</command> X server in XFree86 has built-in drivers that |
| 211 | support PS/2 mice and keyboard under Linux. The mouse driver |
| 212 | can indirectly handle other mouse types if the Linux utility |
| 213 | <command>gpm</command> is used as to translate the native mouse protocol into |
| 214 | PS/2 mouse format. These drivers could be adapted and built in |
| 215 | to the front-end X server if this range of hardware and OS |
| 216 | support is sufficient. While much simpler than the XFree86 |
| 217 | drivers, the <command>kdrive</command> drivers were not used for the DMX |
| 218 | implementation. |
| 219 | </para> |
| 220 | </listitem> |
| 221 | |
| 222 | <listitem> |
| 223 | <para>Reimplementation of keyboard and mouse drivers from |
| 224 | scratch for the DMX framework. Because keyboard and mouse |
| 225 | drivers are relatively trivial to implement, this pathway was |
| 226 | selected. Other drivers in the X source tree were referenced, |
| 227 | and significant contributions from other drivers are noted in |
| 228 | the DMX source code. |
| 229 | </para> |
| 230 | </listitem> |
| 231 | </orderedlist> |
| 232 | </para> |
| 233 | </listitem> |
| 234 | |
| 235 | <listitem> |
| 236 | <para>Backend Input. The front-end can make use of the core input |
| 237 | devices attached to one or more of the back-end X servers. Core |
| 238 | input events from multiple back-ends are merged into a single input |
| 239 | event stream. This can work sanely when only a single set of input |
| 240 | devices is used at any given time. The keyboard and pointer state |
| 241 | will be handled in the front-end, with changes propagated to the |
| 242 | back-end servers as needed. This option was implemented and works |
| 243 | well. Because the core pointer on a back-end controls the hardware |
| 244 | mouse on that back-end, core pointers cannot be treated as XInput |
| 245 | extension devices. However, all back-end XInput extensions devices |
| 246 | can be mapped to either DMX core or DMX XInput extension devices. |
| 247 | </para> |
| 248 | </listitem> |
| 249 | |
| 250 | <listitem> |
| 251 | <para>Console Input. The front-end server could create a console |
| 252 | window that is displayed on an X server independent of the back-end |
| 253 | X servers. This console window could display things like the |
| 254 | physical screen layout, and the front-end could get its core input |
| 255 | events from events delivered to the console window. This option was |
| 256 | implemented and works well. To help the human navigate, window |
| 257 | outlines are also displayed in the console window. Further, console |
| 258 | windows can be used as either core or XInput extension devices. |
| 259 | </para> |
| 260 | </listitem> |
| 261 | |
| 262 | <listitem> |
| 263 | <para>Other options were initially explored, but they were all |
| 264 | partial subsets of the options listed above and, hence, are |
| 265 | irrelevant. |
| 266 | </para> |
| 267 | </listitem> |
| 268 | |
| 269 | </orderedlist> |
| 270 | </para> |
| 271 | |
| 272 | <para>Although extended input devices are not specifically mentioned in the |
| 273 | Distributed X requirements, the options above were all implemented so |
| 274 | that XInput extension devices were supported. |
| 275 | </para> |
| 276 | |
| 277 | <para>The bootstrap code (Xdmx) had dummy input devices, and these are |
| 278 | still supported in the final version. These do the necessary |
| 279 | initialization to satisfy the X server's requirements for core pointer |
| 280 | and keyboard devices, but no input events are ever generated. |
| 281 | </para> |
| 282 | |
| 283 | <para>Status: The input code is complete. Because of the complexity of the |
| 284 | XFree86 input device drivers (and their heavy reliance on XFree86 |
| 285 | infrastructure), separate low-level device drivers were implemented for |
| 286 | Xdmx. The following kinds of drivers are supported (in general, the |
| 287 | devices can be treated arbitrarily as "core" input devices or as XInput |
| 288 | "extension" devices; and multiple instances of different kinds of |
| 289 | devices can be simultaneously available): |
| 290 | <orderedlist> |
| 291 | <listitem> |
| 292 | <para> A "dummy" device drive that never generates events. |
| 293 | </para> |
| 294 | </listitem> |
| 295 | |
| 296 | <listitem> |
| 297 | <para> "Local" input is from the low-level hardware on which the |
| 298 | Xdmx binary is running. This is the only area where using the |
| 299 | XFree86 driver infrastructure would have been helpful, and then |
| 300 | only partially, since good support for generic USB devices does |
| 301 | not yet exist in XFree86 (in any case, XFree86 and kdrive driver |
| 302 | code was used where possible). Currently, the following local |
| 303 | devices are supported under Linux (porting to other operating |
| 304 | systems should be fairly straightforward): |
| 305 | <itemizedlist> |
| 306 | <listitem><para>Linux keyboard</para></listitem> |
| 307 | <listitem><para>Linux serial mouse (MS)</para></listitem> |
| 308 | <listitem><para>Linux PS/2 mouse</para></listitem> |
| 309 | <listitem><para>USB keyboard</para></listitem> |
| 310 | <listitem><para>USB mouse</para></listitem> |
| 311 | <listitem><para>USB generic device (e.g., joystick, gamepad, etc.)</para></listitem> |
| 312 | </itemizedlist> |
| 313 | </para> |
| 314 | </listitem> |
| 315 | |
| 316 | <listitem> |
| 317 | <para> "Backend" input is taken from one or more of the back-end |
| 318 | displays. In this case, events are taken from the back-end X |
| 319 | server and are converted to Xdmx events. Care must be taken so |
| 320 | that the sprite moves properly on the display from which input |
| 321 | is being taken. |
| 322 | </para> |
| 323 | </listitem> |
| 324 | |
| 325 | <listitem> |
| 326 | <para> "Console" input is taken from an X window that Xdmx |
| 327 | creates on the operator's display (i.e., on the machine running |
| 328 | the Xdmx binary). When the operator's mouse is inside the |
| 329 | console window, then those events are converted to Xdmx events. |
| 330 | Several special features are available: the console can display |
| 331 | outlines of windows that are on the Xdmx display (to facilitate |
| 332 | navigation), the cursor can be confined to the console, and a |
| 333 | "fine" mode can be activated to allow very precise cursor |
| 334 | positioning. |
| 335 | </para> |
| 336 | </listitem> |
| 337 | </orderedlist> |
| 338 | |
| 339 | </para> |
| 340 | |
| 341 | </sect2> |
| 342 | |
| 343 | <!-- May 2002; July 2003 --> |
| 344 | |
| 345 | <sect2> |
| 346 | <title>Output device handling</title> |
| 347 | |
| 348 | <para>The output of the DMX system displays rendering and windowing |
| 349 | requests across multiple screens. The screens are typically arranged in |
| 350 | a grid such that together they represent a single large display. |
| 351 | </para> |
| 352 | |
| 353 | <para>The output section of the DMX code consists of two parts. The first |
| 354 | is in the front-end proxy X server (Xdmx), which accepts client |
| 355 | connections, manages the windows, and potentially renders primitives but |
| 356 | does not actually display any of the drawing primitives. The second |
| 357 | part is the back-end X server(s), which accept commands from the |
| 358 | front-end server and display the results on their screens. |
| 359 | </para> |
| 360 | |
| 361 | <sect3> |
| 362 | <title>Initialization</title> |
| 363 | |
| 364 | <para>The DMX front-end must first initialize its screens by connecting to |
| 365 | each of the back-end X servers and collecting information about each of |
| 366 | these screens. However, the information collected from the back-end X |
| 367 | servers might be inconsistent. Handling these cases can be difficult |
| 368 | and/or inefficient. For example, a two screen system has one back-end X |
| 369 | server running at 16bpp while the second is running at 32bpp. |
| 370 | Converting rendering requests (e.g., XPutImage() or XGetImage() |
| 371 | requests) to the appropriate bit depth can be very time consuming. |
| 372 | Analyzing these cases to determine how or even if it is possible to |
| 373 | handle them is required. The current Xinerama code handles many of |
| 374 | these cases (e.g., in PanoramiXConsolidate()) and will be used as a |
| 375 | starting point. In general, the best solution is to use homogeneous X |
| 376 | servers and display devices. Using back-end servers with the same depth |
| 377 | is a requirement of the final DMX implementation. |
| 378 | </para> |
| 379 | |
| 380 | <para>Once this screen consolidation is finished, the relative position of |
| 381 | each back-end X server's screen in the unified screen is initialized. A |
| 382 | full-screen window is opened on each of the back-end X servers, and the |
| 383 | cursor on each screen is turned off. The final DMX implementation can |
| 384 | also make use of a partial-screen window, or multiple windows per |
| 385 | back-end screen. |
| 386 | </para> |
| 387 | </sect3> |
| 388 | |
| 389 | <sect3> |
| 390 | <title>Handling rendering requests</title> |
| 391 | |
| 392 | <para>After initialization, X applications connect to the front-end server. |
| 393 | There are two possible implementations of how rendering and windowing |
| 394 | requests are handled in the DMX system: |
| 395 | |
| 396 | <orderedlist> |
| 397 | <listitem> |
| 398 | <para>A shadow framebuffer is used in the front-end server as the |
| 399 | render target. In this option, all protocol requests are completely |
| 400 | handled in the front-end server. All state and resources are |
| 401 | maintained in the front-end including a shadow copy of the entire |
| 402 | framebuffer. The framebuffers attached to the back-end servers are |
| 403 | updated by XPutImage() calls with data taken directly from the |
| 404 | shadow framebuffer. |
| 405 | </para> |
| 406 | |
| 407 | <para>This solution suffers from two main problems. First, it does not |
| 408 | take advantage of any accelerated hardware available in the system. |
| 409 | Second, the size of the XPutImage() calls can be quite large and |
| 410 | thus will be limited by the bandwidth available. |
| 411 | </para> |
| 412 | |
| 413 | <para>The initial DMX implementation used a shadow framebuffer by |
| 414 | default. |
| 415 | </para> |
| 416 | </listitem> |
| 417 | |
| 418 | <listitem> |
| 419 | <para>Rendering requests are sent to each back-end server for |
| 420 | handling (as is done in the Xnest server described above). In this |
| 421 | option, certain protocol requests are handled in the front-end |
| 422 | server and certain requests are repackaged and then sent to the |
| 423 | back-end servers. The framebuffer is distributed across the |
| 424 | multiple back-end servers. Rendering to the framebuffer is handled |
| 425 | on each back-end and can take advantage of any acceleration |
| 426 | available on the back-end servers' graphics display device. State |
| 427 | is maintained both in the front and back-end servers. |
| 428 | </para> |
| 429 | |
| 430 | <para>This solution suffers from two main drawbacks. First, protocol |
| 431 | requests are sent to all back-end servers -- even those that will |
| 432 | completely clip the rendering primitive -- which wastes bandwidth |
| 433 | and processing time. Second, state is maintained both in the front- |
| 434 | and back-end servers. These drawbacks are not as severe as in |
| 435 | option 1 (above) and can either be overcome through optimizations or |
| 436 | are acceptable. Therefore, this option will be used in the final |
| 437 | implementation. |
| 438 | </para> |
| 439 | |
| 440 | <para>The final DMX implementation defaults to this mechanism, but also |
| 441 | supports the shadow framebuffer mechanism. Several optimizations |
| 442 | were implemented to eliminate the drawbacks of the default |
| 443 | mechanism. These optimizations are described the section below and |
| 444 | in Phase II of the Development Results (see appendix). |
| 445 | </para> |
| 446 | </listitem> |
| 447 | |
| 448 | </orderedlist> |
| 449 | </para> |
| 450 | |
| 451 | <para>Status: Both the shadow framebuffer and Xnest-style code is complete. |
| 452 | <!-- May 2002 --> |
| 453 | </para> |
| 454 | |
| 455 | </sect3> |
| 456 | </sect2> |
| 457 | |
| 458 | <sect2> |
| 459 | <title>Optimizing DMX</title> |
| 460 | |
| 461 | <para>Initially, the Xnest-style solution's performance will be measured |
| 462 | and analyzed to determine where the performance bottlenecks exist. |
| 463 | There are four main areas that will be addressed. |
| 464 | </para> |
| 465 | |
| 466 | <para>First, to obtain reasonable interactivity with the first development |
| 467 | phase, XSync() was called after each protocol request. The XSync() |
| 468 | function flushes any pending protocol requests. It then waits for the |
| 469 | back-end to process the request and send a reply that the request has |
| 470 | completed. This happens with each back-end server and performance |
| 471 | greatly suffers. As a result of the way XSync() is called in the first |
| 472 | development phase, the batching that the X11 library performs is |
| 473 | effectively defeated. The XSync() call usage will be analyzed and |
| 474 | optimized by batching calls and performing them at regular intervals, |
| 475 | except where interactivity will suffer (e.g., on cursor movements). |
| 476 | </para> |
| 477 | |
| 478 | <para>Second, the initial Xnest-style solution described above sends the |
| 479 | repackaged protocol requests to all back-end servers regardless of |
| 480 | whether or not they would be completely clipped out. The requests that |
| 481 | are trivially rejected on the back-end server wastes the limited |
| 482 | bandwidth available. By tracking clipping changes in the DMX X server's |
| 483 | windowing code (e.g., by opening, closing, moving or resizing windows), |
| 484 | we can determine whether or not back-end windows are visible so that |
| 485 | trivial tests in the front-end server's GC ops drawing functions can |
| 486 | eliminate these unnecessary protocol requests. |
| 487 | </para> |
| 488 | |
| 489 | <para>Third, each protocol request will be analyzed to determine if it is |
| 490 | possible to break the request into smaller pieces at display boundaries. |
| 491 | The initial ones to be analyzed are put and get image requests since |
| 492 | they will require the greatest bandwidth to transmit data between the |
| 493 | front and back-end servers. Other protocol requests will be analyzed |
| 494 | and those that will benefit from breaking them into smaller requests |
| 495 | will be implemented. |
| 496 | </para> |
| 497 | |
| 498 | <para>Fourth, an extension is being considered that will allow font glyphs to |
| 499 | be transferred from the front-end DMX X server to each back-end server. |
| 500 | This extension will permit the front-end to handle all font requests and |
| 501 | eliminate the requirement that all back-end X servers share the exact |
| 502 | same fonts as the front-end server. We are investigating the |
| 503 | feasibility of this extension during this development phase. |
| 504 | </para> |
| 505 | |
| 506 | <para>Other potential optimizations will be determined from the performance |
| 507 | analysis. |
| 508 | </para> |
| 509 | |
| 510 | <para>Please note that in our initial design, we proposed optimizing BLT |
| 511 | operations (e.g., XCopyArea() and window moves) by developing an |
| 512 | extension that would allow individual back-end servers to directly copy |
| 513 | pixel data to other back-end servers. This potential optimization was |
| 514 | in response to the simple image movement implementation that required |
| 515 | potentially many calls to GetImage() and PutImage(). However, the |
| 516 | current Xinerama implementation handles these BLT operations |
| 517 | differently. Instead of copying data to and from screens, they generate |
| 518 | expose events -- just as happens in the case when a window is moved from |
| 519 | off a screen to on screen. This approach saves the limited bandwidth |
| 520 | available between front and back-end servers and is being standardized |
| 521 | with Xinerama. It also eliminates the potential setup problems and |
| 522 | security issues resulting from having each back-end server open |
| 523 | connections to all other back-end servers. Therefore, we suggest |
| 524 | accepting Xinerama's expose event solution. |
| 525 | </para> |
| 526 | |
| 527 | <para>Also note that the approach proposed in the second and third |
| 528 | optimizations might cause backing store algorithms in the back-end to be |
| 529 | defeated, so a DMX X server configuration flag will be added to disable |
| 530 | these optimizations. |
| 531 | </para> |
| 532 | |
| 533 | <para>Status: The optimizations proposed above are complete. It was |
| 534 | determined that the using the xfs font server was sufficient and |
| 535 | creating a new mechanism to pass glyphs was redundant; therefore, the |
| 536 | fourth optimization proposed above was not included in DMX. |
| 537 | <!-- September 2002 --> |
| 538 | </para> |
| 539 | |
| 540 | </sect2> |
| 541 | |
| 542 | <sect2> |
| 543 | <title>DMX X extension support</title> |
| 544 | |
| 545 | <para>The DMX X server keeps track of all the windowing information on the |
| 546 | back-end X servers, but does not currently export this information to |
| 547 | any client applications. An extension will be developed to pass the |
| 548 | screen information and back-end window IDs to DMX-aware clients. These |
| 549 | clients can then use this information to directly connect to and render |
| 550 | to the back-end windows. Bypassing the DMX X server allows DMX-aware |
| 551 | clients to break up complex rendering requests on their own and send |
| 552 | them directly to the windows on the back-end server's screens. An |
| 553 | example of a client that can make effective use of this extension is |
| 554 | Chromium. |
| 555 | </para> |
| 556 | |
| 557 | <para>Status: The extension, as implemented, is fully documented in |
| 558 | "Client-to-Server DMX Extension to the X Protocol". Future changes |
| 559 | might be required based on feedback and other proposed enhancements to |
| 560 | DMX. Currently, the following facilities are supported: |
| 561 | <orderedlist> |
| 562 | <listitem><para> |
| 563 | Screen information (clipping rectangle for each screen relative |
| 564 | to the virtual screen) |
| 565 | </para></listitem> |
| 566 | <listitem><para> |
| 567 | Window information (window IDs and clipping information for each |
| 568 | back-end window that corresponds to each DMX window) |
| 569 | </para></listitem> |
| 570 | <listitem><para> |
| 571 | Input device information (mappings from DMX device IDs to |
| 572 | back-end device IDs) |
| 573 | </para></listitem> |
| 574 | <listitem><para> |
| 575 | Force window creation (so that a client can override the |
| 576 | server-side lazy window creation optimization) |
| 577 | </para></listitem> |
| 578 | <listitem><para> |
| 579 | Reconfiguration (so that a client can request that a screen |
| 580 | position be changed) |
| 581 | </para></listitem> |
| 582 | <listitem><para> |
| 583 | Addition and removal of back-end servers and back-end and |
| 584 | console inputs. |
| 585 | </para></listitem> |
| 586 | </orderedlist> |
| 587 | </para> |
| 588 | <!-- September 2002; July 2003 --> |
| 589 | |
| 590 | </sect2> |
| 591 | |
| 592 | <sect2> |
| 593 | <title>Common X extension support</title> |
| 594 | |
| 595 | <para>The XInput, XKeyboard and Shape extensions are commonly used |
| 596 | extensions to the base X11 protocol. XInput allows multiple and |
| 597 | non-standard input devices to be accessed simultaneously. These input |
| 598 | devices can be connected to either the front-end or back-end servers. |
| 599 | XKeyboard allows much better keyboard mappings control. Shape adds |
| 600 | support for arbitrarily shaped windows and is used by various window |
| 601 | managers. Nearly all potential back-end X servers make these extensions |
| 602 | available, and support for each one will be added to the DMX system. |
| 603 | </para> |
| 604 | |
| 605 | <para>In addition to the extensions listed above, support for the X |
| 606 | Rendering extension (Render) is being developed. Render adds digital |
| 607 | image composition to the rendering model used by the X Window System. |
| 608 | While this extension is still under development by Keith Packard of HP, |
| 609 | support for the current version will be added to the DMX system. |
| 610 | </para> |
| 611 | |
| 612 | <para>Support for the XTest extension was added during the first |
| 613 | development phase. |
| 614 | </para> |
| 615 | |
| 616 | <!-- WARNING: this list is duplicated in the Phase IV discussion --> |
| 617 | <para>Status: The following extensions are supported and are discussed in |
| 618 | more detail in Phase IV of the Development Results (see appendix): |
| 619 | BIG-REQUESTS, |
| 620 | DEC-XTRAP, |
| 621 | DMX, |
| 622 | DPMS, |
| 623 | Extended-Visual-Information, |
| 624 | GLX, |
| 625 | LBX, |
| 626 | RECORD, |
| 627 | RENDER, |
| 628 | SECURITY, |
| 629 | SHAPE, |
| 630 | SYNC, |
| 631 | X-Resource, |
| 632 | XC-APPGROUP, |
| 633 | XC-MISC, |
| 634 | XFree86-Bigfont, |
| 635 | XINERAMA, |
| 636 | XInputExtension, |
| 637 | XKEYBOARD, and |
| 638 | XTEST. |
| 639 | <!-- November 2002; updated February 2003, July 2003 --> |
| 640 | </para> |
| 641 | </sect2> |
| 642 | |
| 643 | <sect2> |
| 644 | <title>OpenGL support</title> |
| 645 | |
| 646 | <para>OpenGL support using the Mesa code base exists in XFree86 release 4 |
| 647 | and later. Currently, the direct rendering infrastructure (DRI) |
| 648 | provides accelerated OpenGL support for local clients and unaccelerated |
| 649 | OpenGL support (i.e., software rendering) is provided for non-local |
| 650 | clients. |
| 651 | </para> |
| 652 | |
| 653 | <para>The single head OpenGL support in XFree86 4.x will be extended to use |
| 654 | the DMX system. When the front and back-end servers are on the same |
| 655 | physical hardware, it is possible to use the DRI to directly render to |
| 656 | the back-end servers. First, the existing DRI will be extended to |
| 657 | support multiple display heads, and then to support the DMX system. |
| 658 | OpenGL rendering requests will be direct rendering to each back-end X |
| 659 | server. The DRI will request the screen layout (either from the |
| 660 | existing Xinerama extension or a DMX-specific extension). Support for |
| 661 | synchronized swap buffers will also be added (on hardware that supports |
| 662 | it). Note that a single front-end server with a single back-end server |
| 663 | on the same physical machine can emulate accelerated indirect rendering. |
| 664 | </para> |
| 665 | |
| 666 | <para>When the front and back-end servers are on different physical |
| 667 | hardware or are using non-XFree86 4.x X servers, a mechanism to render |
| 668 | primitives across the back-end servers will be provided. There are |
| 669 | several options as to how this can be implemented. |
| 670 | </para> |
| 671 | |
| 672 | <orderedlist> |
| 673 | <listitem> |
| 674 | <para>The existing OpenGL support in each back-end server can be |
| 675 | used by repackaging rendering primitives and sending them to each |
| 676 | back-end server. This option is similar to the unoptimized |
| 677 | Xnest-style approach mentioned above. Optimization of this solution |
| 678 | is beyond the scope of this project and is better suited to other |
| 679 | distributed rendering systems. |
| 680 | </para></listitem> |
| 681 | |
| 682 | <listitem> |
| 683 | <para>Rendering to a pixmap in the front-end server using the |
| 684 | current XFree86 4.x code, and then displaying to the back-ends via |
| 685 | calls to XPutImage() is another option. This option is similar to |
| 686 | the shadow frame buffer approach mentioned above. It is slower and |
| 687 | bandwidth intensive, but has the advantage that the back-end servers |
| 688 | are not required to have OpenGL support. |
| 689 | </para></listitem> |
| 690 | </orderedlist> |
| 691 | |
| 692 | <para>These, and other, options will be investigated in this phase of the |
| 693 | work. |
| 694 | </para> |
| 695 | |
| 696 | <para>Work by others have made Chromium DMX-aware. Chromium will use the |
| 697 | DMX X protocol extension to obtain information about the back-end |
| 698 | servers and will render directly to those servers, bypassing DMX. |
| 699 | </para> |
| 700 | |
| 701 | <para>Status: OpenGL support by the glxProxy extension was implemented by |
| 702 | SGI and has been integrated into the DMX code base. |
| 703 | </para> |
| 704 | <!-- May 2003--> |
| 705 | </sect2> |
| 706 | |
| 707 | </sect1> |
| 708 | |
| 709 | <!-- ============================================================ --> |
| 710 | <sect1> |
| 711 | <title>Current issues</title> |
| 712 | |
| 713 | <para>In this sections the current issues are outlined that require further |
| 714 | investigation. |
| 715 | </para> |
| 716 | |
| 717 | <sect2> |
| 718 | <title>Fonts</title> |
| 719 | |
| 720 | <para>The font path and glyphs need to be the same for the front-end and |
| 721 | each of the back-end servers. Font glyphs could be sent to the back-end |
| 722 | servers as necessary but this would consume a significant amount of |
| 723 | available bandwidth during font rendering for clients that use many |
| 724 | different fonts (e.g., Netscape). Initially, the font server (xfs) will |
| 725 | be used to provide the fonts to both the front-end and back-end servers. |
| 726 | Other possibilities will be investigated during development. |
| 727 | </para> |
| 728 | </sect2> |
| 729 | |
| 730 | <sect2> |
| 731 | <title>Zero width rendering primitives</title> |
| 732 | |
| 733 | <para>To allow pixmap and on-screen rendering to be pixel perfect, all |
| 734 | back-end servers must render zero width primitives exactly the same as |
| 735 | the front-end renders the primitives to pixmaps. For those back-end |
| 736 | servers that do not exactly match, zero width primitives will be |
| 737 | automatically converted to one width primitives. This can be handled in |
| 738 | the front-end server via the GC state. |
| 739 | </para> |
| 740 | </sect2> |
| 741 | |
| 742 | <sect2> |
| 743 | <title>Output scaling</title> |
| 744 | |
| 745 | <para>With very large tiled displays, it might be difficult to read the |
| 746 | information on the standard X desktop. In particular, the cursor can be |
| 747 | easily lost and fonts could be difficult to read. Automatic primitive |
| 748 | scaling might prove to be very useful. We will investigate the |
| 749 | possibility of scaling the cursor and providing a set of alternate |
| 750 | pre-scaled fonts to replace the standard fonts that many applications |
| 751 | use (e.g., fixed). Other options for automatic scaling will also be |
| 752 | investigated. |
| 753 | </para> |
| 754 | </sect2> |
| 755 | |
| 756 | <sect2> |
| 757 | <title>Per-screen colormaps</title> |
| 758 | |
| 759 | <para>Each screen's default colormap in the set of back-end X servers |
| 760 | should be able to be adjusted via a configuration utility. This support |
| 761 | is would allow the back-end screens to be calibrated via custom gamma |
| 762 | tables. On 24-bit systems that support a DirectColor visual, this type |
| 763 | of correction can be accommodated. One possible implementation would be |
| 764 | to advertise to X client of the DMX server a TrueColor visual while |
| 765 | using DirectColor visuals on the back-end servers to implement this type |
| 766 | of color correction. Other options will be investigated. |
| 767 | </para> |
| 768 | </sect2> |
| 769 | </sect1> |
| 770 | |
| 771 | <!-- ============================================================ --> |
| 772 | <appendix> |
| 773 | <title>Appendix</title> |
| 774 | |
| 775 | <sect1> |
| 776 | <title>Background</title> |
| 777 | |
| 778 | <para>This section describes the existing Open Source architectures that |
| 779 | can be used to handle multiple screens and upon which this development |
| 780 | project is based. This section was written before the implementation |
| 781 | was finished, and may not reflect actual details of the implementation. |
| 782 | It is left for historical interest only. |
| 783 | </para> |
| 784 | |
| 785 | <sect2> |
| 786 | <title>Core input device handling</title> |
| 787 | |
| 788 | <para>The following is a description of how core input devices are handled |
| 789 | by an X server. |
| 790 | </para> |
| 791 | |
| 792 | <sect3> |
| 793 | <title>InitInput()</title> |
| 794 | |
| 795 | <para>InitInput() is a DDX function that is called at the start of each |
| 796 | server generation from the X server's main() function. Its purpose is |
| 797 | to determine what input devices are connected to the X server, register |
| 798 | them with the DIX and MI layers, and initialize the input event queue. |
| 799 | InitInput() does not have a return value, but the X server will abort if |
| 800 | either a core keyboard device or a core pointer device are not |
| 801 | registered. Extended input (XInput) devices can also be registered in |
| 802 | InitInput(). |
| 803 | </para> |
| 804 | |
| 805 | <para>InitInput() usually has implementation specific code to determine |
| 806 | which input devices are available. For each input device it will be |
| 807 | using, it calls AddInputDevice(): |
| 808 | |
| 809 | <variablelist> |
| 810 | <varlistentry> |
| 811 | <term>AddInputDevice()</term> |
| 812 | <listitem><para>This DIX function allocates the device structure, |
| 813 | registers a callback function (which handles device init, close, on and |
| 814 | off), and returns the input handle, which can be treated as opaque. It |
| 815 | is called once for each input device. |
| 816 | </para></listitem> |
| 817 | </varlistentry> |
| 818 | </variablelist> |
| 819 | </para> |
| 820 | |
| 821 | <para>Once input handles for core keyboard and core pointer devices have |
| 822 | been obtained from AddInputDevice(). If both core devices are not |
| 823 | registered, then the X server will exit with a fatal error when it |
| 824 | attempts to start the input devices in InitAndStartDevices(), which is |
| 825 | called directly after InitInput() (see below). |
| 826 | </para> |
| 827 | |
| 828 | <para>The core pointer device is then registered with the miPointer code |
| 829 | (which does the high level cursor handling). While this registration |
| 830 | is not necessary for correct miPointer operation in the current XFree86 |
| 831 | code, it is still done mostly for compatibility reasons. |
| 832 | </para> |
| 833 | |
| 834 | <para><variablelist> |
| 835 | |
| 836 | <varlistentry> |
| 837 | <term>miRegisterPointerDevice()</term> |
| 838 | <listitem><para>This MI function registers the core |
| 839 | pointer's input handle with with the miPointer code. |
| 840 | </para></listitem></varlistentry> |
| 841 | </variablelist> |
| 842 | </para> |
| 843 | |
| 844 | <para>The final part of InitInput() is the initialization of the input |
| 845 | event queue handling. In most cases, the event queue handling provided |
| 846 | in the MI layer is used. The primary XFree86 X server uses its own |
| 847 | event queue handling to support some special cases related to the XInput |
| 848 | extension and the XFree86-specific DGA extension. For our purposes, the |
| 849 | MI event queue handling should be suitable. It is initialized by |
| 850 | calling mieqInit(): |
| 851 | |
| 852 | <variablelist> |
| 853 | <varlistentry> |
| 854 | <term>mieqInit()</term> |
| 855 | <listitem><para>This MI function initializes the MI event queue for the |
| 856 | core devices, and is passed the public component of the input handles |
| 857 | for the two core devices. |
| 858 | </para></listitem></varlistentry> |
| 859 | </variablelist> |
| 860 | </para> |
| 861 | |
| 862 | <para>If a wakeup handler is required to deliver synchronous input |
| 863 | events, it can be registered here by calling the DIX function |
| 864 | RegisterBlockAndWakeupHandlers(). (See the devReadInput() description |
| 865 | below.) |
| 866 | </para> |
| 867 | </sect3> |
| 868 | |
| 869 | <sect3> |
| 870 | <title>InitAndStartDevices()</title> |
| 871 | |
| 872 | <para>InitAndStartDevices() is a DIX function that is called immediately |
| 873 | after InitInput() from the X server's main() function. Its purpose is |
| 874 | to initialize each input device that was registered with |
| 875 | AddInputDevice(), enable each input device that was successfully |
| 876 | initialized, and create the list of enabled input devices. Once each |
| 877 | registered device is processed in this way, the list of enabled input |
| 878 | devices is checked to make sure that both a core keyboard device and |
| 879 | core pointer device were registered and successfully enabled. If not, |
| 880 | InitAndStartDevices() returns failure, and results in the the X server |
| 881 | exiting with a fatal error. |
| 882 | </para> |
| 883 | |
| 884 | <para>Each registered device is initialized by calling its callback |
| 885 | (dev->deviceProc) with the DEVICE_INIT argument: |
| 886 | |
| 887 | <variablelist> |
| 888 | <varlistentry> |
| 889 | <term>(*dev->deviceProc)(dev, DEVICE_INIT)</term> |
| 890 | <listitem> |
| 891 | <para>This function initializes the |
| 892 | device structs with core information relevant to the device. |
| 893 | </para> |
| 894 | |
| 895 | <para>For pointer devices, this means specifying the number of buttons, |
| 896 | default button mapping, the function used to get motion events (usually |
| 897 | miPointerGetMotionEvents()), the function used to change/control the |
| 898 | core pointer motion parameters (acceleration and threshold), and the |
| 899 | motion buffer size. |
| 900 | </para> |
| 901 | |
| 902 | <para>For keyboard devices, this means specifying the keycode range, |
| 903 | default keycode to keysym mapping, default modifier mapping, and the |
| 904 | functions used to sound the keyboard bell and modify/control the |
| 905 | keyboard parameters (LEDs, bell pitch and duration, key click, which |
| 906 | keys are auto-repeating, etc). |
| 907 | </para></listitem></varlistentry> |
| 908 | </variablelist> |
| 909 | </para> |
| 910 | |
| 911 | <para>Each initialized device is enabled by calling EnableDevice(): |
| 912 | |
| 913 | <variablelist> |
| 914 | <varlistentry> |
| 915 | <term>EnableDevice()</term> |
| 916 | <listitem> |
| 917 | <para>EnableDevice() calls the device callback with |
| 918 | DEVICE_ON: |
| 919 | <variablelist> |
| 920 | <varlistentry> |
| 921 | <term>(*dev->deviceProc)(dev, DEVICE_ON)</term> |
| 922 | <listitem> |
| 923 | <para>This typically opens and |
| 924 | initializes the relevant physical device, and when appropriate, |
| 925 | registers the device's file descriptor (or equivalent) as a valid |
| 926 | input source. |
| 927 | </para></listitem></varlistentry> |
| 928 | </variablelist> |
| 929 | </para> |
| 930 | |
| 931 | <para>EnableDevice() then adds the device handle to the X server's |
| 932 | global list of enabled devices. |
| 933 | </para></listitem></varlistentry> |
| 934 | </variablelist> |
| 935 | </para> |
| 936 | |
| 937 | <para>InitAndStartDevices() then verifies that a valid core keyboard and |
| 938 | pointer has been initialized and enabled. It returns failure if either |
| 939 | are missing. |
| 940 | </para> |
| 941 | </sect3> |
| 942 | |
| 943 | <sect3> |
| 944 | <title>devReadInput()</title> |
| 945 | |
| 946 | <para>Each device will have some function that gets called to read its |
| 947 | physical input. These may be called in a number of different ways. In |
| 948 | the case of synchronous I/O, they will be called from a DDX |
| 949 | wakeup-handler that gets called after the server detects that new input is |
| 950 | available. In the case of asynchronous I/O, they will be called from a |
| 951 | (SIGIO) signal handler triggered when new input is available. This |
| 952 | function should do at least two things: make sure that input events get |
| 953 | enqueued, and make sure that the cursor gets moved for motion events |
| 954 | (except if these are handled later by the driver's own event queue |
| 955 | processing function, which cannot be done when using the MI event queue |
| 956 | handling). |
| 957 | </para> |
| 958 | |
| 959 | <para>Events are queued by calling mieqEnqueue(): |
| 960 | |
| 961 | <variablelist> |
| 962 | <varlistentry> |
| 963 | <term>mieqEnqueue()</term> |
| 964 | <listitem> |
| 965 | <para>This MI function is used to add input events to the |
| 966 | event queue. It is simply passed the event to be queued. |
| 967 | </para></listitem></varlistentry> |
| 968 | </variablelist> |
| 969 | </para> |
| 970 | |
| 971 | <para>The cursor position should be updated when motion events are |
| 972 | enqueued by calling miPointerDeltaCursor(): |
| 973 | |
| 974 | <variablelist> |
| 975 | <varlistentry> |
| 976 | <term>miPointerDeltaCursor()</term> |
| 977 | <listitem> |
| 978 | <para>This MI function is used to move the cursor |
| 979 | relative to its current position. |
| 980 | </para></listitem></varlistentry> |
| 981 | </variablelist> |
| 982 | </para> |
| 983 | </sect3> |
| 984 | |
| 985 | <sect3> |
| 986 | <title>ProcessInputEvents()</title> |
| 987 | |
| 988 | <para>ProcessInputEvents() is a DDX function that is called from the X |
| 989 | server's main dispatch loop when new events are available in the input |
| 990 | event queue. It typically processes the enqueued events, and updates |
| 991 | the cursor/pointer position. It may also do other DDX-specific event |
| 992 | processing. |
| 993 | </para> |
| 994 | |
| 995 | <para>Enqueued events are processed by mieqProcessInputEvents() and passed |
| 996 | to the DIX layer for transmission to clients: |
| 997 | |
| 998 | <variablelist> |
| 999 | <varlistentry> |
| 1000 | <term>mieqProcessInputEvents()</term> |
| 1001 | <listitem> |
| 1002 | <para>This function processes each event in the |
| 1003 | event queue, and passes it to the device's input processing function. |
| 1004 | The DIX layer provides default functions to do this processing, and they |
| 1005 | handle the task of getting the events passed back to the relevant |
| 1006 | clients. |
| 1007 | </para></listitem></varlistentry> |
| 1008 | <varlistentry> |
| 1009 | <term>miPointerUpdate()</term> |
| 1010 | <listitem> |
| 1011 | <para>This function resynchronized the cursor position |
| 1012 | with the new pointer position. It also takes care of moving the cursor |
| 1013 | between screens when needed in multi-head configurations. |
| 1014 | </para></listitem></varlistentry> |
| 1015 | </variablelist> |
| 1016 | </para> |
| 1017 | |
| 1018 | </sect3> |
| 1019 | |
| 1020 | <sect3> |
| 1021 | <title>DisableDevice()</title> |
| 1022 | |
| 1023 | <para>DisableDevice is a DIX function that removes an input device from the |
| 1024 | list of enabled devices. The result of this is that the device no |
| 1025 | longer generates input events. The device's data structures are kept in |
| 1026 | place, and disabling a device like this can be reversed by calling |
| 1027 | EnableDevice(). DisableDevice() may be called from the DDX when it is |
| 1028 | desirable to do so (e.g., the XFree86 server does this when VT |
| 1029 | switching). Except for special cases, this is not normally called for |
| 1030 | core input devices. |
| 1031 | </para> |
| 1032 | |
| 1033 | <para>DisableDevice() calls the device's callback function with |
| 1034 | <constant>DEVICE_OFF</constant>: |
| 1035 | |
| 1036 | <variablelist> |
| 1037 | <varlistentry> |
| 1038 | <term>(*dev->deviceProc)(dev, DEVICE_OFF)</term> |
| 1039 | <listitem> |
| 1040 | <para>This typically closes the |
| 1041 | relevant physical device, and when appropriate, unregisters the device's |
| 1042 | file descriptor (or equivalent) as a valid input source. |
| 1043 | </para></listitem></varlistentry> |
| 1044 | </variablelist> |
| 1045 | </para> |
| 1046 | |
| 1047 | <para>DisableDevice() then removes the device handle from the X server's |
| 1048 | global list of enabled devices. |
| 1049 | </para> |
| 1050 | |
| 1051 | </sect3> |
| 1052 | |
| 1053 | <sect3> |
| 1054 | <title>CloseDevice()</title> |
| 1055 | |
| 1056 | <para>CloseDevice is a DIX function that removes an input device from the |
| 1057 | list of available devices. It disables input from the device and frees |
| 1058 | all data structures associated with the device. This function is |
| 1059 | usually called from CloseDownDevices(), which is called from main() at |
| 1060 | the end of each server generation to close all input devices. |
| 1061 | </para> |
| 1062 | |
| 1063 | <para>CloseDevice() calls the device's callback function with |
| 1064 | <constant>DEVICE_CLOSE</constant>: |
| 1065 | |
| 1066 | <variablelist> |
| 1067 | <varlistentry> |
| 1068 | <term>(*dev->deviceProc)(dev, DEVICE_CLOSE)</term> |
| 1069 | <listitem> |
| 1070 | <para>This typically closes the |
| 1071 | relevant physical device, and when appropriate, unregisters the device's |
| 1072 | file descriptor (or equivalent) as a valid input source. If any device |
| 1073 | specific data structures were allocated when the device was initialized, |
| 1074 | they are freed here. |
| 1075 | </para></listitem></varlistentry> |
| 1076 | </variablelist> |
| 1077 | </para> |
| 1078 | |
| 1079 | <para>CloseDevice() then frees the data structures that were allocated |
| 1080 | for the device when it was registered/initialized. |
| 1081 | </para> |
| 1082 | |
| 1083 | </sect3> |
| 1084 | |
| 1085 | <sect3> |
| 1086 | <title>LegalModifier()</title> |
| 1087 | <!-- dmx/dmxinput.c - currently returns TRUE --> |
| 1088 | <para>LegalModifier() is a required DDX function that can be used to |
| 1089 | restrict which keys may be modifier keys. This seems to be present for |
| 1090 | historical reasons, so this function should simply return TRUE |
| 1091 | unconditionally. |
| 1092 | </para> |
| 1093 | |
| 1094 | </sect3> |
| 1095 | </sect2> |
| 1096 | |
| 1097 | <sect2> |
| 1098 | <title>Output handling</title> |
| 1099 | |
| 1100 | <para>The following sections describe the main functions required to |
| 1101 | initialize, use and close the output device(s) for each screen in the X |
| 1102 | server. |
| 1103 | </para> |
| 1104 | |
| 1105 | <sect3> |
| 1106 | <title>InitOutput()</title> |
| 1107 | |
| 1108 | <para>This DDX function is called near the start of each server generation |
| 1109 | from the X server's main() function. InitOutput()'s main purpose is to |
| 1110 | initialize each screen and fill in the global screenInfo structure for |
| 1111 | each screen. It is passed three arguments: a pointer to the screenInfo |
| 1112 | struct, which it is to initialize, and argc and argv from main(), which |
| 1113 | can be used to determine additional configuration information. |
| 1114 | </para> |
| 1115 | |
| 1116 | <para>The primary tasks for this function are outlined below: |
| 1117 | |
| 1118 | <orderedlist> |
| 1119 | <listitem> |
| 1120 | <para><emphasis remap="bf">Parse configuration info:</emphasis> The first task of InitOutput() |
| 1121 | is to parses any configuration information from the configuration |
| 1122 | file. In addition to the XF86Config file, other configuration |
| 1123 | information can be taken from the command line. The command line |
| 1124 | options can be gathered either in InitOutput() or earlier in the |
| 1125 | ddxProcessArgument() function, which is called by |
| 1126 | ProcessCommandLine(). The configuration information determines the |
| 1127 | characteristics of the screen(s). For example, in the XFree86 X |
| 1128 | server, the XF86Config file specifies the monitor information, the |
| 1129 | screen resolution, the graphics devices and slots in which they are |
| 1130 | located, and, for Xinerama, the screens' layout. |
| 1131 | </para> |
| 1132 | </listitem> |
| 1133 | |
| 1134 | <listitem> |
| 1135 | <para><emphasis remap="bf">Initialize screen info:</emphasis> The next task is to initialize |
| 1136 | the screen-dependent internal data structures. For example, part of |
| 1137 | what the XFree86 X server does is to allocate its screen and pixmap |
| 1138 | private indices, probe for graphics devices, compare the probed |
| 1139 | devices to the ones listed in the XF86Config file, and add the ones that |
| 1140 | match to the internal xf86Screens[] structure. |
| 1141 | </para> |
| 1142 | </listitem> |
| 1143 | |
| 1144 | <listitem> |
| 1145 | <para><emphasis remap="bf">Set pixmap formats:</emphasis> The next task is to initialize the |
| 1146 | screenInfo's image byte order, bitmap bit order and bitmap scanline |
| 1147 | unit/pad. The screenInfo's pixmap format's depth, bits per pixel |
| 1148 | and scanline padding is also initialized at this stage. |
| 1149 | </para> |
| 1150 | </listitem> |
| 1151 | |
| 1152 | <listitem> |
| 1153 | <para><emphasis remap="bf">Unify screen info:</emphasis> An optional task that might be done at |
| 1154 | this stage is to compare all of the information from the various |
| 1155 | screens and determines if they are compatible (i.e., if the set of |
| 1156 | screens can be unified into a single desktop). This task has |
| 1157 | potential to be useful to the DMX front-end server, if Xinerama's |
| 1158 | PanoramiXConsolidate() function is not sufficient. |
| 1159 | </para> |
| 1160 | </listitem> |
| 1161 | </orderedlist> |
| 1162 | </para> |
| 1163 | |
| 1164 | <para>Once these tasks are complete, the valid screens are known and each |
| 1165 | of these screens can be initialized by calling AddScreen(). |
| 1166 | </para> |
| 1167 | </sect3> |
| 1168 | |
| 1169 | <sect3> |
| 1170 | <title>AddScreen()</title> |
| 1171 | |
| 1172 | <para>This DIX function is called from InitOutput(), in the DDX layer, to |
| 1173 | add each new screen to the screenInfo structure. The DDX screen |
| 1174 | initialization function and command line arguments (i.e., argc and argv) |
| 1175 | are passed to it as arguments. |
| 1176 | </para> |
| 1177 | |
| 1178 | <para>This function first allocates a new Screen structure and any privates |
| 1179 | that are required. It then initializes some of the fields in the Screen |
| 1180 | struct and sets up the pixmap padding information. Finally, it calls |
| 1181 | the DDX screen initialization function ScreenInit(), which is described |
| 1182 | below. It returns the number of the screen that were just added, or -1 |
| 1183 | if there is insufficient memory to add the screen or if the DDX screen |
| 1184 | initialization fails. |
| 1185 | </para> |
| 1186 | </sect3> |
| 1187 | |
| 1188 | <sect3> |
| 1189 | <title>ScreenInit()</title> |
| 1190 | |
| 1191 | <para>This DDX function initializes the rest of the Screen structure with |
| 1192 | either generic or screen-specific functions (as necessary). It also |
| 1193 | fills in various screen attributes (e.g., width and height in |
| 1194 | millimeters, black and white pixel values). |
| 1195 | </para> |
| 1196 | |
| 1197 | <para>The screen init function usually calls several functions to perform |
| 1198 | certain screen initialization functions. They are described below: |
| 1199 | |
| 1200 | <variablelist> |
| 1201 | <varlistentry> |
| 1202 | <term>{mi,*fb}ScreenInit()</term> |
| 1203 | <listitem> |
| 1204 | <para>The DDX layer's ScreenInit() function usually |
| 1205 | calls another layer's ScreenInit() function (e.g., miScreenInit() or |
| 1206 | fbScreenInit()) to initialize the fallbacks that the DDX driver does not |
| 1207 | specifically handle. |
| 1208 | </para> |
| 1209 | |
| 1210 | <para>After calling another layer's ScreenInit() function, any |
| 1211 | screen-specific functions either wrap or replace the other layer's |
| 1212 | function pointers. If a function is to be wrapped, each of the old |
| 1213 | function pointers from the other layer are stored in a screen private |
| 1214 | area. Common functions to wrap are CloseScreen() and SaveScreen(). |
| 1215 | </para></listitem></varlistentry> |
| 1216 | |
| 1217 | <varlistentry> |
| 1218 | <term>miDCInitialize()</term> |
| 1219 | <listitem> |
| 1220 | <para>This MI function initializes the MI cursor |
| 1221 | display structures and function pointers. If a hardware cursor is used, |
| 1222 | the DDX layer's ScreenInit() function will wrap additional screen and |
| 1223 | the MI cursor display function pointers. |
| 1224 | </para></listitem></varlistentry> |
| 1225 | </variablelist> |
| 1226 | </para> |
| 1227 | |
| 1228 | <para>Another common task for ScreenInit() function is to initialize the |
| 1229 | output device state. For example, in the XFree86 X server, the |
| 1230 | ScreenInit() function saves the original state of the video card and |
| 1231 | then initializes the video mode of the graphics device. |
| 1232 | </para> |
| 1233 | </sect3> |
| 1234 | |
| 1235 | <sect3> |
| 1236 | <title>CloseScreen()</title> |
| 1237 | |
| 1238 | <para>This function restores any wrapped screen functions (and in |
| 1239 | particular the wrapped CloseScreen() function) and restores the state of |
| 1240 | the output device to its original state. It should also free any |
| 1241 | private data it created during the screen initialization. |
| 1242 | </para> |
| 1243 | </sect3> |
| 1244 | |
| 1245 | <sect3> |
| 1246 | <title>GC operations</title> |
| 1247 | |
| 1248 | <para>When the X server is requested to render drawing primitives, it does |
| 1249 | so by calling drawing functions through the graphics context's operation |
| 1250 | function pointer table (i.e., the GCOps functions). These functions |
| 1251 | render the basic graphics operations such as drawing rectangles, lines, |
| 1252 | text or copying pixmaps. Default routines are provided either by the MI |
| 1253 | layer, which draws indirectly through a simple span interface, or by the |
| 1254 | framebuffer layers (e.g., CFB, MFB, FB), which draw directly to a |
| 1255 | linearly mapped frame buffer. |
| 1256 | </para> |
| 1257 | |
| 1258 | <para>To take advantage of special hardware on the graphics device, |
| 1259 | specific GCOps functions can be replaced by device specific code. |
| 1260 | However, many times the graphics devices can handle only a subset of the |
| 1261 | possible states of the GC, so during graphics context validation, |
| 1262 | appropriate routines are selected based on the state and capabilities of |
| 1263 | the hardware. For example, some graphics hardware can accelerate single |
| 1264 | pixel width lines with certain dash patterns. Thus, for dash patterns |
| 1265 | that are not supported by hardware or for width 2 or greater lines, the |
| 1266 | default routine is chosen during GC validation. |
| 1267 | </para> |
| 1268 | |
| 1269 | <para>Note that some pointers to functions that draw to the screen are |
| 1270 | stored in the Screen structure. They include GetImage(), GetSpans(), |
| 1271 | CopyWindow() and RestoreAreas(). |
| 1272 | </para> |
| 1273 | </sect3> |
| 1274 | |
| 1275 | <sect3> |
| 1276 | <title>Xnest</title> |
| 1277 | |
| 1278 | <para>The Xnest X server is a special proxy X server that relays the X |
| 1279 | protocol requests that it receives to a ``real'' X server that then |
| 1280 | processes the requests and displays the results, if applicable. To the X |
| 1281 | applications, Xnest appears as if it is a regular X server. However, |
| 1282 | Xnest is both server to the X application and client of the real X |
| 1283 | server, which will actually handle the requests. |
| 1284 | </para> |
| 1285 | |
| 1286 | <para>The Xnest server implements all of the standard input and output |
| 1287 | initialization steps outlined above. |
| 1288 | </para> |
| 1289 | |
| 1290 | <para><variablelist> |
| 1291 | <varlistentry> |
| 1292 | <term>InitOutput()</term> |
| 1293 | <listitem> |
| 1294 | <para>Xnest takes its configuration information from |
| 1295 | command line arguments via ddxProcessArguments(). This information |
| 1296 | includes the real X server display to connect to, its default visual |
| 1297 | class, the screen depth, the Xnest window's geometry, etc. Xnest then |
| 1298 | connects to the real X server and gathers visual, colormap, depth and |
| 1299 | pixmap information about that server's display, creates a window on that |
| 1300 | server, which will be used as the root window for Xnest. |
| 1301 | </para> |
| 1302 | |
| 1303 | <para>Next, Xnest initializes its internal data structures and uses the |
| 1304 | data from the real X server's pixmaps to initialize its own pixmap |
| 1305 | formats. Finally, it calls AddScreen(xnestOpenScreen, argc, argv) to |
| 1306 | initialize each of its screens. |
| 1307 | </para></listitem></varlistentry> |
| 1308 | |
| 1309 | <varlistentry> |
| 1310 | <term>ScreenInit()</term> |
| 1311 | <listitem> |
| 1312 | <para>Xnest's ScreenInit() function is called |
| 1313 | xnestOpenScreen(). This function initializes its screen's depth and |
| 1314 | visual information, and then calls miScreenInit() to set up the default |
| 1315 | screen functions. It then calls miDCInitialize() to initialize the |
| 1316 | software cursor. |
| 1317 | Finally, it replaces many of the screen functions with its own |
| 1318 | functions that repackage and send the requests to the real X server to |
| 1319 | which Xnest is attached. |
| 1320 | </para></listitem></varlistentry> |
| 1321 | |
| 1322 | <varlistentry> |
| 1323 | <term>CloseScreen()</term> |
| 1324 | <listitem> |
| 1325 | <para>This function frees its internal data structure |
| 1326 | allocations. Since it replaces instead of wrapping screen functions, |
| 1327 | there are no function pointers to unwrap. This can potentially lead to |
| 1328 | problems during server regeneration. |
| 1329 | </para></listitem></varlistentry> |
| 1330 | |
| 1331 | <varlistentry> |
| 1332 | <term>GC operations</term> |
| 1333 | <listitem> |
| 1334 | <para>The GC operations in Xnest are very simple since |
| 1335 | they leave all of the drawing to the real X server to which Xnest is |
| 1336 | attached. Each of the GCOps takes the request and sends it to the |
| 1337 | real X server using standard Xlib calls. For example, the X |
| 1338 | application issues a XDrawLines() call. This function turns into a |
| 1339 | protocol request to Xnest, which calls the xnestPolylines() function |
| 1340 | through Xnest's GCOps function pointer table. The xnestPolylines() |
| 1341 | function is only a single line, which calls XDrawLines() using the same |
| 1342 | arguments that were passed into it. Other GCOps functions are very |
| 1343 | similar. Two exceptions to the simple GCOps functions described above |
| 1344 | are the image functions and the BLT operations. |
| 1345 | </para> |
| 1346 | |
| 1347 | <para>The image functions, GetImage() and PutImage(), must use a temporary |
| 1348 | image to hold the image to be put of the image that was just grabbed |
| 1349 | from the screen while it is in transit to the real X server or the |
| 1350 | client. When the image has been transmitted, the temporary image is |
| 1351 | destroyed. |
| 1352 | </para> |
| 1353 | |
| 1354 | <para>The BLT operations, CopyArea() and CopyPlane(), handle not only the |
| 1355 | copy function, which is the same as the simple cases described above, |
| 1356 | but also the graphics exposures that result when the GC's graphics |
| 1357 | exposure bit is set to True. Graphics exposures are handled in a helper |
| 1358 | function, xnestBitBlitHelper(). This function collects the exposure |
| 1359 | events from the real X server and, if any resulting in regions being |
| 1360 | exposed, then those regions are passed back to the MI layer so that it |
| 1361 | can generate exposure events for the X application. |
| 1362 | </para></listitem></varlistentry> |
| 1363 | </variablelist> |
| 1364 | </para> |
| 1365 | |
| 1366 | <para>The Xnest server takes its input from the X server to which it is |
| 1367 | connected. When the mouse is in the Xnest server's window, keyboard and |
| 1368 | mouse events are received by the Xnest server, repackaged and sent back |
| 1369 | to any client that requests those events. |
| 1370 | </para> |
| 1371 | </sect3> |
| 1372 | |
| 1373 | <sect3> |
| 1374 | <title>Shadow framebuffer</title> |
| 1375 | |
| 1376 | <para>The most common type of framebuffer is a linear array memory that |
| 1377 | maps to the video memory on the graphics device. However, accessing |
| 1378 | that video memory over an I/O bus (e.g., ISA or PCI) can be slow. The |
| 1379 | shadow framebuffer layer allows the developer to keep the entire |
| 1380 | framebuffer in main memory and copy it back to video memory at regular |
| 1381 | intervals. It also has been extended to handle planar video memory and |
| 1382 | rotated framebuffers. |
| 1383 | </para> |
| 1384 | |
| 1385 | <para>There are two main entry points to the shadow framebuffer code: |
| 1386 | |
| 1387 | <variablelist> |
| 1388 | <varlistentry> |
| 1389 | <term>shadowAlloc(width, height, bpp)</term> |
| 1390 | <listitem> |
| 1391 | <para>This function allocates the in |
| 1392 | memory copy of the framebuffer of size width*height*bpp. It returns a |
| 1393 | pointer to that memory, which will be used by the framebuffer |
| 1394 | ScreenInit() code during the screen's initialization. |
| 1395 | </para></listitem></varlistentry> |
| 1396 | |
| 1397 | <varlistentry> |
| 1398 | <term>shadowInit(pScreen, updateProc, windowProc)</term> |
| 1399 | <listitem> |
| 1400 | <para>This function |
| 1401 | initializes the shadow framebuffer layer. It wraps several screen |
| 1402 | drawing functions, and registers a block handler that will update the |
| 1403 | screen. The updateProc is a function that will copy the damaged regions |
| 1404 | to the screen, and the windowProc is a function that is used when the |
| 1405 | entire linear video memory range cannot be accessed simultaneously so |
| 1406 | that only a window into that memory is available (e.g., when using the |
| 1407 | VGA aperture). |
| 1408 | </para></listitem></varlistentry> |
| 1409 | </variablelist> |
| 1410 | </para> |
| 1411 | |
| 1412 | <para>The shadow framebuffer code keeps track of the damaged area of each |
| 1413 | screen by calculating the bounding box of all drawing operations that |
| 1414 | have occurred since the last screen update. Then, when the block handler |
| 1415 | is next called, only the damaged portion of the screen is updated. |
| 1416 | </para> |
| 1417 | |
| 1418 | <para>Note that since the shadow framebuffer is kept in main memory, all |
| 1419 | drawing operations are performed by the CPU and, thus, no accelerated |
| 1420 | hardware drawing operations are possible. |
| 1421 | </para> |
| 1422 | |
| 1423 | </sect3> |
| 1424 | </sect2> |
| 1425 | |
| 1426 | <sect2> |
| 1427 | <title>Xinerama</title> |
| 1428 | |
| 1429 | <para>Xinerama is an X extension that allows multiple physical screens |
| 1430 | controlled by a single X server to appear as a single screen. Although |
| 1431 | the extension allows clients to find the physical screen layout via |
| 1432 | extension requests, it is completely transparent to clients at the core |
| 1433 | X11 protocol level. The original public implementation of Xinerama came |
| 1434 | from Digital/Compaq. XFree86 rewrote it, filling in some missing pieces |
| 1435 | and improving both X11 core protocol compliance and performance. The |
| 1436 | Xinerama extension will be passing through X.Org's standardization |
| 1437 | process in the near future, and the sample implementation will be based |
| 1438 | on this rewritten version. |
| 1439 | </para> |
| 1440 | |
| 1441 | <para>The current implementation of Xinerama is based primarily in the DIX |
| 1442 | (device independent) and MI (machine independent) layers of the X |
| 1443 | server. With few exceptions the DDX layers do not need any changes to |
| 1444 | support Xinerama. X server extensions often do need modifications to |
| 1445 | provide full Xinerama functionality. |
| 1446 | </para> |
| 1447 | |
| 1448 | <para>The following is a code-level description of how Xinerama functions. |
| 1449 | </para> |
| 1450 | |
| 1451 | <para>Note: Because the Xinerama extension was originally called the |
| 1452 | PanoramiX extension, many of the Xinerama functions still have the |
| 1453 | PanoramiX prefix. |
| 1454 | </para> |
| 1455 | |
| 1456 | <variablelist> |
| 1457 | <varlistentry> |
| 1458 | <term>PanoramiXExtensionInit()</term> |
| 1459 | <listitem> |
| 1460 | <para>PanoramiXExtensionInit() is a |
| 1461 | device-independent extension function that is called at the start of |
| 1462 | each server generation from InitExtensions(), which is called from |
| 1463 | the X server's main() function after all output devices have been |
| 1464 | initialized, but before any input devices have been initialized. |
| 1465 | </para> |
| 1466 | |
| 1467 | <para>PanoramiXNumScreens is set to the number of physical screens. If |
| 1468 | only one physical screen is present, the extension is disabled, and |
| 1469 | PanoramiXExtensionInit() returns without doing anything else. |
| 1470 | </para> |
| 1471 | |
| 1472 | <para>The Xinerama extension is registered by calling AddExtension(). |
| 1473 | </para> |
| 1474 | |
| 1475 | <para>GC and Screen private |
| 1476 | indexes are allocated, and both GC and Screen private areas are |
| 1477 | allocated for each physical screen. These hold Xinerama-specific |
| 1478 | per-GC and per-Screen data. Each screen's CreateGC and CloseScreen |
| 1479 | functions are wrapped by XineramaCreateGC() and |
| 1480 | XineramaCloseScreen() respectively. Some new resource classes are |
| 1481 | created for Xinerama drawables and GCs, and resource types for |
| 1482 | Xinerama windows, pixmaps and colormaps. |
| 1483 | </para> |
| 1484 | |
| 1485 | <para>A region (PanoramiXScreenRegion) is |
| 1486 | initialized to be the union of the screen regions. |
| 1487 | The relative positioning information for the |
| 1488 | physical screens is taken from the ScreenRec x and y members, which |
| 1489 | the DDX layer must initialize in InitOutput(). The bounds of the |
| 1490 | combined screen is also calculated (PanoramiXPixWidth and |
| 1491 | PanoramiXPixHeight). |
| 1492 | </para> |
| 1493 | |
| 1494 | <para>The DIX layer has a list of function pointers |
| 1495 | (ProcVector[]) that |
| 1496 | holds the entry points for the functions that process core protocol |
| 1497 | requests. The requests that Xinerama must intercept and break up |
| 1498 | into physical screen-specific requests are wrapped. The original |
| 1499 | set is copied to SavedProcVector[]. The types of requests |
| 1500 | intercepted are Window requests, GC requests, colormap requests, |
| 1501 | drawing requests, and some geometry-related requests. This wrapping |
| 1502 | allows the bulk of the protocol request processing to be handled |
| 1503 | transparently to the DIX layer. Some operations cannot be dealt with |
| 1504 | in this way and are handled with Xinerama-specific code within the |
| 1505 | DIX layer. |
| 1506 | </para> |
| 1507 | </listitem></varlistentry> |
| 1508 | |
| 1509 | <varlistentry> |
| 1510 | <term>PanoramiXConsolidate()</term> |
| 1511 | <listitem> |
| 1512 | <para>PanoramiXConsolidate() is a |
| 1513 | device-independent extension function that is called directly from |
| 1514 | the X server's main() function after extensions and input/output |
| 1515 | devices have been initialized, and before the root windows are |
| 1516 | defined and initialized. |
| 1517 | </para> |
| 1518 | |
| 1519 | <para>This function finds the set of depths (PanoramiXDepths[]) and |
| 1520 | visuals (PanoramiXVisuals[]) |
| 1521 | common to all of the physical screens. |
| 1522 | PanoramiXNumDepths is set to the number of common depths, and |
| 1523 | PanoramiXNumVisuals is set to the number of common visuals. |
| 1524 | Resources are created for the single root window and the default |
| 1525 | colormap. Each of these resources has per-physical screen entries. |
| 1526 | </para> |
| 1527 | </listitem></varlistentry> |
| 1528 | |
| 1529 | <varlistentry> |
| 1530 | <term>PanoramiXCreateConnectionBlock()</term> |
| 1531 | <listitem> |
| 1532 | <para>PanoramiXConsolidate() is a |
| 1533 | device-independent extension function that is called directly from |
| 1534 | the X server's main() function after the per-physical screen root |
| 1535 | windows are created. It is called instead of the standard DIX |
| 1536 | CreateConnectionBlock() function. If this function returns FALSE, |
| 1537 | the X server exits with a fatal error. This function will return |
| 1538 | FALSE if no common depths were found in PanoramiXConsolidate(). |
| 1539 | With no common depths, Xinerama mode is not possible. |
| 1540 | </para> |
| 1541 | |
| 1542 | <para>The connection block holds the information that clients get when |
| 1543 | they open a connection to the X server. It includes information |
| 1544 | such as the supported pixmap formats, number of screens and the |
| 1545 | sizes, depths, visuals, default colormap information, etc, for each |
| 1546 | of the screens (much of information that <command>xdpyinfo</command> shows). The |
| 1547 | connection block is initialized with the combined single screen |
| 1548 | values that were calculated in the above two functions. |
| 1549 | </para> |
| 1550 | |
| 1551 | <para>The Xinerama extension allows the registration of connection |
| 1552 | block callback functions. The purpose of these is to allow other |
| 1553 | extensions to do processing at this point. These callbacks can be |
| 1554 | registered by calling XineramaRegisterConnectionBlockCallback() from |
| 1555 | the other extension's ExtensionInit() function. Each registered |
| 1556 | connection block callback is called at the end of |
| 1557 | PanoramiXCreateConnectionBlock(). |
| 1558 | </para> |
| 1559 | </listitem></varlistentry> |
| 1560 | </variablelist> |
| 1561 | |
| 1562 | <sect3> |
| 1563 | <title>Xinerama-specific changes to the DIX code</title> |
| 1564 | |
| 1565 | <para>There are a few types of Xinerama-specific changes within the DIX |
| 1566 | code. The main ones are described here. |
| 1567 | </para> |
| 1568 | |
| 1569 | <para>Functions that deal with colormap or GC -related operations outside of |
| 1570 | the intercepted protocol requests have a test added to only do the |
| 1571 | processing for screen numbers > 0. This is because they are handled for |
| 1572 | the single Xinerama screen and the processing is done once for screen 0. |
| 1573 | </para> |
| 1574 | |
| 1575 | <para>The handling of motion events does some coordinate translation between |
| 1576 | the physical screen's origin and screen zero's origin. Also, motion |
| 1577 | events must be reported relative to the composite screen origin rather |
| 1578 | than the physical screen origins. |
| 1579 | </para> |
| 1580 | |
| 1581 | <para>There is some special handling for cursor, window and event processing |
| 1582 | that cannot (either not at all or not conveniently) be done via the |
| 1583 | intercepted protocol requests. A particular case is the handling of |
| 1584 | pointers moving between physical screens. |
| 1585 | </para> |
| 1586 | </sect3> |
| 1587 | |
| 1588 | <sect3> |
| 1589 | <title>Xinerama-specific changes to the MI code</title> |
| 1590 | |
| 1591 | <para>The only Xinerama-specific change to the MI code is in miSendExposures() |
| 1592 | to handle the coordinate (and window ID) translation for expose events. |
| 1593 | </para> |
| 1594 | </sect3> |
| 1595 | |
| 1596 | <sect3> |
| 1597 | <title>Intercepted DIX core requests</title> |
| 1598 | |
| 1599 | <para>Xinerama breaks up drawing requests for dispatch to each physical |
| 1600 | screen. It also breaks up windows into pieces for each physical screen. |
| 1601 | GCs are translated into per-screen GCs. Colormaps are replicated on |
| 1602 | each physical screen. The functions handling the intercepted requests |
| 1603 | take care of breaking the requests and repackaging them so that they can |
| 1604 | be passed to the standard request handling functions for each screen in |
| 1605 | turn. In addition, and to aid the repackaging, the information from |
| 1606 | many of the intercepted requests is used to keep up to date the |
| 1607 | necessary state information for the single composite screen. Requests |
| 1608 | (usually those with replies) that can be satisfied completely from this |
| 1609 | stored state information do not call the standard request handling |
| 1610 | functions. |
| 1611 | </para> |
| 1612 | |
| 1613 | </sect3> |
| 1614 | |
| 1615 | </sect2> |
| 1616 | |
| 1617 | </sect1> |
| 1618 | |
| 1619 | <!-- ============================================================ --> |
| 1620 | |
| 1621 | <sect1> |
| 1622 | <title>Development Results</title> |
| 1623 | |
| 1624 | <para>In this section the results of each phase of development are |
| 1625 | discussed. This development took place between approximately June 2001 |
| 1626 | and July 2003. |
| 1627 | </para> |
| 1628 | |
| 1629 | <sect2> |
| 1630 | <title>Phase I</title> |
| 1631 | |
| 1632 | <para>The initial development phase dealt with the basic implementation |
| 1633 | including the bootstrap code, which used the shadow framebuffer, and the |
| 1634 | unoptimized implementation, based on an Xnest-style implementation. |
| 1635 | </para> |
| 1636 | |
| 1637 | <sect3> |
| 1638 | <title>Scope</title> |
| 1639 | |
| 1640 | <para>The goal of Phase I is to provide fundamental functionality that can |
| 1641 | act as a foundation for ongoing work: |
| 1642 | <orderedlist> |
| 1643 | <listitem> |
| 1644 | <para>Develop the proxy X server |
| 1645 | <itemizedlist> |
| 1646 | <listitem> |
| 1647 | <para>The proxy X server will operate on the X11 protocol and |
| 1648 | relay requests as necessary to correctly perform the request. |
| 1649 | </para></listitem> |
| 1650 | <listitem> |
| 1651 | <para>Work will be based on the existing work for Xinerama and |
| 1652 | Xnest. |
| 1653 | </para></listitem> |
| 1654 | <listitem> |
| 1655 | <para>Input events and windowing operations are handled in the |
| 1656 | proxy server and rendering requests are repackaged and sent to |
| 1657 | each of the back-end servers for display. |
| 1658 | </para></listitem> |
| 1659 | <listitem> |
| 1660 | <para>The multiple screen layout (including support for |
| 1661 | overlapping screens) will be user configurable via a |
| 1662 | configuration file or through the configuration tool. |
| 1663 | </para></listitem> |
| 1664 | </itemizedlist> |
| 1665 | </para></listitem> |
| 1666 | <listitem> |
| 1667 | <para>Develop graphical configuration tool |
| 1668 | <itemizedlist> |
| 1669 | <listitem> |
| 1670 | <para>There will be potentially a large number of X servers to |
| 1671 | configure into a single display. The tool will allow the user |
| 1672 | to specify which servers are involved in the configuration and |
| 1673 | how they should be laid out. |
| 1674 | </para></listitem> |
| 1675 | </itemizedlist> |
| 1676 | </para></listitem> |
| 1677 | <listitem> |
| 1678 | <para>Pass the X Test Suite |
| 1679 | <itemizedlist> |
| 1680 | <listitem> |
| 1681 | <para>The X Test Suite covers the basic X11 operations. All |
| 1682 | tests known to succeed must correctly operate in the distributed |
| 1683 | X environment. |
| 1684 | </para></listitem> |
| 1685 | </itemizedlist> |
| 1686 | </para></listitem> |
| 1687 | </orderedlist> |
| 1688 | |
| 1689 | </para> |
| 1690 | |
| 1691 | <para>For this phase, the back-end X servers are assumed to be unmodified X |
| 1692 | servers that do not support any DMX-related protocol extensions; future |
| 1693 | optimization pathways are considered, but are not implemented; and the |
| 1694 | configuration tool is assumed to rely only on libraries in the X source |
| 1695 | tree (e.g., Xt). |
| 1696 | </para> |
| 1697 | </sect3> |
| 1698 | |
| 1699 | <sect3> |
| 1700 | <title>Results</title> |
| 1701 | |
| 1702 | <para>The proxy X server, Xdmx, was developed to distribute X11 protocol |
| 1703 | requests to the set of back-end X servers. It opens a window on each |
| 1704 | back-end server, which represents the part of the front-end's root |
| 1705 | window that is visible on that screen. It mirrors window, pixmap and |
| 1706 | other state in each back-end server. Drawing requests are sent to |
| 1707 | either windows or pixmaps on each back-end server. This code is based |
| 1708 | on Xnest and uses the existing Xinerama extension. |
| 1709 | </para> |
| 1710 | |
| 1711 | <para>Input events can be taken from (1) devices attached to the back-end |
| 1712 | server, (2) core devices attached directly to the Xdmx server, or (3) |
| 1713 | from a ``console'' window on another X server. Events for these devices |
| 1714 | are gathered, processed and delivered to clients attached to the Xdmx |
| 1715 | server. |
| 1716 | </para> |
| 1717 | |
| 1718 | <para>An intuitive configuration format was developed to help the user |
| 1719 | easily configure the multiple back-end X servers. It was defined (see |
| 1720 | grammar in Xdmx man page) and a parser was implemented that is used by |
| 1721 | the Xdmx server and by a standalone xdmxconfig utility. The parsing |
| 1722 | support was implemented such that it can be easily factored out of the X |
| 1723 | source tree for use with other tools (e.g., vdl). Support for |
| 1724 | converting legacy vdl-format configuration files to the DMX format is |
| 1725 | provided by the vdltodmx utility. |
| 1726 | </para> |
| 1727 | |
| 1728 | <para>Originally, the configuration file was going to be a subsection of |
| 1729 | XFree86's XF86Config file, but that was not possible since Xdmx is a |
| 1730 | completely separate X server. Thus, a separate config file format was |
| 1731 | developed. In addition, a graphical configuration |
| 1732 | tool, xdmxconfig, was developed to allow the user to create and arrange |
| 1733 | the screens in the configuration file. The <emphasis remap="bf">-configfile</emphasis> and <emphasis remap="bf">-config</emphasis> |
| 1734 | command-line options can be used to start Xdmx using a configuration |
| 1735 | file. |
| 1736 | </para> |
| 1737 | |
| 1738 | <para>An extension that enables remote input testing is required for the X |
| 1739 | Test Suite to function. During this phase, this extension (XTEST) was |
| 1740 | implemented in the Xdmx server. The results from running the X Test |
| 1741 | Suite are described in detail below. |
| 1742 | </para> |
| 1743 | </sect3> |
| 1744 | |
| 1745 | <sect3> |
| 1746 | <title>X Test Suite</title> |
| 1747 | |
| 1748 | <sect4> |
| 1749 | <title>Introduction</title> |
| 1750 | <para> |
| 1751 | The X Test Suite contains tests that verify Xlib functions |
| 1752 | operate correctly. The test suite is designed to run on a |
| 1753 | single X server; however, since X applications will not be |
| 1754 | able to tell the difference between the DMX server and a |
| 1755 | standard X server, the X Test Suite should also run on the |
| 1756 | DMX server. |
| 1757 | </para> |
| 1758 | <para> |
| 1759 | The Xdmx server was tested with the X Test Suite, and the |
| 1760 | existing failures are noted in this section. To put these |
| 1761 | results in perspective, we first discuss expected X Test |
| 1762 | failures and how errors in underlying systems can impact |
| 1763 | Xdmx test results. |
| 1764 | </para> |
| 1765 | </sect4> |
| 1766 | |
| 1767 | <sect4> |
| 1768 | <title>Expected Failures for a Single Head</title> |
| 1769 | <para> |
| 1770 | A correctly implemented X server with a single screen is |
| 1771 | expected to fail certain X Test tests. The following |
| 1772 | well-known errors occur because of rounding error in the X |
| 1773 | server code: |
| 1774 | <literallayout> |
| 1775 | XDrawArc: Tests 42, 63, 66, 73 |
| 1776 | XDrawArcs: Tests 45, 66, 69, 76 |
| 1777 | </literallayout> |
| 1778 | </para> |
| 1779 | <para> |
| 1780 | The following failures occur because of the high-level X |
| 1781 | server implementation: |
| 1782 | <literallayout> |
| 1783 | XLoadQueryFont: Test 1 |
| 1784 | XListFontsWithInfo: Tests 3, 4 |
| 1785 | XQueryFont: Tests 1, 2 |
| 1786 | </literallayout> |
| 1787 | </para> |
| 1788 | <para> |
| 1789 | The following test fails when running the X server as root |
| 1790 | under Linux because of the way directory modes are |
| 1791 | interpreted: |
| 1792 | <literallayout> |
| 1793 | XWriteBitmapFile: Test 3 |
| 1794 | </literallayout> |
| 1795 | </para> |
| 1796 | <para> |
| 1797 | Depending on the video card used for the back-end, other |
| 1798 | failures may also occur because of bugs in the low-level |
| 1799 | driver implementation. Over time, failures of this kind |
| 1800 | are usually fixed by XFree86, but will show up in Xdmx |
| 1801 | testing until then. |
| 1802 | </para> |
| 1803 | </sect4> |
| 1804 | |
| 1805 | <sect4> |
| 1806 | <title>Expected Failures for Xinerama</title> |
| 1807 | <para> |
| 1808 | Xinerama fails several X Test Suite tests because of |
| 1809 | design decisions made for the current implementation of |
| 1810 | Xinerama. Over time, many of these errors will be |
| 1811 | corrected by XFree86 and the group working on a new |
| 1812 | Xinerama implementation. Therefore, Xdmx will also share |
| 1813 | X Suite Test failures with Xinerama. |
| 1814 | </para> |
| 1815 | |
| 1816 | <para> |
| 1817 | We may be able to fix or work-around some of these |
| 1818 | failures at the Xdmx level, but this will require |
| 1819 | additional exploration that was not part of Phase I. |
| 1820 | </para> |
| 1821 | |
| 1822 | <para> |
| 1823 | Xinerama is constantly improving, and the list of |
| 1824 | Xinerama-related failures depends on XFree86 version and |
| 1825 | the underlying graphics hardware. We tested with a |
| 1826 | variety of hardware, including nVidia, S3, ATI Radeon, |
| 1827 | and Matrox G400 (in dual-head mode). The list below |
| 1828 | includes only those failures that appear to be from the |
| 1829 | Xinerama layer, and does not include failures listed in |
| 1830 | the previous section, or failures that appear to be from |
| 1831 | the low-level graphics driver itself: |
| 1832 | </para> |
| 1833 | |
| 1834 | <para> |
| 1835 | These failures were noted with multiple Xinerama |
| 1836 | configurations: |
| 1837 | <literallayout> |
| 1838 | XCopyPlane: Tests 13, 22, 31 (well-known Xinerama implementation issue) |
| 1839 | XSetFontPath: Test 4 |
| 1840 | XGetDefault: Test 5 |
| 1841 | XMatchVisualInfo: Test 1 |
| 1842 | </literallayout> |
| 1843 | </para> |
| 1844 | <para> |
| 1845 | These failures were noted only when using one dual-head |
| 1846 | video card with a 4.2.99.x XFree86 server: |
| 1847 | <literallayout> |
| 1848 | XListPixmapFormats: Test 1 |
| 1849 | XDrawRectangles: Test 45 |
| 1850 | </literallayout> |
| 1851 | </para> |
| 1852 | <para> |
| 1853 | These failures were noted only when using two video cards |
| 1854 | from different vendors with a 4.1.99.x XFree86 server: |
| 1855 | <literallayout> |
| 1856 | XChangeWindowAttributes: Test 32 |
| 1857 | XCreateWindow: Test 30 |
| 1858 | XDrawLine: Test 22 |
| 1859 | XFillArc: Test 22 |
| 1860 | XChangeKeyboardControl: Tests 9, 10 |
| 1861 | XRebindKeysym: Test 1 |
| 1862 | </literallayout> |
| 1863 | </para> |
| 1864 | </sect4> |
| 1865 | |
| 1866 | <sect4> |
| 1867 | <title>Additional Failures from Xdmx</title> |
| 1868 | |
| 1869 | <para> |
| 1870 | When running Xdmx, no unexpected failures were noted. |
| 1871 | Since the Xdmx server is based on Xinerama, we expect to |
| 1872 | have most of the Xinerama failures present in the Xdmx |
| 1873 | server. Similarly, since the Xdmx server must rely on the |
| 1874 | low-level device drivers on each back-end server, we also |
| 1875 | expect that Xdmx will exhibit most of the back-end |
| 1876 | failures. Here is a summary: |
| 1877 | <literallayout> |
| 1878 | XListPixmapFormats: Test 1 (configuration dependent) |
| 1879 | XChangeWindowAttributes: Test 32 |
| 1880 | XCreateWindow: Test 30 |
| 1881 | XCopyPlane: Test 13, 22, 31 |
| 1882 | XSetFontPath: Test 4 |
| 1883 | XGetDefault: Test 5 (configuration dependent) |
| 1884 | XMatchVisualInfo: Test 1 |
| 1885 | XRebindKeysym: Test 1 (configuration dependent) |
| 1886 | </literallayout> |
| 1887 | </para> |
| 1888 | <para> |
| 1889 | Note that this list is shorter than the combined list for |
| 1890 | Xinerama because Xdmx uses different code paths to perform |
| 1891 | some Xinerama operations. Further, some Xinerama failures |
| 1892 | have been fixed in the XFree86 4.2.99.x CVS repository. |
| 1893 | </para> |
| 1894 | </sect4> |
| 1895 | |
| 1896 | <sect4> |
| 1897 | <title>Summary and Future Work</title> |
| 1898 | |
| 1899 | <para> |
| 1900 | Running the X Test Suite on Xdmx does not produce any |
| 1901 | failures that cannot be accounted for by the underlying |
| 1902 | Xinerama subsystem used by the front-end or by the |
| 1903 | low-level device-driver code running on the back-end X |
| 1904 | servers. The Xdmx server therefore is as ``correct'' as |
| 1905 | possible with respect to the standard set of X Test Suite |
| 1906 | tests. |
| 1907 | </para> |
| 1908 | |
| 1909 | <para> |
| 1910 | During the following phases, we will continue to verify |
| 1911 | Xdmx correctness using the X Test Suite. We may also use |
| 1912 | other tests suites or write additional tests that run |
| 1913 | under the X Test Suite that specifically verify the |
| 1914 | expected behavior of DMX. |
| 1915 | </para> |
| 1916 | </sect4> |
| 1917 | </sect3> |
| 1918 | |
| 1919 | <sect3> |
| 1920 | <title>Fonts</title> |
| 1921 | |
| 1922 | <para>In Phase I, fonts are handled directly by both the front-end and the |
| 1923 | back-end servers, which is required since we must treat each back-end |
| 1924 | server during this phase as a ``black box''. What this requires is that |
| 1925 | <emphasis remap="bf">the front- and back-end servers must share the exact same font |
| 1926 | path</emphasis>. There are two ways to help make sure that all servers share the |
| 1927 | same font path: |
| 1928 | |
| 1929 | <orderedlist> |
| 1930 | <listitem> |
| 1931 | <para>First, each server can be configured to use the same font |
| 1932 | server. The font server, xfs, can be configured to serve fonts to |
| 1933 | multiple X servers via TCP. |
| 1934 | </para></listitem> |
| 1935 | |
| 1936 | <listitem> |
| 1937 | <para>Second, each server can be configured to use the same font |
| 1938 | path and either those font paths can be copied to each back-end |
| 1939 | machine or they can be mounted (e.g., via NFS) on each back-end |
| 1940 | machine. |
| 1941 | </para></listitem> |
| 1942 | </orderedlist> |
| 1943 | </para> |
| 1944 | |
| 1945 | <para>One additional concern is that a client program can set its own font |
| 1946 | path, and if it does so, then that font path must be available on each |
| 1947 | back-end machine. |
| 1948 | </para> |
| 1949 | |
| 1950 | <para>The -fontpath command line option was added to allow users to |
| 1951 | initialize the font path of the front end server. This font path is |
| 1952 | propagated to each back-end server when the default font is loaded. If |
| 1953 | there are any problems, an error message is printed, which will describe |
| 1954 | the problem and list the current font path. For more information about |
| 1955 | setting the font path, see the -fontpath option description in the man |
| 1956 | page. |
| 1957 | </para> |
| 1958 | </sect3> |
| 1959 | |
| 1960 | <sect3> |
| 1961 | <title>Performance</title> |
| 1962 | |
| 1963 | <para>Phase I of development was not intended to optimize performance. Its |
| 1964 | focus was on completely and correctly handling the base X11 protocol in |
| 1965 | the Xdmx server. However, several insights were gained during Phase I, |
| 1966 | which are listed here for reference during the next phase of |
| 1967 | development. |
| 1968 | </para> |
| 1969 | |
| 1970 | <orderedlist> |
| 1971 | <listitem> |
| 1972 | <para>Calls to XSync() can slow down rendering since it requires a |
| 1973 | complete round trip to and from a back-end server. This is |
| 1974 | especially problematic when communicating over long haul networks. |
| 1975 | </para></listitem> |
| 1976 | |
| 1977 | <listitem> |
| 1978 | <para>Sending drawing requests to only the screens that they overlap |
| 1979 | should improve performance. |
| 1980 | </para></listitem> |
| 1981 | </orderedlist> |
| 1982 | </sect3> |
| 1983 | |
| 1984 | <sect3> |
| 1985 | <title>Pixmaps</title> |
| 1986 | |
| 1987 | <para>Pixmaps were originally expected to be handled entirely in the |
| 1988 | front-end X server; however, it was found that this overly complicated |
| 1989 | the rendering code and would have required sending potentially large |
| 1990 | images to each back server that required them when copying from pixmap |
| 1991 | to screen. Thus, pixmap state is mirrored in the back-end server just |
| 1992 | as it is with regular window state. With this implementation, the same |
| 1993 | rendering code that draws to windows can be used to draw to pixmaps on |
| 1994 | the back-end server, and no large image transfers are required to copy |
| 1995 | from pixmap to window. |
| 1996 | </para> |
| 1997 | |
| 1998 | </sect3> |
| 1999 | |
| 2000 | </sect2> |
| 2001 | |
| 2002 | <!-- ============================================================ --> |
| 2003 | <sect2> |
| 2004 | <title>Phase II</title> |
| 2005 | |
| 2006 | <para>The second phase of development concentrates on performance |
| 2007 | optimizations. These optimizations are documented here, with |
| 2008 | <command>x11perf</command> data to show how the optimizations improve performance. |
| 2009 | </para> |
| 2010 | |
| 2011 | <para>All benchmarks were performed by running Xdmx on a dual processor |
| 2012 | 1.4GHz AMD Athlon machine with 1GB of RAM connecting over 100baseT to |
| 2013 | two single-processor 1GHz Pentium III machines with 256MB of RAM and ATI |
| 2014 | Rage 128 (RF) video cards. The front end was running Linux |
| 2015 | 2.4.20-pre1-ac1 and the back ends were running Linux 2.4.7-10 and |
| 2016 | version 4.2.99.1 of XFree86 pulled from the XFree86 CVS repository on |
| 2017 | August 7, 2002. All systems were running Red Hat Linux 7.2. |
| 2018 | </para> |
| 2019 | |
| 2020 | <sect3> |
| 2021 | <title>Moving from XFree86 4.1.99.1 to 4.2.0.0</title> |
| 2022 | |
| 2023 | <para>For phase II, the working source tree was moved to the branch tagged |
| 2024 | with dmx-1-0-branch and was updated from version 4.1.99.1 (20 August |
| 2025 | 2001) of the XFree86 sources to version 4.2.0.0 (18 January 2002). |
| 2026 | After this update, the following tests were noted to be more than 10% |
| 2027 | faster: |
| 2028 | <screen> |
| 2029 | 1.13 Fill 300x300 opaque stippled trapezoid (161x145 stipple) |
| 2030 | 1.16 Fill 1x1 tiled trapezoid (161x145 tile) |
| 2031 | 1.13 Fill 10x10 tiled trapezoid (161x145 tile) |
| 2032 | 1.17 Fill 100x100 tiled trapezoid (161x145 tile) |
| 2033 | 1.16 Fill 1x1 tiled trapezoid (216x208 tile) |
| 2034 | 1.20 Fill 10x10 tiled trapezoid (216x208 tile) |
| 2035 | 1.15 Fill 100x100 tiled trapezoid (216x208 tile) |
| 2036 | 1.37 Circulate Unmapped window (200 kids) |
| 2037 | </screen> |
| 2038 | And the following tests were noted to be more than 10% slower: |
| 2039 | <screen> |
| 2040 | 0.88 Unmap window via parent (25 kids) |
| 2041 | 0.75 Circulate Unmapped window (4 kids) |
| 2042 | 0.79 Circulate Unmapped window (16 kids) |
| 2043 | 0.80 Circulate Unmapped window (25 kids) |
| 2044 | 0.82 Circulate Unmapped window (50 kids) |
| 2045 | 0.85 Circulate Unmapped window (75 kids) |
| 2046 | </screen> |
| 2047 | </para> |
| 2048 | |
| 2049 | <para>These changes were not caused by any changes in the DMX system, and |
| 2050 | may point to changes in the XFree86 tree or to tests that have more |
| 2051 | "jitter" than most other <command>x11perf</command> tests. |
| 2052 | </para> |
| 2053 | </sect3> |
| 2054 | |
| 2055 | <sect3> |
| 2056 | <title>Global changes</title> |
| 2057 | |
| 2058 | <para>During the development of the Phase II DMX server, several global |
| 2059 | changes were made. These changes were also compared with the Phase I |
| 2060 | server. The following tests were noted to be more than 10% faster: |
| 2061 | <screen> |
| 2062 | 1.13 Fill 300x300 opaque stippled trapezoid (161x145 stipple) |
| 2063 | 1.15 Fill 1x1 tiled trapezoid (161x145 tile) |
| 2064 | 1.13 Fill 10x10 tiled trapezoid (161x145 tile) |
| 2065 | 1.17 Fill 100x100 tiled trapezoid (161x145 tile) |
| 2066 | 1.16 Fill 1x1 tiled trapezoid (216x208 tile) |
| 2067 | 1.19 Fill 10x10 tiled trapezoid (216x208 tile) |
| 2068 | 1.15 Fill 100x100 tiled trapezoid (216x208 tile) |
| 2069 | 1.15 Circulate Unmapped window (4 kids) |
| 2070 | </screen> |
| 2071 | </para> |
| 2072 | |
| 2073 | <para>The following tests were noted to be more than 10% slower: |
| 2074 | <screen> |
| 2075 | 0.69 Scroll 10x10 pixels |
| 2076 | 0.68 Scroll 100x100 pixels |
| 2077 | 0.68 Copy 10x10 from window to window |
| 2078 | 0.68 Copy 100x100 from window to window |
| 2079 | 0.76 Circulate Unmapped window (75 kids) |
| 2080 | 0.83 Circulate Unmapped window (100 kids) |
| 2081 | </screen> |
| 2082 | </para> |
| 2083 | |
| 2084 | <para>For the remainder of this analysis, the baseline of comparison will |
| 2085 | be the Phase II deliverable with all optimizations disabled (unless |
| 2086 | otherwise noted). This will highlight how the optimizations in |
| 2087 | isolation impact performance. |
| 2088 | </para> |
| 2089 | </sect3> |
| 2090 | |
| 2091 | <sect3> |
| 2092 | <title>XSync() Batching</title> |
| 2093 | |
| 2094 | <para>During the Phase I implementation, XSync() was called after every |
| 2095 | protocol request made by the DMX server. This provided the DMX server |
| 2096 | with an interactive feel, but defeated X11's protocol buffering system |
| 2097 | and introduced round-trip wire latency into every operation. During |
| 2098 | Phase II, DMX was changed so that protocol requests are no longer |
| 2099 | followed by calls to XSync(). Instead, the need for an XSync() is |
| 2100 | noted, and XSync() calls are only made every 100mS or when the DMX |
| 2101 | server specifically needs to make a call to guarantee interactivity. |
| 2102 | With this new system, X11 buffers protocol as much as possible during a |
| 2103 | 100mS interval, and many unnecessary XSync() calls are avoided. |
| 2104 | </para> |
| 2105 | |
| 2106 | <para>Out of more than 300 <command>x11perf</command> tests, 8 tests became more than 100 |
| 2107 | times faster, with 68 more than 50X faster, 114 more than 10X faster, |
| 2108 | and 181 more than 2X faster. See table below for summary. |
| 2109 | </para> |
| 2110 | |
| 2111 | <para>The following tests were noted to be more than 10% slower with |
| 2112 | XSync() batching on: |
| 2113 | <screen> |
| 2114 | 0.88 500x500 tiled rectangle (161x145 tile) |
| 2115 | 0.89 Copy 500x500 from window to window |
| 2116 | </screen> |
| 2117 | </para> |
| 2118 | </sect3> |
| 2119 | |
| 2120 | <sect3> |
| 2121 | <title>Offscreen Optimization</title> |
| 2122 | |
| 2123 | <para>Windows span one or more of the back-end servers' screens; however, |
| 2124 | during Phase I development, windows were created on every back-end |
| 2125 | server and every rendering request was sent to every window regardless |
| 2126 | of whether or not that window was visible. With the offscreen |
| 2127 | optimization, the DMX server tracks when a window is completely off of a |
| 2128 | back-end server's screen and, in that case, it does not send rendering |
| 2129 | requests to those back-end windows. This optimization saves bandwidth |
| 2130 | between the front and back-end servers, and it reduces the number of |
| 2131 | XSync() calls. The performance tests were run on a DMX system with only |
| 2132 | two back-end servers. Greater performance gains will be had as the |
| 2133 | number of back-end servers increases. |
| 2134 | </para> |
| 2135 | |
| 2136 | <para>Out of more than 300 <command>x11perf</command> tests, 3 tests were at least twice as |
| 2137 | fast, and 146 tests were at least 10% faster. Two tests were more than |
| 2138 | 10% slower with the offscreen optimization: |
| 2139 | <screen> |
| 2140 | 0.88 Hide/expose window via popup (4 kids) |
| 2141 | 0.89 Resize unmapped window (75 kids) |
| 2142 | </screen> |
| 2143 | </para> |
| 2144 | </sect3> |
| 2145 | |
| 2146 | <sect3> |
| 2147 | <title>Lazy Window Creation Optimization</title> |
| 2148 | |
| 2149 | <para>As mentioned above, during Phase I, windows were created on every |
| 2150 | back-end server even if they were not visible on that back-end. With |
| 2151 | the lazy window creation optimization, the DMX server does not create |
| 2152 | windows on a back-end server until they are either visible or they |
| 2153 | become the parents of a visible window. This optimization builds on the |
| 2154 | offscreen optimization (described above) and requires it to be enabled. |
| 2155 | </para> |
| 2156 | |
| 2157 | <para>The lazy window creation optimization works by creating the window |
| 2158 | data structures in the front-end server when a client creates a window, |
| 2159 | but delays creation of the window on the back-end server(s). A private |
| 2160 | window structure in the DMX server saves the relevant window data and |
| 2161 | tracks changes to the window's attributes and stacking order for later |
| 2162 | use. The only times a window is created on a back-end server are (1) |
| 2163 | when it is mapped and is at least partially overlapping the back-end |
| 2164 | server's screen (tracked by the offscreen optimization), or (2) when the |
| 2165 | window becomes the parent of a previously visible window. The first |
| 2166 | case occurs when a window is mapped or when a visible window is copied, |
| 2167 | moved or resized and now overlaps the back-end server's screen. The |
| 2168 | second case occurs when starting a window manager after having created |
| 2169 | windows to which the window manager needs to add decorations. |
| 2170 | </para> |
| 2171 | |
| 2172 | <para>When either case occurs, a window on the back-end server is created |
| 2173 | using the data saved in the DMX server's window private data structure. |
| 2174 | The stacking order is then adjusted to correctly place the window on the |
| 2175 | back-end and lastly the window is mapped. From this time forward, the |
| 2176 | window is handled exactly as if the window had been created at the time |
| 2177 | of the client's request. |
| 2178 | </para> |
| 2179 | |
| 2180 | <para>Note that when a window is no longer visible on a back-end server's |
| 2181 | screen (e.g., it is moved offscreen), the window is not destroyed; |
| 2182 | rather, it is kept and reused later if the window once again becomes |
| 2183 | visible on the back-end server's screen. Originally with this |
| 2184 | optimization, destroying windows was implemented but was later rejected |
| 2185 | because it increased bandwidth when windows were opaquely moved or |
| 2186 | resized, which is common in many window managers. |
| 2187 | </para> |
| 2188 | |
| 2189 | <para>The performance tests were run on a DMX system with only two back-end |
| 2190 | servers. Greater performance gains will be had as the number of |
| 2191 | back-end servers increases. |
| 2192 | </para> |
| 2193 | |
| 2194 | <para>This optimization improved the following <command>x11perf</command> tests by more |
| 2195 | than 10%: |
| 2196 | <screen> |
| 2197 | 1.10 500x500 rectangle outline |
| 2198 | 1.12 Fill 100x100 stippled trapezoid (161x145 stipple) |
| 2199 | 1.20 Circulate Unmapped window (50 kids) |
| 2200 | 1.19 Circulate Unmapped window (75 kids) |
| 2201 | </screen> |
| 2202 | </para> |
| 2203 | </sect3> |
| 2204 | |
| 2205 | <sect3> |
| 2206 | <title>Subdividing Rendering Primitives</title> |
| 2207 | |
| 2208 | <para>X11 imaging requests transfer significant data between the client and |
| 2209 | the X server. During Phase I, the DMX server would then transfer the |
| 2210 | image data to each back-end server. Even with the offscreen |
| 2211 | optimization (above), these requests still required transferring |
| 2212 | significant data to each back-end server that contained a visible |
| 2213 | portion of the window. For example, if the client uses XPutImage() to |
| 2214 | copy an image to a window that overlaps the entire DMX screen, then the |
| 2215 | entire image is copied by the DMX server to every back-end server. |
| 2216 | </para> |
| 2217 | |
| 2218 | <para>To reduce the amount of data transferred between the DMX server and |
| 2219 | the back-end servers when XPutImage() is called, the image data is |
| 2220 | subdivided and only the data that will be visible on a back-end server's |
| 2221 | screen is sent to that back-end server. Xinerama already implements a |
| 2222 | subdivision algorithm for XGetImage() and no further optimization was |
| 2223 | needed. |
| 2224 | </para> |
| 2225 | |
| 2226 | <para>Other rendering primitives were analyzed, but the time required to |
| 2227 | subdivide these primitives was a significant proportion of the time |
| 2228 | required to send the entire rendering request to the back-end server, so |
| 2229 | this optimization was rejected for the other rendering primitives. |
| 2230 | </para> |
| 2231 | |
| 2232 | <para>Again, the performance tests were run on a DMX system with only two |
| 2233 | back-end servers. Greater performance gains will be had as the number |
| 2234 | of back-end servers increases. |
| 2235 | </para> |
| 2236 | |
| 2237 | <para>This optimization improved the following <command>x11perf</command> tests by more |
| 2238 | than 10%: |
| 2239 | <screen> |
| 2240 | 1.12 Fill 100x100 stippled trapezoid (161x145 stipple) |
| 2241 | 1.26 PutImage 10x10 square |
| 2242 | 1.83 PutImage 100x100 square |
| 2243 | 1.91 PutImage 500x500 square |
| 2244 | 1.40 PutImage XY 10x10 square |
| 2245 | 1.48 PutImage XY 100x100 square |
| 2246 | 1.50 PutImage XY 500x500 square |
| 2247 | 1.45 Circulate Unmapped window (75 kids) |
| 2248 | 1.74 Circulate Unmapped window (100 kids) |
| 2249 | </screen> |
| 2250 | </para> |
| 2251 | |
| 2252 | <para>The following test was noted to be more than 10% slower with this |
| 2253 | optimization: |
| 2254 | <screen> |
| 2255 | 0.88 10-pixel fill chord partial circle |
| 2256 | </screen> |
| 2257 | </para> |
| 2258 | </sect3> |
| 2259 | |
| 2260 | <sect3> |
| 2261 | <title>Summary of x11perf Data</title> |
| 2262 | |
| 2263 | <para>With all of the optimizations on, 53 <command>x11perf</command> tests are more than |
| 2264 | 100X faster than the unoptimized Phase II deliverable, with 69 more than |
| 2265 | 50X faster, 73 more than 10X faster, and 199 more than twice as fast. |
| 2266 | No tests were more than 10% slower than the unoptimized Phase II |
| 2267 | deliverable. (Compared with the Phase I deliverable, only Circulate |
| 2268 | Unmapped window (100 kids) was more than 10% slower than the Phase II |
| 2269 | deliverable. As noted above, this test seems to have wider variability |
| 2270 | than other <command>x11perf</command> tests.) |
| 2271 | </para> |
| 2272 | |
| 2273 | <para>The following table summarizes relative <command>x11perf</command> test changes for |
| 2274 | all optimizations individually and collectively. Note that some of the |
| 2275 | optimizations have a synergistic effect when used together. |
| 2276 | <screen> |
| 2277 | |
| 2278 | 1: XSync() batching only |
| 2279 | 2: Off screen optimizations only |
| 2280 | 3: Window optimizations only |
| 2281 | 4: Subdivprims only |
| 2282 | 5: All optimizations |
| 2283 | |
| 2284 | 1 2 3 4 5 Operation |
| 2285 | ------ ---- ---- ---- ------ --------- |
| 2286 | 2.14 1.85 1.00 1.00 4.13 Dot |
| 2287 | 1.67 1.80 1.00 1.00 3.31 1x1 rectangle |
| 2288 | 2.38 1.43 1.00 1.00 2.44 10x10 rectangle |
| 2289 | 1.00 1.00 0.92 0.98 1.00 100x100 rectangle |
| 2290 | 1.00 1.00 1.00 1.00 1.00 500x500 rectangle |
| 2291 | 1.83 1.85 1.05 1.06 3.54 1x1 stippled rectangle (8x8 stipple) |
| 2292 | 2.43 1.43 1.00 1.00 2.41 10x10 stippled rectangle (8x8 stipple) |
| 2293 | 0.98 1.00 1.00 1.00 1.00 100x100 stippled rectangle (8x8 stipple) |
| 2294 | 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (8x8 stipple) |
| 2295 | 1.75 1.75 1.00 1.00 3.40 1x1 opaque stippled rectangle (8x8 stipple) |
| 2296 | 2.38 1.42 1.00 1.00 2.34 10x10 opaque stippled rectangle (8x8 stipple) |
| 2297 | 1.00 1.00 0.97 0.97 1.00 100x100 opaque stippled rectangle (8x8 stipple) |
| 2298 | 1.00 1.00 1.00 1.00 0.99 500x500 opaque stippled rectangle (8x8 stipple) |
| 2299 | 1.82 1.82 1.04 1.04 3.56 1x1 tiled rectangle (4x4 tile) |
| 2300 | 2.33 1.42 1.00 1.00 2.37 10x10 tiled rectangle (4x4 tile) |
| 2301 | 1.00 0.92 1.00 1.00 1.00 100x100 tiled rectangle (4x4 tile) |
| 2302 | 1.00 1.00 1.00 1.00 1.00 500x500 tiled rectangle (4x4 tile) |
| 2303 | 1.94 1.62 1.00 1.00 3.66 1x1 stippled rectangle (17x15 stipple) |
| 2304 | 1.74 1.28 1.00 1.00 1.73 10x10 stippled rectangle (17x15 stipple) |
| 2305 | 1.00 1.00 1.00 0.89 0.98 100x100 stippled rectangle (17x15 stipple) |
| 2306 | 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (17x15 stipple) |
| 2307 | 1.94 1.62 1.00 1.00 3.67 1x1 opaque stippled rectangle (17x15 stipple) |
| 2308 | 1.69 1.26 1.00 1.00 1.66 10x10 opaque stippled rectangle (17x15 stipple) |
| 2309 | 1.00 0.95 1.00 1.00 1.00 100x100 opaque stippled rectangle (17x15 stipple) |
| 2310 | 1.00 1.00 1.00 1.00 0.97 500x500 opaque stippled rectangle (17x15 stipple) |
| 2311 | 1.93 1.61 0.99 0.99 3.69 1x1 tiled rectangle (17x15 tile) |
| 2312 | 1.73 1.27 1.00 1.00 1.72 10x10 tiled rectangle (17x15 tile) |
| 2313 | 1.00 1.00 1.00 1.00 0.98 100x100 tiled rectangle (17x15 tile) |
| 2314 | 1.00 1.00 0.97 0.97 1.00 500x500 tiled rectangle (17x15 tile) |
| 2315 | 1.95 1.63 1.00 1.00 3.83 1x1 stippled rectangle (161x145 stipple) |
| 2316 | 1.80 1.30 1.00 1.00 1.83 10x10 stippled rectangle (161x145 stipple) |
| 2317 | 0.97 1.00 1.00 1.00 1.01 100x100 stippled rectangle (161x145 stipple) |
| 2318 | 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (161x145 stipple) |
| 2319 | 1.95 1.63 1.00 1.00 3.56 1x1 opaque stippled rectangle (161x145 stipple) |
| 2320 | 1.65 1.25 1.00 1.00 1.68 10x10 opaque stippled rectangle (161x145 stipple) |
| 2321 | 1.00 1.00 1.00 1.00 1.01 100x100 opaque stippled rectangle (161x145... |
| 2322 | 1.00 1.00 1.00 1.00 0.97 500x500 opaque stippled rectangle (161x145... |
| 2323 | 1.95 1.63 0.98 0.99 3.80 1x1 tiled rectangle (161x145 tile) |
| 2324 | 1.67 1.26 1.00 1.00 1.67 10x10 tiled rectangle (161x145 tile) |
| 2325 | 1.13 1.14 1.14 1.14 1.14 100x100 tiled rectangle (161x145 tile) |
| 2326 | 0.88 1.00 1.00 1.00 0.99 500x500 tiled rectangle (161x145 tile) |
| 2327 | 1.93 1.63 1.00 1.00 3.53 1x1 tiled rectangle (216x208 tile) |
| 2328 | 1.69 1.26 1.00 1.00 1.66 10x10 tiled rectangle (216x208 tile) |
| 2329 | 1.00 1.00 1.00 1.00 1.00 100x100 tiled rectangle (216x208 tile) |
| 2330 | 1.00 1.00 1.00 1.00 1.00 500x500 tiled rectangle (216x208 tile) |
| 2331 | 1.82 1.70 1.00 1.00 3.38 1-pixel line segment |
| 2332 | 2.07 1.56 0.90 1.00 3.31 10-pixel line segment |
| 2333 | 1.29 1.10 1.00 1.00 1.27 100-pixel line segment |
| 2334 | 1.05 1.06 1.03 1.03 1.09 500-pixel line segment |
| 2335 | 1.30 1.13 1.00 1.00 1.29 100-pixel line segment (1 kid) |
| 2336 | 1.32 1.15 1.00 1.00 1.32 100-pixel line segment (2 kids) |
| 2337 | 1.33 1.16 1.00 1.00 1.33 100-pixel line segment (3 kids) |
| 2338 | 1.92 1.64 1.00 1.00 3.73 10-pixel dashed segment |
| 2339 | 1.34 1.16 1.00 1.00 1.34 100-pixel dashed segment |
| 2340 | 1.24 1.11 0.99 0.97 1.23 100-pixel double-dashed segment |
| 2341 | 1.72 1.77 1.00 1.00 3.25 10-pixel horizontal line segment |
| 2342 | 1.83 1.66 1.01 1.00 3.54 100-pixel horizontal line segment |
| 2343 | 1.86 1.30 1.00 1.00 1.84 500-pixel horizontal line segment |
| 2344 | 2.11 1.52 1.00 0.99 3.02 10-pixel vertical line segment |
| 2345 | 1.21 1.10 1.00 1.00 1.20 100-pixel vertical line segment |
| 2346 | 1.03 1.03 1.00 1.00 1.02 500-pixel vertical line segment |
| 2347 | 4.42 1.68 1.00 1.01 4.64 10x1 wide horizontal line segment |
| 2348 | 1.83 1.31 1.00 1.00 1.83 100x10 wide horizontal line segment |
| 2349 | 1.07 1.00 0.96 1.00 1.07 500x50 wide horizontal line segment |
| 2350 | 4.10 1.67 1.00 1.00 4.62 10x1 wide vertical line segment |
| 2351 | 1.50 1.24 1.06 1.06 1.48 100x10 wide vertical line segment |
| 2352 | 1.06 1.03 1.00 1.00 1.05 500x50 wide vertical line segment |
| 2353 | 2.54 1.61 1.00 1.00 3.61 1-pixel line |
| 2354 | 2.71 1.48 1.00 1.00 2.67 10-pixel line |
| 2355 | 1.19 1.09 1.00 1.00 1.19 100-pixel line |
| 2356 | 1.04 1.02 1.00 1.00 1.03 500-pixel line |
| 2357 | 2.68 1.51 0.98 1.00 3.17 10-pixel dashed line |
| 2358 | 1.23 1.11 0.99 0.99 1.23 100-pixel dashed line |
| 2359 | 1.15 1.08 1.00 1.00 1.15 100-pixel double-dashed line |
| 2360 | 2.27 1.39 1.00 1.00 2.23 10x1 wide line |
| 2361 | 1.20 1.09 1.00 1.00 1.20 100x10 wide line |
| 2362 | 1.04 1.02 1.00 1.00 1.04 500x50 wide line |
| 2363 | 1.52 1.45 1.00 1.00 1.52 100x10 wide dashed line |
| 2364 | 1.54 1.47 1.00 1.00 1.54 100x10 wide double-dashed line |
| 2365 | 1.97 1.30 0.96 0.95 1.95 10x10 rectangle outline |
| 2366 | 1.44 1.27 1.00 1.00 1.43 100x100 rectangle outline |
| 2367 | 3.22 2.16 1.10 1.09 3.61 500x500 rectangle outline |
| 2368 | 1.95 1.34 1.00 1.00 1.90 10x10 wide rectangle outline |
| 2369 | 1.14 1.14 1.00 1.00 1.13 100x100 wide rectangle outline |
| 2370 | 1.00 1.00 1.00 1.00 1.00 500x500 wide rectangle outline |
| 2371 | 1.57 1.72 1.00 1.00 3.03 1-pixel circle |
| 2372 | 1.96 1.35 1.00 1.00 1.92 10-pixel circle |
| 2373 | 1.21 1.07 0.86 0.97 1.20 100-pixel circle |
| 2374 | 1.08 1.04 1.00 1.00 1.08 500-pixel circle |
| 2375 | 1.39 1.19 1.03 1.03 1.38 100-pixel dashed circle |
| 2376 | 1.21 1.11 1.00 1.00 1.23 100-pixel double-dashed circle |
| 2377 | 1.59 1.28 1.00 1.00 1.58 10-pixel wide circle |
| 2378 | 1.22 1.12 0.99 1.00 1.22 100-pixel wide circle |
| 2379 | 1.06 1.04 1.00 1.00 1.05 500-pixel wide circle |
| 2380 | 1.87 1.84 1.00 1.00 1.85 100-pixel wide dashed circle |
| 2381 | 1.90 1.93 1.01 1.01 1.90 100-pixel wide double-dashed circle |
| 2382 | 2.13 1.43 1.00 1.00 2.32 10-pixel partial circle |
| 2383 | 1.42 1.18 1.00 1.00 1.42 100-pixel partial circle |
| 2384 | 1.92 1.85 1.01 1.01 1.89 10-pixel wide partial circle |
| 2385 | 1.73 1.67 1.00 1.00 1.73 100-pixel wide partial circle |
| 2386 | 1.36 1.95 1.00 1.00 2.64 1-pixel solid circle |
| 2387 | 2.02 1.37 1.00 1.00 2.03 10-pixel solid circle |
| 2388 | 1.19 1.09 1.00 1.00 1.19 100-pixel solid circle |
| 2389 | 1.02 0.99 1.00 1.00 1.01 500-pixel solid circle |
| 2390 | 1.74 1.28 1.00 0.88 1.73 10-pixel fill chord partial circle |
| 2391 | 1.31 1.13 1.00 1.00 1.31 100-pixel fill chord partial circle |
| 2392 | 1.67 1.31 1.03 1.03 1.72 10-pixel fill slice partial circle |
| 2393 | 1.30 1.13 1.00 1.00 1.28 100-pixel fill slice partial circle |
| 2394 | 2.45 1.49 1.01 1.00 2.71 10-pixel ellipse |
| 2395 | 1.22 1.10 1.00 1.00 1.22 100-pixel ellipse |
| 2396 | 1.09 1.04 1.00 1.00 1.09 500-pixel ellipse |
| 2397 | 1.90 1.28 1.00 1.00 1.89 100-pixel dashed ellipse |
| 2398 | 1.62 1.24 0.96 0.97 1.61 100-pixel double-dashed ellipse |
| 2399 | 2.43 1.50 1.00 1.00 2.42 10-pixel wide ellipse |
| 2400 | 1.61 1.28 1.03 1.03 1.60 100-pixel wide ellipse |
| 2401 | 1.08 1.05 1.00 1.00 1.08 500-pixel wide ellipse |
| 2402 | 1.93 1.88 1.00 1.00 1.88 100-pixel wide dashed ellipse |
| 2403 | 1.94 1.89 1.01 1.00 1.94 100-pixel wide double-dashed ellipse |
| 2404 | 2.31 1.48 1.00 1.00 2.67 10-pixel partial ellipse |
| 2405 | 1.38 1.17 1.00 1.00 1.38 100-pixel partial ellipse |
| 2406 | 2.00 1.85 0.98 0.97 1.98 10-pixel wide partial ellipse |
| 2407 | 1.89 1.86 1.00 1.00 1.89 100-pixel wide partial ellipse |
| 2408 | 3.49 1.60 1.00 1.00 3.65 10-pixel filled ellipse |
| 2409 | 1.67 1.26 1.00 1.00 1.67 100-pixel filled ellipse |
| 2410 | 1.06 1.04 1.00 1.00 1.06 500-pixel filled ellipse |
| 2411 | 2.38 1.43 1.01 1.00 2.32 10-pixel fill chord partial ellipse |
| 2412 | 2.06 1.30 1.00 1.00 2.05 100-pixel fill chord partial ellipse |
| 2413 | 2.27 1.41 1.00 1.00 2.27 10-pixel fill slice partial ellipse |
| 2414 | 1.98 1.33 1.00 0.97 1.97 100-pixel fill slice partial ellipse |
| 2415 | 57.46 1.99 1.01 1.00 114.92 Fill 1x1 equivalent triangle |
| 2416 | 56.94 1.98 1.01 1.00 73.89 Fill 10x10 equivalent triangle |
| 2417 | 6.07 1.75 1.00 1.00 6.07 Fill 100x100 equivalent triangle |
| 2418 | 51.12 1.98 1.00 1.00 102.81 Fill 1x1 trapezoid |
| 2419 | 51.42 1.82 1.01 1.00 94.89 Fill 10x10 trapezoid |
| 2420 | 6.47 1.80 1.00 1.00 6.44 Fill 100x100 trapezoid |
| 2421 | 1.56 1.28 1.00 0.99 1.56 Fill 300x300 trapezoid |
| 2422 | 51.27 1.97 0.96 0.97 102.54 Fill 1x1 stippled trapezoid (8x8 stipple) |
| 2423 | 51.73 2.00 1.02 1.02 67.92 Fill 10x10 stippled trapezoid (8x8 stipple) |
| 2424 | 5.36 1.72 1.00 1.00 5.36 Fill 100x100 stippled trapezoid (8x8 stipple) |
| 2425 | 1.54 1.26 1.00 1.00 1.59 Fill 300x300 stippled trapezoid (8x8 stipple) |
| 2426 | 51.41 1.94 1.01 1.00 102.82 Fill 1x1 opaque stippled trapezoid (8x8 stipple) |
| 2427 | 50.71 1.95 0.99 1.00 65.44 Fill 10x10 opaque stippled trapezoid (8x8... |
| 2428 | 5.33 1.73 1.00 1.00 5.36 Fill 100x100 opaque stippled trapezoid (8x8... |
| 2429 | 1.58 1.25 1.00 1.00 1.58 Fill 300x300 opaque stippled trapezoid (8x8... |
| 2430 | 51.56 1.96 0.99 0.90 103.68 Fill 1x1 tiled trapezoid (4x4 tile) |
| 2431 | 51.59 1.99 1.01 1.01 62.25 Fill 10x10 tiled trapezoid (4x4 tile) |
| 2432 | 5.38 1.72 1.00 1.00 5.38 Fill 100x100 tiled trapezoid (4x4 tile) |
| 2433 | 1.54 1.25 1.00 0.99 1.58 Fill 300x300 tiled trapezoid (4x4 tile) |
| 2434 | 51.70 1.98 1.01 1.01 103.98 Fill 1x1 stippled trapezoid (17x15 stipple) |
| 2435 | 44.86 1.97 1.00 1.00 44.86 Fill 10x10 stippled trapezoid (17x15 stipple) |
| 2436 | 2.74 1.56 1.00 1.00 2.73 Fill 100x100 stippled trapezoid (17x15 stipple) |
| 2437 | 1.29 1.14 1.00 1.00 1.27 Fill 300x300 stippled trapezoid (17x15 stipple) |
| 2438 | 51.41 1.96 0.96 0.95 103.39 Fill 1x1 opaque stippled trapezoid (17x15... |
| 2439 | 45.14 1.96 1.01 1.00 45.14 Fill 10x10 opaque stippled trapezoid (17x15... |
| 2440 | 2.68 1.56 1.00 1.00 2.68 Fill 100x100 opaque stippled trapezoid (17x15... |
| 2441 | 1.26 1.10 1.00 1.00 1.28 Fill 300x300 opaque stippled trapezoid (17x15... |
| 2442 | 51.13 1.97 1.00 0.99 103.39 Fill 1x1 tiled trapezoid (17x15 tile) |
| 2443 | 47.58 1.96 1.00 1.00 47.86 Fill 10x10 tiled trapezoid (17x15 tile) |
| 2444 | 2.74 1.56 1.00 1.00 2.74 Fill 100x100 tiled trapezoid (17x15 tile) |
| 2445 | 1.29 1.14 1.00 1.00 1.28 Fill 300x300 tiled trapezoid (17x15 tile) |
| 2446 | 51.13 1.97 0.99 0.97 103.39 Fill 1x1 stippled trapezoid (161x145 stipple) |
| 2447 | 45.14 1.97 1.00 1.00 44.29 Fill 10x10 stippled trapezoid (161x145 stipple) |
| 2448 | 3.02 1.77 1.12 1.12 3.38 Fill 100x100 stippled trapezoid (161x145 stipple) |
| 2449 | 1.31 1.13 1.00 1.00 1.30 Fill 300x300 stippled trapezoid (161x145 stipple) |
| 2450 | 51.27 1.97 1.00 1.00 103.10 Fill 1x1 opaque stippled trapezoid (161x145... |
| 2451 | 45.01 1.97 1.00 1.00 45.01 Fill 10x10 opaque stippled trapezoid (161x145... |
| 2452 | 2.67 1.56 1.00 1.00 2.69 Fill 100x100 opaque stippled trapezoid (161x145.. |
| 2453 | 1.29 1.13 1.00 1.01 1.27 Fill 300x300 opaque stippled trapezoid (161x145.. |
| 2454 | 51.41 1.96 1.00 0.99 103.39 Fill 1x1 tiled trapezoid (161x145 tile) |
| 2455 | 45.01 1.96 0.98 1.00 45.01 Fill 10x10 tiled trapezoid (161x145 tile) |
| 2456 | 2.62 1.36 1.00 1.00 2.69 Fill 100x100 tiled trapezoid (161x145 tile) |
| 2457 | 1.27 1.13 1.00 1.00 1.22 Fill 300x300 tiled trapezoid (161x145 tile) |
| 2458 | 51.13 1.98 1.00 1.00 103.39 Fill 1x1 tiled trapezoid (216x208 tile) |
| 2459 | 45.14 1.97 1.01 0.99 45.14 Fill 10x10 tiled trapezoid (216x208 tile) |
| 2460 | 2.62 1.55 1.00 1.00 2.71 Fill 100x100 tiled trapezoid (216x208 tile) |
| 2461 | 1.28 1.13 1.00 1.00 1.20 Fill 300x300 tiled trapezoid (216x208 tile) |
| 2462 | 50.71 1.95 1.00 1.00 54.70 Fill 10x10 equivalent complex polygon |
| 2463 | 5.51 1.71 0.96 0.98 5.47 Fill 100x100 equivalent complex polygons |
| 2464 | 8.39 1.97 1.00 1.00 16.75 Fill 10x10 64-gon (Convex) |
| 2465 | 8.38 1.83 1.00 1.00 8.43 Fill 100x100 64-gon (Convex) |
| 2466 | 8.50 1.96 1.00 1.00 16.64 Fill 10x10 64-gon (Complex) |
| 2467 | 8.26 1.83 1.00 1.00 8.35 Fill 100x100 64-gon (Complex) |
| 2468 | 14.09 1.87 1.00 1.00 14.05 Char in 80-char line (6x13) |
| 2469 | 11.91 1.87 1.00 1.00 11.95 Char in 70-char line (8x13) |
| 2470 | 11.16 1.85 1.01 1.00 11.10 Char in 60-char line (9x15) |
| 2471 | 10.09 1.78 1.00 1.00 10.09 Char16 in 40-char line (k14) |
| 2472 | 6.15 1.75 1.00 1.00 6.31 Char16 in 23-char line (k24) |
| 2473 | 11.92 1.90 1.03 1.03 11.88 Char in 80-char line (TR 10) |
| 2474 | 8.18 1.78 1.00 0.99 8.17 Char in 30-char line (TR 24) |
| 2475 | 42.83 1.44 1.01 1.00 42.11 Char in 20/40/20 line (6x13, TR 10) |
| 2476 | 27.45 1.43 1.01 1.01 27.45 Char16 in 7/14/7 line (k14, k24) |
| 2477 | 12.13 1.85 1.00 1.00 12.05 Char in 80-char image line (6x13) |
| 2478 | 10.00 1.84 1.00 1.00 10.00 Char in 70-char image line (8x13) |
| 2479 | 9.18 1.83 1.00 1.00 9.12 Char in 60-char image line (9x15) |
| 2480 | 9.66 1.82 0.98 0.95 9.66 Char16 in 40-char image line (k14) |
| 2481 | 5.82 1.72 1.00 1.00 5.99 Char16 in 23-char image line (k24) |
| 2482 | 8.70 1.80 1.00 1.00 8.65 Char in 80-char image line (TR 10) |
| 2483 | 4.67 1.66 1.00 1.00 4.67 Char in 30-char image line (TR 24) |
| 2484 | 84.43 1.47 1.00 1.00 124.18 Scroll 10x10 pixels |
| 2485 | 3.73 1.50 1.00 0.98 3.73 Scroll 100x100 pixels |
| 2486 | 1.00 1.00 1.00 1.00 1.00 Scroll 500x500 pixels |
| 2487 | 84.43 1.51 1.00 1.00 134.02 Copy 10x10 from window to window |
| 2488 | 3.62 1.51 0.98 0.98 3.62 Copy 100x100 from window to window |
| 2489 | 0.89 1.00 1.00 1.00 1.00 Copy 500x500 from window to window |
| 2490 | 57.06 1.99 1.00 1.00 88.64 Copy 10x10 from pixmap to window |
| 2491 | 2.49 2.00 1.00 1.00 2.48 Copy 100x100 from pixmap to window |
| 2492 | 1.00 0.91 1.00 1.00 0.98 Copy 500x500 from pixmap to window |
| 2493 | 2.04 1.01 1.00 1.00 2.03 Copy 10x10 from window to pixmap |
| 2494 | 1.05 1.00 1.00 1.00 1.05 Copy 100x100 from window to pixmap |
| 2495 | 1.00 1.00 0.93 1.00 1.04 Copy 500x500 from window to pixmap |
| 2496 | 58.52 1.03 1.03 1.02 57.95 Copy 10x10 from pixmap to pixmap |
| 2497 | 2.40 1.00 1.00 1.00 2.45 Copy 100x100 from pixmap to pixmap |
| 2498 | 1.00 1.00 1.00 1.00 1.00 Copy 500x500 from pixmap to pixmap |
| 2499 | 51.57 1.92 1.00 1.00 85.75 Copy 10x10 1-bit deep plane |
| 2500 | 6.37 1.75 1.01 1.01 6.37 Copy 100x100 1-bit deep plane |
| 2501 | 1.26 1.11 1.00 1.00 1.24 Copy 500x500 1-bit deep plane |
| 2502 | 4.23 1.63 0.98 0.97 4.38 Copy 10x10 n-bit deep plane |
| 2503 | 1.04 1.02 1.00 1.00 1.04 Copy 100x100 n-bit deep plane |
| 2504 | 1.00 1.00 1.00 1.00 1.00 Copy 500x500 n-bit deep plane |
| 2505 | 6.45 1.98 1.00 1.26 12.80 PutImage 10x10 square |
| 2506 | 1.10 1.87 1.00 1.83 2.11 PutImage 100x100 square |
| 2507 | 1.02 1.93 1.00 1.91 1.91 PutImage 500x500 square |
| 2508 | 4.17 1.78 1.00 1.40 7.18 PutImage XY 10x10 square |
| 2509 | 1.27 1.49 0.97 1.48 2.10 PutImage XY 100x100 square |
| 2510 | 1.00 1.50 1.00 1.50 1.52 PutImage XY 500x500 square |
| 2511 | 1.07 1.01 1.00 1.00 1.06 GetImage 10x10 square |
| 2512 | 1.01 1.00 1.00 1.00 1.01 GetImage 100x100 square |
| 2513 | 1.00 1.00 1.00 1.00 1.00 GetImage 500x500 square |
| 2514 | 1.56 1.00 0.99 0.97 1.56 GetImage XY 10x10 square |
| 2515 | 1.02 1.00 1.00 1.00 1.02 GetImage XY 100x100 square |
| 2516 | 1.00 1.00 1.00 1.00 1.00 GetImage XY 500x500 square |
| 2517 | 1.00 1.00 1.01 0.98 0.95 X protocol NoOperation |
| 2518 | 1.02 1.03 1.04 1.03 1.00 QueryPointer |
| 2519 | 1.03 1.02 1.04 1.03 1.00 GetProperty |
| 2520 | 100.41 1.51 1.00 1.00 198.76 Change graphics context |
| 2521 | 45.81 1.00 0.99 0.97 57.10 Create and map subwindows (4 kids) |
| 2522 | 78.45 1.01 1.02 1.02 63.07 Create and map subwindows (16 kids) |
| 2523 | 73.91 1.01 1.00 1.00 56.37 Create and map subwindows (25 kids) |
| 2524 | 73.22 1.00 1.00 1.00 49.07 Create and map subwindows (50 kids) |
| 2525 | 72.36 1.01 0.99 1.00 32.14 Create and map subwindows (75 kids) |
| 2526 | 70.34 1.00 1.00 1.00 30.12 Create and map subwindows (100 kids) |
| 2527 | 55.00 1.00 1.00 0.99 23.75 Create and map subwindows (200 kids) |
| 2528 | 55.30 1.01 1.00 1.00 141.03 Create unmapped window (4 kids) |
| 2529 | 55.38 1.01 1.01 1.00 163.25 Create unmapped window (16 kids) |
| 2530 | 54.75 0.96 1.00 0.99 166.95 Create unmapped window (25 kids) |
| 2531 | 54.83 1.00 1.00 0.99 178.81 Create unmapped window (50 kids) |
| 2532 | 55.38 1.01 1.01 1.00 181.20 Create unmapped window (75 kids) |
| 2533 | 55.38 1.01 1.01 1.00 181.20 Create unmapped window (100 kids) |
| 2534 | 54.87 1.01 1.01 1.00 182.05 Create unmapped window (200 kids) |
| 2535 | 28.13 1.00 1.00 1.00 30.75 Map window via parent (4 kids) |
| 2536 | 36.14 1.01 1.01 1.01 32.58 Map window via parent (16 kids) |
| 2537 | 26.13 1.00 0.98 0.95 29.85 Map window via parent (25 kids) |
| 2538 | 40.07 1.00 1.01 1.00 27.57 Map window via parent (50 kids) |
| 2539 | 23.26 0.99 1.00 1.00 18.23 Map window via parent (75 kids) |
| 2540 | 22.91 0.99 1.00 0.99 16.52 Map window via parent (100 kids) |
| 2541 | 27.79 1.00 1.00 0.99 12.50 Map window via parent (200 kids) |
| 2542 | 22.35 1.00 1.00 1.00 56.19 Unmap window via parent (4 kids) |
| 2543 | 9.57 1.00 0.99 1.00 89.78 Unmap window via parent (16 kids) |
| 2544 | 80.77 1.01 1.00 1.00 103.85 Unmap window via parent (25 kids) |
| 2545 | 96.34 1.00 1.00 1.00 116.06 Unmap window via parent (50 kids) |
| 2546 | 99.72 1.00 1.00 1.00 124.93 Unmap window via parent (75 kids) |
| 2547 | 112.36 1.00 1.00 1.00 125.27 Unmap window via parent (100 kids) |
| 2548 | 105.41 1.00 1.00 0.99 120.00 Unmap window via parent (200 kids) |
| 2549 | 51.29 1.03 1.02 1.02 74.19 Destroy window via parent (4 kids) |
| 2550 | 86.75 0.99 0.99 0.99 116.87 Destroy window via parent (16 kids) |
| 2551 | 106.43 1.01 1.01 1.01 127.49 Destroy window via parent (25 kids) |
| 2552 | 120.34 1.01 1.01 1.00 140.11 Destroy window via parent (50 kids) |
| 2553 | 126.67 1.00 0.99 0.99 145.00 Destroy window via parent (75 kids) |
| 2554 | 126.11 1.01 1.01 1.00 140.56 Destroy window via parent (100 kids) |
| 2555 | 128.57 1.01 1.00 1.00 137.91 Destroy window via parent (200 kids) |
| 2556 | 16.04 0.88 1.00 1.00 20.36 Hide/expose window via popup (4 kids) |
| 2557 | 19.04 1.01 1.00 1.00 23.48 Hide/expose window via popup (16 kids) |
| 2558 | 19.22 1.00 1.00 1.00 20.44 Hide/expose window via popup (25 kids) |
| 2559 | 17.41 1.00 0.91 0.97 17.68 Hide/expose window via popup (50 kids) |
| 2560 | 17.29 1.01 1.00 1.01 17.07 Hide/expose window via popup (75 kids) |
| 2561 | 16.74 1.00 1.00 1.00 16.17 Hide/expose window via popup (100 kids) |
| 2562 | 10.30 1.00 1.00 1.00 10.51 Hide/expose window via popup (200 kids) |
| 2563 | 16.48 1.01 1.00 1.00 26.05 Move window (4 kids) |
| 2564 | 17.01 0.95 1.00 1.00 23.97 Move window (16 kids) |
| 2565 | 16.95 1.00 1.00 1.00 22.90 Move window (25 kids) |
| 2566 | 16.05 1.01 1.00 1.00 21.32 Move window (50 kids) |
| 2567 | 15.58 1.00 0.98 0.98 19.44 Move window (75 kids) |
| 2568 | 14.98 1.02 1.03 1.03 18.17 Move window (100 kids) |
| 2569 | 10.90 1.01 1.01 1.00 12.68 Move window (200 kids) |
| 2570 | 49.42 1.00 1.00 1.00 198.27 Moved unmapped window (4 kids) |
| 2571 | 50.72 0.97 1.00 1.00 193.66 Moved unmapped window (16 kids) |
| 2572 | 50.87 1.00 0.99 1.00 195.09 Moved unmapped window (25 kids) |
| 2573 | 50.72 1.00 1.00 1.00 189.34 Moved unmapped window (50 kids) |
| 2574 | 50.87 1.00 1.00 1.00 191.33 Moved unmapped window (75 kids) |
| 2575 | 50.87 1.00 1.00 0.90 186.71 Moved unmapped window (100 kids) |
| 2576 | 50.87 1.00 1.00 1.00 179.19 Moved unmapped window (200 kids) |
| 2577 | 41.04 1.00 1.00 1.00 56.61 Move window via parent (4 kids) |
| 2578 | 69.81 1.00 1.00 1.00 130.82 Move window via parent (16 kids) |
| 2579 | 95.81 1.00 1.00 1.00 141.92 Move window via parent (25 kids) |
| 2580 | 95.98 1.00 1.00 1.00 149.43 Move window via parent (50 kids) |
| 2581 | 96.59 1.01 1.01 1.00 153.98 Move window via parent (75 kids) |
| 2582 | 97.19 1.00 1.00 1.00 157.30 Move window via parent (100 kids) |
| 2583 | 96.67 1.00 0.99 0.96 159.44 Move window via parent (200 kids) |
| 2584 | 17.75 1.01 1.00 1.00 27.61 Resize window (4 kids) |
| 2585 | 17.94 1.00 1.00 0.99 25.42 Resize window (16 kids) |
| 2586 | 17.92 1.01 1.00 1.00 24.47 Resize window (25 kids) |
| 2587 | 17.24 0.97 1.00 1.00 24.14 Resize window (50 kids) |
| 2588 | 16.81 1.00 1.00 0.99 22.75 Resize window (75 kids) |
| 2589 | 16.08 1.00 1.00 1.00 21.20 Resize window (100 kids) |
| 2590 | 12.92 1.00 0.99 1.00 16.26 Resize window (200 kids) |
| 2591 | 52.94 1.01 1.00 1.00 327.12 Resize unmapped window (4 kids) |
| 2592 | 53.60 1.01 1.01 1.01 333.71 Resize unmapped window (16 kids) |
| 2593 | 52.99 1.00 1.00 1.00 337.29 Resize unmapped window (25 kids) |
| 2594 | 51.98 1.00 1.00 1.00 329.38 Resize unmapped window (50 kids) |
| 2595 | 53.05 0.89 1.00 1.00 322.60 Resize unmapped window (75 kids) |
| 2596 | 53.05 1.00 1.00 1.00 318.08 Resize unmapped window (100 kids) |
| 2597 | 53.11 1.00 1.00 0.99 306.21 Resize unmapped window (200 kids) |
| 2598 | 16.76 1.00 0.96 1.00 19.46 Circulate window (4 kids) |
| 2599 | 17.24 1.00 1.00 0.97 16.24 Circulate window (16 kids) |
| 2600 | 16.30 1.03 1.03 1.03 15.85 Circulate window (25 kids) |
| 2601 | 13.45 1.00 1.00 1.00 14.90 Circulate window (50 kids) |
| 2602 | 12.91 1.00 1.00 1.00 13.06 Circulate window (75 kids) |
| 2603 | 11.30 0.98 1.00 1.00 11.03 Circulate window (100 kids) |
| 2604 | 7.58 1.01 1.01 0.99 7.47 Circulate window (200 kids) |
| 2605 | 1.01 1.01 0.98 1.00 0.95 Circulate Unmapped window (4 kids) |
| 2606 | 1.07 1.07 1.01 1.07 1.02 Circulate Unmapped window (16 kids) |
| 2607 | 1.04 1.09 1.06 1.05 0.97 Circulate Unmapped window (25 kids) |
| 2608 | 1.04 1.23 1.20 1.18 1.05 Circulate Unmapped window (50 kids) |
| 2609 | 1.18 1.53 1.19 1.45 1.24 Circulate Unmapped window (75 kids) |
| 2610 | 1.08 1.02 1.01 1.74 1.01 Circulate Unmapped window (100 kids) |
| 2611 | 1.01 1.12 0.98 0.91 0.97 Circulate Unmapped window (200 kids) |
| 2612 | </screen> |
| 2613 | </para> |
| 2614 | </sect3> |
| 2615 | |
| 2616 | <sect3> |
| 2617 | <title>Profiling with OProfile</title> |
| 2618 | |
| 2619 | <para>OProfile (available from http://oprofile.sourceforge.net/) is a |
| 2620 | system-wide profiler for Linux systems that uses processor-level |
| 2621 | counters to collect sampling data. OProfile can provide information |
| 2622 | that is similar to that provided by <command>gprof</command>, but without the |
| 2623 | necessity of recompiling the program with special instrumentation (i.e., |
| 2624 | OProfile can collect statistical profiling information about optimized |
| 2625 | programs). A test harness was developed to collect OProfile data for |
| 2626 | each <command>x11perf</command> test individually. |
| 2627 | </para> |
| 2628 | |
| 2629 | <para>Test runs were performed using the RETIRED_INSNS counter on the AMD |
| 2630 | Athlon and the CPU_CLK_HALTED counter on the Intel Pentium III (with a |
| 2631 | test configuration different from the one described above). We have |
| 2632 | examined OProfile output and have compared it with <command>gprof</command> output. |
| 2633 | This investigation has not produced results that yield performance |
| 2634 | increases in <command>x11perf</command> numbers. |
| 2635 | </para> |
| 2636 | |
| 2637 | </sect3> |
| 2638 | |
| 2639 | <!-- |
| 2640 | <sect3>Retired Instructions |
| 2641 | |
| 2642 | <p>The initial tests using OProfile were done using the RETIRED_INSNS |
| 2643 | counter with DMX running on the dual-processor AMD Athlon machine - the |
| 2644 | same test configuration that was described above and that was used for |
| 2645 | other tests. The RETIRED_INSNS counter counts retired instructions and |
| 2646 | showed drawing, text, copying, and image tests to be dominated (> |
| 2647 | 30%) by calls to Hash(), SecurityLookupIDByClass(), |
| 2648 | SecurityLookupIDByType(), and StandardReadRequestFromClient(). Some of |
| 2649 | these tests also executed significant instructions in |
| 2650 | WaitForSomething(). |
| 2651 | |
| 2652 | <p>In contrast, the window tests executed significant |
| 2653 | instructions in SecurityLookupIDByType(), Hash(), |
| 2654 | StandardReadRequestFromClient(), but also executed significant |
| 2655 | instructions in other routines, such as ConfigureWindow(). Some time |
| 2656 | was spent looking at Hash() function, but optimizations in this routine |
| 2657 | did not lead to a dramatic increase in <tt/x11perf/ performance. |
| 2658 | --> |
| 2659 | |
| 2660 | <!-- |
| 2661 | <sect3>Clock Cycles |
| 2662 | |
| 2663 | <p>Retired instructions can be misleading because Intel/AMD instructions |
| 2664 | execute in variable amounts of time. The OProfile tests were repeated |
| 2665 | using the Intel CPU_CLK_HALTED counter with DMX running on the second |
| 2666 | back-end machine. Note that this is a different test configuration that |
| 2667 | the one described above. However, these tests show the amount of time |
| 2668 | (as measured in CPU cycles) that are spent in each routine. Because |
| 2669 | <tt/x11perf/ was running on the first back-end machine and because |
| 2670 | window optimizations were on, the load on the second back-end machine |
| 2671 | was not significant. |
| 2672 | |
| 2673 | <p>Using CPU_CLK_HALTED, DMX showed simple drawing |
| 2674 | tests spending more than 10% of their time in |
| 2675 | StandardReadRequestFromClient(), with significant time (> 20% total) |
| 2676 | spent in SecurityLookupIDByClass(), WaitForSomething(), and Dispatch(). |
| 2677 | For these tests, < 5% of the time was spent in Hash(), which explains |
| 2678 | why optimizing the Hash() routine did not impact <tt/x11perf/ results. |
| 2679 | |
| 2680 | <p>The trapezoid, text, scrolling, copying, and image tests were |
| 2681 | dominated by time in ProcFillPoly(), PanoramiXFillPoly(), dmxFillPolygon(), |
| 2682 | SecurityLookupIDByClass(), SecurityLookupIDByType(), and |
| 2683 | StandardReadRequestFromClient(). Hash() time was generally above 5% but |
| 2684 | less than 10% of total time. |
| 2685 | --> |
| 2686 | |
| 2687 | <sect3> |
| 2688 | <title>X Test Suite</title> |
| 2689 | |
| 2690 | <para>The X Test Suite was run on the fully optimized DMX server using the |
| 2691 | configuration described above. The following failures were noted: |
| 2692 | <screen> |
| 2693 | XListPixmapFormats: Test 1 [1] |
| 2694 | XChangeWindowAttributes: Test 32 [1] |
| 2695 | XCreateWindow: Test 30 [1] |
| 2696 | XFreeColors: Test 4 [3] |
| 2697 | XCopyArea: Test 13, 17, 21, 25, 30 [2] |
| 2698 | XCopyPlane: Test 11, 15, 27, 31 [2] |
| 2699 | XSetFontPath: Test 4 [1] |
| 2700 | XChangeKeyboardControl: Test 9, 10 [1] |
| 2701 | |
| 2702 | [1] Previously documented errors expected from the Xinerama |
| 2703 | implementation (see Phase I discussion). |
| 2704 | [2] Newly noted errors that have been verified as expected |
| 2705 | behavior of the Xinerama implementation. |
| 2706 | [3] Newly noted error that has been verified as a Xinerama |
| 2707 | implementation bug. |
| 2708 | </screen> |
| 2709 | </para> |
| 2710 | |
| 2711 | </sect3> |
| 2712 | |
| 2713 | </sect2> |
| 2714 | |
| 2715 | <!-- ============================================================ --> |
| 2716 | <sect2> |
| 2717 | <title>Phase III</title> |
| 2718 | |
| 2719 | <para>During the third phase of development, support was provided for the |
| 2720 | following extensions: SHAPE, RENDER, XKEYBOARD, XInput. |
| 2721 | </para> |
| 2722 | |
| 2723 | <sect3> |
| 2724 | <title>SHAPE</title> |
| 2725 | |
| 2726 | <para>The SHAPE extension is supported. Test applications (e.g., xeyes and |
| 2727 | oclock) and window managers that make use of the SHAPE extension will |
| 2728 | work as expected. |
| 2729 | </para> |
| 2730 | </sect3> |
| 2731 | |
| 2732 | <sect3> |
| 2733 | <title>RENDER</title> |
| 2734 | |
| 2735 | <para>The RENDER extension is supported. The version included in the DMX |
| 2736 | CVS tree is version 0.2, and this version is fully supported by Xdmx. |
| 2737 | Applications using only version 0.2 functions will work correctly; |
| 2738 | however, some apps that make use of functions from later versions do not |
| 2739 | properly check the extension's major/minor version numbers. These apps |
| 2740 | will fail with a Bad Implementation error when using post-version 0.2 |
| 2741 | functions. This is expected behavior. When the DMX CVS tree is updated |
| 2742 | to include newer versions of RENDER, support for these newer functions |
| 2743 | will be added to the DMX X server. |
| 2744 | </para> |
| 2745 | </sect3> |
| 2746 | |
| 2747 | <sect3> |
| 2748 | <title>XKEYBOARD</title> |
| 2749 | |
| 2750 | <para>The XKEYBOARD extension is supported. If present on the back-end X |
| 2751 | servers, the XKEYBOARD extension will be used to obtain information |
| 2752 | about the type of the keyboard for initialization. Otherwise, the |
| 2753 | keyboard will be initialized using defaults. Note that this departs |
| 2754 | from older behavior: when Xdmx is compiled without XKEYBOARD support, |
| 2755 | the map from the back-end X server will be preserved. With XKEYBOARD |
| 2756 | support, the map is not preserved because better information and control |
| 2757 | of the keyboard is available. |
| 2758 | </para> |
| 2759 | </sect3> |
| 2760 | |
| 2761 | <sect3> |
| 2762 | <title>XInput</title> |
| 2763 | |
| 2764 | <para>The XInput extension is supported. Any device can be used as a core |
| 2765 | device and be used as an XInput extension device, with the exception of |
| 2766 | core devices on the back-end servers. This limitation is present |
| 2767 | because cursor handling on the back-end requires that the back-end |
| 2768 | cursor sometimes track the Xdmx core cursor -- behavior that is |
| 2769 | incompatible with using the back-end pointer as a non-core device. |
| 2770 | </para> |
| 2771 | |
| 2772 | <para>Currently, back-end extension devices are not available as Xdmx |
| 2773 | extension devices, but this limitation should be removed in the future. |
| 2774 | </para> |
| 2775 | |
| 2776 | <para>To demonstrate the XInput extension, and to provide more examples for |
| 2777 | low-level input device driver writers, USB device drivers have been |
| 2778 | written for mice (usb-mou), keyboards (usb-kbd), and |
| 2779 | non-mouse/non-keyboard USB devices (usb-oth). Please see the man page |
| 2780 | for information on Linux kernel drivers that are required for using |
| 2781 | these Xdmx drivers. |
| 2782 | </para> |
| 2783 | </sect3> |
| 2784 | |
| 2785 | <sect3> |
| 2786 | <title>DPMS</title> |
| 2787 | |
| 2788 | <para>The DPMS extension is exported but does not do anything at this time. |
| 2789 | </para> |
| 2790 | |
| 2791 | </sect3> |
| 2792 | |
| 2793 | <sect3> |
| 2794 | <title>Other Extensions</title> |
| 2795 | |
| 2796 | <para>The LBX, |
| 2797 | SECURITY, |
| 2798 | XC-APPGROUP, and |
| 2799 | XFree86-Bigfont |
| 2800 | extensions do not require any special Xdmx support and have been exported. |
| 2801 | </para> |
| 2802 | |
| 2803 | <para>The |
| 2804 | BIG-REQUESTS, |
| 2805 | DEC-XTRAP, |
| 2806 | DOUBLE-BUFFER, |
| 2807 | Extended-Visual-Information, |
| 2808 | FontCache, |
| 2809 | GLX, |
| 2810 | MIT-SCREEN-SAVER, |
| 2811 | MIT-SHM, |
| 2812 | MIT-SUNDRY-NONSTANDARD, |
| 2813 | RECORD, |
| 2814 | SECURITY, |
| 2815 | SGI-GLX, |
| 2816 | SYNC, |
| 2817 | TOG-CUP, |
| 2818 | X-Resource, |
| 2819 | XC-MISC, |
| 2820 | XFree86-DGA, |
| 2821 | XFree86-DRI, |
| 2822 | XFree86-Misc, |
| 2823 | XFree86-VidModeExtension, and |
| 2824 | XVideo |
| 2825 | extensions are <emphasis remap="it">not</emphasis> supported at this time, but will be evaluated |
| 2826 | for inclusion in future DMX releases. <emphasis remap="bf">See below for additional work |
| 2827 | on extensions after Phase III.</emphasis> |
| 2828 | </para> |
| 2829 | </sect3> |
| 2830 | </sect2> |
| 2831 | |
| 2832 | <sect2> |
| 2833 | <title>Phase IV</title> |
| 2834 | |
| 2835 | <sect3> |
| 2836 | <title>Moving to XFree86 4.3.0</title> |
| 2837 | |
| 2838 | <para>For Phase IV, the recent release of XFree86 4.3.0 (27 February 2003) |
| 2839 | was merged onto the dmx.sourceforge.net CVS trunk and all work is |
| 2840 | proceeding using this tree. |
| 2841 | </para> |
| 2842 | </sect3> |
| 2843 | |
| 2844 | <sect3> |
| 2845 | <title>Extensions </title> |
| 2846 | |
| 2847 | <sect4> |
| 2848 | <title>XC-MISC (supported)</title> |
| 2849 | |
| 2850 | <para>XC-MISC is used internally by the X library to recycle XIDs from the |
| 2851 | X server. This is important for long-running X server sessions. Xdmx |
| 2852 | supports this extension. The X Test Suite passed and failed the exact |
| 2853 | same tests before and after this extension was enabled. |
| 2854 | <!-- Tested February/March 2003 --> |
| 2855 | </para> |
| 2856 | </sect4> |
| 2857 | |
| 2858 | <sect4> |
| 2859 | <title>Extended-Visual-Information (supported)</title> |
| 2860 | |
| 2861 | <para>The Extended-Visual-Information extension provides a method for an X |
| 2862 | client to obtain detailed visual information. Xdmx supports this |
| 2863 | extension. It was tested using the <filename>hw/dmx/examples/evi</filename> example |
| 2864 | program. <emphasis remap="bf">Note that this extension is not Xinerama-aware</emphasis> -- it will |
| 2865 | return visual information for each screen even though Xinerama is |
| 2866 | causing the X server to export a single logical screen. |
| 2867 | <!-- Tested March 2003 --> |
| 2868 | </para> |
| 2869 | </sect4> |
| 2870 | |
| 2871 | <sect4> |
| 2872 | <title>RES (supported)</title> |
| 2873 | |
| 2874 | <para>The X-Resource extension provides a mechanism for a client to obtain |
| 2875 | detailed information about the resources used by other clients. This |
| 2876 | extension was tested with the <filename>hw/dmx/examples/res</filename> program. The |
| 2877 | X Test Suite passed and failed the exact same tests before and after |
| 2878 | this extension was enabled. |
| 2879 | <!-- Tested March 2003 --> |
| 2880 | </para> |
| 2881 | </sect4> |
| 2882 | |
| 2883 | <sect4> |
| 2884 | <title>BIG-REQUESTS (supported)</title> |
| 2885 | |
| 2886 | <para>This extension enables the X11 protocol to handle requests longer |
| 2887 | than 262140 bytes. The X Test Suite passed and failed the exact same |
| 2888 | tests before and after this extension was enabled. |
| 2889 | <!-- Tested March 2003 --> |
| 2890 | </para> |
| 2891 | </sect4> |
| 2892 | |
| 2893 | <sect4> |
| 2894 | <title>XSYNC (supported)</title> |
| 2895 | |
| 2896 | <para>This extension provides facilities for two different X clients to |
| 2897 | synchronize their requests. This extension was minimally tested with |
| 2898 | <command>xdpyinfo</command> and the X Test Suite passed and failed the exact same |
| 2899 | tests before and after this extension was enabled. |
| 2900 | <!-- Tested March 2003 --> |
| 2901 | </para> |
| 2902 | </sect4> |
| 2903 | |
| 2904 | <sect4> |
| 2905 | <title>XTEST, RECORD, DEC-XTRAP (supported) and XTestExtension1 (not supported)</title> |
| 2906 | |
| 2907 | <para>The XTEST and RECORD extension were developed by the X Consortium for |
| 2908 | use in the X Test Suite and are supported as a standard in the X11R6 |
| 2909 | tree. They are also supported in Xdmx. When X Test Suite tests that |
| 2910 | make use of the XTEST extension are run, Xdmx passes and fails exactly |
| 2911 | the same tests as does a standard XFree86 X server. When the |
| 2912 | <literal remap="tt">rcrdtest</literal> test (a part of the X Test Suite that verifies the RECORD |
| 2913 | extension) is run, Xdmx passes and fails exactly the same tests as does |
| 2914 | a standard XFree86 X server. <!-- Tested February/March 2003 --> |
| 2915 | </para> |
| 2916 | |
| 2917 | <para>There are two older XTEST-like extensions: DEC-XTRAP and |
| 2918 | XTestExtension1. The XTestExtension1 extension was developed for use by |
| 2919 | the X Testing Consortium for use with a test suite that eventually |
| 2920 | became (part of?) the X Test Suite. Unlike XTEST, which only allows |
| 2921 | events to be sent to the server, the XTestExtension1 extension also |
| 2922 | allowed events to be recorded (similar to the RECORD extension). The |
| 2923 | second is the DEC-XTRAP extension that was developed by the Digital |
| 2924 | Equipment Corporation. |
| 2925 | </para> |
| 2926 | |
| 2927 | <para>The DEC-XTRAP extension is available from Xdmx and has been tested |
| 2928 | with the <command>xtrap*</command> tools which are distributed as standard X11R6 |
| 2929 | clients. <!-- Tested March 2003 --> |
| 2930 | </para> |
| 2931 | |
| 2932 | <para>The XTestExtension1 is <emphasis>not</emphasis> supported because it does not appear |
| 2933 | to be used by any modern X clients (the few that support it also support |
| 2934 | XTEST) and because there are no good methods available for testing that |
| 2935 | it functions correctly (unlike XTEST and DEC-XTRAP, the code for |
| 2936 | XTestExtension1 is not part of the standard X server source tree, so |
| 2937 | additional testing is important). <!-- Tested March 2003 --> |
| 2938 | </para> |
| 2939 | |
| 2940 | <para>Most of these extensions are documented in the X11R6 source tree. |
| 2941 | Further, several original papers exist that this author was unable to |
| 2942 | locate -- for completeness and historical interest, citations are |
| 2943 | provide: |
| 2944 | <variablelist> |
| 2945 | <varlistentry> |
| 2946 | <term>XRECORD</term> |
| 2947 | <listitem> |
| 2948 | <para>Martha Zimet. Extending X For Recording. 8th Annual X |
| 2949 | Technical Conference Boston, MA January 24-26, 1994. |
| 2950 | </para></listitem></varlistentry> |
| 2951 | <varlistentry> |
| 2952 | <term>DEC-XTRAP</term> |
| 2953 | <listitem> |
| 2954 | <para>Dick Annicchiarico, Robert Chesler, Alan Jamison. XTrap |
| 2955 | Architecture. Digital Equipment Corporation, July 1991. |
| 2956 | </para></listitem></varlistentry> |
| 2957 | <varlistentry> |
| 2958 | <term>XTestExtension1</term> |
| 2959 | <listitem> |
| 2960 | <para>Larry Woestman. X11 Input Synthesis Extension |
| 2961 | Proposal. Hewlett Packard, November 1991. |
| 2962 | </para></listitem></varlistentry> |
| 2963 | </variablelist> |
| 2964 | </para> |
| 2965 | </sect4> |
| 2966 | |
| 2967 | <sect4> |
| 2968 | <title>MIT-MISC (not supported)</title> |
| 2969 | |
| 2970 | <para>The MIT-MISC extension is used to control a bug-compatibility flag |
| 2971 | that provides compatibility with xterm programs from X11R1 and X11R2. |
| 2972 | There does not appear to be a single client available that makes use of |
| 2973 | this extension and there is not way to verify that it works correctly. |
| 2974 | The Xdmx server does <emphasis>not</emphasis> support MIT-MISC. |
| 2975 | </para> |
| 2976 | </sect4> |
| 2977 | |
| 2978 | <sect4> |
| 2979 | <title>SCREENSAVER (not supported)</title> |
| 2980 | |
| 2981 | <para>This extension provides special support for the X screen saver. It |
| 2982 | was tested with beforelight, which appears to be the only client that |
| 2983 | works with it. When Xinerama was not active, <command>beforelight</command> behaved |
| 2984 | as expected. However, when Xinerama was active, <command>beforelight</command> did |
| 2985 | not behave as expected. Further, when this extension is not active, |
| 2986 | <command>xscreensaver</command> (a widely-used X screen saver program) did not behave |
| 2987 | as expected. Since this extension is not Xinerama-aware and is not |
| 2988 | commonly used with expected results by clients, we have left this |
| 2989 | extension disabled at this time. |
| 2990 | </para> |
| 2991 | </sect4> |
| 2992 | |
| 2993 | <sect4> |
| 2994 | <title>GLX (supported)</title> |
| 2995 | |
| 2996 | <para>The GLX extension provides OpenGL and GLX windowing support. In |
| 2997 | Xdmx, the extension is called glxProxy, and it is Xinerama aware. It |
| 2998 | works by either feeding requests forward through Xdmx to each of the |
| 2999 | back-end servers or handling them locally. All rendering requests are |
| 3000 | handled on the back-end X servers. This code was donated to the DMX |
| 3001 | project by SGI. For the X Test Suite results comparison, see below. |
| 3002 | </para> |
| 3003 | </sect4> |
| 3004 | |
| 3005 | <sect4> |
| 3006 | <title>RENDER (supported)</title> |
| 3007 | |
| 3008 | <para>The X Rendering Extension (RENDER) provides support for digital image |
| 3009 | composition. Geometric and text rendering are supported. RENDER is |
| 3010 | partially Xinerama-aware, with text and the most basic compositing |
| 3011 | operator; however, its higher level primitives (triangles, triangle |
| 3012 | strips, and triangle fans) are not yet Xinerama-aware. The RENDER |
| 3013 | extension is still under development, and is currently at version 0.8. |
| 3014 | Additional support will be required in DMX as more primitives and/or |
| 3015 | requests are added to the extension. |
| 3016 | </para> |
| 3017 | |
| 3018 | <para>There is currently no test suite for the X Rendering Extension; |
| 3019 | however, there has been discussion of developing a test suite as the |
| 3020 | extension matures. When that test suite becomes available, additional |
| 3021 | testing can be performed with Xdmx. The X Test Suite passed and failed |
| 3022 | the exact same tests before and after this extension was enabled. |
| 3023 | </para> |
| 3024 | </sect4> |
| 3025 | |
| 3026 | <sect4> |
| 3027 | <title>Summary</title> |
| 3028 | |
| 3029 | <!-- WARNING: this list is duplicated in the "Common X extension |
| 3030 | support" section --> |
| 3031 | <para>To summarize, the following extensions are currently supported: |
| 3032 | BIG-REQUESTS, |
| 3033 | DEC-XTRAP, |
| 3034 | DMX, |
| 3035 | DPMS, |
| 3036 | Extended-Visual-Information, |
| 3037 | GLX, |
| 3038 | LBX, |
| 3039 | RECORD, |
| 3040 | RENDER, |
| 3041 | SECURITY, |
| 3042 | SHAPE, |
| 3043 | SYNC, |
| 3044 | X-Resource, |
| 3045 | XC-APPGROUP, |
| 3046 | XC-MISC, |
| 3047 | XFree86-Bigfont, |
| 3048 | XINERAMA, |
| 3049 | XInputExtension, |
| 3050 | XKEYBOARD, and |
| 3051 | XTEST. |
| 3052 | </para> |
| 3053 | |
| 3054 | <para>The following extensions are <emphasis>not</emphasis> supported at this time: |
| 3055 | DOUBLE-BUFFER, |
| 3056 | FontCache, |
| 3057 | MIT-SCREEN-SAVER, |
| 3058 | MIT-SHM, |
| 3059 | MIT-SUNDRY-NONSTANDARD, |
| 3060 | TOG-CUP, |
| 3061 | XFree86-DGA, |
| 3062 | XFree86-Misc, |
| 3063 | XFree86-VidModeExtension, |
| 3064 | XTestExtensionExt1, and |
| 3065 | XVideo. |
| 3066 | </para> |
| 3067 | </sect4> |
| 3068 | </sect3> |
| 3069 | |
| 3070 | <sect3> |
| 3071 | <title>Additional Testing with the X Test Suite</title> |
| 3072 | |
| 3073 | <sect4> |
| 3074 | <title>XFree86 without XTEST</title> |
| 3075 | |
| 3076 | <para>After the release of XFree86 4.3.0, we retested the XFree86 X server |
| 3077 | with and without using the XTEST extension. When the XTEST extension |
| 3078 | was <emphasis>not</emphasis> used for testing, the XFree86 4.3.0 server running on our |
| 3079 | usual test system with a Radeon VE card reported unexpected failures in |
| 3080 | the following tests: |
| 3081 | <literallayout> |
| 3082 | XListPixmapFormats: Test 1 |
| 3083 | XChangeKeyboardControl: Tests 9, 10 |
| 3084 | XGetDefault: Test 5 |
| 3085 | XRebindKeysym: Test 1 |
| 3086 | </literallayout> |
| 3087 | </para> |
| 3088 | </sect4> |
| 3089 | |
| 3090 | <sect4> |
| 3091 | <title>XFree86 with XTEST</title> |
| 3092 | |
| 3093 | <para>When using the XTEST extension, the XFree86 4.3.0 server reported the |
| 3094 | following errors: |
| 3095 | <literallayout> |
| 3096 | XListPixmapFormats: Test 1 |
| 3097 | XChangeKeyboardControl: Tests 9, 10 |
| 3098 | XGetDefault: Test 5 |
| 3099 | XRebindKeysym: Test 1 |
| 3100 | |
| 3101 | XAllowEvents: Tests 20, 21, 24 |
| 3102 | XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25 |
| 3103 | XGrabKey: Test 8 |
| 3104 | XSetPointerMapping: Test 3 |
| 3105 | XUngrabButton: Test 4 |
| 3106 | </literallayout> |
| 3107 | </para> |
| 3108 | |
| 3109 | <para>While these errors may be important, they will probably be fixed |
| 3110 | eventually in the XFree86 source tree. We are particularly interested |
| 3111 | in demonstrating that the Xdmx server does not introduce additional |
| 3112 | failures that are not known Xinerama failures. |
| 3113 | </para> |
| 3114 | </sect4> |
| 3115 | |
| 3116 | <sect4> |
| 3117 | <title>Xdmx with XTEST, without Xinerama, without GLX</title> |
| 3118 | |
| 3119 | <para>Without Xinerama, but using the XTEST extension, the following errors |
| 3120 | were reported from Xdmx (note that these are the same as for the XFree86 |
| 3121 | 4.3.0, except that XGetDefault no longer fails): |
| 3122 | <literallayout> |
| 3123 | XListPixmapFormats: Test 1 |
| 3124 | XChangeKeyboardControl: Tests 9, 10 |
| 3125 | XRebindKeysym: Test 1 |
| 3126 | |
| 3127 | XAllowEvents: Tests 20, 21, 24 |
| 3128 | XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25 |
| 3129 | XGrabKey: Test 8 |
| 3130 | XSetPointerMapping: Test 3 |
| 3131 | XUngrabButton: Test 4 |
| 3132 | </literallayout> |
| 3133 | </para> |
| 3134 | </sect4> |
| 3135 | |
| 3136 | <sect4> |
| 3137 | <title>Xdmx with XTEST, with Xinerama, without GLX</title> |
| 3138 | |
| 3139 | <para>With Xinerama, using the XTEST extension, the following errors |
| 3140 | were reported from Xdmx: |
| 3141 | <literallayout> |
| 3142 | XListPixmapFormats: Test 1 |
| 3143 | XChangeKeyboardControl: Tests 9, 10 |
| 3144 | XRebindKeysym: Test 1 |
| 3145 | |
| 3146 | XAllowEvents: Tests 20, 21, 24 |
| 3147 | XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25 |
| 3148 | XGrabKey: Test 8 |
| 3149 | XSetPointerMapping: Test 3 |
| 3150 | XUngrabButton: Test 4 |
| 3151 | |
| 3152 | XCopyPlane: Tests 13, 22, 31 (well-known XTEST/Xinerama interaction issue) |
| 3153 | XDrawLine: Test 67 |
| 3154 | XDrawLines: Test 91 |
| 3155 | XDrawSegments: Test 68 |
| 3156 | </literallayout> |
| 3157 | Note that the first two sets of errors are the same as for the XFree86 |
| 3158 | 4.3.0 server, and that the XCopyPlane error is a well-known error |
| 3159 | resulting from an XTEST/Xinerama interaction when the request crosses a |
| 3160 | screen boundary. The XDraw* errors are resolved when the tests are run |
| 3161 | individually and they do not cross a screen boundary. We will |
| 3162 | investigate these errors further to determine their cause. |
| 3163 | </para> |
| 3164 | </sect4> |
| 3165 | |
| 3166 | <sect4> |
| 3167 | <title>Xdmx with XTEST, with Xinerama, with GLX</title> |
| 3168 | |
| 3169 | <para>With GLX enabled, using the XTEST extension, the following errors |
| 3170 | were reported from Xdmx (these results are from early during the Phase |
| 3171 | IV development, but were confirmed with a late Phase IV snapshot): |
| 3172 | <literallayout> |
| 3173 | XListPixmapFormats: Test 1 |
| 3174 | XChangeKeyboardControl: Tests 9, 10 |
| 3175 | XRebindKeysym: Test 1 |
| 3176 | |
| 3177 | XAllowEvents: Tests 20, 21, 24 |
| 3178 | XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25 |
| 3179 | XGrabKey: Test 8 |
| 3180 | XSetPointerMapping: Test 3 |
| 3181 | XUngrabButton: Test 4 |
| 3182 | |
| 3183 | XClearArea: Test 8 |
| 3184 | XCopyArea: Tests 4, 5, 11, 14, 17, 23, 25, 27, 30 |
| 3185 | XCopyPlane: Tests 6, 7, 10, 19, 22, 31 |
| 3186 | XDrawArcs: Tests 89, 100, 102 |
| 3187 | XDrawLine: Test 67 |
| 3188 | XDrawSegments: Test 68 |
| 3189 | </literallayout> |
| 3190 | Note that the first two sets of errors are the same as for the XFree86 |
| 3191 | 4.3.0 server, and that the third set has different failures than when |
| 3192 | Xdmx does not include GLX support. Since the GLX extension adds new |
| 3193 | visuals to support GLX's visual configs and the X Test Suite runs tests |
| 3194 | over the entire set of visuals, additional rendering tests were run and |
| 3195 | presumably more of them crossed a screen boundary. This conclusion is |
| 3196 | supported by the fact that nearly all of the rendering errors reported |
| 3197 | are resolved when the tests are run individually and they do no cross a |
| 3198 | screen boundary. |
| 3199 | </para> |
| 3200 | |
| 3201 | <para>Further, when hardware rendering is disabled on the back-end displays, |
| 3202 | many of the errors in the third set are eliminated, leaving only: |
| 3203 | <literallayout> |
| 3204 | XClearArea: Test 8 |
| 3205 | XCopyArea: Test 4, 5, 11, 14, 17, 23, 25, 27, 30 |
| 3206 | XCopyPlane: Test 6, 7, 10, 19, 22, 31 |
| 3207 | </literallayout> |
| 3208 | </para> |
| 3209 | </sect4> |
| 3210 | |
| 3211 | <sect4> |
| 3212 | <title>Conclusion</title> |
| 3213 | |
| 3214 | <para>We conclude that all of the X Test Suite errors reported for Xdmx are |
| 3215 | the result of errors in the back-end X server or the Xinerama |
| 3216 | implementation. Further, all of these errors that can be reasonably |
| 3217 | fixed at the Xdmx layer have been. (Where appropriate, we have |
| 3218 | submitted patches to the XFree86 and Xinerama upstream maintainers.) |
| 3219 | </para> |
| 3220 | </sect4> |
| 3221 | </sect3> |
| 3222 | |
| 3223 | <sect3> |
| 3224 | <title>Dynamic Reconfiguration</title> |
| 3225 | |
| 3226 | <para>During this development phase, dynamic reconfiguration support was |
| 3227 | added to DMX. This support allows an application to change the position |
| 3228 | and offset of a back-end server's screen. For example, if the |
| 3229 | application would like to shift a screen slightly to the left, it could |
| 3230 | query Xdmx for the screen's <x,y> position and then dynamically |
| 3231 | reconfigure that screen to be at position <x+10,y>. When a screen |
| 3232 | is dynamically reconfigured, input handling and a screen's root window |
| 3233 | dimensions are adjusted as needed. These adjustments are transparent to |
| 3234 | the user. |
| 3235 | </para> |
| 3236 | |
| 3237 | <sect4> |
| 3238 | <title>Dynamic reconfiguration extension</title> |
| 3239 | |
| 3240 | <para>The application interface to DMX's dynamic reconfiguration is through |
| 3241 | a function in the DMX extension library: |
| 3242 | <programlisting> |
| 3243 | Bool DMXReconfigureScreen(Display *dpy, int screen, int x, int y) |
| 3244 | </programlisting> |
| 3245 | where <parameter>dpy</parameter> is DMX server's display, <parameter>screen</parameter> is the number of the |
| 3246 | screen to be reconfigured, and <parameter>x</parameter> and <parameter>y</parameter> are the new upper, |
| 3247 | left-hand coordinates of the screen to be reconfigured. |
| 3248 | </para> |
| 3249 | |
| 3250 | <para>The coordinates are not limited other than as required by the X |
| 3251 | protocol, which limits all coordinates to a signed 16 bit number. In |
| 3252 | addition, all coordinates within a screen must also be legal values. |
| 3253 | Therefore, setting a screen's upper, left-hand coordinates such that the |
| 3254 | right or bottom edges of the screen is greater than 32,767 is illegal. |
| 3255 | </para> |
| 3256 | </sect4> |
| 3257 | |
| 3258 | <sect4> |
| 3259 | <title>Bounding box</title> |
| 3260 | |
| 3261 | <para>When the Xdmx server is started, a bounding box is calculated from |
| 3262 | the screens' layout given either on the command line or in the |
| 3263 | configuration file. This bounding box is currently fixed for the |
| 3264 | lifetime of the Xdmx server. |
| 3265 | </para> |
| 3266 | |
| 3267 | <para>While it is possible to move a screen outside of the bounding box, it |
| 3268 | is currently not possible to change the dimensions of the bounding box. |
| 3269 | For example, it is possible to specify coordinates of <-100,-100> |
| 3270 | for the upper, left-hand corner of the bounding box, which was |
| 3271 | previously at coordinates <0,0>. As expected, the screen is moved |
| 3272 | down and to the right; however, since the bounding box is fixed, the |
| 3273 | left side and upper portions of the screen exposed by the |
| 3274 | reconfiguration are no longer accessible on that screen. Those |
| 3275 | inaccessible regions are filled with black. |
| 3276 | </para> |
| 3277 | |
| 3278 | <para>This fixed bounding box limitation will be addressed in a future |
| 3279 | development phase. |
| 3280 | </para> |
| 3281 | </sect4> |
| 3282 | |
| 3283 | <sect4> |
| 3284 | <title>Sample applications</title> |
| 3285 | |
| 3286 | <para>An example of where this extension is useful is in setting up a video |
| 3287 | wall. It is not always possible to get everything perfectly aligned, |
| 3288 | and sometimes the positions are changed (e.g., someone might bump into a |
| 3289 | projector). Instead of physically moving projectors or monitors, it is |
| 3290 | now possible to adjust the positions of the back-end server's screens |
| 3291 | using the dynamic reconfiguration support in DMX. |
| 3292 | </para> |
| 3293 | |
| 3294 | <para>Other applications, such as automatic setup and calibration tools, |
| 3295 | can make use of dynamic reconfiguration to correct for projector |
| 3296 | alignment problems, as long as the projectors are still arranged |
| 3297 | rectilinearly. Horizontal and vertical keystone correction could be |
| 3298 | applied to projectors to correct for non-rectilinear alignment problems; |
| 3299 | however, this must be done external to Xdmx. |
| 3300 | </para> |
| 3301 | |
| 3302 | <para>A sample test program is included in the DMX server's examples |
| 3303 | directory to demonstrate the interface and how an application might use |
| 3304 | dynamic reconfiguration. See <filename>dmxreconfig.c</filename> for details. |
| 3305 | </para> |
| 3306 | </sect4> |
| 3307 | |
| 3308 | <sect4> |
| 3309 | <title>Additional notes</title> |
| 3310 | |
| 3311 | <para>In the original development plan, Phase IV was primarily devoted to |
| 3312 | adding OpenGL support to DMX; however, SGI became interested in the DMX |
| 3313 | project and developed code to support OpenGL/GLX. This code was later |
| 3314 | donated to the DMX project and integrated into the DMX code base, which |
| 3315 | freed the DMX developers to concentrate on dynamic reconfiguration (as |
| 3316 | described above). |
| 3317 | </para> |
| 3318 | </sect4> |
| 3319 | </sect3> |
| 3320 | |
| 3321 | <sect3> |
| 3322 | <title>Doxygen documentation</title> |
| 3323 | |
| 3324 | <para>Doxygen is an open-source (GPL) documentation system for generating |
| 3325 | browseable documentation from stylized comments in the source code. We |
| 3326 | have placed all of the Xdmx server and DMX protocol source code files |
| 3327 | under Doxygen so that comprehensive documentation for the Xdmx source |
| 3328 | code is available in an easily browseable format. |
| 3329 | </para> |
| 3330 | </sect3> |
| 3331 | |
| 3332 | <sect3> |
| 3333 | <title>Valgrind</title> |
| 3334 | |
| 3335 | <para>Valgrind, an open-source (GPL) memory debugger for Linux, was used to |
| 3336 | search for memory management errors. Several memory leaks were detected |
| 3337 | and repaired. The following errors were not addressed: |
| 3338 | <orderedlist> |
| 3339 | <listitem><para> |
| 3340 | When the X11 transport layer sends a reply to the client, only |
| 3341 | those fields that are required by the protocol are filled in -- |
| 3342 | unused fields are left as uninitialized memory and are therefore |
| 3343 | noted by valgrind. These instances are not errors and were not |
| 3344 | repaired. |
| 3345 | </para></listitem> |
| 3346 | <listitem><para> |
| 3347 | At each server generation, glxInitVisuals allocates memory that |
| 3348 | is never freed. The amount of memory lost each generation |
| 3349 | approximately equal to 128 bytes for each back-end visual. |
| 3350 | Because the code involved is automatically generated, this bug |
| 3351 | has not been fixed and will be referred to SGI. |
| 3352 | </para></listitem> |
| 3353 | <listitem><para> |
| 3354 | At each server generation, dmxRealizeFont calls XLoadQueryFont, |
| 3355 | which allocates a font structure that is not freed. |
| 3356 | dmxUnrealizeFont can free the font structure for the first |
| 3357 | screen, but cannot free it for the other screens since they are |
| 3358 | already closed by the time dmxUnrealizeFont could free them. |
| 3359 | The amount of memory lost each generation is approximately equal |
| 3360 | to 80 bytes per font per back-end. When this bug is fixed in |
| 3361 | the the X server's device-independent (dix) code, DMX will be |
| 3362 | able to properly free the memory allocated by XLoadQueryFont. |
| 3363 | </para></listitem> |
| 3364 | </orderedlist> |
| 3365 | </para> |
| 3366 | </sect3> |
| 3367 | |
| 3368 | <sect3> |
| 3369 | <title>RATS</title> |
| 3370 | |
| 3371 | <para>RATS (Rough Auditing Tool for Security) is an open-source (GPL) |
| 3372 | security analysis tool that scans source code for common |
| 3373 | security-related programming errors (e.g., buffer overflows and TOCTOU |
| 3374 | races). RATS was used to audit all of the code in the hw/dmx directory |
| 3375 | and all "High" notations were checked manually. The code was either |
| 3376 | re-written to eliminate the warning, or a comment containing "RATS" was |
| 3377 | inserted on the line to indicate that a human had checked the code. |
| 3378 | Unrepaired warnings are as follows: |
| 3379 | <orderedlist> |
| 3380 | <listitem><para> |
| 3381 | Fixed-size buffers are used in many areas, but code has been |
| 3382 | added to protect against buffer overflows (e.g., snprintf). |
| 3383 | The only instances that have not yet been fixed are in |
| 3384 | config/xdmxconfig.c (which is not part of the Xdmx server) and |
| 3385 | input/usb-common.c. |
| 3386 | </para></listitem> |
| 3387 | <listitem><para> |
| 3388 | vprintf and vfprintf are used in the logging routines. In |
| 3389 | general, all uses of these functions (e.g., dmxLog) provide a |
| 3390 | constant format string from a trusted source, so the use is |
| 3391 | relatively benign. |
| 3392 | </para></listitem> |
| 3393 | <listitem><para> |
| 3394 | glxProxy/glxscreens.c uses getenv and strcat. The use of these |
| 3395 | functions is safe and will remain safe as long as |
| 3396 | ExtensionsString is longer then GLXServerExtensions (ensuring |
| 3397 | this may not be ovious to the casual programmer, but this is in |
| 3398 | automatically generated code, so we hope that the generator |
| 3399 | enforces this constraint). |
| 3400 | </para></listitem> |
| 3401 | </orderedlist> |
| 3402 | |
| 3403 | </para> |
| 3404 | |
| 3405 | </sect3> |
| 3406 | |
| 3407 | </sect2> |
| 3408 | |
| 3409 | </sect1> |
| 3410 | |
| 3411 | </appendix> |
| 3412 | |
| 3413 | </article> |
| 3414 | |
| 3415 | <!-- Local Variables: --> |
| 3416 | <!-- fill-column: 72 --> |
| 3417 | <!-- End: --> |