今天看到把渲染人物放到人物列表的函数。
Engine\Engine\Source\Runtime\Core\Private\Async\TaskGraph.cpp
// API inherited from FTaskGraphInterface
/**
* Function to queue a task, called from a FBaseGraphTask
* @param Task; the task to queue
* @param ThreadToExecuteOn; Either a named thread for a threadlocked task or ENamedThreads::AnyThread for a task that is to run on a worker thread
* @param CurrentThreadIfKnown; This should be the current thread if it is known, or otherwise use ENamedThreads::AnyThread and the current thread will be determined.
**/
virtual void QueueTask(FBaseGraphTask* Task, ENamedThreads::Type ThreadToExecuteOn, ENamedThreads::Type CurrentThreadIfKnown = ENamedThreads::AnyThread) override
{
TASKGRAPH_SCOPE_CYCLE_COUNTER(2, STAT_TaskGraph_QueueTask);
TestRandomizedThreads();
checkThreadGraph(NextUnnamedThreadMod);
if (ENamedThreads::GetThreadIndex(CurrentThreadIfKnown) == ENamedThreads::AnyThread)
{
CurrentThreadIfKnown = GetCurrentThread();
}
else
{
CurrentThreadIfKnown = ENamedThreads::GetThreadIndex(CurrentThreadIfKnown);
checkThreadGraph(CurrentThreadIfKnown == GetCurrentThread());
}
if (ENamedThreads::GetThreadIndex(ThreadToExecuteOn) == ENamedThreads::AnyThread)
{
TASKGRAPH_SCOPE_CYCLE_COUNTER(3, STAT_TaskGraph_QueueTask_AnyThread);
if (FPlatformProcess::SupportsMultithreading())
{
{
TASKGRAPH_SCOPE_CYCLE_COUNTER(4, STAT_TaskGraph_QueueTask_IncomingAnyThreadTasks_Push);
if (ENamedThreads::GetPriority(Task->ThreadToExecuteOn))
{
IncomingAnyThreadTasksHiPri.Push(Task);
}
else
{
IncomingAnyThreadTasks.Push(Task);
}
}
FTaskThread* TempTarget;
{
TASKGRAPH_SCOPE_CYCLE_COUNTER(5, STAT_TaskGraph_QueueTask_StalledUnnamedThreads_Pop);
TempTarget = StalledUnnamedThreads.Pop(); //@todo it is possible that a thread is in the process of stalling and we just missed it, non-fatal, but we could lose a whole task of potential parallelism.
}
if (TempTarget)
{
ThreadToExecuteOn = TempTarget->GetThreadId();
}
else
{
ThreadToExecuteOn = ENamedThreads::Type((uint32(NextUnnamedThreadForTaskFromUnknownThread.Increment()) % uint32(NextUnnamedThreadMod)) + NumNamedThreads);
}
FTaskThread* Target = &Thread(ThreadToExecuteOn);
if (ThreadToExecuteOn != CurrentThreadIfKnown)
{
Target->EnqueueFromOtherThread(0, WakeUpBaseGraphTask);
}
return;
}
else
{
ThreadToExecuteOn = ENamedThreads::GameThread;
}
}
{
int32 QueueToExecuteOn = ENamedThreads::GetQueueIndex(ThreadToExecuteOn);
ThreadToExecuteOn = ENamedThreads::GetThreadIndex(ThreadToExecuteOn);
FTaskThread* Target = &Thread(ThreadToExecuteOn);
if (ThreadToExecuteOn == CurrentThreadIfKnown)
{
Target->EnqueueFromThisThread(QueueToExecuteOn, Task);
}
else
{
Target->EnqueueFromOtherThread(QueueToExecuteOn, Task);
}
}
}
这个文件里还有执行一个Task的函数。
/**
* Process tasks until idle. May block if bAllowStall is true
* @param QueueIndex, Queue to process tasks from
* @param bAllowStall, if true, the thread will block on the stall event when it runs out of tasks.
**/
void ProcessTasks(int32 QueueIndex, bool bAllowStall)
{
TStatId StallStatId;
bool bCountAsStall = false;
#if STATS
TStatId StatName;
FCycleCounter ProcessingTasks;
if (ThreadId == ENamedThreads::GameThread)
{
StatName = GET_STATID(STAT_TaskGraph_GameTasks);
StallStatId = GET_STATID(STAT_Ta