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