[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