ugly incomplete hack to put the rendering into another thread so we don't have to wait for the flip

This commit is contained in:
Magnus Auvinen 2011-12-30 16:02:22 +01:00
parent 6e20c32859
commit 8ffe582615
4 changed files with 177 additions and 8 deletions

78
src/base/tl/threading.h Normal file
View file

@ -0,0 +1,78 @@
#pragma once
#include "../system.h"
inline unsigned atomic_inc(volatile unsigned *pValue)
{
return __sync_fetch_and_add(pValue, 1);
}
inline unsigned atomic_dec(volatile unsigned *pValue)
{
return __sync_fetch_and_add(pValue, -1);
}
inline unsigned atomic_compswap(volatile unsigned *pValue, unsigned comperand, unsigned value)
{
return __sync_val_compare_and_swap(pValue, comperand, value);
}
inline void sync_barrier()
{
__sync_synchronize();
}
#include <semaphore.h>
typedef sem_t SEMAPHORE;
inline void semaphore_init(SEMAPHORE *sem) { sem_init(sem, 0, 0); }
inline void semaphore_wait(SEMAPHORE *sem) { sem_wait(sem); }
inline void semaphore_signal(SEMAPHORE *sem) { sem_post(sem); }
inline void semaphore_destroy(SEMAPHORE *sem) { sem_destroy(sem); }
class semaphore
{
SEMAPHORE sem;
public:
semaphore() { semaphore_init(&sem); }
~semaphore() { semaphore_destroy(&sem); }
void wait() { semaphore_wait(&sem); }
void signal() { semaphore_signal(&sem); }
};
class lock
{
friend class scope_lock;
LOCK var;
void take() { lock_wait(var); }
void release() { lock_release(var); }
public:
lock()
{
var = lock_create();
}
~lock()
{
lock_destroy(var);
}
};
class scope_lock
{
lock *var;
public:
scope_lock(lock *l)
{
var = l;
var->take();
}
~scope_lock()
{
var->release();
}
};

View file

@ -7,6 +7,7 @@
#include <base/math.h>
#include <base/system.h>
#include <base/tl/threading.h>
#include <engine/client.h>
#include <engine/config.h>
@ -1688,17 +1689,27 @@ void CClient::InitInterfaces()
m_Friends.Init();
}
void CClient::Run()
enum
{
int64 ReportTime = time_get();
int64 ReportInterval = time_freq()*1;
m_LocalStartTime = time_get();
m_SnapshotParts = 0;
GFXSTATE_ERROR = -1,
GFXSTATE_INIT = 0,
GFXSTATE_IDLE,
GFXSTATE_RENDERING,
GFXSTATE_SWAPPING,
};
void CClient::GraphicsThread()
{
// init graphics
if(m_pGraphics->Init() != 0)
{
m_GfxState = GFXSTATE_ERROR;
m_GfxStateSemaphore.signal();
m_GfxState = GFXSTATE_ERROR;
return;
}
// open socket
{
@ -1708,6 +1719,7 @@ void CClient::Run()
if(!m_NetClient.Open(BindAddr, 0))
{
dbg_msg("client", "couldn't start network");
m_GfxState = GFXSTATE_ERROR;
return;
}
}
@ -1722,16 +1734,66 @@ void CClient::Run()
MasterServer()->RefreshAddresses(m_NetClient.NetType());
// init the editor
m_pEditor->Init();
//m_pEditor->Init();
// init sound, allowed to fail
m_SoundInitFailed = Sound()->Init() != 0;
// load data
if(!LoadData())
{
m_GfxState = GFXSTATE_ERROR;
return;
}
GameClient()->OnInit();
while(1)
{
// do idle
sync_barrier();
m_GfxState = GFXSTATE_IDLE;
m_GfxStateSemaphore.signal();
m_GfxRenderSemaphore.wait();
// do render
m_GfxState = GFXSTATE_RENDERING;
m_GfxStateSemaphore.signal();
Render();
sync_barrier();
// do swap
m_GfxState = GFXSTATE_SWAPPING;
m_GfxStateSemaphore.signal();
m_pGraphics->Swap();
}
// do shutdown
}
void CClient::Run()
{
int64 ReportTime = time_get();
int64 ReportInterval = time_freq()*1;
m_LocalStartTime = time_get();
m_SnapshotParts = 0;
m_GfxState = GFXSTATE_INIT;
thread_create(GraphicsThreadProxy, this);
// wait for gfx to init
while(1)
{
m_GfxStateSemaphore.wait();
if(m_GfxState == GFXSTATE_ERROR)
return;
if(m_GfxState != GFXSTATE_INIT)
break;
}
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "version %s", GameClient()->NetVersion());
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf);
@ -1847,7 +1909,27 @@ void CClient::Run()
m_EditorActive = false;
Update();
if(m_GfxState == GFXSTATE_IDLE)
{
// issue new rendering
m_GfxRenderSemaphore.signal();
// wait for gfx to finish rendering
while(m_GfxState != GFXSTATE_SWAPPING)
m_GfxStateSemaphore.wait();
}
/*
if(m_pGraphics->AsyncSwapIsDone())
{
m_pGraphics->BeginScene();
Render();
m_pGraphics->EndScene();
}*/
/*
if(g_Config.m_DbgStress)
{
if((m_Frames%10) == 0)
@ -1860,7 +1942,7 @@ void CClient::Run()
{
Render();
m_pGraphics->Swap();
}
}*/
}
AutoScreenshot_Cleanup();

View file

@ -172,6 +172,12 @@ class CClient : public IClient, public CDemoPlayer::IListner
class CHostLookup m_VersionServeraddr;
} m_VersionInfo;
semaphore m_GfxRenderSemaphore;
semaphore m_GfxStateSemaphore;
volatile int m_GfxState;
static void GraphicsThreadProxy(void *pThis) { ((CClient*)pThis)->GraphicsThread(); }
void GraphicsThread();
public:
IEngine *Engine() { return m_pEngine; }
IEngineGraphics *Graphics() { return m_pGraphics; }

View file

@ -627,6 +627,9 @@ int CMenus::RenderMenubar(CUIRect r)
void CMenus::RenderLoading()
{
// TODO: not supported right now due to separate render thread
return;
static int64 LastLoadRender = 0;
float Percent = m_LoadCurrent++/(float)m_LoadTotal;