Do a first pass of doxygen documentation of EXA. This removes the

corresponding pieces of exa-driver.txt, which were becoming stale.
    Hopefully the documentation will stay much more up-to-date this way.
    Many thanks to jbarnes for writing exa-driver.txt which was used a lot
    in writing this documentation.
This commit is contained in:
Eric Anholt 2006-03-09 23:18:15 +00:00
parent d8f8bfecce
commit ab35c3fbc1
5 changed files with 635 additions and 58 deletions

View File

@ -1,3 +1,16 @@
2006-03-09 Eric Anholt <anholt@FreeBSD.org>
* exa/exa.c:
* exa/exa.h:
* exa/exa_offscreen.c:
* exa/exa_priv.h:
* hw/xfree86/doc/devel/exa-driver.txt:
Do a first pass of doxygen documentation of EXA. This removes the
corresponding pieces of exa-driver.txt, which were becoming stale.
Hopefully the documentation will stay much more up-to-date this way.
Many thanks to jbarnes for writing exa-driver.txt which was used a lot
in writing this documentation.
2006-03-09 Matthias Hopf <mhopf@suse.de>
* configure.ac: Do Xorg configure checks for Xgl only as well

View File

@ -22,6 +22,12 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/** @file
* This file covers the initialization and teardown of EXA, and has various
* functions not responsible for performing rendering, pixmap migration, or
* memory management.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
@ -38,9 +44,15 @@ static int exaGeneration;
int exaScreenPrivateIndex;
int exaPixmapPrivateIndex;
/* Returns the offset (in bytes) within the framebuffer of the beginning of the
* given pixmap. May need to be extended in the future if we grow support for
* having multiple card-accessible areas at different offsets.
/**
* exaGetPixmapOffset() returns the offset (in bytes) within the framebuffer of
* the beginning of the given pixmap.
*
* Note that drivers are free to, and often do, munge this offset as necessary
* for handing to the hardware -- for example, translating it into a different
* aperture. This function may need to be extended in the future if we grow
* support for having multiple card-accessible offscreen, such as an AGP memory
* pool alongside the framebuffer pool.
*/
unsigned long
exaGetPixmapOffset(PixmapPtr pPix)
@ -51,16 +63,21 @@ exaGetPixmapOffset(PixmapPtr pPix)
(unsigned long)pExaScr->info->memoryBase);
}
/* Returns the pitch in bytes of the given pixmap. */
/**
* exaGetPixmapPitch() returns the pitch (in bytes) of the given pixmap.
*
* This is a helper to make driver code more obvious, due to the rather obscure
* naming of the pitch field in the pixmap.
*/
unsigned long
exaGetPixmapPitch(PixmapPtr pPix)
{
return pPix->devKind;
}
/* Returns the size in bytes of the given pixmap in
* video memory. Only valid when the vram storage has been
* allocated
/**
* exaGetPixmapSize() returns the size in bytes of the given pixmap in video
* memory. Only valid when the pixmap is currently in framebuffer.
*/
unsigned long
exaGetPixmapSize(PixmapPtr pPix)
@ -73,6 +90,17 @@ exaGetPixmapSize(PixmapPtr pPix)
return 0;
}
/**
* exaGetDrawablePixmap() returns a backing pixmap for a given drawable.
*
* @param pDrawable the drawable being requested.
*
* This function returns the backing pixmap for a drawable, whether it is a
* redirected window, unredirected window, or already a pixmap. Note that
* coordinate translation is needed when drawing to the backing pixmap of a
* redirected window, and the translation coordinates are provided by calling
* exaGetOffscreenPixmap() on the drawable.
*/
PixmapPtr
exaGetDrawablePixmap(DrawablePtr pDrawable)
{
@ -82,6 +110,10 @@ exaGetDrawablePixmap(DrawablePtr pDrawable)
return (PixmapPtr) pDrawable;
}
/**
* exaDrawableDirty() marks a pixmap backing a drawable as dirty, allowing for
* optimizations in pixmap migration when no changes have occurred.
*/
void
exaDrawableDirty (DrawablePtr pDrawable)
{
@ -301,6 +333,8 @@ exaCloseScreen(int i, ScreenPtr pScreen)
* responsibility is to check beforehand that the EXA module has a matching
* major number and sufficient minor. Drivers are responsible for freeing the
* driver structure using xfree().
*
* @return a newly allocated, zero-filled driver structure
*/
ExaDriverPtr
exaDriverAlloc(void)
@ -309,9 +343,14 @@ exaDriverAlloc(void)
}
/**
* @param pScreen screen being initialized
* @param pScreenInfo EXA driver record
*
* exaDriverInit sets up EXA given a driver record filled in by the driver.
* See the comments in ExaDriverRec for what must be filled in and what is
* optional.
* pScreenInfo should have been allocated by exaDriverAlloc(). See the
* comments in _ExaDriver for what must be filled in and what is optional.
*
* @return TRUE if EXA was successfully initialized.
*/
Bool
exaDriverInit (ScreenPtr pScreen,
@ -431,12 +470,28 @@ exaDriverInit (ScreenPtr pScreen,
return TRUE;
}
/**
* exaDriverFini tears down EXA on a given screen.
*
* @param pScreen screen being torn down.
*/
void
exaDriverFini (ScreenPtr pScreen)
{
/*right now does nothing*/
}
/**
* exaMarkSync() should be called after any asynchronous drawing by the hardware.
*
* @param pScreen screen which drawing occurred on
*
* exaMarkSync() sets a flag to indicate that some asynchronous drawing has
* happened and a WaitSync() will be necessary before relying on the contents of
* offscreen memory from the CPU's perspective. It also calls an optional
* driver MarkSync() callback, the return value of which may be used to do partial
* synchronization with the hardware in the future.
*/
void exaMarkSync(ScreenPtr pScreen)
{
ExaScreenPriv(pScreen);
@ -447,6 +502,15 @@ void exaMarkSync(ScreenPtr pScreen)
}
}
/**
* exaWaitSync() ensures that all drawing has been completed.
*
* @param pScreen screen being synchronized.
*
* Calls down into the driver to ensure that all previous drawing has completed.
* It should always be called before relying on the framebuffer contents
* reflecting previous drawing, from a CPU perspective.
*/
void exaWaitSync(ScreenPtr pScreen)
{
ExaScreenPriv(pScreen);

546
exa/exa.h
View File

@ -23,6 +23,11 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/** @file
* This is the header containing the public API of EXA for exa drivers.
*/
#ifndef EXA_H
#define EXA_H
@ -73,47 +78,183 @@ typedef struct _ExaDriver {
*/
int exa_major, exa_minor;
/* These are here because I don't want to be adding more to
* ScrnInfoRec */
/**
* memoryBase is the address of the beginning of framebuffer memory.
* The visible screen should be within memoryBase to memoryBase +
* memorySize.
*/
CARD8 *memoryBase;
/**
* offScreenBase is the offset from memoryBase of the beginning of the area
* to be managed by EXA's linear offscreen memory manager.
*
* In XFree86 DDX drivers, this is probably:
* (pScrn->displayWidth * cpp * pScrn->virtualY)
*/
unsigned long offScreenBase;
/* It's fix.smem_len.
This one could be potentially substituted by ScrnInfoRec
videoRam member, but I do not want to be doing the silly
<< 10, >>10 all over the place */
/**
* memorySize is the length (in bytes) of framebuffer memory beginning
* from memoryBase.
*
* The offscreen memory manager will manage the area beginning at
* (memoryBase + offScreenBase), with a length of (memorySize -
* offScreenBase)
*
* In XFree86 DDX drivers, this is probably (pScrn->videoRam * 1024)
*/
unsigned long memorySize;
/**
* pixmapOffsetAlign is the byte alignment necessary for pixmap offsets
* within framebuffer.
*
* Hardware typically has a required alignment of offsets, which may or may
* not be a power of two. EXA will ensure that pixmaps managed by the
* offscreen memory manager meet this alignment requirement.
*/
int pixmapOffsetAlign;
/**
* pixmapPitchAlign is the byte alignment necessary for pixmap pitches
* within the framebuffer.
*
* Hardware typically has a required alignment of pitches for acceleration.
* For 3D hardware, Composite acceleration often requires that source and
* mask pixmaps (textures) have a power-of-two pitch, which can be demanded
* using EXA_OFFSCREEN_ALIGN_POT. These pitch requirements only apply to
* pixmaps managed by the offscreen memory manager. Thus, it is up to the
* driver to ensure that the visible screen has an appropriate pitch for
* acceleration.
*/
int pixmapPitchAlign;
/**
* The flags field is bitfield of boolean values controlling EXA's behavior.
*
* The flags in clude EXA_OFFSCREEN_PIXMAPS, EXA_OFFSCREEN_ALIGN_POT, and
* EXA_TWO_BITBLT_DIRECTIONS.
*/
int flags;
/* The coordinate limitations for rendering for this hardware.
* Exa breaks larger pixmaps into smaller pieces and calls Prepare multiple times
* to handle larger pixmaps
/** @{ */
/**
* maxX controls the X coordinate limitation for rendering from the card.
* The driver should never receive a request for rendering beyond maxX
* in the X direction from the origin of a pixmap.
*/
int maxX;
/**
* maxY controls the Y coordinate limitation for rendering from the card.
* The driver should never receive a request for rendering beyond maxY
* in the Y direction from the origin of a pixmap.
*/
int maxY;
/** @} */
/* private */
ExaOffscreenArea *offScreenAreas;
Bool needsSync;
int lastMarker;
/* PrepareSolid may fail if the pixmaps can't be accelerated to/from.
* This is an important feature for handling strange corner cases
* in hardware that are poorly expressed through flags.
/** @name Solid
* @{
*/
/**
* PrepareSolid sets up the driver for doing a solid fill.
* @param pPixmap Destination pixmap
* @param alu raster operation
* @param planemask write mask for the fill
* @param fg "foreground" color for the fill
*
* This call should set up the driver for doing a series of solid fills
* through the Solid call. The alu raster op is one of the GX*
* graphics functions listed in X.h, and typically maps to a similar
* single-byte "ROP" setting in all hardware. The planemask controls
* which bits of
* the destination should be affected, and will only represent the bits up
* to the depth of pPixmap. The fg is the pixel value of the foreground
* color referred to in ROP descriptions.
*
* Note that many drivers will need to store some of the data in the driver
* private record, for sending to the hardware with each drawing command.
*
* The PrepareSolid() call is required of all drivers, but it may fail for any
* reason. Failure results in a fallback to software rendering.
*/
Bool (*PrepareSolid) (PixmapPtr pPixmap,
int alu,
Pixel planemask,
Pixel fg);
void (*Solid) (PixmapPtr pPixmap, int x1, int y1, int x2, int y2);
void (*DoneSolid) (PixmapPtr pPixmap);
/* PrepareSolid may fail if the pixmaps can't be accelerated to/from.
* This is an important feature for handling strange corner cases
* in hardware that are poorly expressed through flags.
/**
* Solid performs a solid fill set up in the last PrepareSolid call.
*
* @param pPixmap destination pixmap
* @param x1 left coordinate
* @param y1 top coordinate
* @param x2 right coordinate
* @param y2 bottom coordinate
*
* Performs the fill set up by the last PrepareSolid() call, covering the
* area from (x1,y1) to (x2,y2) in pPixmap. Note that the coordinates are
* in the coordinate space of the destination pixmap, so the driver will
* need to set up the hardware's offset and pitch for the destination
* coordinates according to the pixmap's offset and pitch within
* framebuffer. This likely means using exaGetPixmapOffset() and
* exaGetPixmapPitch().
*
* This call is required if PrepareSolid() ever succeeds.
*/
void (*Solid) (PixmapPtr pPixmap, int x1, int y1, int x2, int y2);
/**
* DoneSolid finishes a set of solid fills.
*
* @param pPixmap destination pixmap.
*
* The DoneSolid call is called at the end of a set of a series of Solid()
* calls following a PrepareSolid() that was called. This allows drivers to
* finish up emitting drawing commands that were buffered.
*
* This call is required if PrepareSolid() ever succeeds.
*/
void (*DoneSolid) (PixmapPtr pPixmap);
/** @} */
/** @name Copy
* @{
*/
/**
* PrepareCopy sets up the driver for doing a copy within offscreen memory.
* @param pSrcPixmap source pixmap
* @param pDstPixmap destination pixmap
* @param dx X copy direction
* @param dy Y copy direction
* @param alu raster operation
* @param planemask write mask for the fill
*
* This call should set up the driver for doing a series of copies from the
* the pSrcPixmap to the pDstPixmap. The dx flag will be positive if the
* hardware should do the copy from the left to the right, and dy will be
* positive if the copy should be done from the top to the bottom. This
* is to deal with self-overlapping copies when pSrcPixmap == pDstPixmap.
* If your hardware can only support blits that are (left to right, top to
* bottom) or (right to left, bottom to top), then you should set
* EXA_TWO_BITBLT_DIRECTIONS, and EXA will break down Copy operations to
* ones that meet those requirements. The alu raster op is one of the GX*
* graphics functions listed in X.h, and typically maps to a similar
* single-byte "ROP" setting in all hardware. The planemask controls which
* bits of the destination should be affected, and will only represent the
* bits up to the depth of pPixmap.
*
* Note that many drivers will need to store some of the data in the driver
* private record, for sending to the hardware with each drawing command.
*
* The PrepareCopy() call is required of all drivers, but it may fail for any
* reason. Failure results in a fallback to software rendering.
*/
Bool (*PrepareCopy) (PixmapPtr pSrcPixmap,
PixmapPtr pDstPixmap,
@ -121,6 +262,31 @@ typedef struct _ExaDriver {
int dy,
int alu,
Pixel planemask);
/**
* Copy performs a copy set up in the last PrepareCopy call.
*
* @param pDstPixmap destination pixmap
* @param srcX source X coordinate
* @param srcY source Y coordinate
* @param dstX destination X coordinate
* @param dstY destination Y coordinate
* @param width width of the rectangle to be copied
* @param height height of the rectangle to be copied.
*
* Performs the copy set up by the last PrepareCopy() call, copying the
* rectangle from (srcX, srcY) to (srcX + width, srcY + width) in the source
* pixmap to the same-sized rectangle at (dstX, dstY) in the destination
* pixmap. Those rectangles may overlap in memory, if
* pSrcPixmap == pDstPixmap. Note that this call does not receive the
* pSrcPixmap as an argument -- if it's needed in this function, it should
* be stored in the driver private during PrepareCopy(). As with Solid(),
* the coordinates are in the coordinate space of each pixmap, so the driver
* will need to set up source and destination pitches and offsets from those
* pixmaps, probably using exaGetPixmapOffset() and exaGetPixmapPitch().
*
* This call is required if PrepareCopy ever succeeds.
*/
void (*Copy) (PixmapPtr pDstPixmap,
int srcX,
int srcY,
@ -128,19 +294,106 @@ typedef struct _ExaDriver {
int dstY,
int width,
int height);
void (*DoneCopy) (PixmapPtr pDstPixmap);
/* The Composite hooks are a wrapper around the Composite operation.
* The CheckComposite occurs before pixmap migration occurs,
* and may fail for many hardware-dependent reasons.
* PrepareComposite should not fail, and the Bool return may
* not be necessary if we can
* adequately represent pixmap location/pitch limitations..
/**
* DoneCopy finishes a set of copies.
*
* @param pPixmap destination pixmap.
*
* The DoneCopy call is called at the end of a set of a series of Copy()
* calls following a PrepareCopy() that was called. This allows drivers to
* finish up emitting drawing commands that were buffered.
*
* This call is required if PrepareCopy ever succeeds.
*/
void (*DoneCopy) (PixmapPtr pDstPixmap);
/** @} */
/** @name Composite
* @{
*/
/**
* CheckComposite checks to see if a composite operation could be accelerated.
*
* @param op Render operation
* @param pSrcPicture source Picture
* @param pMaskPicture mask picture
* @param pDstPicture destination Picture
*
* The CheckComposite call checks if the driver could handle acceleration of
* op with the given source, mask, and destination pictures. This allows
* drivers to check source and destination formats, supported operations,
* transformations, and component alpha state, and send operations it can't
* support to software rendering early on. This avoids costly pixmap
* migration to the wrong places when the driver can't accelerate
* operations. Note that because migration hasn't happened, the driver
* can't know during CheckComposite what the pitches and offsets of the
* pixmaps are going to be.
*
* See PrepareComposite() for more details on likely issues that drivers
* will have in accelerating Composite operations.
*
* The CheckComposite call is recommended if PrepareComposite() is
* implemented, but is not required.
*/
Bool (*CheckComposite) (int op,
PicturePtr pSrcPicture,
PicturePtr pMaskPicture,
PicturePtr pDstPicture);
/**
* PrepareComposite sets up the driver for doing a Composite operations
* described in the Render extension protocol spec.
*
* @param op Render operation
* @param pSrcPicture source Picture
* @param pMaskPicture mask picture
* @param pDstPicture destination Picture
* @param pSrc source pixmap
* @param pMask mask pixmap
* @param pDst destination pixmap
*
* This call should set up the driver for doing a series of Composite
* operations, as described in the Render protocol spec, with the given
* pSrcPicture, pMaskPicture, and pDstPicture. The pSrc, pMask, and
* pDst are the pixmaps containing the pixel data, and should be used for
* setting the offset and pitch used for the coordinate spaces for each of
* the Pictures.
*
* Notes on interpreting Picture structures:
* - The Picture structures will always have a valid pDrawable.
* - The Picture structures will never have alphaMap set.
* - The mask Picture (and therefore pMask) may be NULL, in which case the
* operation is simply src OP dst instead of src IN mask OP dst, and
* mask coordinates should be ignored.
* - pMarkPicture may have componentAlpha set, which greatly changes
* the behavior of the Composite operation. componentAlpha has no effect
* when set on pSrcPicture or pDstPicture.
* - The source and mask Pictures may have a transformation set
* (Picture->transform != NULL), which means that the source coordinates
* should be transformed by that transformation, resulting in scaling,
* rotation, etc. The PictureTransformPoint() call can transform
* coordinates for you. Transforms have no effect on Pictures when used
* as a destination.
* - The source and mask pictures may have a filter set. PictFilterNearest
* and PictFilterBilinear are defined in the Render protocol, but others
* may be encountered, and must be handled correctly (usually by
* PrepareComposite failing, and falling back to software). Filters have
* no effect on Pictures when used as a destination.
* - The source and mask Pictures may have repeating set, which must be
* respected. Many chipsets will be unable to support repeating on
* pixmaps that have a width or height that is not a power of two.
*
* If your hardware can't support source pictures (textures) with
* non-power-of-two pitches, you should set EXA_OFFSCREEN_ALIGN_POT.
*
* Note that many drivers will need to store some of the data in the driver
* private record, for sending to the hardware with each drawing command.
*
* The PrepareCopy call is not required. However, it is highly recommended
* for performance of antialiased font rendering and performance of cairo
* applications. Failure results in a fallback to software rendering.
*/
Bool (*PrepareComposite) (int op,
PicturePtr pSrcPicture,
PicturePtr pMaskPicture,
@ -148,6 +401,31 @@ typedef struct _ExaDriver {
PixmapPtr pSrc,
PixmapPtr pMask,
PixmapPtr pDst);
/**
* Composite performs a Composite operation set up in the last
* PrepareComposite call.
*
* @param pDstPixmap destination pixmap
* @param srcX source X coordinate
* @param srcY source Y coordinate
* @param maskX source X coordinate
* @param maskY source Y coordinate
* @param dstX destination X coordinate
* @param dstY destination Y coordinate
* @param width destination rectangle width
* @param height destination rectangle height
*
* Performs the Composite operation set up by the last PrepareComposite
* call, to the rectangle from (dstX, dstY) to (dstX + width, dstY + height)
* in the destination Pixmap. Note that if a transformation was set on
* the source or mask Pictures, the source rectangles may not be the same
* size as the destination rectangles and filtering. Getting the coordinate
* transformation right at the subpixel level can be tricky, and rendercheck
* can test this for you.
*
* This call is required if PrepareComposite ever succeeds.
*/
void (*Composite) (PixmapPtr pDst,
int srcX,
int srcY,
@ -157,10 +435,51 @@ typedef struct _ExaDriver {
int dstY,
int width,
int height);
void (*DoneComposite) (PixmapPtr pDst);
/* Attempt to upload the data from src into the rectangle of the
* in-framebuffer pDst beginning at x,y and of width w,h. May fail.
/**
* DoneComposite finishes a set of Composite operations.
*
* @param pPixmap destination pixmap.
*
* The DoneComposite call is called at the end of a set of a series of
* Composite() calls following a PrepareCopy() that was called. This allows
* drivers to finish up emitting drawing commands that were buffered.
*
* This call is required if PrepareComposite ever succeeds.
*/
void (*DoneComposite) (PixmapPtr pDst);
/** @} */
/**
* UploadToScreen() loads a rectangle of data from src into pDst.
*
* @param pDst destination pixmap
* @param x destination X coordinate.
* @param y destination Y coordinate
* @param width width of the rectangle to be copied
* @param height height of the rectangle to be copied
* @param src pointer to the beginning of the source data
* @param src_pitch pitch (in bytes) of the lines of source data.
*
* UploadToScreen() copies data in system memory beginning at src (with
* pitch src_pitch) into the destination pixmap from (x, y) to
* (x + width, y + height). This is typically done with hostdata uploads,
* where the CPU sets up a blit command on the hardware with instructions
* that the blit data will be fed through some sort of aperture on the card.
*
* If UploadToScreen is performed asynchronously, it is up to the driver to
* call exaMarkSync(). This is in contrast to most other acceleration calls
* in EXA.
*
* UploadToScreen can aid in pixmap migration, but is most important for
* the performance of exaGlyphs (antialiased font drawing) by allowing
* pipelining of data uploads, avoiding a sync of the card after each glyph.
*
* @return TRUE if the driver successfully uploaded the data. FALSE
* indicates that EXA should fall back to doing the upload in software.
*
* UploadToScreen() is not required, but is recommended if Composite
* acceleration is supported.
*/
Bool (*UploadToScreen) (PixmapPtr pDst,
int x,
@ -169,13 +488,63 @@ typedef struct _ExaDriver {
int h,
char *src,
int src_pitch);
/**
* UploadToScratch() is used to upload a pixmap to a scratch area for
* acceleration.
*
* @param pSrc source pixmap in host memory
* @param pDst fake, scratch pixmap to be set up in offscreen memory.
*
* The UploadToScratch() call was added to support Xati before Xati had
* support for hostdata uploads and before exaGlyphs() was written. It
* behaves incorrectly (uses an invalid pixmap as pDst), and UploadToScreen()
* should be implemented instead.
*
* Drivers implementing UploadToScratch() had to set up space (likely in a
* statically allocated area) in offscreen memory, copy pSrc to that
* scratch area, and adust pDst->devKind for the pitch and
* pDst->devPrivate.ptr for the pointer to that scratch area. The driver
* was responsible for syncing (as it was implemented using memcpy() in
* Xati), and only the data from the last UploadToScratch() was guaranteed to
* be valid at any given time.
*
* UploadToScratch() should not be implemented by drivers, and will likely be
* removed in a future version of EXA.
*/
Bool (*UploadToScratch) (PixmapPtr pSrc,
PixmapPtr pDst);
/* Attempt to download the rectangle from the in-framebuffer pSrc into
* dst, given the pitch. May fail. Since it is likely
* accelerated, a markSync will follow it as with other acceleration
* hooks.
/**
* DownloadFromScreen loads a rectangle of data from @param pSrc into
* @param dst
*
* @param pSrc source pixmap
* @param x source X coordinate.
* @param y source Y coordinate
* @param width width of the rectangle to be copied
* @param height height of the rectangle to be copied
* @param dst pointer to the beginning of the destination data
* @param dst_pitch pitch (in bytes) of the lines of destination data.
*
* DownloadFromScreen copies data from offscreen memory in pSrc from
* (x, y) to (x + width, y + height), to system memory starting at
* dst (with pitch dst_pitch). This would usually be done
* using scatter-gather DMA, supported by a DRM call, or by blitting to AGP
* and then synchronously reading from AGP. Because the implementation
* might be synchronous, EXA leaves it up to the driver to call
* exaMarkSync() if DownloadFromScreen was asynchronous. This is in
* contrast to most other acceleration calls in EXA.
*
* DownloadFromScreen can aid in the largest bottleneck in pixmap migration,
* which is the read from framebuffer when evicting pixmaps from framebuffer
* memory. Thus, it is highly recommended, even though implementations are
* typically complicated.
*
* @return TRUE if the driver successfully downloaded the data. FALSE
* indicates that EXA should fall back to doing the download in software.
*
* UploadToScreen is not required, but is highly recommended.
*/
Bool (*DownloadFromScreen)(PixmapPtr pSrc,
int x, int y,
@ -183,34 +552,116 @@ typedef struct _ExaDriver {
char *dst, int dst_pitch);
/* Should return a hrdware-dependent marker number which can
* be waited for with WaitMarker. It can be not implemented in which
* case WaitMarker must wait for idle on any given marker
* be waited for with WaitMarker(). It can be not implemented in which
* case WaitMarker() must wait for idle on any given marker
* number.
*/
/**
* MarkSync() requests that the driver mark a synchronization point, returning
* an driver-devined integer marker which could be requested for
* synchronization to later in WaitMarker(). This might be used in the future
* to avoid waiting for full hardware stalls before accessing pixmap data
* with the CPU, but is not important in the current incarnation of EXA.
*
* MarkSync() is optional.
*/
int (*MarkSync) (ScreenPtr pScreen);
/**
* WaitMarker() waits for all rendering before the given marker to have
* completed. If the driver does not implement MarkSync(), marker is
* meaningless, and all rendering by the hardware should be completed before
* WaitMarker() returns.
*
* WaitMarker() is required of all drivers.
*/
void (*WaitMarker) (ScreenPtr pScreen, int marker);
/* These are wrapping all fb or composite operations that will cause
* a direct access to the framebuffer. You can use them to update
* endian swappers, force migration to RAM, or whatever else you find
* useful at this point. EXA can stack up to 3 calls to Prepare/Finish
* access, though they will have a different index. If your hardware
* doesn't have enough separate configurable swapper, you can return
* FALSE from PrepareAccess() to force EXA to migrate the pixmap to RAM.
* Note that DownloadFromScreen and UploadToScreen can both be called
* between PrepareAccess() and FinishAccess(). If they need to use a
* swapper, they should save & restore its setting.
/** @{ */
/**
* PrepareAccess() is called before CPU access to an offscreen pixmap.
*
* @param pPix the pixmap being accessed
* @param index the index of the pixmap being accessed.
*
* PrepareAccess() will be called before CPU access to an offscreen pixmap.
* This can be used to set up hardware surfaces for byteswapping or
* untiling, or to adjust the pixmap's devPrivate.ptr for the purpose of
* making CPU access use a different aperture.
*
* The index is one of EXA_PREPARE_DEST, EXA_PREPARE_SRC, or EXA_PREPARE_MASK,
* indicating which pixmap is in question. Since only up to three
* pixmaps will have PrepareAccess() called on them per operation, drivers
* can have a small, statically-allocated space to maintain state
* for PrepareAccess() and FinishAccess() in. Note that the same pixmap may have
* PrepareAccess() called on it more than once, for example when doing a copy
* within the same pixmap (so it gets PrepareAccess as EXA_PREPARE_DEST and
* then as EXA_PREPARE_SRC).
*
* @return TRUE if PrepareAccess() successfully prepared the pixmap for CPU
* drawing. Failure means that EXA should migrate the pixmap out of
* offscreen memory, but this code path is currently broken. Note that
* DownloadFromScreen() will be called in case of a PrepareAccess() failure.
* Also, PrepareAccess() may not fail on a pixmap representing the front
* buffer, because the front buffer may not be migrated.
*/
Bool (*PrepareAccess)(PixmapPtr pPix, int index);
/**
* FinishAccess() is called after CPU access to an offscreen pixmap.
*
* @param pPix the pixmap being accessed
* @param index the index of the pixmap being accessed.
*
* FinishAccess() will be called after finishing CPU access of an offscreen
* pixmap set up by PrepareAccess(). Note that the FinishAccess() will not be
* called if PrepareAccess() failed and the pixmap was migrated out.
*/
void (*FinishAccess)(PixmapPtr pPix, int index);
/** @name PrepareAccess() and FinishAccess() indices
* @{
*/
/**
* EXA_PREPARE_DEST is the index for a pixmap that may be drawn to or
* read from.
*/
#define EXA_PREPARE_DEST 0
/**
* EXA_PREPARE_SRC is the index for a pixmap that may be read from
*/
#define EXA_PREPARE_SRC 1
/**
* EXA_PREPARE_SRC is the index for a second pixmap that may be read
* from.
*/
#define EXA_PREPARE_MASK 2
/** @} */
/** @} */
} ExaDriverRec, *ExaDriverPtr;
#define EXA_OFFSCREEN_PIXMAPS (1 << 0)
#define EXA_OFFSCREEN_ALIGN_POT (1 << 1)
#define EXA_TWO_BITBLT_DIRECTIONS (1 << 2)
/** @name EXA driver flags
* @{
*/
/**
* EXA_OFFSCREEN_PIXMAPS indicates to EXA that the driver can support
* offscreen pixmaps.
*/
#define EXA_OFFSCREEN_PIXMAPS (1 << 0)
/**
* EXA_OFFSCREEN_ALIGN_POT indicates to EXA that the driver needs pixmaps
* to have a power-of-two pitch.
*/
#define EXA_OFFSCREEN_ALIGN_POT (1 << 1)
/**
* EXA_TWO_BITBLT_DIRECTIONS indicates to EXA that the driver can only
* support copies that are (left-to-right, top-to-bottom) or
* (right-to-left, bottom-to-top).
*/
#define EXA_TWO_BITBLT_DIRECTIONS (1 << 2)
/** @} */
ExaDriverPtr
exaDriverAlloc(void);
@ -227,9 +678,6 @@ exaMarkSync(ScreenPtr pScreen);
void
exaWaitSync(ScreenPtr pScreen);
Bool
exaOffscreenInit(ScreenPtr pScreen);
ExaOffscreenArea *
exaOffscreenAlloc(ScreenPtr pScreen, int size, int align,
Bool locked,

View File

@ -20,6 +20,14 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/** @file
* This allocator allocates blocks of memory by maintaining a list of areas
* and a score for each area. As an area is marked used, its score is
* incremented, and periodically all of the areas have their scores decayed by
* a fraction. When allocating, the contiguous block of areas with the minimum
* score is found and evicted in order to make room for the new allocation.
*/
#include "exa_priv.h"
#include <limits.h>
@ -63,6 +71,26 @@ ExaOffscreenKickOut (ScreenPtr pScreen, ExaOffscreenArea *area)
return exaOffscreenFree (pScreen, area);
}
/**
* exaOffscreenAlloc allocates offscreen memory
*
* @param pScreen current screen
* @param size size in bytes of the allocation
* @param align byte alignment requirement for the offset of the allocated area
* @param locked whether the allocated area is locked and can't be kicked out
* @param save callback for when the area is evicted from memory
* @param privdata private data for the save callback.
*
* Allocates offscreen memory from the device associated with pScreen. size and
* align deteremine where and how large the allocated area is, and locked will
* mark whether it should be held in card memory. privdata may be any pointer
* for the save callback when the area is removed.
*
* Note that locked areas do get evicted on VT switch, because during that time
* all offscreen memory becomes inaccessible. This may change in the future,
* but drivers should be aware of this and provide a callback to mark that their
* locked allocation was evicted, and then restore it if necessary on EnterVT.
*/
ExaOffscreenArea *
exaOffscreenAlloc (ScreenPtr pScreen, int size, int align,
Bool locked,
@ -289,6 +317,19 @@ ExaOffscreenMerge (ExaOffscreenArea *area)
xfree (next);
}
/**
* exaOffscreenFree frees an allocation.
*
* @param pScreen current screen
* @param area offscreen area to free
*
* exaOffscreenFree frees an allocation created by exaOffscreenAlloc. Note that
* the save callback of the area is not called, and it is up to the driver to
* do any cleanup necessary as a result.
*
* @return pointer to the newly freed area. This behavior should not be relied
* on.
*/
ExaOffscreenArea *
exaOffscreenFree (ScreenPtr pScreen, ExaOffscreenArea *area)
{
@ -352,6 +393,14 @@ ExaOffscreenMarkUsed (PixmapPtr pPixmap)
}
}
/**
* exaOffscreenInit initializes the offscreen memory manager.
*
* @param pScreen current screen
*
* exaOffscreenInit is called by exaDriverInit to set up the memory manager for
* the screen, if any offscreen memory is available.
*/
Bool
exaOffscreenInit (ScreenPtr pScreen)
{

View File

@ -281,6 +281,9 @@ ExaOffscreenSwapOut (ScreenPtr pScreen);
void
ExaOffscreenSwapIn (ScreenPtr pScreen);
Bool
exaOffscreenInit(ScreenPtr pScreen);
void
ExaOffscreenFini (ScreenPtr pScreen);