Add generic rootless layer documentation missed from last commit.
This commit is contained in:
		
							parent
							
								
									784e4d1cc0
								
							
						
					
					
						commit
						29012adb37
					
				|  | @ -0,0 +1,403 @@ | ||||||
|  |                             Generic Rootless Layer | ||||||
|  |                                  Version 1.0 | ||||||
|  |                                 July 13, 2004 | ||||||
|  | 
 | ||||||
|  |                                Torrey T. Lyons | ||||||
|  |                               torrey@xfree86.org | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Introduction | ||||||
|  | 
 | ||||||
|  |         The generic rootless layer allows an X server to be implemented  | ||||||
|  | on top of another window server in a cooperative manner. This allows the  | ||||||
|  | X11 windows and native windows of the underlying window server to  | ||||||
|  | coexist on the same screen. The layer is called "rootless" because the root  | ||||||
|  | window of the X server is generally not drawn. Instead, each top-level  | ||||||
|  | child of the root window is represented as a separate on-screen window by  | ||||||
|  | the underlying window server. The layer is referred to as "generic"  | ||||||
|  | because it abstracts away the details of the underlying window system and  | ||||||
|  | contains code that is useful for any rootless X server. The code for the  | ||||||
|  | generic rootless layer is located in xc/programs/Xserver/miext/rootless. To  | ||||||
|  | build a complete rootless X server requires a specific rootless  | ||||||
|  | implementation, which provides functions that allow the generic rootless  | ||||||
|  | layer to interact with the underlying window system. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Concepts | ||||||
|  | 
 | ||||||
|  |         In the context of a rootless X server the term window is used to  | ||||||
|  | mean many fundamentally different things. For X11 a window is a DDX  | ||||||
|  | resource that describes a visible, or potentially visible, rectangle on the  | ||||||
|  | screen. A top-level window is a direct child of the root window. To avoid  | ||||||
|  | confusion, an on-screen native window of the underlying window system  | ||||||
|  | is referred to as a "frame". The generic rootless layer associates each  | ||||||
|  | mapped top-level X11 window with a frame. An X11 window may be said  | ||||||
|  | to be "framed" if it or its top-level parent is represented by a frame. | ||||||
|  | 
 | ||||||
|  |         The generic rootless layer models each frame as being backed at  | ||||||
|  | all times by a backing buffer, which is periodically flushed to the screen.  | ||||||
|  | If the underlying window system does not provide a backing buffer for  | ||||||
|  | frames, this must be done by the rootless implementation. The generic  | ||||||
|  | rootless layer model does not assume it always has access to the frames'  | ||||||
|  | backing buffers. Any drawing to the buffer will be proceeded by a call to  | ||||||
|  | the rootless implementation's StartDrawing() function and StopDrawing()  | ||||||
|  | will be called when the drawing is concluded. The address of the frame's  | ||||||
|  | backing buffer is returned by the StartDrawing() function and it can  | ||||||
|  | change between successive calls. | ||||||
|  | 
 | ||||||
|  |         Because each frame is assumed to have a backing buffer, the  | ||||||
|  | generic rootless layer will stop Expose events being generated when the  | ||||||
|  | regions of visibility of a frame change on screen. This is similar to backing  | ||||||
|  | store, but backing buffers are different in that they always store a copy of  | ||||||
|  | the entire window contents, not just the obscured portions. The price paid  | ||||||
|  | in increased memory consumption is made up by the greatly decreased  | ||||||
|  | complexity in not having to track and record regions as they are obscured. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Rootless Implementation | ||||||
|  | 
 | ||||||
|  |         The specifics of the underlying window system are provided to the  | ||||||
|  | generic rootless layer through rootless implementation functions, compile- | ||||||
|  | time options, and runtime parameters. The rootless implementation  | ||||||
|  | functions are a list of functions that allow the generic rootless layer to  | ||||||
|  | perform operations such as creating, destroying, moving, and resizing  | ||||||
|  | frames. Some of the implementation functions are optional. A detailed  | ||||||
|  | description of the rootless implementation functions is provided in  | ||||||
|  | Appendix A. | ||||||
|  | 
 | ||||||
|  |         By design, a rootless implementation should only have to include  | ||||||
|  | the rootless.h header file. The rootlessCommon.h file contains definitions  | ||||||
|  | internal to the generic rootless layer. (If you find you need to use  | ||||||
|  | rootlessCommon.h in your implementation, let the generic rootless layer  | ||||||
|  | maintainers know. This could be an area where the generic rootless layer  | ||||||
|  | should be generalized.) A rootless implementation should also modify  | ||||||
|  | rootlessConfig.h to specify compile time options for its platform. | ||||||
|  | 
 | ||||||
