[Spice-commits] 3 commits - display/driver.c display/qxldd.h display/res.c display/surface.c display/surface.h

Alexander Larsson alexl at kemper.freedesktop.org
Mon Aug 23 03:25:26 PDT 2010


 display/driver.c  |   18 ++----------------
 display/qxldd.h   |   30 +++++++++++++++---------------
 display/res.c     |   15 +++++++++++++--
 display/surface.c |    8 ++++----
 display/surface.h |   26 ++++++++++++++++++++------
 5 files changed, 54 insertions(+), 43 deletions(-)

New commits:
commit 1849821335cc7be6a5b2e6a6326ba52b31e01798
Author: Alexander Larsson <alexl at redhat.com>
Date:   Fri Aug 20 14:15:43 2010 +0200

    Move SurfaceInfo to global data
    
    When we release a surface resource, for instance when AllocMem gets
    OOM, we call ReleaseOutput with the pdev in use (i.e. probably the
    currently active one). However, its possible that the resource we
    free is actually from another (now inactive) pdev.
    
    Since the surface release function FreeDelSurface() uses pdev to
    find the data for the surface id we may find the wrong surface data.
    
    So, we move all the SurfaceInfos except the primary one to a global
    array. This is fine since the surface ids (except 0) are never shared
    between pdevs due to the surfaces_used global array.

diff --git a/display/driver.c b/display/driver.c
index 9abecb3..742348c 100644
--- a/display/driver.c
+++ b/display/driver.c
@@ -553,7 +553,6 @@ VOID DrvDisablePDEV(DHPDEV in_pdev)
     PDev* pdev = (PDev*)in_pdev;
 
     DEBUG_PRINT((NULL, 1, "%s: 0x%lx\n", __FUNCTION__, pdev));
-    EngFreeMem(pdev->surfaces_info);
     ResDestroy(pdev);
     DestroyPalette(pdev);
     EngDeleteSemaphore(pdev->cmd_sem);
@@ -744,12 +743,6 @@ BOOL PrepareHardware(PDev *pdev)
     pdev->log_level = dev_info.log_level;
 
     pdev->n_surfaces = dev_info.n_surfaces;
-    if (!(pdev->surfaces_info = (SurfaceInfo *)EngAllocMem(FL_ZERO_MEMORY,
-                                                           sizeof(SurfaceInfo) *
-                                                           pdev->n_surfaces, ALLOC_TAG))) {
-        DEBUG_PRINT((NULL, 0, "%s: surfaces_info alloc failed\n", __FUNCTION__));
-        return FALSE;
-    }
 
     pdev->mem_slots = EngAllocMem(FL_ZERO_MEMORY, sizeof(PMemSlot) * dev_info.num_mem_slot,
                                   ALLOC_TAG);
@@ -932,11 +925,6 @@ VOID DrvDisableSurface(DHPDEV in_pdev)
         pdev->surf = NULL;
     }
 
-    if (pdev->surfaces_info) {
-        EngFreeMem(pdev->surfaces_info);
-        pdev->surfaces_info = NULL;
-    }
-
     if (pdev->mem_slots) {
         EngFreeMem(pdev->mem_slots);
         pdev->mem_slots = NULL;
diff --git a/display/qxldd.h b/display/qxldd.h
index b896e23..7d22a0d 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -191,6 +191,7 @@ typedef struct DevRes {
     struct InternalPalette *palette_cache[PALETTE_HASH_SIZE];
     UINT32 num_palettes;
 
+    SurfaceInfo *surfaces_info;
     UINT8 *surfaces_used;
 
     HANDLE driver;
@@ -313,7 +314,7 @@ typedef struct PDev {
     UINT8 FPUSave[16 * 4 + 15];
 
     UINT32 n_surfaces;
-    SurfaceInfo *surfaces_info;
+    SurfaceInfo surface0_info;
 
     VIDEOMEMORY *pvmList;
 } PDev;
diff --git a/display/res.c b/display/res.c
index e1bb110..15e14ae 100644
--- a/display/res.c
+++ b/display/res.c
@@ -358,6 +358,10 @@ void CleanGlobalRes()
                 EngFreeMem(global_res[i].surfaces_used);
                 global_res[i].surfaces_used = NULL;
             }
+            if (global_res[i].surfaces_info) {
+                EngFreeMem(global_res[i].surfaces_info);
+                global_res[i].surfaces_info = NULL;
+            }
         }
         EngFreeMem(global_res);
         global_res = NULL;
