【冷漠搬砖】UE4随笔——渲染线程使用
通常情况下UE4的渲染操作是在渲染线程下执行的,这样无疑可以提高系统的效率以及电脑CPU的利用率,当然在某些情况下也可能在game线程下进行渲染操作,但一般都是渲染线程会比game线程晚一帧执行。下面将对渲染线程的调用流程进行一个简单的介绍。
http://cdn.u1.huluxia.com/g4/M02/F9/58/rBAAdl8w6K2AVSfbAAAP5DPxc6c587.jpg
1 线程创建
将代码定位到
int32 FEngineLoop::PreInit(const TCHAR* CmdLine
其中有一行代码为
// initialize task graph sub-system with potential multiple threads
FTaskGraphInterface::Startup(FPlatformMisc::
这行代码就是在引擎加载阶段对线程进行创建,具体过程请继续往下看,
http://cdn.u1.huluxia.com/g4/M02/F9/58/rBAAdl8w6K6AFRkbAAEDIRmwJhk472.jpg
在上述代码中FTaskGraphInterface是一个单件,而FTaskGraphImplementation是FTaskGraphInterface的一个实现类,也就是创建这个单件,下面进入FTaskGraphImplementation来看下这个单件实现类。
http://cdn.u1.huluxia.com/g4/M02/F9/58/rBAAdl8w6K-AanSjAAVHdkkXl9M200.jpg
纵观以上代码,说白了就是计算需要创建线程个数,并且创建的过程,线程分为FTaskThreadAnyThread和FNamedTaskThread两种,创建的代码如下:
http://cdn.u1.huluxia.com/g4/M02/F9/58/rBAAdl8w6LCAKPtGAAD9KFn69X4367.jpg
创建好的任务线程保存在WorkerThreads[]中,而且这些任务线程均继承于FRunnable接口,该接口是UE4自定义的线程,不过是一个假的线程,线程真正的创建在以下代码中执行。
WorkerThreads.RunnableThread = FRunnableThread::
以上线程的创建并未包括渲染线程,渲染线程的创建如下:
void StartRenderingThread()
{
static uint32 ThreadCount = 0;
check(!GIsThreadedRendering && GUseThreadedRendering);
check(!GRHIThread_InternalUseOnly && !GIsRunningRHIInSeparateThread_InternalUseOnly && !GIsRunningRHIInDedicatedThread_InternalUseOnly && !GIsRunningRHIInTaskThread_InternalUseOnly);
if (GUseRHIThread_InternalUseOnly)
{
FRHICommandListExecutor::GetImmediateCommandList().ImmediateFlush(EImmediateFlushType::DispatchToRHIThread);
if (!FTaskGraphInterface::Get().IsThreadProcessingTasks(ENamedThreads::RHIThread))
{
FRHIThread::Get().Start();
}
DECLARE_CYCLE_STAT(TEXT("Wait For RHIThread"), STAT_WaitForRHIThread, STATGROUP_TaskGraphTasks);
FGraphEventRef CompletionEvent = TGraphTask<FOwnershipOfRHIThreadTask>::CreateTask(NULL, ENamedThreads::GameThread).ConstructAndDispatchWhenReady(true, GET_STATID(STAT_WaitForRHIThread));
QUICK_SCOPE_CYCLE_COUNTER(STAT_StartRenderingThread);
该过程也是在以下代码中调用。
int32 FEngineLoop::PreInit(const TCHAR* CmdLine)
2 线程调用
渲染线程创建完成之后便可以对其进行使用了,下面以FPrimitiveSceneProxy::SetSelection_GameThread为例进行讲解,完整代码如下所示。
页:
[1]