|  |         The following compile-time options are defined in  | ||||||
|  | rootlessConfig.h: | ||||||
|  | 
 | ||||||
|  |       o ROOTLESS_ACCEL: If true, use the optional rootless acceleration | ||||||
|  |         functions where possible to a accelerate X11 drawing primitives. | ||||||
|  |         If false, all drawing will be done with fb. | ||||||
|  | 
 | ||||||
|  |       o ROOTLESS_GLOBAL_COORDS: This option controls the way that frame | ||||||
|  |         coordinates are passed to the rootless implementation. If false, | ||||||
|  |         the coordinates are passed per screen relative to the origin of  | ||||||
|  |         the screen the frame is currently on. Some implementations may  | ||||||
|  |         prefer to work in a single global coordinate space that spans all  | ||||||
|  |         screens. If this option is true, the coordinates are passed after  | ||||||
|  |         adding the coordinates of the screen origin and an overall offset of  | ||||||
|  |         (rootlessGlobalOffsetX, rootlessGlobalOffsetY). | ||||||
|  | 
 | ||||||
|  |       o ROOTLESS_PROTECT_ALPHA: By default for a color bit depth of 24 and | ||||||
|  |         32 bits per pixel, fb will overwrite the "unused" 8 bits to optimize | ||||||
|  |         drawing speed. If this is true, the alpha channel of frames is | ||||||
|  |         protected and is not modified when drawing to them. The bits  | ||||||
|  |         containing the alpha channel are defined by the macro  | ||||||
|  |         RootlessAlphaMask(bpp), which should return a bit mask for  | ||||||
|  |         various bits per pixel. | ||||||
|  | 
 | ||||||
|  |       o ROOTLESS_REDISPLAY_DELAY: Time in milliseconds between updates to | ||||||
|  |         the underlying window server. Most operations will be buffered until | ||||||
|  |         this time has expired. | ||||||
|  | 
 | ||||||
|  |       o ROOTLESS_RESIZE_GRAVITY: If the underlying window system supports it, | ||||||
|  |         some frame resizes can be optimized by relying on the frame contents | ||||||
|  |         maintaining a particular gravity during the resize. In this way less | ||||||
|  |         of the frame contents need to be preserved by the generic rootless | ||||||
|  |         layer. If true, the generic rootless layer will pass gravity hints | ||||||
|  |         during resizing and rely on the frame contents being preserved | ||||||
|  |         accordingly. | ||||||
|  | 
 | ||||||
|  |       o ROOTLESS_TRACK_DAMAGE: The generic rootless layer draws to the | ||||||
|  |         frames' backing buffers and periodically flushes the modified | ||||||
|  |         regions to the underlying window server. If this option is true, | ||||||
|  |         the generic rootless layer will track these damaged regions.  | ||||||
|  |         Currently it uses the miRegion code and will not simplify damaged  | ||||||
|  |         regions even when updating a bounding region would be more  | ||||||
|  |         efficient. Some window systems provide a more efficient way to  | ||||||
|  |         track damaged regions. If this option is false, the rootless  | ||||||
|  |         implementation function DamageRects() is called whenever a  | ||||||
|  |         backing buffer is modified and the rootless implementation is  | ||||||
|  |         expected to track the damaged regions itself. | ||||||
|  | 
 | ||||||
|  |         The following runtime options are defined in rootless.h: | ||||||
|  | 
 | ||||||
|  |       o rootlessGlobalOffsetX, rootlessGlobalOffsetY: These are only  | ||||||
|  |         used if ROOTLESS_GLOBAL_COORDS is true. They specify the global | ||||||
|  |         offset that is applied to all screens when converting from | ||||||
|  |         screen-local to global coordinates. | ||||||
|  | 
 | ||||||
|  |       o rootless_CopyBytes_threshold, rootless_FillBytes_threshold,  | ||||||
|  |         rootless_CompositePixels_threshold, rootless_CopyWindow_threshold: | ||||||
|  |         The minimum number of bytes or pixels for which to use the rootless | ||||||
|  |         implementation's respective acceleration function. The rootless | ||||||
|  |         acceleration functions are all optional so these will only be used | ||||||
|  |         if the respective acceleration function pointer is not NULL. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Accelerated Drawing | ||||||
|  | 
 | ||||||
