Display driver loop refactor

This commit is contained in:
elasota
2021-03-26 17:05:38 -04:00
parent 48fe83bb33
commit c87f238563
30 changed files with 595 additions and 735 deletions

View File

@@ -11,16 +11,13 @@
#include <assert.h>
GpAppEnvironment::GpAppEnvironment()
: m_applicationState(ApplicationState_NotStarted)
, m_displayDriver(nullptr)
: m_displayDriver(nullptr)
, m_audioDriver(nullptr)
, m_inputDrivers(nullptr)
, m_numInputDrivers(0)
, m_fontHandler(nullptr)
, m_vosEventQueue(nullptr)
, m_systemServices(nullptr)
, m_applicationFiber(nullptr)
, m_vosFiber(nullptr)
, m_suspendCallID(PortabilityLayer::HostSuspendCallID_Unknown)
, m_suspendArgs(nullptr)
, m_suspendReturnValue(nullptr)
@@ -29,7 +26,6 @@ GpAppEnvironment::GpAppEnvironment()
GpAppEnvironment::~GpAppEnvironment()
{
assert(m_applicationFiber == nullptr);
}
void GpAppEnvironment::Init()
@@ -37,69 +33,13 @@ void GpAppEnvironment::Init()
GpAppInterface_Get()->ApplicationInit();
}
GpDisplayDriverTickStatus_t GpAppEnvironment::Tick(IGpFiber *vosFiber)
void GpAppEnvironment::Run()
{
GpAppInterface_Get()->PL_IncrementTickCounter(1);
m_vosFiber = vosFiber;
if (m_applicationState == ApplicationState_WaitingForEvents)
m_applicationState = ApplicationState_Running;
for (;;)
{
switch (m_applicationState)
{
case ApplicationState_NotStarted:
InitializeApplicationState();
m_applicationFiber = GpFiberStarter::StartFiber(m_systemServices, GpAppEnvironment::StaticAppThreadFunc, this, vosFiber);
m_applicationState = ApplicationState_Running;
break;
case ApplicationState_WaitingForEvents:
return GpDisplayDriverTickStatuses::kOK;
case ApplicationState_Running:
SynchronizeState();
m_vosFiber->YieldTo(m_applicationFiber);
break;
case ApplicationState_SystemCall:
{
PortabilityLayer::HostSuspendCallID callID = m_suspendCallID;
const PortabilityLayer::HostSuspendCallArgument *args = m_suspendArgs;
PortabilityLayer::HostSuspendCallArgument *returnValue = m_suspendReturnValue;
DispatchSystemCall(callID, args, returnValue);
assert(m_applicationState != ApplicationState_SystemCall);
}
break;
case ApplicationState_TimedSuspend:
if (m_delaySuspendTicks == 0)
m_applicationState = ApplicationState_Running;
else
{
m_delaySuspendTicks--;
return GpDisplayDriverTickStatuses::kOK;
}
break;
case ApplicationState_Synchronizing:
if (m_delaySuspendTicks == 0)
m_applicationState = ApplicationState_Running;
else
{
m_delaySuspendTicks--;
return GpDisplayDriverTickStatuses::kSynchronizing;
}
break;
case ApplicationState_Terminated:
m_applicationFiber->Destroy();
m_applicationFiber = nullptr;
return GpDisplayDriverTickStatuses::kApplicationTerminated;
default:
assert(false);
break;
};
}
InitializeApplicationState();
GpAppInterface_Get()->ApplicationMain();
}
void GpAppEnvironment::Render()
{
GpAppInterface_Get()->PL_Render(m_displayDriver);
@@ -141,19 +81,6 @@ void GpAppEnvironment::SetSystemServices(IGpSystemServices *systemServices)
m_systemServices = systemServices;
}
void GpAppEnvironment::StaticAppThreadFunc(void *context)
{
static_cast<GpAppEnvironment*>(context)->AppThreadFunc();
}
void GpAppEnvironment::AppThreadFunc()
{
GpAppInterface_Get()->ApplicationMain();
m_applicationState = ApplicationState_Terminated;
m_applicationFiber->YieldToTerminal(m_vosFiber);
}
void GpAppEnvironment::InitializeApplicationState()
{
GpDriverCollection *drivers = GpAppInterface_Get()->PL_GetDriverCollection();
@@ -162,8 +89,6 @@ void GpAppEnvironment::InitializeApplicationState()
drivers->SetDrivers<GpDriverIDs::kInput>(m_inputDrivers, m_numInputDrivers);
drivers->SetDriver<GpDriverIDs::kFont>(m_fontHandler);
drivers->SetDriver<GpDriverIDs::kEventQueue>(m_vosEventQueue);
GpAppInterface_Get()->PL_InstallHostSuspendHook(GpAppEnvironment::StaticSuspendHookFunc, this);
}
void GpAppEnvironment::SynchronizeState()
@@ -172,36 +97,3 @@ void GpAppEnvironment::SynchronizeState()
for (size_t i = 0; i < numInputDrivers; i++)
m_inputDrivers[i]->ProcessInput();
}
void GpAppEnvironment::StaticSuspendHookFunc(void *context, PortabilityLayer::HostSuspendCallID callID, const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue)
{
GpAppEnvironment *appEnv = static_cast<GpAppEnvironment*>(context);
appEnv->m_suspendCallID = callID;
appEnv->m_suspendArgs = args;
appEnv->m_suspendReturnValue = returnValue;
appEnv->m_applicationState = ApplicationState_SystemCall;
appEnv->m_applicationFiber->YieldTo(appEnv->m_vosFiber);
}
void GpAppEnvironment::DispatchSystemCall(PortabilityLayer::HostSuspendCallID callID, const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue)
{
switch (callID)
{
case PortabilityLayer::HostSuspendCallID_Delay:
m_applicationState = ApplicationState_TimedSuspend;
m_delaySuspendTicks = args[0].m_uint;
break;
case PortabilityLayer::HostSuspendCallID_ForceSyncFrame:
m_applicationState = ApplicationState_Synchronizing;
m_delaySuspendTicks = 1;
break;
case PortabilityLayer::HostSuspendCallID_CallOnVOSThread:
args[0].m_functionPtr(args[1].m_pointer);
m_applicationState = ApplicationState_Running;
break;
default:
assert(false);
}
}

