[Spice-devel,RFC,qxl-wddm-dod,3/3] Synchronize display mode change and pushing drawables

Submitted by Yuri Benditovich on April 16, 2017, 7:43 p.m.

Details

Message ID 1492371783-19724-4-git-send-email-yuri.benditovich@daynix.com
State New
Headers show
Series "Synchronization of display mode change and pushing drawables" ( rev: 1 ) in Spice

Not browsing as part of any series.

Commit Message

Yuri Benditovich April 16, 2017, 7:43 p.m.
Upon change of display mode the driver waits until all the
queued drawables pushed to the host. This eliminates server
warnings "rendering incorrect" in "get_drawable" when the
drawable command was created by guest driver just before change
of display mode and posted to the server during or after the change.

Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
---
 qxldod/QxlDod.cpp | 15 +++++++++++++++
 qxldod/QxlDod.h   |  1 +
 2 files changed, 16 insertions(+)

Patch hide | download patch | download mbox

diff --git a/qxldod/QxlDod.cpp b/qxldod/QxlDod.cpp
index c60cf31..277630a 100755
--- a/qxldod/QxlDod.cpp
+++ b/qxldod/QxlDod.cpp
@@ -3258,8 +3258,10 @@  NTSTATUS QxlDevice::SetCurrentMode(ULONG Mode)
     {
         if (Mode == m_ModeNumbers[idx])
         {
+            m_RenderingSM.Stop();
             DestroyPrimarySurface();
             CreatePrimarySurface(&m_ModeInfo[idx]);
+            m_RenderingSM.Start();
             DbgPrint(TRACE_LEVEL_INFORMATION, ("%s device %d: setting current mode %d (%d x %d)\n",
                 __FUNCTION__, m_Id, Mode, m_ModeInfo[idx].VisScreenWidth,
                 m_ModeInfo[idx].VisScreenHeight));
@@ -5278,6 +5280,9 @@  void QxlDevice::PresentThreadRoutine()
                 }
             }
             delete[] drawables;
+
+            m_RenderingSM.UnregisterOutstandingItem(__FUNCTION__);
+
         } else {
             DbgPrint(TRACE_LEVEL_WARNING, ("%s is being terminated\n", __FUNCTION__));
             break;
@@ -5294,6 +5299,16 @@  void QxlDevice::PostToWorkerThread(QXLDrawable** drawables)
     PAGED_CODE();
     // Push drawables into PresentRing and notify worker thread
     int notify, wait;
+
+    if (drawables && !m_RenderingSM.RegisterOutstandingItem()) {
+        // for completeness only, the OS does not render in the middle of change
+        for (UINT i = 0; drawables[i]; ++i)
+        {
+            DiscardDrawable(drawables[i]);
+        }
+        return;
+    }
+
     SPICE_RING_PROD_WAIT(m_PresentRing, wait);
     while (wait) {
         WaitForObject(&m_PresentThreadReadyEvent, NULL);
diff --git a/qxldod/QxlDod.h b/qxldod/QxlDod.h
index 63cb3d7..c8d06bd 100755
--- a/qxldod/QxlDod.h
+++ b/qxldod/QxlDod.h
@@ -776,6 +776,7 @@  private:
 
     QXLPresentOnlyRing m_PresentRing[1];
     HANDLE m_PresentThread;
+    RenderingStateMachine m_RenderingSM;
     BOOLEAN m_bActive;
 };