mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-22 05:27:20 +00:00
[c-host] rework events
This commit is contained in:
parent
a8b018d5da
commit
6f545483c9
89
c-host/app.c
89
c-host/app.c
@ -49,31 +49,31 @@ struct app
|
||||
|
||||
bool running;
|
||||
bool reinit;
|
||||
osEventHandle * updateEvent;
|
||||
osThreadHandle * pointerThread;
|
||||
osEventHandle * pointerEvent;
|
||||
osThreadHandle * frameThread;
|
||||
osEventHandle * frameEvent;
|
||||
};
|
||||
|
||||
static struct app app;
|
||||
|
||||
static int pointerThread(void * opaque)
|
||||
{
|
||||
DEBUG_INFO("Cursor thread started");
|
||||
DEBUG_INFO("Pointer thread started");
|
||||
|
||||
while(os_waitEvent(app.pointerEvent) && app.running)
|
||||
{
|
||||
#if 0
|
||||
while(app.running)
|
||||
{
|
||||
CapturePointer pointer;
|
||||
pointer->data = app.pointerData;
|
||||
if (!app.iface->getPointer(&pointer))
|
||||
{
|
||||
DEBUG_ERROR("Failed to get the pointer");
|
||||
#endif
|
||||
os_signalEvent(app.updateEvent);
|
||||
app.reinit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
DEBUG_INFO("Cursor thread stopped");
|
||||
DEBUG_INFO("Pointer thread stopped");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ static int frameThread(void * opaque)
|
||||
int frameIndex = 0;
|
||||
volatile KVMFRFrame * fi = &(app.shmHeader->frame);
|
||||
|
||||
while(os_waitEvent(app.frameEvent) && app.running)
|
||||
while(app.running)
|
||||
{
|
||||
CaptureFrame frame;
|
||||
frame.data = app.frame[frameIndex];
|
||||
@ -92,12 +92,9 @@ static int frameThread(void * opaque)
|
||||
{
|
||||
DEBUG_ERROR("Failed to get the frame");
|
||||
app.reinit = true;
|
||||
os_signalEvent(app.updateEvent);
|
||||
break;
|
||||
}
|
||||
|
||||
os_signalEvent(app.updateEvent);
|
||||
|
||||
// wait for the client to finish with the previous frame
|
||||
while(fi->flags & KVMFR_FRAME_FLAG_UPDATE && app.running)
|
||||
{
|
||||
@ -155,8 +152,6 @@ bool stopThreads()
|
||||
bool ok = true;
|
||||
|
||||
app.running = false;
|
||||
os_signalEvent(app.frameEvent );
|
||||
os_signalEvent(app.pointerEvent);
|
||||
|
||||
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);
|
||||
|
||||
// start signalled
|
||||
os_signalEvent(app.updateEvent);
|
||||
|
||||
DEBUG_INFO("==== [ Capture Start ] ====");
|
||||
return startThreads();
|
||||
}
|
||||
@ -270,30 +262,7 @@ int app_main()
|
||||
goto fail;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
app.iface = iface;
|
||||
|
||||
// initialize the shared memory headers
|
||||
memcpy(app.shmHeader->magic, KVMFR_HEADER_MAGIC, sizeof(KVMFR_HEADER_MAGIC));
|
||||
@ -310,19 +279,12 @@ int app_main()
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// start signalled
|
||||
os_signalEvent(app.updateEvent);
|
||||
|
||||
volatile char * flags = (volatile char *)&(app.shmHeader->flags);
|
||||
|
||||
while(app.running)
|
||||
{
|
||||
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())
|
||||
{
|
||||
exitcode = -1;
|
||||
@ -333,7 +295,6 @@ int app_main()
|
||||
bool frameUpdate = false;
|
||||
bool pointerUpdate = false;
|
||||
|
||||
retry_capture:
|
||||
switch(iface->capture(&frameUpdate, &pointerUpdate))
|
||||
{
|
||||
case CAPTURE_RESULT_OK:
|
||||
@ -355,39 +316,12 @@ retry_capture:
|
||||
exitcode = -1;
|
||||
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:
|
||||
stopThreads();
|
||||
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->free();
|
||||
fail:
|
||||
@ -398,5 +332,4 @@ fail:
|
||||
void app_quit()
|
||||
{
|
||||
app.running = false;
|
||||
os_signalEvent(app.updateEvent);
|
||||
}
|
@ -32,17 +32,21 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
// locals
|
||||
struct iface
|
||||
{
|
||||
bool initialized;
|
||||
IDXGIFactory1 * factory;
|
||||
IDXGIAdapter1 * adapter;
|
||||
IDXGIOutput * output;
|
||||
ID3D11Device * device;
|
||||
ID3D11DeviceContext * deviceContext;
|
||||
D3D_FEATURE_LEVEL featureLevel;
|
||||
IDXGIOutputDuplication * dup;
|
||||
ID3D11Texture2D * texture;
|
||||
bool needsRelease;
|
||||
osEventHandle * copyEvent;
|
||||
bool initialized;
|
||||
IDXGIFactory1 * factory;
|
||||
IDXGIAdapter1 * adapter;
|
||||
IDXGIOutput * output;
|
||||
ID3D11Device * device;
|
||||
ID3D11DeviceContext * deviceContext;
|
||||
D3D_FEATURE_LEVEL featureLevel;
|
||||
IDXGIOutputDuplication * dup;
|
||||
ID3D11Texture2D * texture;
|
||||
D3D11_MAPPED_SUBRESOURCE mapping;
|
||||
bool needsRelease;
|
||||
bool needsUnmap;
|
||||
osEventHandle * copyEvent;
|
||||
osEventHandle * frameEvent;
|
||||
osEventHandle * pointerEvent;
|
||||
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
@ -84,6 +88,25 @@ static bool dxgi_create()
|
||||
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;
|
||||
}
|
||||
|
||||
@ -364,6 +387,12 @@ static bool dxgi_deinit()
|
||||
{
|
||||
assert(this);
|
||||
|
||||
if (this->needsUnmap)
|
||||
{
|
||||
ID3D11DeviceContext_Unmap(this->deviceContext, (ID3D11Resource*)this->texture, 0);
|
||||
this->needsUnmap = false;
|
||||
}
|
||||
|
||||
if (this->texture)
|
||||
{
|
||||
ID3D11Texture2D_Release(this->texture);
|
||||
@ -424,7 +453,9 @@ static void dxgi_free()
|
||||
if (this->initialized)
|
||||
dxgi_deinit();
|
||||
|
||||
os_freeEvent(this->copyEvent);
|
||||
os_freeEvent(this->copyEvent );
|
||||
os_freeEvent(this->frameEvent );
|
||||
os_freeEvent(this->pointerEvent);
|
||||
|
||||
free(this);
|
||||
this = NULL;
|
||||
@ -482,18 +513,40 @@ static CaptureResult dxgi_capture(bool * hasFrameUpdate, bool * hasPointerUpdate
|
||||
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);
|
||||
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,
|
||||
(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);
|
||||
*hasFrameUpdate = true;
|
||||
}
|
||||
|
||||
if (frameInfo.PointerShapeBufferSize > 0)
|
||||
{
|
||||
os_signalEvent(this->pointerEvent);
|
||||
*hasPointerUpdate = true;
|
||||
}
|
||||
|
||||
IDXGIResource_Release(res);
|
||||
return CAPTURE_RESULT_OK;
|
||||
@ -504,24 +557,21 @@ static bool dxgi_getFrame(CaptureFrame * frame)
|
||||
assert(this);
|
||||
assert(this->initialized);
|
||||
|
||||
if (!os_waitEvent(this->frameEvent))
|
||||
{
|
||||
DEBUG_ERROR("Failed to wait on the frame event");
|
||||
return false;
|
||||
}
|
||||
|
||||
frame->width = this->width;
|
||||
frame->height = this->height;
|
||||
frame->pitch = this->pitch;
|
||||
frame->stride = this->stride;
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user