从蓝图载入一张纹理开始理解UE4的资源加载(九)——ProcessImportsAndExp...
发布网友
发布时间:2024-10-09 15:19
我来回答
共1个回答
热心网友
时间:2024-10-09 23:26
在这一阶段,主要任务涉及资源的导入与导出,具体流程如下:
首先,需处理的是待开始预缓存请求的数组。引擎中设定了GMaxPrecacheRequestsInFlight为2,意味着最多同时执行2个预缓存请求。
接着,需关注ExportsThatCanHaveIOStarted数组,此数组中记录了需开始IO操作的ExportIndex,且Export需完成Create后方能加入此数组。需要注意的是,此数组为堆排序结构,按ExportIndex排序。
在StartPrecacheRequest方法中,依次处理可进行IO操作的Export。过程中,通过bReady变量标记加载状态。若Export含有NeedLoad标记,则无需加载。然后判断是否已有所需Block,否则检查Block请求是否已发出。若任一环节执行过,则删除StartIO节点,通过依赖关系添加Export的Serialized节点。
若以上流程均未执行,则创建新的请求,该请求包含IO所需偏移和大小参数,内部关联相关Export。接着,检查并合并可一起请求IO的Export,以减少IO请求次数,条件是请求大小小于1MB且Export跨度不超过20个。
对于待IO的Export,若位于Block中则视为加载完成,直接删除并结束处理。若两个Export之间距离小于48KB且总请求大小未超过限制,说明可合并请求,扩大请求范围。
创建异步读取请求,回调为FPrecacheCallbackHandler::RequestComplete方法,添加到Incoming中。发起请求后,维护Export与PrecacheRequest的映射表与哈希表,并注册到PrecacheHandler中。
在LinkImport阶段,处理ImportsThatAreNowCreated数组中的Import,需Link的Import在此阶段添加。Import->XObject不为空时,LinkImport方法执行简单过程。处理结束时删除Import_Create节点并触发,最终将Import添加到ImportsThatAreNowSerialized数组中。
在RemoveNode阶段,处理上个工作添加的数组元素,实质上是删除Import_Serialize节点。值得注意的是,需遵循EventLoadGraph中提到的隐式依赖。
EventDrivenCreateExport阶段处理ExpsortsThatCanBeCreated数组中的Export,此数组在SetupExports阶段添加。关键步骤是判断Export类型,并通过Package尝试内存中加载对应Object。若未加载,则生成模板并返回。随后创建Export.Object,检查LoadClass对应的CDO是否需加载并创建,然后调用StaticConstructObject_Internal方法创建Object。创建过程中在内存中寻找对象,若未找到则创建新对象并原地构造。创建后通过模板进行初始化。最后,设置Linker给Export.Object,删除Export的Create节点,触发其StartIO节点。
在EventDrivenSerializeExport阶段处理ExportsThatCanBeSerialized数组中的Export,由MakeNextPrecacheRequestCurrent方法添加。完成序列化后删除节点。若所有Import和Export序列化完毕,则触发Package_ExportsSerialized节点,进入下一阶段。
IO完成回调中,将Precache加入到Incoming中,由FAsyncLoadingThread::TickAsyncThread处理,添加到ReadyPrecacheRequests数组中。在ProcessImportsAndExports阶段处理,取出IAsyncReadRequest,找到对应的FExportIORequest。设置CurrentBlockOffset与CurrentBlockBytes。主要工作是将Block.Processed内容复制到FAsyncArchive::Memory中,同时表明哪些Export数据已载入,移除请求加载的Export对应的StartIO节点。