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

Direct Graphics Access Drawable DDX Interface

10

This chapter describes routines the server provides for you to interface with DGA with your DDX handlers to make various types of changes to a drawable. This interface is called the direct graphics access (DGA) drawable DDX interface.

Note - The old DGA initialization function DgaDevFuncsInit is still supported. This routine allows grabbing of windows only. DgaDevFuncsInit and the newer initialization function dgaScreenInit are mutually exclusive. A DDX handler must use only one of the two functions.

Initializing Drawable Grabs

The DGA application programming interface (API) supports direct access to window and pixmap drawables. In the initialization sequence that supports arbitrary drawable types, not only is this same function vector given to DGA, but two new functions are also given. Providing these new functions is optional. If they are NULL, the DGA drawable interface (dga_draw_xxxx API routines) is only able to grab window drawables.
Call the following initialization routine from the InitOutput routine of your DDX handler.

dgaScreenInit


  int  
  dgaScreenInit(pScreen, pDgadevfuncs, major, minor)  
  ScreenPtr    pScreen;  
  void         *pDgadevfuncs;  
  int          major;  
  int          minor;  

Arguments..pDgadevfuncs is a function vector of device-dependent functions cast to a void*:

  typedef struct _DgaDevFuncsDraw {  
  int              (*DgaAvail)();  
  void             (*GrabDrawable)(DrawablePtr);  
  void             (*UngrabDrawable)(DrawablePtr);  
  int              (*CacheDrawInit)(DrawablePtr);  
  int              (*CacheDrawCleanup)(DrawablePtr);  
  int              (*DbSetup)(WindowPtr, WXINFO*, int, Bool);  
  int              (*WidSetup)(WindowPtr, int, WXINFO*);  
  int              (*FcsSetup)(WindowPtr, WXINFO*, int);  
  int              (*ZbufSetup)(WindowPtr, int, WXINFO*);  
  int              (*StereoSetup)(WindowPtr, int, WXINFO*);  
  int              (*ChokeFb)(ScreenPtr, Bool);  
  int              (*SyncDrawable)(DrawablePtr,GCPtr);  
  int              (*UnsyncDrawable)(DrawablePtr,GCPtr);  
  int              (*CmapSetup)(CmapPtr, Grabbedcmap*)  
  } DgaDevFuncsDraw;  

The pDgadevfuncs argument may be NULL. If so, it means that client DGA is not available on the device.
The device handler is not required fill out all members of devFuncs; some functions may not be applicable to a device and these entries should be NULL in the vector.
The major and minor arguments are the major and minor version numbers for the DDK release as specified in "DDX Versioning" on page 12.
All of the types and structures listed above are defined in the include file dga/dgawinstr.h.

Device-Supplied Routines

Use the following routines during DGA initialization. Values can be NULL; however, functionality might be limited.

DgaAvail


  int (*DgaAvail)()  

PurposeThis function advertises the flavor of DGA that a device supports. If this function is NULL, the device is considered to not support client DGA. All devices supporting client DGA must supply this routine.
ReturnsThe definitions of the return codes are found in
dga/dgawinstr.h.

If a device does not support DGA, this routine should return
DGA_AVAIL_NONE.

If the device supports DGA and also has a cursor that is always rendered in hardware, it should return DGA_AVAIL_CURS_HW.
If the cursor is always rendered in software, this routine should return DGA_AVAIL_CURS_SW.
A device that has a limit to the size of cursor that can be drawn in hardware and intends to support larger cursors in software, this routine should return DGA_AVAIL_CURS_HW_SW.
For example, on the GX/GX+, the maximum size for a hardware cursor is 32x32. If a client loads in a cursor that is larger than this, the GX switches to software to render this cursor. So, GX/GX+ would return DGA_AVAIL_CURS_HW_SW from this routine.

GrabDrawable


  void (*GrabDrawable)(DrawablePtr pDraw)  

Purpose....This function is called when a drawable is first grabbed to allow the device handler to initialize device-dependent information for the drawable.

Note - This function is only called the first time a client grabs the drawable. It is never called for subsequent attempts to grab the same drawable, either by the client to first grab or other clients. Likewise, UngrabDrawable is only called when the last grabbing client ungrabs.


Note - This function is called on the first grab, even if the drawable is a window that is being grabbed through the older version of the DGA interface, the Window Compatibility Interface. In this case the WindowPtr is cast to a DrawablePtr.

UngrabDrawable


  void (*UngrabDrawable)(DrawablePtr pDraw)  

