mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-26 07:17:23 +00:00
[host] use a local copy of the header and then update it all in one go
Writing to shared memory is much faster then reading as the shared memory is not cached, this change ensures we are using a local copy of the header performing the final update all in one go.
This commit is contained in:
parent
b89a8fee04
commit
758b7af754
@ -40,7 +40,7 @@ Service::Service() :
|
|||||||
m_memory(NULL),
|
m_memory(NULL),
|
||||||
m_timer(NULL),
|
m_timer(NULL),
|
||||||
m_capture(NULL),
|
m_capture(NULL),
|
||||||
m_header(NULL),
|
m_shmHeader(NULL),
|
||||||
m_frameIndex(0),
|
m_frameIndex(0),
|
||||||
m_cursorDataSize(0),
|
m_cursorDataSize(0),
|
||||||
m_cursorData(NULL),
|
m_cursorData(NULL),
|
||||||
@ -92,15 +92,15 @@ bool Service::Initialize(ICapture * captureDevice)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update everything except for the hostID
|
// update everything except for the hostID
|
||||||
memcpy(m_header->magic, KVMFR_HEADER_MAGIC, sizeof(KVMFR_HEADER_MAGIC));
|
memcpy(m_shmHeader->magic, KVMFR_HEADER_MAGIC, sizeof(KVMFR_HEADER_MAGIC));
|
||||||
m_header->version = KVMFR_HEADER_VERSION;
|
m_shmHeader->version = KVMFR_HEADER_VERSION;
|
||||||
m_header->guestID = m_ivshmem->GetPeerID();
|
m_shmHeader->guestID = m_ivshmem->GetPeerID();
|
||||||
m_header->updateCount = 0;
|
m_shmHeader->updateCount = 0;
|
||||||
|
|
||||||
// clear but retain the restart flag if it was set by the client
|
// clear but retain the restart flag if it was set by the client
|
||||||
INTERLOCKED_AND8((char *)&m_header->flags, KVMFR_HEADER_FLAG_RESTART);
|
INTERLOCKED_AND8((char *)&m_shmHeader->flags, KVMFR_HEADER_FLAG_RESTART);
|
||||||
ZeroMemory(&m_header->frame , sizeof(KVMFRFrame ));
|
ZeroMemory(&m_shmHeader->frame , sizeof(KVMFRFrame ));
|
||||||
ZeroMemory(&m_header->cursor, sizeof(KVMFRCursor));
|
ZeroMemory(&m_shmHeader->cursor, sizeof(KVMFRCursor));
|
||||||
|
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
return true;
|
return true;
|
||||||
@ -108,7 +108,7 @@ bool Service::Initialize(ICapture * captureDevice)
|
|||||||
|
|
||||||
bool Service::InitPointers()
|
bool Service::InitPointers()
|
||||||
{
|
{
|
||||||
m_header = reinterpret_cast<KVMFRHeader *>(m_memory);
|
m_shmHeader = reinterpret_cast<KVMFRHeader *>(m_memory);
|
||||||
m_frame[0] = (uint8_t *)(((uintptr_t)m_memory + sizeof(KVMFRHeader *) + 0x7F) & ~0x7F);
|
m_frame[0] = (uint8_t *)(((uintptr_t)m_memory + sizeof(KVMFRHeader *) + 0x7F) & ~0x7F);
|
||||||
m_frameSize = ((m_ivshmem->GetSize() - (m_frame[0] - m_memory)) & ~0x7F) >> 1;
|
m_frameSize = ((m_ivshmem->GetSize() - (m_frame[0] - m_memory)) & ~0x7F) >> 1;
|
||||||
m_frame[1] = m_frame[0] + m_frameSize;
|
m_frame[1] = m_frame[0] + m_frameSize;
|
||||||
@ -142,7 +142,7 @@ void Service::DeInitialize()
|
|||||||
m_cursorData = NULL;
|
m_cursorData = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_header = NULL;
|
m_shmHeader = NULL;
|
||||||
m_frame[0] = NULL;
|
m_frame[0] = NULL;
|
||||||
m_frame[1] = NULL;
|
m_frame[1] = NULL;
|
||||||
m_dataOffset[0] = 0;
|
m_dataOffset[0] = 0;
|
||||||
@ -171,7 +171,7 @@ bool Service::Process()
|
|||||||
frame.buffer = m_frame[m_frameIndex];
|
frame.buffer = m_frame[m_frameIndex];
|
||||||
frame.bufferSize = m_frameSize;
|
frame.bufferSize = m_frameSize;
|
||||||
|
|
||||||
volatile uint8_t *flags = &m_header->flags;
|
volatile uint8_t *flags = &m_shmHeader->flags;
|
||||||
|
|
||||||
// wait for the host to notify that is it is ready to proceed
|
// wait for the host to notify that is it is ready to proceed
|
||||||
while (true)
|
while (true)
|
||||||
@ -181,7 +181,7 @@ bool Service::Process()
|
|||||||
// check if the client has flagged a restart
|
// check if the client has flagged a restart
|
||||||
if (f & KVMFR_HEADER_FLAG_RESTART)
|
if (f & KVMFR_HEADER_FLAG_RESTART)
|
||||||
{
|
{
|
||||||
m_header->updateCount = 0;
|
m_shmHeader->updateCount = 0;
|
||||||
INTERLOCKED_AND8((volatile char *)flags, ~(KVMFR_HEADER_FLAG_RESTART));
|
INTERLOCKED_AND8((volatile char *)flags, ~(KVMFR_HEADER_FLAG_RESTART));
|
||||||
restart = true;
|
restart = true;
|
||||||
break;
|
break;
|
||||||
@ -252,17 +252,17 @@ bool Service::Process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t updateFlags = 0;
|
uint8_t updateFlags = 0;
|
||||||
m_header->cursor.flags = 0;
|
m_header.cursor.flags = 0;
|
||||||
|
|
||||||
if (!cursorOnly)
|
if (!cursorOnly)
|
||||||
{
|
{
|
||||||
// signal a frame update
|
// signal a frame update
|
||||||
updateFlags |= KVMFR_HEADER_FLAG_FRAME;
|
updateFlags |= KVMFR_HEADER_FLAG_FRAME;
|
||||||
m_header->frame.type = m_capture->GetFrameType();
|
m_header.frame.type = m_capture->GetFrameType();
|
||||||
m_header->frame.width = frame.width;
|
m_header.frame.width = frame.width;
|
||||||
m_header->frame.height = frame.height;
|
m_header.frame.height = frame.height;
|
||||||
m_header->frame.stride = frame.stride;
|
m_header.frame.stride = frame.stride;
|
||||||
m_header->frame.dataPos = m_dataOffset[m_frameIndex];
|
m_header.frame.dataPos = m_dataOffset[m_frameIndex];
|
||||||
if (++m_frameIndex == 2)
|
if (++m_frameIndex == 2)
|
||||||
m_frameIndex = 0;
|
m_frameIndex = 0;
|
||||||
}
|
}
|
||||||
@ -280,11 +280,11 @@ bool Service::Process()
|
|||||||
|
|
||||||
// tell the host where the cursor is
|
// tell the host where the cursor is
|
||||||
updateFlags |= KVMFR_HEADER_FLAG_CURSOR;
|
updateFlags |= KVMFR_HEADER_FLAG_CURSOR;
|
||||||
m_header->cursor.flags |= KVMFR_CURSOR_FLAG_POS;
|
m_header.cursor.flags |= KVMFR_CURSOR_FLAG_POS;
|
||||||
if (m_cursor.visible)
|
if (m_cursor.visible)
|
||||||
m_header->cursor.flags |= KVMFR_CURSOR_FLAG_VISIBLE;
|
m_header.cursor.flags |= KVMFR_CURSOR_FLAG_VISIBLE;
|
||||||
m_header->cursor.x = m_cursor.x;
|
m_header.cursor.x = m_cursor.x;
|
||||||
m_header->cursor.y = m_cursor.y;
|
m_header.cursor.y = m_cursor.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame.cursor.hasShape || m_shapePending || (m_cursor.hasShape && restart))
|
if (frame.cursor.hasShape || m_shapePending || (m_cursor.hasShape && restart))
|
||||||
@ -323,15 +323,15 @@ bool Service::Process()
|
|||||||
{
|
{
|
||||||
// give the host the new cursor shape
|
// give the host the new cursor shape
|
||||||
updateFlags |= KVMFR_HEADER_FLAG_CURSOR;
|
updateFlags |= KVMFR_HEADER_FLAG_CURSOR;
|
||||||
m_header->cursor.flags |= KVMFR_CURSOR_FLAG_SHAPE;
|
m_header.cursor.flags |= KVMFR_CURSOR_FLAG_SHAPE;
|
||||||
if (m_cursor.visible)
|
if (m_cursor.visible)
|
||||||
m_header->cursor.flags |= KVMFR_CURSOR_FLAG_VISIBLE;
|
m_header.cursor.flags |= KVMFR_CURSOR_FLAG_VISIBLE;
|
||||||
|
|
||||||
m_header->cursor.type = m_cursor.type;
|
m_header.cursor.type = m_cursor.type;
|
||||||
m_header->cursor.w = m_cursor.w;
|
m_header.cursor.w = m_cursor.w;
|
||||||
m_header->cursor.h = m_cursor.h;
|
m_header.cursor.h = m_cursor.h;
|
||||||
m_header->cursor.pitch = m_cursor.pitch;
|
m_header.cursor.pitch = m_cursor.pitch;
|
||||||
m_header->cursor.dataPos = m_dataOffset[m_frameIndex];
|
m_header.cursor.dataPos = m_dataOffset[m_frameIndex];
|
||||||
memcpy(m_frame[m_frameIndex], m_cursorData, m_cursor.dataSize);
|
memcpy(m_frame[m_frameIndex], m_cursorData, m_cursor.dataSize);
|
||||||
m_shapePending = false;
|
m_shapePending = false;
|
||||||
|
|
||||||
@ -344,8 +344,16 @@ bool Service::Process()
|
|||||||
INTERLOCKED_AND8((volatile char *)flags, KVMFR_HEADER_FLAG_RESTART);
|
INTERLOCKED_AND8((volatile char *)flags, KVMFR_HEADER_FLAG_RESTART);
|
||||||
INTERLOCKED_OR8 ((volatile char *)flags, updateFlags);
|
INTERLOCKED_OR8 ((volatile char *)flags, updateFlags);
|
||||||
|
|
||||||
// increment the update count to resume the host
|
// update the shared header but don't touch the setup fields
|
||||||
++m_header->updateCount;
|
const size_t offset = (uintptr_t)&m_header.frame - (uintptr_t)&m_header;
|
||||||
|
memcpy(
|
||||||
|
(uint8_t *)m_shmHeader + offset,
|
||||||
|
(uint8_t *)&m_header + offset,
|
||||||
|
sizeof(KVMFRHeader) - offset
|
||||||
|
);
|
||||||
|
|
||||||
|
// increment the update count so the guest stops waiting
|
||||||
|
++m_shmHeader->updateCount;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
@ -54,7 +54,8 @@ private:
|
|||||||
HANDLE m_timer;
|
HANDLE m_timer;
|
||||||
ICapture * m_capture;
|
ICapture * m_capture;
|
||||||
|
|
||||||
KVMFRHeader * m_header;
|
KVMFRHeader m_header;
|
||||||
|
KVMFRHeader * m_shmHeader;
|
||||||
uint8_t * m_frame[2];
|
uint8_t * m_frame[2];
|
||||||
size_t m_frameSize;
|
size_t m_frameSize;
|
||||||
uint64_t m_dataOffset[2];
|
uint64_t m_dataOffset[2];
|
||||||
|
Loading…
Reference in New Issue
Block a user