[c-host] improved intial connection sync

This commit is contained in:
Geoffrey McRae 2020-01-09 19:49:47 +11:00
parent 73e8bc41cd
commit b0fb7177bb
3 changed files with 72 additions and 29 deletions

2
LGMP

@ -1 +1 @@
Subproject commit f941a676c87de15e75f7d62c77ba0a7dca314158 Subproject commit 32d872398d0d5ef1bec58f8fe722b9025fc9a7bd

View File

@ -710,9 +710,9 @@ static CaptureResult dxgi_capture()
frameInfo.PointerPosition.Visible != this->lastPointerVisible frameInfo.PointerPosition.Visible != this->lastPointerVisible
) )
{ {
pointer.x = frameInfo.PointerPosition.Position.x; this->lastPointerX = pointer.x = frameInfo.PointerPosition.Position.x;
pointer.y = frameInfo.PointerPosition.Position.y; this->lastPointerY = pointer.y = frameInfo.PointerPosition.Position.y;
pointer.visible = frameInfo.PointerPosition.Visible; this->lastPointerVisible = pointer.visible = frameInfo.PointerPosition.Visible;
postPointer = true; postPointer = true;
} }
} }
@ -744,6 +744,7 @@ static CaptureResult dxgi_capture()
return CAPTURE_RESULT_ERROR; return CAPTURE_RESULT_ERROR;
} }
pointer.shapeUpdate = true;
pointer.width = shapeInfo.Width; pointer.width = shapeInfo.Width;
pointer.height = shapeInfo.Height; pointer.height = shapeInfo.Height;
pointer.pitch = shapeInfo.Pitch; pointer.pitch = shapeInfo.Pitch;

View File