Purpose....This function is called when a drawable is ungrabbed. It should undo anything that GrabDrawable has done. For example, the device-specific shared information may need to be updated.

Note - This function is called on the first grab, even if the drawable is a window that is being grabbed through the older version of the DGA interface, the Window Compatibility Interface. In this case the WindowPtr is cast to a DrawablePtr.

CachedDrawInit


  int (*CachedDrawInit)(DrawablePtr pDraw)  

Purpose....This function allows the device handler to do any device-specific setup needed for the drawable when it is cached. Examples include: location within the cache and the format of the data within the cache.
This routine is called for drawables that may be cached in special device memory. Drawable types that can cached include: pixmaps, and the backing store of a window.

Note - Drawable refers to backing store in this context, even though a backing store is technically not a drawable because it doesn't have an XID.

The type of drawable may be determined by inspecting pDraw->type. If this is DRAWABLE_WINDOW, the type of drawable that is being referred to is the drawable's backing store. The server-internal structure for this backing store (which, incidentally, happens to be of type PixmapPtr) can be derived using the expression:

  ((miBSWindowPtr)((WindowPtr)pDraw)->backStorage)->pBackingPixmap  

Results....If the drawable is cached, this routine should do the following:
  1. Call DgaCacheDescribeDev on the pScreen of the drawable with devCode and devname.

  2. Call DgaCacheStateChange with a value of TRUE.

  3. Call DgaDevInfoGet and DgaDevInfoChange to update any device-dependent information which is necessary for the cached drawable.

After this routine has been called, whenever the device handler changes the cache state of the drawable, it should call these routines.
Returns....If this routine returns 0, DGA assumes that the drawable is of type DGA_DRAW_SYSTEM and it copies the contents of the pixmap to the shared page.
This routine should return 1 if the drawable is not of type DGA_DRAW_SYSTEM, or the device handler has already copied the pixmap to the shared page.

CachedDrawCleanup


  int  
  (*CachedDrawCleanup)(DrawablePtr pDraw)  

Purpose....This function is called when a nonviewable drawable or backing store is ungrabbed. It should undo anything done by CachedDrawInit. For example, it would call DgaCacheStateChange to mark the drawable as uncached. DgaDevInfoGet and DgaDevInfoChange might need to be called to clean up information in the device-dependent shared area.
The type of drawable might be determined by inspecting pDraw->type. If this is DRAWABLE_WINDOW, the type of drawable being referred to is the drawable's backing store. The server-internal structure for this backing store can be derived using the expression:

  ((miBSWindowPtr)((WindowPtr)pDraw)->backStorage)->pBackingPixmap  

Returns....1 on success; 0 on failure. If 0 is returned, DGA assumes the drawable (or backing store) is uncached and directs its data pointer at the shared page. At this time, the contents of the drawable (or backing store) are copied to the shared page.

DbSetup


  int  
  (*DbSetup)(WindowPtr pWin, WXINFO *infop, int num_buf,  
           Bool flag)  

PurposeThis function is called when an application requests direct access to do multibuffering. Typically, this function would update some device-specific structures/hardware states, as well as information on the shared info page.
ArgumentsThe WXINFO structure has a field, wx_dbuf, which is a structure containing information relevant to multibuffering. The definitions of these structures are found in dga/dgawinstr.h.
This function must update the following structures:
infop->wx_dbuf.num_buffers should be set equal to the total number of buffers that the device supports in hardware. If the number of buffers available from the device is less than the requested number, num_buf, this function should return failure (0).
MPG Devices with hardware window IDs can allocate a new window ID for the multibuffered window. If so, this function is responsible for repreparing the window with the new (hardware) window ID. If a new and unique WID is allocated for this window, the infop->wx_dbuf.WID field should be updated with this new value and the infop->wx_dbuf.UNIQUE flag should be set to 1 to indicate that this is a unique window ID. See Chapter 5, "Multiple Plane Group Interface" for more information.
The wx_dbuf structure contains a device-specific field, wx_dbuf->device, that can be used by the device to communicate information between the server and the client. In the wx_dbuf structure, this is declared as:

  union { char pad[128];} device  

