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