[client/host] added new asyncronous memory copy

This changes the method of the memory copy from the host application to
the guest. Instead of performing a full copy from the capture device
into shared memory, and then flagging the new frame, we instead set a
write pointer, flag the client that there is a new frame and then copy
in chunks of 1024 bytes until the entire frame is copied. The client
upon seeing the new frame flag begins to poll at high frequency the
write pointer and upon each update copies as much as it can into the
texture.

This should improve latency but also slightly increase CPU usage on the
client due to the high frequency polling.
This commit is contained in:
Geoffrey McRae 2019-10-01 23:17:20 +10:00
parent 6d2c464436
commit bca54ab1f6
17 changed files with 358 additions and 277 deletions

View file

@ -766,7 +766,7 @@ static CaptureResult dxgi_capture()
return CAPTURE_RESULT_OK;
}
static CaptureResult dxgi_getFrame(CaptureFrame * frame)
static CaptureResult dxgi_waitFrame(CaptureFrame * frame)
{
assert(this);
assert(this->initialized);
@ -778,7 +778,6 @@ static CaptureResult dxgi_getFrame(CaptureFrame * frame)
if (this->stop)
return CAPTURE_RESULT_REINIT;
// only reset the event if we used the texture
os_resetEvent(tex->mapped);
frame->width = this->width;
@ -787,7 +786,16 @@ static CaptureResult dxgi_getFrame(CaptureFrame * frame)
frame->stride = this->stride;
frame->format = this->format;
memcpy(frame->data, tex->map.pData, this->pitch * this->height);
return CAPTURE_RESULT_OK;
}
static CaptureResult dxgi_getFrame(FrameBuffer frame)
{
assert(this);
assert(this->initialized);
Texture * tex = &this->texture[this->texRIndex];
framebuffer_write(frame, tex->map.pData, this->pitch * this->height);
os_signalEvent(tex->free);
if (++this->texRIndex == this->maxTextures)
@ -867,6 +875,7 @@ struct CaptureInterface Capture_DXGI =
.free = dxgi_free,
.getMaxFrameSize = dxgi_getMaxFrameSize,
.capture = dxgi_capture,
.waitFrame = dxgi_waitFrame,
.getFrame = dxgi_getFrame,
.getPointer = dxgi_getPointer
};