Each device can cast this to its own structure and communicate information to the client.
infop->w_refresh_period should be set equal to the refresh period of the monitor in milliseconds. This information is required by client-side DGA code. If this value is not supplied (set to zero), the client-side code defaults to a 66Hz monitor.
ReturnsWidSetup1 on success; 0 on failure.
int
PurposeThis function is called when an application requests a block of window IDs to be grabbed. The allocation of window IDs is device specific and should be handled by this routine.
ResultsOn MPG devices, the window might need to be reprepared after new window IDs are allocated. This routine should take care of the repreparation as well.
ArgumentsThis routine should update information in the DGA shared page pertaining to window IDs:
infop->w_number_wids should be set equal to the number of contiguous WIDs, num_wids that have been allocated. If the device was not able to allocate the requested number of contiguous WIDs, this function should return 0 for failure.
infop->w_start_wid should be set equal to the value of the first WID in the newly allocated block. The base WID should be aligned on a power-of-two boundary.
infop->w_wid should be set equal to the current WID of the window. This is often equal to infop->w_start_wid.
If the window has been allocated a new window ID, this function is responsible for repreparing the window with this WID value. See Chapter 5, "Multiple Plane Group Interface" for details on how to do this.
ReturnsFcsSetup1 on success; 0 on failure.
int
PurposeThis function is called when an application requests a number of fast clear planes, num_fcs, to be grabbed for a window, pWin. The allocation of fcs planes is device-specific and should be handled by this routine.
On MPG devices, allocation of FCS planes may require repreparation of the window. This function is responsible for repreparation. See Chapter 5, "Multiple Plane Group Interface" for more details about accessing the MPG information.
ArgumentsThis routine should update the information in the DGA shared page pertaining to fast clear planes. Information about a window's fast clear planes is stored in the device-specific portion of the wx_dbuf structure found in the WXINFO structure infop->wx_dbuf.device. This structure can be cast to a device-defined structure and the fcs information could be stored here.
Returns1 on success; 0 on failure.

ZbufSetup


  int  
  (*ZbufSetup)(WindowPtr pWin, int zbuf_type, WXINFO *infop)  

PurposeThis function is called when an application requests direct access to the Zbuffer for a window, pWin. This is a device-specific operation and should be handled by this routine.
ArgumentsThis routine should update the device-specific information in the DGA shared page pertaining to Zbuffer. A device may support various types of Z buffers and the second argument, zbuf_type, indicates which type of Zbuffer is being requested. Each device may support different types of Z buffers.
Information about a window's Zbuffer is stored in the device-specific portion of the wx_dbuf structure found in the WXINFO structure infop->wx_dbuf.device.
This array can be cast to a device-defined structure and the Zbuffer information could be stored here. On MPG devices, allocation of Zbuffer may require repreparation of the window. This function is responsible for repreparation. See Chapter 5, "Multiple Plane Group Interface" for more details about accessing the MPG information.
ReturnsStereoSetup1 on success; 0 on failure.
int
PurposeThis function is called when an application requests that a stereo mode be associated or disassociated with this window, pWin.
Arguments..If the second argument, st_mode is a nonzero value, a stereo mode is associated with the window and if it is equal to zero, stereo mode is turned off. This is device-specific and should be handled by this routine.
This routine should update the device-dependent information in the DGA shared page pertaining to stereo.
Information about a window's stereo state is stored in the device-specific portion of the wx_dbuf structure found in the WXINFO structure infop->wx_dbuf.device.
This array can be cast to a device-defined structure and the stereo information could be stored here.
ReturnsChokeFb1 on success; 0 on failure.
int
PurposeWhen all windows on a screen are locked down, frame buffers having asynchronous accelerators need to choke the accelerator. This prevents the accelerator from rendering into a locked window. Since this is a device-specific operation, this function has to implement the choking and unchoking.
ArgumentsIf the second argument, flag, is 1, this function should choke the accelerator; if flag is 0, it should unchoke the accelerator. Typically, this is done via an ioctl. For example, the GT uses the FBIOGRABHW ioctl to choke its accelerator.
Returns1 on success; 0 on failure.

SyncDrawable


  int  
  (*SyncDrawable)(DrawablePtr pDraw, GCPtr pGC)  

Purpose....When DGA is used to switch buffers, all X rendering functions need to be directed at the currently displayed buffer. This function is called before calling the X rendering function but only if the window is multibuffered.
This routine can also be used to update device-private structures with the current buffer state.
ResultsUnsyncDrawableThis function might need to call dgaMbGetBufferInfo to get the current buffer configuration.
int
PurposeThis function should undo anything that was done in
                  SyncDrawable.

This routine can also be used to update device private structures with the current buffer state.
Results....This function may need to call dgaMbGetBufferInfo to get the current buffer configuration.