View File

@@ -26,8 +26,8 @@ public:
~GpAppEnvironment();
void Init();
void Run();
GpDisplayDriverTickStatus_t Tick(IGpFiber *vosFiber);
void Render();
bool AdjustRequestedResolution(uint32_t &physicalWidth, uint32_t &physicalHeight, uint32_t &virtualWidth, uint32_t &virtualheight, float &pixelScaleX, float &pixelScaleY);
@@ -39,34 +39,16 @@ public:
void SetSystemServices(IGpSystemServices *systemServices);
private:
enum ApplicationState
{
ApplicationState_NotStarted,
ApplicationState_WaitingForEvents,
ApplicationState_Running,
ApplicationState_Terminated,
ApplicationState_SystemCall,
ApplicationState_TimedSuspend,
ApplicationState_Synchronizing,
};
static void StaticAppThreadFunc(void *context);
void AppThreadFunc();
void InitializeApplicationState();
void SynchronizeState();
static void StaticSuspendHookFunc(void *context, PortabilityLayer::HostSuspendCallID callID, const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue);
void DispatchSystemCall(PortabilityLayer::HostSuspendCallID callID, const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue);
ApplicationState m_applicationState;
IGpDisplayDriver *m_displayDriver;
IGpAudioDriver *m_audioDriver;
IGpInputDriver *const* m_inputDrivers;
IGpFontHandler *m_fontHandler;
GpVOSEventQueue *m_vosEventQueue;
IGpSystemServices *m_systemServices;
IGpFiber *m_applicationFiber;
IGpFiber *m_vosFiber;
uint32_t m_delaySuspendTicks;
size_t m_numInputDrivers;

View File

@@ -1,4 +1,5 @@
#include "GpMain.h"
#include "GpAppInterface.h"
#include "GpAudioDriverFactory.h"
#include "GpAudioDriverProperties.h"
#include "GpDisplayDriverFactory.h"
@@ -20,11 +21,6 @@
namespace
{
GpDisplayDriverTickStatus_t TickAppEnvironment(void *context, IGpFiber *vosFiber)
{
return static_cast<GpAppEnvironment*>(context)->Tick(vosFiber);
}
void RenderAppEnvironment(void *context)
{
static_cast<GpAppEnvironment*>(context)->Render();
@@ -53,9 +49,6 @@ int GpMain::Run()
ddProps.m_frameTimeLockMaxNumerator = 101;
ddProps.m_frameTimeLockMaxDenominator = 6000;
ddProps.m_tickFunc = TickAppEnvironment;
ddProps.m_tickFuncContext = appEnvironment;
ddProps.m_renderFunc = RenderAppEnvironment;
ddProps.m_renderFuncContext = appEnvironment;
@@ -120,7 +113,9 @@ int GpMain::Run()
appEnvironment->SetSystemServices(g_gpGlobalConfig.m_systemServices);
// Start the display loop
displayDriver->Run();
displayDriver->Init();
appEnvironment->Run();
// Clean up
if (inputDrivers)