~ubuntu-branches/ubuntu/oneiric/xorg-server/oneiric-proposed

« back to all changes in this revision

Viewing changes to hw/dmx/doc/dmx.txt

  • Committer: Bazaar Package Importer
  • Author(s): Timo Aaltonen
  • Date: 2011-07-05 16:22:23 UTC
  • mfrom: (1.1.44 upstream) (0.11.25 sid)
  • Revision ID: james.westby@ubuntu.com-20110705162223-r7wfqdkwl8zubdjb
Tags: 2:1.10.2.902-1ubuntu1
* Merge from Debian unstable. (LP: #441653)
  - Update 500_xi2.1.patch to apply.
  - Drop patch 218_randr-check-rotated-virtual-size-limits-correctly.diff,
    fixed upstream.
* Update the crtc confinement patch with one that should work, with
  further fixes from upstream. (LP: #389519)
* Dropped a bunch of old Breaks from xserver-xorg-core.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
Distributed Multihead X design
2
2
 
3
 
  Kevin E. Martin
4
 
 
5
 
  David H. Dawes
6
 
 
7
 
  Rickard E. Faith
8
 
 
9
 
   29 June 2004 (created 25 July 2001)
10
 
 
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
18
 
 
19
 
     ----------------------------------------------------------------------
20
 
 
21
 
   Table of Contents
22
 
 
23
 
   Introduction
24
 
 
25
 
                The Distributed Multihead X Server
26
 
 
27
 
                Layout of Paper
28
 
 
29
 
   Development plan
30
 
 
31
 
                Bootstrap code
32
 
 
33
 
                Input device handling
34
 
 
35
 
                Output device handling
36
 
 
37
 
                Optimizing DMX
38
 
 
39
 
                DMX X extension support
40
 
 
41
 
                Common X extension support
42
 
 
43
 
                OpenGL support
44
 
 
45
 
   Current issues
46
 
 
47
 
                Fonts
48
 
 
49
 
                Zero width rendering primitives
50
 
 
51
 
                Output scaling
52
 
 
53
 
                Per-screen colormaps
54
 
 
55
 
   A. Appendix
56
 
 
57
 
                Background
58
 
 
59
 
                             Core input device handling
60
 
 
61
 
                             Output handling
62
 
 
63
 
                             Xinerama
64
 
 
65
 
                Development Results
66
 
 
67
 
                             Phase I
68
 
 
69
 
                             Phase II
70
 
 
71
 
                             Phase III
72
 
 
73
 
                             Phase IV
 
3
Kevin E. Martin
 
4
 
 
5
David H. Dawes
 
6
 
 
7
Rickard E. Faith
 
8
 
 
9
29 June 2004 (created 25 July 2001)
 
10
 
 
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
 
17
 
 
18
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 
19
 
 
20
Table of Contents
74
21
 
75
22
Introduction
76
23
 
77
 
  The Distributed Multihead X Server
78
 
 
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.
89
 
 
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.).
101
 
 
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.
106
 
 
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.
116
 
 
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.
128
 
 
129
 
  Layout of Paper
130
 
 
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.
137
 
 
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
144
 
   detail.
 
24
    The Distributed Multihead X Server
 
25
    Layout of Paper
145
26
 
146
27
Development plan
147
28
 
148
 
   This section describes the development plan from approximately June 2001
149
 
   through July 2003.
150
 
 
151
 
  Bootstrap code
152
 
 
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.
162
 
 
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.
169
 
 
170
 
   Status: The boot strap code is complete.
171
 
 
172
 
  Input device handling
173
 
 
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'',
179
 
 
180
 
   There are some options as to how the front-end X server gets its core
181
 
   input devices:
182
 
 
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.
198
 
 
199
 
       The following options are available for implementing local input
200
 
       devices:
201
 
 
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.
213
 
 
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.
222
 
 
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
228
 
            code.
229
 
 
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.
241
 
 
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.
250
 
 
251
 
    4. Other options were initially explored, but they were all partial
252
 
       subsets of the options listed above and, hence, are irrelevant.
253
 
 
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.
257
 
 
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.
262
 
 
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):
270
 
 
271
 
    1. A "dummy" device drive that never generates events.
272
 
 
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):
280
 
 
281
 
          o Linux keyboard
282
 
 
283
 
          o Linux serial mouse (MS)
284
 
 
285
 
          o Linux PS/2 mouse
286
 
 
287
 
          o USB keyboard
288
 
 
289
 
          o USB mouse
290
 
 
291
 
          o USB generic device (e.g., joystick, gamepad, etc.)
292
 
 
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.
297
 
 
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
305
 
       cursor positioning.
306
 
 
307
 
  Output device handling
308
 
 
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.
312
 
 
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.
319
 
 
320
 
    Initialization
321
 
 
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
335
 
   DMX implementation.
336
 
 
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
342
 
   screen.
343
 
 
344
 
    Handling rendering requests
345
 
 
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:
349
 
 
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
356
 
       framebuffer.
357
 
 
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.
362
 
 
363
 
       The initial DMX implementation used a shadow framebuffer by default.
364
 
 
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
373
 
       back-end servers.
374
 
 
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
382
 
       implementation.
383
 
 
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).
389
 
 
390
 
   Status: Both the shadow framebuffer and Xnest-style code is complete.
391
 
 
392
 
  Optimizing DMX
393
 
 
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.
397
 
 
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).
408
 
 
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.
418
 
 
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.
425
 
 
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.
432
 
 
433
 
   Other potential optimizations will be determined from the performance
434
 
   analysis.
435
 
 
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.
450
 
 
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
454
 
   optimizations.
455
 
 
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.
460
 
 
461
 
  DMX X extension support
462
 
 
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.
472
 
 
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:
477
 
 
478
 
    1. Screen information (clipping rectangle for each screen relative to the
479
 
       virtual screen)
480
 
 
481
 
    2. Window information (window IDs and clipping information for each
482
 
       back-end window that corresponds to each DMX window)
483
 
 
484
 
    3. Input device information (mappings from DMX device IDs to back-end
485
 
       device IDs)
486
 
 
487
 
    4. Force window creation (so that a client can override the server-side
488
 
       lazy window creation optimization)
489
 
 
490
 
    5. Reconfiguration (so that a client can request that a screen position
491
 
       be changed)
492
 
 
493
 
    6. Addition and removal of back-end servers and back-end and console
494
 
       inputs.
495
 
 
496
 
  Common X extension support
497
 
 
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.
506
 
 
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.
512
 
 
513
 
   Support for the XTest extension was added during the first development
514
 
   phase.
515
 
 
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.
521
 
 
522
 
  OpenGL support
523
 
 
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.
528
 
 
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.
540
 
 
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.
545
 
 
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
551
 
       systems.
552
 
 
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.
559
 
 
560
 
   These, and other, options will be investigated in this phase of the work.
561
 
 
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.
565
 
 
566
 
   Status: OpenGL support by the glxProxy extension was implemented by SGI
567
 
   and has been integrated into the DMX code base.
 
29
    Bootstrap code
 
