diff options
Diffstat (limited to 'xorg-server/hw/dmx/doc/dmx.txt')
-rw-r--r-- | xorg-server/hw/dmx/doc/dmx.txt | 2989 |
1 files changed, 2989 insertions, 0 deletions
diff --git a/xorg-server/hw/dmx/doc/dmx.txt b/xorg-server/hw/dmx/doc/dmx.txt new file mode 100644 index 000000000..568c75178 --- /dev/null +++ b/xorg-server/hw/dmx/doc/dmx.txt @@ -0,0 +1,2989 @@ + Distributed Multihead X design + Kevin E. Martin, David H. Dawes, and Rickard E. Faith + + 29 June 2004 (created 25 July 2001) + + This document covers the motivation, background, design, and implemen- + tation of the distributed multihead X (DMX) system. It is a living + document and describes the current design and implementation details + of the DMX system. As the project progresses, this document will be + continually updated to reflect the changes in the code and/or design. + _C_o_p_y_r_i_g_h_t _2_0_0_1 _b_y _V_A _L_i_n_u_x _S_y_s_t_e_m_s_, _I_n_c_._, _F_r_e_m_o_n_t_, _C_a_l_i_f_o_r_n_i_a_. _C_o_p_y_- + _r_i_g_h_t _2_0_0_1_-_2_0_0_4 _b_y _R_e_d _H_a_t_, _I_n_c_._, _R_a_l_e_i_g_h_, _N_o_r_t_h _C_a_r_o_l_i_n_a + + ______________________________________________________________________ + + Table of Contents + + + + 1. Introduction + 1.1 The Distributed Multihead X Server + 1.2 Layout of Paper + + 2. Development plan + 2.1 Bootstrap code + 2.2 Input device handling + 2.3 Output device handling + 2.3.1 Initialization + 2.3.2 Handling rendering requests + 2.4 Optimizing DMX + 2.5 DMX X extension support + 2.6 Common X extension support + 2.7 OpenGL support + + 3. Current issues + 3.1 Fonts + 3.2 Zero width rendering primitives + 3.3 Output scaling + 3.4 Per-screen colormaps + + A. Background + A.1 Core input device handling + A.1.1 InitInput() + A.1.2 InitAndStartDevices() + A.1.3 devReadInput() + A.1.4 ProcessInputEvents() + A.1.5 DisableDevice() + A.1.6 CloseDevice() + A.1.7 LegalModifier() + A.2 Output handling + A.2.1 InitOutput() + A.2.2 AddScreen() + A.2.3 ScreenInit() + A.2.4 CloseScreen() + A.2.5 GC operations + A.2.6 Xnest + A.2.7 Shadow framebuffer + A.3 Xinerama + A.3.1 Xinerama-specific changes to the DIX code + A.3.2 Xinerama-specific changes to the MI code + A.3.3 Intercepted DIX core requests + + B. Development Results + B.1 Phase I + B.1.1 Scope + B.1.2 Results + B.1.3 X Test Suite + B.1.3.1 Introduction + B.1.3.2 Expected Failures for a Single Head + B.1.3.3 Expected Failures for Xinerama + B.1.3.4 Additional Failures from Xdmx + B.1.3.5 Summary and Future Work + B.1.4 Fonts + B.1.5 Performance + B.1.6 Pixmaps + B.2 Phase II + B.2.1 Moving from XFree86 4.1.99.1 to 4.2.0.0 + B.2.2 Global changes + B.2.3 XSync() Batching + B.2.4 Offscreen Optimization + B.2.5 Lazy Window Creation Optimization + B.2.6 Subdividing Rendering Primitives + B.2.7 Summary of x11perf Data + B.2.8 Profiling with OProfile + B.2.9 X Test Suite + B.3 Phase III + B.3.1 SHAPE + B.3.2 RENDER + B.3.3 XKEYBOARD + B.3.4 XInput + B.3.5 DPMS + B.3.6 Other Extensions + B.4 Phase IV + B.4.1 Moving to XFree86 4.3.0 + B.4.2 Extensions + B.4.2.1 XC-MISC (supported) + B.4.2.2 Extended-Visual-Information (supported) + B.4.2.3 RES (supported) + B.4.2.4 BIG-REQUESTS (supported) + B.4.2.5 XSYNC (supported) + B.4.2.6 XTEST, RECORD, DEC-XTRAP (supported) and XTestExtension1 (not supported) + B.4.2.7 MIT-MISC (not supported) + B.4.2.8 SCREENSAVER (not supported) + B.4.2.9 GLX (supported) + B.4.2.10 RENDER (supported) + B.4.2.11 Summary + B.4.3 Additional Testing with the X Test Suite + B.4.3.1 XFree86 without XTEST + B.4.3.2 XFree86 with XTEST + B.4.3.3 Xdmx with XTEST, without Xinerama, without GLX + B.4.3.4 Xdmx with XTEST, with Xinerama, without GLX + B.4.3.5 Xdmx with XTEST, with Xinerama, with GLX + B.4.3.6 Conclusion + B.4.4 Dynamic Reconfiguration + B.4.4.1 Dynamic reconfiguration extension + B.4.4.2 Bounding box + B.4.4.3 Sample applications + B.4.4.4 Additional notes + B.4.5 Doxygen documentation + B.4.6 Valgrind + B.4.7 RATS + + + ______________________________________________________________________ + + 11.. IInnttrroodduuccttiioonn + + 11..11.. TThhee DDiissttrriibbuutteedd MMuullttiihheeaadd XX SSeerrvveerr + + Current Open Source multihead solutions are limited to a single + physical machine. A single X server controls multiple display + devices, which can be arranged as independent heads or unified into a + single desktop (with Xinerama). These solutions are limited to the + number of physical devices that can co-exist in a single machine + (e.g., due to the number of AGP/PCI slots available for graphics + cards). Thus, large tiled displays are not currently possible. The + work described in this paper will eliminate the requirement that the + display devices reside in the same physical machine. This will be + accomplished by developing a front-end proxy X server that will + control multiple back-end X servers that make up the large display. + + + The overall structure of the distributed multihead X (DMX) project is + as follows: A single front-end X server will act as a proxy to a set + of back-end X servers, which handle all of the visible rendering. X + clients will connect to the front-end server just as they normally + would to a regular X server. The front-end server will present an + abstracted view to the client of a single large display. This will + ensure that all standard X clients will continue to operate without + modification (limited, as always, by the visuals and extensions + provided by the X server). Clients that are DMX-aware will be able to + use an extension to obtain information about the back-end servers + (e.g., for placement of pop-up windows, window alignments by the + window manager, etc.). + + + The architecture of the DMX server is divided into two main sections: + input (e.g., mouse and keyboard events) and output (e.g., rendering + and windowing requests). Each of these are describe briefly below, + and the rest of this design document will describe them in greater + detail. + + + The DMX server can receive input from three general types of input + devices: "local" devices that are physically attached to the machine + on which DMX is running, "backend" devices that are physically + attached to one or more of the back-end X servers (and that generate + events via the X protocol stream from the backend), and "console" + devices that can be abstracted from any non-back-end X server. + Backend and console devices are treated differently because the + pointer device on the back-end X server also controls the location of + the hardware X cursor. Full support for XInput extension devices is + provided. + + + Rendering requests will be accepted by the front-end server; however, + rendering to visible windows will be broken down as needed and sent to + the appropriate back-end server(s) via X11 library calls for actual + rendering. The basic framework will follow a Xnest-style approach. + GC state will be managed in the front-end server and sent to the + appropriate back-end server(s) as required. Pixmap rendering will (at + least initially) be handled by the front-end X server. Windowing + requests (e.g., ordering, mapping, moving, etc.) will handled in the + front-end server. If the request requires a visible change, the + windowing operation will be translated into requests for the + appropriate back-end server(s). Window state will be mirrored in the + back-end server(s) as needed. + + + 11..22.. LLaayyoouutt ooff PPaappeerr + + The next section describes the general development plan that was + actually used for implementation. The final section discusses + outstanding issues at the conclusion of development. The first + appendix provides low-level technical detail that may be of interest + to those intimately familiar with the X server architecture. The + final appendix describes the four phases of development that were + performed during the first two years of development. + + + The final year of work was divided into 9 tasks that are not described + in specific sections of this document. The major tasks during that + time were the enhancement of the reconfiguration ability added in + Phase IV, addition of support for a dynamic number of back-end + displays (instead of a hard-coded limit), and the support for back-end + display and input removal and addition. This work is mentioned in + this paper, but is not covered in detail. + + + 22.. DDeevveellooppmmeenntt ppllaann + + This section describes the development plan from approximately June + 2001 through July 2003. + + + + 22..11.. BBoooottssttrraapp ccooddee + + To allow for rapid development of the DMX server by multiple + developers during the first development stage, the problem will be + broken down into three tasks: the overall DMX framework, back-end + rendering services and input device handling services. However, + before the work begins on these tasks, a simple framework that each + developer could use was implemented to bootstrap the development + effort. This framework renders to a single back-end server and + provides dummy input devices (i.e., the keyboard and mouse). The + simple back-end rendering service was implemented using the shadow + framebuffer support currently available in the XFree86 environment. + + + Using this bootstrapping framework, each developer has been able to + work on each of the tasks listed above independently as follows: the + framework will be extended to handle arbitrary back-end server + configurations; the back-end rendering services will be transitioned + to the more efficient Xnest-style implementation; and, an input device + framework to handle various input devices via the input extension will + be developed. + + + Status: The boot strap code is complete. + + + + 22..22.. IInnppuutt ddeevviiccee hhaannddlliinngg + + An X server (including the front-end X server) requires two core input + devices -- a keyboard and a pointer (mouse). These core devices are + handled and required by the core X11 protocol. Additional types of + input devices may be attached and utilized via the XInput extension. + These are usually referred to as ``XInput extension devices'', + + + There are some options as to how the front-end X server gets its core + input devices: + + + 1. Local Input. The physical input devices (e.g., keyboard and mouse) + can be attached directly to the front-end X server. In this case, + the keyboard and mouse on the machine running the front-end X + server will be used. The front-end will have drivers to read the + raw input from those devices and convert it into the required X + input events (e.g., key press/release, pointer button + press/release, pointer motion). The front-end keyboard driver will + keep track of keyboard properties such as key and modifier + mappings, autorepeat state, keyboard sound and led state. + Similarly the front-end pointer driver will keep track if pointer + properties such as the button mapping and movement acceleration + parameters. With this option, input is handled fully in the front- + end X server, and the back-end X servers are used in a display-only + mode. This option was implemented and works for a limited number + of Linux-specific devices. Adding additional local input devices + for other architectures is expected to be relatively simple. + + + The following options are available for implementing local input + devices: + + + a. The XFree86 X server has modular input drivers that could be + adapted for this purpose. The mouse driver supports a wide + range of mouse types and interfaces, as well as a range of + Operating System platforms. The keyboard driver in XFree86 is + not currently as modular as the mouse driver, but could be made + so. The XFree86 X server also has a range of other input + drivers for extended input devices such as tablets and touch + screens. Unfortunately, the XFree86 drivers are generally + complex, often simultaneously providing support for multiple + devices across multiple architectures; and rely so heavily on + XFree86-specific helper-functions, that this option was not + pursued. + + + b. The kdrive X server in XFree86 has built-in drivers that support + PS/2 mice and keyboard under Linux. The mouse driver can + indirectly handle other mouse types if the Linux utility gpm is + used as to translate the native mouse protocol into PS/2 mouse + format. These drivers could be adapted and built in to the + front-end X server if this range of hardware and OS support is + sufficient. While much simpler than the XFree86 drivers, the + kdrive drivers were not used for the DMX implementation. + + c. Reimplementation of keyboard and mouse drivers from scratch for + the DMX framework. Because keyboard and mouse drivers are + relatively trivial to implement, this pathway was selected. + Other drivers in the X source tree were referenced, and + significant contributions from other drivers are noted in the + DMX source code. + + + 2. Backend Input. The front-end can make use of the core input + devices attached to one or more of the back-end X servers. Core + input events from multiple back-ends are merged into a single input + event stream. This can work sanely when only a single set of input + devices is used at any given time. The keyboard and pointer state + will be handled in the front-end, with changes propagated to the + back-end servers as needed. This option was implemented and works + well. Because the core pointer on a back-end controls the hardware + mouse on that back-end, core pointers cannot be treated as XInput + extension devices. However, all back-end XInput extensions devices + can be mapped to either DMX core or DMX XInput extension devices. + + 3. Console Input. The front-end server could create a console window + that is displayed on an X server independent of the back-end X + servers. This console window could display things like the + physical screen layout, and the front-end could get its core input + events from events delivered to the console window. This option + was implemented and works well. To help the human navigate, window + outlines are also displayed in the console window. Further, + console windows can be used as either core or XInput extension + devices. + + 4. Other options were initially explored, but they were all partial + subsets of the options listed above and, hence, are irrelevant. + + + Although extended input devices are not specifically mentioned in the + Distributed X requirements, the options above were all implemented so + that XInput extension devices were supported. + + + The bootstrap code (Xdmx) had dummy input devices, and these are still + supported in the final version. These do the necessary initialization + to satisfy the X server's requirements for core pointer and keyboard + devices, but no input events are ever generated. + + + Status: The input code is complete. Because of the complexity of the + XFree86 input device drivers (and their heavy reliance on XFree86 + infrastructure), separate low-level device drivers were implemented + for Xdmx. The following kinds of drivers are supported (in general, + the devices can be treated arbitrarily as "core" input devices or as + XInput "extension" devices; and multiple instances of different kinds + of devices can be simultaneously available): + + 1. A "dummy" device drive that never generates events. + + 2. "Local" input is from the low-level hardware on which the Xdmx + binary is running. This is the only area where using the XFree86 + driver infrastructure would have been helpful, and then only + partially, since good support for generic USB devices does not yet + exist in XFree86 (in any case, XFree86 and kdrive driver code was + used where possible). Currently, the following local devices are + supported under Linux (porting to other operating systems should be + fairly straightforward): + + +o Linux keyboard + + +o Linux serial mouse (MS) + + +o Linux PS/2 mouse + + +o USB keyboard + + +o USB mouse + + +o USB generic device (e.g., joystick, gamepad, etc.) + + + 3. "Backend" input is taken from one or more of the back-end displays. + In this case, events are taken from the back-end X server and are + converted to Xdmx events. Care must be taken so that the sprite + moves properly on the display from which input is being taken. + + 4. "Console" input is taken from an X window that Xdmx creates on the + operator's display (i.e., on the machine running the Xdmx binary). + When the operator's mouse is inside the console window, then those + events are converted to Xdmx events. Several special features are + available: the console can display outlines of windows that are on + the Xdmx display (to facilitate navigation), the cursor can be + confined to the console, and a "fine" mode can be activated to + allow very precise cursor positioning. + + + + 22..33.. OOuuttppuutt ddeevviiccee hhaannddlliinngg + + The output of the DMX system displays rendering and windowing requests + across multiple screens. The screens are typically arranged in a grid + such that together they represent a single large display. + + + The output section of the DMX code consists of two parts. The first + is in the front-end proxy X server (Xdmx), which accepts client + connections, manages the windows, and potentially renders primitives + but does not actually display any of the drawing primitives. The + second part is the back-end X server(s), which accept commands from + the front-end server and display the results on their screens. + + + 22..33..11.. IInniittiiaalliizzaattiioonn + + The DMX front-end must first initialize its screens by connecting to + each of the back-end X servers and collecting information about each + of these screens. However, the information collected from the back- + end X servers might be inconsistent. Handling these cases can be + difficult and/or inefficient. For example, a two screen system has + one back-end X server running at 16bpp while the second is running at + 32bpp. Converting rendering requests (e.g., XPutImage() or + XGetImage() requests) to the appropriate bit depth can be very time + consuming. Analyzing these cases to determine how or even if it is + possible to handle them is required. The current Xinerama code + handles many of these cases (e.g., in PanoramiXConsolidate()) and will + be used as a starting point. In general, the best solution is to use + homogeneous X servers and display devices. Using back-end servers + with the same depth is a requirement of the final DMX implementation. + + + Once this screen consolidation is finished, the relative position of + each back-end X server's screen in the unified screen is initialized. + A full-screen window is opened on each of the back-end X servers, and + the cursor on each screen is turned off. The final DMX implementation + can also make use of a partial-screen window, or multiple windows per + back-end screen. + + + 22..33..22.. HHaannddlliinngg rreennddeerriinngg rreeqquueessttss + + After initialization, X applications connect to the front-end server. + There are two possible implementations of how rendering and windowing + requests are handled in the DMX system: + + + 1. A shadow framebuffer is used in the front-end server as the render + target. In this option, all protocol requests are completely + handled in the front-end server. All state and resources are + maintained in the front-end including a shadow copy of the entire + framebuffer. The framebuffers attached to the back-end servers are + updated by XPutImage() calls with data taken directly from the + shadow framebuffer. + + + This solution suffers from two main problems. First, it does not + take advantage of any accelerated hardware available in the system. + Second, the size of the XPutImage() calls can be quite large and + thus will be limited by the bandwidth available. + + + The initial DMX implementation used a shadow framebuffer by + default. + + + 2. Rendering requests are sent to each back-end server for handling + (as is done in the Xnest server described above). In this option, + certain protocol requests are handled in the front-end server and + certain requests are repackaged and then sent to the back-end + servers. The framebuffer is distributed across the multiple back- + end servers. Rendering to the framebuffer is handled on each back- + end and can take advantage of any acceleration available on the + back-end servers' graphics display device. State is maintained + both in the front and back-end servers. + + + This solution suffers from two main drawbacks. First, protocol + requests are sent to all back-end servers -- even those that will + completely clip the rendering primitive -- which wastes bandwidth + and processing time. Second, state is maintained both in the + front- and back-end servers. These drawbacks are not as severe as + in option 1 (above) and can either be overcome through + optimizations or are acceptable. Therefore, this option will be + used in the final implementation. + + + The final DMX implementation defaults to this mechanism, but also + supports the shadow framebuffer mechanism. Several optimizations + were implemented to eliminate the drawbacks of the default + mechanism. These optimizations are described the section below and + in Phase II of the Development Results (see appendix). + + + + Status: Both the shadow framebuffer and Xnest-style code is complete. + + + + 22..44.. OOppttiimmiizziinngg DDMMXX + + Initially, the Xnest-style solution's performance will be measured and + analyzed to determine where the performance bottlenecks exist. There + are four main areas that will be addressed. + + + First, to obtain reasonable interactivity with the first development + phase, XSync() was called after each protocol request. The XSync() + function flushes any pending protocol requests. It then waits for the + back-end to process the request and send a reply that the request has + completed. This happens with each back-end server and performance + greatly suffers. As a result of the way XSync() is called in the + first development phase, the batching that the X11 library performs is + effectively defeated. The XSync() call usage will be analyzed and + optimized by batching calls and performing them at regular intervals, + except where interactivity will suffer (e.g., on cursor movements). + + + Second, the initial Xnest-style solution described above sends the + repackaged protocol requests to all back-end servers regardless of + whether or not they would be completely clipped out. The requests + that are trivially rejected on the back-end server wastes the limited + bandwidth available. By tracking clipping changes in the DMX X + server's windowing code (e.g., by opening, closing, moving or resizing + windows), we can determine whether or not back-end windows are visible + so that trivial tests in the front-end server's GC ops drawing + functions can eliminate these unnecessary protocol requests. + + + Third, each protocol request will be analyzed to determine if it is + possible to break the request into smaller pieces at display + boundaries. The initial ones to be analyzed are put and get image + requests since they will require the greatest bandwidth to transmit + data between the front and back-end servers. Other protocol requests + will be analyzed and those that will benefit from breaking them into + smaller requests will be implemented. + + + Fourth, an extension is being considered that will allow font glyphs + to be transferred from the front-end DMX X server to each back-end + server. This extension will permit the front-end to handle all font + requests and eliminate the requirement that all back-end X servers + share the exact same fonts as the front-end server. We are + investigating the feasibility of this extension during this + development phase. + + + Other potential optimizations will be determined from the performance + analysis. + + Please note that in our initial design, we proposed optimizing BLT + operations (e.g., XCopyArea() and window moves) by developing an + extension that would allow individual back-end servers to directly + copy pixel data to other back-end servers. This potential + optimization was in response to the simple image movement + implementation that required potentially many calls to GetImage() and + PutImage(). However, the current Xinerama implementation handles + these BLT operations differently. Instead of copying data to and from + screens, they generate expose events -- just as happens in the case + when a window is moved from off a screen to on screen. This approach + saves the limited bandwidth available between front and back-end + servers and is being standardized with Xinerama. It also eliminates + the potential setup problems and security issues resulting from having + each back-end server open connections to all other back-end servers. + Therefore, we suggest accepting Xinerama's expose event solution. + + + Also note that the approach proposed in the second and third + optimizations might cause backing store algorithms in the back-end to + be defeated, so a DMX X server configuration flag will be added to + disable these optimizations. + + + Status: The optimizations proposed above are complete. It was + determined that the using the xfs font server was sufficient and + creating a new mechanism to pass glyphs was redundant; therefore, the + fourth optimization proposed above was not included in DMX. + + + + 22..55.. DDMMXX XX eexxtteennssiioonn ssuuppppoorrtt + + The DMX X server keeps track of all the windowing information on the + back-end X servers, but does not currently export this information to + any client applications. An extension will be developed to pass the + screen information and back-end window IDs to DMX-aware clients. + These clients can then use this information to directly connect to and + render to the back-end windows. Bypassing the DMX X server allows + DMX-aware clients to break up complex rendering requests on their own + and send them directly to the windows on the back-end server's + screens. An example of a client that can make effective use of this + extension is Chromium. + + + Status: The extension, as implemented, is fully documented in "Client- + to-Server DMX Extension to the X Protocol". Future changes might be + required based on feedback and other proposed enhancements to DMX. + Currently, the following facilities are supported: + + 1. Screen information (clipping rectangle for each screen relative to + the virtual screen) + + 2. Window information (window IDs and clipping information for each + back-end window that corresponds to each DMX window) + + 3. Input device information (mappings from DMX device IDs to back-end + device IDs) + + 4. Force window creation (so that a client can override the server- + side lazy window creation optimization) + + 5. Reconfiguration (so that a client can request that a screen + position be changed) + + 6. Addition and removal of back-end servers and back-end and console + inputs. + 22..66.. CCoommmmoonn XX eexxtteennssiioonn ssuuppppoorrtt + + The XInput, XKeyboard and Shape extensions are commonly used + extensions to the base X11 protocol. XInput allows multiple and non- + standard input devices to be accessed simultaneously. These input + devices can be connected to either the front-end or back-end servers. + XKeyboard allows much better keyboard mappings control. Shape adds + support for arbitrarily shaped windows and is used by various window + managers. Nearly all potential back-end X servers make these + extensions available, and support for each one will be added to the + DMX system. + + + In addition to the extensions listed above, support for the X + Rendering extension (Render) is being developed. Render adds digital + image composition to the rendering model used by the X Window System. + While this extension is still under development by Keith Packard of + HP, support for the current version will be added to the DMX system. + + + Support for the XTest extension was added during the first development + phase. + + + Status: The following extensions are supported and are discussed in + more detail in Phase IV of the Development Results (see appendix): + BIG-REQUESTS, DEC-XTRAP, DMX, DPMS, Extended-Visual-Information, GLX, + LBX, RECORD, RENDER, SECURITY, SHAPE, SYNC, X-Resource, XC-APPGROUP, + XC-MISC, XFree86-Bigfont, XINERAMA, XInputExtension, XKEYBOARD, and + XTEST. + + + 22..77.. OOppeennGGLL ssuuppppoorrtt + + OpenGL support using the Mesa code base exists in XFree86 release 4 + and later. Currently, the direct rendering infrastructure (DRI) + provides accelerated OpenGL support for local clients and + unaccelerated OpenGL support (i.e., software rendering) is provided + for non-local clients. + + + The single head OpenGL support in XFree86 4.x will be extended to use + the DMX system. When the front and back-end servers are on the same + physical hardware, it is possible to use the DRI to directly render to + the back-end servers. First, the existing DRI will be extended to + support multiple display heads, and then to support the DMX system. + OpenGL rendering requests will be direct rendering to each back-end X + server. The DRI will request the screen layout (either from the + existing Xinerama extension or a DMX-specific extension). Support for + synchronized swap buffers will also be added (on hardware that + supports it). Note that a single front-end server with a single back- + end server on the same physical machine can emulate accelerated + indirect rendering. + + + When the front and back-end servers are on different physical hardware + or are using non-XFree86 4.x X servers, a mechanism to render + primitives across the back-end servers will be provided. There are + several options as to how this can be implemented. + + + 1. The existing OpenGL support in each back-end server can be used by + repackaging rendering primitives and sending them to each back-end + server. This option is similar to the unoptimized Xnest-style + approach mentioned above. Optimization of this solution is beyond + the scope of this project and is better suited to other distributed + rendering systems. + + 2. Rendering to a pixmap in the front-end server using the current + XFree86 4.x code, and then displaying to the back-ends via calls to + XPutImage() is another option. This option is similar to the + shadow frame buffer approach mentioned above. It is slower and + bandwidth intensive, but has the advantage that the back-end + servers are not required to have OpenGL support. + + + These, and other, options will be investigated in this phase of the + work. + + + Work by others have made Chromium DMX-aware. Chromium will use the + DMX X protocol extension to obtain information about the back-end + servers and will render directly to those servers, bypassing DMX. + + + Status: OpenGL support by the glxProxy extension was implemented by + SGI and has been integrated into the DMX code base. + + + + 33.. CCuurrrreenntt iissssuueess + + In this sections the current issues are outlined that require further + investigation. + + + 33..11.. FFoonnttss + + The font path and glyphs need to be the same for the front-end and + each of the back-end servers. Font glyphs could be sent to the back- + end servers as necessary but this would consume a significant amount + of available bandwidth during font rendering for clients that use many + different fonts (e.g., Netscape). Initially, the font server (xfs) + will be used to provide the fonts to both the front-end and back-end + servers. Other possibilities will be investigated during development. + + + 33..22.. ZZeerroo wwiiddtthh rreennddeerriinngg pprriimmiittiivveess + + To allow pixmap and on-screen rendering to be pixel perfect, all back- + end servers must render zero width primitives exactly the same as the + front-end renders the primitives to pixmaps. For those back-end + servers that do not exactly match, zero width primitives will be + automatically converted to one width primitives. This can be handled + in the front-end server via the GC state. + + + 33..33.. OOuuttppuutt ssccaalliinngg + + With very large tiled displays, it might be difficult to read the + information on the standard X desktop. In particular, the cursor can + be easily lost and fonts could be difficult to read. Automatic + primitive scaling might prove to be very useful. We will investigate + the possibility of scaling the cursor and providing a set of alternate + pre-scaled fonts to replace the standard fonts that many applications + use (e.g., fixed). Other options for automatic scaling will also be + investigated. + + + + 33..44.. PPeerr--ssccrreeeenn ccoolloorrmmaappss + + Each screen's default colormap in the set of back-end X servers should + be able to be adjusted via a configuration utility. This support is + would allow the back-end screens to be calibrated via custom gamma + tables. On 24-bit systems that support a DirectColor visual, this + type of correction can be accommodated. One possible implementation + would be to advertise to X client of the DMX server a TrueColor visual + while using DirectColor visuals on the back-end servers to implement + this type of color correction. Other options will be investigated. + + + AA.. BBaacckkggrroouunndd + + This section describes the existing Open Source architectures that can + be used to handle multiple screens and upon which this development + project is based. This section was written before the implementation + was finished, and may not reflect actual details of the + implementation. It is left for historical interest only. + + + AA..11.. CCoorree iinnppuutt ddeevviiccee hhaannddlliinngg + + The following is a description of how core input devices are handled + by an X server. + + + AA..11..11.. IInniittIInnppuutt(()) + + InitInput() is a DDX function that is called at the start of each + server generation from the X server's main() function. Its purpose is + to determine what input devices are connected to the X server, + register them with the DIX and MI layers, and initialize the input + event queue. InitInput() does not have a return value, but the X + server will abort if either a core keyboard device or a core pointer + device are not registered. Extended input (XInput) devices can also + be registered in InitInput(). + + + InitInput() usually has implementation specific code to determine + which input devices are available. For each input device it will be + using, it calls AddInputDevice(): + + + AAddddIInnppuuttDDeevviiccee(()) + This DIX function allocates the device structure, registers a + callback function (which handles device init, close, on and + off), and returns the input handle, which can be treated as + opaque. It is called once for each input device. + + + Once input handles for core keyboard and core pointer devices have + been obtained from AddInputDevice(), they are registered as core + devices by calling RegisterPointerDevice() and + RegisterKeyboardDevice(). Each of these should be called once. If + both core devices are not registered, then the X server will exit with + a fatal error when it attempts to start the input devices in + InitAndStartDevices(), which is called directly after InitInput() (see + below). + + + RReeggiisstteerr{{PPooiinntteerr,,KKeeyybbooaarrdd}}DDeevviiccee(()) + These DIX functions take a handle returned from AddInputDevice() + and initialize the core input device fields in inputInfo, and + initialize the input processing and grab functions for each core + input device. + The core pointer device is then registered with the miPointer code + (which does the high level cursor handling). While this registration + is not necessary for correct miPointer operation in the current + XFree86 code, it is still done mostly for compatibility reasons. + + + mmiiRReeggiisstteerrPPooiinntteerrDDeevviiccee(()) + This MI function registers the core pointer's input handle with + with the miPointer code. + + + The final part of InitInput() is the initialization of the input event + queue handling. In most cases, the event queue handling provided in + the MI layer is used. The primary XFree86 X server uses its own event + queue handling to support some special cases related to the XInput + extension and the XFree86-specific DGA extension. For our purposes, + the MI event queue handling should be suitable. It is initialized by + calling mieqInit(): + + + mmiieeqqIInniitt(()) + This MI function initializes the MI event queue for the core + devices, and is passed the public component of the input handles + for the two core devices. + + + If a wakeup handler is required to deliver synchronous input events, + it can be registered here by calling the DIX function + RegisterBlockAndWakeupHandlers(). (See the devReadInput() description + below.) + + + AA..11..22.. IInniittAAnnddSSttaarrttDDeevviicceess(()) + + InitAndStartDevices() is a DIX function that is called immediately + after InitInput() from the X server's main() function. Its purpose is + to initialize each input device that was registered with + AddInputDevice(), enable each input device that was successfully + initialized, and create the list of enabled input devices. Once each + registered device is processed in this way, the list of enabled input + devices is checked to make sure that both a core keyboard device and + core pointer device were registered and successfully enabled. If not, + InitAndStartDevices() returns failure, and results in the the X server + exiting with a fatal error. + + + Each registered device is initialized by calling its callback + (dev->deviceProc) with the DEVICE_INIT argument: + + + ((**ddeevv-->>ddeevviicceePPrroocc))((ddeevv,, DDEEVVIICCEE__IINNIITT)) + This function initializes the device structs with core + information relevant to the device. + + + For pointer devices, this means specifying the number of + buttons, default button mapping, the function used to get motion + events (usually miPointerGetMotionEvents()), the function used + to change/control the core pointer motion parameters + (acceleration and threshold), and the motion buffer size. + + + For keyboard devices, this means specifying the keycode range, + default keycode to keysym mapping, default modifier mapping, and + the functions used to sound the keyboard bell and modify/control + the keyboard parameters (LEDs, bell pitch and duration, key + click, which keys are auto-repeating, etc). + + + Each initialized device is enabled by calling EnableDevice(): + + + EEnnaabblleeDDeevviiccee(()) + EnableDevice() calls the device callback with DEVICE_ON: + + ((**ddeevv-->>ddeevviicceePPrroocc))((ddeevv,, DDEEVVIICCEE__OONN)) + This typically opens and initializes the relevant physical + device, and when appropriate, registers the device's file + descriptor (or equivalent) as a valid input source. + + + EnableDevice() then adds the device handle to the X server's + global list of enabled devices. + + + InitAndStartDevices() then verifies that a valid core keyboard and + pointer has been initialized and enabled. It returns failure if + either are missing. + + + AA..11..33.. ddeevvRReeaaddIInnppuutt(()) + + Each device will have some function that gets called to read its + physical input. These may be called in a number of different ways. + In the case of synchronous I/O, they will be called from a DDX wakeup- + handler that gets called after the server detects that new input is + available. In the case of asynchronous I/O, they will be called from + a (SIGIO) signal handler triggered when new input is available. This + function should do at least two things: make sure that input events + get enqueued, and make sure that the cursor gets moved for motion + events (except if these are handled later by the driver's own event + queue processing function, which cannot be done when using the MI + event queue handling). + + + Events are queued by calling mieqEnqueue(): + + + mmiieeqqEEnnqquueeuuee(()) + This MI function is used to add input events to the event queue. + It is simply passed the event to be queued. + + + The cursor position should be updated when motion events are enqueued, + by calling either miPointerAbsoluteCursor() or miPointerDeltaCursor(): + + + mmiiPPooiinntteerrAAbbssoolluutteeCCuurrssoorr(()) + This MI function is used to move the cursor to the absolute + coordinates provided. + + mmiiPPooiinntteerrDDeellttaaCCuurrssoorr(()) + This MI function is used to move the cursor relative to its + current position. + + + AA..11..44.. PPrroocceessssIInnppuuttEEvveennttss(()) + + ProcessInputEvents() is a DDX function that is called from the X + server's main dispatch loop when new events are available in the input + event queue. It typically processes the enqueued events, and updates + the cursor/pointer position. It may also do other DDX-specific event + processing. + + + Enqueued events are processed by mieqProcessInputEvents() and passed + to the DIX layer for transmission to clients: + + + mmiieeqqPPrroocceessssIInnppuuttEEvveennttss(()) + This function processes each event in the event queue, and + passes it to the device's input processing function. The DIX + layer provides default functions to do this processing, and they + handle the task of getting the events passed back to the + relevant clients. + + mmiiPPooiinntteerrUUppddaattee(()) + This function resynchronized the cursor position with the new + pointer position. It also takes care of moving the cursor + between screens when needed in multi-head configurations. + + + + AA..11..55.. DDiissaabblleeDDeevviiccee(()) + + DisableDevice is a DIX function that removes an input device from the + list of enabled devices. The result of this is that the device no + longer generates input events. The device's data structures are kept + in place, and disabling a device like this can be reversed by calling + EnableDevice(). DisableDevice() may be called from the DDX when it is + desirable to do so (e.g., the XFree86 server does this when VT + switching). Except for special cases, this is not normally called for + core input devices. + + + DisableDevice() calls the device's callback function with DEVICE_OFF: + + + ((**ddeevv-->>ddeevviicceePPrroocc))((ddeevv,, DDEEVVIICCEE__OOFFFF)) + This typically closes the relevant physical device, and when + appropriate, unregisters the device's file descriptor (or + equivalent) as a valid input source. + + + DisableDevice() then removes the device handle from the X server's + global list of enabled devices. + + + + AA..11..66.. CClloosseeDDeevviiccee(()) + + CloseDevice is a DIX function that removes an input device from the + list of available devices. It disables input from the device and + frees all data structures associated with the device. This function + is usually called from CloseDownDevices(), which is called from main() + at the end of each server generation to close all input devices. + + + CloseDevice() calls the device's callback function with DEVICE_CLOSE: + + + ((**ddeevv-->>ddeevviicceePPrroocc))((ddeevv,, DDEEVVIICCEE__CCLLOOSSEE)) + This typically closes the relevant physical device, and when + appropriate, unregisters the device's file descriptor (or + equivalent) as a valid input source. If any device specific + data structures were allocated when the device was initialized, + they are freed here. + + CloseDevice() then frees the data structures that were allocated for + the device when it was registered/initialized. + + + + AA..11..77.. LLeeggaallMMooddiiffiieerr(()) + + LegalModifier() is a required DDX function that can be used to + restrict which keys may be modifier keys. This seems to be present + for historical reasons, so this function should simply return TRUE + unconditionally. + + + + AA..22.. OOuuttppuutt hhaannddlliinngg + + The following sections describe the main functions required to + initialize, use and close the output device(s) for each screen in the + X server. + + + AA..22..11.. IInniittOOuuttppuutt(()) + + This DDX function is called near the start of each server generation + from the X server's main() function. InitOutput()'s main purpose is + to initialize each screen and fill in the global screenInfo structure + for each screen. It is passed three arguments: a pointer to the + screenInfo struct, which it is to initialize, and argc and argv from + main(), which can be used to determine additional configuration + information. + + + The primary tasks for this function are outlined below: + + + 1. PPaarrssee ccoonnffiigguurraattiioonn iinnffoo:: The first task of InitOutput() is to + parses any configuration information from the configuration file. + In addition to the XF86Config file, other configuration information + can be taken from the command line. The command line options can + be gathered either in InitOutput() or earlier in the + ddxProcessArgument() function, which is called by + ProcessCommandLine(). The configuration information determines the + characteristics of the screen(s). For example, in the XFree86 X + server, the XF86Config file specifies the monitor information, the + screen resolution, the graphics devices and slots in which they are + located, and, for Xinerama, the screens' layout. + + 2. IInniittiiaalliizzee ssccrreeeenn iinnffoo:: The next task is to initialize the screen- + dependent internal data structures. For example, part of what the + XFree86 X server does is to allocate its screen and pixmap private + indices, probe for graphics devices, compare the probed devices to + the ones listed in the XF86Config file, and add the ones that match + to the internal xf86Screens[] structure. + + 3. SSeett ppiixxmmaapp ffoorrmmaattss:: The next task is to initialize the screenInfo's + image byte order, bitmap bit order and bitmap scanline unit/pad. + The screenInfo's pixmap format's depth, bits per pixel and scanline + padding is also initialized at this stage. + + 4. UUnniiffyy ssccrreeeenn iinnffoo:: An optional task that might be done at this + stage is to compare all of the information from the various screens + and determines if they are compatible (i.e., if the set of screens + can be unified into a single desktop). This task has potential to + be useful to the DMX front-end server, if Xinerama's + PanoramiXConsolidate() function is not sufficient. + + Once these tasks are complete, the valid screens are known and each of + these screens can be initialized by calling AddScreen(). + + + AA..22..22.. AAddddSSccrreeeenn(()) + + This DIX function is called from InitOutput(), in the DDX layer, to + add each new screen to the screenInfo structure. The DDX screen + initialization function and command line arguments (i.e., argc and + argv) are passed to it as arguments. + + + This function first allocates a new Screen structure and any privates + that are required. It then initializes some of the fields in the + Screen struct and sets up the pixmap padding information. Finally, it + calls the DDX screen initialization function ScreenInit(), which is + described below. It returns the number of the screen that were just + added, or -1 if there is insufficient memory to add the screen or if + the DDX screen initialization fails. + + + AA..22..33.. SSccrreeeennIInniitt(()) + + This DDX function initializes the rest of the Screen structure with + either generic or screen-specific functions (as necessary). It also + fills in various screen attributes (e.g., width and height in + millimeters, black and white pixel values). + + + The screen init function usually calls several functions to perform + certain screen initialization functions. They are described below: + + + {{mmii,,**ffbb}}SSccrreeeennIInniitt(()) + The DDX layer's ScreenInit() function usually calls another + layer's ScreenInit() function (e.g., miScreenInit() or + fbScreenInit()) to initialize the fallbacks that the DDX driver + does not specifically handle. + + + After calling another layer's ScreenInit() function, any screen- + specific functions either wrap or replace the other layer's + function pointers. If a function is to be wrapped, each of the + old function pointers from the other layer are stored in a + screen private area. Common functions to wrap are CloseScreen() + and SaveScreen(). + + + mmiiIInniittiiaalliizzeeBBaacckkiinnggSSttoorree(()) + This MI function initializes the screen's backing storage + functions, which are used to save areas of windows that are + currently covered by other windows. + + + mmiiDDCCIInniittiiaalliizzee(()) + This MI function initializes the MI cursor display structures + and function pointers. If a hardware cursor is used, the DDX + layer's ScreenInit() function will wrap additional screen and + the MI cursor display function pointers. + + + Another common task for ScreenInit() function is to initialize the + output device state. For example, in the XFree86 X server, the + ScreenInit() function saves the original state of the video card and + then initializes the video mode of the graphics device. + + AA..22..44.. CClloosseeSSccrreeeenn(()) + + This function restores any wrapped screen functions (and in particular + the wrapped CloseScreen() function) and restores the state of the + output device to its original state. It should also free any private + data it created during the screen initialization. + + + AA..22..55.. GGCC ooppeerraattiioonnss + + When the X server is requested to render drawing primitives, it does + so by calling drawing functions through the graphics context's + operation function pointer table (i.e., the GCOps functions). These + functions render the basic graphics operations such as drawing + rectangles, lines, text or copying pixmaps. Default routines are + provided either by the MI layer, which draws indirectly through a + simple span interface, or by the framebuffer layers (e.g., CFB, MFB, + FB), which draw directly to a linearly mapped frame buffer. + + + To take advantage of special hardware on the graphics device, specific + GCOps functions can be replaced by device specific code. However, + many times the graphics devices can handle only a subset of the + possible states of the GC, so during graphics context validation, + appropriate routines are selected based on the state and capabilities + of the hardware. For example, some graphics hardware can accelerate + single pixel width lines with certain dash patterns. Thus, for dash + patterns that are not supported by hardware or for width 2 or greater + lines, the default routine is chosen during GC validation. + + + Note that some pointers to functions that draw to the screen are + stored in the Screen structure. They include GetImage(), GetSpans(), + PaintWindowBackground(), PaintWindowBorder(), CopyWindow() and + RestoreAreas(). + + + AA..22..66.. XXnneesstt + + The Xnest X server is a special proxy X server that relays the X + protocol requests that it receives to a ``real'' X server that then + processes the requests and displays the results, if applicable. To + the X applications, Xnest appears as if it is a regular X server. + However, Xnest is both server to the X application and client of the + real X server, which will actually handle the requests. + + + The Xnest server implements all of the standard input and output + initialization steps outlined above. + + + IInniittOOuuttppuutt(()) + Xnest takes its configuration information from command line + arguments via ddxProcessArguments(). This information includes + the real X server display to connect to, its default visual + class, the screen depth, the Xnest window's geometry, etc. + Xnest then connects to the real X server and gathers visual, + colormap, depth and pixmap information about that server's + display, creates a window on that server, which will be used as + the root window for Xnest. + + + Next, Xnest initializes its internal data structures and uses + the data from the real X server's pixmaps to initialize its own + pixmap formats. Finally, it calls AddScreen(xnestOpenScreen, + argc, argv) to initialize each of its screens. + SSccrreeeennIInniitt(()) + Xnest's ScreenInit() function is called xnestOpenScreen(). This + function initializes its screen's depth and visual information, + and then calls miScreenInit() to set up the default screen + functions. It then calls miInitializeBackingStore() and + miDCInitialize() to initialize backing store and the software + cursor. Finally, it replaces many of the screen functions with + its own functions that repackage and send the requests to the + real X server to which Xnest is attached. + + + CClloosseeSSccrreeeenn(()) + This function frees its internal data structure allocations. + Since it replaces instead of wrapping screen functions, there + are no function pointers to unwrap. This can potentially lead + to problems during server regeneration. + + + GGCC ooppeerraattiioonnss + The GC operations in Xnest are very simple since they leave all + of the drawing to the real X server to which Xnest is attached. + Each of the GCOps takes the request and sends it to the real X + server using standard Xlib calls. For example, the X + application issues a XDrawLines() call. This function turns + into a protocol request to Xnest, which calls the + xnestPolylines() function through Xnest's GCOps function pointer + table. The xnestPolylines() function is only a single line, + which calls XDrawLines() using the same arguments that were + passed into it. Other GCOps functions are very similar. Two + exceptions to the simple GCOps functions described above are the + image functions and the BLT operations. + + + The image functions, GetImage() and PutImage(), must use a + temporary image to hold the image to be put of the image that + was just grabbed from the screen while it is in transit to the + real X server or the client. When the image has been + transmitted, the temporary image is destroyed. + + + The BLT operations, CopyArea() and CopyPlane(), handle not only + the copy function, which is the same as the simple cases + described above, but also the graphics exposures that result + when the GC's graphics exposure bit is set to True. Graphics + exposures are handled in a helper function, + xnestBitBlitHelper(). This function collects the exposure + events from the real X server and, if any resulting in regions + being exposed, then those regions are passed back to the MI + layer so that it can generate exposure events for the X + application. + + + The Xnest server takes its input from the X server to which it is + connected. When the mouse is in the Xnest server's window, keyboard + and mouse events are received by the Xnest server, repackaged and sent + back to any client that requests those events. + + + AA..22..77.. SShhaaddooww ffrraammeebbuuffffeerr + + The most common type of framebuffer is a linear array memory that maps + to the video memory on the graphics device. However, accessing that + video memory over an I/O bus (e.g., ISA or PCI) can be slow. The + shadow framebuffer layer allows the developer to keep the entire + framebuffer in main memory and copy it back to video memory at regular + intervals. It also has been extended to handle planar video memory + and rotated framebuffers. + + + There are two main entry points to the shadow framebuffer code: + + + sshhaaddoowwAAlllloocc((wwiiddtthh,, hheeiigghhtt,, bbpppp)) + This function allocates the in memory copy of the framebuffer of + size width*height*bpp. It returns a pointer to that memory, + which will be used by the framebuffer ScreenInit() code during + the screen's initialization. + + + sshhaaddoowwIInniitt((ppSSccrreeeenn,, uuppddaatteePPrroocc,, wwiinnddoowwPPrroocc)) + This function initializes the shadow framebuffer layer. It + wraps several screen drawing functions, and registers a block + handler that will update the screen. The updateProc is a + function that will copy the damaged regions to the screen, and + the windowProc is a function that is used when the entire linear + video memory range cannot be accessed simultaneously so that + only a window into that memory is available (e.g., when using + the VGA aperture). + + + The shadow framebuffer code keeps track of the damaged area of each + screen by calculating the bounding box of all drawing operations that + have occurred since the last screen update. Then, when the block + handler is next called, only the damaged portion of the screen is + updated. + + + Note that since the shadow framebuffer is kept in main memory, all + drawing operations are performed by the CPU and, thus, no accelerated + hardware drawing operations are possible. + + + + AA..33.. XXiinneerraammaa + + Xinerama is an X extension that allows multiple physical screens + controlled by a single X server to appear as a single screen. + Although the extension allows clients to find the physical screen + layout via extension requests, it is completely transparent to clients + at the core X11 protocol level. The original public implementation of + Xinerama came from Digital/Compaq. XFree86 rewrote it, filling in + some missing pieces and improving both X11 core protocol compliance + and performance. The Xinerama extension will be passing through + X.Org's standardization process in the near future, and the sample + implementation will be based on this rewritten version. + + + The current implementation of Xinerama is based primarily in the DIX + (device independent) and MI (machine independent) layers of the X + server. With few exceptions the DDX layers do not need any changes to + support Xinerama. X server extensions often do need modifications to + provide full Xinerama functionality. + + + The following is a code-level description of how Xinerama functions. + + + Note: Because the Xinerama extension was originally called the + PanoramiX extension, many of the Xinerama functions still have the + PanoramiX prefix. + + + PPaannoorraammiiXXEExxtteennssiioonnIInniitt(()) + PanoramiXExtensionInit() is a device-independent extension + function that is called at the start of each server generation + from InitExtensions(), which is called from the X server's + main() function after all output devices have been initialized, + but before any input devices have been initialized. + + + PanoramiXNumScreens is set to the number of physical screens. + If only one physical screen is present, the extension is + disabled, and PanoramiXExtensionInit() returns without doing + anything else. + + + The Xinerama extension is registered by calling AddExtension(). + + + A local per-screen array of data structures (panoramiXdataPtr[]) + is allocated for each physical screen, and GC and Screen private + indexes are allocated, and both GC and Screen private areas are + allocated for each physical screen. These hold Xinerama- + specific per-GC and per-Screen data. Each screen's CreateGC and + CloseScreen functions are wrapped by XineramaCreateGC() and + XineramaCloseScreen() respectively. Some new resource classes + are created for Xinerama drawables and GCs, and resource types + for Xinerama windows, pixmaps and colormaps. + + + A region (XineramaScreenRegions[i]) is initialized for each + physical screen, and single region (PanoramiXScreenRegion) is + initialized to be the union of the screen regions. The + panoramiXdataPtr[] array is also initialized with the size and + origin of each screen. The relative positioning information for + the physical screens is taken from the array dixScreenOrigins[], + which the DDX layer must initialize in InitOutput(). The bounds + of the combined screen is also calculated (PanoramiXPixWidth and + PanoramiXPixHeight). + + + The DIX layer has a list of function pointers (ProcVector[]) + that holds the entry points for the functions that process core + protocol requests. The requests that Xinerama must intercept + and break up into physical screen-specific requests are wrapped. + The original set is copied to SavedProcVector[]. The types of + requests intercepted are Window requests, GC requests, colormap + requests, drawing requests, and some geometry-related requests. + This wrapping allows the bulk of the protocol request processing + to be handled transparently to the DIX layer. Some operations + cannot be dealt with in this way and are handled with Xinerama- + specific code within the DIX layer. + + + PPaannoorraammiiXXCCoonnssoolliiddaattee(()) + PanoramiXConsolidate() is a device-independent extension + function that is called directly from the X server's main() + function after extensions and input/output devices have been + initialized, and before the root windows are defined and + initialized. + + + This function finds the set of depths (PanoramiXDepths[]) and + visuals (PanoramiXVisuals[]) common to all of the physical + screens. PanoramiXNumDepths is set to the number of common + depths, and PanoramiXNumVisuals is set to the number of common + visuals. Resources are created for the single root window and + the default colormap. Each of these resources has per-physical + screen entries. + + + PPaannoorraammiiXXCCrreeaatteeCCoonnnneeccttiioonnBBlloocckk(()) + PanoramiXConsolidate() is a device-independent extension + function that is called directly from the X server's main() + function after the per-physical screen root windows are created. + It is called instead of the standard DIX CreateConnectionBlock() + function. If this function returns FALSE, the X server exits + with a fatal error. This function will return FALSE if no + common depths were found in PanoramiXConsolidate(). With no + common depths, Xinerama mode is not possible. + + + The connection block holds the information that clients get when + they open a connection to the X server. It includes information + such as the supported pixmap formats, number of screens and the + sizes, depths, visuals, default colormap information, etc, for + each of the screens (much of information that xdpyinfo shows). + The connection block is initialized with the combined single + screen values that were calculated in the above two functions. + + + The Xinerama extension allows the registration of connection + block callback functions. The purpose of these is to allow + other extensions to do processing at this point. These + callbacks can be registered by calling + XineramaRegisterConnectionBlockCallback() from the other + extension's ExtensionInit() function. Each registered + connection block callback is called at the end of + PanoramiXCreateConnectionBlock(). + + + AA..33..11.. XXiinneerraammaa--ssppeecciiffiicc cchhaannggeess ttoo tthhee DDIIXX ccooddee + + There are a few types of Xinerama-specific changes within the DIX + code. The main ones are described here. + + + Functions that deal with colormap or GC -related operations outside of + the intercepted protocol requests have a test added to only do the + processing for screen numbers > 0. This is because they are handled + for the single Xinerama screen and the processing is done once for + screen 0. + + + The handling of motion events does some coordinate translation between + the physical screen's origin and screen zero's origin. Also, motion + events must be reported relative to the composite screen origin rather + than the physical screen origins. + + + There is some special handling for cursor, window and event processing + that cannot (either not at all or not conveniently) be done via the + intercepted protocol requests. A particular case is the handling of + pointers moving between physical screens. + + + AA..33..22.. XXiinneerraammaa--ssppeecciiffiicc cchhaannggeess ttoo tthhee MMII ccooddee + + The only Xinerama-specific change to the MI code is in + miSendExposures() to handle the coordinate (and window ID) translation + for expose events. + + + + AA..33..33.. IInntteerrcceepptteedd DDIIXX ccoorree rreeqquueessttss + + Xinerama breaks up drawing requests for dispatch to each physical + screen. It also breaks up windows into pieces for each physical + screen. GCs are translated into per-screen GCs. Colormaps are + replicated on each physical screen. The functions handling the + intercepted requests take care of breaking the requests and + repackaging them so that they can be passed to the standard request + handling functions for each screen in turn. In addition, and to aid + the repackaging, the information from many of the intercepted requests + is used to keep up to date the necessary state information for the + single composite screen. Requests (usually those with replies) that + can be satisfied completely from this stored state information do not + call the standard request handling functions. + + + + BB.. DDeevveellooppmmeenntt RReessuullttss + + In this section the results of each phase of development are + discussed. This development took place between approximately June + 2001 and July 2003. + + + BB..11.. PPhhaassee II + + The initial development phase dealt with the basic implementation + including the bootstrap code, which used the shadow framebuffer, and + the unoptimized implementation, based on an Xnest-style + implementation. + + + BB..11..11.. SSccooppee + + The goal of Phase I is to provide fundamental functionality that can + act as a foundation for ongoing work: + + 1. Develop the proxy X server + + +o The proxy X server will operate on the X11 protocol and relay + requests as necessary to correctly perform the request. + + +o Work will be based on the existing work for Xinerama and Xnest. + + +o Input events and windowing operations are handled in the proxy + server and rendering requests are repackaged and sent to each of + the back-end servers for display. + + +o The multiple screen layout (including support for overlapping + screens) will be user configurable via a configuration file or + through the configuration tool. + + 2. Develop graphical configuration tool + + +o There will be potentially a large number of X servers to + configure into a single display. The tool will allow the user + to specify which servers are involved in the configuration and + how they should be laid out. + + 3. Pass the X Test Suite + + +o The X Test Suite covers the basic X11 operations. All tests + known to succeed must correctly operate in the distributed X + environment. + + + For this phase, the back-end X servers are assumed to be unmodified X + servers that do not support any DMX-related protocol extensions; + future optimization pathways are considered, but are not implemented; + and the configuration tool is assumed to rely only on libraries in the + X source tree (e.g., Xt). + + + BB..11..22.. RReessuullttss + + The proxy X server, Xdmx, was developed to distribute X11 protocol + requests to the set of back-end X servers. It opens a window on each + back-end server, which represents the part of the front-end's root + window that is visible on that screen. It mirrors window, pixmap and + other state in each back-end server. Drawing requests are sent to + either windows or pixmaps on each back-end server. This code is based + on Xnest and uses the existing Xinerama extension. + + + Input events can be taken from (1) devices attached to the back-end + server, (2) core devices attached directly to the Xdmx server, or (3) + from a ``console'' window on another X server. Events for these + devices are gathered, processed and delivered to clients attached to + the Xdmx server. + + + An intuitive configuration format was developed to help the user + easily configure the multiple back-end X servers. It was defined (see + grammar in Xdmx man page) and a parser was implemented that is used by + the Xdmx server and by a standalone xdmxconfig utility. The parsing + support was implemented such that it can be easily factored out of the + X source tree for use with other tools (e.g., vdl). Support for + converting legacy vdl-format configuration files to the DMX format is + provided by the vdltodmx utility. + + + Originally, the configuration file was going to be a subsection of + XFree86's XF86Config file, but that was not possible since Xdmx is a + completely separate X server. Thus, a separate config file format was + developed. In addition, a graphical configuration tool, xdmxconfig, + was developed to allow the user to create and arrange the screens in + the configuration file. The --ccoonnffiiggffiillee and --ccoonnffiigg command-line + options can be used to start Xdmx using a configuration file. + + + An extension that enables remote input testing is required for the X + Test Suite to function. During this phase, this extension (XTEST) was + implemented in the Xdmx server. The results from running the X Test + Suite are described in detail below. + + + BB..11..33.. XX TTeesstt SSuuiittee + + BB..11..33..11.. IInnttrroodduuccttiioonn + + The X Test Suite contains tests that verify Xlib functions operate + correctly. The test suite is designed to run on a single X server; + however, since X applications will not be able to tell the difference + between the DMX server and a standard X server, the X Test Suite + should also run on the DMX server. + + The Xdmx server was tested with the X Test Suite, and the existing + failures are noted in this section. To put these results in + perspective, we first discuss expected X Test failures and how errors + in underlying systems can impact Xdmx test results. + + + BB..11..33..22.. EExxppeecctteedd FFaaiilluurreess ffoorr aa SSiinnggllee HHeeaadd + + A correctly implemented X server with a single screen is expected to + fail certain X Test tests. The following well-known errors occur + because of rounding error in the X server code: + + XDrawArc: Tests 42, 63, 66, 73 + XDrawArcs: Tests 45, 66, 69, 76 + + + + The following failures occur because of the high-level X server + implementation: + + XLoadQueryFont: Test 1 + XListFontsWithInfo: Tests 3, 4 + XQueryFont: Tests 1, 2 + + + + The following test fails when running the X server as root under Linux + because of the way directory modes are interpreted: + + XWriteBitmapFile: Test 3 + + + + Depending on the video card used for the back-end, other failures may + also occur because of bugs in the low-level driver implementation. + Over time, failures of this kind are usually fixed by XFree86, but + will show up in Xdmx testing until then. + + + BB..11..33..33.. EExxppeecctteedd FFaaiilluurreess ffoorr XXiinneerraammaa + + Xinerama fails several X Test Suite tests because of design decisions + made for the current implementation of Xinerama. Over time, many of + these errors will be corrected by XFree86 and the group working on a + new Xinerama implementation. Therefore, Xdmx will also share X Suite + Test failures with Xinerama. + + We may be able to fix or work-around some of these failures at the + Xdmx level, but this will require additional exploration that was not + part of Phase I. + + Xinerama is constantly improving, and the list of Xinerama-related + failures depends on XFree86 version and the underlying graphics + hardware. We tested with a variety of hardware, including nVidia, S3, + ATI Radeon, and Matrox G400 (in dual-head mode). The list below + includes only those failures that appear to be from the Xinerama + layer, and does not include failures listed in the previous section, + or failures that appear to be from the low-level graphics driver + itself: + + These failures were noted with multiple Xinerama configurations: + + XCopyPlane: Tests 13, 22, 31 (well-known Xinerama implementation issue) + XSetFontPath: Test 4 + XGetDefault: Test 5 + XMatchVisualInfo: Test 1 + + + + These failures were noted only when using one dual-head video card + with a 4.2.99.x XFree86 server: + + XListPixmapFormats: Test 1 + XDrawRectangles: Test 45 + + + + These failures were noted only when using two video cards from + different vendors with a 4.1.99.x XFree86 server: + + XChangeWindowAttributes: Test 32 + XCreateWindow: Test 30 + XDrawLine: Test 22 + XFillArc: Test 22 + XChangeKeyboardControl: Tests 9, 10 + XRebindKeysym: Test 1 + + + + BB..11..33..44.. AAddddiittiioonnaall FFaaiilluurreess ffrroomm XXddmmxx + + When running Xdmx, no unexpected failures were noted. Since the Xdmx + server is based on Xinerama, we expect to have most of the Xinerama + failures present in the Xdmx server. Similarly, since the Xdmx server + must rely on the low-level device drivers on each back-end server, we + also expect that Xdmx will exhibit most of the back-end failures. + Here is a summary: + + XListPixmapFormats: Test 1 (configuration dependent) + XChangeWindowAttributes: Test 32 + XCreateWindow: Test 30 + XCopyPlane: Test 13, 22, 31 + XSetFontPath: Test 4 + XGetDefault: Test 5 (configuration dependent) + XMatchVisualInfo: Test 1 + XRebindKeysym: Test 1 (configuration dependent) + + + + Note that this list is shorter than the combined list for Xinerama + because Xdmx uses different code paths to perform some Xinerama + operations. Further, some Xinerama failures have been fixed in the + XFree86 4.2.99.x CVS repository. + + + BB..11..33..55.. SSuummmmaarryy aanndd FFuuttuurree WWoorrkk + + Running the X Test Suite on Xdmx does not produce any failures that + cannot be accounted for by the underlying Xinerama subsystem used by + the front-end or by the low-level device-driver code running on the + back-end X servers. The Xdmx server therefore is as ``correct'' as + possible with respect to the standard set of X Test Suite tests. + + During the following phases, we will continue to verify Xdmx + correctness using the X Test Suite. We may also use other tests + suites or write additional tests that run under the X Test Suite that + specifically verify the expected behavior of DMX. + + + + BB..11..44.. FFoonnttss + + In Phase I, fonts are handled directly by both the front-end and the + back-end servers, which is required since we must treat each back-end + server during this phase as a ``black box''. What this requires is + that tthhee ffrroonntt-- aanndd bbaacckk--eenndd sseerrvveerrss mmuusstt sshhaarree tthhee eexxaacctt ssaammee ffoonntt + ppaatthh. There are two ways to help make sure that all servers share the + same font path: + + + 1. First, each server can be configured to use the same font server. + The font server, xfs, can be configured to serve fonts to multiple + X servers via TCP. + + 2. Second, each server can be configured to use the same font path and + either those font paths can be copied to each back-end machine or + they can be mounted (e.g., via NFS) on each back-end machine. + + + One additional concern is that a client program can set its own font + path, and if it does so, then that font path must be available on each + back-end machine. + + + The -fontpath command line option was added to allow users to + initialize the font path of the front end server. This font path is + propagated to each back-end server when the default font is loaded. + If there are any problems, an error message is printed, which will + describe the problem and list the current font path. For more + information about setting the font path, see the -fontpath option + description in the man page. + + + BB..11..55.. PPeerrffoorrmmaannccee + + Phase I of development was not intended to optimize performance. Its + focus was on completely and correctly handling the base X11 protocol + in the Xdmx server. However, several insights were gained during + Phase I, which are listed here for reference during the next phase of + development. + + + 1. Calls to XSync() can slow down rendering since it requires a + complete round trip to and from a back-end server. This is + especially problematic when communicating over long haul networks. + + 2. Sending drawing requests to only the screens that they overlap + should improve performance. + + + BB..11..66.. PPiixxmmaappss + + Pixmaps were originally expected to be handled entirely in the front- + end X server; however, it was found that this overly complicated the + rendering code and would have required sending potentially large + images to each back server that required them when copying from pixmap + to screen. Thus, pixmap state is mirrored in the back-end server just + as it is with regular window state. With this implementation, the + same rendering code that draws to windows can be used to draw to + pixmaps on the back-end server, and no large image transfers are + required to copy from pixmap to window. + + + + BB..22.. PPhhaassee IIII + + The second phase of development concentrates on performance + optimizations. These optimizations are documented here, with x11perf + data to show how the optimizations improve performance. + + + All benchmarks were performed by running Xdmx on a dual processor + 1.4GHz AMD Athlon machine with 1GB of RAM connecting over 100baseT to + two single-processor 1GHz Pentium III machines with 256MB of RAM and + ATI Rage 128 (RF) video cards. The front end was running Linux + 2.4.20-pre1-ac1 and the back ends were running Linux 2.4.7-10 and + version 4.2.99.1 of XFree86 pulled from the XFree86 CVS repository on + August 7, 2002. All systems were running Red Hat Linux 7.2. + + + BB..22..11.. MMoovviinngg ffrroomm XXFFrreeee8866 44..11..9999..11 ttoo 44..22..00..00 + + For phase II, the working source tree was moved to the branch tagged + with dmx-1-0-branch and was updated from version 4.1.99.1 (20 August + 2001) of the XFree86 sources to version 4.2.0.0 (18 January 2002). + After this update, the following tests were noted to be more than 10% + faster: + + 1.13 Fill 300x300 opaque stippled trapezoid (161x145 stipple) + 1.16 Fill 1x1 tiled trapezoid (161x145 tile) + 1.13 Fill 10x10 tiled trapezoid (161x145 tile) + 1.17 Fill 100x100 tiled trapezoid (161x145 tile) + 1.16 Fill 1x1 tiled trapezoid (216x208 tile) + 1.20 Fill 10x10 tiled trapezoid (216x208 tile) + 1.15 Fill 100x100 tiled trapezoid (216x208 tile) + 1.37 Circulate Unmapped window (200 kids) + + + + And the following tests were noted to be more than 10% slower: + + 0.88 Unmap window via parent (25 kids) + 0.75 Circulate Unmapped window (4 kids) + 0.79 Circulate Unmapped window (16 kids) + 0.80 Circulate Unmapped window (25 kids) + 0.82 Circulate Unmapped window (50 kids) + 0.85 Circulate Unmapped window (75 kids) + + + + These changes were not caused by any changes in the DMX system, and + may point to changes in the XFree86 tree or to tests that have more + "jitter" than most other x11perf tests. + + + BB..22..22.. GGlloobbaall cchhaannggeess + + During the development of the Phase II DMX server, several global + changes were made. These changes were also compared with the Phase I + server. The following tests were noted to be more than 10% faster: + + + + 1.13 Fill 300x300 opaque stippled trapezoid (161x145 stipple) + 1.15 Fill 1x1 tiled trapezoid (161x145 tile) + 1.13 Fill 10x10 tiled trapezoid (161x145 tile) + 1.17 Fill 100x100 tiled trapezoid (161x145 tile) + 1.16 Fill 1x1 tiled trapezoid (216x208 tile) + 1.19 Fill 10x10 tiled trapezoid (216x208 tile) + 1.15 Fill 100x100 tiled trapezoid (216x208 tile) + 1.15 Circulate Unmapped window (4 kids) + + + + The following tests were noted to be more than 10% slower: + + 0.69 Scroll 10x10 pixels + 0.68 Scroll 100x100 pixels + 0.68 Copy 10x10 from window to window + 0.68 Copy 100x100 from window to window + 0.76 Circulate Unmapped window (75 kids) + 0.83 Circulate Unmapped window (100 kids) + + + + For the remainder of this analysis, the baseline of comparison will be + the Phase II deliverable with all optimizations disabled (unless + otherwise noted). This will highlight how the optimizations in + isolation impact performance. + + + BB..22..33.. XXSSyynncc(()) BBaattcchhiinngg + + During the Phase I implementation, XSync() was called after every + protocol request made by the DMX server. This provided the DMX server + with an interactive feel, but defeated X11's protocol buffering system + and introduced round-trip wire latency into every operation. During + Phase II, DMX was changed so that protocol requests are no longer + followed by calls to XSync(). Instead, the need for an XSync() is + noted, and XSync() calls are only made every 100mS or when the DMX + server specifically needs to make a call to guarantee interactivity. + With this new system, X11 buffers protocol as much as possible during + a 100mS interval, and many unnecessary XSync() calls are avoided. + + + Out of more than 300 x11perf tests, 8 tests became more than 100 times + faster, with 68 more than 50X faster, 114 more than 10X faster, and + 181 more than 2X faster. See table below for summary. + + + The following tests were noted to be more than 10% slower with XSync() + batching on: + + 0.88 500x500 tiled rectangle (161x145 tile) + 0.89 Copy 500x500 from window to window + + + + BB..22..44.. OOffffssccrreeeenn OOppttiimmiizzaattiioonn + + Windows span one or more of the back-end servers' screens; however, + during Phase I development, windows were created on every back-end + server and every rendering request was sent to every window regardless + of whether or not that window was visible. With the offscreen + optimization, the DMX server tracks when a window is completely off of + a back-end server's screen and, in that case, it does not send + rendering requests to those back-end windows. This optimization saves + bandwidth between the front and back-end servers, and it reduces the + number of XSync() calls. The performance tests were run on a DMX + system with only two back-end servers. Greater performance gains will + be had as the number of back-end servers increases. + + + Out of more than 300 x11perf tests, 3 tests were at least twice as + fast, and 146 tests were at least 10% faster. Two tests were more + than 10% slower with the offscreen optimization: + + 0.88 Hide/expose window via popup (4 kids) + 0.89 Resize unmapped window (75 kids) + + + + BB..22..55.. LLaazzyy WWiinnddooww CCrreeaattiioonn OOppttiimmiizzaattiioonn + + As mentioned above, during Phase I, windows were created on every + back-end server even if they were not visible on that back-end. With + the lazy window creation optimization, the DMX server does not create + windows on a back-end server until they are either visible or they + become the parents of a visible window. This optimization builds on + the offscreen optimization (described above) and requires it to be + enabled. + + + The lazy window creation optimization works by creating the window + data structures in the front-end server when a client creates a + window, but delays creation of the window on the back-end server(s). + A private window structure in the DMX server saves the relevant window + data and tracks changes to the window's attributes and stacking order + for later use. The only times a window is created on a back-end + server are (1) when it is mapped and is at least partially overlapping + the back-end server's screen (tracked by the offscreen optimization), + or (2) when the window becomes the parent of a previously visible + window. The first case occurs when a window is mapped or when a + visible window is copied, moved or resized and now overlaps the back- + end server's screen. The second case occurs when starting a window + manager after having created windows to which the window manager needs + to add decorations. + + + When either case occurs, a window on the back-end server is created + using the data saved in the DMX server's window private data + structure. The stacking order is then adjusted to correctly place the + window on the back-end and lastly the window is mapped. From this + time forward, the window is handled exactly as if the window had been + created at the time of the client's request. + + + Note that when a window is no longer visible on a back-end server's + screen (e.g., it is moved offscreen), the window is not destroyed; + rather, it is kept and reused later if the window once again becomes + visible on the back-end server's screen. Originally with this + optimization, destroying windows was implemented but was later + rejected because it increased bandwidth when windows were opaquely + moved or resized, which is common in many window managers. + + + + The performance tests were run on a DMX system with only two back-end + servers. Greater performance gains will be had as the number of back- + end servers increases. + + + This optimization improved the following x11perf tests by more than + 10%: + + 1.10 500x500 rectangle outline + 1.12 Fill 100x100 stippled trapezoid (161x145 stipple) + 1.20 Circulate Unmapped window (50 kids) + 1.19 Circulate Unmapped window (75 kids) + + + + BB..22..66.. SSuubbddiivviiddiinngg RReennddeerriinngg PPrriimmiittiivveess + + X11 imaging requests transfer significant data between the client and + the X server. During Phase I, the DMX server would then transfer the + image data to each back-end server. Even with the offscreen + optimization (above), these requests still required transferring + significant data to each back-end server that contained a visible + portion of the window. For example, if the client uses XPutImage() to + copy an image to a window that overlaps the entire DMX screen, then + the entire image is copied by the DMX server to every back-end server. + + + To reduce the amount of data transferred between the DMX server and + the back-end servers when XPutImage() is called, the image data is + subdivided and only the data that will be visible on a back-end + server's screen is sent to that back-end server. Xinerama already + implements a subdivision algorithm for XGetImage() and no further + optimization was needed. + + + Other rendering primitives were analyzed, but the time required to + subdivide these primitives was a significant proportion of the time + required to send the entire rendering request to the back-end server, + so this optimization was rejected for the other rendering primitives. + + + Again, the performance tests were run on a DMX system with only two + back-end servers. Greater performance gains will be had as the number + of back-end servers increases. + + + This optimization improved the following x11perf tests by more than + 10%: + + 1.12 Fill 100x100 stippled trapezoid (161x145 stipple) + 1.26 PutImage 10x10 square + 1.83 PutImage 100x100 square + 1.91 PutImage 500x500 square + 1.40 PutImage XY 10x10 square + 1.48 PutImage XY 100x100 square + 1.50 PutImage XY 500x500 square + 1.45 Circulate Unmapped window (75 kids) + 1.74 Circulate Unmapped window (100 kids) + + + + The following test was noted to be more than 10% slower with this + optimization: + + 0.88 10-pixel fill chord partial circle + + + + BB..22..77.. SSuummmmaarryy ooff xx1111ppeerrff DDaattaa + + With all of the optimizations on, 53 x11perf tests are more than 100X + faster than the unoptimized Phase II deliverable, with 69 more than + 50X faster, 73 more than 10X faster, and 199 more than twice as fast. + No tests were more than 10% slower than the unoptimized Phase II + deliverable. (Compared with the Phase I deliverable, only Circulate + Unmapped window (100 kids) was more than 10% slower than the Phase II + deliverable. As noted above, this test seems to have wider + variability than other x11perf tests.) + + + The following table summarizes relative x11perf test changes for all + optimizations individually and collectively. Note that some of the + optimizations have a synergistic effect when used together. + + + + 1: XSync() batching only + 2: Off screen optimizations only + 3: Window optimizations only + 4: Subdivprims only + 5: All optimizations + + 1 2 3 4 5 Operation + ------ ---- ---- ---- ------ --------- + 2.14 1.85 1.00 1.00 4.13 Dot + 1.67 1.80 1.00 1.00 3.31 1x1 rectangle + 2.38 1.43 1.00 1.00 2.44 10x10 rectangle + 1.00 1.00 0.92 0.98 1.00 100x100 rectangle + 1.00 1.00 1.00 1.00 1.00 500x500 rectangle + 1.83 1.85 1.05 1.06 3.54 1x1 stippled rectangle (8x8 stipple) + 2.43 1.43 1.00 1.00 2.41 10x10 stippled rectangle (8x8 stipple) + 0.98 1.00 1.00 1.00 1.00 100x100 stippled rectangle (8x8 stipple) + 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (8x8 stipple) + 1.75 1.75 1.00 1.00 3.40 1x1 opaque stippled rectangle (8x8 stipple) + 2.38 1.42 1.00 1.00 2.34 10x10 opaque stippled rectangle (8x8 stipple) + 1.00 1.00 0.97 0.97 1.00 100x100 opaque stippled rectangle (8x8 stipple) + 1.00 1.00 1.00 1.00 0.99 500x500 opaque stippled rectangle (8x8 stipple) + 1.82 1.82 1.04 1.04 3.56 1x1 tiled rectangle (4x4 tile) + 2.33 1.42 1.00 1.00 2.37 10x10 tiled rectangle (4x4 tile) + 1.00 0.92 1.00 1.00 1.00 100x100 tiled rectangle (4x4 tile) + 1.00 1.00 1.00 1.00 1.00 500x500 tiled rectangle (4x4 tile) + 1.94 1.62 1.00 1.00 3.66 1x1 stippled rectangle (17x15 stipple) + 1.74 1.28 1.00 1.00 1.73 10x10 stippled rectangle (17x15 stipple) + 1.00 1.00 1.00 0.89 0.98 100x100 stippled rectangle (17x15 stipple) + 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (17x15 stipple) + 1.94 1.62 1.00 1.00 3.67 1x1 opaque stippled rectangle (17x15 stipple) + 1.69 1.26 1.00 1.00 1.66 10x10 opaque stippled rectangle (17x15 stipple) + 1.00 0.95 1.00 1.00 1.00 100x100 opaque stippled rectangle (17x15 stipple) + 1.00 1.00 1.00 1.00 0.97 500x500 opaque stippled rectangle (17x15 stipple) + 1.93 1.61 0.99 0.99 3.69 1x1 tiled rectangle (17x15 tile) + 1.73 1.27 1.00 1.00 1.72 10x10 tiled rectangle (17x15 tile) + 1.00 1.00 1.00 1.00 0.98 100x100 tiled rectangle (17x15 tile) + 1.00 1.00 0.97 0.97 1.00 500x500 tiled rectangle (17x15 tile) + 1.95 1.63 1.00 1.00 3.83 1x1 stippled rectangle (161x145 stipple) + 1.80 1.30 1.00 1.00 1.83 10x10 stippled rectangle (161x145 stipple) + 0.97 1.00 1.00 1.00 1.01 100x100 stippled rectangle (161x145 stipple) + 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (161x145 stipple) + 1.95 1.63 1.00 1.00 3.56 1x1 opaque stippled rectangle (161x145 stipple) + 1.65 1.25 1.00 1.00 1.68 10x10 opaque stippled rectangle (161x145 stipple) + 1.00 1.00 1.00 1.00 1.01 100x100 opaque stippled rectangle (161x145... + 1.00 1.00 1.00 1.00 0.97 500x500 opaque stippled rectangle (161x145... + 1.95 1.63 0.98 0.99 3.80 1x1 tiled rectangle (161x145 tile) + 1.67 1.26 1.00 1.00 1.67 10x10 tiled rectangle (161x145 tile) + 1.13 1.14 1.14 1.14 1.14 100x100 tiled rectangle (161x145 tile) + 0.88 1.00 1.00 1.00 0.99 500x500 tiled rectangle (161x145 tile) + 1.93 1.63 1.00 1.00 3.53 1x1 tiled rectangle (216x208 tile) + 1.69 1.26 1.00 1.00 1.66 10x10 tiled rectangle (216x208 tile) + 1.00 1.00 1.00 1.00 1.00 100x100 tiled rectangle (216x208 tile) + 1.00 1.00 1.00 1.00 1.00 500x500 tiled rectangle (216x208 tile) + 1.82 1.70 1.00 1.00 3.38 1-pixel line segment + 2.07 1.56 0.90 1.00 3.31 10-pixel line segment + 1.29 1.10 1.00 1.00 1.27 100-pixel line segment + 1.05 1.06 1.03 1.03 1.09 500-pixel line segment + 1.30 1.13 1.00 1.00 1.29 100-pixel line segment (1 kid) + 1.32 1.15 1.00 1.00 1.32 100-pixel line segment (2 kids) + 1.33 1.16 1.00 1.00 1.33 100-pixel line segment (3 kids) + 1.92 1.64 1.00 1.00 3.73 10-pixel dashed segment + 1.34 1.16 1.00 1.00 1.34 100-pixel dashed segment + 1.24 1.11 0.99 0.97 1.23 100-pixel double-dashed segment + 1.72 1.77 1.00 1.00 3.25 10-pixel horizontal line segment + 1.83 1.66 1.01 1.00 3.54 100-pixel horizontal line segment + 1.86 1.30 1.00 1.00 1.84 500-pixel horizontal line segment + 2.11 1.52 1.00 0.99 3.02 10-pixel vertical line segment + 1.21 1.10 1.00 1.00 1.20 100-pixel vertical line segment + 1.03 1.03 1.00 1.00 1.02 500-pixel vertical line segment + 4.42 1.68 1.00 1.01 4.64 10x1 wide horizontal line segment + 1.83 1.31 1.00 1.00 1.83 100x10 wide horizontal line segment + 1.07 1.00 0.96 1.00 1.07 500x50 wide horizontal line segment + 4.10 1.67 1.00 1.00 4.62 10x1 wide vertical line segment + 1.50 1.24 1.06 1.06 1.48 100x10 wide vertical line segment + 1.06 1.03 1.00 1.00 1.05 500x50 wide vertical line segment + 2.54 1.61 1.00 1.00 3.61 1-pixel line + 2.71 1.48 1.00 1.00 2.67 10-pixel line + 1.19 1.09 1.00 1.00 1.19 100-pixel line + 1.04 1.02 1.00 1.00 1.03 500-pixel line + 2.68 1.51 0.98 1.00 3.17 10-pixel dashed line + 1.23 1.11 0.99 0.99 1.23 100-pixel dashed line + 1.15 1.08 1.00 1.00 1.15 100-pixel double-dashed line + 2.27 1.39 1.00 1.00 2.23 10x1 wide line + 1.20 1.09 1.00 1.00 1.20 100x10 wide line + 1.04 1.02 1.00 1.00 1.04 500x50 wide line + 1.52 1.45 1.00 1.00 1.52 100x10 wide dashed line + 1.54 1.47 1.00 1.00 1.54 100x10 wide double-dashed line + 1.97 1.30 0.96 0.95 1.95 10x10 rectangle outline + 1.44 1.27 1.00 1.00 1.43 100x100 rectangle outline + 3.22 2.16 1.10 1.09 3.61 500x500 rectangle outline + 1.95 1.34 1.00 1.00 1.90 10x10 wide rectangle outline + 1.14 1.14 1.00 1.00 1.13 100x100 wide rectangle outline + 1.00 1.00 1.00 1.00 1.00 500x500 wide rectangle outline + 1.57 1.72 1.00 1.00 3.03 1-pixel circle + 1.96 1.35 1.00 1.00 1.92 10-pixel circle + 1.21 1.07 0.86 0.97 1.20 100-pixel circle + 1.08 1.04 1.00 1.00 1.08 500-pixel circle + 1.39 1.19 1.03 1.03 1.38 100-pixel dashed circle + 1.21 1.11 1.00 1.00 1.23 100-pixel double-dashed circle + 1.59 1.28 1.00 1.00 1.58 10-pixel wide circle + 1.22 1.12 0.99 1.00 1.22 100-pixel wide circle + 1.06 1.04 1.00 1.00 1.05 500-pixel wide circle + 1.87 1.84 1.00 1.00 1.85 100-pixel wide dashed circle + 1.90 1.93 1.01 1.01 1.90 100-pixel wide double-dashed circle + 2.13 1.43 1.00 1.00 2.32 10-pixel partial circle + 1.42 1.18 1.00 1.00 1.42 100-pixel partial circle + 1.92 1.85 1.01 1.01 1.89 10-pixel wide partial circle + 1.73 1.67 1.00 1.00 1.73 100-pixel wide partial circle + 1.36 1.95 1.00 1.00 2.64 1-pixel solid circle + 2.02 1.37 1.00 1.00 2.03 10-pixel solid circle + 1.19 1.09 1.00 1.00 1.19 100-pixel solid circle + 1.02 0.99 1.00 1.00 1.01 500-pixel solid circle + 1.74 1.28 1.00 0.88 1.73 10-pixel fill chord partial circle + 1.31 1.13 1.00 1.00 1.31 100-pixel fill chord partial circle + 1.67 1.31 1.03 1.03 1.72 10-pixel fill slice partial circle + 1.30 1.13 1.00 1.00 1.28 100-pixel fill slice partial circle + 2.45 1.49 1.01 1.00 2.71 10-pixel ellipse + 1.22 1.10 1.00 1.00 1.22 100-pixel ellipse + 1.09 1.04 1.00 1.00 1.09 500-pixel ellipse + 1.90 1.28 1.00 1.00 1.89 100-pixel dashed ellipse + 1.62 1.24 0.96 0.97 1.61 100-pixel double-dashed ellipse + 2.43 1.50 1.00 1.00 2.42 10-pixel wide ellipse + 1.61 1.28 1.03 1.03 1.60 100-pixel wide ellipse + 1.08 1.05 1.00 1.00 1.08 500-pixel wide ellipse + 1.93 1.88 1.00 1.00 1.88 100-pixel wide dashed ellipse + 1.94 1.89 1.01 1.00 1.94 100-pixel wide double-dashed ellipse + 2.31 1.48 1.00 1.00 2.67 10-pixel partial ellipse + 1.38 1.17 1.00 1.00 1.38 100-pixel partial ellipse + 2.00 1.85 0.98 0.97 1.98 10-pixel wide partial ellipse + 1.89 1.86 1.00 1.00 1.89 100-pixel wide partial ellipse + 3.49 1.60 1.00 1.00 3.65 10-pixel filled ellipse + 1.67 1.26 1.00 1.00 1.67 100-pixel filled ellipse + 1.06 1.04 1.00 1.00 1.06 500-pixel filled ellipse + 2.38 1.43 1.01 1.00 2.32 10-pixel fill chord partial ellipse + 2.06 1.30 1.00 1.00 2.05 100-pixel fill chord partial ellipse + 2.27 1.41 1.00 1.00 2.27 10-pixel fill slice partial ellipse + 1.98 1.33 1.00 0.97 1.97 100-pixel fill slice partial ellipse + 57.46 1.99 1.01 1.00 114.92 Fill 1x1 equivalent triangle + 56.94 1.98 1.01 1.00 73.89 Fill 10x10 equivalent triangle + 6.07 1.75 1.00 1.00 6.07 Fill 100x100 equivalent triangle + 51.12 1.98 1.00 1.00 102.81 Fill 1x1 trapezoid + 51.42 1.82 1.01 1.00 94.89 Fill 10x10 trapezoid + 6.47 1.80 1.00 1.00 6.44 Fill 100x100 trapezoid + 1.56 1.28 1.00 0.99 1.56 Fill 300x300 trapezoid + 51.27 1.97 0.96 0.97 102.54 Fill 1x1 stippled trapezoid (8x8 stipple) + 51.73 2.00 1.02 1.02 67.92 Fill 10x10 stippled trapezoid (8x8 stipple) + 5.36 1.72 1.00 1.00 5.36 Fill 100x100 stippled trapezoid (8x8 stipple) + 1.54 1.26 1.00 1.00 1.59 Fill 300x300 stippled trapezoid (8x8 stipple) + 51.41 1.94 1.01 1.00 102.82 Fill 1x1 opaque stippled trapezoid (8x8 stipple) + 50.71 1.95 0.99 1.00 65.44 Fill 10x10 opaque stippled trapezoid (8x8... + 5.33 1.73 1.00 1.00 5.36 Fill 100x100 opaque stippled trapezoid (8x8... + 1.58 1.25 1.00 1.00 1.58 Fill 300x300 opaque stippled trapezoid (8x8... + 51.56 1.96 0.99 0.90 103.68 Fill 1x1 tiled trapezoid (4x4 tile) + 51.59 1.99 1.01 1.01 62.25 Fill 10x10 tiled trapezoid (4x4 tile) + 5.38 1.72 1.00 1.00 5.38 Fill 100x100 tiled trapezoid (4x4 tile) + 1.54 1.25 1.00 0.99 1.58 Fill 300x300 tiled trapezoid (4x4 tile) + 51.70 1.98 1.01 1.01 103.98 Fill 1x1 stippled trapezoid (17x15 stipple) + 44.86 1.97 1.00 1.00 44.86 Fill 10x10 stippled trapezoid (17x15 stipple) + 2.74 1.56 1.00 1.00 2.73 Fill 100x100 stippled trapezoid (17x15 stipple) + 1.29 1.14 1.00 1.00 1.27 Fill 300x300 stippled trapezoid (17x15 stipple) + 51.41 1.96 0.96 0.95 103.39 Fill 1x1 opaque stippled trapezoid (17x15... + 45.14 1.96 1.01 1.00 45.14 Fill 10x10 opaque stippled trapezoid (17x15... + 2.68 1.56 1.00 1.00 2.68 Fill 100x100 opaque stippled trapezoid (17x15... + 1.26 1.10 1.00 1.00 1.28 Fill 300x300 opaque stippled trapezoid (17x15... + 51.13 1.97 1.00 0.99 103.39 Fill 1x1 tiled trapezoid (17x15 tile) + 47.58 1.96 1.00 1.00 47.86 Fill 10x10 tiled trapezoid (17x15 tile) + 2.74 1.56 1.00 1.00 2.74 Fill 100x100 tiled trapezoid (17x15 tile) + 1.29 1.14 1.00 1.00 1.28 Fill 300x300 tiled trapezoid (17x15 tile) + 51.13 1.97 0.99 0.97 103.39 Fill 1x1 stippled trapezoid (161x145 stipple) + 45.14 1.97 1.00 1.00 44.29 Fill 10x10 stippled trapezoid (161x145 stipple) + 3.02 1.77 1.12 1.12 3.38 Fill 100x100 stippled trapezoid (161x145 stipple) + 1.31 1.13 1.00 1.00 1.30 Fill 300x300 stippled trapezoid (161x145 stipple) + 51.27 1.97 1.00 1.00 103.10 Fill 1x1 opaque stippled trapezoid (161x145... + 45.01 1.97 1.00 1.00 45.01 Fill 10x10 opaque stippled trapezoid (161x145... + 2.67 1.56 1.00 1.00 2.69 Fill 100x100 opaque stippled trapezoid (161x145.. + 1.29 1.13 1.00 1.01 1.27 Fill 300x300 opaque stippled trapezoid (161x145.. + 51.41 1.96 1.00 0.99 103.39 Fill 1x1 tiled trapezoid (161x145 tile) + 45.01 1.96 0.98 1.00 45.01 Fill 10x10 tiled trapezoid (161x145 tile) + 2.62 1.36 1.00 1.00 2.69 Fill 100x100 tiled trapezoid (161x145 tile) + 1.27 1.13 1.00 1.00 1.22 Fill 300x300 tiled trapezoid (161x145 tile) + 51.13 1.98 1.00 1.00 103.39 Fill 1x1 tiled trapezoid (216x208 tile) + 45.14 1.97 1.01 0.99 45.14 Fill 10x10 tiled trapezoid (216x208 tile) + 2.62 1.55 1.00 1.00 2.71 Fill 100x100 tiled trapezoid (216x208 tile) + 1.28 1.13 1.00 1.00 1.20 Fill 300x300 tiled trapezoid (216x208 tile) + 50.71 1.95 1.00 1.00 54.70 Fill 10x10 equivalent complex polygon + 5.51 1.71 0.96 0.98 5.47 Fill 100x100 equivalent complex polygons + 8.39 1.97 1.00 1.00 16.75 Fill 10x10 64-gon (Convex) + 8.38 1.83 1.00 1.00 8.43 Fill 100x100 64-gon (Convex) + 8.50 1.96 1.00 1.00 16.64 Fill 10x10 64-gon (Complex) + 8.26 1.83 1.00 1.00 8.35 Fill 100x100 64-gon (Complex) + 14.09 1.87 1.00 1.00 14.05 Char in 80-char line (6x13) + 11.91 1.87 1.00 1.00 11.95 Char in 70-char line (8x13) + 11.16 1.85 1.01 1.00 11.10 Char in 60-char line (9x15) + 10.09 1.78 1.00 1.00 10.09 Char16 in 40-char line (k14) + 6.15 1.75 1.00 1.00 6.31 Char16 in 23-char line (k24) + 11.92 1.90 1.03 1.03 11.88 Char in 80-char line (TR 10) + 8.18 1.78 1.00 0.99 8.17 Char in 30-char line (TR 24) + 42.83 1.44 1.01 1.00 42.11 Char in 20/40/20 line (6x13, TR 10) + 27.45 1.43 1.01 1.01 27.45 Char16 in 7/14/7 line (k14, k24) + 12.13 1.85 1.00 1.00 12.05 Char in 80-char image line (6x13) + 10.00 1.84 1.00 1.00 10.00 Char in 70-char image line (8x13) + 9.18 1.83 1.00 1.00 9.12 Char in 60-char image line (9x15) + 9.66 1.82 0.98 0.95 9.66 Char16 in 40-char image line (k14) + 5.82 1.72 1.00 1.00 5.99 Char16 in 23-char image line (k24) + 8.70 1.80 1.00 1.00 8.65 Char in 80-char image line (TR 10) + 4.67 1.66 1.00 1.00 4.67 Char in 30-char image line (TR 24) + 84.43 1.47 1.00 1.00 124.18 Scroll 10x10 pixels + 3.73 1.50 1.00 0.98 3.73 Scroll 100x100 pixels + 1.00 1.00 1.00 1.00 1.00 Scroll 500x500 pixels + 84.43 1.51 1.00 1.00 134.02 Copy 10x10 from window to window + 3.62 1.51 0.98 0.98 3.62 Copy 100x100 from window to window + 0.89 1.00 1.00 1.00 1.00 Copy 500x500 from window to window + 57.06 1.99 1.00 1.00 88.64 Copy 10x10 from pixmap to window + 2.49 2.00 1.00 1.00 2.48 Copy 100x100 from pixmap to window + 1.00 0.91 1.00 1.00 0.98 Copy 500x500 from pixmap to window + 2.04 1.01 1.00 1.00 2.03 Copy 10x10 from window to pixmap + 1.05 1.00 1.00 1.00 1.05 Copy 100x100 from window to pixmap + 1.00 1.00 0.93 1.00 1.04 Copy 500x500 from window to pixmap + 58.52 1.03 1.03 1.02 57.95 Copy 10x10 from pixmap to pixmap + 2.40 1.00 1.00 1.00 2.45 Copy 100x100 from pixmap to pixmap + 1.00 1.00 1.00 1.00 1.00 Copy 500x500 from pixmap to pixmap + 51.57 1.92 1.00 1.00 85.75 Copy 10x10 1-bit deep plane + 6.37 1.75 1.01 1.01 6.37 Copy 100x100 1-bit deep plane + 1.26 1.11 1.00 1.00 1.24 Copy 500x500 1-bit deep plane + 4.23 1.63 0.98 0.97 4.38 Copy 10x10 n-bit deep plane + 1.04 1.02 1.00 1.00 1.04 Copy 100x100 n-bit deep plane + 1.00 1.00 1.00 1.00 1.00 Copy 500x500 n-bit deep plane + 6.45 1.98 1.00 1.26 12.80 PutImage 10x10 square + 1.10 1.87 1.00 1.83 2.11 PutImage 100x100 square + 1.02 1.93 1.00 1.91 1.91 PutImage 500x500 square + 4.17 1.78 1.00 1.40 7.18 PutImage XY 10x10 square + 1.27 1.49 0.97 1.48 2.10 PutImage XY 100x100 square + 1.00 1.50 1.00 1.50 1.52 PutImage XY 500x500 square + 1.07 1.01 1.00 1.00 1.06 GetImage 10x10 square + 1.01 1.00 1.00 1.00 1.01 GetImage 100x100 square + 1.00 1.00 1.00 1.00 1.00 GetImage 500x500 square + 1.56 1.00 0.99 0.97 1.56 GetImage XY 10x10 square + 1.02 1.00 1.00 1.00 1.02 GetImage XY 100x100 square + 1.00 1.00 1.00 1.00 1.00 GetImage XY 500x500 square + 1.00 1.00 1.01 0.98 0.95 X protocol NoOperation + 1.02 1.03 1.04 1.03 1.00 QueryPointer + 1.03 1.02 1.04 1.03 1.00 GetProperty + 100.41 1.51 1.00 1.00 198.76 Change graphics context + 45.81 1.00 0.99 0.97 57.10 Create and map subwindows (4 kids) + 78.45 1.01 1.02 1.02 63.07 Create and map subwindows (16 kids) + 73.91 1.01 1.00 1.00 56.37 Create and map subwindows (25 kids) + 73.22 1.00 1.00 1.00 49.07 Create and map subwindows (50 kids) + 72.36 1.01 0.99 1.00 32.14 Create and map subwindows (75 kids) + 70.34 1.00 1.00 1.00 30.12 Create and map subwindows (100 kids) + 55.00 1.00 1.00 0.99 23.75 Create and map subwindows (200 kids) + 55.30 1.01 1.00 1.00 141.03 Create unmapped window (4 kids) + 55.38 1.01 1.01 1.00 163.25 Create unmapped window (16 kids) + 54.75 0.96 1.00 0.99 166.95 Create unmapped window (25 kids) + 54.83 1.00 1.00 0.99 178.81 Create unmapped window (50 kids) + 55.38 1.01 1.01 1.00 181.20 Create unmapped window (75 kids) + 55.38 1.01 1.01 1.00 181.20 Create unmapped window (100 kids) + 54.87 1.01 1.01 1.00 182.05 Create unmapped window (200 kids) + 28.13 1.00 1.00 1.00 30.75 Map window via parent (4 kids) + 36.14 1.01 1.01 1.01 32.58 Map window via parent (16 kids) + 26.13 1.00 0.98 0.95 29.85 Map window via parent (25 kids) + 40.07 1.00 1.01 1.00 27.57 Map window via parent (50 kids) + 23.26 0.99 1.00 1.00 18.23 Map window via parent (75 kids) + 22.91 0.99 1.00 0.99 16.52 Map window via parent (100 kids) + 27.79 1.00 1.00 0.99 12.50 Map window via parent (200 kids) + 22.35 1.00 1.00 1.00 56.19 Unmap window via parent (4 kids) + 9.57 1.00 0.99 1.00 89.78 Unmap window via parent (16 kids) + 80.77 1.01 1.00 1.00 103.85 Unmap window via parent (25 kids) + 96.34 1.00 1.00 1.00 116.06 Unmap window via parent (50 kids) + 99.72 1.00 1.00 1.00 124.93 Unmap window via parent (75 kids) + 112.36 1.00 1.00 1.00 125.27 Unmap window via parent (100 kids) + 105.41 1.00 1.00 0.99 120.00 Unmap window via parent (200 kids) + 51.29 1.03 1.02 1.02 74.19 Destroy window via parent (4 kids) + 86.75 0.99 0.99 0.99 116.87 Destroy window via parent (16 kids) + 106.43 1.01 1.01 1.01 127.49 Destroy window via parent (25 kids) + 120.34 1.01 1.01 1.00 140.11 Destroy window via parent (50 kids) + 126.67 1.00 0.99 0.99 145.00 Destroy window via parent (75 kids) + 126.11 1.01 1.01 1.00 140.56 Destroy window via parent (100 kids) + 128.57 1.01 1.00 1.00 137.91 Destroy window via parent (200 kids) + 16.04 0.88 1.00 1.00 20.36 Hide/expose window via popup (4 kids) + 19.04 1.01 1.00 1.00 23.48 Hide/expose window via popup (16 kids) + 19.22 1.00 1.00 1.00 20.44 Hide/expose window via popup (25 kids) + 17.41 1.00 0.91 0.97 17.68 Hide/expose window via popup (50 kids) + 17.29 1.01 1.00 1.01 17.07 Hide/expose window via popup (75 kids) + 16.74 1.00 1.00 1.00 16.17 Hide/expose window via popup (100 kids) + 10.30 1.00 1.00 1.00 10.51 Hide/expose window via popup (200 kids) + 16.48 1.01 1.00 1.00 26.05 Move window (4 kids) + 17.01 0.95 1.00 1.00 23.97 Move window (16 kids) + 16.95 1.00 1.00 1.00 22.90 Move window (25 kids) + 16.05 1.01 1.00 1.00 21.32 Move window (50 kids) + 15.58 1.00 0.98 0.98 19.44 Move window (75 kids) + 14.98 1.02 1.03 1.03 18.17 Move window (100 kids) + 10.90 1.01 1.01 1.00 12.68 Move window (200 kids) + 49.42 1.00 1.00 1.00 198.27 Moved unmapped window (4 kids) + 50.72 0.97 1.00 1.00 193.66 Moved unmapped window (16 kids) + 50.87 1.00 0.99 1.00 195.09 Moved unmapped window (25 kids) + 50.72 1.00 1.00 1.00 189.34 Moved unmapped window (50 kids) + 50.87 1.00 1.00 1.00 191.33 Moved unmapped window (75 kids) + 50.87 1.00 1.00 0.90 186.71 Moved unmapped window (100 kids) + 50.87 1.00 1.00 1.00 179.19 Moved unmapped window (200 kids) + 41.04 1.00 1.00 1.00 56.61 Move window via parent (4 kids) + 69.81 1.00 1.00 1.00 130.82 Move window via parent (16 kids) + 95.81 1.00 1.00 1.00 141.92 Move window via parent (25 kids) + 95.98 1.00 1.00 1.00 149.43 Move window via parent (50 kids) + 96.59 1.01 1.01 1.00 153.98 Move window via parent (75 kids) + 97.19 1.00 1.00 1.00 157.30 Move window via parent (100 kids) + 96.67 1.00 0.99 0.96 159.44 Move window via parent (200 kids) + 17.75 1.01 1.00 1.00 27.61 Resize window (4 kids) + 17.94 1.00 1.00 0.99 25.42 Resize window (16 kids) + 17.92 1.01 1.00 1.00 24.47 Resize window (25 kids) + 17.24 0.97 1.00 1.00 24.14 Resize window (50 kids) + 16.81 1.00 1.00 0.99 22.75 Resize window (75 kids) + 16.08 1.00 1.00 1.00 21.20 Resize window (100 kids) + 12.92 1.00 0.99 1.00 16.26 Resize window (200 kids) + 52.94 1.01 1.00 1.00 327.12 Resize unmapped window (4 kids) + 53.60 1.01 1.01 1.01 333.71 Resize unmapped window (16 kids) + 52.99 1.00 1.00 1.00 337.29 Resize unmapped window (25 kids) + 51.98 1.00 1.00 1.00 329.38 Resize unmapped window (50 kids) + 53.05 0.89 1.00 1.00 322.60 Resize unmapped window (75 kids) + 53.05 1.00 1.00 1.00 318.08 Resize unmapped window (100 kids) + 53.11 1.00 1.00 0.99 306.21 Resize unmapped window (200 kids) + 16.76 1.00 0.96 1.00 19.46 Circulate window (4 kids) + 17.24 1.00 1.00 0.97 16.24 Circulate window (16 kids) + 16.30 1.03 1.03 1.03 15.85 Circulate window (25 kids) + 13.45 1.00 1.00 1.00 14.90 Circulate window (50 kids) + 12.91 1.00 1.00 1.00 13.06 Circulate window (75 kids) + 11.30 0.98 1.00 1.00 11.03 Circulate window (100 kids) + 7.58 1.01 1.01 0.99 7.47 Circulate window (200 kids) + 1.01 1.01 0.98 1.00 0.95 Circulate Unmapped window (4 kids) + 1.07 1.07 1.01 1.07 1.02 Circulate Unmapped window (16 kids) + 1.04 1.09 1.06 1.05 0.97 Circulate Unmapped window (25 kids) + 1.04 1.23 1.20 1.18 1.05 Circulate Unmapped window (50 kids) + 1.18 1.53 1.19 1.45 1.24 Circulate Unmapped window (75 kids) + 1.08 1.02 1.01 1.74 1.01 Circulate Unmapped window (100 kids) + 1.01 1.12 0.98 0.91 0.97 Circulate Unmapped window (200 kids) + + + + BB..22..88.. PPrrooffiilliinngg wwiitthh OOPPrrooffiillee + + OProfile (available from http://oprofile.sourceforge.net/) is a + system-wide profiler for Linux systems that uses processor-level + counters to collect sampling data. OProfile can provide information + that is similar to that provided by gprof, but without the necessity + of recompiling the program with special instrumentation (i.e., + OProfile can collect statistical profiling information about optimized + programs). A test harness was developed to collect OProfile data for + each x11perf test individually. + + + Test runs were performed using the RETIRED_INSNS counter on the AMD + Athlon and the CPU_CLK_HALTED counter on the Intel Pentium III (with a + test configuration different from the one described above). We have + examined OProfile output and have compared it with gprof output. This + investigation has not produced results that yield performance + increases in x11perf numbers. + + + + BB..22..99.. XX TTeesstt SSuuiittee + + The X Test Suite was run on the fully optimized DMX server using the + configuration described above. The following failures were noted: + + XListPixmapFormats: Test 1 [1] + XChangeWindowAttributes: Test 32 [1] + XCreateWindow: Test 30 [1] + XFreeColors: Test 4 [3] + XCopyArea: Test 13, 17, 21, 25, 30 [2] + XCopyPlane: Test 11, 15, 27, 31 [2] + XSetFontPath: Test 4 [1] + XChangeKeyboardControl: Test 9, 10 [1] + + [1] Previously documented errors expected from the Xinerama + implementation (see Phase I discussion). + [2] Newly noted errors that have been verified as expected + behavior of the Xinerama implementation. + [3] Newly noted error that has been verified as a Xinerama + implementation bug. + + + + BB..33.. PPhhaassee IIIIII + + During the third phase of development, support was provided for the + following extensions: SHAPE, RENDER, XKEYBOARD, XInput. + + + BB..33..11.. SSHHAAPPEE + + The SHAPE extension is supported. Test applications (e.g., xeyes and + oclock) and window managers that make use of the SHAPE extension will + work as expected. + + + BB..33..22.. RREENNDDEERR + + The RENDER extension is supported. The version included in the DMX + CVS tree is version 0.2, and this version is fully supported by Xdmx. + Applications using only version 0.2 functions will work correctly; + however, some apps that make use of functions from later versions do + not properly check the extension's major/minor version numbers. These + apps will fail with a Bad Implementation error when using post-version + 0.2 functions. This is expected behavior. When the DMX CVS tree is + updated to include newer versions of RENDER, support for these newer + functions will be added to the DMX X server. + + + BB..33..33.. XXKKEEYYBBOOAARRDD + + The XKEYBOARD extension is supported. If present on the back-end X + servers, the XKEYBOARD extension will be used to obtain information + about the type of the keyboard for initialization. Otherwise, the + keyboard will be initialized using defaults. Note that this departs + from older behavior: when Xdmx is compiled without XKEYBOARD support, + the map from the back-end X server will be preserved. With XKEYBOARD + support, the map is not preserved because better information and + control of the keyboard is available. + + + BB..33..44.. XXIInnppuutt + + The XInput extension is supported. Any device can be used as a core + device and be used as an XInput extension device, with the exception + of core devices on the back-end servers. This limitation is present + because cursor handling on the back-end requires that the back-end + cursor sometimes track the Xdmx core cursor -- behavior that is + incompatible with using the back-end pointer as a non-core device. + + + Currently, back-end extension devices are not available as Xdmx + extension devices, but this limitation should be removed in the + future. + + + To demonstrate the XInput extension, and to provide more examples for + low-level input device driver writers, USB device drivers have been + written for mice (usb-mou), keyboards (usb-kbd), and non-mouse/non- + keyboard USB devices (usb-oth). Please see the man page for + information on Linux kernel drivers that are required for using these + Xdmx drivers. + + + BB..33..55.. DDPPMMSS + + The DPMS extension is exported but does not do anything at this time. + + + BB..33..66.. OOtthheerr EExxtteennssiioonnss + + The LBX, SECURITY, XC-APPGROUP, and XFree86-Bigfont extensions do not + require any special Xdmx support and have been exported. + + + The BIG-REQUESTS, DEC-XTRAP, DOUBLE-BUFFER, Extended-Visual- + Information, FontCache, GLX, MIT-SCREEN-SAVER, MIT-SHM, MIT-SUNDRY- + NONSTANDARD, RECORD, SECURITY, SGI-GLX, SYNC, TOG-CUP, X-Resource, XC- + MISC, XFree86-DGA, XFree86-DRI, XFree86-Misc, + XFree86-VidModeExtension, and XVideo extensions are _n_o_t supported at + this time, but will be evaluated for inclusion in future DMX releases. + SSeeee bbeellooww ffoorr aaddddiittiioonnaall wwoorrkk oonn eexxtteennssiioonnss aafftteerr PPhhaassee IIIIII.. + + + BB..44.. PPhhaassee IIVV + + BB..44..11.. MMoovviinngg ttoo XXFFrreeee8866 44..33..00 + + For Phase IV, the recent release of XFree86 4.3.0 (27 February 2003) + was merged onto the dmx.sourceforge.net CVS trunk and all work is + proceeding using this tree. + + + BB..44..22.. EExxtteennssiioonnss + + BB..44..22..11.. XXCC--MMIISSCC ((ssuuppppoorrtteedd)) + + XC-MISC is used internally by the X library to recycle XIDs from the X + server. This is important for long-running X server sessions. Xdmx + supports this extension. The X Test Suite passed and failed the exact + same tests before and after this extension was enabled. + + + BB..44..22..22.. EExxtteennddeedd--VViissuuaall--IInnffoorrmmaattiioonn ((ssuuppppoorrtteedd)) + + The Extended-Visual-Information extension provides a method for an X + client to obtain detailed visual information. Xdmx supports this + extension. It was tested using the hw/dmx/examples/evi example + program. NNoottee tthhaatt tthhiiss eexxtteennssiioonn iiss nnoott XXiinneerraammaa--aawwaarree -- it will + return visual information for each screen even though Xinerama is + causing the X server to export a single logical screen. + + + BB..44..22..33.. RREESS ((ssuuppppoorrtteedd)) + + The X-Resource extension provides a mechanism for a client to obtain + detailed information about the resources used by other clients. This + extension was tested with the hw/dmx/examples/res program. The X Test + Suite passed and failed the exact same tests before and after this + extension was enabled. + + + BB..44..22..44.. BBIIGG--RREEQQUUEESSTTSS ((ssuuppppoorrtteedd)) + + This extension enables the X11 protocol to handle requests longer than + 262140 bytes. The X Test Suite passed and failed the exact same tests + before and after this extension was enabled. + + + BB..44..22..55.. XXSSYYNNCC ((ssuuppppoorrtteedd)) + + This extension provides facilities for two different X clients to + synchronize their requests. This extension was minimally tested with + xdpyinfo and the X Test Suite passed and failed the exact same tests + before and after this extension was enabled. + + + BB..44..22..66.. XXTTEESSTT,, RREECCOORRDD,, DDEECC--XXTTRRAAPP ((ssuuppppoorrtteedd)) aanndd XXTTeessttEExxtteennssiioonn11 + ((nnoott ssuuppppoorrtteedd)) + + The XTEST and RECORD extension were developed by the X Consortium for + use in the X Test Suite and are supported as a standard in the X11R6 + tree. They are also supported in Xdmx. When X Test Suite tests that + make use of the XTEST extension are run, Xdmx passes and fails exactly + the same tests as does a standard XFree86 X server. When the rcrdtest + test (a part of the X Test Suite that verifies the RECORD extension) + is run, Xdmx passes and fails exactly the same tests as does a + standard XFree86 X server. + + + There are two older XTEST-like extensions: DEC-XTRAP and + XTestExtension1. The XTestExtension1 extension was developed for use + by the X Testing Consortium for use with a test suite that eventually + became (part of?) the X Test Suite. Unlike XTEST, which only allows + events to be sent to the server, the XTestExtension1 extension also + allowed events to be recorded (similar to the RECORD extension). The + second is the DEC-XTRAP extension that was developed by the Digital + Equipment Corporation. + + + The DEC-XTRAP extension is available from Xdmx and has been tested + with the xtrap* tools which are distributed as standard X11R6 clients. + + + The XTestExtension1 is _n_o_t supported because it does not appear to be + used by any modern X clients (the few that support it also support + XTEST) and because there are no good methods available for testing + that it functions correctly (unlike XTEST and DEC-XTRAP, the code for + XTestExtension1 is not part of the standard X server source tree, so + additional testing is important). + + + Most of these extensions are documented in the X11R6 source tree. + Further, several original papers exist that this author was unable to + locate -- for completeness and historical interest, citations are + provide: + + XXRREECCOORRDD + Martha Zimet. Extending X For Recording. 8th Annual X Technical + Conference Boston, MA January 24-26, 1994. + + DDEECC--XXTTRRAAPP + Dick Annicchiarico, Robert Chesler, Alan Jamison. XTrap + Architecture. Digital Equipment Corporation, July 1991. + + XXTTeessttEExxtteennssiioonn11 + Larry Woestman. X11 Input Synthesis Extension Proposal. Hewlett + Packard, November 1991. + + + BB..44..22..77.. MMIITT--MMIISSCC ((nnoott ssuuppppoorrtteedd)) + + The MIT-MISC extension is used to control a bug-compatibility flag + that provides compatibility with xterm programs from X11R1 and X11R2. + There does not appear to be a single client available that makes use + of this extension and there is not way to verify that it works + correctly. The Xdmx server does _n_o_t support MIT-MISC. + + + BB..44..22..88.. SSCCRREEEENNSSAAVVEERR ((nnoott ssuuppppoorrtteedd)) + + This extension provides special support for the X screen saver. It + was tested with beforelight, which appears to be the only client that + works with it. When Xinerama was not active, beforelight behaved as + expected. However, when Xinerama was active, beforelight did not + behave as expected. Further, when this extension is not active, + xscreensaver (a widely-used X screen saver program) did not behave as + expected. Since this extension is not Xinerama-aware and is not + commonly used with expected results by clients, we have left this + extension disabled at this time. + + BB..44..22..99.. GGLLXX ((ssuuppppoorrtteedd)) + + The GLX extension provides OpenGL and GLX windowing support. In Xdmx, + the extension is called glxProxy, and it is Xinerama aware. It works + by either feeding requests forward through Xdmx to each of the back- + end servers or handling them locally. All rendering requests are + handled on the back-end X servers. This code was donated to the DMX + project by SGI. For the X Test Suite results comparison, see below. + + + BB..44..22..1100.. RREENNDDEERR ((ssuuppppoorrtteedd)) + + The X Rendering Extension (RENDER) provides support for digital image + composition. Geometric and text rendering are supported. RENDER is + partially Xinerama-aware, with text and the most basic compositing + operator; however, its higher level primitives (triangles, triangle + strips, and triangle fans) are not yet Xinerama-aware. The RENDER + extension is still under development, and is currently at version 0.8. + Additional support will be required in DMX as more primitives and/or + requests are added to the extension. + + + There is currently no test suite for the X Rendering Extension; + however, there has been discussion of developing a test suite as the + extension matures. When that test suite becomes available, additional + testing can be performed with Xdmx. The X Test Suite passed and + failed the exact same tests before and after this extension was + enabled. + + + BB..44..22..1111.. SSuummmmaarryy + + To summarize, the following extensions are currently supported: BIG- + REQUESTS, DEC-XTRAP, DMX, DPMS, Extended-Visual-Information, GLX, LBX, + RECORD, RENDER, SECURITY, SHAPE, SYNC, X-Resource, XC-APPGROUP, XC- + MISC, XFree86-Bigfont, XINERAMA, XInputExtension, XKEYBOARD, and + XTEST. + + + The following extensions are _n_o_t supported at this time: DOUBLE- + BUFFER, FontCache, MIT-SCREEN-SAVER, MIT-SHM, MIT-SUNDRY-NONSTANDARD, + TOG-CUP, XFree86-DGA, XFree86-Misc, XFree86-VidModeExtension, + XTestExtensionExt1, and XVideo. + + + BB..44..33.. AAddddiittiioonnaall TTeessttiinngg wwiitthh tthhee XX TTeesstt SSuuiittee + + BB..44..33..11.. XXFFrreeee8866 wwiitthhoouutt XXTTEESSTT + + After the release of XFree86 4.3.0, we retested the XFree86 X server + with and without using the XTEST extension. When the XTEST extension + was _n_o_t used for testing, the XFree86 4.3.0 server running on our + usual test system with a Radeon VE card reported unexpected failures + in the following tests: + + XListPixmapFormats: Test 1 + XChangeKeyboardControl: Tests 9, 10 + XGetDefault: Test 5 + XRebindKeysym: Test 1 + + + + BB..44..33..22.. XXFFrreeee8866 wwiitthh XXTTEESSTT + + When using the XTEST extension, the XFree86 4.3.0 server reported the + following errors: + + XListPixmapFormats: Test 1 + XChangeKeyboardControl: Tests 9, 10 + XGetDefault: Test 5 + XRebindKeysym: Test 1 + + XAllowEvents: Tests 20, 21, 24 + XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25 + XGrabKey: Test 8 + XSetPointerMapping: Test 3 + XUngrabButton: Test 4 + + + + While these errors may be important, they will probably be fixed + eventually in the XFree86 source tree. We are particularly interested + in demonstrating that the Xdmx server does not introduce additional + failures that are not known Xinerama failures. + + + BB..44..33..33.. XXddmmxx wwiitthh XXTTEESSTT,, wwiitthhoouutt XXiinneerraammaa,, wwiitthhoouutt GGLLXX + + Without Xinerama, but using the XTEST extension, the following errors + were reported from Xdmx (note that these are the same as for the + XFree86 4.3.0, except that XGetDefault no longer fails): + + XListPixmapFormats: Test 1 + XChangeKeyboardControl: Tests 9, 10 + XRebindKeysym: Test 1 + + XAllowEvents: Tests 20, 21, 24 + XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25 + XGrabKey: Test 8 + XSetPointerMapping: Test 3 + XUngrabButton: Test 4 + + + + BB..44..33..44.. XXddmmxx wwiitthh XXTTEESSTT,, wwiitthh XXiinneerraammaa,, wwiitthhoouutt GGLLXX + + With Xinerama, using the XTEST extension, the following errors were + reported from Xdmx: + + XListPixmapFormats: Test 1 + XChangeKeyboardControl: Tests 9, 10 + XRebindKeysym: Test 1 + + XAllowEvents: Tests 20, 21, 24 + XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25 + XGrabKey: Test 8 + XSetPointerMapping: Test 3 + XUngrabButton: Test 4 + + XCopyPlane: Tests 13, 22, 31 (well-known XTEST/Xinerama interaction issue) + XDrawLine: Test 67 + XDrawLines: Test 91 + XDrawSegments: Test 68 + + + + Note that the first two sets of errors are the same as for the XFree86 + 4.3.0 server, and that the XCopyPlane error is a well-known error + resulting from an XTEST/Xinerama interaction when the request crosses + a screen boundary. The XDraw* errors are resolved when the tests are + run individually and they do not cross a screen boundary. We will + investigate these errors further to determine their cause. + + + BB..44..33..55.. XXddmmxx wwiitthh XXTTEESSTT,, wwiitthh XXiinneerraammaa,, wwiitthh GGLLXX + + With GLX enabled, using the XTEST extension, the following errors were + reported from Xdmx (these results are from early during the Phase IV + development, but were confirmed with a late Phase IV snapshot): + + XListPixmapFormats: Test 1 + XChangeKeyboardControl: Tests 9, 10 + XRebindKeysym: Test 1 + + XAllowEvents: Tests 20, 21, 24 + XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25 + XGrabKey: Test 8 + XSetPointerMapping: Test 3 + XUngrabButton: Test 4 + + XClearArea: Test 8 + XCopyArea: Tests 4, 5, 11, 14, 17, 23, 25, 27, 30 + XCopyPlane: Tests 6, 7, 10, 19, 22, 31 + XDrawArcs: Tests 89, 100, 102 + XDrawLine: Test 67 + XDrawSegments: Test 68 + + + Note that the first two sets of errors are the same as for the XFree86 + 4.3.0 server, and that the third set has different failures than when + Xdmx does not include GLX support. Since the GLX extension adds new + visuals to support GLX's visual configs and the X Test Suite runs + tests over the entire set of visuals, additional rendering tests were + run and presumably more of them crossed a screen boundary. This con- + clusion is supported by the fact that nearly all of the rendering + errors reported are resolved when the tests are run individually and + they do no cross a screen boundary. + + + Further, when hardware rendering is disabled on the back-end displays, + many of the errors in the third set are eliminated, leaving only: + + XClearArea: Test 8 + XCopyArea: Test 4, 5, 11, 14, 17, 23, 25, 27, 30 + XCopyPlane: Test 6, 7, 10, 19, 22, 31 + + + + BB..44..33..66.. CCoonncclluussiioonn + + We conclude that all of the X Test Suite errors reported for Xdmx are + the result of errors in the back-end X server or the Xinerama + implementation. Further, all of these errors that can be reasonably + fixed at the Xdmx layer have been. (Where appropriate, we have + submitted patches to the XFree86 and Xinerama upstream maintainers.) + + + BB..44..44.. DDyynnaammiicc RReeccoonnffiigguurraattiioonn + + During this development phase, dynamic reconfiguration support was + added to DMX. This support allows an application to change the + position and offset of a back-end server's screen. For example, if + the application would like to shift a screen slightly to the left, it + could query Xdmx for the screen's <x,y> position and then dynamically + reconfigure that screen to be at position <x+10,y>. When a screen is + dynamically reconfigured, input handling and a screen's root window + dimensions are adjusted as needed. These adjustments are transparent + to the user. + + + BB..44..44..11.. DDyynnaammiicc rreeccoonnffiigguurraattiioonn eexxtteennssiioonn + + The application interface to DMX's dynamic reconfiguration is through + a function in the DMX extension library: + + Bool DMXReconfigureScreen(Display *dpy, int screen, int x, int y) + + + where _d_p_y is DMX server's display, _s_c_r_e_e_n is the number of the screen + to be reconfigured, and _x and _y are the new upper, left-hand coordi- + nates of the screen to be reconfigured. + + + The coordinates are not limited other than as required by the X + protocol, which limits all coordinates to a signed 16 bit number. In + addition, all coordinates within a screen must also be legal values. + Therefore, setting a screen's upper, left-hand coordinates such that + the right or bottom edges of the screen is greater than 32,767 is + illegal. + + + BB..44..44..22.. BBoouunnddiinngg bbooxx + + When the Xdmx server is started, a bounding box is calculated from the + screens' layout given either on the command line or in the + configuration file. This bounding box is currently fixed for the + lifetime of the Xdmx server. + + + While it is possible to move a screen outside of the bounding box, it + is currently not possible to change the dimensions of the bounding + box. For example, it is possible to specify coordinates of + <-100,-100> for the upper, left-hand corner of the bounding box, which + was previously at coordinates <0,0>. As expected, the screen is moved + down and to the right; however, since the bounding box is fixed, the + left side and upper portions of the screen exposed by the + reconfiguration are no longer accessible on that screen. Those + inaccessible regions are filled with black. + + + This fixed bounding box limitation will be addressed in a future + development phase. + + + BB..44..44..33.. SSaammppllee aapppplliiccaattiioonnss + + An example of where this extension is useful is in setting up a video + wall. It is not always possible to get everything perfectly aligned, + and sometimes the positions are changed (e.g., someone might bump into + a projector). Instead of physically moving projectors or monitors, it + is now possible to adjust the positions of the back-end server's + screens using the dynamic reconfiguration support in DMX. + + + Other applications, such as automatic setup and calibration tools, can + make use of dynamic reconfiguration to correct for projector alignment + problems, as long as the projectors are still arranged rectilinearly. + Horizontal and vertical keystone correction could be applied to + projectors to correct for non-rectilinear alignment problems; however, + this must be done external to Xdmx. + + + A sample test program is included in the DMX server's examples + directory to demonstrate the interface and how an application might + use dynamic reconfiguration. See dmxreconfig.c for details. + + + BB..44..44..44.. AAddddiittiioonnaall nnootteess + + In the original development plan, Phase IV was primarily devoted to + adding OpenGL support to DMX; however, SGI became interested in the + DMX project and developed code to support OpenGL/GLX. This code was + later donated to the DMX project and integrated into the DMX code + base, which freed the DMX developers to concentrate on dynamic + reconfiguration (as described above). + + + BB..44..55.. DDooxxyyggeenn ddooccuummeennttaattiioonn + + Doxygen is an open-source (GPL) documentation system for generating + browseable documentation from stylized comments in the source code. + We have placed all of the Xdmx server and DMX protocol source code + files under Doxygen so that comprehensive documentation for the Xdmx + source code is available in an easily browseable format. + + + BB..44..66.. VVaallggrriinndd + + Valgrind, an open-source (GPL) memory debugger for Linux, was used to + search for memory management errors. Several memory leaks were + detected and repaired. The following errors were not addressed: + + 1. When the X11 transport layer sends a reply to the client, only + those fields that are required by the protocol are filled in -- + unused fields are left as uninitialized memory and are therefore + noted by valgrind. These instances are not errors and were not + repaired. + + 2. At each server generation, glxInitVisuals allocates memory that is + never freed. The amount of memory lost each generation + approximately equal to 128 bytes for each back-end visual. Because + the code involved is automatically generated, this bug has not been + fixed and will be referred to SGI. + + 3. At each server generation, dmxRealizeFont calls XLoadQueryFont, + which allocates a font structure that is not freed. + dmxUnrealizeFont can free the font structure for the first screen, + but cannot free it for the other screens since they are already + closed by the time dmxUnrealizeFont could free them. The amount of + memory lost each generation is approximately equal to 80 bytes per + font per back-end. When this bug is fixed in the the X server's + device-independent (dix) code, DMX will be able to properly free + the memory allocated by XLoadQueryFont. + + + BB..44..77.. RRAATTSS + + RATS (Rough Auditing Tool for Security) is an open-source (GPL) + security analysis tool that scans source code for common security- + related programming errors (e.g., buffer overflows and TOCTOU races). + RATS was used to audit all of the code in the hw/dmx directory and all + "High" notations were checked manually. The code was either re- + written to eliminate the warning, or a comment containing "RATS" was + inserted on the line to indicate that a human had checked the code. + Unrepaired warnings are as follows: + + 1. Fixed-size buffers are used in many areas, but code has been added + to protect against buffer overflows (e.g., XmuSnprint). The only + instances that have not yet been fixed are in config/xdmxconfig.c + (which is not part of the Xdmx server) and input/usb-common.c. + + 2. vprintf and vfprintf are used in the logging routines. In general, + all uses of these functions (e.g., dmxLog) provide a constant + format string from a trusted source, so the use is relatively + benign. + + 3. glxProxy/glxscreens.c uses getenv and strcat. The use of these + functions is safe and will remain safe as long as ExtensionsString + is longer then GLXServerExtensions (ensuring this may not be ovious + to the casual programmer, but this is in automatically generated + code, so we hope that the generator enforces this constraint). + + + |