Add support for offscreen pixmaps.

This commit is contained in:
Anders Carlsson 2003-10-13 01:19:37 +00:00
parent c538fa8742
commit 47a9fab5e2
4 changed files with 188 additions and 7 deletions

View File

@ -239,7 +239,8 @@ KaaScreenInfoRec mgaKaa = {
mgaDoneCopy,
192, /* Offscreen byte alignment */
64, /* Offset pitch */
64, /* Offset pitch */
KAA_OFFSCREEN_PIXMAPS, /* Flags */
};
Bool

View File

@ -54,13 +54,17 @@ typedef struct {
typedef struct {
KdOffscreenArea *offscreenArea;
Bool swappedOut;
} KaaPixmapPrivRec, *KaaPixmapPrivPtr;
#define KaaGetScreenPriv(s) ((KaaScreenPrivPtr)(s)->devPrivates[kaaScreenPrivateIndex].ptr)
#define KaaScreenPriv(s) KaaScreenPrivPtr pKaaScr = KaaGetScreenPriv(s)
#define KaaGetPixmapPriv(p) ((KaaPixmapPrivPtr)(p)->devPrivates[kaaPixmapPrivateIndex].ptr)
#define KaaPixmapPriv(p) KaaPixmapPrivPtr pKaaPixmap = KaaGetPixmapPriv (p)
#define KaaPixmapPitch(w) (((w) + (pKaaScr->info->offscreenPitch - 1)) & ~(pKaaScr->info->offscreenPitch - 1))
#define KAA_SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = \
((KaaScreenPrivPtr) (pScreen)->devPrivates[kaaScreenPrivateIndex].ptr)->field)
@ -69,6 +73,182 @@ typedef struct {
#define MIN_OFFPIX_SIZE (320*200)
static void
kaaMoveOutPixmap (KdOffscreenArea *area)
{
PixmapPtr pPixmap = area->privData;
int dst_pitch, src_pitch;
unsigned char *dst, *src;
int i;
src_pitch = pPixmap->devKind;
dst_pitch = BitmapBytePad (pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel);
src = pPixmap->devPrivate.ptr;
dst = xalloc (dst_pitch * pPixmap->drawable.height);
if (!dst)
FatalError("Out of memory\n");
pPixmap->devKind = dst_pitch;
pPixmap->devPrivate.ptr = dst;
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
i = pPixmap->drawable.height;
while (i--) {
memcpy (dst, src, dst_pitch);
dst += dst_pitch;
src += src_pitch;
}
}
static void
kaaMoveInPixmap (KdOffscreenArea *area)
{
PixmapPtr pPixmap = area->privData;
ScreenPtr pScreen = pPixmap->drawable.pScreen;
KaaScreenPriv (pScreen);
PixmapPtr pScreenPixmap = (*pScreen->GetScreenPixmap) (pScreen);
int dst_pitch, src_pitch;
unsigned char *dst, *src;
int i;
src_pitch = pPixmap->devKind;
dst_pitch = BitmapBytePad (KaaPixmapPitch (pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel));
src = pPixmap->devPrivate.ptr;
dst = pScreenPixmap->devPrivate.ptr + area->offset;
pPixmap->devKind = dst_pitch;
pPixmap->devPrivate.ptr = dst;
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
i = pPixmap->drawable.height;
while (i--) {
memcpy (dst, src, dst_pitch);
dst += dst_pitch;
src += src_pitch;
}
}
static Bool
kaaDestroyPixmap (PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
KaaPixmapPriv (pPixmap);
KaaScreenPriv (pScreen);
Bool ret;
if (pPixmap->refcnt == 1)
{
if (pKaaPixmap->offscreenArea)
{
PixmapLink *link, *prev;
/* Free the offscreen area */
KdOffscreenFree (pKaaPixmap->offscreenArea);
if (pKaaPixmap->offscreenArea->swappedOut)
{
xfree (pPixmap->devPrivate.ptr);
pPixmap->devPrivate.ptr = NULL;
}
link = pKaaScr->offscreenPixmaps;
prev = NULL;
while (link->pPixmap != pPixmap)
{
prev = link;
link = link->next;
}
if (prev)
prev->next = link->next;
else
pKaaScr->offscreenPixmaps = link->next;
xfree (link);
}
}
KAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap);
ret = (*pScreen->DestroyPixmap) (pPixmap);
KAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, kaaDestroyPixmap);
return ret;
}
static PixmapPtr
kaaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
{
KaaScreenPriv (pScreen);
int size = w * h;
int pitch;
int bpp;
PixmapPtr pPixmap = NULL;
KaaPixmapPrivPtr pKaaPixmap;
if (kdEnabled &&
size > MIN_OFFPIX_SIZE)
{
KdOffscreenArea *area;
PixmapLink *link;
PixmapPtr pScreenPixmap;
bpp = BitsPerPixel (depth);
pitch = KaaPixmapPitch (w);
area = KdOffscreenAlloc (pScreen, pitch * h * (bpp >> 3), pKaaScr->info->offscreenByteAlign,
FALSE, kaaMoveInPixmap, kaaMoveOutPixmap, NULL);
if (!area)
goto oom;
link = xalloc (sizeof (PixmapLink));
if (!link)
{
KdOffscreenFree (area);
goto oom;
}
KAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
pPixmap = (* pScreen->CreatePixmap) (pScreen, 0, 0, depth);
KAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, kaaCreatePixmap);
pKaaPixmap = (KaaPixmapPrivPtr)pPixmap->devPrivates[kaaPixmapPrivateIndex].ptr;
pKaaPixmap->offscreenArea = area;
pScreenPixmap = (*pScreen->GetScreenPixmap)(pScreen);
pPixmap->drawable.width = w;
pPixmap->drawable.height = h;
pPixmap->drawable.bitsPerPixel = bpp;
pPixmap->devKind = pitch * (bpp >> 3);
pPixmap->devPrivate.ptr = pScreenPixmap->devPrivate.ptr + area->offset;
link->pPixmap = pPixmap;
link->next = pKaaScr->offscreenPixmaps;
area->privData = pPixmap;
pKaaScr->offscreenPixmaps = link;
return pPixmap;
}
oom:
KAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
pPixmap = (* pScreen->CreatePixmap) (pScreen, w, h, depth);
KAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, kaaCreatePixmap);
if (pPixmap)
{
pKaaPixmap = (KaaPixmapPrivPtr)pPixmap->devPrivates[kaaPixmapPrivateIndex].ptr;
pKaaPixmap->offscreenArea = NULL;
}
return pPixmap;
}
void
kaaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
@ -689,18 +869,18 @@ kaaDrawInit (ScreenPtr pScreen,
pScreen->PaintWindowBackground = kaaPaintWindow;
pScreen->PaintWindowBorder = kaaPaintWindow;
#if 0
/*
* Hookup offscreen pixmaps
*/
if (screen->off_screen_size > 0)
if ((pKaaScr->info->flags & KAA_OFFSCREEN_PIXMAPS) &&
screen->off_screen_size > 0)
{
pKaaScr->CreatePixmap = pScreen->CreatePixmap;
pScreen->CreatePixmap = kaaCreatePixmap;
pKaaScr->DestroyPixmap = pScreen->DestroyPixmap;
pScreen->DestroyPixmap = kaaDestroyPixmap;
}
#endif
return TRUE;
}

View File

@ -301,8 +301,10 @@ typedef struct _KaaScreenInfo {
int offscreenByteAlign;
int offscreenPitch;
int flags;
} KaaScreenInfoRec, *KaaScreenInfoPtr;
#define KAA_OFFSCREEN_PIXMAPS (1 << 0)
/*
* This is the only completely portable way to

View File

@ -121,8 +121,6 @@ KdOffscreenSwapOut (ScreenPtr pScreen)
while (area)
{
fprintf (stderr, "area is: %p\n", area);
if (area->area.screen && area->moveOut)
(*area->moveOut) ((KdOffscreenArea *)area);