From 041b95507d1f75a798ebdb997b774a609c81e5b3 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Fri, 9 Jul 2021 10:19:55 +1000 Subject: [PATCH] [host] windows/nvfbc/common: strip out broken "enhanced" event logic This so called "enhanced" event logic is completely flawed and can never work correctly, better to strip it out and put our faith in windows to handle the events for us. And yes, I am fully aware I wrote the utter trash in the first place :) --- common/include/common/event.h | 1 - common/src/platform/windows/event.c | 164 ++---------------- .../Windows/capture/NVFBC/src/nvfbc.c | 77 ++++---- 3 files changed, 44 insertions(+), 198 deletions(-) diff --git a/common/include/common/event.h b/common/include/common/event.h index e403c32b..cc573d8e 100644 --- a/common/include/common/event.h +++ b/common/include/common/event.h @@ -31,7 +31,6 @@ typedef struct LGEvent LGEvent; LGEvent * lgCreateEvent(bool autoReset, unsigned int msSpinTime); void lgFreeEvent (LGEvent * handle); bool lgWaitEvent (LGEvent * handle, unsigned int timeout); -bool lgWaitEvents (LGEvent * handles[], int count, bool waitAll, unsigned int timeout); bool lgSignalEvent(LGEvent * handle); bool lgResetEvent (LGEvent * handle); diff --git a/common/src/platform/windows/event.c b/common/src/platform/windows/event.c index ef6b36cf..052266f2 100644 --- a/common/src/platform/windows/event.c +++ b/common/src/platform/windows/event.c @@ -25,132 +25,36 @@ #include #include -struct LGEvent -{ - volatile int lock; - bool reset; - HANDLE handle; - bool wrapped; - unsigned int msSpinTime; - _Atomic(bool) signaled; -}; - LGEvent * lgCreateEvent(bool autoReset, unsigned int msSpinTime) { - LGEvent * event = (LGEvent *)malloc(sizeof(LGEvent)); - if (!event) - { - DEBUG_ERROR("out of ram"); - return NULL; - } - - event->lock = 0; - event->reset = autoReset; - event->handle = CreateEvent(NULL, autoReset ? FALSE : TRUE, FALSE, NULL); - event->wrapped = false; - event->msSpinTime = msSpinTime; - atomic_store(&event->signaled, false); - - if (!event->handle) + HANDLE handle = CreateEvent(NULL, autoReset ? FALSE : TRUE, FALSE, NULL); + if (!handle) { DEBUG_WINERROR("Failed to create the event", GetLastError()); - free(event); return NULL; } - return event; + return (LGEvent *)handle; } LGEvent * lgWrapEvent(void * handle) { - LGEvent * event = (LGEvent *)malloc(sizeof(LGEvent)); - if (!event) - { - DEBUG_ERROR("out of ram"); - return NULL; - } - - event->lock = 0; - event->reset = false; - event->handle = (HANDLE)handle; - event->wrapped = true; - event->msSpinTime = 0; - atomic_store(&event->signaled, false); - return event; + return (LGEvent *)handle; } void lgFreeEvent(LGEvent * event) { - CloseHandle(event->handle); + CloseHandle((HANDLE)event); } bool lgWaitEvent(LGEvent * event, unsigned int timeout) { - // wrapped events can't be enahnced - if (!event->wrapped) - { - if (event->reset) - { - if (atomic_exchange(&event->signaled, false)) - return true; - } - else - { - if (atomic_load(&event->signaled)) - return true; - } - - if (timeout == 0) - return false; - - if (event->msSpinTime) - { - unsigned int spinTime = event->msSpinTime; - if (timeout != TIMEOUT_INFINITE) - { - if (timeout > event->msSpinTime) - timeout -= event->msSpinTime; - else - { - spinTime -= timeout; - timeout = 0; - } - } - - uint64_t now = microtime(); - uint64_t end = now + spinTime * 1000; - - if (event->reset) - { - while(!atomic_exchange(&event->signaled, false)) - { - now = microtime(); - if (now >= end) - return false; - } - return true; - } - else - { - while(!atomic_load(&event->signaled)) - { - now = microtime(); - if (now >= end) - return false; - } - return true; - } - } - } - const DWORD to = (timeout == TIMEOUT_INFINITE) ? INFINITE : (DWORD)timeout; - while(true) + do { - switch(WaitForSingleObject(event->handle, to)) + switch(WaitForSingleObject((HANDLE)event, to)) { case WAIT_OBJECT_0: - if (!event->reset) - atomic_store(&event->signaled, true); return true; case WAIT_ABANDONED: @@ -159,7 +63,6 @@ bool lgWaitEvent(LGEvent * event, unsigned int timeout) case WAIT_TIMEOUT: if (timeout == TIMEOUT_INFINITE) continue; - return false; case WAIT_FAILED: @@ -168,63 +71,18 @@ bool lgWaitEvent(LGEvent * event, unsigned int timeout) } DEBUG_ERROR("Unknown wait event return code"); - return false; } -} + while(0); -bool lgWaitEvents(LGEvent * events[], int count, bool waitAll, unsigned int timeout) -{ - const DWORD to = (timeout == TIMEOUT_INFINITE) ? INFINITE : (DWORD)timeout; - - HANDLE * handles = (HANDLE *)malloc(sizeof(HANDLE) * count); - for(int i = 0; i < count; ++i) - handles[i] = events[i]->handle; - - while(true) - { - DWORD result = WaitForMultipleObjects(count, handles, waitAll, to); - if (result >= WAIT_OBJECT_0 && result < count) - { - // null non signaled events from the handle list - for(int i = 0; i < count; ++i) - if (i != result && !lgWaitEvent(events[i], 0)) - events[i] = NULL; - free(handles); - return true; - } - - if (result >= WAIT_ABANDONED_0 && result - WAIT_ABANDONED_0 < count) - continue; - - switch(result) - { - case WAIT_TIMEOUT: - if (timeout == TIMEOUT_INFINITE) - continue; - - free(handles); - return false; - - case WAIT_FAILED: - DEBUG_WINERROR("Wait for event failed", GetLastError()); - free(handles); - return false; - } - - DEBUG_ERROR("Unknown wait event return code"); - free(handles); - return false; - } + return false; } bool lgSignalEvent(LGEvent * event) { - atomic_store(&event->signaled, true); - return SetEvent(event->handle); + return SetEvent((HANDLE)event); } bool lgResetEvent(LGEvent * event) { - atomic_store(&event->signaled, false); - return ResetEvent(event->handle); + return ResetEvent((HANDLE)event); } diff --git a/host/platform/Windows/capture/NVFBC/src/nvfbc.c b/host/platform/Windows/capture/NVFBC/src/nvfbc.c index a75b4449..36f36c82 100644 --- a/host/platform/Windows/capture/NVFBC/src/nvfbc.c +++ b/host/platform/Windows/capture/NVFBC/src/nvfbc.c @@ -58,7 +58,7 @@ struct iface NvFBCFrameGrabInfo grabInfo; LGEvent * frameEvent; - LGEvent * cursorEvents[2]; + LGEvent * cursorEvent; int mouseX, mouseY, mouseHotX, mouseHotY; bool mouseVisible, hasMousePosition; @@ -92,8 +92,16 @@ static void on_mouseMove(int x, int y) this->hasMousePosition = true; this->mouseX = x; this->mouseY = y; - if (this->cursorEvents[0]) - lgSignalEvent(this->cursorEvents[0]); + + const CapturePointer pointer = + { + .positionUpdate = true, + .visible = this->mouseVisible, + .x = x - this->mouseHotX, + .y = y - this->mouseHotY + }; + + this->postPointerBufferFn(pointer); } static const char * nvfbc_getName(void) @@ -196,10 +204,8 @@ static bool nvfbc_init(void) return false; } - this->cursorEvents[0] = lgCreateEvent(true, 10); - if (this->seperateCursor) - this->cursorEvents[1] = lgWrapEvent(event); + this->cursorEvent = lgWrapEvent(event); if (!this->mouseHookCreated) { @@ -232,7 +238,7 @@ static void nvfbc_stop(void) { this->stop = true; - lgSignalEvent(this->cursorEvents[0]); + lgSignalEvent(this->cursorEvent); lgSignalEvent(this->frameEvent); if (this->pointerThread) @@ -244,12 +250,7 @@ static void nvfbc_stop(void) static bool nvfbc_deinit(void) { - if (this->cursorEvents[0]) - { - lgFreeEvent(this->cursorEvents[0]); - this->cursorEvents[0] = NULL; - } - + this->cursorEvent = NULL; if (this->nvfbc) { NvFBCToSysRelease(&this->nvfbc); @@ -378,13 +379,9 @@ static CaptureResult nvfbc_getFrame(FrameBuffer * frame, static int pointerThread(void * unused) { - lgSignalEvent(this->cursorEvents[1]); - while(!this->stop) { - LGEvent * events[2]; - memcpy(&events, &this->cursorEvents, sizeof(LGEvent *) * 2); - if (!lgWaitEvents(events, this->seperateCursor ? 2 : 1, false, 1000)) + if (!lgWaitEvent(this->cursorEvent, 1000)) continue; if (this->stop) @@ -392,39 +389,31 @@ static int pointerThread(void * unused) CaptureResult result; CapturePointer pointer = { 0 }; - bool hotspotUpdated = false; - if (this->seperateCursor && events[1]) + void * data; + uint32_t size; + if (!this->getPointerBufferFn(&data, &size)) { - void * data; - uint32_t size; - if (!this->getPointerBufferFn(&data, &size)) - { - DEBUG_WARN("failed to get a pointer buffer"); - continue; - } - - result = NvFBCToSysGetCursor(this->nvfbc, &pointer, data, size); - if (result != CAPTURE_RESULT_OK) - { - DEBUG_WARN("NvFBCToSysGetCursor failed"); - continue; - } - - this->mouseVisible = pointer.visible; - this->mouseHotX = pointer.hx; - this->mouseHotY = pointer.hy; - hotspotUpdated = true; + DEBUG_WARN("failed to get a pointer buffer"); + continue; } - if (events[0] || (hotspotUpdated && this->hasMousePosition)) + result = NvFBCToSysGetCursor(this->nvfbc, &pointer, data, size); + if (result != CAPTURE_RESULT_OK) { - pointer.positionUpdate = true; - pointer.visible = this->mouseVisible; - pointer.x = this->mouseX - this->mouseHotX; - pointer.y = this->mouseY - this->mouseHotY; + DEBUG_WARN("NvFBCToSysGetCursor failed"); + continue; } + this->mouseVisible = pointer.visible; + this->mouseHotX = pointer.hx; + this->mouseHotY = pointer.hy; + + pointer.positionUpdate = true; + pointer.visible = this->mouseVisible; + pointer.x = this->mouseX - pointer.hx; + pointer.y = this->mouseY - pointer.hy; + this->postPointerBufferFn(pointer); }