summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/kdrive/mach64/mach64draw.c2
-rw-r--r--hw/kdrive/mga/mga.c26
-rw-r--r--hw/kdrive/mga/mga.h2
-rw-r--r--hw/kdrive/mga/mgadraw.c81
-rw-r--r--hw/kdrive/nvidia/nvidiadraw.c2
-rw-r--r--hw/kdrive/r128/r128draw.c2
-rw-r--r--hw/kdrive/smi/smidraw.c2
-rw-r--r--hw/kdrive/src/Makefile.am1
-rw-r--r--hw/kdrive/src/kaa.c143
-rw-r--r--hw/kdrive/src/kdrive.c6
-rw-r--r--hw/kdrive/src/kdrive.h49
-rw-r--r--hw/kdrive/src/koffscreen.c200
12 files changed, 434 insertions, 82 deletions
diff --git a/hw/kdrive/mach64/mach64draw.c b/hw/kdrive/mach64/mach64draw.c
index c02f774d9..0847e506c 100644
--- a/hw/kdrive/mach64/mach64draw.c
+++ b/hw/kdrive/mach64/mach64draw.c
@@ -224,7 +224,7 @@ mach64DoneCopy (void)
{
}
-KaaScreenPrivRec mach64Kaa = {
+KaaScreenInfoRec mach64Kaa = {
mach64PrepareSolid,
mach64Solid,
mach64DoneSolid,
diff --git a/hw/kdrive/mga/mga.c b/hw/kdrive/mga/mga.c
index c4a473e9c..05994dae8 100644
--- a/hw/kdrive/mga/mga.c
+++ b/hw/kdrive/mga/mga.c
@@ -54,7 +54,6 @@ mgaCardInit (KdCardInfo *card)
Bool
mgaScreenInit (KdScreenInfo *screen)
{
- MgaCardInfo *mgac = screen->card->driver;
MgaScreenInfo *mgas;
int screen_size, memory;
@@ -84,13 +83,13 @@ mgaScreenInit (KdScreenInfo *screen)
memory -= screen_size;
if (memory > screen->fb[0].byteStride)
{
- mgas->off_screen = mgas->screen + screen_size;
- mgas->off_screen_size = memory;
+ screen->off_screen_base = screen_size;
+ screen->off_screen_size = memory;
}
else
{
- mgas->off_screen = 0;
- mgas->off_screen_size = 0;
+ screen->off_screen_base = 0;
+ screen->off_screen_size = 0;
}
screen->driver = mgas;
return TRUE;
@@ -115,8 +114,6 @@ mgaFinishInitScreen (ScreenPtr pScreen)
void
mgaPreserve (KdCardInfo *card)
{
- MgaCardInfo *mgac = card->driver;
-
vesaPreserve (card);
}
@@ -166,6 +163,13 @@ mgaResetMMIO (KdCardInfo *card, MgaCardInfo *mgac)
}
Bool
+mgaDPMS (ScreenPtr pScreen, int mode)
+{
+ /* XXX */
+ return TRUE;
+}
+
+Bool
mgaEnable (ScreenPtr pScreen)
{
KdScreenPriv (pScreen);
@@ -187,14 +191,8 @@ mgaDisable (ScreenPtr pScreen)
MgaCardInfo *mgac = pScreenPriv->card->driver;
mgaResetMMIO (pScreenPriv->card, mgac);
- vesaDisable (pScreen);
-}
-Bool
-mgaDPMS (ScreenPtr pScreen, int mode)
-{
- /* XXX */
- return TRUE;
+ vesaDisable (pScreen);
}
void
diff --git a/hw/kdrive/mga/mga.h b/hw/kdrive/mga/mga.h
index 17f7e9095..408db3acb 100644
--- a/hw/kdrive/mga/mga.h
+++ b/hw/kdrive/mga/mga.h
@@ -96,8 +96,6 @@ typedef struct _mgaCardInfo {
typedef struct _mgaScreenInfo {
VesaScreenPrivRec vesa;
CARD8 *screen;
- CARD8 *off_screen;
- int off_screen_size;
int pitch;
int pw;
diff --git a/hw/kdrive/mga/mgadraw.c b/hw/kdrive/mga/mgadraw.c
index 07ceea517..d080d0fa9 100644
--- a/hw/kdrive/mga/mgadraw.c
+++ b/hw/kdrive/mga/mgadraw.c
@@ -48,14 +48,12 @@ CARD32 mgaRop[16] = {
static VOL8 *mmio;
int fifo_size;
-int pitch;
+int pitch, src_pitch;
int dir;
void
mgaWaitAvail (int n)
{
- int i;
-
if (fifo_size < n) {
while ((fifo_size = MGA_IN32 (mmio, MGA_REG_FIFOSTATUS) & 0xff) < n)
;
@@ -84,25 +82,43 @@ mgaSetup (ScreenPtr pScreen, int wait)
if (!mmio)
return FALSE;
- mgaWaitAvail (wait + 7);
- MGA_OUT32 (mmio, MGA_REG_PITCH, mgas->pitch);
- MGA_OUT32 (mmio, MGA_REG_SRCORG, 0);
- MGA_OUT32 (mmio, MGA_REG_DSTORG, 0);
+ mgaWaitAvail (wait + 4);
MGA_OUT32 (mmio, MGA_REG_MACCESS, mgas->pw);
MGA_OUT32 (mmio, MGA_REG_CXBNDRY, 0xffff0000);
MGA_OUT32 (mmio, MGA_REG_YTOP, 0x00000000);
MGA_OUT32 (mmio, MGA_REG_YBOT, 0x007fffff);
+
+ return TRUE;
}
Bool
mgaPrepareSolid (DrawablePtr pDrawable, int alu, Pixel pm, Pixel fg)
{
+ KdScreenPriv(pDrawable->pScreen);
+ mgaScreenInfo (pScreenPriv);
int cmd;
cmd = MGA_OPCOD_TRAP | MGA_DWGCTL_SOLID | MGA_DWGCTL_ARZERO | MGA_DWGCTL_SGNZERO |
MGA_DWGCTL_SHIFTZERO | mgaRop[alu];
- mgaSetup (pDrawable->pScreen, 3);
+ mgaSetup (pDrawable->pScreen, 5);
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ MGA_OUT32 (mmio, MGA_REG_DSTORG, 0);
+ MGA_OUT32 (mmio, MGA_REG_PITCH, pitch);
+ }
+ else
+ {
+ PixmapPtr pPixmap = (PixmapPtr)pDrawable;
+ int dst_org;
+
+ dst_org = (int)pPixmap->devPrivate.ptr - (int)mgas->screen;
+
+ MGA_OUT32 (mmio, MGA_REG_DSTORG, dst_org);
+ MGA_OUT32 (mmio, MGA_REG_PITCH, pPixmap->devKind / (pPixmap->drawable.bitsPerPixel >> 3));
+ }
+
MGA_OUT32 (mmio, MGA_REG_DWGCTL, cmd);
MGA_OUT32 (mmio, MGA_REG_FCOL, fg);
MGA_OUT32 (mmio, MGA_REG_PLNWT, pm);
@@ -114,7 +130,8 @@ void
mgaSolid (int x1, int y1, int x2, int y2)
{
mgaWaitAvail (2);
- MGA_OUT32 (mmio, MGA_REG_FXBNDRY, (x2 << 16) | x1 & 0xffff);
+
+ MGA_OUT32 (mmio, MGA_REG_FXBNDRY, (x2 << 16) | (x1 & 0xffff));
MGA_OUT32 (mmio, MGA_REG_YDSTLEN | MGA_REG_EXEC, (y1 << 16) | (y2 - y1));
}
@@ -139,13 +156,44 @@ mgaPrepareCopy (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, int dx, int
dir |= BLIT_UP;
if (dx < 0)
dir |= BLIT_LEFT;
+
+ mgaSetup (pDstDrawable->pScreen, 6);
+
+ if (pSrcDrawable->type == DRAWABLE_WINDOW)
+ {
+ MGA_OUT32 (mmio, MGA_REG_SRCORG, 0);
+
+ src_pitch = pitch;
+ }
+ else
+ {
+ KdScreenPriv(pSrcDrawable->pScreen);
+ mgaScreenInfo (pScreenPriv);
+ PixmapPtr pPixmap = (PixmapPtr)pSrcDrawable;
+
+ MGA_OUT32 (mmio, MGA_REG_SRCORG, ((int)pPixmap->devPrivate.ptr - (int)mgas->screen));
+ src_pitch = pPixmap->devKind / (pPixmap->drawable.bitsPerPixel >> 3);
+ }
- mgaSetup (pDstDrawable->pScreen, 4);
+ if (pDstDrawable->type == DRAWABLE_WINDOW)
+ {
+ MGA_OUT32 (mmio, MGA_REG_DSTORG, 0);
+ MGA_OUT32 (mmio, MGA_REG_PITCH, pitch);
+ }
+ else
+ {
+ KdScreenPriv(pDstDrawable->pScreen);
+ mgaScreenInfo (pScreenPriv);
+ PixmapPtr pPixmap = (PixmapPtr)pDstDrawable;
+
+ MGA_OUT32 (mmio, MGA_REG_DSTORG, ((int)pPixmap->devPrivate.ptr - (int)mgas->screen));
+ MGA_OUT32 (mmio, MGA_REG_PITCH, pPixmap->devKind / (pPixmap->drawable.bitsPerPixel >> 3));
+ }
MGA_OUT32 (mmio, MGA_REG_DWGCTL, cmd);
MGA_OUT32 (mmio, MGA_REG_SGN, dir);
MGA_OUT32 (mmio, MGA_REG_PLNWT, pm);
- MGA_OUT32 (mmio, MGA_REG_AR5, pitch * (dy < 0 ? -1 : 1) );
+ MGA_OUT32 (mmio, MGA_REG_AR5, src_pitch * (dy < 0 ? -1 : 1) );
return TRUE;
}
@@ -162,7 +210,7 @@ mgaCopy (int srcX, int srcY, int dstX, int dstY, int w, int h)
}
w--;
- start = end = srcY * pitch + srcX;
+ start = end = srcY * src_pitch + srcX;
if (dir & BLIT_LEFT)
start += w;
@@ -173,7 +221,6 @@ mgaCopy (int srcX, int srcY, int dstX, int dstY, int w, int h)
MGA_OUT32 (mmio, MGA_REG_AR0, end);
MGA_OUT32 (mmio, MGA_REG_AR3, start);
MGA_OUT32 (mmio, MGA_REG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff));
-
MGA_OUT32 (mmio, MGA_REG_YDSTLEN | MGA_REG_EXEC, (dstY << 16) | h);
}
@@ -182,7 +229,7 @@ mgaDoneCopy (void)
{
}
-KaaScreenPrivRec mgaKaa = {
+KaaScreenInfoRec mgaKaa = {
mgaPrepareSolid,
mgaSolid,
mgaDoneSolid,
@@ -190,13 +237,17 @@ KaaScreenPrivRec mgaKaa = {
mgaPrepareCopy,
mgaCopy,
mgaDoneCopy,
+
+ 192, /* Offscreen byte alignment */
+ 64, /* Offset pitch */
};
Bool
mgaDrawInit (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
-
+ mgaScreenInfo (pScreenPriv);
+
if (!kaaDrawInit (pScreen, &mgaKaa))
return FALSE;
diff --git a/hw/kdrive/nvidia/nvidiadraw.c b/hw/kdrive/nvidia/nvidiadraw.c
index c523562e2..840b0752c 100644
--- a/hw/kdrive/nvidia/nvidiadraw.c
+++ b/hw/kdrive/nvidia/nvidiadraw.c
@@ -156,7 +156,7 @@ nvidiaDoneCopy (void)
{
}
-KaaScreenPrivRec nvidiaKaa = {
+KaaScreenInfoRec nvidiaKaa = {
nvidiaPrepareSolid,
nvidiaSolid,
nvidiaDoneSolid,
diff --git a/hw/kdrive/r128/r128draw.c b/hw/kdrive/r128/r128draw.c
index 3dd806979..7a8de7479 100644
--- a/hw/kdrive/r128/r128draw.c
+++ b/hw/kdrive/r128/r128draw.c
@@ -212,7 +212,7 @@ r128DoneCopy (void)
{
}
-KaaScreenPrivRec r128Kaa = {
+KaaScreenInfoRec r128Kaa = {
r128PrepareSolid,
r128Solid,
r128DoneSolid,
diff --git a/hw/kdrive/smi/smidraw.c b/hw/kdrive/smi/smidraw.c
index 161fe91f0..3b0033586 100644
--- a/hw/kdrive/smi/smidraw.c
+++ b/hw/kdrive/smi/smidraw.c
@@ -233,7 +233,7 @@ smiDoneCopy (void)
{
}
-KaaScreenPrivRec smiKaa = {
+KaaScreenInfoRec smiKaa = {
smiPrepareSolid,
smiSolid,
smiDoneSolid,
diff --git a/hw/kdrive/src/Makefile.am b/hw/kdrive/src/Makefile.am
index f6de7ec7f..95677f9f6 100644
--- a/hw/kdrive/src/Makefile.am
+++ b/hw/kdrive/src/Makefile.am
@@ -19,6 +19,7 @@ libkdrive_a_SOURCES = \
kmap.c \
kmode.c \
knoop.c \
+ koffscreen.c \
kpict.c \
kshadow.c \
ktest.c \
diff --git a/hw/kdrive/src/kaa.c b/hw/kdrive/src/kaa.c
index 162dae6f6..49a2885bd 100644
--- a/hw/kdrive/src/kaa.c
+++ b/hw/kdrive/src/kaa.c
@@ -3,6 +3,8 @@
*
* Copyright © 2001 Keith Packard
*
+ * Partly based on code that is Copyright © The XFree86 Project Inc.
+ *
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
@@ -29,10 +31,44 @@
#include "fontstruct.h"
#include "dixfontstr.h"
-int kaaGeneration;
-int kaaScreenPrivateIndex;
+int kaaGeneration;
+int kaaScreenPrivateIndex;
+int kaaPixmapPrivateIndex;
+
+typedef struct _PixmapLink {
+ PixmapPtr pPixmap;
+
+ struct _PixmapLink *next;
+} PixmapLink;
+
+typedef struct {
+ KaaScreenInfoPtr info;
+
+ int offscreenSize;
+ int offscreenBase;
+ PixmapLink *offscreenPixmaps;
+
+ CreatePixmapProcPtr CreatePixmap;
+ DestroyPixmapProcPtr DestroyPixmap;
+} KaaScreenPrivRec, *KaaScreenPrivPtr;
+
+typedef struct {
+ KdOffscreenArea *offscreenArea;
+ Bool swappedOut;
+} KaaPixmapPrivRec, *KaaPixmapPrivPtr;
+
+
+#define KaaGetScreenPriv(s) ((KaaScreenPrivPtr)(s)->devPrivates[kaaScreenPrivateIndex].ptr)
+#define KaaScreenPriv(s) KaaScreenPrivPtr pKaaScr = KaaGetScreenPriv(s)
+
+#define KAA_SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = \
+ ((KaaScreenPrivPtr) (pScreen)->devPrivates[kaaScreenPrivateIndex].ptr)->field)
+
+#define KAA_SCREEN_EPILOGUE(pScreen, field, wrapper)\
+ ((pScreen)->field = wrapper)
+
+#define MIN_OFFPIX_SIZE (320*200)
-#define KaaScreenPriv(s) KaaScreenPrivPtr pKaaScr = (KaaScreenPrivPtr) (s)->devPrivates[kaaScreenPrivateIndex].ptr
void
kaaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
@@ -50,10 +86,10 @@ kaaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
if (!pScreenPriv->enabled ||
pGC->fillStyle != FillSolid ||
- !(*pKaaScr->PrepareSolid) (pDrawable,
- pGC->alu,
- pGC->planemask,
- pGC->fgPixel))
+ !(*pKaaScr->info->PrepareSolid) (pDrawable,
+ pGC->alu,
+ pGC->planemask,
+ pGC->fgPixel))
{
KdCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
return;
@@ -87,7 +123,7 @@ kaaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
nbox = REGION_NUM_RECTS (pClip);
if (nbox == 1)
{
- (*pKaaScr->Solid) (fullX1, fullY1, fullX2, fullY1 + 1);
+ (*pKaaScr->info->Solid) (fullX1, fullY1, fullX2, fullY1 + 1);
}
else
{
@@ -103,13 +139,13 @@ kaaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
if (partX2 > fullX2)
partX2 = fullX2;
if (partX2 > partX1)
- (*pKaaScr->Solid) (partX1, fullY1, partX2, fullY1 + 1);
+ (*pKaaScr->info->Solid) (partX1, fullY1, partX2, fullY1 + 1);
}
pbox++;
}
}
}
- (*pKaaScr->DoneSolid) ();
+ (*pKaaScr->info->DoneSolid) ();
KdMarkSync(pDrawable->pScreen);
}
@@ -133,29 +169,31 @@ kaaCopyNtoN (DrawablePtr pSrcDrawable,
CARD32 flags;
CARD32 cmd;
CARD8 alu;
-
+
if (pScreenPriv->enabled &&
pSrcDrawable->type == DRAWABLE_WINDOW &&
- (*pKaaScr->PrepareCopy) (pSrcDrawable,
- pDstDrawable,
- dx,
- dy,
- pGC ? pGC->alu : GXcopy,
- pGC ? pGC->planemask : FB_ALLONES))
+ (*pKaaScr->info->PrepareCopy) (pSrcDrawable,
+ pDstDrawable,
+ dx,
+ dy,
+ pGC ? pGC->alu : GXcopy,
+ pGC ? pGC->planemask : FB_ALLONES))
{
while (nbox--)
{
- (*pKaaScr->Copy) (pbox->x1 + dx, pbox->y1 + dy,
- pbox->x1, pbox->y1,
- pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1);
+ (*pKaaScr->info->Copy) (pbox->x1 + dx, pbox->y1 + dy,
+ pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
pbox++;
}
- (*pKaaScr->DoneCopy) ();
+ (*pKaaScr->info->DoneCopy) ();
KdMarkSync(pDstDrawable->pScreen);
}
else
{
+ KdScreenPriv (pDstDrawable->pScreen);
+
KdCheckSync (pDstDrawable->pScreen);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
@@ -191,10 +229,10 @@ kaaPolyFillRect(DrawablePtr pDrawable,
if (!pScreenPriv->enabled ||
pGC->fillStyle != FillSolid ||
- !(*pKaaScr->PrepareSolid) (pDrawable,
- pGC->alu,
- pGC->planemask,
- pGC->fgPixel))
+ !(*pKaaScr->info->PrepareSolid) (pDrawable,
+ pGC->alu,
+ pGC->planemask,
+ pGC->fgPixel))
{
KdCheckPolyFillRect (pDrawable, pGC, nrect, prect);
return;
@@ -233,7 +271,7 @@ kaaPolyFillRect(DrawablePtr pDrawable,
n = REGION_NUM_RECTS (pClip);
if (n == 1)
{
- (*pKaaScr->Solid) (fullX1, fullY1, fullX2, fullY2);
+ (*pKaaScr->info->Solid) (fullX1, fullY1, fullX2, fullY2);
}
else
{
@@ -260,12 +298,12 @@ kaaPolyFillRect(DrawablePtr pDrawable,
pbox++;
if (partX1 < partX2 && partY1 < partY2)
- (*pKaaScr->Solid) (partX1, partY1,
- partX2, partY2);
+ (*pKaaScr->info->Solid) (partX1, partY1,
+ partX2, partY2);
}
}
}
- (*pKaaScr->DoneSolid) ();
+ (*pKaaScr->info->DoneSolid) ();
KdMarkSync(pDrawable->pScreen);
}
@@ -287,7 +325,7 @@ kaaSolidBoxClipped (DrawablePtr pDrawable,
CARD32 cmd;
if (!pScreenPriv->enabled ||
- !(*pKaaScr->PrepareSolid) (pDrawable, GXcopy, pm, fg))
+ !(*pKaaScr->info->PrepareSolid) (pDrawable, GXcopy, pm, fg))
{
KdCheckSync (pDrawable->pScreen);
fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
@@ -322,9 +360,9 @@ kaaSolidBoxClipped (DrawablePtr pDrawable,
if (partY2 <= partY1)
continue;
- (*pKaaScr->Solid) (partX1, partY1, partX2, partY2);
+ (*pKaaScr->info->Solid) (partX1, partY1, partX2, partY2);
}
- (*pKaaScr->DoneSolid) ();
+ (*pKaaScr->info->DoneSolid) ();
KdMarkSync(pDrawable->pScreen);
}
@@ -520,6 +558,7 @@ kaaCreateGC (GCPtr pGC)
return TRUE;
}
+
void
kaaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
@@ -555,17 +594,17 @@ kaaFillRegionSolid (DrawablePtr pDrawable,
KaaScreenPriv(pDrawable->pScreen);
if (pScreenPriv->enabled &&
- (*pKaaScr->PrepareSolid) (pDrawable, GXcopy, FB_ALLONES, pixel))
+ (*pKaaScr->info->PrepareSolid) (pDrawable, GXcopy, FB_ALLONES, pixel))
{
int nbox = REGION_NUM_RECTS (pRegion);
BoxPtr pBox = REGION_RECTS (pRegion);
while (nbox--)
{
- (*pKaaScr->Solid) (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
+ (*pKaaScr->info->Solid) (pBox->x1, pBox->y1, pBox->x2, pBox->y2);
pBox++;
}
- (*pKaaScr->DoneSolid) ();
+ (*pKaaScr->info->DoneSolid) ();
KdMarkSync(pDrawable->pScreen);
}
else
@@ -613,14 +652,30 @@ kaaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
Bool
kaaDrawInit (ScreenPtr pScreen,
- KaaScreenPrivPtr pScreenPriv)
+ KaaScreenInfoPtr pScreenInfo)
{
+ KaaScreenPrivPtr pKaaScr;
+ KdScreenInfo *screen = KdGetScreenPriv (pScreen)->screen;
+
if (kaaGeneration != serverGeneration)
{
kaaScreenPrivateIndex = AllocateScreenPrivateIndex();
+ kaaPixmapPrivateIndex = AllocatePixmapPrivateIndex();
kaaGeneration = serverGeneration;
}
- pScreen->devPrivates[kaaScreenPrivateIndex].ptr = (pointer) pScreenPriv;
+
+ if (!AllocatePixmapPrivate(pScreen, kaaPixmapPrivateIndex, sizeof(KaaPixmapPrivRec)))
+ return FALSE;
+
+ pKaaScr = xalloc (sizeof (KaaScreenPrivRec));
+
+ if (!pKaaScr)
+ return FALSE;
+
+ pKaaScr->info = pScreenInfo;
+ pKaaScr->offscreenPixmaps = NULL;
+
+ pScreen->devPrivates[kaaScreenPrivateIndex].ptr = (pointer) pKaaScr;
/*
* Hook up asynchronous drawing
@@ -634,6 +689,18 @@ kaaDrawInit (ScreenPtr pScreen,
pScreen->PaintWindowBackground = kaaPaintWindow;
pScreen->PaintWindowBorder = kaaPaintWindow;
+#if 0
+ /*
+ * Hookup offscreen pixmaps
+ */
+ if (screen->off_screen_size > 0)
+ {
+ pKaaScr->CreatePixmap = pScreen->CreatePixmap;
+ pScreen->CreatePixmap = kaaCreatePixmap;
+ pKaaScr->DestroyPixmap = pScreen->DestroyPixmap;
+ pScreen->DestroyPixmap = kaaDestroyPixmap;
+ }
+#endif
return TRUE;
}
diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c
index ab75db7f4..02e6e1d1b 100644
--- a/hw/kdrive/src/kdrive.c
+++ b/hw/kdrive/src/kdrive.c
@@ -214,6 +214,7 @@ KdDisableScreen (ScreenPtr pScreen)
if (!pScreenPriv->closed)
KdSetRootClip (pScreen, FALSE);
KdDisableColormap (pScreen);
+ KdOffscreenSwapOut (pScreen);
if (!pScreenPriv->screen->dumb)
(*pScreenPriv->card->cfuncs->disableAccel) (pScreen);
if (!pScreenPriv->screen->softCursor)
@@ -290,6 +291,7 @@ KdEnableScreen (ScreenPtr pScreen)
(*pScreenPriv->card->cfuncs->enableCursor) (pScreen);
if (!pScreenPriv->screen->dumb)
(*pScreenPriv->card->cfuncs->enableAccel) (pScreen);
+ KdOffscreenSwapIn (pScreen);
KdEnableColormap (pScreen);
KdSetRootClip (pScreen, TRUE);
if (pScreenPriv->card->cfuncs->dpms)
@@ -1129,6 +1131,9 @@ KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
if (!(*card->cfuncs->initAccel) (pScreen))
screen->dumb = TRUE;
+ if (screen->off_screen_size > 0)
+ KdOffscreenInit (pScreen);
+
#ifdef PSEUDO8
(void) p8Init (pScreen, PSEUDO8_USE_DEFAULT);
#endif
@@ -1216,7 +1221,6 @@ KdInitScreen (ScreenInfo *pScreenInfo,
screen->dumb = TRUE;
if (!card->cfuncs->initCursor)
screen->softCursor = TRUE;
-
}
Bool
diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h
index c38d4959c..30e852476 100644
--- a/hw/kdrive/src/kdrive.h
+++ b/hw/kdrive/src/kdrive.h
@@ -118,6 +118,9 @@ typedef struct _KdScreenInfo {
int mynum;
DDXPointRec origin;
KdFrameBuffer fb[KD_MAX_FB];
+ int off_screen_base;
+ int off_screen_size;
+ pointer off_screen_areas;
} KdScreenInfo;
typedef struct _KdCardFuncs {
@@ -259,6 +262,14 @@ typedef struct _KdMonitorTiming {
KdSyncPolarity vpol; /* polarity */
} KdMonitorTiming;
+typedef struct _KdOffscreenArea {
+ ScreenPtr screen;
+ int offset;
+ int size;
+ pointer privData;
+ Bool swappedOut;
+} KdOffscreenArea;
+
extern const KdMonitorTiming kdMonitorTimings[];
extern const int kdNumMonitorTimings;
@@ -266,7 +277,7 @@ typedef struct _KdMouseMatrix {
int matrix[2][3];
} KdMouseMatrix;
-typedef struct _KaaScreenPriv {
+typedef struct _KaaScreenInfo {
Bool (*PrepareSolid) (DrawablePtr pDrawable,
int alu,
Pixel planemask,
@@ -287,11 +298,11 @@ typedef struct _KaaScreenPriv {
int width,
int height);
void (*DoneCopy) (void);
-} KaaScreenPrivRec, *KaaScreenPrivPtr;
-Bool
-KaaInit (ScreenPtr pScreen,
- KaaScreenPrivPtr pScreenPriv);
+ int offscreenByteAlign;
+ int offscreenPitch;
+} KaaScreenInfoRec, *KaaScreenInfoPtr;
+
/*
* This is the only completely portable way to
@@ -335,8 +346,8 @@ extern KdOsFuncs *kdOsFuncs;
/* kaa.c */
Bool
-kaaDrawInit (ScreenPtr pScreen,
- KaaScreenPrivPtr pScreenPriv);
+kaaDrawInit (ScreenPtr pScreen,
+ KaaScreenInfoPtr pScreenInfo);
void
kaaWrapGC (GCPtr pGC);
@@ -751,6 +762,28 @@ KdFrameBufferValid (CARD8 *base, int size);
int
KdFrameBufferSize (CARD8 *base, int max);
-/* function prototypes to be imlpemented by the drivers */
+/* koffscreen.c */
+typedef void (*KdOffscreenMoveDataProc) (KdOffscreenArea *area);
+
+Bool
+KdOffscreenInit (ScreenPtr pScreen);
+
+KdOffscreenArea *
+KdOffscreenAlloc (ScreenPtr pScreen, int size, int align,
+ Bool locked,
+ KdOffscreenMoveDataProc moveIn,
+ KdOffscreenMoveDataProc moveOut,
+ pointer privData);
+
+void
+KdOffscreenFree (KdOffscreenArea *area);
+
+void
+KdOffscreenSwapOut (ScreenPtr pScreen);
+
+void
+KdOffscreenSwapIn (ScreenPtr pScreen);
+
+/* function prototypes to be implemented by the drivers */
void
InitCard (char *name);
diff --git a/hw/kdrive/src/koffscreen.c b/hw/kdrive/src/koffscreen.c
new file mode 100644
index 000000000..e1a775bc2
--- /dev/null
+++ b/hw/kdrive/src/koffscreen.c
@@ -0,0 +1,200 @@
+/*
+ * $Id$
+ *
+ * Copyright © 2003 Anders Carlsson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Anders Carlsson not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Anders Carlsson makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * ANDERS CARLSSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ANDERS CARLSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $Header$ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "kdrive.h"
+
+typedef struct _RealOffscreenArea {
+ KdOffscreenArea area;
+
+ KdOffscreenMoveDataProc moveIn;
+ KdOffscreenMoveDataProc moveOut;
+
+ Bool locked;
+
+ struct _RealOffscreenArea *next;
+ struct _RealOffscreenArea *prev;
+} RealOffscreenArea;
+
+KdOffscreenArea *
+KdOffscreenAlloc (ScreenPtr pScreen, int size, int align,
+ Bool locked,
+ KdOffscreenMoveDataProc moveIn,
+ KdOffscreenMoveDataProc moveOut,
+ pointer privData)
+{
+ RealOffscreenArea *area;
+ KdScreenPriv (pScreen);
+ int tmp, real_size;
+
+
+ /* Go through the areas */
+ area = pScreenPriv->screen->off_screen_areas;
+ while (area != NULL)
+ {
+ if (area->area.screen != NULL)
+ {
+ area = area->next;
+ continue;
+ }
+
+ real_size = size;
+ tmp = (area->area.offset + area->area.size - size) % align;
+
+ if (tmp)
+ real_size += (align - tmp);
+
+ if (real_size <= area->area.size)
+ {
+ RealOffscreenArea *new_area;
+
+ if (real_size == area->area.size)
+ {
+ area->area.screen = pScreen;
+ area->area.privData = privData;
+ area->locked = locked;
+ area->moveIn = moveIn;
+ area->moveOut = moveOut;
+
+ return (KdOffscreenArea *)area;
+ }
+
+ /* Create a new area */
+ new_area = xalloc (sizeof (RealOffscreenArea));
+ new_area->area.offset = area->area.offset + area->area.size - real_size;
+ new_area->area.size = real_size;
+ new_area->area.screen = pScreen;
+
+ area->area.size -= real_size;
+
+ new_area->prev = area;
+ new_area->next = area->next;
+
+ if (area->next)
+ area->next->prev = new_area;
+ area->next = new_area;
+
+ return (KdOffscreenArea *)new_area;
+ }
+
+ area = area->next;
+ }
+
+ /* Could not allocate memory */
+ return NULL;
+}
+
+void
+KdOffscreenSwapOut (ScreenPtr pScreen)
+{
+ KdScreenPriv (pScreen);
+ RealOffscreenArea *area = pScreenPriv->screen->off_screen_areas;
+
+ while (area)
+ {
+ (*area->moveOut) ((KdOffscreenArea *)area);
+
+ area->area.swappedOut = TRUE;
+
+ area = area->next;
+ }
+}
+
+void
+KdOffscreenSwapIn (ScreenPtr pScreen)
+{
+ KdScreenPriv (pScreen);
+ RealOffscreenArea *area = pScreenPriv->screen->off_screen_areas;
+
+ while (area)
+ {
+ (*area->moveOut) ((KdOffscreenArea *)area);
+
+ area->area.swappedOut = TRUE;
+ area = area->next;
+ }
+}
+
+void
+KdOffscreenFree (KdOffscreenArea *area)
+{
+ RealOffscreenArea *real_area = (RealOffscreenArea *)area;
+
+ real_area->area.screen = NULL;
+
+ if (real_area && real_area->next && !real_area->next->area.screen)
+ {
+ RealOffscreenArea *tmp;
+
+ real_area->next->prev = real_area->prev;
+ if (real_area->prev)
+ real_area->prev->next = real_area->next;
+
+ real_area->next->area.size += real_area->area.size;
+ real_area->next->area.offset = real_area->area.offset;
+
+ tmp = real_area->next;
+ xfree (real_area);
+ real_area = tmp;
+ }
+
+ if (real_area->prev && !real_area->prev->area.screen)
+ {
+ real_area->prev->next = real_area->next;
+ if (real_area->next)
+ real_area->next->prev = real_area->prev;
+
+ real_area->prev->area.size += real_area->area.size;
+
+ xfree (real_area);
+ }
+}
+
+Bool
+KdOffscreenInit (ScreenPtr pScreen)
+{
+ KdScreenPriv (pScreen);
+ RealOffscreenArea *area;
+
+ /* Allocate a big free area */
+ area = xalloc (sizeof (RealOffscreenArea));
+
+ if (!area)
+ return FALSE;
+
+ area->area.screen = NULL;
+ area->area.offset = pScreenPriv->screen->off_screen_base;
+ area->area.size = pScreenPriv->screen->off_screen_size;
+ area->next = NULL;
+ area->prev = NULL;
+
+ /* Add it to the free areas */
+ pScreenPriv->screen->off_screen_areas = area;
+
+ return TRUE;
+}
+