30
    Input device handling
 
31
    Output device handling
 
32
    Optimizing DMX
 
33
    DMX X extension support
 
34
    Common X extension support
 
35
    OpenGL support
568
36
 
569
37
Current issues
570
38
 
571
 
   In this sections the current issues are outlined that require further
572
 
   investigation.
573
 
 
574
 
  Fonts
575
 
 
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.
583
 
 
584
 
  Zero width rendering primitives
585
 
 
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.
592
 
 
593
 
  Output scaling
594
 
 
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.
602
 
 
603
 
  Per-screen colormaps
604
 
 
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.
 
39
    Fonts
 
40
    Zero width rendering primitives
 
41
    Output scaling
 
42
    Per-screen colormaps
613
43
 
614
44
A. Appendix
615
45
 
 
46
    Background
 
47
 
 
48
        Core input device handling
 
49
        Output handling
 
50
        Xinerama
 
51
 
 
52
    Development Results
 
53
 
 
54
        Phase I
 
55
        Phase II
 
56
        Phase III
 
57
        Phase IV
 
58
 
 
59
Introduction
 
60
 
 
61
The Distributed Multihead X Server
 
62
 
 
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.
 
73
 
 
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.).
 
84
 
 
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.
 
89
 
 
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.
 
98
 
 
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
 
109
needed.
 
110
 
 
111
Layout of Paper
 
112
 
 
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.
 
119
 
 
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.
 
126
 
 
127
Development plan
 
128
 
 
129
This section describes the development plan from approximately June 2001
 
130
through July 2003.
 
131
 
 
132
Bootstrap code
 
133
 
 
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.
 
143
 
 
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.
 
150
 
 
151
Status: The boot strap code is complete.
 
152
 
 
153
Input device handling
 
154
 
 
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'',
 
160
 
 
161
There are some options as to how the front-end X server gets its core input
 
162
devices:
 
163
 
 
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
 
178
    simple.
 
179
 
 
180
    The following options are available for implementing local input devices:
 
181
 
 
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.
 
192
 
 
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
 
200
        implementation.
 
201
 
 
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.
 
207
 
 
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.
 
218
 
 
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
 
226
    devices.
 
227
 
 
228
 4. Other options were initially explored, but they were all partial subsets of
 
229
    the options listed above and, hence, are irrelevant.
 
230
 
 
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.
 
234
 
 
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.
 
239
 
 
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
 
246
available):
 
247
 
 
248
 1. A "dummy" device drive that never generates events.
 
249
 
 
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):
 
257
 
 
258
      ● Linux keyboard
 
259
 
 
260
      ● Linux serial mouse (MS)
 
261
 
 
262
      ● Linux PS/2 mouse
 
263
 
 
264
      ● USB keyboard
 
265
 
 
266
      ● USB mouse
 
267
 
 
268
      ● USB generic device (e.g., joystick, gamepad, etc.)
 
269
 
 
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.
 
274
 
 
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.
 
282
 
 
283
Output device handling
 
284
 
 
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.
 
288
 
 
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
 
294
screens.
 
295
 
 
296
Initialization
 
297
 
 
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
 
310
implementation.
 
311
 
 
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.
 
317
 
 
318
Handling rendering requests
 
319
 
 
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:
 
323
 
 
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.
 
330
 
 
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.
 
335
 
 
336
    The initial DMX implementation used a shadow framebuffer by default.
 
337
 
 
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.
 
346
 
 
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.
 
354
 
 
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
 
359
    appendix).
 
360
 
 
361
Status: Both the shadow framebuffer and Xnest-style code is complete.
 
362
 
 
363
Optimizing DMX
 
364
 
 
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.
 
368
 
 
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).
 
378
 
 
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.
 
387
 
 
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.
 
394
 
 
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.
 
401
 
 
402
Other potential optimizations will be determined from the performance analysis.
 
403
 
 
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
 
417
solution.
 
418
 
 
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.
 
422
 
 
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.
 
427
 
 
428
DMX X extension support
 
429
 
 
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.
 
439
 
 
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:
 
444
 
 
445
 1. Screen information (clipping rectangle for each screen relative to the
 
446
    virtual screen)
 
447
 
 
448
 2. Window information (window IDs and clipping information for each back-end
 
449
    window that corresponds to each DMX window)
 
450
 
 
451
 3. Input device information (mappings from DMX device IDs to back-end device
 
452
    IDs)
 
453
 
 
454
 4. Force window creation (so that a client can override the server-side lazy
 
455
    window creation optimization)
 
456
 
 
457
 5. Reconfiguration (so that a client can request that a screen position be
 
458
    changed)
 
459
 
 
460
 6. Addition and removal of back-end servers and back-end and console inputs.
 
461
 
 
462
Common X extension support
 
463
 
 
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.
 
471
 
 
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.
 
477
 
 
478
Support for the XTest extension was added during the first development phase.
 
479
 
 
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.
 
485
 
 
486
OpenGL support
 
487
 
 
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.
 
492
 
 
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.
 
503
 
 
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
 
507
be implemented.
 
508
 
 
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.
 
514
 
 
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
 
520
    support.
 
521
 
 
522
These, and other, options will be investigated in this phase of the work.
 
523
 
 
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.
 
527
 
 
528
Status: OpenGL support by the glxProxy extension was implemented by SGI and has
 
529
been integrated into the DMX code base.
 
530
 
 
531
Current issues
 
532
 
 
533
In this sections the current issues are outlined that require further
 
534
investigation.
 
535
 
 
536
Fonts
 
537
 
 
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.
 
545
 
 
546
Zero width rendering primitives
 
547
 
 
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.
 
553
 
 
554
Output scaling
 
555
 
 
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.
 
563
 
 
564
Per-screen colormaps
 
565
 
 
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.
 
573
 
 
574
A. Appendix
 
575
 
616
576
Background
617
577
 
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.
623
 
 
624
 
  Core input device handling
625
 
 
626
 
   The following is a description of how core input devices are handled by an
627
 
   X server.
628
 
 
629
 
    InitInput()
630
 
 
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().
638
 
 
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():
642
 
 
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      
647
 
                    input device.                                             
648
 
 
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).
654
 
 
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.
659
 
 
660
 
   miRegisterPointerDevice() This MI function registers the core pointer's    
661
 
                             input handle with with the miPointer code.       
662
 
 
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():
669
 
 
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.                               
673
 
 
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
677
 
   below.)
678
 
 
679
 
    InitAndStartDevices()
680
 
 
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.
690
 
 
691
 
   Each registered device is initialized by calling its callback
692
 
   (dev->deviceProc) with the DEVICE_INIT argument:
693
 
 
694
 
   (*dev->deviceProc)(dev, This function initializes the device structs with  
695
 
   DEVICE_INIT)            core information relevant to the device.           
696
 
                                                                              
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       
703
 
                           buffer size.                                       
704
 
                                                                              
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).                              
712
 
 
713
 
   Each initialized device is enabled by calling EnableDevice():
714
 
 
715
 
   EnableDevice() EnableDevice() calls the device callback with DEVICE_ON:    
716
 
                                                                              
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     
722
 
                                          valid input source.                 
723
 
                                                                              
724
 
                  EnableDevice() then adds the device handle to the X         
725
 
                  server's global list of enabled devices.                    
726
 
 
727
 
   InitAndStartDevices() then verifies that a valid core keyboard and pointer
728
 
   has been initialized and enabled. It returns failure if either are
729
 
   missing.
730
 
 
731
 
    devReadInput()
732
 
 
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).
743
 
 
744
 
   Events are queued by calling mieqEnqueue():
745
 
 
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.           
748
 
 
749
 
   The cursor position should be updated when motion events are enqueued, by
750
 
   calling either miPointerAbsoluteCursor() or miPointerDeltaCursor():
751
 
 
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.                
756
 
 
757
 
    ProcessInputEvents()
758
 
 
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.
763
 
 
764
 
   Enqueued events are processed by mieqProcessInputEvents() and passed to
765
 
   the DIX layer for transmission to clients:
766
 
 
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.                     
777
 
 
778
 
    DisableDevice()
779
 
 
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
787
 
   devices.
788
 
 
789
 
   DisableDevice() calls the device's callback function with DEVICE_OFF:
790
 
 
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  
795
 
                                       input source.                          
796
 
 
797
 
   DisableDevice() then removes the device handle from the X server's global
798
 
   list of enabled devices.
799
 
 
800
 
    CloseDevice()
801
 
 
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.
807
 
 
808
 
   CloseDevice() calls the device's callback function with DEVICE_CLOSE:
809
 
 
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.                  
816
 
 
817
 
   CloseDevice() then frees the data structures that were allocated for the
818
 
   device when it was registered/initialized.
819
 
 
820
 
    LegalModifier()
821
 
 
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.
825
 
 
826
 
  Output handling
827
 
 
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.
830
 
 
831
 
    InitOutput()
832
 
 
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.
839
 
 
840
 
   The primary tasks for this function are outlined below:
841
 
 
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.
852
 
 
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.
859
 
 
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.
864
 
 
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.
871
 
 
872
 
   Once these tasks are complete, the valid screens are known and each of
873
 
   these screens can be initialized by calling AddScreen().
874
 
 
875
 
    AddScreen()
876
 
 
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
880
 
   as arguments.
881
 
 
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
888
 
   fails.
889
 
 
890
 
    ScreenInit()
891
 
 
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).
896
 
 
897
 
   The screen init function usually calls several functions to perform
898
 
   certain screen initialization functions. They are described below:
899
 
 
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.                   
905
 
                                                                              
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  
913
 
                              SaveScreen().                                   
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       
923
 
                              pointers.                                       
924
 
 
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.
929
 
 
930
 
    CloseScreen()
931
 
 
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.
936
 
 
937
 
    GC operations
938
 
 
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
946
 
   mapped frame buffer.
947
 
 
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.
957
 
 
958
 
   Note that some pointers to functions that draw to the screen are stored in
959
 
   the Screen structure. They include GetImage(), GetSpans(), CopyWindow()
960
 
   and RestoreAreas().
961
 
 
962
 
    Xnest
963
 
 
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.
970
 
 
971
 
   The Xnest server implements all of the standard input and output
972
 
   initialization steps outlined above.
973
 
 
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.             
982
 
                                                                              
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 
987
 
                 its screens.                                                 
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    
1013
 
                 BLT operations.                                              
1014
 
                                                                              
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.               
1020
 
                                                                              
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 
1030
 
                 X application.                                               
1031
 
 
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.
1036
 
 
1037
 
    Shadow framebuffer
1038
 
 
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.
1045
 
 
1046
 
   There are two main entry points to the shadow framebuffer code:
1047
 
 
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 
1063
 
                              the VGA aperture).                              
1064
 
 
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.
1069
 
 
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.
1073
 
 
1074
 
  Xinerama
1075
 
 
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
1085
 
   version.
1086
 
 
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.
1092
 
 
1093
 
   The following is a code-level description of how Xinerama functions.
1094
 
 
1095
 
   Note: Because the Xinerama extension was originally called the PanoramiX
1096
 
   extension, many of the Xinerama functions still have the PanoramiX prefix.
1097
 
 
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.      
1106
 
                                                                              
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.      
1112
 
                                                                              
1113
 
                                    The Xinerama extension is registered by   
1114
 
                                    calling AddExtension().                   
1115
 
                                                                              
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   
1127
 
                                    colormaps.                                
1128
 
                                                                              
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).                      
1139
 
                                                                              
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     
1157
 
                                    layer.                                    
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.              
1165
 
                                                                              
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.    
1189
 
                                                                              
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.               
1202
 
                                                                              
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    
1213
 
                                    the end of                                
1214
 
                                    PanoramiXCreateConnectionBlock().         
1215
 
 
1216
 
    Xinerama-specific changes to the DIX code
1217
 
 
1218
 
   There are a few types of Xinerama-specific changes within the DIX code.
1219
 
   The main ones are described here.
1220
 
 
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.
1225
 
 
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.
1230
 
 
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.
1235
 
 
1236
 
    Xinerama-specific changes to the MI code
1237
 
 
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.
1240
 
 
1241
 
    Intercepted DIX core requests
1242
 
 
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
 
582
interest only.
 
583
 
 
584
Core input device handling
 
585
 
 
586
The following is a description of how core input devices are handled by an X
 
587
server.
 
588
 
 
589
InitInput()
 
590
 
 
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().
 
598
 
 
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
 
601
AddInputDevice():
 
602
 
 
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.
 
607
 
 
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()
 
612
(see below).
 
613
 
 
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.
 
618
 
 
619
miRegisterPointerDevice This MI function registers the core pointer's input
 
620
()                      handle with with the miPointer code.
 
621
 
 
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():
 
628
 
 
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
 
631
         core devices.
 
632
 
 
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.)
 
636
 
 
637
InitAndStartDevices()
 
638
 
 
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
 
647
with a fatal error.
 
648
 
 
649
Each registered device is initialized by calling its callback (dev->deviceProc)
 
650
with the DEVICE_INIT argument:
 
651
 
 
652
              This function initializes the device structs with core
 
653
              information relevant to the device.
 
654
 
 
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.
 
660
DEVICE_INIT)
 
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).
 
666
 
 
667
Each initialized device is enabled by calling EnableDevice():
 
668
 
 
669
             EnableDevice() calls the device callback with DEVICE_ON:
 
670
 
 
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.
 
675
 
 
676
             EnableDevice() then adds the device handle to the X server's
 
677
             global list of enabled devices.
 
678
 
 
679
InitAndStartDevices() then verifies that a valid core keyboard and pointer has
 
680
been initialized and enabled. It returns failure if either are missing.
 
681
 
 
682
devReadInput()
 
683
 
 
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
 
693
handling).
 
694
 
 
695
Events are queued by calling mieqEnqueue():
 
696
 
 
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.
 
699
 
 
700
The cursor position should be updated when motion events are enqueued, by
 
