[Spice-devel,qxl-win,v2,5/6] display: fix how MoveAllSurfacesToRam handles failure

Submitted by Yonit Halperin on Aug. 28, 2011, 3:23 p.m.

Details

Message ID 1314519838-16161-6-git-send-email-yhalperi@redhat.com
State New, archived
Headers show

Not browsing as part of any series.

Commit Message

Yonit Halperin Aug. 28, 2011, 3:23 p.m.
1) send create surface commands for all the surfaces that have not been
   moved to vram
2) fix the parameters sent to SendSurfaceCreateCommand
3) send create primary surface IO
---
 display/driver.c  |    1 +
 display/qxldd.h   |    1 +
 display/surface.c |   54 +++++++++++++++++++++++++++++++++++++++-------------
 3 files changed, 42 insertions(+), 14 deletions(-)

Patch hide | download patch | download mbox

diff --git a/display/driver.c b/display/driver.c
index 30f0373..de1f714 100644
--- a/display/driver.c
+++ b/display/driver.c
@@ -1028,6 +1028,7 @@  static BOOL AssertModeDisable(PDev *pdev)
     async_io(pdev, ASYNCABLE_DESTROY_ALL_SURFACES, 0);
     /* move all surfaces from device to system memory */
     if (!MoveAllSurfacesToRam(pdev)) {
+        EnableQXLPrimarySurface(pdev);
         return FALSE;
     }
     if (!FlushRelease(pdev)) {
diff --git a/display/qxldd.h b/display/qxldd.h
index b03c3de..6482e8a 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -200,6 +200,7 @@  struct SurfaceInfo {
     SIZEL       size;
     UINT8      *copy;
     ULONG       bitmap_format;
+    INT32       stride;
     union {
         PDev *pdev;
         SurfaceInfo *next_free;
diff --git a/display/surface.c b/display/surface.c
index 60bbd99..16723d3 100644
--- a/display/surface.c
+++ b/display/surface.c
@@ -187,7 +187,7 @@  HBITMAP CreateDeviceBitmap(PDev *pdev, SIZEL size, ULONG format, QXLPHYSICAL *ph
                     __FUNCTION__, pdev, surface_id));
         goto out_error2;
     }
-
+    surface_info->stride = stride;
     if (allocation_type != DEVICE_BITMAP_ALLOCATION_TYPE_SURF0) {
         SendSurfaceCreateCommand(pdev, surface_id, size, surface_format, -stride, *phys_mem, 0);
     }
@@ -318,6 +318,42 @@  int MoveAllSurfacesToVideoRam(PDev *pdev)
     return TRUE;
 }
 
+/* to_surface_id is exclusive */
+static void SendSurfaceRangeCreateCommand(PDev *pdev, UINT32 from_surface_id, UINT32 to_surface_id)
+{
+    UINT32 surface_id;
+
+    ASSERT(pdev, from_surface_id < to_surface_id);
+    ASSERT(pdev, to_surface_id <= pdev->n_surfaces);
+
+    for (surface_id = from_surface_id; surface_id < to_surface_id; surface_id++) {
+        SurfaceInfo *surface_info;
+        SURFOBJ *surf_obj;
+        QXLPHYSICAL phys_mem;
+        UINT32 surface_format;
+        UINT32 depth;
+
+        surface_info = GetSurfaceInfo(pdev, surface_id);
+        if (!surface_info->draw_area.base_mem) {
+            continue;
+        }
+
+        surf_obj = surface_info->draw_area.surf_obj;
+
+        if (!surf_obj) {
+            continue;
+        }
+
+        phys_mem = SurfaceToPhysical(pdev, surface_info->draw_area.base_mem);
+        BitmapFormatToDepthAndSurfaceFormat(surface_info->bitmap_format, &depth, &surface_format);
+
+        SendSurfaceCreateCommand(pdev, surface_id, surf_obj->sizlBitmap,
+                                 surface_format, -surface_info->stride, phys_mem,
+                                 /* the surface is still there, tell server not to erase */
+                                 1);
+    }
+}
+
 BOOL MoveAllSurfacesToRam(PDev *pdev)
 {
     UINT32 surface_id;
@@ -357,19 +393,9 @@  BOOL MoveAllSurfacesToRam(PDev *pdev)
             /* Send a create messsage for this surface - we previously did a destroy all. */
             EngFreeMem(surface_info->copy);
             surface_info->copy = NULL;
-            DEBUG_PRINT((pdev, 0, "%s: %d: EngModifySurface failed, sending create\n",
-                         __FUNCTION__, surface_id));
-            phys_mem = SurfaceToPhysical(pdev, surface_info->draw_area.base_mem);
-            /*
-             * TODO: bug. create_command should be send for all surfaces >= surface_id
-             *       since they stay in the pci-bar. Alternatively,
-             *       don't call destroy_all_surfaces, instead send destroy commands
-             *       for all surfaces with id < surface_id.
-             */
-            SendSurfaceCreateCommand(pdev, surface_id, surf_obj->sizlBitmap,
-                                     surface_info->bitmap_format, -surf_obj->lDelta, phys_mem,
-                                     /* the surface is still there, tell server not to erase */
-                                     1);
+            DEBUG_PRINT((pdev, 0, "%s: %d: EngModifySurface failed, sending create for %d-%d\n",
+                         __FUNCTION__, surface_id, surface_id, pdev->n_surfaces - 1));
+            SendSurfaceRangeCreateCommand(pdev, surface_id, pdev->n_surfaces);
             return FALSE;
         }
         QXLDelSurface(pdev, surface_info->draw_area.base_mem, DEVICE_BITMAP_ALLOCATION_TYPE_VRAM);