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