mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-02-04 11:53:31 +00:00
[c-host] rework events
This commit is contained in:
parent
a8b018d5da
commit
6f545483c9
2 changed files with 84 additions and 101 deletions
87
c-host/app.c
87
c-host/app.c
|
@ -49,31 +49,31 @@ struct app
|
||||||
|
|
||||||
bool running;
|
bool running;
|
||||||
bool reinit;
|
bool reinit;
|
||||||
osEventHandle * updateEvent;
|
|
||||||
osThreadHandle * pointerThread;
|
osThreadHandle * pointerThread;
|
||||||
osEventHandle * pointerEvent;
|
|
||||||
osThreadHandle * frameThread;
|
osThreadHandle * frameThread;
|
||||||
osEventHandle * frameEvent;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct app app;
|
static struct app app;
|
||||||
|
|
||||||
static int pointerThread(void * opaque)
|
static int pointerThread(void * opaque)
|
||||||
{
|
{
|
||||||
DEBUG_INFO("Cursor thread started");
|
DEBUG_INFO("Pointer thread started");
|
||||||
|
|
||||||
while(os_waitEvent(app.pointerEvent) && app.running)
|
|
||||||
{
|
|
||||||
#if 0
|
#if 0
|
||||||
|
while(app.running)
|
||||||
|
{
|
||||||
CapturePointer pointer;
|
CapturePointer pointer;
|
||||||
pointer->data = app.pointerData;
|
pointer->data = app.pointerData;
|
||||||
if (!app.iface->getPointer(&pointer))
|
if (!app.iface->getPointer(&pointer))
|
||||||
|
{
|
||||||
DEBUG_ERROR("Failed to get the pointer");
|
DEBUG_ERROR("Failed to get the pointer");
|
||||||
#endif
|
app.reinit = true;
|
||||||
os_signalEvent(app.updateEvent);
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
DEBUG_INFO("Cursor thread stopped");
|
DEBUG_INFO("Pointer thread stopped");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ static int frameThread(void * opaque)
|
||||||
int frameIndex = 0;
|
int frameIndex = 0;
|
||||||
volatile KVMFRFrame * fi = &(app.shmHeader->frame);
|
volatile KVMFRFrame * fi = &(app.shmHeader->frame);
|
||||||
|
|
||||||
while(os_waitEvent(app.frameEvent) && app.running)
|
while(app.running)
|
||||||
{
|
{
|
||||||
CaptureFrame frame;
|
CaptureFrame frame;
|
||||||
frame.data = app.frame[frameIndex];
|
frame.data = app.frame[frameIndex];
|
||||||
|
@ -92,12 +92,9 @@ static int frameThread(void * opaque)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to get the frame");
|
DEBUG_ERROR("Failed to get the frame");
|
||||||
app.reinit = true;
|
app.reinit = true;
|
||||||
os_signalEvent(app.updateEvent);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
os_signalEvent(app.updateEvent);
|
|
||||||
|
|
||||||
// wait for the client to finish with the previous frame
|
// wait for the client to finish with the previous frame
|
||||||
while(fi->flags & KVMFR_FRAME_FLAG_UPDATE && app.running)
|
while(fi->flags & KVMFR_FRAME_FLAG_UPDATE && app.running)
|
||||||
{
|
{
|
||||||
|
@ -155,8 +152,6 @@ bool stopThreads()
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
app.running = false;
|
app.running = false;
|
||||||
os_signalEvent(app.frameEvent );
|
|
||||||
os_signalEvent(app.pointerEvent);
|
|
||||||
|
|
||||||
if (app.frameThread && !os_joinThread(app.frameThread, NULL))
|
if (app.frameThread && !os_joinThread(app.frameThread, NULL))
|
||||||
{
|
{
|
||||||
|
@ -187,9 +182,6 @@ static bool captureStart()
|
||||||
}
|
}
|
||||||
DEBUG_INFO("Capture Size : %u MiB (%u)", maxFrameSize / 1048576, maxFrameSize);
|
DEBUG_INFO("Capture Size : %u MiB (%u)", maxFrameSize / 1048576, maxFrameSize);
|
||||||
|
|
||||||
// start signalled
|
|
||||||
os_signalEvent(app.updateEvent);
|
|
||||||
|
|
||||||
DEBUG_INFO("==== [ Capture Start ] ====");
|
DEBUG_INFO("==== [ Capture Start ] ====");
|
||||||
return startThreads();
|
return startThreads();
|
||||||
}
|
}
|
||||||
|
@ -271,29 +263,6 @@ int app_main()
|
||||||
}
|
}
|
||||||
|
|
||||||
app.iface = iface;
|
app.iface = iface;
|
||||||
app.frameEvent = os_createEvent(true);
|
|
||||||
if (!app.frameEvent)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to create the frame event");
|
|
||||||
exitcode = -1;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
app.updateEvent = os_createEvent(false);
|
|
||||||
if (!app.updateEvent)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to create the update event");
|
|
||||||
exitcode = -1;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
app.pointerEvent = os_createEvent(true);
|
|
||||||
if (!app.pointerEvent)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to create the pointer event");
|
|
||||||
exitcode = -1;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize the shared memory headers
|
// initialize the shared memory headers
|
||||||
memcpy(app.shmHeader->magic, KVMFR_HEADER_MAGIC, sizeof(KVMFR_HEADER_MAGIC));
|
memcpy(app.shmHeader->magic, KVMFR_HEADER_MAGIC, sizeof(KVMFR_HEADER_MAGIC));
|
||||||
|
@ -310,19 +279,12 @@ int app_main()
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start signalled
|
|
||||||
os_signalEvent(app.updateEvent);
|
|
||||||
|
|
||||||
volatile char * flags = (volatile char *)&(app.shmHeader->flags);
|
volatile char * flags = (volatile char *)&(app.shmHeader->flags);
|
||||||
|
|
||||||
while(app.running)
|
while(app.running)
|
||||||
{
|
{
|
||||||
INTERLOCKED_AND8(flags, ~(KVMFR_HEADER_FLAG_RESTART));
|
INTERLOCKED_AND8(flags, ~(KVMFR_HEADER_FLAG_RESTART));
|
||||||
|
|
||||||
// wait for one of the threads to flag an update
|
|
||||||
if (!os_waitEvent(app.updateEvent) || !app.running)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (app.reinit && !captureRestart())
|
if (app.reinit && !captureRestart())
|
||||||
{
|
{
|
||||||
exitcode = -1;
|
exitcode = -1;
|
||||||
|
@ -333,7 +295,6 @@ int app_main()
|
||||||
bool frameUpdate = false;
|
bool frameUpdate = false;
|
||||||
bool pointerUpdate = false;
|
bool pointerUpdate = false;
|
||||||
|
|
||||||
retry_capture:
|
|
||||||
switch(iface->capture(&frameUpdate, &pointerUpdate))
|
switch(iface->capture(&frameUpdate, &pointerUpdate))
|
||||||
{
|
{
|
||||||
case CAPTURE_RESULT_OK:
|
case CAPTURE_RESULT_OK:
|
||||||
|
@ -355,39 +316,12 @@ retry_capture:
|
||||||
exitcode = -1;
|
exitcode = -1;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!frameUpdate && !pointerUpdate)
|
|
||||||
goto retry_capture;
|
|
||||||
|
|
||||||
os_resetEvent(app.updateEvent);
|
|
||||||
if (frameUpdate && !os_signalEvent(app.frameEvent))
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to signal the frame thread");
|
|
||||||
exitcode = -1;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pointerUpdate && !os_signalEvent(app.pointerEvent))
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to signal the pointer thread");
|
|
||||||
exitcode = -1;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
stopThreads();
|
stopThreads();
|
||||||
exit:
|
exit:
|
||||||
|
|
||||||
if (app.pointerEvent)
|
|
||||||
os_freeEvent(app.pointerEvent);
|
|
||||||
|
|
||||||
if (app.frameEvent)
|
|
||||||
os_freeEvent(app.frameEvent);
|
|
||||||
|
|
||||||
if (app.updateEvent)
|
|
||||||
os_freeEvent(app.updateEvent);
|
|
||||||
|
|
||||||
iface->deinit();
|
iface->deinit();
|
||||||
iface->free();
|
iface->free();
|
||||||
fail:
|
fail:
|
||||||
|
@ -398,5 +332,4 @@ fail:
|
||||||
void app_quit()
|
void app_quit()
|
||||||
{
|
{
|
||||||
app.running = false;
|
app.running = false;
|
||||||
os_signalEvent(app.updateEvent);
|
|
||||||
}
|
}
|
|
@ -41,8 +41,12 @@ struct iface
|
||||||
D3D_FEATURE_LEVEL featureLevel;
|
D3D_FEATURE_LEVEL featureLevel;
|
||||||
IDXGIOutputDuplication * dup;
|
IDXGIOutputDuplication * dup;
|
||||||
ID3D11Texture2D * texture;
|
ID3D11Texture2D * texture;
|
||||||
|
D3D11_MAPPED_SUBRESOURCE mapping;
|
||||||
bool needsRelease;
|
bool needsRelease;
|
||||||
|
bool needsUnmap;
|
||||||
osEventHandle * copyEvent;
|
osEventHandle * copyEvent;
|
||||||
|
osEventHandle * frameEvent;
|
||||||
|
osEventHandle * pointerEvent;
|
||||||
|
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
|
@ -84,6 +88,25 @@ static bool dxgi_create()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->frameEvent = os_createEvent(true);
|
||||||
|
if (!this->frameEvent)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("failed to create the frame event");
|
||||||
|
os_freeEvent(this->copyEvent);
|
||||||
|
free(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->pointerEvent = os_createEvent(true);
|
||||||
|
if (!this->pointerEvent)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("failed to create the pointer event");
|
||||||
|
os_freeEvent(this->copyEvent );
|
||||||
|
os_freeEvent(this->frameEvent);
|
||||||
|
free(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,6 +387,12 @@ static bool dxgi_deinit()
|
||||||
{
|
{
|
||||||
assert(this);
|
assert(this);
|
||||||
|
|
||||||
|
if (this->needsUnmap)
|
||||||
|
{
|
||||||
|
ID3D11DeviceContext_Unmap(this->deviceContext, (ID3D11Resource*)this->texture, 0);
|
||||||
|
this->needsUnmap = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->texture)
|
if (this->texture)
|
||||||
{
|
{
|
||||||
ID3D11Texture2D_Release(this->texture);
|
ID3D11Texture2D_Release(this->texture);
|
||||||
|
@ -424,7 +453,9 @@ static void dxgi_free()
|
||||||
if (this->initialized)
|
if (this->initialized)
|
||||||
dxgi_deinit();
|
dxgi_deinit();
|
||||||
|
|
||||||
os_freeEvent(this->copyEvent);
|
os_freeEvent(this->copyEvent );
|
||||||
|
os_freeEvent(this->frameEvent );
|
||||||
|
os_freeEvent(this->pointerEvent);
|
||||||
|
|
||||||
free(this);
|
free(this);
|
||||||
this = NULL;
|
this = NULL;
|
||||||
|
@ -482,18 +513,40 @@ static CaptureResult dxgi_capture(bool * hasFrameUpdate, bool * hasPointerUpdate
|
||||||
return CAPTURE_RESULT_ERROR;
|
return CAPTURE_RESULT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for the prior copy to finish in getFrame
|
// wait for the prior copy to finish in getFrame and unmap
|
||||||
os_waitEvent(this->copyEvent);
|
os_waitEvent(this->copyEvent);
|
||||||
|
if (this->needsUnmap)
|
||||||
|
{
|
||||||
|
ID3D11DeviceContext_Unmap(this->deviceContext, (ID3D11Resource*)this->texture, 0);
|
||||||
|
this->needsUnmap = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// issue the copy from GPU to CPU RAM
|
||||||
ID3D11DeviceContext_CopyResource(this->deviceContext,
|
ID3D11DeviceContext_CopyResource(this->deviceContext,
|
||||||
(ID3D11Resource *)this->texture, (ID3D11Resource *)src);
|
(ID3D11Resource *)this->texture, (ID3D11Resource *)src);
|
||||||
|
|
||||||
|
// map the resource (this must be done here as ID3D11DeviceContext is not thread safe)
|
||||||
|
status = ID3D11DeviceContext_Map(this->deviceContext, (ID3D11Resource*)this->texture, 0, D3D11_MAP_READ, 0, &this->mapping);
|
||||||
|
if (FAILED(status))
|
||||||
|
{
|
||||||
|
DEBUG_WINERROR("Failed to map the texture", status);
|
||||||
|
IDXGIResource_Release(res);
|
||||||
|
return CAPTURE_RESULT_ERROR;
|
||||||
|
}
|
||||||
|
this->needsUnmap = true;
|
||||||
|
|
||||||
|
// signal that a frame is available
|
||||||
|
os_signalEvent(this->frameEvent);
|
||||||
|
|
||||||
ID3D11Texture2D_Release(src);
|
ID3D11Texture2D_Release(src);
|
||||||
*hasFrameUpdate = true;
|
*hasFrameUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frameInfo.PointerShapeBufferSize > 0)
|
if (frameInfo.PointerShapeBufferSize > 0)
|
||||||
|
{
|
||||||
|
os_signalEvent(this->pointerEvent);
|
||||||
*hasPointerUpdate = true;
|
*hasPointerUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
IDXGIResource_Release(res);
|
IDXGIResource_Release(res);
|
||||||
return CAPTURE_RESULT_OK;
|
return CAPTURE_RESULT_OK;
|
||||||
|
@ -504,24 +557,21 @@ static bool dxgi_getFrame(CaptureFrame * frame)
|
||||||
assert(this);
|
assert(this);
|
||||||
assert(this->initialized);
|
assert(this->initialized);
|
||||||
|
|
||||||
|
if (!os_waitEvent(this->frameEvent))
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to wait on the frame event");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
frame->width = this->width;
|
frame->width = this->width;
|
||||||
frame->height = this->height;
|
frame->height = this->height;
|
||||||
frame->pitch = this->pitch;
|
frame->pitch = this->pitch;
|
||||||
frame->stride = this->stride;
|
frame->stride = this->stride;
|
||||||
frame->format = this->format;
|
frame->format = this->format;
|
||||||
|
|
||||||
HRESULT status;
|
|
||||||
D3D11_MAPPED_SUBRESOURCE mapping;
|
|
||||||
status = ID3D11DeviceContext_Map(this->deviceContext, (ID3D11Resource*)this->texture, 0, D3D11_MAP_READ, 0, &mapping);
|
|
||||||
if (FAILED(status))
|
|
||||||
{
|
|
||||||
DEBUG_WINERROR("Failed to map the texture", status);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(frame->data, mapping.pData, this->pitch * this->height);
|
memcpy(frame->data, this->mapping.pData, this->pitch * this->height);
|
||||||
|
|
||||||
ID3D11DeviceContext_Unmap(this->deviceContext, (ID3D11Resource*)this->texture, 0);
|
|
||||||
os_signalEvent(this->copyEvent);
|
os_signalEvent(this->copyEvent);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue