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