701
calling either miPointerAbsoluteCursor() or miPointerDeltaCursor():
 
702
 
 
703
miPointerAbsoluteCursor This MI function is used to move the cursor to the
 
704
()                      absolute coordinates provided.
 
705
 
 
706
miPointerDeltaCursor()  This MI function is used to move the cursor relative to
 
707
                        its current position.
 
708
 
 
709
ProcessInputEvents()
 
710
 
 
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.
 
715
 
 
716
Enqueued events are processed by mieqProcessInputEvents() and passed to the DIX
 
717
layer for transmission to clients:
 
718
 
 
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.
 
724
 
 
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
 
728
                       configurations.
 
729
 
 
730
DisableDevice()
 
731
 
 
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.
 
739
 
 
740
DisableDevice() calls the device's callback function with DEVICE_OFF:
 
741
 
 
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.
 
745
 
 
746
DisableDevice() then removes the device handle from the X server's global list
 
747
of enabled devices.
 
748
 
 
749
CloseDevice()
 
750
 
 
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.
 
756
 
 
757
CloseDevice() calls the device's callback function with DEVICE_CLOSE:
 
758
 
 
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
 
763
               are freed here.
 
764
 
 
765
CloseDevice() then frees the data structures that were allocated for the device
 
766
when it was registered/initialized.
 
767
 
 
768
LegalModifier()
 
769
 
 
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.
 
773
 
 
774
Output handling
 
775
 
 
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.
 
778
 
 
779
InitOutput()
 
780
 
 
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.
 
787
 
 
788
The primary tasks for this function are outlined below:
 
789
 
 
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.
 
800
 
 
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[]
 
806
    structure.
 
807
 
 
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.
 
812
 
 
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.
 
818
 
 
819
Once these tasks are complete, the valid screens are known and each of these
 
820
screens can be initialized by calling AddScreen().
 
821
 
 
822
AddScreen()
 
823
 
 
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.
 
827
 
 
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.
 
834
 
 
835
ScreenInit()
 
836
 
 
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
 
840
values).
 
841
 
 
842
The screen init function usually calls several functions to perform certain
 
843
screen initialization functions. They are described below:
 
844
 
 
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
 
849
                         handle.
 
850
 
 
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
 
857
                         SaveScreen().
 
858
 
 
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.
 
862
 
 
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
 
867
                         function pointers.
 
868
 
 
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.
 
873
 
 
874
CloseScreen()
 
875
 
 
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.
 
880
 
 
881
GC operations
 
882
 
 
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.
 
890
 
 
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.
 
899
 
 
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
 
902
RestoreAreas().
 
903
 
 
904
Xnest
 
905
 
 
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
 
911
requests.
 
912
 
 
913
The Xnest server implements all of the standard input and output initialization
 
914
steps outlined above.
 
915
 
 
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.
 
923
 
 
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.
 
928
 
 
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
 
936
            is attached.
 
937
 
 
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.
 
942
 
 
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.
 
954
 
 
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.
 
960
 
 
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
 
969
            the X application.
 
970
 
 
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.
 
975
 
 
976
Shadow framebuffer
 
977
 
 
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.
 
984
 
 
985
There are two main entry points to the shadow framebuffer code:
 
986
 
 
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.
 
991
 
 
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
 
999
              aperture).
 
1000
 
 
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.
 
1005
 
 
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.
 
1009
 
 
1010
Xinerama
 
1011
 
 
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.
 
1021
 
 
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.
 
1026
 
 
1027
The following is a code-level description of how Xinerama functions.
 
1028
 
 
1029
Note: Because the Xinerama extension was originally called the PanoramiX
 
1030
extension, many of the Xinerama functions still have the PanoramiX prefix.
 
1031
 
 
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
 
1038
                               been initialized.
 
1039
 
 
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
 
1044
                               anything else.
 
1045
 
 
1046
                               The Xinerama extension is registered by calling
 
1047
                               AddExtension().
 
1048
 
 
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.
 
1059
 
 
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).
 
1068
 
 
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
 
1084
                               layer.
 
1085
 
 
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
 
1091
                               initialized.
 
1092
 
 
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
 
1102
                               entries.
 
1103
 
 
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.
 
1115
 
 
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.
 
1126
 
 
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().
 
1137
 
 
1138
Xinerama-specific changes to the DIX code
 
1139
 
 
1140
There are a few types of Xinerama-specific changes within the DIX code. The
 
1141
main ones are described here.
 
1142
 
 
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.
 
1147
 
 
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
 
1151
screen origins.
 
1152
 
 
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
 
1156
physical screens.
 
1157
 
 
1158
Xinerama-specific changes to the MI code
 
1159
 
 
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.
 
1162
 
 
1163
Intercepted DIX core requests
 
1164
 
 
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
 
1175
functions.
1254
1176
 
1255
1177
Development Results
1256
1178
 
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.
1259
 
 
1260
 
  Phase I
1261
 
 
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.
1265
 
 
1266
 
    Scope
1267
 
 
1268
 
   The goal of Phase I is to provide fundamental functionality that can act
1269
 
   as a foundation for ongoing work:
1270
 
 
1271
 
    1. Develop the proxy X server
1272
 
 
1273
 
          o The proxy X server will operate on the X11 protocol and relay
1274
 
            requests as necessary to correctly perform the request.
1275
 
 
1276
 
          o Work will be based on the existing work for Xinerama and Xnest.
1277
 
 
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.
1281
 
 
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.
1285
 
 
1286
 
    2. Develop graphical configuration tool
1287
 
 
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.
1292
 
 
1293
 
    3. Pass the X Test Suite
1294
 
 
1295
 
          o The X Test Suite covers the basic X11 operations. All tests known
1296
 
            to succeed must correctly operate in the distributed X
1297
 
            environment.
1298
 
 
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
1303
 
   tree (e.g., Xt).
1304
 
 
1305
 
    Results
1306
 
 
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.
1314
 
 
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.
1319
 
 
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
1327
 
   vdltodmx utility.
1328
 
 
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.
1336
 
 
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.
1341
 
 
1342
 
    X Test Suite
1343
 
 
1344
 
      Introduction
1345
 
 
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.
1351
 
 
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.
1356
 
 
1357
 
      Expected Failures for a Single Head
1358
 
 
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:
1362
 
 
1363
 
   XDrawArc: Tests 42, 63, 66, 73
1364
 
   XDrawArcs: Tests 45, 66, 69, 76
1365
 
                 
1366
 
 
1367
 
   The following failures occur because of the high-level X server
1368
 
   implementation:
1369
 
 
1370
 
   XLoadQueryFont: Test 1
1371
 
   XListFontsWithInfo: Tests 3, 4
1372
 
   XQueryFont: Tests 1, 2
1373
 
                 
1374
 
 
1375
 
   The following test fails when running the X server as root under Linux
1376
 
   because of the way directory modes are interpreted:
1377
 
 
1378
 
   XWriteBitmapFile: Test 3
1379
 
                 
1380
 
 
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.
1385
 
 
1386
 
      Expected Failures for Xinerama
1387
 
 
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.
1393
 
 
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
1396
 
   Phase I.
1397
 
 
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:
1405
 
 
1406
 
   These failures were noted with multiple Xinerama configurations:
1407
 
 
1408
 
   XCopyPlane: Tests 13, 22, 31 (well-known Xinerama implementation issue)
1409
 
   XSetFontPath: Test 4
1410
 
   XGetDefault: Test 5
1411
 
   XMatchVisualInfo: Test 1
1412
 
                 
1413
 
 
1414
 
   These failures were noted only when using one dual-head video card with a
1415
 
   4.2.99.x XFree86 server:
1416
 
 
1417
 
   XListPixmapFormats: Test 1
1418
 
   XDrawRectangles: Test 45
1419
 
                 
1420
 
 
1421
 
   These failures were noted only when using two video cards from different
1422
 
   vendors with a 4.1.99.x XFree86 server:
1423
 
 
1424
 
   XChangeWindowAttributes: Test 32
1425
 
   XCreateWindow: Test 30
1426
 
   XDrawLine: Test 22
1427
 
   XFillArc: Test 22
1428
 
   XChangeKeyboardControl: Tests 9, 10
1429
 
   XRebindKeysym: Test 1
1430
 
                 
1431
 
 
1432
 
      Additional Failures from Xdmx
1433
 
 
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
1439
 
   summary:
1440
 
 
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)
1449
 
                   
1450
 
 
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
1454
 
   CVS repository.
1455
 
 
1456
 
      Summary and Future Work
1457
 
 
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.
1463
 
 
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.
1468
 
 
1469
 
    Fonts
1470
 
 
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:
1476
 
 
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
1479
 
       servers via TCP.
1480
 
 
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.
1484
 
 
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
1487
 
   machine.
1488
 
 
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.
1495
 
 
1496
 
    Performance
1497
 
 
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.
1502
 
 
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.
1506
 
 
1507
 
    2. Sending drawing requests to only the screens that they overlap should
1508
 
       improve performance.
1509
 
 
1510
 
    Pixmaps
1511
 
 
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.
1520
 
 
1521
 
  Phase II
1522
 
 
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.
1526
 
 
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.
1534
 
 
1535
 
    Moving from XFree86 4.1.99.1 to 4.2.0.0
1536
 
 
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:
1541
 
 
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)
1550
 
 
1551
 
   And the following tests were noted to be more than 10% slower:
1552
 
 
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)
1559
 
 
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.
1563
 
 
1564
 
    Global changes
1565
 
 
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:
1569
 
 
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)
1578
 
 
1579
 
   The following tests were noted to be more than 10% slower:
1580
 
 
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)
1587
 
 
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
1591
 
   performance.
1592
 
 
1593
 
    XSync() Batching
1594
 
 
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.
1605
 
 
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.
1609
 
 
1610
 
   The following tests were noted to be more than 10% slower with XSync()
1611
 
   batching on:
1612
 
 
1613
 
 0.88   500x500 tiled rectangle (161x145 tile)
1614
 
 0.89   Copy 500x500 from window to window
1615
 
 
1616
 
    Offscreen Optimization
1617
 
 
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
1628
 
   increases.
1629
 
 
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:
1633
 
 
1634
 
 0.88   Hide/expose window via popup (4 kids)
1635
 
 0.89   Resize unmapped window (75 kids)
1636
 
 
1637
 
    Lazy Window Creation Optimization
1638
 
 
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.
1645
 
 
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.
1659
 
 
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.
1666
 
 
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.
1674
 
 
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
1677
 
   servers increases.
1678
 
 
1679
 
   This optimization improved the following x11perf tests by more than 10%:
1680
 
 
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)
1685
 
 
1686
 
    Subdividing Rendering Primitives
1687
 
 
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.
1696
 
 
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.
1702
 
 
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.
1707
 
 
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.
1711
 
 
1712
 
   This optimization improved the following x11perf tests by more than 10%:
1713
 
 
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)
1723
 
 
1724
 
   The following test was noted to be more than 10% slower with this
1725
 
   optimization:
1726
 
 
1727
 
 0.88   10-pixel fill chord partial circle
1728
 
 
1729
 
    Summary of x11perf Data
1730
 
 
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
1738
 
   tests.)
1739
 
 
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.
1743
 
 
1744
 
 
1745
 
 1: XSync() batching only
1746
 
 2: Off screen optimizations only
1747
 
 3: Window optimizations only
1748
 
 4: Subdivprims only
1749
 
 5: All optimizations
1750
 
 
1751
 
     1     2    3    4      5 Operation
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)
2079
 
 
2080
 
    Profiling with OProfile
2081
 
 
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
2089
 
   individually.
2090
 
 
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
2096
 
   numbers.
2097
 
 
2098
 
    X Test Suite
2099
 
 
2100
 
   The X Test Suite was run on the fully optimized DMX server using the
2101
 
   configuration described above. The following failures were noted:
2102
 
 
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]
2111
 
 
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
2117
 
     implementation bug.
2118
 
 
2119
 
  Phase III
2120
 
 
2121
 
   During the third phase of development, support was provided for the
2122
 
   following extensions: SHAPE, RENDER, XKEYBOARD, XInput.
2123
 
 
2124
 
    SHAPE
2125
 
 
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
2128
 
   as expected.
2129
 
 
2130
 
    RENDER
2131
 
 
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.
2141
 
 
2142
 
    XKEYBOARD
2143
 
 
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
2151
 
   available.
2152
 
 
2153
 
    XInput
2154
 
 
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.
2161
 
 
2162
 
   Currently, back-end extension devices are not available as Xdmx extension
2163
 
   devices, but this limitation should be removed in the future.
2164
 
 
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
2170
 
   drivers.
2171
 
 
2172
 
    DPMS
2173
 
 
2174
 
   The DPMS extension is exported but does not do anything at this time.
2175
 
 
2176
 
    Other Extensions
2177
 
 
2178
 
   The LBX, SECURITY, XC-APPGROUP, and XFree86-Bigfont extensions do not
2179
 
   require any special Xdmx support and have been exported.
2180
 
 
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
2187
 
   Phase III.
2188
 
 
2189
 
  Phase IV
2190
 
 
2191
 
    Moving to XFree86 4.3.0
2192
 
 
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
2195
 
   using this tree.
2196
 
 
2197
 
    Extensions
2198
 
 
2199
 
      XC-MISC (supported)
2200
 
 
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.
2205
 
 
2206
 
      Extended-Visual-Information (supported)
2207
 
 
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.
2214
 
 
2215
 
      RES (supported)
2216
 
 
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.
2222
 
 
2223
 
      BIG-REQUESTS (supported)
2224
 
 
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.
2228
 
 
2229
 
      XSYNC (supported)
2230
 
 
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.
2235
 
 
2236
 
      XTEST, RECORD, DEC-XTRAP (supported) and XTestExtension1 (not supported)
2237
 
 
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.
2245
 
 
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.
2253
 
 
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.
2256
 
 
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
2262
 
   important).
