diff --git a/hw/kdrive/mach64/mach64video.c b/hw/kdrive/mach64/mach64video.c index 23d671580..1f945db3c 100644 --- a/hw/kdrive/mach64/mach64video.c +++ b/hw/kdrive/mach64/mach64video.c @@ -68,7 +68,7 @@ mach64StopVideo(KdScreenInfo *screen, pointer data, Bool exit) } if (pPortPriv->off_screen) { - KdOffscreenFree (pPortPriv->off_screen); + KdOffscreenFree (pScreen, pPortPriv->off_screen); pPortPriv->off_screen = 0; } } @@ -556,9 +556,8 @@ mach64DisplayVideo(KdScreenInfo *screen, } static void -mach64VideoSave (KdOffscreenArea *area) +mach64VideoSave (ScreenPtr pScreen, KdOffscreenArea *area) { - ScreenPtr pScreen = area->screen; KdScreenPriv(pScreen); KdScreenInfo *screen = pScreenPriv->screen; Mach64ScreenInfo *mach64s = (Mach64ScreenInfo *) screen->driver; @@ -706,7 +705,7 @@ mach64PutImage(KdScreenInfo *screen, if (pPortPriv->off_screen && size != pPortPriv->size) { - KdOffscreenFree (pPortPriv->off_screen); + KdOffscreenFree (screen->pScreen, pPortPriv->off_screen); pPortPriv->off_screen = 0; } diff --git a/hw/kdrive/src/kaa.c b/hw/kdrive/src/kaa.c index d861a232a..66e5fc874 100644 --- a/hw/kdrive/src/kaa.c +++ b/hw/kdrive/src/kaa.c @@ -75,7 +75,7 @@ typedef struct { #define MIN_OFFPIX_SIZE (4096) static void -kaaPixmapSave (KdOffscreenArea *area) +kaaPixmapSave (ScreenPtr pScreen, KdOffscreenArea *area) { PixmapPtr pPixmap = area->privData; KaaPixmapPriv(pPixmap); @@ -196,8 +196,8 @@ kaaMoveOutPixmap (PixmapPtr pPixmap) pPixmap->drawable.height)); if (area) { - kaaPixmapSave (area); - KdOffscreenFree (area); + kaaPixmapSave (pPixmap->drawable.pScreen, area); + KdOffscreenFree (pPixmap->drawable.pScreen, area); } } @@ -243,7 +243,7 @@ kaaDestroyPixmap (PixmapPtr pPixmap) pPixmap->drawable.width, pPixmap->drawable.height)); /* Free the offscreen area */ - KdOffscreenFree (pKaaPixmap->area); + KdOffscreenFree (pPixmap->drawable.pScreen, pKaaPixmap->area); pPixmap->devPrivate = pKaaPixmap->devPrivate; pPixmap->devKind = pKaaPixmap->devKind; } diff --git a/hw/kdrive/src/kdrive.h b/hw/kdrive/src/kdrive.h index 8969e6f83..0fb991ec6 100644 --- a/hw/kdrive/src/kdrive.h +++ b/hw/kdrive/src/kdrive.h @@ -99,6 +99,28 @@ typedef struct _KdFrameBuffer { void *closure; } KdFrameBuffer; +typedef struct _KdOffscreenArea KdOffscreenArea; + +typedef void (*KdOffscreenSaveProc) (ScreenPtr pScreen, KdOffscreenArea *area); + +typedef enum _KdOffscreenState { + KdOffscreenAvail, + KdOffscreenRemovable, + KdOffscreenLocked, +} KdOffscreenState; + +struct _KdOffscreenArea { + int offset; + int size; + pointer privData; + + KdOffscreenSaveProc save; + + KdOffscreenState state; + + KdOffscreenArea *next; +}; + #define RR_Rotate_All (RR_Rotate_0|RR_Rotate_90|RR_Rotate_180|RR_Rotate_270) #define RR_Reflect_All (RR_Reflect_X|RR_Reflect_Y) @@ -122,7 +144,6 @@ typedef struct _KdScreenInfo { CARD8 *memory_base; unsigned long memory_size; unsigned long off_screen_base; - struct _RealOffscreenArea *off_screen_areas; } KdScreenInfo; typedef struct _KdCardFuncs { @@ -169,6 +190,8 @@ typedef struct { int dpmsState; + KdOffscreenArea *off_screen_areas; + ColormapPtr pInstalledmap[KD_MAX_FB]; /* current colormap */ xColorItem systemPalette[KD_MAX_PSEUDO_SIZE];/* saved windows colors */ @@ -267,13 +290,6 @@ typedef struct _KdMonitorTiming { KdSyncPolarity vpol; /* polarity */ } KdMonitorTiming; -typedef struct _KdOffscreenArea { - ScreenPtr screen; - int offset; - int size; - pointer privData; -} KdOffscreenArea; - extern const KdMonitorTiming kdMonitorTimings[]; extern const int kdNumMonitorTimings; @@ -800,7 +816,6 @@ int KdFrameBufferSize (CARD8 *base, int max); /* koffscreen.c */ -typedef void (*KdOffscreenSaveProc) (KdOffscreenArea *area); Bool KdOffscreenInit (ScreenPtr pScreen); @@ -812,7 +827,7 @@ KdOffscreenAlloc (ScreenPtr pScreen, int size, int align, pointer privData); void -KdOffscreenFree (KdOffscreenArea *area); +KdOffscreenFree (ScreenPtr pScreen, KdOffscreenArea *area); void KdOffscreenSwapOut (ScreenPtr pScreen); diff --git a/hw/kdrive/src/koffscreen.c b/hw/kdrive/src/koffscreen.c index 71dfa6bb0..61cf37a62 100644 --- a/hw/kdrive/src/koffscreen.c +++ b/hw/kdrive/src/koffscreen.c @@ -34,26 +34,15 @@ #define DBG_OFFSCREEN(a) #endif -typedef struct _RealOffscreenArea { - KdOffscreenArea area; - - KdOffscreenSaveProc save; - - Bool locked; - - struct _RealOffscreenArea *prev; - struct _RealOffscreenArea *next; -} RealOffscreenArea; - #if DEBUG_OFFSCREEN static void KdOffscreenValidate (ScreenPtr pScreen) { KdScreenPriv (pScreen); - RealOffscreenArea *prev = 0, *area; + KdOffscreenArea *prev = 0, *area; assert (pScreenPriv->screen->off_screen_areas->area.offset == 0); - for (area = pScreenPriv->screen->off_screen_areas; area; area = area->next) + for (area = pScreenPriv->off_screen_areas; area; area = area->next) { if (prev) assert (prev->area.offset + prev->area.size == area->area.offset); @@ -67,12 +56,11 @@ KdOffscreenValidate (ScreenPtr pScreen) #endif static void -KdOffscreenKickOut (KdOffscreenArea *area) +KdOffscreenKickOut (ScreenPtr pScreen, KdOffscreenArea *area) { - RealOffscreenArea *real_area = (RealOffscreenArea *) area; - if (real_area->save) - (*real_area->save) (area); - KdOffscreenFree (area); + if (area->save) + (*area->save) (pScreen, area); + KdOffscreenFree (pScreen, area); } KdOffscreenArea * @@ -81,7 +69,7 @@ KdOffscreenAlloc (ScreenPtr pScreen, int size, int align, KdOffscreenSaveProc save, pointer privData) { - RealOffscreenArea *area, **prev; + KdOffscreenArea *area, **prev; KdScreenPriv (pScreen); int tmp, real_size = 0; @@ -103,20 +91,20 @@ KdOffscreenAlloc (ScreenPtr pScreen, int size, int align, } /* Go through the areas */ - for (area = pScreenPriv->screen->off_screen_areas; area; area = area->next) + for (area = pScreenPriv->off_screen_areas; area; area = area->next) { /* skip allocated areas */ - if (area->area.screen) + if (area->state != KdOffscreenAvail) continue; /* adjust size to match alignment requirement */ real_size = size; - tmp = area->area.offset % align; + tmp = area->offset % align; if (tmp) real_size += (align - tmp); /* does it fit? */ - if (real_size <= area->area.size) + if (real_size <= area->size) break; } @@ -129,25 +117,25 @@ KdOffscreenAlloc (ScreenPtr pScreen, int size, int align, */ /* prev points at the first object to boot */ - prev = (RealOffscreenArea **) &pScreenPriv->screen->off_screen_areas; + prev = (KdOffscreenArea **) &pScreenPriv->off_screen_areas; while ((area = *prev)) { int avail; - RealOffscreenArea *scan; + KdOffscreenArea *scan, **nprev; /* adjust size to match alignment requirement */ real_size = size; - tmp = area->area.offset % align; + tmp = area->offset % align; if (tmp) real_size += (align - tmp); avail = 0; /* now see if we can make room here */ - for (scan = area; scan; scan = scan->next) + for (nprev = prev; (scan = *nprev); nprev = &scan->next) { - if (scan->locked) + if (scan->state == KdOffscreenLocked) break; - avail += scan->area.size; + avail += scan->size; if (avail >= real_size) break; } @@ -156,7 +144,10 @@ KdOffscreenAlloc (ScreenPtr pScreen, int size, int align, break; /* nope, try the next area */ - prev = &scan->next; + prev = nprev; + /* skip to next unlocked area */ + while ((area = *prev) && area->state == KdOffscreenLocked) + prev = &area->next; } if (!area) { @@ -169,47 +160,46 @@ KdOffscreenAlloc (ScreenPtr pScreen, int size, int align, /* * Kick out first area if in use */ - if (area->area.screen) - KdOffscreenKickOut (&area->area); + if (area->state != KdOffscreenAvail) + KdOffscreenKickOut (pScreen, area); /* * Now get the system to merge the other needed areas together */ - while (area->area.size < real_size) + while (area->size < real_size) { - assert (area->next && area->next->area.screen); - KdOffscreenKickOut (&area->next->area); + assert (area->next && area->next->state == KdOffscreenRemovable); + KdOffscreenKickOut (pScreen, area->next); } } /* save extra space in new area */ - if (real_size < area->area.size) + if (real_size < area->size) { - RealOffscreenArea *new_area = xalloc (sizeof (RealOffscreenArea)); + KdOffscreenArea *new_area = xalloc (sizeof (KdOffscreenArea)); if (!new_area) return NULL; - new_area->area.offset = area->area.offset + real_size; - new_area->area.size = area->area.size - real_size; - new_area->area.screen = 0; - new_area->locked = FALSE; + new_area->offset = area->offset + real_size; + new_area->size = area->size - real_size; + new_area->state = KdOffscreenAvail; new_area->save = 0; - if ((new_area->next = area->next)) - new_area->next->prev = new_area; - new_area->prev = area; + new_area->next = area->next; area->next = new_area; - area->area.size = real_size; + area->size = real_size; } /* * Mark this area as in use */ - area->area.screen = pScreen; - area->area.privData = privData; - area->locked = locked; + if (locked) + area->state = KdOffscreenLocked; + else + area->state = KdOffscreenRemovable; + area->privData = privData; area->save = save; KdOffscreenValidate (pScreen); - DBG_OFFSCREEN (("Alloc 0x%x -> 0x%x\n", size, area->area.offset)); - return &area->area; + DBG_OFFSCREEN (("Alloc 0x%x -> 0x%x\n", size, area->offset)); + return area; } void @@ -221,18 +211,18 @@ KdOffscreenSwapOut (ScreenPtr pScreen) /* loop until a single free area spans the space */ for (;;) { - RealOffscreenArea *area = pScreenPriv->screen->off_screen_areas; + KdOffscreenArea *area = pScreenPriv->off_screen_areas; if (!area) break; - if (!area->area.screen) + if (area->state == KdOffscreenAvail) { area = area->next; if (!area) break; } - assert (area->area.screen); - KdOffscreenKickOut (&area->area); + assert (area->state != KdOffscreenAvail); + KdOffscreenKickOut (pScreen, area); KdOffscreenValidate (pScreen); } KdOffscreenValidate (pScreen); @@ -249,36 +239,44 @@ KdOffscreenSwapIn (ScreenPtr pScreen) static void KdOffscreenMerge (KdOffscreenArea *area) { - RealOffscreenArea *real_area = (RealOffscreenArea *) area; - RealOffscreenArea *next = real_area->next; + KdOffscreenArea *next = area->next; /* account for space */ - real_area->area.size += next->area.size; - /* frob pointers */ - if ((real_area->next = next->next)) - real_area->next->prev = real_area; + area->size += next->size; + /* frob pointer */ + area->next = next->next; xfree (next); } void -KdOffscreenFree (KdOffscreenArea *area) +KdOffscreenFree (ScreenPtr pScreen, KdOffscreenArea *area) { - RealOffscreenArea *real_area = (RealOffscreenArea *) area; - RealOffscreenArea *next = real_area->next; - RealOffscreenArea *prev = real_area->prev; + KdScreenPriv(pScreen); + KdOffscreenArea *next = area->next; + KdOffscreenArea *prev; DBG_OFFSCREEN (("Free 0x%x -> 0x%x\n", area->size, area->offset)); KdOffscreenValidate (pScreen); - area->screen = NULL; + area->state = KdOffscreenAvail; + /* + * Find previous area + */ + if (area == pScreenPriv->off_screen_areas) + prev = 0; + else + for (prev = pScreenPriv->off_screen_areas; prev; prev = prev->next) + if (prev->next == area) + break; + /* link with next area if free */ - if (next && !next->area.screen) - KdOffscreenMerge (&real_area->area); + if (next && next->state == KdOffscreenAvail) + KdOffscreenMerge (area); /* link with prev area if free */ - if (prev && !prev->area.screen) - KdOffscreenMerge (&prev->area); + if (prev && prev->state == KdOffscreenAvail) + KdOffscreenMerge (prev); KdOffscreenValidate (pScreen); } @@ -287,24 +285,22 @@ Bool KdOffscreenInit (ScreenPtr pScreen) { KdScreenPriv (pScreen); - RealOffscreenArea *area; + KdOffscreenArea *area; /* Allocate a big free area */ - area = xalloc (sizeof (RealOffscreenArea)); + area = xalloc (sizeof (KdOffscreenArea)); if (!area) return FALSE; - area->area.screen = NULL; - area->area.offset = pScreenPriv->screen->off_screen_base; - area->area.size = pScreenPriv->screen->memory_size - area->area.offset; + area->state = KdOffscreenAvail; + area->offset = pScreenPriv->screen->off_screen_base; + area->size = pScreenPriv->screen->memory_size - area->offset; area->save = 0; - area->locked = FALSE; area->next = NULL; - area->prev = NULL; /* Add it to the free areas */ - pScreenPriv->screen->off_screen_areas = area; + pScreenPriv->off_screen_areas = area; KdOffscreenValidate (pScreen); @@ -315,12 +311,12 @@ void KdOffscreenFini (ScreenPtr pScreen) { KdScreenPriv (pScreen); - RealOffscreenArea *area; + KdOffscreenArea *area; /* just free all of the area records */ - while ((area = pScreenPriv->screen->off_screen_areas)) + while ((area = pScreenPriv->off_screen_areas)) { - pScreenPriv->screen->off_screen_areas = area->next; + pScreenPriv->off_screen_areas = area->next; xfree (area); } }