summaryrefslogtreecommitdiff
path: root/app/lbxproxy/design
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 14:09:43 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 14:09:43 +0000
commitf833ce79ae0da9b5ef4eb544909048189731091a (patch)
tree19449c1463c7ee2bdfc826a230e54e644db88166 /app/lbxproxy/design
parent0e5035729a2092ccc5045597199839f4a78326f2 (diff)
Importing from X.Org indiviual releases
Diffstat (limited to 'app/lbxproxy/design')
-rw-r--r--app/lbxproxy/design266
1 files changed, 266 insertions, 0 deletions
diff --git a/app/lbxproxy/design b/app/lbxproxy/design
new file mode 100644
index 000000000..c76a7da95
--- /dev/null
+++ b/app/lbxproxy/design
@@ -0,0 +1,266 @@
+ LBX design notes
+ ----------------
+
+Much of LBX is implemented as an extension. Some modifications have
+been made to the Xserver OS layer to support its requirements, but
+the only other impact LBX has on the core server are some hooks for
+supporting tags.
+
+Flow control
+
+ LBX multiplexes the data streams of all its clients into one, and then
+ splits them apart again when they are received. The X_LbxSwitch message
+ is used to tell each end which client is using the wire at the time.
+
+Swapping
+
+ Swapping is handled as with any X extension, with one caveat.
+ Since a proxy can be supporting clients with different byte orders,
+ and they all share the same wire, all length fields are converted
+ to be sent in the proxy byte order. This prevents any problems with
+ length computation that may occur when clients are switched.
+
+Tags
+
+ Tags are used to support large data items that are expected to be
+ queried multiple times. Such things as the keyboard map and font
+ metrics are often requested by multiple clients. Rather than send the
+ data each time, the first time the data is sent it includes a tag.
+ The proxy saves this data, so that subsequent requests can send
+ only the tag. The proxy then pulls up its local copy of the data
+ and sends it on to its clients.
+
+ To support this, the Xserver keeps track of what tags are known to
+ the proxy. The proxy can send InvalidateTag messages if it doesn't
+ store the tagged data. The server also sends InvalidateTag messages
+ when the data changes, to allow the proxy to clean out obsolete data.
+
+ If the server & proxy get out of sync, and the proxy receives a
+ tag which is cannot resolve, it can send a QueryTag message and the
+ server will respond with the requested data.
+
+ Property data makes special use of tags. A common use of properties
+ is for inter-client communication. If both clients use the proxy,
+ its wasteful to send the data to the server and then back, when
+ the server may never need it. X_LbxChangeProperty does the
+ same work as X_ChangeProperty, but it does not send the data.
+ X_LbxChangeProperty replies with a tag which points to the data.
+ If the property information is used locally, the server responds to
+ X_LbxGetProperty with a tag, and the property data need never be
+ sent to the server. If the server does require the data, it can
+ issue a QueryTag message. The proxy can also send the data on at
+ any time if it thinks its appropriate (ie, wire goes idle).
+
+ The heuristics of property handling can be complex. Because
+ X_LbxChangeProperty is a round-trip, it can take longer to use it
+ than X_ChangeProperty for some wires, especially if the amount of
+ property data is small. Using X_LbxChangeProperty can also be
+ a mistake for ICCCM properties, if the window manager is not a
+ proxy client.
+
+Tag caching
+
+ The proxy contains a tag caching system that allows it to store a
+ controlled amount of tag data. Limited proxy hosts may wish to use
+ small caches or none at all. When the cache becomes full, it will
+ throw out the oldest data (and send the appropriate InvalidateTag
+ message to the Xserver).
+
+ Currently two tag caches are used, one for properties and another
+ for other data types. This may want to be modified to separate
+ out font metrics.
+
+ All tagged data is stored in the proxy byte order.
+
+Short-circuiting
+
+ Short-circuiting is used to handle 'constant' data. This includes
+ atoms, colorname/RGB mappings, and AllocColor calls. Atoms and
+ colorname/RGB mappings stay constant for the life of the server.
+ AllocColor replies are constant for each colormap. Short-circuiting
+ replaces round-trip requests with one-way requests, and can sometimes
+ use one in place of many.
+
+ Atoms are used heavily for ICCCM communication. Once the proxy knows
+ the string<->atom mapping, it has no need to send the request on to
+ the server.
+
+ Colorname/RGB mappings are constant, so once the proxy sees the
+ response from X_LookupColor, it need not forward any subsequent
+ requests.
+
+ Clients often use the same color cells, so once a read-only color
+ allocation has occurred, the proxy knows what RGB values should
+ be returned to the client. The proxy doesn't need to forward any
+ AllocColor requests it can resolve, but it must tell the server to
+ modify the color cell's reference count. X_LbxIncrementPixel is
+ used to support this.
+
+ For all three classes of short-circuiting, the server must still
+ tell the server a request has occured, so that the request sequence
+ numbers stay in sync. This is done with X_LbxModifySequence.
+
+ Sequence numbers cause the major complication with short-circuiting.
+ X guarantees that any replies, events or errors generated by a
+ previous request will be sent before those of a later request.
+ This means that any requests that can be handled by the proxy must
+ have their reply sent after any previous events or errors.
+
+ There are 3 possible ways to support short-circuiting:
+
+ - fully correct protocol, which ensures that nothing can be out
+ of order
+ - mostly correct protocol, where only errors can be out of order
+ - poor protocol, where events & errors can be out of order.
+
+ A smart client or test suite could send a request it knows will
+ generate an event or error, followed by an InternAtom request,
+ and get the InternAtom reply before it gets the event.
+
+ Xlib hides this problem from most applications, so the 'poor'
+ protocol can be sufficient. For a fully safe environment, the proxy
+ can be compiled to use any of the three forms (or no short-circuiting
+ at all). In no case do we allow replies to come back out of order.
+ The proxy knows what can come back from all the core requests --
+ for any extensions it assumes the worst case and expects a reply.
+
+Reply matching
+
+ LBX needs to store information about certain requests to support both
+ tags and short-circuiting. To do this, it creates a Reply record for
+ each request that can return a reply. Most of these are only used
+ as place holders, but for special requests data is stashed in them
+ (eg, InternAtom needs to save the atom name, so it can store it with
+ the returned Atom.)
+
+ Using the core protocol and Xlib, there is usually only one
+ pending Reply record per client. One common exception is caused by
+ XGetWIndowAttributes(), which sends two roundtrip requests and then
+ collects the results from both.
+
+ Test suites and interfaces other than Xlib may not follow this
+ convention, and could result in a number of pending Reply records.
+
+ The worst case are extensions. If the proxy doesn't know about
+ them, it must assume the worst case, and create a Reply record for
+ each extension request. These cannot be cleaned out until data
+ comes back from the server (event, error or reply), which allows
+ the proxy to flush any Reply records with older sequence numbers.
+ This has the potential to eat a huge amount of proxy memory, if an
+ extension issues a huge number of one-way requests.
+
+Motion events
+
+ To prevent clogging the wire with MotionNotify events, the server and
+ proxy work together to minimize the number of events on the wire.
+ This is done with X_LbxAllowMotion. The proxy determines how many
+ events 'fill' the wire (currently hardcoded -- should be computed) and
+ 'allows' that many events. When the server generates a MotionEvent
+ for a proxy client, it decrements the allowed number, throwing away
+ any after the wire is full. When the proxy receives a MotionNotify,
+ it sends an X_LbxAllowMotion to the server.
+
+Delta cache
+
+ LBX takes advantage of the fact that an X message may be very similar
+ to one that has been previously sent. For example, a KeyPress event
+ may differ from a previous KeyPress event in just a few bytes. By
+ sending just the bytes that differ (or "deltas"), the number of bytes
+ sent over the wire can be substantially reduced. Delta compaction is
+ used on requests being sent by the proxy as well as on replies and
+ events being sent by the server.
+
+ Both the server and the proxy keep a cache of the N (currently
+ defaulted to 16) X messages sent and received. Only messages
+ smaller than a fixed maximum (currently defaulted to 64) are
+ saved in the delta cache.
+
+ Whenever the server has a message to send, and the message is of
+ appropriate length, the message is compared to any same-length messages
+ in its send cache. The message with the fewest number of differing
+ bytes is selected. If the number of differences is small enough and
+ the resulting X_LbxDelta message would not be longer than the original
+ message, the X_LbxDelta message is sent in place of the original.
+ The original message must also be place in the send cache. The proxy
+ uses the same algorithm when it has a message to send to the server.
+
+Compression
+ Before being passed down to the transport layer, all messages are
+ passed through a general purpose data compressor (currently only LZW is
+ supported). The LZW compressor is presented with a simple byte stream -
+ the X and LBX message boundaries are not apparent. The data is
+ broken up into fixed sized blocks. Each block is compressed, then a two
+ byte header is prepended, and then the entire packet is transmitted.
+ (NOTE: LBX is designed to allow other compression algorithms to be used
+ instead of LZW. However, there is no requirement that the packet format
+ used for LZW be used for implementations involving other compression
+ algorithms.) The LZW compressor also provides for the ability to transmit
+ data uncompressed. This is useful when the data has already been
+ compressed by some other means (eg. a bitmap may be compressed using a
+ FAX G4 encoding) and further compression would not be effective.
+
+ The LZW compressor attempts to buffer up enough raw data to fill out a
+ complete block before actually compressing the data. This improves
+ compression efficiency. However, the LZW buffers are always flushed
+ before the server/proxy goes to sleep to await more data.
+
+Master Client
+ When the initial X connection between the proxy and the server is
+ converted to LBX mode, the proxy itself becomes the "master" client.
+ New client requests and some tags related messages are sent in the
+ context of the master client.
+
+Server Grabs
+ The master client must be grab-proof because the server may need to
+ retrieve tagged data from the proxy at any time. Since the master client
+ is multiplexed onto the same connection as other clients, the other
+ clients effectively become grab-proof as well. While the server is
+ grabbed, messages for non-master clients can be buffered. However, it's
+ possible for some client to eat up a large amount of buffer space before
+ the server is ungrabbed. In order to counteract this, when the server
+ is grabbed, an X_LbxListenToOne message will be sent to the proxy. If
+ the client grabbing the server belongs to the proxy, then only master
+ client and grabbing client messages will be transmitted to the server.
+ If the grabbing client does not belong to the proxy, then only master
+ client messages will be transmitted. The server will transmit an
+ X_LbxListenToAll to the proxy when the server is ungrabbed.
+
+Graphics Re-encoding
+
+ The LBX proxy attempts to reencode X_PolyPoint, X_PolyLine, X_PolySegment,
+ X_PolyRectangle, X_PolyArc, X_FillPoly, X_PolyFillRectangle, and
+ X_PolyFillArc requests. If the request can be reencoded, it is
+ replaced by an equivalent LBX form of the request. The requests
+ are reencoded by attempting to reduce all 2-byte coordinate, length,
+ width and angle fields to 1 byte. Where applicable, the coordinate mode
+ is also converted to "previous" to improve the compressibility of the
+ resulting data.
+
+Data Flow
+
+ The LBX data stream goes through a number of layers, all of which
+ should be negotiable:
+
+ 0. client requests
+
+ 1. read by LBX proxy
+ 2. potential byte-swapping
+ 3. requests-specific processing and reencoding
+ 4. potential byte swapping
+ 5. delta replacement
+ 6. stream (LZW) compression
+
+ transport
+
+ 5. stream decompression
+ 4. delta substitution
+ 3. potential byte swapping
+ 2. re-encoding
+ 1. request processing
+
+ The reverse process occurs with X server replies/events/errors.
+
+
+--------
+$NCDXorg: @(#)design,v 1.4 1994/04/11 18:17:03 lemke Exp $
+$Xorg: design,v 1.3 2000/08/17 19:53:53 cpqbld Exp $