虚幻4 Task的创建和执行

本文介绍了虚幻4引擎中Task的创建和执行流程,重点解析了如何将渲染人物放入人物列表,并展示了如何从Sort列表中选取高优先级任务进行执行。通过示例代码展示了任务的创建和分发过程,以及渲染线程的启动和任务队列的管理,帮助理解渲染过程和Task执行的内部机制。
摘要由CSDN通过智能技术生成

今天看到把渲染人物放到人物列表的函数。

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值