mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
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:
parent
6e20c32859
commit
8ffe582615
78
src/base/tl/threading.h
Normal file
78
src/base/tl/threading.h
Normal 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();
|
||||
}
|
||||
};
|
|
@ -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();
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue