Use same assumptions as layergc about what layer kind is approprate for
unwrapping pixmap operations. This makes sure the accelerated code gets invoked for pixmaps Add pixmap migration support to kaa. Can't quite automatically migrate pixmaps off-screen, but soon we will. Can kick objects out of video memory. Move per-screen linked list pointers to pixmap private. Wrap Composite in preparation for migrating pixmaps. Have kasync ignore drawable type so that pixmaps trigger sync Add KdOffscreenFini to cleanup on server reset. Switch off screen area to have only a 'save' function; moving objects to off screen memory is done by saving then freeing the area.
This commit is contained in:
parent
109b949516
commit
cb46169759
|
@ -31,43 +31,50 @@
|
||||||
#include "fontstruct.h"
|
#include "fontstruct.h"
|
||||||
#include "dixfontstr.h"
|
#include "dixfontstr.h"
|
||||||
|
|
||||||
|
#define DEBUG_MIGRATE 0
|
||||||
|
#if DEBUG_MIGRATE
|
||||||
|
#define DBG_MIGRATE(a) ErrorF a
|
||||||
|
#else
|
||||||
|
#define DBG_MIGRATE(a)
|
||||||
|
#endif
|
||||||
|
|
||||||
int kaaGeneration;
|
int kaaGeneration;
|
||||||
int kaaScreenPrivateIndex;
|
int kaaScreenPrivateIndex;
|
||||||
int kaaPixmapPrivateIndex;
|
int kaaPixmapPrivateIndex;
|
||||||
|
|
||||||
typedef struct _PixmapLink {
|
|
||||||
PixmapPtr pPixmap;
|
|
||||||
|
|
||||||
struct _PixmapLink *next;
|
|
||||||
} PixmapLink;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
KaaScreenInfoPtr info;
|
KaaScreenInfoPtr info;
|
||||||
|
|
||||||
int offscreenSize;
|
|
||||||
int offscreenBase;
|
|
||||||
PixmapLink *offscreenPixmaps;
|
|
||||||
|
|
||||||
CreatePixmapProcPtr CreatePixmap;
|
CreatePixmapProcPtr CreatePixmap;
|
||||||
DestroyPixmapProcPtr DestroyPixmap;
|
DestroyPixmapProcPtr DestroyPixmap;
|
||||||
|
int pixelOffset; /* offset from pPixmap to pixels */
|
||||||
} KaaScreenPrivRec, *KaaScreenPrivPtr;
|
} KaaScreenPrivRec, *KaaScreenPrivPtr;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
KdOffscreenArea *offscreenArea;
|
KdOffscreenArea *area;
|
||||||
|
int score;
|
||||||
|
int devKind;
|
||||||
|
DevUnion devPrivate;
|
||||||
} KaaPixmapPrivRec, *KaaPixmapPrivPtr;
|
} KaaPixmapPrivRec, *KaaPixmapPrivPtr;
|
||||||
|
|
||||||
|
#define KAA_PIXMAP_SCORE_MOVE_IN 10
|
||||||
|
#define KAA_PIXMAP_SCORE_MAX 20
|
||||||
|
#define KAA_PIXMAP_SCORE_MOVE_OUT -10
|
||||||
|
#define KAA_PIXMAP_SCORE_MIN -20
|
||||||
|
|
||||||
#define KaaGetScreenPriv(s) ((KaaScreenPrivPtr)(s)->devPrivates[kaaScreenPrivateIndex].ptr)
|
#define KaaGetScreenPriv(s) ((KaaScreenPrivPtr)(s)->devPrivates[kaaScreenPrivateIndex].ptr)
|
||||||
#define KaaScreenPriv(s) KaaScreenPrivPtr pKaaScr = KaaGetScreenPriv(s)
|
#define KaaScreenPriv(s) KaaScreenPrivPtr pKaaScr = KaaGetScreenPriv(s)
|
||||||
|
|
||||||
#define KaaGetPixmapPriv(p) ((KaaPixmapPrivPtr)(p)->devPrivates[kaaPixmapPrivateIndex].ptr)
|
#define KaaGetPixmapPriv(p) ((KaaPixmapPrivPtr)(p)->devPrivates[kaaPixmapPrivateIndex].ptr)
|
||||||
#define KaaPixmapPriv(p) KaaPixmapPrivPtr pKaaPixmap = KaaGetPixmapPriv (p)
|
#define KaaSetPixmapPriv(p,a) ((p)->devPrivates[kaaPixmapPrivateIndex].ptr = (pointer) (a))
|
||||||
|
#define KaaPixmapPriv(p) KaaPixmapPrivPtr pKaaPixmap = KaaGetPixmapPriv(p)
|
||||||
|
|
||||||
#define KaaPixmapPitch(w) (((w) + (pKaaScr->info->offscreenPitch - 1)) & ~(pKaaScr->info->offscreenPitch - 1))
|
#define KaaPixmapPitch(w) (((w) + (pKaaScr->info->offscreenPitch - 1)) & ~(pKaaScr->info->offscreenPitch - 1))
|
||||||
#define KaaDrawableIsOffscreenPixmap(d) (d->type == DRAWABLE_PIXMAP && \
|
#define KaaDrawableIsOffscreenPixmap(d) (d->type == DRAWABLE_PIXMAP && \
|
||||||
KaaGetPixmapPriv ((PixmapPtr)(d)) != NULL && \
|
KaaGetPixmapPriv((PixmapPtr)(d)) && \
|
||||||
KaaGetPixmapPriv ((PixmapPtr)(d))->offscreenArea != NULL && \
|
KaaGetPixmapPriv((PixmapPtr)(d))->area)
|
||||||
!KaaGetPixmapPriv ((PixmapPtr)(d))->offscreenArea->swappedOut)
|
#define KaaDrawableIsScreen(d) (((d)->type == DRAWABLE_WINDOW) || \
|
||||||
|
KaaDrawableIsOffscreenPixmap(d))
|
||||||
|
|
||||||
#define KAA_SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = \
|
#define KAA_SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = \
|
||||||
((KaaScreenPrivPtr) (pScreen)->devPrivates[kaaScreenPrivateIndex].ptr)->field)
|
((KaaScreenPrivPtr) (pScreen)->devPrivates[kaaScreenPrivateIndex].ptr)->field)
|
||||||
|
@ -75,62 +82,162 @@ typedef struct {
|
||||||
#define KAA_SCREEN_EPILOGUE(pScreen, field, wrapper)\
|
#define KAA_SCREEN_EPILOGUE(pScreen, field, wrapper)\
|
||||||
((pScreen)->field = wrapper)
|
((pScreen)->field = wrapper)
|
||||||
|
|
||||||
#define MIN_OFFPIX_SIZE (320*200)
|
#define MIN_OFFPIX_SIZE (4096)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
kaaMoveOutPixmap (KdOffscreenArea *area)
|
kaaPixmapSave (KdOffscreenArea *area)
|
||||||
{
|
{
|
||||||
PixmapPtr pPixmap = area->privData;
|
PixmapPtr pPixmap = area->privData;
|
||||||
int dst_pitch, src_pitch;
|
KaaPixmapPriv(pPixmap);
|
||||||
|
int dst_pitch, src_pitch, bytes;
|
||||||
unsigned char *dst, *src;
|
unsigned char *dst, *src;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
DBG_MIGRATE (("Save 0x%08x (0x%x) (%dx%d)\n",
|
||||||
|
pPixmap->drawable.id,
|
||||||
|
KaaGetPixmapPriv(pPixmap)->area ?
|
||||||
|
KaaGetPixmapPriv(pPixmap)->area->offset : -1,
|
||||||
|
pPixmap->drawable.width,
|
||||||
|
pPixmap->drawable.height));
|
||||||
|
|
||||||
|
KdCheckSync (pPixmap->drawable.pScreen);
|
||||||
|
|
||||||
src_pitch = pPixmap->devKind;
|
src_pitch = pPixmap->devKind;
|
||||||
dst_pitch = BitmapBytePad (pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel);
|
dst_pitch = pKaaPixmap->devKind;
|
||||||
|
|
||||||
src = pPixmap->devPrivate.ptr;
|
src = pPixmap->devPrivate.ptr;
|
||||||
dst = xalloc (dst_pitch * pPixmap->drawable.height);
|
dst = pKaaPixmap->devPrivate.ptr;
|
||||||
if (!dst)
|
|
||||||
FatalError("Out of memory\n");
|
|
||||||
|
|
||||||
pPixmap->devKind = dst_pitch;
|
pPixmap->devKind = dst_pitch;
|
||||||
pPixmap->devPrivate.ptr = dst;
|
pPixmap->devPrivate.ptr = dst;
|
||||||
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||||
|
pKaaPixmap->area = NULL;
|
||||||
|
|
||||||
|
bytes = src_pitch < dst_pitch ? src_pitch : dst_pitch;
|
||||||
|
|
||||||
i = pPixmap->drawable.height;
|
i = pPixmap->drawable.height;
|
||||||
while (i--) {
|
while (i--) {
|
||||||
memcpy (dst, src, dst_pitch);
|
memcpy (dst, src, bytes);
|
||||||
|
dst += dst_pitch;
|
||||||
|
src += src_pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
kaaPixmapAllocArea (PixmapPtr pPixmap)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||||
|
KaaScreenPriv (pScreen);
|
||||||
|
KaaPixmapPriv (pPixmap);
|
||||||
|
int bpp = pPixmap->drawable.bitsPerPixel;
|
||||||
|
CARD16 h = pPixmap->drawable.height;
|
||||||
|
CARD16 w = pPixmap->drawable.width;
|
||||||
|
int pitch = KaaPixmapPitch (w);
|
||||||
|
PixmapPtr pScreenPixmap = (*pScreen->GetScreenPixmap)(pScreen);
|
||||||
|
|
||||||
|
pKaaPixmap->devKind = pPixmap->devKind;
|
||||||
|
pKaaPixmap->devPrivate = pPixmap->devPrivate;
|
||||||
|
pKaaPixmap->area = KdOffscreenAlloc (pScreen, pitch * h * (bpp >> 3),
|
||||||
|
pKaaScr->info->offscreenByteAlign,
|
||||||
|
FALSE,
|
||||||
|
kaaPixmapSave, (pointer) pPixmap);
|
||||||
|
if (!pKaaPixmap->area)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
DBG_MIGRATE(("++ 0x%08x (0x%x) (%dx%d)\n",
|
||||||
|
pPixmap->drawable.id,
|
||||||
|
KaaGetPixmapPriv(pPixmap)->area ?
|
||||||
|
KaaGetPixmapPriv(pPixmap)->area->offset : -1,
|
||||||
|
pPixmap->drawable.width,
|
||||||
|
pPixmap->drawable.height));
|
||||||
|
pPixmap->devKind = pitch * (bpp >> 3);
|
||||||
|
pPixmap->devPrivate.ptr = (pointer) ((CARD8 *) pScreenPixmap->devPrivate.ptr + pKaaPixmap->area->offset);
|
||||||
|
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
kaaMoveInPixmap (PixmapPtr pPixmap)
|
||||||
|
{
|
||||||
|
int dst_pitch, src_pitch, bytes;
|
||||||
|
unsigned char *dst, *src;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
return;
|
||||||
|
KdCheckSync (pPixmap->drawable.pScreen);
|
||||||
|
|
||||||
|
DBG_MIGRATE (("-> 0x%08x (0x%x) (%dx%d)\n",
|
||||||
|
pPixmap->drawable.id,
|
||||||
|
KaaGetPixmapPriv(pPixmap)->area ?
|
||||||
|
KaaGetPixmapPriv(pPixmap)->area->offset : -1,
|
||||||
|
pPixmap->drawable.width,
|
||||||
|
pPixmap->drawable.height));
|
||||||
|
|
||||||
|
src = pPixmap->devPrivate.ptr;
|
||||||
|
src_pitch = pPixmap->devKind;
|
||||||
|
|
||||||
|
if (!kaaPixmapAllocArea (pPixmap))
|
||||||
|
return;
|
||||||
|
|
||||||
|
dst = pPixmap->devPrivate.ptr;
|
||||||
|
dst_pitch = pPixmap->devKind;
|
||||||
|
|
||||||
|
bytes = src_pitch < dst_pitch ? src_pitch : dst_pitch;
|
||||||
|
|
||||||
|
i = pPixmap->drawable.height;
|
||||||
|
while (i--) {
|
||||||
|
memcpy (dst, src, bytes);
|
||||||
dst += dst_pitch;
|
dst += dst_pitch;
|
||||||
src += src_pitch;
|
src += src_pitch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
kaaMoveInPixmap (KdOffscreenArea *area)
|
kaaMoveOutPixmap (PixmapPtr pPixmap)
|
||||||
{
|
{
|
||||||
PixmapPtr pPixmap = area->privData;
|
KaaPixmapPriv (pPixmap);
|
||||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
KdOffscreenArea *area = pKaaPixmap->area;
|
||||||
KaaScreenPriv (pScreen);
|
|
||||||
PixmapPtr pScreenPixmap = (*pScreen->GetScreenPixmap) (pScreen);
|
|
||||||
int dst_pitch, src_pitch;
|
|
||||||
unsigned char *dst, *src;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
src_pitch = pPixmap->devKind;
|
|
||||||
dst_pitch = BitmapBytePad (KaaPixmapPitch (pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel));
|
|
||||||
|
|
||||||
src = pPixmap->devPrivate.ptr;
|
DBG_MIGRATE (("<- 0x%08x (0x%x) (%dx%d)\n",
|
||||||
dst = pScreenPixmap->devPrivate.ptr + area->offset;
|
pPixmap->drawable.id,
|
||||||
|
KaaGetPixmapPriv(pPixmap)->area ?
|
||||||
|
KaaGetPixmapPriv(pPixmap)->area->offset : -1,
|
||||||
|
pPixmap->drawable.width,
|
||||||
|
pPixmap->drawable.height));
|
||||||
|
if (area)
|
||||||
|
{
|
||||||
|
kaaPixmapSave (area);
|
||||||
|
KdOffscreenFree (area);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pPixmap->devKind = dst_pitch;
|
static void
|
||||||
pPixmap->devPrivate.ptr = dst;
|
kaaPixmapUseScreen (PixmapPtr pPixmap)
|
||||||
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
{
|
||||||
|
KaaPixmapPriv (pPixmap);
|
||||||
i = pPixmap->drawable.height;
|
|
||||||
while (i--) {
|
if (pKaaPixmap->score < KAA_PIXMAP_SCORE_MAX)
|
||||||
memcpy (dst, src, dst_pitch);
|
{
|
||||||
dst += dst_pitch;
|
pKaaPixmap->score++;
|
||||||
src += src_pitch;
|
DBG_MIGRATE (("UseScreen 0x%x (%d)\n", pPixmap->drawable.id, pKaaPixmap->score));
|
||||||
|
if (!pKaaPixmap->area &&
|
||||||
|
pKaaPixmap->score >= KAA_PIXMAP_SCORE_MOVE_IN)
|
||||||
|
kaaMoveInPixmap (pPixmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
kaaPixmapUseMemory (PixmapPtr pPixmap)
|
||||||
|
{
|
||||||
|
KaaPixmapPriv (pPixmap);
|
||||||
|
|
||||||
|
if (pKaaPixmap->score > KAA_PIXMAP_SCORE_MIN)
|
||||||
|
{
|
||||||
|
pKaaPixmap->score--;
|
||||||
|
DBG_MIGRATE (("UseMemory 0x%x (%d)\n", pPixmap->drawable.id, pKaaPixmap->score));
|
||||||
|
if (pKaaPixmap->area &&
|
||||||
|
pKaaPixmap->score <= KAA_PIXMAP_SCORE_MOVE_OUT)
|
||||||
|
kaaMoveOutPixmap (pPixmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,39 +245,23 @@ static Bool
|
||||||
kaaDestroyPixmap (PixmapPtr pPixmap)
|
kaaDestroyPixmap (PixmapPtr pPixmap)
|
||||||
{
|
{
|
||||||
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
ScreenPtr pScreen = pPixmap->drawable.pScreen;
|
||||||
KaaPixmapPriv (pPixmap);
|
|
||||||
KaaScreenPriv (pScreen);
|
|
||||||
Bool ret;
|
Bool ret;
|
||||||
|
|
||||||
if (pPixmap->refcnt == 1)
|
if (pPixmap->refcnt == 1)
|
||||||
{
|
{
|
||||||
if (pKaaPixmap->offscreenArea)
|
KaaPixmapPriv (pPixmap);
|
||||||
|
if (pKaaPixmap->area)
|
||||||
{
|
{
|
||||||
PixmapLink *link, *prev;
|
DBG_MIGRATE(("-- 0x%08x (0x%x) (%dx%d)\n",
|
||||||
|
pPixmap->drawable.id,
|
||||||
|
KaaGetPixmapPriv(pPixmap)->area->offset,
|
||||||
|
pPixmap->drawable.width,
|
||||||
|
pPixmap->drawable.height));
|
||||||
/* Free the offscreen area */
|
/* Free the offscreen area */
|
||||||
KdOffscreenFree (pKaaPixmap->offscreenArea);
|
KdCheckSync (pScreen);
|
||||||
|
KdOffscreenFree (pKaaPixmap->area);
|
||||||
if (pKaaPixmap->offscreenArea->swappedOut)
|
pPixmap->devPrivate = pKaaPixmap->devPrivate;
|
||||||
{
|
pPixmap->devKind = pKaaPixmap->devKind;
|
||||||
xfree (pPixmap->devPrivate.ptr);
|
|
||||||
pPixmap->devPrivate.ptr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
link = pKaaScr->offscreenPixmaps;
|
|
||||||
prev = NULL;
|
|
||||||
while (link->pPixmap != pPixmap)
|
|
||||||
{
|
|
||||||
prev = link;
|
|
||||||
link = link->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prev)
|
|
||||||
prev->next = link->next;
|
|
||||||
else
|
|
||||||
pKaaScr->offscreenPixmaps = link->next;
|
|
||||||
|
|
||||||
xfree (link);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,72 +275,21 @@ kaaDestroyPixmap (PixmapPtr pPixmap)
|
||||||
static PixmapPtr
|
static PixmapPtr
|
||||||
kaaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
|
kaaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
|
||||||
{
|
{
|
||||||
KaaScreenPriv (pScreen);
|
|
||||||
int size = w * h;
|
|
||||||
int pitch;
|
|
||||||
int bpp;
|
|
||||||
PixmapPtr pPixmap = NULL;
|
PixmapPtr pPixmap = NULL;
|
||||||
KaaPixmapPrivPtr pKaaPixmap;
|
KaaPixmapPrivPtr pKaaPixmap;
|
||||||
|
|
||||||
if (kdEnabled &&
|
|
||||||
size > MIN_OFFPIX_SIZE)
|
|
||||||
{
|
|
||||||
KdOffscreenArea *area;
|
|
||||||
PixmapLink *link;
|
|
||||||
PixmapPtr pScreenPixmap;
|
|
||||||
|
|
||||||
bpp = BitsPerPixel (depth);
|
|
||||||
pitch = KaaPixmapPitch (w);
|
|
||||||
|
|
||||||
area = KdOffscreenAlloc (pScreen, pitch * h * (bpp >> 3), pKaaScr->info->offscreenByteAlign,
|
|
||||||
FALSE, kaaMoveInPixmap, kaaMoveOutPixmap, NULL);
|
|
||||||
|
|
||||||
if (!area)
|
|
||||||
goto oom;
|
|
||||||
|
|
||||||
link = xalloc (sizeof (PixmapLink));
|
|
||||||
if (!link)
|
|
||||||
{
|
|
||||||
KdOffscreenFree (area);
|
|
||||||
goto oom;
|
|
||||||
}
|
|
||||||
|
|
||||||
KAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
|
|
||||||
pPixmap = (* pScreen->CreatePixmap) (pScreen, 0, 0, depth);
|
|
||||||
KAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, kaaCreatePixmap);
|
|
||||||
|
|
||||||
pKaaPixmap = (KaaPixmapPrivPtr)pPixmap->devPrivates[kaaPixmapPrivateIndex].ptr;
|
|
||||||
pKaaPixmap->offscreenArea = area;
|
|
||||||
|
|
||||||
pScreenPixmap = (*pScreen->GetScreenPixmap)(pScreen);
|
|
||||||
|
|
||||||
pPixmap->drawable.width = w;
|
|
||||||
pPixmap->drawable.height = h;
|
|
||||||
pPixmap->drawable.bitsPerPixel = bpp;
|
|
||||||
pPixmap->devKind = pitch * (bpp >> 3);
|
|
||||||
pPixmap->devPrivate.ptr = pScreenPixmap->devPrivate.ptr + area->offset;
|
|
||||||
|
|
||||||
link->pPixmap = pPixmap;
|
|
||||||
link->next = pKaaScr->offscreenPixmaps;
|
|
||||||
|
|
||||||
area->privData = pPixmap;
|
|
||||||
|
|
||||||
pKaaScr->offscreenPixmaps = link;
|
|
||||||
|
|
||||||
return pPixmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
oom:
|
|
||||||
KAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
|
KAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
|
||||||
pPixmap = (* pScreen->CreatePixmap) (pScreen, w, h, depth);
|
pPixmap = (* pScreen->CreatePixmap) (pScreen, w, h, depth);
|
||||||
KAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, kaaCreatePixmap);
|
KAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, kaaCreatePixmap);
|
||||||
|
if (!pPixmap)
|
||||||
if (pPixmap)
|
return NULL;
|
||||||
{
|
pKaaPixmap = KaaGetPixmapPriv(pPixmap);
|
||||||
pKaaPixmap = (KaaPixmapPrivPtr)pPixmap->devPrivates[kaaPixmapPrivateIndex].ptr;
|
pKaaPixmap->score = 0;
|
||||||
pKaaPixmap->offscreenArea = NULL;
|
pKaaPixmap->area = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
|
/* if ((pPixmap->devKind * h >= MIN_OFFPIX_SIZE) */
|
||||||
|
if (w * h > 100 * 100)
|
||||||
|
kaaPixmapAllocArea (pPixmap);
|
||||||
return pPixmap;
|
return pPixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,6 +414,14 @@ kaaCopyNtoN (DrawablePtr pSrcDrawable,
|
||||||
KaaScreenPriv (pDstDrawable->pScreen);
|
KaaScreenPriv (pDstDrawable->pScreen);
|
||||||
PixmapPtr pSrcPixmap, pDstPixmap;
|
PixmapPtr pSrcPixmap, pDstPixmap;
|
||||||
|
|
||||||
|
/* Migrate pixmaps to same place as destination */
|
||||||
|
if (pScreenPriv->enabled && pSrcDrawable->type == DRAWABLE_PIXMAP) {
|
||||||
|
if (KaaDrawableIsScreen (pDstDrawable))
|
||||||
|
kaaPixmapUseScreen ((PixmapPtr) pSrcDrawable);
|
||||||
|
else
|
||||||
|
kaaPixmapUseMemory ((PixmapPtr) pSrcDrawable);
|
||||||
|
}
|
||||||
|
|
||||||
if (pScreenPriv->enabled &&
|
if (pScreenPriv->enabled &&
|
||||||
(pSrcPixmap = kaaGetDrawingPixmap (pSrcDrawable, NULL, NULL)) &&
|
(pSrcPixmap = kaaGetDrawingPixmap (pSrcDrawable, NULL, NULL)) &&
|
||||||
(pDstPixmap = kaaGetDrawingPixmap (pDstDrawable, NULL, NULL)) &&
|
(pDstPixmap = kaaGetDrawingPixmap (pDstDrawable, NULL, NULL)) &&
|
||||||
|
@ -731,8 +779,7 @@ kaaValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
|
||||||
{
|
{
|
||||||
fbValidateGC (pGC, changes, pDrawable);
|
fbValidateGC (pGC, changes, pDrawable);
|
||||||
|
|
||||||
if (pDrawable->type == DRAWABLE_WINDOW ||
|
if (KaaDrawableIsScreen (pDrawable))
|
||||||
KaaDrawableIsOffscreenPixmap (pDrawable))
|
|
||||||
pGC->ops = (GCOps *) &kaaOps;
|
pGC->ops = (GCOps *) &kaaOps;
|
||||||
else
|
else
|
||||||
pGC->ops = (GCOps *) &kdAsyncPixmapGCOps;
|
pGC->ops = (GCOps *) &kdAsyncPixmapGCOps;
|
||||||
|
@ -850,12 +897,44 @@ kaaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
|
||||||
KdCheckPaintWindow (pWin, pRegion, what);
|
KdCheckPaintWindow (pWin, pRegion, what);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef RENDER
|
||||||
|
static void
|
||||||
|
kaaComposite(CARD8 op,
|
||||||
|
PicturePtr pSrc,
|
||||||
|
PicturePtr pMask,
|
||||||
|
PicturePtr pDst,
|
||||||
|
INT16 xSrc,
|
||||||
|
INT16 ySrc,
|
||||||
|
INT16 xMask,
|
||||||
|
INT16 yMask,
|
||||||
|
INT16 xDst,
|
||||||
|
INT16 yDst,
|
||||||
|
CARD16 width,
|
||||||
|
CARD16 height)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
kaaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable);
|
||||||
|
if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
kaaPixmapUseMemory ((PixmapPtr) pMask->pDrawable);
|
||||||
|
if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
|
||||||
|
kaaPixmapUseMemory ((PixmapPtr) pDst->pDrawable);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
KdCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
|
||||||
|
xMask, yMask, xDst, yDst, width, height);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
kaaDrawInit (ScreenPtr pScreen,
|
kaaDrawInit (ScreenPtr pScreen,
|
||||||
KaaScreenInfoPtr pScreenInfo)
|
KaaScreenInfoPtr pScreenInfo)
|
||||||
{
|
{
|
||||||
KaaScreenPrivPtr pKaaScr;
|
KaaScreenPrivPtr pKaaScr;
|
||||||
KdScreenInfo *screen = KdGetScreenPriv (pScreen)->screen;
|
KdScreenInfo *screen = KdGetScreenPriv (pScreen)->screen;
|
||||||
|
#ifdef RENDER
|
||||||
|
PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (kaaGeneration != serverGeneration)
|
if (kaaGeneration != serverGeneration)
|
||||||
{
|
{
|
||||||
|
@ -870,7 +949,6 @@ kaaDrawInit (ScreenPtr pScreen,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
pKaaScr->info = pScreenInfo;
|
pKaaScr->info = pScreenInfo;
|
||||||
pKaaScr->offscreenPixmaps = NULL;
|
|
||||||
|
|
||||||
pScreen->devPrivates[kaaScreenPrivateIndex].ptr = (pointer) pKaaScr;
|
pScreen->devPrivates[kaaScreenPrivateIndex].ptr = (pointer) pKaaScr;
|
||||||
|
|
||||||
|
@ -885,6 +963,10 @@ kaaDrawInit (ScreenPtr pScreen,
|
||||||
pScreen->CopyWindow = kaaCopyWindow;
|
pScreen->CopyWindow = kaaCopyWindow;
|
||||||
pScreen->PaintWindowBackground = kaaPaintWindow;
|
pScreen->PaintWindowBackground = kaaPaintWindow;
|
||||||
pScreen->PaintWindowBorder = kaaPaintWindow;
|
pScreen->PaintWindowBorder = kaaPaintWindow;
|
||||||
|
#ifdef RENDER
|
||||||
|
if (ps)
|
||||||
|
ps->Composite = kaaComposite;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hookup offscreen pixmaps
|
* Hookup offscreen pixmaps
|
||||||
|
@ -892,13 +974,13 @@ kaaDrawInit (ScreenPtr pScreen,
|
||||||
if ((pKaaScr->info->flags & KAA_OFFSCREEN_PIXMAPS) &&
|
if ((pKaaScr->info->flags & KAA_OFFSCREEN_PIXMAPS) &&
|
||||||
screen->off_screen_size > 0)
|
screen->off_screen_size > 0)
|
||||||
{
|
{
|
||||||
if (!AllocatePixmapPrivate(pScreen, kaaPixmapPrivateIndex, sizeof(KaaPixmapPrivRec)))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
pKaaScr->CreatePixmap = pScreen->CreatePixmap;
|
pKaaScr->CreatePixmap = pScreen->CreatePixmap;
|
||||||
pScreen->CreatePixmap = kaaCreatePixmap;
|
pScreen->CreatePixmap = kaaCreatePixmap;
|
||||||
pKaaScr->DestroyPixmap = pScreen->DestroyPixmap;
|
pKaaScr->DestroyPixmap = pScreen->DestroyPixmap;
|
||||||
pScreen->DestroyPixmap = kaaDestroyPixmap;
|
pScreen->DestroyPixmap = kaaDestroyPixmap;
|
||||||
|
if (!AllocatePixmapPrivate(pScreen, kaaPixmapPrivateIndex,
|
||||||
|
sizeof (KaaPixmapPrivRec)))
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -63,8 +63,7 @@ RegionPtr
|
||||||
KdCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
KdCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||||
int srcx, int srcy, int w, int h, int dstx, int dsty)
|
int srcx, int srcy, int w, int h, int dstx, int dsty)
|
||||||
{
|
{
|
||||||
if (pSrc->type == DRAWABLE_WINDOW || pDst->type == DRAWABLE_WINDOW)
|
KdCheckSync (pSrc->pScreen);
|
||||||
KdCheckSync (pSrc->pScreen);
|
|
||||||
return fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
|
return fbCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,8 +72,7 @@ KdCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||||
int srcx, int srcy, int w, int h, int dstx, int dsty,
|
int srcx, int srcy, int w, int h, int dstx, int dsty,
|
||||||
unsigned long bitPlane)
|
unsigned long bitPlane)
|
||||||
{
|
{
|
||||||
if (pSrc->type == DRAWABLE_WINDOW || pDst->type == DRAWABLE_WINDOW)
|
KdCheckSync (pSrc->pScreen);
|
||||||
KdCheckSync (pSrc->pScreen);
|
|
||||||
return fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
|
return fbCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
|
||||||
bitPlane);
|
bitPlane);
|
||||||
}
|
}
|
||||||
|
@ -199,8 +197,7 @@ KdCheckGetSpans (DrawablePtr pDrawable,
|
||||||
int nspans,
|
int nspans,
|
||||||
char *pdstStart)
|
char *pdstStart)
|
||||||
{
|
{
|
||||||
if (pDrawable->type != DRAWABLE_PIXMAP)
|
KdCheckSync(pDrawable->pScreen);
|
||||||
KdCheckSync(pDrawable->pScreen);
|
|
||||||
fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
|
fbGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,3 +305,11 @@ const GCOps kdAsyncPixmapGCOps = {
|
||||||
,NULL
|
,NULL
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
KdAssertSync (ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
KdScreenPriv(pScreen);
|
||||||
|
KdCardInfo *card = pScreenPriv->card;
|
||||||
|
assert (!card->needSync);
|
||||||
|
}
|
||||||
|
|
|
@ -844,6 +844,9 @@ KdCloseScreen (int index, ScreenPtr pScreen)
|
||||||
pScreen->CloseScreen = pScreenPriv->CloseScreen;
|
pScreen->CloseScreen = pScreenPriv->CloseScreen;
|
||||||
ret = (*pScreen->CloseScreen) (index, pScreen);
|
ret = (*pScreen->CloseScreen) (index, pScreen);
|
||||||
|
|
||||||
|
if (screen->off_screen_size > 0)
|
||||||
|
KdOffscreenFini (pScreen);
|
||||||
|
|
||||||
if (pScreenPriv->dpmsState != KD_DPMS_NORMAL)
|
if (pScreenPriv->dpmsState != KD_DPMS_NORMAL)
|
||||||
(*card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL);
|
(*card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL);
|
||||||
|
|
||||||
|
|
|
@ -267,7 +267,6 @@ typedef struct _KdOffscreenArea {
|
||||||
int offset;
|
int offset;
|
||||||
int size;
|
int size;
|
||||||
pointer privData;
|
pointer privData;
|
||||||
Bool swappedOut;
|
|
||||||
} KdOffscreenArea;
|
} KdOffscreenArea;
|
||||||
|
|
||||||
extern const KdMonitorTiming kdMonitorTimings[];
|
extern const KdMonitorTiming kdMonitorTimings[];
|
||||||
|
@ -753,6 +752,22 @@ KdRandRGetTiming (ScreenPtr pScreen,
|
||||||
void
|
void
|
||||||
KdPictureInitAsync (ScreenPtr pScreen);
|
KdPictureInitAsync (ScreenPtr pScreen);
|
||||||
|
|
||||||
|
#ifdef RENDER
|
||||||
|
void
|
||||||
|
KdCheckComposite (CARD8 op,
|
||||||
|
PicturePtr pSrc,
|
||||||
|
PicturePtr pMask,
|
||||||
|
PicturePtr pDst,
|
||||||
|
INT16 xSrc,
|
||||||
|
INT16 ySrc,
|
||||||
|
INT16 xMask,
|
||||||
|
INT16 yMask,
|
||||||
|
INT16 xDst,
|
||||||
|
INT16 yDst,
|
||||||
|
CARD16 width,
|
||||||
|
CARD16 height);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* kshadow.c */
|
/* kshadow.c */
|
||||||
Bool
|
Bool
|
||||||
KdShadowScreenInit (KdScreenInfo *screen);
|
KdShadowScreenInit (KdScreenInfo *screen);
|
||||||
|
@ -771,7 +786,7 @@ int
|
||||||
KdFrameBufferSize (CARD8 *base, int max);
|
KdFrameBufferSize (CARD8 *base, int max);
|
||||||
|
|
||||||
/* koffscreen.c */
|
/* koffscreen.c */
|
||||||
typedef void (*KdOffscreenMoveDataProc) (KdOffscreenArea *area);
|
typedef void (*KdOffscreenSaveProc) (KdOffscreenArea *area);
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
KdOffscreenInit (ScreenPtr pScreen);
|
KdOffscreenInit (ScreenPtr pScreen);
|
||||||
|
@ -779,8 +794,7 @@ KdOffscreenInit (ScreenPtr pScreen);
|
||||||
KdOffscreenArea *
|
KdOffscreenArea *
|
||||||
KdOffscreenAlloc (ScreenPtr pScreen, int size, int align,
|
KdOffscreenAlloc (ScreenPtr pScreen, int size, int align,
|
||||||
Bool locked,
|
Bool locked,
|
||||||
KdOffscreenMoveDataProc moveIn,
|
KdOffscreenSaveProc save,
|
||||||
KdOffscreenMoveDataProc moveOut,
|
|
||||||
pointer privData);
|
pointer privData);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -792,6 +806,9 @@ KdOffscreenSwapOut (ScreenPtr pScreen);
|
||||||
void
|
void
|
||||||
KdOffscreenSwapIn (ScreenPtr pScreen);
|
KdOffscreenSwapIn (ScreenPtr pScreen);
|
||||||
|
|
||||||
|
void
|
||||||
|
KdOffscreenFini (ScreenPtr pScreen);
|
||||||
|
|
||||||
/* function prototypes to be implemented by the drivers */
|
/* function prototypes to be implemented by the drivers */
|
||||||
void
|
void
|
||||||
InitCard (char *name);
|
InitCard (char *name);
|
||||||
|
|
|
@ -28,91 +28,171 @@
|
||||||
#endif
|
#endif
|
||||||
#include "kdrive.h"
|
#include "kdrive.h"
|
||||||
|
|
||||||
|
#define DEBUG_OFFSCREEN 0
|
||||||
|
#if DEBUG_OFFSCREEN
|
||||||
|
#define DBG_OFFSCREEN(a) ErrorF a
|
||||||
|
#else
|
||||||
|
#define DBG_OFFSCREEN(a)
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct _RealOffscreenArea {
|
typedef struct _RealOffscreenArea {
|
||||||
KdOffscreenArea area;
|
KdOffscreenArea area;
|
||||||
|
|
||||||
KdOffscreenMoveDataProc moveIn;
|
KdOffscreenSaveProc save;
|
||||||
KdOffscreenMoveDataProc moveOut;
|
|
||||||
|
|
||||||
Bool locked;
|
Bool locked;
|
||||||
|
|
||||||
struct _RealOffscreenArea *next;
|
|
||||||
struct _RealOffscreenArea *prev;
|
struct _RealOffscreenArea *prev;
|
||||||
|
struct _RealOffscreenArea *next;
|
||||||
} RealOffscreenArea;
|
} RealOffscreenArea;
|
||||||
|
|
||||||
|
#if DEBUG_OFFSCREEN
|
||||||
|
static void
|
||||||
|
KdOffscreenValidate (ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
KdScreenPriv (pScreen);
|
||||||
|
RealOffscreenArea *prev = 0, *area;
|
||||||
|
|
||||||
|
assert (pScreenPriv->screen->off_screen_areas->area.offset == 0);
|
||||||
|
for (area = pScreenPriv->screen->off_screen_areas; area; area = area->next)
|
||||||
|
{
|
||||||
|
if (prev)
|
||||||
|
assert (prev->area.offset + prev->area.size == area->area.offset);
|
||||||
|
|
||||||
|
prev = area;
|
||||||
|
}
|
||||||
|
assert (prev->area.offset + prev->area.size == pScreenPriv->screen->off_screen_size);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define KdOffscreenValidate(s)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
KdOffscreenKickOut (KdOffscreenArea *area)
|
||||||
|
{
|
||||||
|
RealOffscreenArea *real_area = (RealOffscreenArea *) area;
|
||||||
|
KdCheckSync (area->screen);
|
||||||
|
if (real_area->save)
|
||||||
|
(*real_area->save) (area);
|
||||||
|
KdOffscreenFree (area);
|
||||||
|
}
|
||||||
|
|
||||||
KdOffscreenArea *
|
KdOffscreenArea *
|
||||||
KdOffscreenAlloc (ScreenPtr pScreen, int size, int align,
|
KdOffscreenAlloc (ScreenPtr pScreen, int size, int align,
|
||||||
Bool locked,
|
Bool locked,
|
||||||
KdOffscreenMoveDataProc moveIn,
|
KdOffscreenSaveProc save,
|
||||||
KdOffscreenMoveDataProc moveOut,
|
|
||||||
pointer privData)
|
pointer privData)
|
||||||
{
|
{
|
||||||
RealOffscreenArea *area;
|
RealOffscreenArea *area, **prev;
|
||||||
KdScreenPriv (pScreen);
|
KdScreenPriv (pScreen);
|
||||||
int tmp, real_size;
|
int tmp, real_size;
|
||||||
|
|
||||||
|
KdOffscreenValidate (pScreen);
|
||||||
if (!align)
|
if (!align)
|
||||||
align = 1;
|
align = 1;
|
||||||
|
|
||||||
/* Go through the areas */
|
if (!size)
|
||||||
area = pScreenPriv->screen->off_screen_areas;
|
|
||||||
while (area != NULL)
|
|
||||||
{
|
{
|
||||||
if (area->area.screen != NULL)
|
DBG_OFFSCREEN (("Alloc 0x%x -> EMPTY\n", size));
|
||||||
{
|
return NULL;
|
||||||
area = area->next;
|
}
|
||||||
|
|
||||||
|
/* throw out requests that cannot fit */
|
||||||
|
if (size > pScreenPriv->screen->off_screen_size)
|
||||||
|
{
|
||||||
|
DBG_OFFSCREEN (("Alloc 0x%x -> TOBIG\n", size));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
retry:
|
||||||
|
|
||||||
|
/* Go through the areas */
|
||||||
|
for (area = pScreenPriv->screen->off_screen_areas; area; area = area->next)
|
||||||
|
{
|
||||||
|
/* skip allocated areas */
|
||||||
|
if (area->area.screen)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
|
/* adjust size to match alignment requirement */
|
||||||
real_size = size;
|
real_size = size;
|
||||||
tmp = (area->area.offset + area->area.size - size) % align;
|
tmp = area->area.offset % align;
|
||||||
|
|
||||||
if (tmp)
|
if (tmp)
|
||||||
real_size += (align - tmp);
|
real_size += (align - tmp);
|
||||||
|
|
||||||
|
/* does it fit? */
|
||||||
if (real_size <= area->area.size)
|
if (real_size <= area->area.size)
|
||||||
{
|
{
|
||||||
RealOffscreenArea *new_area;
|
RealOffscreenArea *new_area;
|
||||||
|
|
||||||
if (real_size == area->area.size)
|
/* save extra space in new area */
|
||||||
|
if (real_size < area->area.size)
|
||||||
{
|
{
|
||||||
area->area.screen = pScreen;
|
new_area = xalloc (sizeof (RealOffscreenArea));
|
||||||
area->area.privData = privData;
|
if (!new_area)
|
||||||
area->area.swappedOut = FALSE;
|
return NULL;
|
||||||
area->locked = locked;
|
new_area->area.offset = area->area.offset + real_size;
|
||||||
area->moveIn = moveIn;
|
new_area->area.size = area->area.size - real_size;
|
||||||
area->moveOut = moveOut;
|
new_area->area.screen = 0;
|
||||||
|
new_area->locked = FALSE;
|
||||||
return (KdOffscreenArea *)area;
|
new_area->save = 0;
|
||||||
|
if ((new_area->next = area->next))
|
||||||
|
new_area->next->prev = new_area;
|
||||||
|
new_area->prev = area;
|
||||||
|
area->next = new_area;
|
||||||
|
area->area.size = real_size;
|
||||||
}
|
}
|
||||||
|
area->area.screen = pScreen;
|
||||||
|
area->area.privData = privData;
|
||||||
|
area->locked = locked;
|
||||||
|
area->save = save;
|
||||||
|
|
||||||
|
KdOffscreenValidate (pScreen);
|
||||||
|
|
||||||
/* Create a new area */
|
DBG_OFFSCREEN (("Alloc 0x%x -> 0x%x\n", size, area->area.offset));
|
||||||
new_area = xalloc (sizeof (RealOffscreenArea));
|
return &area->area;
|
||||||
new_area->area.offset = area->area.offset + area->area.size - real_size;
|
|
||||||
new_area->area.size = real_size;
|
|
||||||
new_area->area.screen = pScreen;
|
|
||||||
new_area->area.swappedOut = FALSE;
|
|
||||||
new_area->locked = locked;
|
|
||||||
new_area->moveIn = moveIn;
|
|
||||||
new_area->moveOut = moveOut;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Kick out existing users. This is pretty simplistic; it just
|
||||||
|
* keeps deleting areas until the first area is free and has enough room
|
||||||
|
*/
|
||||||
|
|
||||||
|
prev = (RealOffscreenArea **) &pScreenPriv->screen->off_screen_areas;
|
||||||
|
while ((area = *prev))
|
||||||
|
{
|
||||||
|
if (area->area.screen && !area->locked)
|
||||||
|
{
|
||||||
|
KdOffscreenKickOut (&area->area);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* adjust size to match alignment requirement */
|
||||||
|
real_size = size;
|
||||||
|
tmp = area->area.offset % align;
|
||||||
|
if (tmp)
|
||||||
|
real_size += (align - tmp);
|
||||||
|
|
||||||
|
/* does it fit? */
|
||||||
|
if (real_size <= area->area.size)
|
||||||
|
goto retry;
|
||||||
|
|
||||||
|
/* kick out the next area */
|
||||||
|
area = area->next;
|
||||||
|
if (!area)
|
||||||
|
break;
|
||||||
|
/* skip over locked areas */
|
||||||
|
if (area->locked)
|
||||||
|
{
|
||||||
|
prev = &area->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
assert (area->area.screen);
|
||||||
|
KdOffscreenKickOut (&area->area);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG_OFFSCREEN (("Alloc 0x%x -> NOSPACE\n", size));
|
||||||
/* Could not allocate memory */
|
/* Could not allocate memory */
|
||||||
|
KdOffscreenValidate (pScreen);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,68 +200,73 @@ void
|
||||||
KdOffscreenSwapOut (ScreenPtr pScreen)
|
KdOffscreenSwapOut (ScreenPtr pScreen)
|
||||||
{
|
{
|
||||||
KdScreenPriv (pScreen);
|
KdScreenPriv (pScreen);
|
||||||
RealOffscreenArea *area = pScreenPriv->screen->off_screen_areas;
|
|
||||||
|
|
||||||
while (area)
|
KdOffscreenValidate (pScreen);
|
||||||
|
/* loop until a single free area spans the space */
|
||||||
|
for (;;)
|
||||||
{
|
{
|
||||||
if (area->area.screen && area->moveOut)
|
RealOffscreenArea *area = pScreenPriv->screen->off_screen_areas;
|
||||||
(*area->moveOut) ((KdOffscreenArea *)area);
|
|
||||||
|
if (!area)
|
||||||
area->area.swappedOut = TRUE;
|
break;
|
||||||
|
if (area->area.screen)
|
||||||
|
{
|
||||||
|
KdOffscreenKickOut (&area->area);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
area = area->next;
|
area = area->next;
|
||||||
|
if (!area)
|
||||||
|
break;
|
||||||
|
assert (area->area.screen);
|
||||||
|
KdOffscreenKickOut (&area->area);
|
||||||
|
KdOffscreenValidate (pScreen);
|
||||||
}
|
}
|
||||||
|
KdOffscreenValidate (pScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
KdOffscreenSwapIn (ScreenPtr pScreen)
|
KdOffscreenSwapIn (ScreenPtr pScreen)
|
||||||
{
|
{
|
||||||
KdScreenPriv (pScreen);
|
/* nothing to do here; page in on usage */
|
||||||
RealOffscreenArea *area = pScreenPriv->screen->off_screen_areas;
|
}
|
||||||
|
|
||||||
while (area)
|
/* merge the next free area into this one */
|
||||||
{
|
static void
|
||||||
if (area->area.screen && area->moveIn)
|
KdOffscreenMerge (KdOffscreenArea *area)
|
||||||
(*area->moveIn) ((KdOffscreenArea *)area);
|
{
|
||||||
|
RealOffscreenArea *real_area = (RealOffscreenArea *) area;
|
||||||
|
RealOffscreenArea *next = real_area->next;
|
||||||
|
|
||||||
area->area.swappedOut = FALSE;
|
/* account for space */
|
||||||
area = area->next;
|
real_area->area.size += next->area.size;
|
||||||
}
|
/* frob pointers */
|
||||||
|
if ((real_area->next = next->next))
|
||||||
|
real_area->next->prev = real_area;
|
||||||
|
xfree (next);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
KdOffscreenFree (KdOffscreenArea *area)
|
KdOffscreenFree (KdOffscreenArea *area)
|
||||||
{
|
{
|
||||||
RealOffscreenArea *real_area = (RealOffscreenArea *)area;
|
ScreenPtr pScreen = area->screen;
|
||||||
|
RealOffscreenArea *real_area = (RealOffscreenArea *) area;
|
||||||
|
RealOffscreenArea *next = real_area->next;
|
||||||
|
RealOffscreenArea *prev = real_area->prev;
|
||||||
|
|
||||||
real_area->area.screen = NULL;
|
DBG_OFFSCREEN (("Free 0x%x -> 0x%x\n", area->size, area->offset));
|
||||||
|
KdOffscreenValidate (pScreen);
|
||||||
|
|
||||||
if (real_area && real_area->next && !real_area->next->area.screen)
|
area->screen = NULL;
|
||||||
{
|
|
||||||
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;
|
/* link with next area if free */
|
||||||
real_area->next->area.offset = real_area->area.offset;
|
if (next && !next->area.screen)
|
||||||
|
KdOffscreenMerge (&real_area->area);
|
||||||
tmp = real_area->next;
|
|
||||||
xfree (real_area);
|
|
||||||
real_area = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (real_area->prev && !real_area->prev->area.screen)
|
/* link with prev area if free */
|
||||||
{
|
if (prev && !prev->area.screen)
|
||||||
real_area->prev->next = real_area->next;
|
KdOffscreenMerge (&prev->area);
|
||||||
if (real_area->next)
|
|
||||||
real_area->next->prev = real_area->prev;
|
KdOffscreenValidate (pScreen);
|
||||||
|
|
||||||
real_area->prev->area.size += real_area->area.size;
|
|
||||||
|
|
||||||
xfree (real_area);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
|
@ -199,13 +284,29 @@ KdOffscreenInit (ScreenPtr pScreen)
|
||||||
area->area.screen = NULL;
|
area->area.screen = NULL;
|
||||||
area->area.offset = pScreenPriv->screen->off_screen_base;
|
area->area.offset = pScreenPriv->screen->off_screen_base;
|
||||||
area->area.size = pScreenPriv->screen->off_screen_size;
|
area->area.size = pScreenPriv->screen->off_screen_size;
|
||||||
area->area.swappedOut = FALSE;
|
area->save = 0;
|
||||||
|
area->locked = FALSE;
|
||||||
area->next = NULL;
|
area->next = NULL;
|
||||||
area->prev = NULL;
|
area->prev = NULL;
|
||||||
|
|
||||||
/* Add it to the free areas */
|
/* Add it to the free areas */
|
||||||
pScreenPriv->screen->off_screen_areas = area;
|
pScreenPriv->screen->off_screen_areas = area;
|
||||||
|
|
||||||
|
KdOffscreenValidate (pScreen);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
KdOffscreenFini (ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
KdScreenPriv (pScreen);
|
||||||
|
RealOffscreenArea *area;
|
||||||
|
|
||||||
|
/* just free all of the area records */
|
||||||
|
while ((area = pScreenPriv->screen->off_screen_areas))
|
||||||
|
{
|
||||||
|
pScreenPriv->screen->off_screen_areas = area->next;
|
||||||
|
xfree (area);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue