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