|  | 	The rootless implementation typically does not have direct access  | ||||||
|  | to the hardware. Its access to the graphics hardware is generally through  | ||||||
|  | the API of the underlying window system. This underlying API may not  | ||||||
|  | overlap well with the X11 drawing primitives. The generic rootless layer  | ||||||
|  | falls back to using fb for all its 2-D drawing. Providing optional rootless  | ||||||
|  | implementation acceleration functions can accelerate some graphics  | ||||||
|  | primitives and some window functions. Typically calling through to the  | ||||||
|  | underlying window systems API will not speed up these operations for  | ||||||
|  | small enough areas. The rootless_*_threshold runtime options allow the  | ||||||
|  | rootless implementation to provide hints for when the acceleration  | ||||||
|  | functions should be used instead of fb. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Alpha Channel Protection | ||||||
|  | 
 | ||||||
|  | 	If the bits per pixel is greater then the color bit depth, the contents  | ||||||
|  | of the extra bits are undefined by the X11 protocol. Some window systems  | ||||||
|  | will use these extra bits as an alpha channel. The generic rootless layer can  | ||||||
|  | be configured to protect these bits and make sure they are not modified by  | ||||||
|  | other parts of the X server. To protect the alpha channel  | ||||||
|  | ROOTLESS_PROTECT_ALPHA and RootlessAlphaMask(bpp) must be  | ||||||
|  | set appropriately as described under the compile time options. This  | ||||||
|  | ensures that the X11 graphics primitives do not overwrite the alpha  | ||||||
|  | channel in an attempt to optimize drawing. In addition, the window  | ||||||
|  | functions PaintWindow() and Composite() must be replaced by alpha  | ||||||
|  | channel safe variants. These are provided in rootless/safeAlpha. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Credits | ||||||
|  | 
 | ||||||
|  | 	The generic rootless layer was originally conceived and developed  | ||||||
|  | by Greg Parker as part of the XDarwin X server on Mac OS X. John  | ||||||
|  | Harper made later optimizations to this code but removed its generic  | ||||||
|  | independence of the underlying window system. Torrey T. Lyons  | ||||||
|  | reintroduced the generic abstractions and made the rootless code suitable  | ||||||
|  | for use by other X servers. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Appendix A: Rootless Implementation Functions | ||||||
|  | 
 | ||||||
|  | 	The rootless implementation functions are defined in rootless.h. It  | ||||||
|  | is intended that rootless.h contains the complete interface that is needed by  | ||||||
|  | rootless implementations. The definitions contained in rootlessCommon.h  | ||||||
|  | are intended for internal use by the generic rootless layer and are more  | ||||||
|  | likely to change. | ||||||
|  | 
 | ||||||