CmapSetup


  int  
  (*CmapSetup)(CmapPtr pCmap, Grabbedcmap cginfop)  

PurposeThis function is called when a colormap is being grabbed. The include file that provides definition of the Grabbedcmap structure is dga/dgacmapstr.h. This function is typically used by devices supporting multiple hardware colormaps or other specialized colormap hardware.
ArgumentsIn this routine, the DDX handlers can set up cginfo->devinfop to point to a private data area. The maximum size of this private area is DGA_CM_DEV_INFO_SZ, defined in dga/dgacmapstr.h. This field is declared as an u_char array.
Each DDX handler can cast this to a device-private structure. Typically, this device-dependent structure contains information about the hardware colormap associated with the grabbed X colormap.
On the client side, the client program can gain access to this data by using the appropriate libdga function call, dga_cm_get_devinfo. See Chapter 9, "Multibuffering Extension to X Interface" for more information.
Devices that do not have specialized colormap hardware, like multiple hardware color look up tables, do not need to fill out this element in the function vector, DgaDevFuncsDraw.
Returns....The return value is ignored.

Caching Routines

The following routines allow a DDX handler to keep DGA informed of caching changes on a device.

dgaCacheDescribeDev


  void  
  DgaCacheDescribeDev (pScreen, devCode, devName)  
  ScreenPtr    pScreen;  
  int          devCode;  
  char         *devName;  

ResultsdgaCacheStateChangeThe contents of devName are copied into an internal structure.
void
PurposeInforms DGA that a change has occurred to the cache state of a drawable. DgaCacheDescribeDev must have been called prior to calling this routine.
ArgumentsdgaSharedDataInfoIf state is TRUE, the drawable is currently cached. If it is FALSE, the drawable is not cached.
void
PurposeWhen a nonviewable drawable or backing store is not cached, the data pointer of the drawable should be directed toward the pixel store that exists in the shared page and the contents of the drawable should be copied into the shared page. This is automatically performed by DGA if the DGA
routines CacheDrawInit or CacheDrawCleanup return 0. However, the DDX handler itself may want to copy the drawable contents into the shared page (for performance). To do this, the DDX handler must know where to put the data. It must also know the scanline stride (linebytes). This routine supplies the necessary information necessary. This routine should only be called when the drawable has been grabbed.

Device Information Routines

In each shared information page of a drawable, DGA provides an area in which a DDX handler can place device-specific information. When anything in this area changes, the DDX handler must inform DGA so that it can signal the change to the client.

dgaDevInfoGet


  pointer  
  DgaDevInfoGet (pDraw)  
  DrawablePtr      pDraw;  

PurposeThe device-dependent area can be used by DDX handlers to transmit device-dependent information to the DDX handlers of the client foundation libraries. The format of this area is completely opaque to DGA; no interpretation is given.
Called byThis routine might need to be called from a DDX handler's DGA GrabDrawable routine to initialize device-dependent information for a drawable. It might also need to be called for a cached nonviewable drawable if the DDX handler changes the location of the cache.
ResultsIf the device alters any information in this area, it should call DgaDevInfoChange to inform DGA.
ReturnsA pointer to the device-dependent area in the shared information of the given drawable. Returns NULL if the drawable has not yet been grabbed.

dgaDevInfoChange


  void  
  DgaDevInfoChange (pDraw)  
  DrawablePtr      pDraw;  

Purpose....This routine informs DGA that a change has occurred to the device-dependent area of the drawable. A pointer to this area is returned by calling DgaCacheDevInfo. This routine must be called after any DDX handler changes to this area.

DGA and Colormaps

The colormap grabber is discussed in "Colormap Grabber Interface" on page 180. It allows DGA foundation libraries to directly load color lookup tables, bypassing the X protocol. This functionality is not required for Solaris to operate properly. The implementation of DGA libraries handles the case where colormap grabs fail and fall back to Xlib to load the lookup tables. The performance loss is minimal.
The implementation of the colormap grabber uses interfaces which are private to the CMAP package and DGA. By default, the colormap grabber is disabled for each screen. It is enabled when the handler for a given screen calls cmapScreenInit() to initialize the CMAP package for that screen.
If the DDX handler implementor chooses to disable the colormap grabber on a device that is using the CMAP package, the handler should call the function dgaDisableCmapGrabs(ScreenPtr) after the call to cmapScreenInit().

Note - Ideally, the DGA implementation should check the return value from the screen's CmapSetup function to disable and enable grabs, but unfortunately, it does not. This cannot be changed without breaking binary compatibility.