2263
 
 
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:
2267
 
 
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.                            
2274
 
 
2275
 
      MIT-MISC (not supported)
2276
 
 
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.
2282
 
 
2283
 
      SCREENSAVER (not supported)
2284
 
 
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.
2293
 
 
2294
 
      GLX (supported)
2295
 
 
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.
2302
 
 
2303
 
      RENDER (supported)
2304
 
 
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.
2313
 
 
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.
2319
 
 
2320
 
      Summary
2321
 
 
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.
2326
 
 
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,
2330
 
   and XVideo.
2331
 
 
2332
 
    Additional Testing with the X Test Suite
2333
 
 
2334
 
      XFree86 without XTEST
2335
 
 
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
2340
 
   tests:
2341
 
 
2342
 
   XListPixmapFormats: Test 1
2343
 
   XChangeKeyboardControl: Tests 9, 10
2344
 
   XGetDefault: Test 5
2345
 
   XRebindKeysym: Test 1
2346
 
 
2347
 
      XFree86 with XTEST
2348
 
 
2349
 
   When using the XTEST extension, the XFree86 4.3.0 server reported the
2350
 
   following errors:
2351
 
 
2352
 
   XListPixmapFormats: Test 1
2353
 
   XChangeKeyboardControl: Tests 9, 10
2354
 
   XGetDefault: Test 5
2355
 
   XRebindKeysym: Test 1
2356
 
 
2357
 
   XAllowEvents: Tests 20, 21, 24
2358
 
   XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
2359
 
   XGrabKey: Test 8
2360
 
   XSetPointerMapping: Test 3
2361
 
   XUngrabButton: Test 4
2362
 
 
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.
2367
 
 
2368
 
      Xdmx with XTEST, without Xinerama, without GLX
2369
 
 
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):
2373
 
 
2374
 
   XListPixmapFormats: Test 1
2375
 
   XChangeKeyboardControl: Tests 9, 10
2376
 
   XRebindKeysym: Test 1
2377
 
 
2378
 
   XAllowEvents: Tests  20, 21, 24
2379
 
   XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
2380
 
   XGrabKey: Test 8
2381
 
   XSetPointerMapping: Test 3
2382
 
   XUngrabButton: Test 4
2383
 
 
2384
 
      Xdmx with XTEST, with Xinerama, without GLX
2385
 
 
2386
 
   With Xinerama, using the XTEST extension, the following errors were
2387
 
   reported from Xdmx:
2388
 
 
2389
 
   XListPixmapFormats: Test 1
2390
 
   XChangeKeyboardControl: Tests 9, 10
2391
 
   XRebindKeysym: Test 1
2392
 
 
2393
 
   XAllowEvents: Tests 20, 21, 24
2394
 
   XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
2395
 
   XGrabKey: Test 8
2396
 
   XSetPointerMapping: Test 3
2397
 
   XUngrabButton: Test 4
2398
 
 
2399
 
   XCopyPlane: Tests 13, 22, 31 (well-known XTEST/Xinerama interaction issue)
2400
 
   XDrawLine: Test 67
2401
 
   XDrawLines: Test 91
2402
 
   XDrawSegments: Test 68
2403
 
 
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.
2410
 
 
2411
 
      Xdmx with XTEST, with Xinerama, with GLX
2412
 
 
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):
2416
 
 
2417
 
   XListPixmapFormats: Test 1
2418
 
   XChangeKeyboardControl: Tests 9, 10
2419
 
   XRebindKeysym: Test 1
2420
 
 
2421
 
   XAllowEvents: Tests 20, 21, 24
2422
 
   XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
2423
 
   XGrabKey: Test 8
2424
 
   XSetPointerMapping: Test 3
2425
 
   XUngrabButton: Test 4
2426
 
 
2427
 
   XClearArea: Test 8
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
2431
 
   XDrawLine: Test 67
2432
 
   XDrawSegments: Test 68
2433
 
 
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
2442
 
   boundary.
2443
 
 
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:
2446
 
 
2447
 
   XClearArea: Test 8
2448
 
   XCopyArea: Test 4, 5, 11, 14, 17, 23, 25, 27, 30
2449
 
   XCopyPlane: Test 6, 7, 10, 19, 22, 31
2450
 
 
2451
 
      Conclusion
2452
 
 
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.)
2458
 
 
2459
 
    Dynamic Reconfiguration
2460
 
 
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.
2469
 
 
2470
 
      Dynamic reconfiguration extension
2471
 
 
2472
 
   The application interface to DMX's dynamic reconfiguration is through a
2473
 
   function in the DMX extension library:
2474
 
 
2475
 
 Bool DMXReconfigureScreen(Display *dpy, int screen, int x, int y)
2476
 
 
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.
2480
 
 
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.
2486
 
 
2487
 
      Bounding box
2488
 
 
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
2492
 
   server.
2493
 
 
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.
2502
 
 
2503
 
   This fixed bounding box limitation will be addressed in a future
2504
 
   development phase.
2505
 
 
2506
 
      Sample applications
2507
 
 
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.
2514
 
 
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.
2521
 
 
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.
2525
 
 
2526
 
      Additional notes
2527
 
 
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).
2533
 
 
2534
 
    Doxygen documentation
2535
 
 
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.
2541
 
 
2542
 
    Valgrind
2543
 
 
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:
2547
 
 
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.
2552
 
 
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
2557
 
       referred to SGI.
2558
 
 
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
2567
 
       XLoadQueryFont.
2568
 
 
2569
 
    RATS
2570
 
 
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
2578
 
   are as follows:
2579
 
 
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.
2584
 
 
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.
2588
 
 
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.
 
1181
 
 
1182
Phase I
 
1183
 
 
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.
 
1187
 
 
1188
Scope
 
1189
 
 
1190
The goal of Phase I is to provide fundamental functionality that can act as a
 
1191
foundation for ongoing work:
 
1192
 
 
1193
 1. Develop the proxy X server
 
1194
 
 
1195
      ● The proxy X server will operate on the X11 protocol and relay requests
 
1196
        as necessary to correctly perform the request.
 
1197
 
 
1198
      ● Work will be based on the existing work for Xinerama and Xnest.
 
1199
 
 
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.
 
1203
 
 
1204
      ● The multiple screen layout (including support for overlapping screens)
 
1205
        will be user configurable via a configuration file or through the
 
1206
        configuration tool.
 
1207
 
 
1208
 2. Develop graphical configuration tool
 
1209
 
 
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.
 
1213
 
 
1214
 3. Pass the X Test Suite
 
1215
 
 
1216
      ● The X Test Suite covers the basic X11 operations. All tests known to
 
1217
        succeed must correctly operate in the distributed X environment.
 
1218
 
 
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).
 
1223
 
 
1224
Results
 
1225
 
 
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.
 
1232
 
 
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.
 
1237
 
 
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.
 
1245
 
 
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
 
1252
file.
 
1253
 
 
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
 
1257
below.
 
1258
 
 
1259
X Test Suite
 
1260
 
 
1261
Introduction
 
1262
 
 
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.
 
1267
 
 
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
 
