From 5899508a5bf2ddf248f2564e0ec9d3aaac2b2a1a Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Wed, 15 Nov 2017 17:28:17 +1100 Subject: [PATCH] [host] add initial buffering support --- common/KVMGFXHeader.h | 1 + host/Service.cpp | 85 ++++++++++++++++++++++++------------------- host/Service.h | 3 +- 3 files changed, 50 insertions(+), 39 deletions(-) diff --git a/common/KVMGFXHeader.h b/common/KVMGFXHeader.h index 2da250c4..8c92c7b7 100644 --- a/common/KVMGFXHeader.h +++ b/common/KVMGFXHeader.h @@ -54,6 +54,7 @@ struct KVMGFXHeader int32_t mouseX; // the initial mouse X position int32_t mouseY; // the initial mouse Y position uint64_t dataLen; // total lengh of the data after this header + uint64_t dataPos; // offset to the frame }; #pragma pack(push,1) diff --git a/host/Service.cpp b/host/Service.cpp index 48de78ff..fddfd774 100644 --- a/host/Service.cpp +++ b/host/Service.cpp @@ -30,7 +30,8 @@ Service::Service() : m_initialized(false), m_readyEvent(INVALID_HANDLE_VALUE), m_capture(NULL), - m_memory(NULL) + m_memory(NULL), + m_frameIndex(0) { m_ivshmem = IVSHMEM::Get(); } @@ -66,7 +67,7 @@ bool Service::Initialize() return false; } - m_memory = m_ivshmem->GetMemory(); + m_memory = static_cast(m_ivshmem->GetMemory()); if (!m_memory) { DEBUG_ERROR("Failed to get IVSHMEM memory"); @@ -82,7 +83,7 @@ bool Service::Initialize() return false; } - KVMGFXHeader * header = static_cast(m_memory); + KVMGFXHeader * header = reinterpret_cast(m_memory); // we save this as it might actually be valid UINT16 hostID = header->hostID; @@ -120,12 +121,14 @@ bool Service::Process() if (!m_initialized) return false; - KVMGFXHeader * header = static_cast(m_memory ); - void * data = static_cast(header + 1); - const size_t available = m_ivshmem->GetSize() - sizeof(KVMGFXHeader); - if (m_capture->GetMaxFrameSize() > available) + KVMGFXHeader * header = reinterpret_cast(m_memory); + const uint64_t dataOffset = sizeof(KVMGFXHeader) + m_frameIndex * m_capture->GetMaxFrameSize(); + uint8_t * data = m_memory + dataOffset; + const size_t available = m_ivshmem->GetSize() - sizeof(KVMGFXHeader); + + if (dataOffset + m_capture->GetMaxFrameSize() > available) { - DEBUG_ERROR("Frame could exceed buffer size!"); + DEBUG_ERROR("Frame can exceed buffer size!"); return false; } @@ -146,10 +149,40 @@ bool Service::Process() return false; } + // wait for the host to notify that is it is ready to proceed + ResetEvent(m_readyEvent); + bool eventDone = false; + while (!eventDone) + { + switch (WaitForSingleObject(m_readyEvent, 1000)) + { + case WAIT_ABANDONED: + DEBUG_ERROR("Wait abandoned"); + return false; + + case WAIT_OBJECT_0: + eventDone = true; + break; + + // if we timed out we just continue to ring until we get an answer or we are stopped + case WAIT_TIMEOUT: + continue; + + case WAIT_FAILED: + DEBUG_ERROR("Wait failed"); + return false; + + default: + DEBUG_ERROR("Unknown error"); + return false; + } + } + // copy the frame details into the header header->width = frame.width; header->height = frame.height; header->stride = frame.stride; + header->dataPos = dataOffset; header->dataLen = frame.outSize; // tell the host where the cursor is @@ -158,38 +191,14 @@ bool Service::Process() header->mouseX = cursorPos.x; header->mouseY = cursorPos.y; - // wait for the host to notify that is it is ready to proceed - ResetEvent(m_readyEvent); - while(true) + if (!m_ivshmem->RingDoorbell(header->hostID, 0)) { - if (!m_ivshmem->RingDoorbell(header->hostID, 0)) - { - DEBUG_ERROR("Failed to ring doorbell"); - return false; - } - - switch (WaitForSingleObject(m_readyEvent, 1000)) - { - case WAIT_ABANDONED: - DEBUG_ERROR("Wait abandoned"); - return false; - - case WAIT_OBJECT_0: - return true; - - // if we timed out we just continue to ring until we get an answer or we are stopped - case WAIT_TIMEOUT: - break; - - case WAIT_FAILED: - DEBUG_ERROR("Wait failed"); - return false; - - default: - DEBUG_ERROR("Unknown error"); - return false; - } + DEBUG_ERROR("Failed to ring doorbell"); + return false; } + if (++m_frameIndex == 2) + m_frameIndex = 0; + return true; } \ No newline at end of file diff --git a/host/Service.h b/host/Service.h index 08cf2a8f..8f7644e9 100644 --- a/host/Service.h +++ b/host/Service.h @@ -49,5 +49,6 @@ private: IVSHMEM * m_ivshmem; HANDLE m_readyEvent; ICapture * m_capture; - void * m_memory; + uint8_t * m_memory; + int m_frameIndex; }; \ No newline at end of file