[Spice-devel] [RFC PATCH qxl-wddm-dod 27/28] Fix source buffer mapping in PresentDisplayOnly

Dmitry Fleytman dmitry at daynix.com
Mon Jul 18 06:34:08 UTC 2016


From: Sameeh Jubran <sameeh at daynix.com>

Part of source image mapped by PresentDisplayOnly
should be big enough to cover all rectangles being
transferred.

Signed-off-by: Sameeh Jubran <sameeh at daynix.com>
Signed-off-by: Dmitry Fleytman <dmitry at daynix.com>
---
 qxldod/QxlDod.cpp | 28 +++++++++++++++++++++++-----
 qxldod/QxlDod.h   |  1 +
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/qxldod/QxlDod.cpp b/qxldod/QxlDod.cpp
index 7b3d353..0ec00fe 100755
--- a/qxldod/QxlDod.cpp
+++ b/qxldod/QxlDod.cpp
@@ -3642,12 +3642,11 @@ QxlDevice::ExecutePresentDisplayOnly(
     ctx->Mdl              = NULL;
     ctx->DisplaySource    = this;
 
-    // Alternate between synch and asynch execution, for demonstrating 
-    // that a real hardware implementation can do either
-
+    // Source bitmap is in user mode, must be locked under __try/__except
+    // and mapped to kernel space before use.
     {
-        // Map Source into kernel space, as Blt will be executed by system worker thread
-        UINT sizeToMap = ctx->SrcPitch * ctx->SrcHeight;
+        LONG maxHeight = GetMaxSourceMappingHeight(ctx->Moves, ctx->NumMoves, ctx->DirtyRect, ctx->NumDirtyRects);
+        UINT sizeToMap = ctx->SrcPitch * maxHeight;
 
         PMDL mdl = IoAllocateMdl((PVOID)SrcAddr, sizeToMap,  FALSE, FALSE, NULL);
         if(!mdl)
@@ -4527,6 +4526,25 @@ void QxlDevice::SaveVDAgentState(QXLEscapeVDAgentRunning* vdagent_running)
     m_VDAgentRunning = (vdagent_running->running == 0) ? FALSE : TRUE;
 }
 
+LONG QxlDevice::GetMaxSourceMappingHeight(D3DKMT_MOVE_RECT* Moves, ULONG NumMoves, RECT* DirtyRects, ULONG NumDirtyRects)
+{
+    LONG maxHeight = 0;
+    if (Moves != NULL) {
+        for (UINT i = 0; i < NumMoves; i++) {
+            POINT*   pSourcePoint = &Moves[i].SourcePoint;
+            RECT*    pDestRect = &Moves[i].DestRect;
+            maxHeight = MAX(maxHeight, pDestRect->bottom - pDestRect->top + pSourcePoint->y);
+        }
+    }
+    if (DirtyRects != NULL) {
+        for (UINT i = 0; i < NumDirtyRects; i++) {
+            RECT*    pDirtyRect = &DirtyRects[i];
+            maxHeight = MAX(maxHeight, pDirtyRect->bottom);
+        }
+    }
+    return maxHeight;
+}
+
 NTSTATUS QxlDevice::Escape(_In_ CONST DXGKARG_ESCAPE* pEscape)
 {
     PAGED_CODE();
diff --git a/qxldod/QxlDod.h b/qxldod/QxlDod.h
index 41189b3..0757648 100755
--- a/qxldod/QxlDod.h
+++ b/qxldod/QxlDod.h
@@ -553,6 +553,7 @@ private:
     NTSTATUS SetCustomDisplay(QXLEscapeSetCustomDisplay* custom_display);
     void SetMonitorConfig(QXLHead* monitor_config);
     void SaveVDAgentState(QXLEscapeVDAgentRunning* vdagent_running);
+    LONG static GetMaxSourceMappingHeight(D3DKMT_MOVE_RECT* Moves, ULONG NumMoves, RECT* DirtyRects, ULONG NumDirtyRects);
 
 private:
     BOOLEAN m_VDAgentRunning;
-- 
1.8.3.1



More information about the Spice-devel mailing list