offscreen_manager.c [plain text]
#include "vmware.h"
struct _Heap {
CARD8* ptr;
CARD32 size;
CARD32 maxSlots;
CARD32 startOffset;
SVGASurface* frontBuffer;
SVGASurface* slotsStart;
Bool clear;
};
static SVGASurface* FillInSurface(Heap* heap, SVGASurface* surface,
CARD32 width, CARD32 height,
CARD32 bpp, CARD32 pitch, CARD32 size,
CARD32 sizeUsed);
Heap*
vmwareHeap_Create(CARD8* ptr, CARD32 size, CARD32 maxSlots, CARD32 startOffset,
CARD32 sWidth, CARD32 sHeight, CARD32 sBPP, CARD32 sPitch,
CARD32 sFbOffset)
{
Heap* newHeap = malloc(sizeof (Heap));
newHeap->ptr = ptr;
newHeap->size = size - sizeof(SVGASurface);
newHeap->maxSlots = maxSlots;
newHeap->startOffset = startOffset;
newHeap->frontBuffer = FillInSurface(newHeap,
(SVGASurface*)(ptr + newHeap->size),
sWidth, sHeight, sBPP, sPitch,
sHeight * sPitch, 0);
newHeap->frontBuffer->dataOffset = sFbOffset;
newHeap->frontBuffer->numQueued = newHeap->frontBuffer->numDequeued = 0;
newHeap->slotsStart = (SVGASurface*)(newHeap->ptr + newHeap->size) -
newHeap->maxSlots;
newHeap->clear = FALSE;
vmwareHeap_Clear(newHeap);
return newHeap;
}
void
vmwareHeap_Destroy(Heap* heap)
{
free(heap);
}
void
vmwareHeap_Clear(Heap* heap)
{
if (!heap->clear) {
memset(heap->slotsStart, 0, heap->maxSlots * sizeof (SVGASurface));
heap->clear = TRUE;
}
}
static SVGASurface*
FillInSurface(Heap* heap, SVGASurface* surface, CARD32 width, CARD32 height,
CARD32 bpp, CARD32 pitch, CARD32 size, CARD32 offset)
{
surface->size = sizeof (SVGASurface);
surface->version = SVGA_SURFACE_VERSION_1;
surface->bpp = bpp;
surface->width = width;
surface->height = height;
surface->pitch = pitch;
if (surface->userData == 0) {
surface->userData = size;
}
surface->dataOffset = offset + heap->startOffset;
return surface;
}
SVGASurface*
vmwareHeap_GetFrontBuffer(Heap* heap)
{
return heap->frontBuffer;
}
SVGASurface*
vmwareHeap_AllocSurface(Heap* heap, CARD32 width, CARD32 height,
CARD32 pitch, CARD32 bpp)
{
CARD32 size = pitch * height;
CARD32 sizeUsed = 0;
SVGASurface* surface = heap->slotsStart;
int i;
for (i = 0; i < heap->maxSlots; i++) {
if (surface[i].userData == 0) {
if ((CARD8*)heap->slotsStart - heap->ptr - sizeUsed < size) {
return NULL;
}
heap->clear = FALSE;
return FillInSurface(heap, surface + i, width, height, bpp,
pitch, size, sizeUsed);
}
if (surface[i].numQueued == surface[i].numDequeued &&
surface[i].userData >= size) {
heap->clear = FALSE;
return FillInSurface(heap, surface + i, width, height, bpp,
pitch, size, sizeUsed);
}
sizeUsed += surface[i].userData;
}
return NULL;
}