OpenWindows Server Device Developer's Guide
只搜尋這本書
以 PDF 格式下載這本書

Multibuffering Extension to X Interface

9

This chapter describes the MBX (the Multibuffering Extension to X) interface for DDX handlers. This implementation of MBX permits hardware multibuffering on devices with special hardware (HW MBX). Internal changes were made to the X11R5 MBX sample implementation and a device porting interface was added.
Devices not capable of supporting hardware multibuffering can still use the MBX extension without any porting effort. Devices capable of hardware multibuffering need to register a device-dependent function vector with the server during Screen initialization.
See the OpenWindows Server Programmer's Guide, which is part of the SDK, for the MBX extension specification.
dl>

Multibuffering

Clients can grab MBX image buffers and render directly to them.

Multibuffered Windows and Multibuffer Sets

A window is multibuffered if the MBX API routine XmbufCreateBuffers has been called on the window. XmbufCreateBuffers creates a specified number of multibuffers associated with the window. At any one time, the contents of one of these multibuffers is displayed within the window. Together, the
window and its associated multibuffers form a multibuffer set. The window of a multibuffer set is called the main window. The main window and its multibuffers are called members of the multibuffer set.

Multibuffer Flip Modes

Two methods exist for an undisplayed buffer to become the displayed buffer, or buffer flipping. The first is the copy flip method, or MBCOPY_FLIP, where the framebuffer creates n buffers in memory. When a client requests that buffer, i becomes the displayed buffer and the pixel contents of i are copied to the pixel store of the window drawable. This copying is transparent to MBX clients. This means that if the client renders to multibuffer i (the current display buffer) again, the rendering should be immediately visible. But, since copying is being used, the rendering instead goes into a nonviewable pixel store. Buffer aliasing solves this problem in copy flip mode: whenever a multibuffer is made the current display buffer, its XID is aliased to refer to the pixel store of the window drawable. If the client makes any multibuffer the current display buffer, subsequent rendering to that multibuffer will be immediately visible because it is drawn to the pixel store of the window drawable, which is always viewable.
The second method of buffer flipping is video flip, or MBVIDEO_FLIP, and can only be accomplished on an MPG device. This method requires that the framebuffer be capable of switching the video to be displayed out of any of the multibuffers created for a window. When the DDX handler is notified to display buffer i it is responsible for switching the hardware so that it displays from buffer i. Additionally, it must notify MPG that the window has migrated to a new plane group so that rendering to the window or displayed buffer will be immediately viewable.

HW MBX Functions

MbxScreenInit


  #define _MULTIBUF_SERVER /* do not want Xlib structures */  
  #include "multibufst.h"  
  #include "multibufstruct.h"  
  .  
  .  
  .  
  int  
  mbxScreenInit(pScreen, pMbxdevfuncs, major, minor)  
  ScreenPtr    pScreen;  
  void         *pMbxdevfuncs;  
  int          major;  
  int          minor;  

PurposeThis function initializes HW MBX from your DDX handler's Screen initialization function, if the Screen supports hardware multibuffering.
Argumentsmajor is the major version number of the server DDK (1).
minor is the minor version number of the server DDK (0).

Note - The MBX initialization function in last release, MultibufferDevFuncsInit, is supported in this release. See New Features and Changes for information on backward compatibility.

MbxDevFuncs

This function vector, as well as many other MBX data structures and constants referenced throughout this chapter, is defined in the multibufst.h (in /usr/openwin/include/X11/extensions) and the multibufstruct.h (in SUNWowddk/extensions/server/multibufstruct.h) header files.

  typedef struct _MbxDevFuncs {  
  int          (*TryMpg)(WindowPtr, int, int, int);  
  PixmapPtr    (*CreateMultibuffer2)(WindowPtr, int, int, int, int, int);  
  void         (*DestroyMultibuffer)(WindowPtr, PixmapPtr, int, int);  
  PixmapPtr    (*ResizeMultibuffer)(WindowPtr, int, int, int, int);  
  void         (*RepositionMultibuffer)(WindowPtr, PixmapPtr, int, int);  
  int          (*DisplayMultibuffer)(WindowPtr,int);  
  int          (*SetMultibufferInvisible)(WindowPtr, PixmapPtr);  
  int          (*SetMultibufferVisible)(WindowPtr, PixmapPtr);  
  void         (*LastUpdateTime)(WindowPtr, u_long, u_long);  
  } MbxDevFuncs;  