1271
test results.
 
1272
 
 
1273
Expected Failures for a Single Head
 
1274
 
 
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:
 
1278
 
 
1279
 
 
1280
XDrawArc: Tests 42, 63, 66, 73
 
1281
XDrawArcs: Tests 45, 66, 69, 76
 
1282
 
 
1283
 
 
1284
The following failures occur because of the high-level X server implementation:
 
1285
 
 
1286
 
 
1287
XLoadQueryFont: Test 1
 
1288
XListFontsWithInfo: Tests 3, 4
 
1289
XQueryFont: Tests 1, 2
 
1290
 
 
1291
 
 
1292
The following test fails when running the X server as root under Linux because
 
1293
of the way directory modes are interpreted:
 
1294
 
 
1295
 
 
1296
XWriteBitmapFile: Test 3
 
1297
 
 
1298
 
 
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
 
1302
testing until then.
 
1303
 
 
1304
Expected Failures for Xinerama
 
1305
 
 
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.
 
1310
 
 
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.
 
1313
 
 
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
 
1320
itself:
 
1321
 
 
1322
These failures were noted with multiple Xinerama configurations:
 
1323
 
 
1324
 
 
1325
XCopyPlane: Tests 13, 22, 31 (well-known Xinerama implementation issue)
 
1326
XSetFontPath: Test 4
 
1327
XGetDefault: Test 5
 
1328
XMatchVisualInfo: Test 1
 
1329
 
 
1330
 
 
1331
These failures were noted only when using one dual-head video card with a
 
1332
4.2.99.x XFree86 server:
 
1333
 
 
1334
 
 
1335
XListPixmapFormats: Test 1
 
1336
XDrawRectangles: Test 45
 
1337
 
 
1338
 
 
1339
These failures were noted only when using two video cards from different
 
1340
vendors with a 4.1.99.x XFree86 server:
 
1341
 
 
1342
 
 
1343
XChangeWindowAttributes: Test 32
 
1344
XCreateWindow: Test 30
 
1345
XDrawLine: Test 22
 
1346
XFillArc: Test 22
 
1347
XChangeKeyboardControl: Tests 9, 10
 
1348
XRebindKeysym: Test 1
 
1349
 
 
1350
 
 
1351
Additional Failures from Xdmx
 
1352
 
 
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:
 
1358
 
 
1359
 
 
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)
 
1368
 
 
1369
 
 
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.
 
1373
 
 
1374
Summary and Future Work
 
1375
 
 
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.
 
1381
 
 
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
 
1385
of DMX.
 
1386
 
 
1387
Fonts
 
1388
 
 
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:
 
1394
 
 
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
 
1397
    TCP.
 
1398
 
 
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.
 
1402
 
 
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.
 
1405
 
 
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.
 
1412
 
 
1413
Performance
 
1414
 
 
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.
 
1419
 
 
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.
 
1423
 
 
1424
 2. Sending drawing requests to only the screens that they overlap should
 
1425
    improve performance.
 
1426
 
 
1427
Pixmaps
 
1428
 
 
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.
 
1437
 
 
1438
Phase II
 
1439
 
 
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.
 
1443
 
 
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.
 
1450
 
 
1451
Moving from XFree86 4.1.99.1 to 4.2.0.0
 
1452
 
 
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:
 
1457
 
 
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)
 
1466
 
 
1467
And the following tests were noted to be more than 10% slower:
 
1468
 
 
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)
 
1475
 
 
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.
 
1479
 
 
1480
Global changes
 
1481
 
 
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:
 
1485
 
 
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)
 
1494
 
 
1495
The following tests were noted to be more than 10% slower:
 
1496
 
 
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)
 
1503
 
 
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.
 
1507
 
 
1508
XSync() Batching
 
1509
 
 
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.
 
1519
 
 
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.
 
1523
 
 
1524
The following tests were noted to be more than 10% slower with XSync() batching
 
1525
on:
 
1526
 
 
1527
0.88   500x500 tiled rectangle (161x145 tile)
 
1528
0.89   Copy 500x500 from window to window
 
1529
 
 
1530
Offscreen Optimization
 
1531
 
 
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.
 
1542
 
 
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:
 
1546
 
 
1547
0.88   Hide/expose window via popup (4 kids)
 
1548
0.89   Resize unmapped window (75 kids)
 
1549
 
 
1550
Lazy Window Creation Optimization
 
1551
 
 
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.
 
1558
 
 
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.
 
1571
 
 
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.
 
1577
 
 
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.
 
1584
 
 
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
 
1587
increases.
 
1588
 
 
1589
This optimization improved the following x11perf tests by more than 10%:
 
1590
 
 
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)
 
1595
 
 
1596
Subdividing Rendering Primitives
 
1597
 
 
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.
 
1605
 
 
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.
 
1611
 
 
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.
 
1616
 
 
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
 
1619
servers increases.
 
1620
 
 
1621
This optimization improved the following x11perf tests by more than 10%:
 
1622
 
 
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)
 
1632
 
 
1633
The following test was noted to be more than 10% slower with this optimization:
 
1634
 
 
1635
0.88   10-pixel fill chord partial circle
 
1636
 
 
1637
Summary of x11perf Data
 
1638
 
 
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.)
 
1646
 
 
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.
 
1650
 
 
1651
 
 
1652
1: XSync() batching only
 
1653
2: Off screen optimizations only
 
1654
3: Window optimizations only
 
1655
4: Subdivprims only
 
1656
5: All optimizations
 
1657
 
 
1658
    1     2    3    4      5 Operation
 
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)
 
1986
 
 
1987
Profiling with OProfile
 
1988
 
 
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.
 
1996
 
 
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.
 
2002
 
 
2003
X Test Suite
 
2004
 
 
2005
The X Test Suite was run on the fully optimized DMX server using the
 
2006
configuration described above. The following failures were noted:
 
2007
 
 
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]
 
2016
 
 
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
 
2022
    implementation bug.
 
2023
 
 
2024
Phase III
 
2025
 
 
2026
During the third phase of development, support was provided for the following
 
2027
extensions: SHAPE, RENDER, XKEYBOARD, XInput.
 
2028
 
 
2029
SHAPE
 
2030
 
 
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.
 
2033
 
 
2034
RENDER
 
2035
 
 
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.
 
2044
 
 
2045
XKEYBOARD
 
2046
 
 
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.
 
2054
 
 
2055
XInput
 
2056
 
 
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
 
2062
device.
 
2063
 
 
2064
Currently, back-end extension devices are not available as Xdmx extension
 
2065
devices, but this limitation should be removed in the future.
 
2066
 
 
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.
 
2072
 
 
2073
DPMS
 
2074
 
 
2075
The DPMS extension is exported but does not do anything at this time.
 
2076
 
 
2077
Other Extensions
 
2078
 
 
2079
The LBX, SECURITY, XC-APPGROUP, and XFree86-Bigfont extensions do not require
 
2080
any special Xdmx support and have been exported.
 
2081
 
 
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.
 
2088
 
 
2089
Phase IV
 