@ -50,6 +50,8 @@ struct app
PLGMPHQueue pointerQueue; PLGMPHQueue pointerQueue;
PLGMPMemory pointerMemory[LGMP_Q_POINTER_LEN]; PLGMPMemory pointerMemory[LGMP_Q_POINTER_LEN];
PLGMPMemory pointerShape;
bool pointerShapeValid;
unsigned int pointerIndex; unsigned int pointerIndex;
size_t maxFrameSize; size_t maxFrameSize;
@ -98,13 +100,6 @@ static int frameThread(void * opaque)
while(app.running) while(app.running)
{ {
//wait until there is room in the queue
if (lgmpHostQueuePending(app.frameQueue) == LGMP_Q_FRAME_LEN)
{
usleep(1);
continue;
}
switch(app.iface->waitFrame(&frame)) switch(app.iface->waitFrame(&frame))
{ {
case CAPTURE_RESULT_OK: case CAPTURE_RESULT_OK:
@ -137,6 +132,14 @@ static int frameThread(void * opaque)
} }
} }
//wait until there is room in the queue
if (lgmpHostQueuePending(app.frameQueue) == LGMP_Q_FRAME_LEN)
{
if (!app.running)
break;
}
// if we are repeating a frame just send the last frame again
if (repeatFrame) if (repeatFrame)
{ {
lgmpHostPost(app.frameQueue, 0, app.frameMemory[app.frameIndex]); lgmpHostPost(app.frameQueue, 0, app.frameMemory[app.frameIndex]);
@ -168,9 +171,10 @@ static int frameThread(void * opaque)
FrameBuffer fb = (FrameBuffer)(fi + 1); FrameBuffer fb = (FrameBuffer)(fi + 1);
framebuffer_prepare(fb); framebuffer_prepare(fb);
app.iface->getFrame(fb);
/* we post and then get the frame, this is intentional! */
lgmpHostPost(app.frameQueue, 0, app.frameMemory[app.frameIndex]); lgmpHostPost(app.frameQueue, 0, app.frameMemory[app.frameIndex]);
app.iface->getFrame(fb);
} }
DEBUG_INFO("Frame thread stopped"); DEBUG_INFO("Frame thread stopped");
return 0; return 0;
@ -254,8 +258,12 @@ static bool captureRestart()
bool captureGetPointerBuffer(void ** data, uint32_t * size) bool captureGetPointerBuffer(void ** data, uint32_t * size)
{ {
if (lgmpHostQueuePending(app.pointerQueue) == LGMP_Q_POINTER_LEN) // spin until there is room
while(lgmpHostQueuePending(app.pointerQueue) == LGMP_Q_POINTER_LEN)
{
if (!app.running)
return false; return false;
}
PLGMPMemory mem = app.pointerMemory[app.pointerIndex]; PLGMPMemory mem = app.pointerMemory[app.pointerIndex];
*data = ((uint8_t*)lgmpHostMemPtr(mem)) + sizeof(KVMFRCursor); *data = ((uint8_t*)lgmpHostMemPtr(mem)) + sizeof(KVMFRCursor);
@ -265,18 +273,40 @@ bool captureGetPointerBuffer(void ** data, uint32_t * size)
void capturePostPointerBuffer(CapturePointer pointer) void capturePostPointerBuffer(CapturePointer pointer)
{ {
if (lgmpHostQueuePending(app.pointerQueue) == LGMP_Q_POINTER_LEN) // spin until there is room
while(lgmpHostQueuePending(app.pointerQueue) == LGMP_Q_POINTER_LEN)
{
if (!app.running)
return; return;
}
PLGMPMemory mem;
const bool newClient = lgmpHostNewSubCount(app.pointerQueue) > 0;
if (pointer.shapeUpdate || newClient)
{
if (!newClient)
{
// swap the latest shape buffer out of rotation
PLGMPMemory tmp = app.pointerShape;
app.pointerShape = app.pointerMemory[app.pointerIndex];
app.pointerMemory[app.pointerIndex] = tmp;
}
// use the last known shape buffer
mem = app.pointerShape;
}
else
mem = app.pointerMemory[app.pointerIndex];
PLGMPMemory mem = app.pointerMemory[app.pointerIndex];
KVMFRCursor *cursor = lgmpHostMemPtr(mem); KVMFRCursor *cursor = lgmpHostMemPtr(mem);
cursor->x = pointer.x; cursor->x = pointer.x;
cursor->y = pointer.y; cursor->y = pointer.y;
cursor->visible = pointer.visible; cursor->visible = pointer.visible;
if (pointer.shapeUpdate) if (pointer.shapeUpdate)
{ {
// remember which slot has the latest shape
cursor->width = pointer.width; cursor->width = pointer.width;
cursor->height = pointer.height; cursor->height = pointer.height;
cursor->pitch = pointer.pitch; cursor->pitch = pointer.pitch;
@ -290,10 +320,14 @@ void capturePostPointerBuffer(CapturePointer pointer)
DEBUG_ERROR("Invalid pointer type"); DEBUG_ERROR("Invalid pointer type");
return; return;
} }
app.pointerShapeValid = true;
} }
const bool sendShape = (pointer.shapeUpdate || newClient) && app.pointerShapeValid;
LGMP_STATUS status; LGMP_STATUS status;
if ((status = lgmpHostPost(app.pointerQueue, pointer.shapeUpdate ? 1 : 0, mem)) != LGMP_OK) if ((status = lgmpHostPost(app.pointerQueue, sendShape ? 1 : 0, mem)) != LGMP_OK)
{ {
DEBUG_ERROR("lgmpHostPost Failed (Pointer): %s", lgmpStatusString(status)); DEBUG_ERROR("lgmpHostPost Failed (Pointer): %s", lgmpStatusString(status));
return; return;
@ -357,9 +391,15 @@ int app_main(int argc, char * argv[])
goto fail; goto fail;
} }
if ((status = lgmpHostAddQueue(app.lgmp, LGMP_Q_FRAME, LGMP_Q_FRAME_LEN, &app.frameQueue)) != LGMP_OK)
{
DEBUG_ERROR("lgmpHostQueueCreate Failed (Frame): %s", lgmpStatusString(status));
goto fail;
}
if ((status = lgmpHostAddQueue(app.lgmp, LGMP_Q_POINTER, LGMP_Q_POINTER_LEN, &app.pointerQueue)) != LGMP_OK) if ((status = lgmpHostAddQueue(app.lgmp, LGMP_Q_POINTER, LGMP_Q_POINTER_LEN, &app.pointerQueue)) != LGMP_OK)
{ {
DEBUG_ERROR("lgmpHostQueueCreate Failed (Pointer): %s", lgmpStatusString(status)); DEBUG_ERROR("lgmpHostAddQueue Failed (Pointer): %s", lgmpStatusString(status));
goto fail; goto fail;
} }
@ -372,9 +412,10 @@ int app_main(int argc, char * argv[])
} }
} }
if ((status = lgmpHostAddQueue(app.lgmp, LGMP_Q_FRAME, LGMP_Q_FRAME_LEN, &app.frameQueue)) != LGMP_OK) app.pointerShapeValid = false;
if ((status = lgmpHostMemAlloc(app.lgmp, MAX_POINTER_SIZE, &app.pointerShape)) != LGMP_OK)
{ {
DEBUG_ERROR("lgmpHostQueueCreate Failed (Frame): %s", lgmpStatusString(status)); DEBUG_ERROR("lgmpHostMemAlloc Failed (Pointer Shape): %s", lgmpStatusString(status));
goto fail; goto fail;
} }
@ -466,10 +507,11 @@ exit:
iface->free(); iface->free();
fail: fail:
for(int i = 0; i < LGMP_Q_POINTER_LEN; ++i)
lgmpHostMemFree(&app.pointerMemory[i]);
for(int i = 0; i < LGMP_Q_FRAME_LEN; ++i) for(int i = 0; i < LGMP_Q_FRAME_LEN; ++i)
lgmpHostMemFree(&app.frameMemory[i]); lgmpHostMemFree(&app.frameMemory[i]);
for(int i = 0; i < LGMP_Q_POINTER_LEN; ++i)
lgmpHostMemFree(&app.pointerMemory[i]);
lgmpHostMemFree(&app.pointerShape);
lgmpHostFree(&app.lgmp); lgmpHostFree(&app.lgmp);
ivshmemClose(&shmDev); ivshmemClose(&shmDev);