mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-20 09:34:19 +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/math.h>
|
||||||
#include <base/system.h>
|
#include <base/system.h>
|
||||||
|
#include <base/tl/threading.h>
|
||||||
|
|
||||||
#include <engine/client.h>
|
#include <engine/client.h>
|
||||||
#include <engine/config.h>
|
#include <engine/config.h>
|
||||||
|
@ -1688,17 +1689,27 @@ void CClient::InitInterfaces()
|
||||||
m_Friends.Init();
|
m_Friends.Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClient::Run()
|
|
||||||
|
enum
|
||||||
{
|
{
|
||||||
int64 ReportTime = time_get();
|
GFXSTATE_ERROR = -1,
|
||||||
int64 ReportInterval = time_freq()*1;
|
GFXSTATE_INIT = 0,
|
||||||
|
GFXSTATE_IDLE,
|
||||||
m_LocalStartTime = time_get();
|
GFXSTATE_RENDERING,
|
||||||
m_SnapshotParts = 0;
|
GFXSTATE_SWAPPING,
|
||||||
|
};
|
||||||
|
|
||||||
|
void CClient::GraphicsThread()
|
||||||
|
{
|
||||||
// init graphics
|
// init graphics
|
||||||
if(m_pGraphics->Init() != 0)
|
if(m_pGraphics->Init() != 0)
|
||||||
|
{
|
||||||
|
m_GfxState = GFXSTATE_ERROR;
|
||||||
|
m_GfxStateSemaphore.signal();
|
||||||
|
m_GfxState = GFXSTATE_ERROR;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// open socket
|
// open socket
|
||||||
{
|
{
|
||||||
|
@ -1708,6 +1719,7 @@ void CClient::Run()
|
||||||
if(!m_NetClient.Open(BindAddr, 0))
|
if(!m_NetClient.Open(BindAddr, 0))
|
||||||
{
|
{
|
||||||
dbg_msg("client", "couldn't start network");
|
dbg_msg("client", "couldn't start network");
|
||||||
|
m_GfxState = GFXSTATE_ERROR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1722,16 +1734,66 @@ void CClient::Run()
|
||||||
MasterServer()->RefreshAddresses(m_NetClient.NetType());
|
MasterServer()->RefreshAddresses(m_NetClient.NetType());
|
||||||
|
|
||||||
// init the editor
|
// init the editor
|
||||||
m_pEditor->Init();
|
//m_pEditor->Init();
|
||||||
|
|
||||||
// init sound, allowed to fail
|
// init sound, allowed to fail
|
||||||
m_SoundInitFailed = Sound()->Init() != 0;
|
m_SoundInitFailed = Sound()->Init() != 0;
|
||||||
|
|
||||||
// load data
|
// load data
|
||||||
if(!LoadData())
|
if(!LoadData())
|
||||||
|
{
|
||||||
|
m_GfxState = GFXSTATE_ERROR;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
GameClient()->OnInit();
|
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];
|
char aBuf[256];
|
||||||
str_format(aBuf, sizeof(aBuf), "version %s", GameClient()->NetVersion());
|
str_format(aBuf, sizeof(aBuf), "version %s", GameClient()->NetVersion());
|
||||||
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf);
|
m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "client", aBuf);
|
||||||
|
@ -1848,6 +1910,26 @@ void CClient::Run()
|
||||||
|
|
||||||
Update();
|
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(g_Config.m_DbgStress)
|
||||||
{
|
{
|
||||||
if((m_Frames%10) == 0)
|
if((m_Frames%10) == 0)
|
||||||
|
@ -1860,7 +1942,7 @@ void CClient::Run()
|
||||||
{
|
{
|
||||||
Render();
|
Render();
|
||||||
m_pGraphics->Swap();
|
m_pGraphics->Swap();
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoScreenshot_Cleanup();
|
AutoScreenshot_Cleanup();
|
||||||
|
|
|
@ -172,6 +172,12 @@ class CClient : public IClient, public CDemoPlayer::IListner
|
||||||
class CHostLookup m_VersionServeraddr;
|
class CHostLookup m_VersionServeraddr;
|
||||||
} m_VersionInfo;
|
} m_VersionInfo;
|
||||||
|
|
||||||
|
semaphore m_GfxRenderSemaphore;
|
||||||
|
semaphore m_GfxStateSemaphore;
|
||||||
|
volatile int m_GfxState;
|
||||||
|
static void GraphicsThreadProxy(void *pThis) { ((CClient*)pThis)->GraphicsThread(); }
|
||||||
|
void GraphicsThread();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IEngine *Engine() { return m_pEngine; }
|
IEngine *Engine() { return m_pEngine; }
|
||||||
IEngineGraphics *Graphics() { return m_pGraphics; }
|
IEngineGraphics *Graphics() { return m_pGraphics; }
|
||||||
|
|
|
@ -627,6 +627,9 @@ int CMenus::RenderMenubar(CUIRect r)
|
||||||
|
|
||||||
void CMenus::RenderLoading()
|
void CMenus::RenderLoading()
|
||||||
{
|
{
|
||||||
|
// TODO: not supported right now due to separate render thread
|
||||||
|
return;
|
||||||
|
|
||||||
static int64 LastLoadRender = 0;
|
static int64 LastLoadRender = 0;
|
||||||
float Percent = m_LoadCurrent++/(float)m_LoadTotal;
|
float Percent = m_LoadCurrent++/(float)m_LoadTotal;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue