[Spice-devel] [PATCH 7/8] Store surfaces_used in a bit-array

alexl at redhat.com alexl at redhat.com
Fri Aug 20 11:54:39 PDT 2010


From: Alexander Larsson <alexl at redhat.com>

This is smaller than a byte array, and allows us to skip full
blocks of 32 ids in one check.
---
 display/qxldd.h   |    2 +-
 display/res.c     |    2 +-
 display/surface.h |   55 +++++++++++++++++++++++++++++++++++++++++++---------
 3 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/display/qxldd.h b/display/qxldd.h
index 7984fc8..aa20ef4 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -192,7 +192,7 @@ typedef struct DevRes {
     UINT32 num_palettes;
 
     SurfaceInfo *surfaces_info;
-    UINT8 *surfaces_used;
+    UINT32 *surfaces_used;
 
     HANDLE driver;
 #ifdef DBG
diff --git a/display/res.c b/display/res.c
index 7773e40..4569315 100644
--- a/display/res.c
+++ b/display/res.c
@@ -402,7 +402,7 @@ static void InitRes(PDev *pdev)
         PANIC(pdev, "Res dynamic allocation failed\n");
     }
 
-    pdev->Res.surfaces_used = EngAllocMem(FL_ZERO_MEMORY, sizeof(UINT8) * pdev->n_surfaces,
+    pdev->Res.surfaces_used = EngAllocMem(FL_ZERO_MEMORY, sizeof(UINT32) * ((pdev->n_surfaces + 31) / 32),
                                           ALLOC_TAG);
     if (!pdev->Res.surfaces_used) {
         PANIC(pdev, "Res surfaces_used allocation failed\n");
diff --git a/display/surface.h b/display/surface.h
index 14c67b0..2b23272 100644
--- a/display/surface.h
+++ b/display/surface.h
@@ -32,28 +32,63 @@ static _inline UINT32 GetSurfaceId(SURFOBJ *surf)
 
 static _inline void FreeSurface(PDev *pdev, UINT32 surface_id)
 {
-   pdev->Res.surfaces_used[surface_id] = 0;
+    UINT32 i, bitmask;
+
+    i = surface_id / 32;
+    bitmask = (~0x80000000) >> (surface_id % 32);
+
+    pdev->Res.surfaces_used[i] &= bitmask;
 }
 
 
 static UINT32 GetFreeSurface(PDev *pdev)
 {
-    UINT32 x;
-
-    //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;
+    UINT32 start = 1;
+    UINT32 bit;
+    UINT32 i, end_i;
+    UINT32 bitmask;
+    UINT32 used_mask;
+    UINT32 res = 0;
+
+    i = start / 32;
+    end_i = (pdev->n_surfaces + 31) / 32;
+    bit = start % 32;
+    bitmask = (0x80000000) >> (bit % 32);
+
+    while (i < end_i) {
+        used_mask = pdev->Res.surfaces_used[i];
+        /* Avoid checks early if no unused */
+        if (used_mask == 0xffffffff) {
+            while (bit < 32) {
+                if ((used_mask & bitmask) == 0) {
+                    res = i*32 + bit;
+                    pdev->Res.surfaces_used[i] |= bitmask;
+                    break;
+                }
+                bit++;
+                bitmask >>= 1;
+            }
         }
+        i++;
+        bit = 0;
+        bitmask = 0x80000000;
     }
 
-    return 0;
+    if (res > pdev->n_surfaces) {
+        /* Could happen in the last word if n_surfaces is not a multiple of 32 */
+        res = 0;
+    }
+
+    return res;
 }
 
 static BOOL SurfaceInUse(PDev *pdev, UINT32 id)
 {
-  return pdev->Res.surfaces_used[id];
+    UINT32 i, bitmask;
+
+    i = id / 32;
+    bitmask = 0x80000000 >> (id % 32);
+    return (pdev->Res.surfaces_used[id] & bitmask) != 0;
 }
 
 enum {
-- 
1.7.2.1



More information about the Spice-devel mailing list