2090
 
 
2091
Moving to XFree86 4.3.0
 
2092
 
 
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
 
2095
tree.
 
2096
 
 
2097
Extensions
 
2098
 
 
2099
XC-MISC (supported)
 
2100
 
 
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.
 
2105
 
 
2106
Extended-Visual-Information (supported)
 
2107
 
 
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.
 
2113
 
 
2114
RES (supported)
 
2115
 
 
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.
 
2120
 
 
2121
BIG-REQUESTS (supported)
 
2122
 
 
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.
 
2126
 
 
2127
XSYNC (supported)
 
2128
 
 
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.
 
2133
 
 
2134
XTEST, RECORD, DEC-XTRAP (supported) and XTestExtension1 (not supported)
 
2135
 
 
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.
 
2143
 
 
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.
 
2151
 
 
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.
 
2154
 
 
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).
 
2160
 
 
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:
 
2164
 
 
2165
XRECORD         Martha Zimet. Extending X For Recording. 8th Annual X Technical
 
2166
                Conference Boston, MA January 24-26, 1994.
 
2167
 
 
2168
DEC-XTRAP       Dick Annicchiarico, Robert Chesler, Alan Jamison. XTrap
 
2169
                Architecture. Digital Equipment Corporation, July 1991.
 
2170
 
 
2171
XTestExtension1 Larry Woestman. X11 Input Synthesis Extension Proposal. Hewlett
 
2172
                Packard, November 1991.
 
2173
 
 
2174
MIT-MISC (not supported)
 
2175
 
 
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
 
2180
support MIT-MISC.
 
2181
 
 
2182
SCREENSAVER (not supported)
 
2183
 
 
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.
 
2192
 
 
2193
GLX (supported)
 
2194
 
 
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.
 
2201
 
 
2202
RENDER (supported)
 
2203
 
 
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.
 
2211
 
 
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.
 
2217
 
 
2218
Summary
 
2219
 
 
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.
 
2224
 
 
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
 
2228
XVideo.
 
2229
 
 
2230
Additional Testing with the X Test Suite
 
2231
 
 
2232
XFree86 without XTEST
 
2233
 
 
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:
 
2238
 
 
2239
 
 
2240
XListPixmapFormats: Test 1
 
2241
XChangeKeyboardControl: Tests 9, 10
 
2242
XGetDefault: Test 5
 
2243
XRebindKeysym: Test 1
 
2244
 
 
2245
XFree86 with XTEST
 
2246
 
 
2247
When using the XTEST extension, the XFree86 4.3.0 server reported the following
 
2248
errors:
 
2249
 
 
2250
 
 
2251
XListPixmapFormats: Test 1
 
2252
XChangeKeyboardControl: Tests 9, 10
 
2253
XGetDefault: Test 5
 
2254
XRebindKeysym: Test 1
 
2255
 
 
2256
XAllowEvents: Tests 20, 21, 24
 
2257
XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
 
2258
XGrabKey: Test 8
 
2259
XSetPointerMapping: Test 3
 
2260
XUngrabButton: Test 4
 
2261
 
 
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
 
2265
Xinerama failures.
 
2266
 
 
2267
Xdmx with XTEST, without Xinerama, without GLX
 
2268
 
 
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):
 
2272
 
 
2273
 
 
2274
XListPixmapFormats: Test 1
 
2275
XChangeKeyboardControl: Tests 9, 10
 
2276
XRebindKeysym: Test 1
 
2277
 
 
2278
XAllowEvents: Tests  20, 21, 24
 
2279
XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
 
2280
XGrabKey: Test 8
 
2281
XSetPointerMapping: Test 3
 
2282
XUngrabButton: Test 4
 
2283
 
 
2284
Xdmx with XTEST, with Xinerama, without GLX
 
2285
 
 
2286
With Xinerama, using the XTEST extension, the following errors were reported
 
2287
from Xdmx:
 
2288
 
 
2289
 
 
2290
XListPixmapFormats: Test 1
 
2291
XChangeKeyboardControl: Tests 9, 10
 
2292
XRebindKeysym: Test 1
 
2293
 
 
2294
XAllowEvents: Tests 20, 21, 24
 
2295
XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
 
2296
XGrabKey: Test 8
 
2297
XSetPointerMapping: Test 3
 
2298
XUngrabButton: Test 4
 
2299
 
 
2300
XCopyPlane: Tests 13, 22, 31 (well-known XTEST/Xinerama interaction issue)
 
2301
XDrawLine: Test 67
 
2302
XDrawLines: Test 91
 
2303
XDrawSegments: Test 68
 
2304
 
 
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
 
2310
their cause.
 
2311
 
 
2312
Xdmx with XTEST, with Xinerama, with GLX
 
2313
 
 
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):
 
2317
 
 
2318
 
 
2319
XListPixmapFormats: Test 1
 
2320
XChangeKeyboardControl: Tests 9, 10
 
2321
XRebindKeysym: Test 1
 
2322
 
 
2323
XAllowEvents: Tests 20, 21, 24
 
2324
XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
 
2325
XGrabKey: Test 8
 
2326
XSetPointerMapping: Test 3
 
2327
XUngrabButton: Test 4
 
2328
 
 
2329
XClearArea: Test 8
 
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
 
2333
XDrawLine: Test 67
 
2334
XDrawSegments: Test 68
 
2335
 
 
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.
 
2344
 
 
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:
 
2347
 
 
2348
 
 
2349
XClearArea: Test 8
 
2350
XCopyArea: Test 4, 5, 11, 14, 17, 23, 25, 27, 30
 
2351
XCopyPlane: Test 6, 7, 10, 19, 22, 31
 
2352
 
 
2353
Conclusion
 
2354
 
 
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.)
 
2360
 
 
2361
Dynamic Reconfiguration
 
2362
 
 
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.
 
2371
 
 
2372
Dynamic reconfiguration extension
 
2373
 
 
2374
The application interface to DMX's dynamic reconfiguration is through a
 
2375
function in the DMX extension library:
 
2376
 
 
2377
Bool DMXReconfigureScreen(Display *dpy, int screen, int x, int y)
 
2378
 
 
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.
 
2382
 
 
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.
 
2388
 
 
2389
Bounding box
 
2390
 
 
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.
 
2394
 
 
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.
 
2403
 
 
2404
This fixed bounding box limitation will be addressed in a future development
 
2405
phase.
 
2406
 
 
2407
Sample applications
 
2408
 
 
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
 
2414
support in DMX.
 
2415
 
 
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
 
2421
Xdmx.
 
2422
 
 
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.
 
2426
 
 
2427
Additional notes
 
2428
 
 
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).
 
2434
 
 
2435
Doxygen documentation
 
2436
 
 
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
 
2441
browseable format.
 
2442
 
 
2443
Valgrind
 
2444
 
 
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:
 
2448
 
 
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.
 
2453
 
 
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.
 
2458
 
 
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.
 
2467
 
 
2468
RATS
 
2469
 
 
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:
 
2477
 
 
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.
 
2482
 
 
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.
 
2486
 
 
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).
 
2492