diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-25 19:29:01 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-25 19:29:01 +0000 |
commit | adc7f9a4ebdfe11d4cd6de9388b63dfe36450b39 (patch) | |
tree | 23eb7becc5360b2cbe16aa8d45529880067f3989 /hw/xfree86/common/xf86fbman.c | |
parent | 90f1536dd315cd265bfc7ef35058761a65a01734 (diff) |
XFree86 4.3.99.16 Bring the tree up to date for the Cygwin folksxf86-4_3_99_16
Diffstat (limited to 'hw/xfree86/common/xf86fbman.c')
-rw-r--r-- | hw/xfree86/common/xf86fbman.c | 315 |
1 files changed, 261 insertions, 54 deletions
diff --git a/hw/xfree86/common/xf86fbman.c b/hw/xfree86/common/xf86fbman.c index 7f4cffaae..b7c4afa1c 100644 --- a/hw/xfree86/common/xf86fbman.c +++ b/hw/xfree86/common/xf86fbman.c @@ -1,4 +1,31 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86fbman.c,v 1.24 2001/12/05 19:23:52 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86fbman.c,v 1.28 2003/11/03 05:11:03 tsi Exp $ */ + +/* + * Copyright (c) 1998-2001 by The XFree86 Project, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ #include "misc.h" #include "xf86.h" @@ -8,6 +35,10 @@ #include "regionstr.h" #include "xf86fbman.h" +/* +#define DEBUG +*/ + static int xf86FBMangerIndex = -1; static unsigned long xf86ManagerGeneration = 0; @@ -118,19 +149,19 @@ xf86FreeOffscreenArea(FBAreaPtr area) void -xf86FreeOffscreenLinear(FBLinearPtr area) +xf86FreeOffscreenLinear(FBLinearPtr linear) { FBManagerFuncsPtr funcs; - if(!area) return; + if(!linear) return; if(xf86FBMangerIndex < 0) return; if(!(funcs = - (FBManagerFuncsPtr)area->pScreen->devPrivates[xf86FBMangerIndex].ptr)) + (FBManagerFuncsPtr)linear->pScreen->devPrivates[xf86FBMangerIndex].ptr)) return; - (*funcs->FreeOffscreenLinear)(area); + (*funcs->FreeOffscreenLinear)(linear); return; } @@ -244,18 +275,19 @@ typedef struct _FBLink { } FBLink, *FBLinkPtr; typedef struct _FBLinearLink { - FBLinear linear; - FBAreaPtr area; + FBLinear linear; + int free; /* need to add free here as FBLinear is publicly accessible */ + FBAreaPtr area; /* only used if allocation came from XY area */ struct _FBLinearLink *next; } FBLinearLink, *FBLinearLinkPtr; typedef struct { - ScreenPtr pScreen; - RegionPtr InitialBoxes; - RegionPtr FreeBoxes; - FBLinkPtr UsedAreas; - int NumUsedAreas; + ScreenPtr pScreen; + RegionPtr InitialBoxes; + RegionPtr FreeBoxes; + FBLinkPtr UsedAreas; + int NumUsedAreas; FBLinearLinkPtr LinearAreas; CloseScreenProcPtr CloseScreen; int NumCallbacks; @@ -772,6 +804,97 @@ LinearRemoveCBWrapper(FBAreaPtr area) xfree(pLink); } +#ifdef DEBUG +static void +Dump(FBLinearLinkPtr pLink) +{ + if (!pLink) ErrorF("MMmm, PLINK IS NULL!\n"); + + while (pLink) { + ErrorF(" Offset:%08x, Size:%08x, %s,%s\n", + pLink->linear.offset, + pLink->linear.size, + pLink->free ? "Free" : "Used", + pLink->area ? "Area" : "Linear"); + + pLink = pLink->next; + } +} +#endif + +static FBLinearPtr +AllocateLinear( + FBManagerPtr offman, + int size, + int granularity, + pointer privData +){ + ScreenPtr pScreen = offman->pScreen; + FBLinearLinkPtr linear = NULL; + FBLinearLinkPtr newlink = NULL; + int offset, end; + + if(size <= 0) return NULL; + + if (!offman->LinearAreas) return NULL; + + linear = offman->LinearAreas; + while (linear) { + /* Make sure we get a free area that's not an XY fallback case */ + if (!linear->area && linear->free) { + offset = (linear->linear.offset + granularity) & ~granularity; + end = offset+size; + if (end <= (linear->linear.offset + linear->linear.size)) + break; + } + linear = linear->next; + } + if (!linear) + return NULL; + + /* break left */ + if (offset > linear->linear.offset) { + newlink = xalloc(sizeof(FBLinearLink)); + if (!newlink) + return NULL; + newlink->area = NULL; + newlink->linear.offset = offset; + newlink->linear.size = linear->linear.size - (offset - linear->linear.offset); + newlink->free = 1; + newlink->next = linear->next; + linear->linear.size -= newlink->linear.size; + linear->next = newlink; + linear = newlink; + } + + /* break right */ + if (size < linear->linear.size) { + newlink = xalloc(sizeof(FBLinearLink)); + if (!newlink) + return NULL; + newlink->area = NULL; + newlink->linear.offset = offset + size; + newlink->linear.size = linear->linear.size - size; + newlink->free = 1; + newlink->next = linear->next; + linear->linear.size = size; + linear->next = newlink; + } + + /* p = middle block */ + linear->linear.granularity = granularity; + linear->free = 0; + linear->linear.pScreen = pScreen; + linear->linear.MoveLinearCallback = NULL; + linear->linear.RemoveLinearCallback = NULL; + linear->linear.devPrivate.ptr = NULL; + +#ifdef DEBUG + Dump(offman->LinearAreas); +#endif + + return &(linear->linear); +} static FBLinearPtr localAllocateOffscreenLinear( @@ -791,28 +914,21 @@ localAllocateOffscreenLinear( offman = pScreen->devPrivates[xf86FBScreenIndex].ptr; - if(!(link = xalloc(sizeof(FBLinearLink)))) - return NULL; + /* Try to allocate from linear memory first...... */ +#ifdef DEBUG + ErrorF("ALLOCATING LINEAR\n"); +#endif + if ((linear = AllocateLinear(offman, length, gran, privData))) + return linear; -#if 0 - if(we have linear heap space) { - if(able to allocate some) { - link->area = NULL; - link->next = offman->LinearAreas; - offman->LinearAreas = link; - linear = link->linear; - linear->pScreen = pScreen; - linear->size = length; - linear->offset = ????; - linear->granularity = gran; - linear->MoveLinearAreaCallback = moveCB; - linear->RemoveLinearAreaCallback = removeCB; - linear->devPrivate.ptr = privData; - return linear; - } /* else fallthrough */ - } +#ifdef DEBUG + ErrorF("NOPE, ALLOCATING AREA\n"); #endif + if(!(link = xalloc(sizeof(FBLinearLink)))) + return NULL; + + /* No linear available, so try and pinch some from the XY areas */ extents = REGION_EXTENTS(pScreen, offman->InitialBoxes); pitch = extents->x2 - extents->x1; @@ -836,6 +952,7 @@ localAllocateOffscreenLinear( privData))) { link->area = area; + link->free = 0; link->next = offman->LinearAreas; offman->LinearAreas = link; linear = &(link->linear); @@ -849,6 +966,10 @@ localAllocateOffscreenLinear( } else xfree(link); +#ifdef DEBUG + Dump(offman->LinearAreas); +#endif + return linear; } @@ -861,7 +982,7 @@ localFreeOffscreenLinear(FBLinearPtr linear) ScreenPtr pScreen = linear->pScreen; offman = pScreen->devPrivates[xf86FBScreenIndex].ptr; - + pLink = offman->LinearAreas; if(!pLink) return; @@ -872,16 +993,42 @@ localFreeOffscreenLinear(FBLinearPtr linear) } if(pLink->area) { /* really an XY area */ - localFreeOffscreenArea(pLink->area); - } else { - /* free the linear area */ +#ifdef DEBUG + ErrorF("FREEING AREA\n"); +#endif + localFreeOffscreenArea(pLink->area); + if(pLinkPrev) + pLinkPrev->next = pLink->next; + else offman->LinearAreas = pLink->next; + xfree(pLink); +#ifdef DEBUG + Dump(offman->LinearAreas); +#endif + return; } - if(pLinkPrev) - pLinkPrev->next = pLink->next; - else offman->LinearAreas = pLink->next; + pLink->free = 1; - xfree(pLink); + if (pLink->next && pLink->next->free) { + FBLinearLinkPtr p = pLink->next; + pLink->linear.size += p->linear.size; + pLink->next = p->next; + free(p); + } + + if(pLinkPrev) { + if (pLinkPrev->next && pLinkPrev->next->free && !pLinkPrev->area) { + FBLinearLinkPtr p = pLinkPrev->next; + pLinkPrev->linear.size += p->linear.size; + pLinkPrev->next = p->next; + free(p); + } + } + +#ifdef DEBUG + ErrorF("FREEING LINEAR\n"); + Dump(offman->LinearAreas); +#endif } @@ -889,7 +1036,7 @@ static Bool localResizeOffscreenLinear(FBLinearPtr resize, int length) { FBManagerPtr offman; - FBLinearLinkPtr pLink, pLinkPrev = NULL; + FBLinearLinkPtr pLink; ScreenPtr pScreen = resize->pScreen; offman = pScreen->devPrivates[xf86FBScreenIndex].ptr; @@ -898,7 +1045,6 @@ localResizeOffscreenLinear(FBLinearPtr resize, int length) if(!pLink) return FALSE; while(&(pLink->linear) != resize) { - pLinkPrev = pLink; pLink = pLink->next; if(!pLink) return FALSE; } @@ -928,7 +1074,7 @@ localResizeOffscreenLinear(FBLinearPtr resize, int length) return TRUE; } } else { - /* resize the linear area */ + /* TODO!!!! resize the linear area */ } return FALSE; @@ -943,22 +1089,45 @@ localQueryLargestOffscreenLinear( int priority ) { - int w, h; + FBManagerPtr offman = pScreen->devPrivates[xf86FBScreenIndex].ptr; + FBLinearLinkPtr pLink; + FBLinearLinkPtr pLinkRet; *size = 0; + + if (!offman->LinearAreas) return FALSE; - /* for now, we only look at XY space */ - if(localQueryLargestOffscreenArea(pScreen, &w, &h, gran, - FAVOR_WIDTH_THEN_AREA, priority)) - { - FBManagerPtr offman; - BoxPtr extents; + pLink = offman->LinearAreas; + pLinkRet = pLink; - offman = pScreen->devPrivates[xf86FBScreenIndex].ptr; - extents = REGION_EXTENTS(pScreen, offman->InitialBoxes); - if((extents->x2 - extents->x1) == w) - *size = w * h; - return TRUE; + if (!pLink->area) { + while (pLink) { + if (pLink->free) { + if (pLink->linear.size > pLinkRet->linear.size) + pLinkRet = pLink; + } + pLink = pLink->next; + } + + if (pLinkRet->free) { + *size = pLinkRet->linear.size; + return TRUE; + } + } else { + int w, h; + + if(localQueryLargestOffscreenArea(pScreen, &w, &h, gran, + FAVOR_WIDTH_THEN_AREA, priority)) + { + FBManagerPtr offman; + BoxPtr extents; + + offman = pScreen->devPrivates[xf86FBScreenIndex].ptr; + extents = REGION_EXTENTS(pScreen, offman->InitialBoxes); + if((extents->x2 - extents->x1) == w) + *size = w * h; + return TRUE; + } } return FALSE; @@ -1189,6 +1358,44 @@ xf86InitFBManagerRegion( return TRUE; } +Bool +xf86InitFBManagerLinear( + ScreenPtr pScreen, + int offset, + int size +){ + FBManagerPtr offman; + FBLinearLinkPtr link; + FBLinearPtr linear; + + if (size <= 0) + return FALSE; + + /* we expect people to have called the Area setup first for pixmap cache */ + if (!pScreen->devPrivates[xf86FBScreenIndex].ptr) + return FALSE; + + offman = pScreen->devPrivates[xf86FBScreenIndex].ptr; + + offman->LinearAreas = xalloc(sizeof(FBLinearLink)); + if (!offman->LinearAreas) + return FALSE; + + link = offman->LinearAreas; + link->area = NULL; + link->next = NULL; + link->free = 1; + linear = &(link->linear); + linear->pScreen = pScreen; + linear->size = size; + linear->offset = offset; + linear->granularity = 0; + linear->MoveLinearCallback = NULL; + linear->RemoveLinearCallback = NULL; + linear->devPrivate.ptr = NULL; + + return TRUE; +} /* This is an implementation specific function and should |