diff options
-rw-r--r-- | hw/kdrive/mach64/mach64draw.c | 2 | ||||
-rw-r--r-- | hw/kdrive/mga/mga.c | 26 | ||||
-rw-r--r-- | hw/kdrive/mga/mga.h | 2 | ||||
-rw-r--r-- | hw/kdrive/mga/mgadraw.c | 81 | ||||
-rw-r--r-- | hw/kdrive/nvidia/nvidiadraw.c | 2 | ||||
-rw-r--r-- | hw/kdrive/r128/r128draw.c | 2 | ||||
-rw-r--r-- | hw/kdrive/smi/smidraw.c | 2 | ||||
-rw-r--r-- | hw/kdrive/src/Makefile.am | 1 | ||||
-rw-r--r-- | hw/kdrive/src/kaa.c | 143 | ||||
-rw-r--r-- | hw/kdrive/src/kdrive.c | 6 | ||||
-rw-r--r-- | hw/kdrive/src/kdrive.h | 49 | ||||
-rw-r--r-- | hw/kdrive/src/koffscreen.c | 200 |
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; +} + |