This function vector does not have to be completely filled in by every device. Only functions applicable to the device need to be filled in; other entries can be NULL. Functions, if supplied, are called by the device-independent layer of MBX when it needs to perform a device-dependent operation.

TryMpg


  int  
  (*TryMpg)(WindowPtr pWin, int num_buf, int updateAction,  
           int updateHint)  

Purpose....This function is called when a client initiates multibuffering on a window, pWin, through MBX. The server attempts to create the requested number of buffers, num_buf, to associate with the window. This call requests the handler to indicate whether the device provides MPG multibuffering. If a device supports MPG, then the plane group used by the window for multibuffering might be different than the current plane group. In this case, this routine re-prepares the necessary plane groups. Refer to Chapter 5, "Multiple Plane
Group Interface" for more details. Non-MPG devices need not supply this routine and should have a NULL entry in the mbufdevfunc vector.
Results....If the number of buffers requested for multibuffering, num_buf, is greater than the available number that hardware can support, or if any other device- dependent criteria for turning on hardware multibuffering fails, hardware multibuffering is not enabled.
If all conditions are satisfied, the device maintains private information about the multibuffering state if necessary.
ReturnsThis function returns 1 if hardware multibuffering is enabled and 0 otherwise.
ArgumentsThe last two arguments to this function, updateAction and updateHint, are supplied because some devices might not handle all cases and combinations of update action or update hint.
updateHint indicates how often the client will request a different buffer to be displayed. This hint allows smart server implementations to choose the most efficient means to support a multibuffered window based on the current need of the application (dumb implementations may choose to ignore this hint). Possible hints are:
MultibufferUpdateHintFrequent means an animation or movie loop is being attempted and the fastest, most efficient means for multibuffering should be employed.
MultibufferUpdateHintIntermittent means the displayed image will be changed every so often. This is common for images displayed at a rate slower than a second. For example, a clock that is updated only once a minute.
MultibufferUpdateHintStatic means the displayed image buffer will not be changed any time soon. Typically set by an application whenever there is a pause in the animation.
updateAction indicates what should happen to a previously displayed buffer when a different buffer becomes displayed. Possible actions are:
MultibufferUpdateActionUndefined means the contents of the buffer last displayed will become undefined after the update. This is the most efficient action since it allows the implementation to trash the contents of the buffer if it needs to.
MultibufferUpdateActionBackground means the contents of the buffer last displayed will be set to the background of the window after the update. The background action allows devices to use a fast clear capability during an update.
MultibufferUpdateActionUntouched means the contents of the buffer last displayed will be untouched after the update. Used primarily when cycling through images that have already been drawn.
MultibufferUpdateActionCopied means the contents of the buffer last displayed will become the same as those that are being displayed after the update. This is useful when incrementally adding to an image.

CreateMultibuffer2


  PixmapPtr  
  (*CreateMultibuffer2)(WindowPtr pWin, int num_buf,  
           int cur_buf, int updateAction, int updateHint,  
           int mode);  

Purpose....When the device does not support hardware buffers, the buffers are implemented as software pixmaps. However, on devices supporting hardware buffers, this function has to create a pixmap that points to device memory and return a pointer to the pixmap.
ReturnsIf the requested number of buffers is greater than what the hardware can support, this routine returns NULL. If the buffer was created, this routine returns a pointer to the pixmap.
Argumentsnum_buf indicates the total number of buffers being requested and this routine is called to create each of the requested image buffers.
cur_buf indicates the number of the buffer being created. num_buf is provided in case you want to perform a sanity check on cur_buf.
The values of updateHint and updateAction are supplied, because you might not want to support hardware buffers for certain values or combinations of updateAction and updateHint. See page 139 and page 140 for complete definitions of these arguments.
mode is an integer pointer that the DDX handler should fill in with either MBCOPY_FLIP or MBVIDEO_FLIP, depending on the type of buffer created. All buffers for any window must be the same mode.

Note - The MBX creation function in last release, CreateMultibuffer, is supported in this release. See New Features and Changes for information on backward compatibility.

DestroyMultibuffer


  void  
  (*DestroyMultibuffer)(Windowptr pWin, PixmapPtr pPix,  
           int num_buf, int cur_buf);  

Purpose....This function is called when the server is destroying the multibuffers of a window so that the DDX handler can clean up the resources used by the buffers. This function is called once for each buffer in a window's multibuffer set that is being destroyed.
Arguments..pPix is the PixmapPtr that was returned by CreateMultibuffer2.
num_buf is the total number of buffers allocated to this window. This number should not change throughout the existence of a multibuffer. It can change if a multibuffered window is unbuffered, then buffered again with a differing number of buffers. In particular, this value should not change during the buffer destruction process (rather than being updated after the deletion of each buffer/pixmap).
cur_buf is the buffer number of the buffer currently being deleted.

