接着上一篇:
CleanupEditToolRenderData=TypeName
RETURN_QUICK_DECLARE_CYCLE_STAT(TypeName, STATGROUP_RenderThreadCommands); \
#define RETURN_QUICK_DECLARE_CYCLE_STAT(StatId,GroupId) \
DECLARE_STAT(TEXT(#StatId),StatId,GroupId,EStatDataType::ST_int64, true, true, FPlatformMemory::MCR_Invalid); \
static DEFINE_STAT(StatId) \
return GET_STATID(StatId);
#define DECLARE_STAT(Description, StatName, GroupName, StatType, bShouldClearEveryFrame, bCycleStat, MemoryRegion) \
struct FStat_##StatName\
{ \
typedef FStatGroup_##GroupName TGroup; \
static FORCEINLINE const char* GetStatName() \
{ \
return #StatName; \
} \
static FORCEINLINE const TCHAR* GetDescription() \
{ \
return Description; \
} \
static FORCEINLINE EStatDataType::Type GetStatType() \
{ \
return StatType; \
} \
static FORCEINLINE bool IsClearEveryFrame() \
{ \
return bShouldClearEveryFrame; \
} \
static FORCEINLINE bool IsCycleStat() \
{ \
return bCycleStat; \
} \
static FORCEINLINE FPlatformMemory::EMemoryCounterRegion GetMemoryRegion() \
{ \
return MemoryRegion; \
} \
};
所以
RETURN_QUICK_DECLARE_CYCLE_STAT(TypeName, STATGROUP_RenderThreadCommands);
变成了:
struct FStat_CleanupEditToolRenderData\
{ \
typedef FStatGroup_STATGROUP_RenderThreadCommands TGroup; \
static FORCEINLINE const char* GetStatName() \
{ \
return CleanupEditToolRenderData; \
} \
static FORCEINLINE const TCHAR* GetDescription() \
{ \
return Description; \
} \
static FORCEINLINE EStatDataType::Type GetStatType() \
{ \
return StatType; \
} \
static FORCEINLINE bool IsClearEveryFrame() \
{ \
return bShouldClearEveryFrame; \
} \
static FORCEINLINE bool IsCycleStat() \
{ \
return bCycleStat; \
} \
static FORCEINLINE FPlatformMemory::EMemoryCounterRegion GetMemoryRegion() \
{ \
return MemoryRegion; \
} \
};
static DEFINE_STAT(StatId) \
return GET_STATID(StatId);
第二个宏:
static DEFINE_STAT(StatId) \
#define DEFINE_STAT(Stat) \
struct FThreadSafeStaticStat<FStat_##Stat> StatPtr_##Stat;
所以上面的代码变成了:
struct FStat_CleanupEditToolRenderData\
{ \
typedef FStatGroup_STATGROUP_RenderThreadCommands TGroup; \
static FORCEINLINE const char* GetStatName() \
{ \
return CleanupEditToolRenderData; \
} \
static FORCEINLINE const TCHAR* GetDescription() \
{ \
return Description; \
} \
static FORCEINLINE EStatDataType::Type GetStatType() \
{ \
return StatType; \
} \
static FORCEINLINE bool IsClearEveryFrame() \
{ \
return bShouldClearEveryFrame; \
} \
static FORCEINLINE bool IsCycleStat() \
{ \
return bCycleStat; \
} \
static FORCEINLINE FPlatformMemory::EMemoryCounterRegion GetMemoryRegion() \
{ \
return MemoryRegion; \
} \
};
static struct FThreadSafeStaticStat<FStat_CleanupEditToolRenderData> StatPtr_CleanupEditToolRenderData;
return GET_STATID(StatId);
最后一个宏:
GET_STATID(StatId);
#define GET_STATID(Stat) (StatPtr_##Stat.GetStatId())
所以最后代码变成了:
struct FStat_CleanupEditToolRenderData\
{ \
typedef FStatGroup_STATGROUP_RenderThreadCommands TGroup; \
static FORCEINLINE const char* GetStatName() \
{ \
return CleanupEditToolRenderData; \
} \
static FORCEINLINE const TCHAR* GetDescription() \
{ \
return Description; \
} \
static FORCEINLINE EStatDataType::Type GetStatType() \
{ \
return StatType; \
} \
static FORCEINLINE bool IsClearEveryFrame() \
{ \
return bShouldClearEveryFrame; \
} \
static FORCEINLINE bool IsCycleStat() \
{ \
return bCycleStat; \
} \
static FORCEINLINE FPlatformMemory::EMemoryCounterRegion GetMemoryRegion() \
{ \
return MemoryRegion; \
} \
};
static struct FThreadSafeStaticStat<FStat_CleanupEditToolRenderData> StatPtr_CleanupEditToolRenderData;
return (StatPtr_CleanupEditToolRenderData.GetStatId());
所以上一篇代码
ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER(
CleanupEditToolRenderData,
FLandscapeEditToolRenderData*, LandscapeEditToolRenderData, this,
{
delete LandscapeEditToolRenderData;
}
);
变成了:
class EURCMacro_CleanupEditToolRenderData : public FRenderCommand
{
public:
EURCMacro_CleanupEditToolRenderData(OptTypename TCallTraits<FLandscapeEditToolRenderData*>::ParamType In##LandscapeEditToolRenderData):
LandscapeEditToolRenderData(InLandscapeEditToolRenderData)
{}
void DoTask(ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent)
{
FRHICommandListImmediate& RHICmdList = GetImmediateCommandList_ForRenderCommand();
delete LandscapeEditToolRenderData;
}
FORCEINLINE TStatId GetStatId() const
{
struct FStat_CleanupEditToolRenderData
{
typedef FStatGroup_STATGROUP_RenderThreadCommands TGroup;
static FORCEINLINE const char* GetStatName()
{
return CleanupEditToolRenderData;
}
static FORCEINLINE const TCHAR* GetDescription()
{
return Description;
}
static FORCEINLINE EStatDataType::Type GetStatType()
{
return StatType;
}
static FORCEINLINE bool IsClearEveryFrame()
{
return bShouldClearEveryFrame;
}
static FORCEINLINE bool IsCycleStat()
{
return bCycleStat;
}
static FORCEINLINE FPlatformMemory::EMemoryCounterRegion GetMemoryRegion()
{
return MemoryRegion;
}
};
static struct FThreadSafeStaticStat<FStat_CleanupEditToolRenderData> StatPtr_CleanupEditToolRenderData;
return (StatPtr_CleanupEditToolRenderData.GetStatId());
}
private:
FLandscapeEditToolRenderData* LandscapeEditToolRenderData;
};
{
if(GIsThreadedRendering || !IsInGameThread())
{
CheckNotBlockedOnRenderThread();
TGraphTask<EURCMacro_CleanupEditToolRenderData>::CreateTask().ConstructAndDispatchWhenReady(this);
}
else
{
EURCMacro_CleanupEditToolRenderData TempCommand(this);
FScopeCycleCounter EURCMacro_Scope(TempCommand.GetStatId());
TempCommand.DoTask(ENamedThreads::GameThread, FGraphEventRef() );
}
}
最后解释一下,
GIsThreadedRendering 是判断是否是多线程渲染,如果是多线程渲染,就发送给渲染线程,如果是不支持多线程,就直接在主线程DoTask。
被这个问题困扰了好久。。无奈了。。。。