@@ -400,6 +404,13 @@ static void InitRes(PDev *pdev)
         PANIC(pdev, "Res surfaces_used allocation failed\n");
     }
 
+    pdev->Res.surfaces_info = (SurfaceInfo *)EngAllocMem(FL_ZERO_MEMORY,
+							 sizeof(SurfaceInfo) * pdev->n_surfaces, 
+							 ALLOC_TAG);
+    if (!pdev->Res.surfaces_info) {
+        PANIC(pdev, "Res surfaces_info allocation failed\n");
+    }
+
     pdev->Res.free_outputs = 0;
     InitMspace(&pdev->Res, MSPACE_TYPE_DEVRAM, pdev->io_pages_virt, pdev->num_io_pages * PAGE_SIZE);
     InitMspace(&pdev->Res, MSPACE_TYPE_VRAM, pdev->fb, pdev->fb_size);
diff --git a/display/surface.h b/display/surface.h
index 6390d77..dfda502 100644
--- a/display/surface.h
+++ b/display/surface.h
@@ -8,12 +8,18 @@ static _inline UINT32 GetSurfaceIdFromInfo(SurfaceInfo *info)
   PDev *pdev;
 
   pdev = info->pdev;
-  return info - pdev->surfaces_info;
+  if (info == &pdev->surface0_info) {
+    return 0;
+  }
+  return info - pdev->Res.surfaces_info;
 }
 
 static _inline SurfaceInfo *GetSurfaceInfo(PDev *pdev, UINT32 id)
 {
-  return &pdev->surfaces_info[id];
+  if (id == 0) {
+    return &pdev->surface0_info;
+  }
+  return &pdev->Res.surfaces_info[id];
 }
 
 static _inline UINT32 GetSurfaceId(SURFOBJ *surf)
commit d48f555acb1c962305c4853154989143685b8b01
Author: Alexander Larsson <alexl at redhat.com>
Date:   Fri Aug 20 13:43:11 2010 +0200

    Add helper functions for surface info <-> id mapping

diff --git a/display/driver.c b/display/driver.c
index c00adb0..9abecb3 100644
--- a/display/driver.c
+++ b/display/driver.c
@@ -1283,14 +1283,12 @@ out_error:
 VOID APIENTRY DrvDeleteDeviceBitmap(DHSURF dhsurf)
 {
     UINT32 surface_id;
-    PDev *pdev;
     SurfaceInfo *surface;
 
     surface = (SurfaceInfo *)dhsurf;
-    pdev = surface->pdev;
-    surface_id = surface - pdev->surfaces_info;
+    surface_id = GetSurfaceIdFromInfo(surface);
 
-    DeleteDeviceBitmap(pdev, surface_id, DEVICE_BITMAP_ALLOCATION_TYPE_VRAM);
+    DeleteDeviceBitmap(surface->pdev, surface_id, DEVICE_BITMAP_ALLOCATION_TYPE_VRAM);
 }
 
 #ifdef CALL_TEST
diff --git a/display/res.c b/display/res.c
index 6be006e..e1bb110 100644
--- a/display/res.c
+++ b/display/res.c
@@ -648,11 +648,11 @@ static void FreeDelSurface(PDev *pdev, Resource *res)
     switch (internal->allocation_type) {
     case DEVICE_BITMAP_ALLOCATION_TYPE_DEVRAM:
         FreeMem(pdev, MSPACE_TYPE_DEVRAM,
-                pdev->surfaces_info[internal->surface_id].draw_area.base_mem);
+                GetSurfaceInfo(pdev, internal->surface_id)->draw_area.base_mem);
         break;
     case DEVICE_BITMAP_ALLOCATION_TYPE_VRAM:
         FreeMem(pdev, MSPACE_TYPE_VRAM,
-                pdev->surfaces_info[internal->surface_id].draw_area.base_mem);
+                GetSurfaceInfo(pdev, internal->surface_id)->draw_area.base_mem);
         break;
     default:
         PANIC(pdev, "bad allocation type");
