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