[Spice-devel] [PATCH 6/7] New list based surface allocator
alexl at redhat.com
alexl at redhat.com
Tue Aug 24 01:41:13 PDT 2010
From: Alexander Larsson <alexl at redhat.com>
We store a free list in the SurfaceInfos, using a field not otherwise
used for free surfaces. Also, treat base_mem == NULL as "surface in use"
for easy checking.
---
display/qxldd.h | 1 +
display/res.c | 4 ++++
display/surface.c | 2 +-
display/surface.h | 24 ++++++++++++++++--------
4 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/display/qxldd.h b/display/qxldd.h
index 7c5b6ec..2cb2db4 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -197,6 +197,7 @@ typedef struct DevRes {
UINT32 num_palettes;
SurfaceInfo *surfaces_info;
+ SurfaceInfo *free_surfaces;
UINT8 *surfaces_used;
HANDLE driver;
diff --git a/display/res.c b/display/res.c
index eef6a49..e20dc96 100644
--- a/display/res.c
+++ b/display/res.c
@@ -437,6 +437,10 @@ static void InitRes(PDev *pdev)
if (!pdev->Res.surfaces_info) {
PANIC(pdev, "Res surfaces_info allocation failed\n");
}
+ pdev->Res.free_surfaces = &pdev->Res.surfaces_info[0];
+ for (i = 0; i < pdev->n_surfaces - 1; i++) {
+ pdev->Res.surfaces_info[i].u.next_free = &pdev->Res.surfaces_info[i+1];
+ }
pdev->Res.free_outputs = 0;
pdev->Res.malloc_sem = EngCreateSemaphore();
diff --git a/display/surface.c b/display/surface.c
index 54e0d0c..bfffb7f 100644
--- a/display/surface.c
+++ b/display/surface.c
@@ -163,7 +163,7 @@ VOID DeleteDeviceBitmap(PDev *pdev, UINT32 surface_id, UINT8 allocation_type)
FreeDrawArea(drawarea);
if (allocation_type != DEVICE_BITMAP_ALLOCATION_TYPE_SURF0 &&
- pdev->Res.surfaces_used[surface_id]) {
+ pdev->Res.surfaces_info[surface_id].draw_area.base_mem != NULL) {
QXLSurfaceCmd *surface;
surface = SurfaceCmd(pdev, QXL_SURFACE_CMD_DESTROY, surface_id);
diff --git a/display/surface.h b/display/surface.h
index 5504793..27e8239 100644
--- a/display/surface.h
+++ b/display/surface.h
@@ -32,23 +32,31 @@ static _inline UINT32 GetSurfaceId(SURFOBJ *surf)
static _inline void FreeSurface(PDev *pdev, UINT32 surface_id)
{
- pdev->Res.surfaces_used[surface_id] = 0;
+ SurfaceInfo *surface;
+
+ if (surface_id == 0) {
+ return;
+ }
+ surface = &pdev->Res.surfaces_info[surface_id];
+ surface->draw_area.base_mem = NULL; /* Mark as not used */
+ surface->u.next_free = pdev->Res.free_surfaces;
+ pdev->Res.free_surfaces = surface;
}
static UINT32 GetFreeSurface(PDev *pdev)
{
UINT32 x;
+ SurfaceInfo *surface;
- //not effective, fix me
- for (x = 1; x < pdev->n_surfaces; ++x) {
- if (!pdev->Res.surfaces_used[x]) {
- pdev->Res.surfaces_used[x] = 1;
- return x;
- }
+ surface = pdev->Res.free_surfaces;
+ if (surface == NULL) {
+ return 0;
}
- return 0;
+ pdev->Res.free_surfaces = surface->u.next_free;
+
+ return surface - pdev->Res.surfaces_info;
}
enum {
--
1.7.2.1
More information about the Spice-devel
mailing list