mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-08-06 02:34:00 +00:00
[client] allow frame updates to be triggered by a timed event
This is a major change to how the LG client performs it's updates. In the past LG would operate a fixed FPS regardless of incoming update speed and/or frequency. This change allows LG to dynamically increase it's FPS in order to better sync with the guest as it's rate changes.
This commit is contained in:
@@ -20,6 +20,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
|
||||
#define TIMEOUT_INFINITE ((unsigned int)~0)
|
||||
|
||||
@@ -34,4 +35,8 @@ bool lgResetEvent (LGEvent * handle);
|
||||
|
||||
// os specific method to wrap/convert a native event into a LGEvent
|
||||
// for windows this is an event HANDLE
|
||||
LGEvent * lgWrapEvent(void * handle);
|
||||
LGEvent * lgWrapEvent(void * handle);
|
||||
|
||||
// Posix specific, not implmented/possible in windows
|
||||
bool lgWaitEventAbs(LGEvent * handle, struct timespec * ts);
|
||||
bool lgWaitEventNS (LGEvent * handle, unsigned int timeout);
|
||||
|
@@ -72,7 +72,7 @@ void lgFreeEvent(LGEvent * handle)
|
||||
free(handle);
|
||||
}
|
||||
|
||||
bool lgWaitEvent(LGEvent * handle, unsigned int timeout)
|
||||
bool lgWaitEventAbs(LGEvent * handle, struct timespec * ts)
|
||||
{
|
||||
assert(handle);
|
||||
|
||||
@@ -82,29 +82,32 @@ bool lgWaitEvent(LGEvent * handle, unsigned int timeout)
|
||||
return false;
|
||||
}
|
||||
|
||||
while(!atomic_load(&handle->flag))
|
||||
bool ret = true;
|
||||
while(ret && !atomic_load(&handle->flag))
|
||||
{
|
||||
if (timeout == TIMEOUT_INFINITE)
|
||||
if (!ts)
|
||||
{
|
||||
if (pthread_cond_wait(&handle->cond, &handle->mutex) != 0)
|
||||
{
|
||||
DEBUG_ERROR("Wait to wait on the condition");
|
||||
return false;
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
struct timespec ts;
|
||||
ts.tv_sec = timeout / 1000;
|
||||
ts.tv_nsec = (timeout % 1000) * 1000000;
|
||||
switch(pthread_cond_timedwait(&handle->cond, &handle->mutex, &ts))
|
||||
switch(pthread_cond_timedwait(&handle->cond, &handle->mutex, ts))
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case ETIMEDOUT:
|
||||
return false;
|
||||
ret = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = false;
|
||||
DEBUG_ERROR("Timed wait failed");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,7 +121,31 @@ bool lgWaitEvent(LGEvent * handle, unsigned int timeout)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool lgWaitEventNS(LGEvent * handle, unsigned int timeout)
|
||||
{
|
||||
if (timeout == TIMEOUT_INFINITE)
|
||||
return lgWaitEventAbs(handle, NULL);
|
||||
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
uint64_t nsec = ts.tv_nsec + timeout;
|
||||
if(nsec > 1e9)
|
||||
{
|
||||
ts.tv_nsec = nsec - 1e9;
|
||||
++ts.tv_sec;
|
||||
}
|
||||
else
|
||||
ts.tv_nsec = nsec;
|
||||
|
||||
return lgWaitEventAbs(handle, &ts);
|
||||
}
|
||||
|
||||
bool lgWaitEvent(LGEvent * handle, unsigned int timeout)
|
||||
{
|
||||
return lgWaitEventNS(handle, timeout * 1000000);
|
||||
}
|
||||
|
||||
bool lgSignalEvent(LGEvent * handle)
|
||||
|
Reference in New Issue
Block a user