diff --git a/display/surface.c b/display/surface.c
index 4a84f45..d9fc6f4 100644
--- a/display/surface.c
+++ b/display/surface.c
@@ -45,7 +45,7 @@ BOOL CreateDrawArea(PDev *pdev, UINT8 *base_mem, ULONG format, UINT32 cx, UINT32
     size.cx = cx;
     size.cy = cy;
 
-    drawarea = &pdev->surfaces_info[surface_id].draw_area;
+    drawarea = &GetSurfaceInfo(pdev, surface_id)->draw_area;
 
     if (!(drawarea->bitmap = (HSURF)EngCreateBitmap(size, stride, format, 0, base_mem))) {
         DEBUG_PRINT((pdev, 0, "%s: EngCreateBitmap failed\n", __FUNCTION__));
@@ -101,7 +101,7 @@ HBITMAP CreateDeviceBitmap(PDev *pdev, SIZEL size, ULONG format, QXLPHYSICAL *ph
             return 0;
     };
 
-    if (!(surf = EngCreateDeviceBitmap((DHSURF)&pdev->surfaces_info[surface_id], size, format))) {
+    if (!(surf = EngCreateDeviceBitmap((DHSURF)GetSurfaceInfo(pdev, surface_id), size, format))) {
         DEBUG_PRINT((NULL, 0, "%s: create device surface failed, 0x%lx\n",
                      __FUNCTION__, pdev));
         goto out_error1;
@@ -119,7 +119,7 @@ HBITMAP CreateDeviceBitmap(PDev *pdev, SIZEL size, ULONG format, QXLPHYSICAL *ph
         goto out_error2;
     }
 
-    pdev->surfaces_info[surface_id].pdev = pdev;
+    GetSurfaceInfo(pdev, surface_id)->pdev = pdev;
 
     QXLGetSurface(pdev, phys_mem, size.cx, size.cy, depth,
                   &stride, base_mem, allocation_type);
@@ -158,7 +158,7 @@ VOID DeleteDeviceBitmap(PDev *pdev, UINT32 surface_id, UINT8 allocation_type)
 {
     DrawArea *drawarea;
 
-    drawarea = &pdev->surfaces_info[surface_id].draw_area;
+    drawarea = &GetSurfaceInfo(pdev,surface_id)->draw_area;
 
     FreeDrawArea(drawarea);
 
diff --git a/display/surface.h b/display/surface.h
index ca1ffec..6390d77 100644
--- a/display/surface.h
+++ b/display/surface.h
@@ -3,17 +3,25 @@
 
 #include "qxldd.h"
 
+static _inline UINT32 GetSurfaceIdFromInfo(SurfaceInfo *info)
+{
+  PDev *pdev;
+
+  pdev = info->pdev;
+  return info - pdev->surfaces_info;
+}
+
+static _inline SurfaceInfo *GetSurfaceInfo(PDev *pdev, UINT32 id)
+{
+  return &pdev->surfaces_info[id];
+}
+
 static _inline UINT32 GetSurfaceId(SURFOBJ *surf)
 {
-    PDev *pdev;
     SurfaceInfo *surface;
-    UINT32 surface_id;
-
-    pdev = (PDev *)surf->dhpdev;
 
     surface = (SurfaceInfo *)surf->dhsurf;
-    surface_id = surface - pdev->surfaces_info;
-    return surface_id;
+    return GetSurfaceIdFromInfo(surface);
 }
 
 static _inline void FreeSurface(PDev *pdev, UINT32 surface_id)
commit 1c7c3ad104dfdd265de4795816a7e92ec9c49e4b
Author: Alexander Larsson <alexl at redhat.com>
Date:   Fri Aug 20 11:39:31 2010 +0200

    Move SurfaceInfo structure
    
    This is in preparation for using it in DevRes

diff --git a/display/qxldd.h b/display/qxldd.h
index 4d3911d..b896e23 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -161,6 +161,19 @@ enum {
     NUM_MSPACES,
 };
 
+typedef struct PDev PDev;
+
+typedef struct DrawArea {
+   HSURF bitmap;
+   SURFOBJ* surf_obj;
+   UINT8 *base_mem;
+} DrawArea;
+
+typedef struct SurfaceInfo {
+    DrawArea draw_area;
+    PDev *pdev;
+} SurfaceInfo;
+
 typedef struct DevRes {   
     MspaceInfo mspaces[NUM_MSPACES];
 
@@ -202,20 +215,6 @@ typedef struct DevRes {
 #define SSE_MASK 15
 #define SSE_ALIGN 16
 
- 
-typedef struct DrawArea {
-   HSURF bitmap;
-   SURFOBJ* surf_obj;
-   UINT8 *base_mem;
-} DrawArea;
-
-typedef struct PDev PDev;
-
-typedef struct SurfaceInfo {
-    DrawArea draw_area;
-    PDev *pdev;
-} SurfaceInfo;
-
 typedef struct PDev {
     HANDLE driver;
     HDEV eng;


More information about the Spice-commits mailing list