mirror of
https://git.yoctoproject.org/poky
synced 2026-09-24 13:36:22 +02:00
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@1684 311d38ba-8fff-0310-9ca6-ca027cbcb966
757 lines
23 KiB
Diff
757 lines
23 KiB
Diff
|
|
# Author : Manuel Teira <manuel.teira@telefonica.net> (sirfred in #oe)
|
|
# Description: Support for multiple memory video zones in kdrive. Make offscreen
|
|
# areas aware of the memory video zone it belongs to. Change the fbdev driver to
|
|
# honour this new model.
|
|
|
|
#
|
|
# Patch managed by http://www.holgerschurig.de/patcher.html
|
|
#
|
|
|
|
--- xorg-server-X11R7.1-1.1.0.orig/hw/kdrive/src/kdrive.c~kdrive-vidmemarea
|
|
+++ xorg-server-X11R7.1-1.1.0.orig/hw/kdrive/src/kdrive.c
|
|
@@ -908,9 +908,10 @@
|
|
ret = (*pScreen->CloseScreen) (index, pScreen);
|
|
else
|
|
ret = TRUE;
|
|
-
|
|
- if (screen->off_screen_base < screen->memory_size)
|
|
- KdOffscreenFini (pScreen);
|
|
+
|
|
+ if (KdHasOffscreen(screen)) {
|
|
+ KdOffscreenFini(pScreen);
|
|
+ }
|
|
|
|
if (pScreenPriv->dpmsState != KD_DPMS_NORMAL)
|
|
(*card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL);
|
|
@@ -1219,8 +1220,9 @@
|
|
if (!(*card->cfuncs->initAccel) (pScreen))
|
|
screen->dumb = TRUE;
|
|
|
|
- if (screen->off_screen_base < screen->memory_size)
|
|
- KdOffscreenInit (pScreen);
|
|
+ if (KdHasOffscreen(screen)) {
|
|
+ KdOffscreenInit(pScreen);
|
|
+ }
|
|
|
|
#ifdef PSEUDO8
|
|
(void) p8Init (pScreen, PSEUDO8_USE_DEFAULT);
|
|
--- xorg-server-X11R7.1-1.1.0.orig/hw/kdrive/src/kdrive.h~kdrive-vidmemarea
|
|
+++ xorg-server-X11R7.1-1.1.0.orig/hw/kdrive/src/kdrive.h
|
|
@@ -63,6 +63,9 @@
|
|
#define KD_MAX_CARD_ADDRESS 8
|
|
#endif
|
|
|
|
+#define KD_VIDMEM_MINPRIO 0
|
|
+#define KD_VIDMEM_MAXPRIO 255
|
|
+
|
|
/*
|
|
* Configuration information per video card
|
|
*/
|
|
@@ -115,6 +118,13 @@
|
|
|
|
typedef void (*KdOffscreenSaveProc) (ScreenPtr pScreen, KdOffscreenArea *area);
|
|
|
|
+typedef struct _KdVideoMemArea {
|
|
+ CARD8 priority;
|
|
+ CARD8 *base;
|
|
+ CARD32 size;
|
|
+ CARD32 available_offset;
|
|
+} KdVideoMemArea;
|
|
+
|
|
typedef enum _KdOffscreenState {
|
|
KdOffscreenAvail,
|
|
KdOffscreenRemovable,
|
|
@@ -127,7 +137,8 @@
|
|
int size;
|
|
int score;
|
|
pointer privData;
|
|
-
|
|
+ KdVideoMemArea *vidmem;
|
|
+ int pool;
|
|
KdOffscreenSaveProc save;
|
|
|
|
KdOffscreenState state;
|
|
@@ -138,6 +149,7 @@
|
|
#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)
|
|
|
|
+
|
|
typedef struct _KdScreenInfo {
|
|
struct _KdScreenInfo *next;
|
|
KdCardInfo *card;
|
|
@@ -155,9 +167,8 @@
|
|
int mynum;
|
|
DDXPointRec origin;
|
|
KdFrameBuffer fb[KD_MAX_FB];
|
|
- CARD8 *memory_base;
|
|
- unsigned long memory_size;
|
|
- unsigned long off_screen_base;
|
|
+ KdVideoMemArea **videomem_areas;
|
|
+ int num_videomem_areas;
|
|
} KdScreenInfo;
|
|
|
|
typedef struct _KdCardFuncs {
|
|
@@ -187,7 +198,6 @@
|
|
|
|
void (*getColors) (ScreenPtr, int, int, xColorItem *);
|
|
void (*putColors) (ScreenPtr, int, int, xColorItem *);
|
|
-
|
|
} KdCardFuncs;
|
|
|
|
#define KD_MAX_PSEUDO_DEPTH 8
|
|
@@ -203,7 +213,8 @@
|
|
|
|
int dpmsState;
|
|
|
|
- KdOffscreenArea *off_screen_areas;
|
|
+ KdOffscreenArea **offscreen_pools;
|
|
+ int num_offscreen_pools;
|
|
|
|
ColormapPtr pInstalledmap[KD_MAX_FB]; /* current colormap */
|
|
xColorItem systemPalette[KD_MAX_PSEUDO_SIZE];/* saved windows colors */
|
|
@@ -881,6 +892,15 @@
|
|
KdOffscreenInit (ScreenPtr pScreen);
|
|
|
|
KdOffscreenArea *
|
|
+KdOffscreenAllocPrio (ScreenPtr pScreen, int size, int align,
|
|
+ Bool locked,
|
|
+ KdOffscreenSaveProc save,
|
|
+ pointer privData,
|
|
+ int minPriority,
|
|
+ int maxPriority,
|
|
+ Bool allowEviction);
|
|
+
|
|
+KdOffscreenArea *
|
|
KdOffscreenAlloc (ScreenPtr pScreen, int size, int align,
|
|
Bool locked,
|
|
KdOffscreenSaveProc save,
|
|
--- xorg-server-X11R7.1-1.1.0.orig/hw/kdrive/src/kaa.c~kdrive-vidmemarea
|
|
+++ xorg-server-X11R7.1-1.1.0.orig/hw/kdrive/src/kaa.c
|
|
@@ -160,7 +160,7 @@
|
|
pPixmap->drawable.width,
|
|
pPixmap->drawable.height));
|
|
pPixmap->devKind = pitch;
|
|
- pPixmap->devPrivate.ptr = (pointer) ((CARD8 *) pScreenPriv->screen->memory_base + pKaaPixmap->area->offset);
|
|
+ pPixmap->devPrivate.ptr = (pointer) ((CARD8 *) pKaaPixmap->area->vidmem->base + pKaaPixmap->area->offset);
|
|
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
|
return TRUE;
|
|
}
|
|
@@ -198,7 +198,7 @@
|
|
|
|
dst = pPixmap->devPrivate.ptr;
|
|
dst_pitch = pPixmap->devKind;
|
|
-
|
|
+
|
|
bytes = src_pitch < dst_pitch ? src_pitch : dst_pitch;
|
|
|
|
kaaWaitSync (pPixmap->drawable.pScreen);
|
|
@@ -336,10 +336,16 @@
|
|
{
|
|
ScreenPtr pScreen = p->drawable.pScreen;
|
|
KdScreenPriv(pScreen);
|
|
+ int index;
|
|
|
|
- return ((unsigned long) ((CARD8 *) p->devPrivate.ptr -
|
|
- (CARD8 *) pScreenPriv->screen->memory_base) <
|
|
- pScreenPriv->screen->memory_size);
|
|
+ for (index = 0; index < pScreenPriv->screen->num_videomem_areas; index++) {
|
|
+ KdVideoMemArea *vidmem = pScreenPriv->screen->videomem_areas[index];
|
|
+ if ((((CARD8 *)p->devPrivate.ptr) >= vidmem->base) &&
|
|
+ (((CARD8 *)p->devPrivate.ptr) <= (vidmem->base + vidmem->size))) {
|
|
+ return TRUE;
|
|
+ }
|
|
+ }
|
|
+ return FALSE;
|
|
}
|
|
|
|
PixmapPtr
|
|
@@ -1060,6 +1066,7 @@
|
|
KdCheckPaintWindow (pWin, pRegion, what);
|
|
}
|
|
|
|
+
|
|
Bool
|
|
kaaDrawInit (ScreenPtr pScreen,
|
|
KaaScreenInfoPtr pScreenInfo)
|
|
@@ -1109,7 +1116,7 @@
|
|
* Hookup offscreen pixmaps
|
|
*/
|
|
if ((pKaaScr->info->flags & KAA_OFFSCREEN_PIXMAPS) &&
|
|
- screen->off_screen_base < screen->memory_size)
|
|
+ KdHasOffscreen(screen))
|
|
{
|
|
if (!AllocatePixmapPrivate(pScreen, kaaPixmapPrivateIndex,
|
|
sizeof (KaaPixmapPrivRec)))
|
|
--- xorg-server-X11R7.1-1.1.0.orig/hw/kdrive/src/koffscreen.c~kdrive-vidmemarea
|
|
+++ xorg-server-X11R7.1-1.1.0.orig/hw/kdrive/src/koffscreen.c
|
|
@@ -41,16 +41,20 @@
|
|
{
|
|
KdScreenPriv (pScreen);
|
|
KdOffscreenArea *prev = 0, *area;
|
|
-
|
|
- assert (pScreenPriv->screen->off_screen_areas->area.offset == 0);
|
|
- for (area = pScreenPriv->off_screen_areas; area; area = area->next)
|
|
- {
|
|
- if (prev)
|
|
- assert (prev->offset + prev->size == area->offset);
|
|
+ int index;
|
|
+
|
|
+ for (index = 0; index < pScreenPriv->num_offscreen_pools; index++) {
|
|
+ area = pScreenPriv->offscreen_pools[index];
|
|
+ assert (area->vidmem->available_offset - area.offset == 0);
|
|
+ while(area) {
|
|
+ if (prev)
|
|
+ assert (prev->offset + prev->size == area->offset);
|
|
|
|
- prev = area;
|
|
+ prev = area;
|
|
+ area = area->next;
|
|
+ }
|
|
+ assert (prev->offset + prev->size == prev->vidmem->size);
|
|
}
|
|
- assert (prev->offset + prev->size == pScreenPriv->screen->memory_size);
|
|
}
|
|
#else
|
|
#define KdOffscreenValidate(s)
|
|
@@ -65,101 +69,133 @@
|
|
}
|
|
|
|
KdOffscreenArea *
|
|
-KdOffscreenAlloc (ScreenPtr pScreen, int size, int align,
|
|
- Bool locked,
|
|
- KdOffscreenSaveProc save,
|
|
- pointer privData)
|
|
+KdOffscreenAllocPrio (ScreenPtr pScreen, int size, int align,
|
|
+ Bool locked,
|
|
+ KdOffscreenSaveProc save,
|
|
+ pointer privData,
|
|
+ int minPriority,
|
|
+ int maxPriority,
|
|
+ Bool allowEviction)
|
|
{
|
|
KdOffscreenArea *area, *begin, *best;
|
|
KdScreenPriv (pScreen);
|
|
int tmp, real_size = 0, best_score;
|
|
+ int index;
|
|
+ Bool canFit = FALSE;
|
|
|
|
- KdOffscreenValidate (pScreen);
|
|
if (!align)
|
|
align = 1;
|
|
|
|
if (!size)
|
|
{
|
|
- DBG_OFFSCREEN (("Alloc 0x%x -> EMPTY\n", size));
|
|
+ DBG_OFFSCREEN(("Alloc 0x%x -> EMPTY\n", size));
|
|
return NULL;
|
|
}
|
|
|
|
/* throw out requests that cannot fit */
|
|
- if (size > (pScreenPriv->screen->memory_size - pScreenPriv->screen->off_screen_base))
|
|
- {
|
|
- DBG_OFFSCREEN (("Alloc 0x%x -> TOBIG\n", size));
|
|
- return NULL;
|
|
+ for (index = 0; index < pScreenPriv->screen->num_videomem_areas; index++) {
|
|
+ KdVideoMemArea *vidmem = pScreenPriv->screen->videomem_areas[index];
|
|
+ if ((vidmem->priority <= maxPriority) &&
|
|
+ (vidmem->priority >= minPriority)) {
|
|
+ if (size <= (vidmem->size - vidmem->available_offset)) {
|
|
+ canFit = TRUE;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
}
|
|
-
|
|
- /* Try to find a free space that'll fit. */
|
|
- for (area = pScreenPriv->off_screen_areas; area; area = area->next)
|
|
+ if (!canFit)
|
|
{
|
|
- /* skip allocated areas */
|
|
- if (area->state != KdOffscreenAvail)
|
|
- continue;
|
|
+ DBG_OFFSCREEN(("Alloc 0x%x -> TOOBIG\n", size));
|
|
+ return NULL;
|
|
+ }
|
|
|
|
- /* adjust size to match alignment requirement */
|
|
- real_size = size;
|
|
- tmp = area->offset % align;
|
|
- if (tmp)
|
|
- real_size += (align - tmp);
|
|
-
|
|
- /* does it fit? */
|
|
- if (real_size <= area->size)
|
|
- break;
|
|
+ for (index = 0; index < pScreenPriv->num_offscreen_pools; index++) {
|
|
+ /* Look just in the head, as all the areas of the pool have
|
|
+ the same vidmem */
|
|
+ area = pScreenPriv->offscreen_pools[index];
|
|
+ if ((area->vidmem->priority > maxPriority) ||
|
|
+ (area->vidmem->priority < minPriority))
|
|
+ continue;
|
|
+
|
|
+ /* Try to find a free space that'll fit. */
|
|
+ for (area = pScreenPriv->offscreen_pools[index]; area;
|
|
+ area = area->next) {
|
|
+ /* skip allocated areas */
|
|
+ if (area->state != KdOffscreenAvail)
|
|
+ continue;
|
|
+
|
|
+ /* adjust size to match alignment requirement */
|
|
+ real_size = size;
|
|
+ tmp = area->offset % align;
|
|
+ if (tmp)
|
|
+ real_size += (align - tmp);
|
|
+
|
|
+ /* does it fit? */
|
|
+ if (real_size <= area->size)
|
|
+ break;
|
|
+ }
|
|
+ if (area)
|
|
+ break;
|
|
}
|
|
-
|
|
- if (!area)
|
|
- {
|
|
+
|
|
+ if (!area && allowEviction) {
|
|
/*
|
|
* Kick out existing users to make space.
|
|
*
|
|
* First, locate a region which can hold the desired object.
|
|
*/
|
|
+ for (index = 0; index < pScreenPriv->num_offscreen_pools; index++) {
|
|
+ if ((area->vidmem->priority > maxPriority) ||
|
|
+ (area->vidmem->priority < minPriority))
|
|
+ continue;
|
|
|
|
- /* prev points at the first object to boot */
|
|
- best = NULL;
|
|
- best_score = MAXINT;
|
|
- for (begin = pScreenPriv->off_screen_areas; begin != NULL;
|
|
- begin = begin->next)
|
|
- {
|
|
- int avail, score;
|
|
- KdOffscreenArea *scan;
|
|
+ /* prev points at the first object to boot */
|
|
+ best = NULL;
|
|
+ best_score = MAXINT;
|
|
|
|
- if (begin->state == KdOffscreenLocked)
|
|
- continue;
|
|
+ for (begin = pScreenPriv->offscreen_pools[index]; begin != NULL;
|
|
+ begin = begin->next) {
|
|
+ int avail, score;
|
|
+ KdOffscreenArea *scan;
|
|
|
|
- /* adjust size to match alignment requirement */
|
|
- real_size = size;
|
|
- tmp = begin->offset % align;
|
|
- if (tmp)
|
|
- real_size += (align - tmp);
|
|
+ if (begin->state == KdOffscreenLocked)
|
|
+ continue;
|
|
+
|
|
+ /* adjust size to match alignment requirement */
|
|
+ real_size = size;
|
|
+ tmp = begin->offset % align;
|
|
+ if (tmp)
|
|
+ real_size += (align - tmp);
|
|
|
|
- avail = 0;
|
|
- score = 0;
|
|
- /* now see if we can make room here, and how "costly" it'll be. */
|
|
- for (scan = begin; scan != NULL; scan = scan->next)
|
|
- {
|
|
- if (scan->state == KdOffscreenLocked) {
|
|
- /* Can't make room here, start after this locked area. */
|
|
- begin = scan->next;
|
|
- break;
|
|
- }
|
|
- /* Score should only be non-zero for KdOffscreenRemovable */
|
|
- score += scan->score;
|
|
- avail += scan->size;
|
|
- if (avail >= real_size)
|
|
- break;
|
|
- }
|
|
- /* Is it the best option we've found so far? */
|
|
- if (avail >= real_size && score < best_score) {
|
|
- best = begin;
|
|
- best_score = score;
|
|
- }
|
|
- }
|
|
- area = best;
|
|
- if (!area)
|
|
- {
|
|
+ avail = 0;
|
|
+ score = 0;
|
|
+ /* now see if we can make room here,
|
|
+ and how "costly" it'll be. */
|
|
+ for (scan = begin; scan != NULL; scan = scan->next) {
|
|
+ if (scan->state == KdOffscreenLocked) {
|
|
+ /* Can't make room here,
|
|
+ start after this locked area. */
|
|
+ begin = scan->next;
|
|
+ break;
|
|
+ }
|
|
+ /* Score should only be non-zero for KdOffscreenRemovable */
|
|
+ score += scan->score;
|
|
+ avail += scan->size;
|
|
+ if (avail >= real_size)
|
|
+ break;
|
|
+ }
|
|
+ /* Is it the best option we've found so far? */
|
|
+ if (avail >= real_size && score < best_score) {
|
|
+ best = begin;
|
|
+ best_score = score;
|
|
+ }
|
|
+ }
|
|
+ area = best;
|
|
+ if (area)
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (!area) {
|
|
DBG_OFFSCREEN (("Alloc 0x%x -> NOSPACE\n", size));
|
|
/* Could not allocate memory */
|
|
KdOffscreenValidate (pScreen);
|
|
@@ -180,16 +216,14 @@
|
|
/*
|
|
* Now get the system to merge the other needed areas together
|
|
*/
|
|
- while (area->size < real_size)
|
|
- {
|
|
- assert (area->next && area->next->state == KdOffscreenRemovable);
|
|
+ while (area->size < real_size) {
|
|
+ assert (area->next && area->next->state == KdOffscreenRemovable);
|
|
(void) KdOffscreenKickOut (pScreen, area->next);
|
|
}
|
|
}
|
|
-
|
|
+
|
|
/* save extra space in new area */
|
|
- if (real_size < area->size)
|
|
- {
|
|
+ if (real_size < area->size) {
|
|
KdOffscreenArea *new_area = xalloc (sizeof (KdOffscreenArea));
|
|
if (!new_area)
|
|
return NULL;
|
|
@@ -198,9 +232,14 @@
|
|
new_area->state = KdOffscreenAvail;
|
|
new_area->save = 0;
|
|
new_area->score = 0;
|
|
+ new_area->vidmem = area->vidmem;
|
|
+ new_area->pool = area->pool;
|
|
new_area->next = area->next;
|
|
area->next = new_area;
|
|
area->size = real_size;
|
|
+ DBG_OFFSCREEN (("New OffscreenArea at %p (offset:0x%08x, size:0x%08x, pool:%d\n", area, area->offset, area->size, area->pool));
|
|
+
|
|
+
|
|
}
|
|
/*
|
|
* Mark this area as in use
|
|
@@ -212,42 +251,80 @@
|
|
area->privData = privData;
|
|
area->save = save;
|
|
area->score = 0;
|
|
-
|
|
+
|
|
area->save_offset = area->offset;
|
|
{
|
|
int tmp = area->offset % align;
|
|
if (tmp)
|
|
area->offset += (align - tmp);
|
|
}
|
|
-
|
|
+
|
|
KdOffscreenValidate (pScreen);
|
|
|
|
DBG_OFFSCREEN (("Alloc 0x%x -> 0x%x\n", size, area->offset));
|
|
return area;
|
|
}
|
|
|
|
+Bool
|
|
+KdHasOffscreen(KdScreenInfo *screen)
|
|
+{
|
|
+ int index;
|
|
+ DBG_OFFSCREEN (("KdHasOffscreen\n"));
|
|
+
|
|
+ for (index = 0; index < screen->num_videomem_areas; index++) {
|
|
+ KdVideoMemArea *vidmem = screen->videomem_areas[index];
|
|
+ if (vidmem->available_offset < vidmem->size) {
|
|
+ return TRUE;
|
|
+ }
|
|
+ }
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+KdOffscreenArea *
|
|
+KdOffscreenAlloc (ScreenPtr pScreen, int size, int align,
|
|
+ Bool locked,
|
|
+ KdOffscreenSaveProc save,
|
|
+ pointer privData)
|
|
+{
|
|
+ DBG_OFFSCREEN (("KdOffscreenAlloc(size:%d, align:%d, locked:%d)\n",
|
|
+ size, align, locked));
|
|
+ return KdOffscreenAllocPrio(pScreen, size, align,
|
|
+ locked,
|
|
+ save,
|
|
+ privData,
|
|
+ KD_VIDMEM_MINPRIO,
|
|
+ KD_VIDMEM_MAXPRIO,
|
|
+ TRUE);
|
|
+}
|
|
+
|
|
void
|
|
KdOffscreenSwapOut (ScreenPtr pScreen)
|
|
{
|
|
KdScreenPriv (pScreen);
|
|
+ int index;
|
|
+
|
|
+ DBG_OFFSCREEN (("KdOffscreenSwapOut\n"));
|
|
|
|
KdOffscreenValidate (pScreen);
|
|
- /* loop until a single free area spans the space */
|
|
- for (;;)
|
|
- {
|
|
- KdOffscreenArea *area = pScreenPriv->off_screen_areas;
|
|
+
|
|
+ for (index = 0; index < pScreenPriv->num_offscreen_pools; index++) {
|
|
+ /* loop until a single free area spans the space */
|
|
+ for (;;)
|
|
+ {
|
|
+ KdOffscreenArea *area = pScreenPriv->offscreen_pools[index];
|
|
|
|
- if (!area)
|
|
- break;
|
|
- if (area->state == KdOffscreenAvail)
|
|
- {
|
|
- area = area->next;
|
|
- if (!area)
|
|
- break;
|
|
- }
|
|
- assert (area->state != KdOffscreenAvail);
|
|
- (void) KdOffscreenKickOut (pScreen, area);
|
|
- KdOffscreenValidate (pScreen);
|
|
+ if (!area)
|
|
+ break;
|
|
+ if (area->state == KdOffscreenAvail)
|
|
+ {
|
|
+ area = area->next;
|
|
+ if (!area)
|
|
+ break;
|
|
+ }
|
|
+ assert (area->state != KdOffscreenAvail);
|
|
+ (void) KdOffscreenKickOut (pScreen, area);
|
|
+ KdOffscreenValidate (pScreen);
|
|
+ }
|
|
}
|
|
KdOffscreenValidate (pScreen);
|
|
KdOffscreenFini (pScreen);
|
|
@@ -256,6 +333,8 @@
|
|
void
|
|
KdOffscreenSwapIn (ScreenPtr pScreen)
|
|
{
|
|
+ KdScreenPriv (pScreen);
|
|
+ DBG_OFFSCREEN (("KdOffscreenSwapIn\n"));
|
|
KdOffscreenInit (pScreen);
|
|
}
|
|
|
|
@@ -264,7 +343,7 @@
|
|
KdOffscreenMerge (KdOffscreenArea *area)
|
|
{
|
|
KdOffscreenArea *next = area->next;
|
|
-
|
|
+ //DBG_OFFSCREEN (("KdOffscreenMerge %p\n", area));
|
|
/* account for space */
|
|
area->size += next->size;
|
|
/* frob pointer */
|
|
@@ -278,8 +357,9 @@
|
|
KdScreenPriv(pScreen);
|
|
KdOffscreenArea *next = area->next;
|
|
KdOffscreenArea *prev;
|
|
-
|
|
- DBG_OFFSCREEN (("Free 0x%x -> 0x%x\n", area->size, area->offset));
|
|
+
|
|
+ DBG_OFFSCREEN (("KdOffscreenFree 0x%x -> 0x%x\n",
|
|
+ area->size, area->offset));
|
|
KdOffscreenValidate (pScreen);
|
|
|
|
area->state = KdOffscreenAvail;
|
|
@@ -290,10 +370,11 @@
|
|
/*
|
|
* Find previous area
|
|
*/
|
|
- if (area == pScreenPriv->off_screen_areas)
|
|
+ if (area == pScreenPriv->offscreen_pools[area->pool])
|
|
prev = 0;
|
|
else
|
|
- for (prev = pScreenPriv->off_screen_areas; prev; prev = prev->next)
|
|
+ for (prev = pScreenPriv->offscreen_pools[area->pool];
|
|
+ prev; prev = prev->next)
|
|
if (prev->next == area)
|
|
break;
|
|
|
|
@@ -317,21 +398,30 @@
|
|
{
|
|
KaaPixmapPriv (pPixmap);
|
|
KdScreenPriv (pPixmap->drawable.pScreen);
|
|
+ int index;
|
|
static int iter = 0;
|
|
|
|
+
|
|
if (!pKaaPixmap->area)
|
|
return;
|
|
|
|
+ /*
|
|
+ DBG_OFFSCREEN(("KdOffscreenMarkUsed(offset:0x%08x, pool:%d)\n",
|
|
+ pKaaPixmap->area->offset,
|
|
+ pKaaPixmap->area->pool));
|
|
+ */
|
|
/* The numbers here are arbitrary. We may want to tune these. */
|
|
pKaaPixmap->area->score += 100;
|
|
if (++iter == 10) {
|
|
KdOffscreenArea *area;
|
|
- for (area = pScreenPriv->off_screen_areas; area != NULL;
|
|
- area = area->next)
|
|
- {
|
|
- if (area->state == KdOffscreenRemovable)
|
|
- area->score = (area->score * 7) / 8;
|
|
- }
|
|
+ for (index = 0; index < pScreenPriv->num_offscreen_pools; index++) {
|
|
+ for (area = pScreenPriv->offscreen_pools[index]; area != NULL;
|
|
+ area = area->next)
|
|
+ {
|
|
+ if (area->state == KdOffscreenRemovable)
|
|
+ area->score = (area->score * 7) / 8;
|
|
+ }
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -340,23 +430,41 @@
|
|
{
|
|
KdScreenPriv (pScreen);
|
|
KdOffscreenArea *area;
|
|
+ KdVideoMemArea *vidmem;
|
|
+ int index, num_offscreen;
|
|
|
|
- /* Allocate a big free area */
|
|
- area = xalloc (sizeof (KdOffscreenArea));
|
|
+ DBG_OFFSCREEN (("KdOffscreenInit\n"));
|
|
+ num_offscreen = 0;
|
|
+ pScreenPriv->num_offscreen_pools = 0;
|
|
+ pScreenPriv->offscreen_pools = NULL;
|
|
|
|
- if (!area)
|
|
- return FALSE;
|
|
+ for (index = 0; index < pScreenPriv->screen->num_videomem_areas; index++) {
|
|
+ vidmem = pScreenPriv->screen->videomem_areas[index];
|
|
+ DBG_OFFSCREEN (("Searching vidmemarea base:0x%p, size:0x%08x, available_offset:0x%08x\n", vidmem->base, vidmem->size, vidmem->available_offset));
|
|
+ if (vidmem->available_offset < vidmem->size) {
|
|
+ pScreenPriv->offscreen_pools = xrealloc(pScreenPriv->offscreen_pools,
|
|
+ sizeof(KdOffscreenArea*) * (pScreenPriv->num_offscreen_pools + 1));
|
|
+ if (!pScreenPriv->offscreen_pools) {
|
|
+ return FALSE;
|
|
+ }
|
|
+ pScreenPriv->offscreen_pools[pScreenPriv->num_offscreen_pools] =
|
|
+ area = xcalloc(sizeof(KdOffscreenArea), 1);
|
|
+ if (!area)
|
|
+ return FALSE;
|
|
+
|
|
+ area->state = KdOffscreenAvail;
|
|
+ area->vidmem = vidmem;
|
|
+ area->offset = vidmem->available_offset;
|
|
+ area->size = vidmem->size - vidmem->available_offset;
|
|
+ area->save = 0;
|
|
+ area->pool = pScreenPriv->num_offscreen_pools;
|
|
+ area->next = NULL;
|
|
+ area->score = 0;
|
|
+ pScreenPriv->num_offscreen_pools++;
|
|
+ DBG_OFFSCREEN (("New OffscreenArea at %p (offset:0x%08x, size:0x%08x, pool:%d)\n", area, area->offset, area->size, area->pool));
|
|
+ }
|
|
+ }
|
|
|
|
- area->state = KdOffscreenAvail;
|
|
- area->offset = pScreenPriv->screen->off_screen_base;
|
|
- area->size = pScreenPriv->screen->memory_size - area->offset;
|
|
- area->save = 0;
|
|
- area->next = NULL;
|
|
- area->score = 0;
|
|
-
|
|
- /* Add it to the free areas */
|
|
- pScreenPriv->off_screen_areas = area;
|
|
-
|
|
KdOffscreenValidate (pScreen);
|
|
|
|
return TRUE;
|
|
@@ -367,11 +475,17 @@
|
|
{
|
|
KdScreenPriv (pScreen);
|
|
KdOffscreenArea *area;
|
|
-
|
|
- /* just free all of the area records */
|
|
- while ((area = pScreenPriv->off_screen_areas))
|
|
- {
|
|
- pScreenPriv->off_screen_areas = area->next;
|
|
- xfree (area);
|
|
+ int index;
|
|
+
|
|
+ DBG_OFFSCREEN (("KdOffscreenFini\n"));
|
|
+ for (index = 0; index < pScreenPriv->num_offscreen_pools; index++) {
|
|
+ /* just free all of the area records */
|
|
+ while ((area = pScreenPriv->offscreen_pools[index])) {
|
|
+ pScreenPriv->offscreen_pools[index] = area->next;
|
|
+ xfree (area);
|
|
+ }
|
|
}
|
|
+ xfree(pScreenPriv->offscreen_pools);
|
|
+ pScreenPriv->offscreen_pools = NULL;
|
|
+ pScreenPriv->num_offscreen_pools = 0;
|
|
}
|
|
--- xorg-server-X11R7.1-1.1.0.orig/hw/kdrive/fbdev/fbdev.c~kdrive-vidmemarea
|
|
+++ xorg-server-X11R7.1-1.1.0.orig/hw/kdrive/fbdev/fbdev.c
|
|
@@ -330,6 +330,7 @@
|
|
FbdevScrPriv *scrpriv = screen->driver;
|
|
KdMouseMatrix m;
|
|
FbdevPriv *priv = screen->card->driver;
|
|
+ KdVideoMemArea *vidmem;
|
|
|
|
if (scrpriv->randr != RR_Rotate_0)
|
|
scrpriv->shadow = TRUE;
|
|
@@ -342,15 +343,20 @@
|
|
|
|
screen->width = priv->var.xres;
|
|
screen->height = priv->var.yres;
|
|
- screen->memory_base = (CARD8 *) (priv->fb);
|
|
- screen->memory_size = priv->fix.smem_len;
|
|
+ screen->videomem_areas = xcalloc(sizeof(KdVideoMemArea*), 1);
|
|
+ screen->videomem_areas[0] = vidmem = xcalloc(sizeof(KdVideoMemArea), 1);
|
|
+ screen->num_videomem_areas = 1;
|
|
+
|
|
+ vidmem->priority = KD_VIDMEM_MINPRIO;
|
|
+ vidmem->base = (CARD8 *) (priv->fb);
|
|
+ vidmem->size = priv->fix.smem_len;
|
|
|
|
if (scrpriv->shadow)
|
|
{
|
|
if (!KdShadowFbAlloc (screen, 0,
|
|
scrpriv->randr & (RR_Rotate_90|RR_Rotate_270)))
|
|
return FALSE;
|
|
- screen->off_screen_base = screen->memory_size;
|
|
+ vidmem->available_offset = vidmem->size;
|
|
}
|
|
else
|
|
{
|
|
@@ -358,7 +364,7 @@
|
|
screen->fb[0].pixelStride = (priv->fix.line_length * 8 /
|
|
priv->var.bits_per_pixel);
|
|
screen->fb[0].frameBuffer = (CARD8 *) (priv->fb);
|
|
- screen->off_screen_base = screen->fb[0].byteStride * screen->height;
|
|
+ vidmem->available_offset = screen->fb[0].byteStride * screen->height;
|
|
}
|
|
|
|
return TRUE;
|