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