|  | 	Most of these functions take a RootlessFrameID as a parameter.  | ||||||
|  | The RootlessFrameID is an opaque object that is returned by the  | ||||||
|  | implementation's CreateFrame() function. The generic rootless layer does  | ||||||
|  | not use this frame id other than to pass it back to the rootless  | ||||||
|  | implementation to indicate the frame to operate on. | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Create a new frame. | ||||||
|  |  *  The frame is created unmapped. | ||||||
|  |  * | ||||||
|  |  *  pFrame      RootlessWindowPtr for this frame should be completely | ||||||
|  |  *              initialized before calling except for pFrame->wid, which | ||||||
|  |  *              is set by this function. | ||||||
|  |  *  pScreen     Screen on which to place the new frame | ||||||
|  |  *  newX, newY  Position of the frame. These will be identical to pFrame-x, | ||||||
|  |  *              pFrame->y unless ROOTLESS_GLOBAL_COORDS is set. | ||||||
|  |  *  pNewShape   Shape for the frame (in frame-local coordinates). NULL for | ||||||
|  |  *              unshaped frames. | ||||||
|  |  */ | ||||||
|  | typedef Bool (*RootlessCreateFrameProc) | ||||||
|  |     (RootlessWindowPtr pFrame, ScreenPtr pScreen, int newX, int newY, | ||||||
|  |      RegionPtr pNewShape); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Destroy a frame. | ||||||
|  |  *  Drawing is stopped and all updates are flushed before this is called. | ||||||
|  |  * | ||||||
|  |  *  wid         Frame id | ||||||
|  |  */ | ||||||
|  | typedef void (*RootlessDestroyFrameProc) | ||||||
|  |     (RootlessFrameID wid); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Move a frame on screen. | ||||||
|  |  *  Drawing is stopped and all updates are flushed before this is called. | ||||||
|  |  * | ||||||
|  |  *  wid         Frame id | ||||||
|  |  *  pScreen     Screen to move the new frame to | ||||||
|  |  *  newX, newY  New position of the frame | ||||||
|  |  */ | ||||||
|  | typedef void (*RootlessMoveFrameProc)  | ||||||
|  |     (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Resize and move a frame. | ||||||
|  |  *  Drawing is stopped and all updates are flushed before this is called. | ||||||
|  |  * | ||||||
|  |  *  wid         Frame id | ||||||
|  |  *  pScreen     Screen to move the new frame to | ||||||
|  |  *  newX, newY  New position of the frame | ||||||
|  |  *  newW, newH  New size of the frame | ||||||
|  |  *  gravity     Gravity for window contents (rl_gravity_enum). This is always | ||||||
|  |  *              RL_GRAVITY_NONE unless ROOTLESS_RESIZE_GRAVITY is set. | ||||||
|  |  */ | ||||||
|  | typedef void (*RootlessResizeFrameProc) | ||||||
|  |     (RootlessFrameID wid, ScreenPtr pScreen, | ||||||
|  |      int newX, int newY, unsigned int newW, unsigned int newH, | ||||||
|  |      unsigned int gravity); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Change frame ordering (AKA stacking, layering). | ||||||
|  |  *  Drawing is stopped before this is called. Unmapped frames are mapped by | ||||||
|  |  *  setting their ordering. | ||||||
|  |  * | ||||||
|  |  *  wid         Frame id | ||||||
|  |  *  nextWid     Frame id of frame that is now above this one or NULL if this | ||||||
|  |  *              frame is at the top. | ||||||
|  |  */ | ||||||
|  | typedef void (*RootlessRestackFrameProc) | ||||||
|  |     (RootlessFrameID wid, RootlessFrameID nextWid); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Change frame's shape. | ||||||
|  |  *  Drawing is stopped before this is called. | ||||||
|  |  * | ||||||
|  |  *  wid         Frame id | ||||||
|  |  *  pNewShape   New shape for the frame (in frame-local coordinates) | ||||||
|  |  *              or NULL if now unshaped. | ||||||
|  |  */ | ||||||
|  | typedef void (*RootlessReshapeFrameProc) | ||||||
|  |     (RootlessFrameID wid, RegionPtr pNewShape); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Unmap a frame. | ||||||
|  |  * | ||||||
|  |  *  wid         Frame id | ||||||
|  |  */ | ||||||
|  | typedef void (*RootlessUnmapFrameProc) | ||||||
|  |     (RootlessFrameID wid); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Start drawing to a frame. | ||||||
|  |  *  Prepare a frame for direct access to its backing buffer. | ||||||
|  |  * | ||||||
|  |  *  wid         Frame id | ||||||
|  |  *  pixelData   Address of the backing buffer (returned) | ||||||
|  |  *  bytesPerRow Width in bytes of the backing buffer (returned) | ||||||
|  |  */ | ||||||
|  | typedef void (*RootlessStartDrawingProc) | ||||||
|  |     (RootlessFrameID wid, char **pixelData, int *bytesPerRow); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Stop drawing to a frame. | ||||||
|  |  *  No drawing to the frame's backing buffer will occur until drawing | ||||||
|  |  *  is started again. | ||||||
|  |  * | ||||||
|  |  *  wid         Frame id | ||||||
|  |  *  flush       Flush drawing updates for this frame to the screen. This | ||||||
|  |  *              will always be FALSE if ROOTLESS_TRACK_DAMAGE is set. | ||||||
|  |  */ | ||||||
|  | typedef void (*RootlessStopDrawingProc) | ||||||
|  |     (RootlessFrameID wid, Bool flush); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Flush drawing updates to the screen. | ||||||
|  |  *  Drawing is stopped before this is called. | ||||||
|  |  * | ||||||
|  |  *  wid         Frame id | ||||||
|  |  *  pDamage     Region containing all the changed pixels in frame-local | ||||||
|  |  *              coordinates. This is clipped to the window's clip. This | ||||||
|  |  *              will be NULL if ROOTLESS_TRACK_DAMAGE is not set. | ||||||
|  |  */ | ||||||
|  | typedef void (*RootlessUpdateRegionProc) | ||||||
|  |     (RootlessFrameID wid, RegionPtr pDamage); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Mark damaged rectangles as requiring redisplay to screen. | ||||||
|  |  *  This will only be called if ROOTLESS_TRACK_DAMAGE is not set. | ||||||
|  |  * | ||||||
|  |  *  wid         Frame id | ||||||
|  |  *  nrects      Number of damaged rectangles | ||||||
|  |  *  rects       Array of damaged rectangles in frame-local coordinates | ||||||
|  |  *  shift_x,    Vector to shift rectangles by | ||||||
|  |  *   shift_y | ||||||
|  |  */ | ||||||
|  | typedef void (*RootlessDamageRectsProc) | ||||||
|  |     (RootlessFrameID wid, int nrects, const BoxRec *rects, | ||||||
|  |      int shift_x, int shift_y); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Switch the window associated with a frame. (Optional) | ||||||
|  |  *  When a framed window is reparented, the frame is resized and set to | ||||||
|  |  *  use the new top-level parent. If defined this function will be called | ||||||
|  |  *  afterwards for implementation specific bookkeeping. | ||||||
|  |  * | ||||||
|  |  *  pFrame      Frame whose window has switched | ||||||
|  |  *  oldWin      Previous window wrapped by this frame | ||||||
|  |  */ | ||||||
|  | typedef void (*RootlessSwitchWindowProc) | ||||||
|  |     (RootlessWindowPtr pFrame, WindowPtr oldWin); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Copy bytes. (Optional) | ||||||
|  |  *  Source and destinate may overlap and the right thing should happen. | ||||||
|  |  * | ||||||
|  |  *  width       Bytes to copy per row | ||||||
|  |  *  height      Number of rows | ||||||
|  |  *  src         Source data | ||||||
|  |  *  srcRowBytes Width of source in bytes | ||||||
|  |  *  dst         Destination data | ||||||
|  |  *  dstRowBytes Width of destination in bytes | ||||||
|  |  */ | ||||||
|  | typedef void (*RootlessCopyBytesProc) | ||||||
|  |     (unsigned int width, unsigned int height, | ||||||
|  |      const void *src, unsigned int srcRowBytes, | ||||||
|  |      void *dst, unsigned int dstRowBytes); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Fill memory with 32-bit pattern. (Optional) | ||||||
|  |  * | ||||||
|  |  *  width       Bytes to fill per row | ||||||
|  |  *  height      Number of rows | ||||||
|  |  *  value       32-bit pattern to fill with | ||||||
|  |  *  dst         Destination data | ||||||
|  |  *  dstRowBytes Width of destination in bytes | ||||||
|  |  */ | ||||||
|  | typedef void (*RootlessFillBytesProc) | ||||||
|  |     (unsigned int width, unsigned int height, unsigned int value, | ||||||
|  |      void *dst, unsigned int dstRowBytes); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Composite pixels from source and mask to destination. (Optional) | ||||||
|  |  * | ||||||
|  |  *  width, height   Size of area to composite to in pizels | ||||||
|  |  *  function        Composite function built with RL_COMPOSITE_FUNCTION | ||||||
|  |  *  src             Source data | ||||||
|  |  *  srcRowBytes     Width of source in bytes (Passing NULL means source | ||||||
|  |  *                  is a single pixel. | ||||||
|  |  *  mask            Mask data | ||||||
|  |  *  maskRowBytes    Width of mask in bytes | ||||||
|  |  *  dst             Destination data | ||||||
|  |  *  dstRowBytes     Width of destination in bytes | ||||||
|  |  * | ||||||
|  |  *  For src and dst, the first element of the array is the color data. If | ||||||
|  |  *  the second element is non-null it implies there is alpha data (which | ||||||
|  |  *  may be meshed or planar). Data without alpha is assumed to be opaque. | ||||||
|  |  * | ||||||
|  |  *  An X11 error code is returned. | ||||||
|  |  */ | ||||||
|  | typedef int (*RootlessCompositePixelsProc) | ||||||
|  |     (unsigned int width, unsigned int height, unsigned int function, | ||||||
|  |      void *src[2], unsigned int srcRowBytes[2], | ||||||
|  |      void *mask, unsigned int maskRowBytes, | ||||||
|  |      void *dst[2], unsigned int dstRowBytes[2]); | ||||||
|  | 
 | ||||||
|  | /* | ||||||
|  |  * Copy area in frame to another part of frame. (Optional) | ||||||
|  |  * | ||||||
|  |  *  wid         Frame id | ||||||
|  |  *  dstNrects   Number of rectangles to copy | ||||||
|  |  *  dstRects    Array of rectangles to copy | ||||||
|  |  *  dx, dy      Number of pixels away to copy area | ||||||
|  |  */ | ||||||
|  | typedef void (*RootlessCopyWindowProc) | ||||||
|  |     (RootlessFrameID wid, int dstNrects, const BoxRec *dstRects, | ||||||
|  |      int dx, int dy); | ||||||
|  | 
 | ||||||
		Loading…
	
		Reference in New Issue