ResizeMultibuffer


  PixmapPtr  
  (*ResizeMultibuffer)(WindowPtr pWin, int num_buf,  
                int cur_buf, int updateAction, int updateHint);  

PurposeIf a multibuffer window pWin, is resized, and if the buffers are in hardware, they need to be resized as well. Often, this means destroying the previously allocated hardware buffer and recreating a new one with the new size. This function, if available, is called to resize each of the buffers associated with the window pWin.
ResultsThe new dimensions of the buffer are the same as the dimensions of the window, pWin. All the conditions specified for CreateMultibuffer also apply to this function.
If the device maintains private data about the hardware buffers, it is updated as well. The contents from the buffer before it was resized are copied into the newly resized buffer.
Returns....If the hardware pixmap-buffer associated with the cur_buf is successfully resized, a pointer to this pixmap-buffer is returned. Otherwise a NULL pointer is returned.
Arguments..num_buf indicates the total number of buffers associated with this window and cur_buf indicates the number of the buffer currently being resized.
See page 139 and page 140 for complete definitions of updateAction and updateHint.

RepositionMultibuffer


  void  
  (*RepositionMultibuffer)(WindowPtr pWin,  
           PixmapPtr pBuffer, int new_x, int new_y)  

PurposeIf a multibuffer window pWin, is repositioned, and if the buffers are in hardware, they each need to be repositioned. The hardware might need to be updated with the new origin of the buffer, as well as any private information that the device maintains about this buffer. This function, if available, is called to reposition each of the hardware buffers.
Argumentsnew_x and new_y indicate the new coordinates of the window.
Depending on the hardware, the contents in the hardware buffers might need to be copied to the new location.

DisplayMultibuffer


  int  
  (*DisplayMultibuffer)(WindowPtr pWin, int buf_num)  

Purpose....When the client program issues a request to display a certain buffer on a multibuffered window, pWin, this function, if available, is called. If the multibuffer set of pWin is of type MBVIDEO_FLIP, mpgChangeInfo() must be called to migrate the window to the plane group of the new display buffer.
ReturnsThis function then initiates flipping the buffer to display the hardware buffer associated with this buffer number and return 1 upon success and 0 on failure. If the hardware buffer flip fails for some reason, the contents of the buffer are copied to the window using CopyArea.
Argumentsbuf_num indicates the number of the buffer to be displayed.
DisplayMultibuffer can be an asynchronous function. It can post the buffer flip to the device and return immediately. If this is the case, it is the responsibility of the device handlers' rendering code to block until the buffer flip has been completed before proceeding to render.
Some devices do not display a new buffer by doing a flip in hardware. Instead their hardware is specialized to perform accelerated copying from the hardware buffer to the window. These devices have a NULL entry in the device function vector for this function.

SetupMultibufferInvisible


  int  
  (*SetMultibufferInvisible)(WindowPtr pWin,  
           PixmapPtr pPrevBuf);  

Purpose....This function, if available, is called to indicate that pPrevBuf is no longer the visible buffer of the multibuffered window, pWin.
In the device-independent part of MBX, the resource id of the window is aliased to the resource id of the visible buffer. When the client requests a new buffer to be displayed, the resource id of the window needs to be aliased to the new buffer. If the currently visible buffer is in hardware, the hardware might need to be updated to know that this buffer is no longer the visible buffer.
Returns....This function returns 1 upon success and 0 on failure.

SetMultibufferVisible


  int  
  (*SetMultibufferVisible)(WindowPtr pWin, PixmapPtr pCurBuf);  

Purpose....This function, if available, is called to indicate that the buffer, pCurBuf is the currently visible buffer on the multibuffered window, pWin.
After marking the currently visible buffer as invisible, MBX then aliases the resource id of the window to the resource id of the buffer (pixmap) about to be displayed. If this buffer is in hardware, the hardware might need to be updated to indicate that this buffer is now visible.
ReturnsLastUpdateTimeThis function returns 1 upon success and 0 on failure.
int
PurposeThis function, if available, is called to find out when the last display update was completed. You are required to supply the last update time in your device handler.
ResultsThis function assumes that DisplayMultibuffer returns after the buffer is flipped.
On devices that allow DisplayMultibuffer to be asynchronous, this assumption is no longer valid.