Skip to content

Commit

Permalink
- Added Profiling macros to the plugin's code base to help optimize i…
Browse files Browse the repository at this point in the history
…ts performance with

  HDAs that have a lot of nodes/parameters.
  • Loading branch information
dpernuit committed Sep 20, 2024
1 parent 8d80bdd commit 18551a8
Show file tree
Hide file tree
Showing 19 changed files with 141 additions and 14 deletions.
2 changes: 2 additions & 0 deletions Source/HoudiniEngine/Private/HoudiniAnimationTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,8 @@ FHoudiniAnimationTranslator::GetFbxCustomAttributes(
//Creates SkelatalMesh and Skeleton Assets and Packages, and adds them to OutputObjects
bool FHoudiniAnimationTranslator::CreateAnimationFromMotionClip(UHoudiniOutput* InOutput, const TArray<FHoudiniGeoPartObject>& HGPOs, const FHoudiniPackageParams& InPackageParams, UObject* InOuterComponent)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniAnimationTranslator::CreateAnimationFromMotionClip);

if (HGPOs.Num() == 0)
{
HOUDINI_LOG_WARNING(TEXT("Could not translate MotionClip. No Geo Part Objects."));
Expand Down
2 changes: 2 additions & 0 deletions Source/HoudiniEngine/Private/HoudiniDataTableTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,8 @@ FHoudiniDataTableTranslator::BuildDataTable(
UHoudiniOutput* CurOutput,
FHoudiniPackageParams& PackageParams)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniDataTableTranslator::BuildDataTable);

DeletePreviousOutput(CurOutput);

int32 GeoId = HGPO.GeoId;
Expand Down
22 changes: 20 additions & 2 deletions Source/HoudiniEngine/Private/HoudiniEngineManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,8 @@ FHoudiniEngineManager::ProcessComponent(UHoudiniAssetComponent* HAC)
{
case EHoudiniAssetState::NeedInstantiation:
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineManager::ProcessComponent-NeedInstantiation);

// Do nothing unless the HAC has been updated
if (HAC->NeedUpdate())
{
Expand All @@ -525,6 +527,8 @@ FHoudiniEngineManager::ProcessComponent(UHoudiniAssetComponent* HAC)

case EHoudiniAssetState::NewHDA:
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineManager::ProcessComponent-NewHDA);

// Update parameters. Since there is no instantiated node yet, this will only fetch the defaults from
// the asset definition.
FHoudiniParameterTranslator::UpdateParameters(HAC);
Expand All @@ -538,6 +542,8 @@ FHoudiniEngineManager::ProcessComponent(UHoudiniAssetComponent* HAC)

case EHoudiniAssetState::PreInstantiation:
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineManager::ProcessComponent-PreInstantiation);

// Only proceed forward if we don't need to wait for our input HoudiniAssets to finish cooking/instantiating
if (HAC->NeedsToWaitForInputHoudiniAssets())
break;
Expand Down Expand Up @@ -603,7 +609,8 @@ FHoudiniEngineManager::ProcessComponent(UHoudiniAssetComponent* HAC)
}

case EHoudiniAssetState::Instantiating:
{
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineManager::ProcessComponent-Instantiating);
EHoudiniAssetState NewState = EHoudiniAssetState::Instantiating;
if (UpdateInstantiating(HAC, NewState))
{
Expand All @@ -620,6 +627,7 @@ FHoudiniEngineManager::ProcessComponent(UHoudiniAssetComponent* HAC)

case EHoudiniAssetState::PreCook:
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineManager::ProcessComponent-PreCook);
// Only proceed forward if we don't need to wait for our input
// HoudiniAssets to finish cooking/instantiating
if (HAC->NeedsToWaitForInputHoudiniAssets())
Expand Down Expand Up @@ -670,6 +678,7 @@ FHoudiniEngineManager::ProcessComponent(UHoudiniAssetComponent* HAC)

case EHoudiniAssetState::Cooking:
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineManager::ProcessComponent-Cooking);
EHoudiniAssetState NewState = EHoudiniAssetState::Cooking;
bool state = UpdateCooking(HAC, NewState);
if (state)
Expand All @@ -687,6 +696,7 @@ FHoudiniEngineManager::ProcessComponent(UHoudiniAssetComponent* HAC)

case EHoudiniAssetState::PostCook:
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineManager::ProcessComponent-PostCook);
// Handle PostCook
EHoudiniAssetState NewState = EHoudiniAssetState::None;
bool bSuccess = HAC->bLastCookSuccess;
Expand All @@ -709,12 +719,15 @@ FHoudiniEngineManager::ProcessComponent(UHoudiniAssetComponent* HAC)

case EHoudiniAssetState::PreProcess:
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineManager::ProcessComponent-PreProcess);
StartTaskAssetProcess(HAC);
break;
}

case EHoudiniAssetState::Processing:
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineManager::ProcessComponent-Processing);

UpdateProcess(HAC);

HAC->HandleOnPostOutputProcessing();
Expand All @@ -725,6 +738,8 @@ FHoudiniEngineManager::ProcessComponent(UHoudiniAssetComponent* HAC)

case EHoudiniAssetState::None:
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineManager::ProcessComponent-None);

// Update world inputs if we have any
FHoudiniInputTranslator::UpdateWorldInputs(HAC);

Expand Down Expand Up @@ -794,6 +809,7 @@ FHoudiniEngineManager::ProcessComponent(UHoudiniAssetComponent* HAC)

case EHoudiniAssetState::NeedRebuild:
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineManager::ProcessComponent-NeedRebuild);
if (!bIsNodeSyncComponent)
{
// Do not delete nodes for NodeSync components!
Expand All @@ -806,6 +822,7 @@ FHoudiniEngineManager::ProcessComponent(UHoudiniAssetComponent* HAC)

case EHoudiniAssetState::NeedDelete:
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineManager::ProcessComponent-NeedDelete);
if (!bIsNodeSyncComponent)
{
// Do not delete nodes for NodeSync components!
Expand All @@ -821,6 +838,7 @@ FHoudiniEngineManager::ProcessComponent(UHoudiniAssetComponent* HAC)

case EHoudiniAssetState::Deleting:
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineManager::ProcessComponent-Deleting);
break;
}
}
Expand Down Expand Up @@ -854,7 +872,7 @@ FHoudiniEngineManager::StartTaskAssetInstantiation(UHoudiniAsset* HoudiniAsset,
}

// Handle hda files that contain multiple assets
TArray< HAPI_StringHandle > AssetNames;
TArray<HAPI_StringHandle> AssetNames;
if (!FHoudiniEngineUtils::GetSubAssetNames(AssetLibraryId, AssetNames))
{
HOUDINI_LOG_ERROR(TEXT("Cancelling asset instantiation - unable to retrieve asset names."));
Expand Down
2 changes: 2 additions & 0 deletions Source/HoudiniEngine/Private/HoudiniEngineString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ FHoudiniEngineString::HasValidId() const
bool
FHoudiniEngineString::ToStdString(std::string& String, const HAPI_Session* InSession) const
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineString::ToStdString);

String = "";

// Null string ID / zero should be considered invalid
Expand Down
69 changes: 58 additions & 11 deletions Source/HoudiniEngine/Private/HoudiniEngineUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1229,6 +1229,8 @@ FHoudiniEngineUtils::GatherLandscapeInputs(
UHoudiniAssetComponent* HAC,
TArray<ALandscapeProxy*>& AllInputLandscapes)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::GatherLandscapeInputs);

if (!IsValid(HAC))
return;

Expand Down Expand Up @@ -1528,6 +1530,7 @@ FHoudiniEngineUtils::LoadLibHAPI(FString & StoredLibHAPILocation)
bool
FHoudiniEngineUtils::IsInitialized()
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::IsInitialized);
if (!FHoudiniApi::IsHAPIInitialized())
return false;

Expand Down Expand Up @@ -1706,6 +1709,8 @@ FHoudiniEngineUtils::LoadHoudiniAsset(const UHoudiniAsset * HoudiniAsset, HAPI_A
// Lambda to detect license issues
auto CheckLicenseValid = [&AssetFileName](const HAPI_Result& Result)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::LoadHoudiniAsset - CheckLicenseValid);

// HoudiniEngine acquires a license when creating/loading a node, not when creating a session
if (Result >= HAPI_RESULT_NO_LICENSE_FOUND && Result < HAPI_RESULT_ASSET_INVALID)
{
Expand All @@ -1730,6 +1735,8 @@ FHoudiniEngineUtils::LoadHoudiniAsset(const UHoudiniAsset * HoudiniAsset, HAPI_A
// Lambda to load an HDA from file
auto LoadAssetFromFile = [&Result, &OutAssetLibraryId](const FString& InAssetFileName)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::LoadHoudiniAsset - LoadAssetFromFile);

// Load the asset from file.
std::string AssetFileNamePlain;
FHoudiniEngineUtils::ConvertUnrealString(InAssetFileName, AssetFileNamePlain);
Expand All @@ -1741,6 +1748,8 @@ FHoudiniEngineUtils::LoadHoudiniAsset(const UHoudiniAsset * HoudiniAsset, HAPI_A
// Lambda to load an HDA from memory
auto LoadAssetFromMemory = [&Result, &OutAssetLibraryId](const UHoudiniAsset* InHoudiniAsset)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::LoadHoudiniAsset - LoadAssetFromMemory);

// Load the asset from the cached memory buffer
Result = FHoudiniApi::LoadAssetLibraryFromMemory(
FHoudiniEngine::Get().GetSession(),
Expand Down Expand Up @@ -1833,6 +1842,8 @@ FHoudiniEngineUtils::GetSubAssetNames(
const HAPI_AssetLibraryId& AssetLibraryId,
TArray< HAPI_StringHandle >& OutAssetNames)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::GetSubAssetNames);

if (AssetLibraryId < 0)
return false;

Expand Down Expand Up @@ -1940,6 +1951,8 @@ FHoudiniEngineUtils::IsValidNodeId(HAPI_NodeId NodeId)
bool
FHoudiniEngineUtils::GetHoudiniAssetName(const HAPI_NodeId& AssetNodeId, FString& NameString)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::GetHoudiniAssetName);

if (AssetNodeId < 0)
return false;

Expand Down Expand Up @@ -2018,6 +2031,8 @@ FHoudiniEngineUtils::HapiGetAbsNodePath(const HAPI_NodeId& InNodeId, FString& Ou
bool
FHoudiniEngineUtils::HapiGetNodePath(const HAPI_NodeId& InNodeId, const HAPI_NodeId& InRelativeToNodeId, FString& OutPath)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::HapiGetNodePath);

// Retrieve Path to the given Node, relative to the other given Node
if ((InNodeId < 0) || (InRelativeToNodeId < 0))
return false;
Expand Down Expand Up @@ -2100,6 +2115,8 @@ FHoudiniEngineUtils::HapiGetNodePath(const FHoudiniGeoPartObject& InHGPO, FStrin
bool
FHoudiniEngineUtils::HapiGetObjectInfos(const HAPI_NodeId& InNodeId, TArray<HAPI_ObjectInfo>& OutObjectInfos, TArray<HAPI_Transform>& OutObjectTransforms)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::HapiGetObjectInfos);

HAPI_NodeInfo NodeInfo;
FHoudiniApi::NodeInfo_Init(&NodeInfo);
HOUDINI_CHECK_ERROR_RETURN(FHoudiniApi::GetNodeInfo(
Expand Down Expand Up @@ -2211,6 +2228,8 @@ FHoudiniEngineUtils::HapiGetObjectInfos(const HAPI_NodeId& InNodeId, TArray<HAPI
bool
FHoudiniEngineUtils::IsObjNodeFullyVisible(const TSet<HAPI_NodeId>& AllObjectIds, const HAPI_NodeId& InRootNodeId, const HAPI_NodeId& InChildNodeId)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::IsObjNodeFullyVisible);

// Walk up the hierarchy from child to root.
// If any node in that hierarchy is not in the "AllObjectIds" set, the OBJ node is considered to
// be hidden.
Expand Down Expand Up @@ -2289,6 +2308,7 @@ FHoudiniEngineUtils::IsSopNode(const HAPI_NodeId& NodeId)

bool FHoudiniEngineUtils::ContainsSopNodes(const HAPI_NodeId& NodeId)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::ContainsSopNodes);
int ChildCount = 0;
HOUDINI_CHECK_ERROR_RETURN(
FHoudiniApi::ComposeChildNodeList(
Expand Down Expand Up @@ -2339,15 +2359,23 @@ FHoudiniEngineUtils::GatherAllAssetOutputs(

// Get the AssetInfo
HAPI_AssetInfo AssetInfo;
FHoudiniApi::AssetInfo_Init(&AssetInfo);
bool bAssetInfoResult = HAPI_RESULT_SUCCESS == FHoudiniApi::GetAssetInfo(
FHoudiniEngine::Get().GetSession(), AssetId, &AssetInfo);
bool bAssetInfoResult = false;
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::GatherAllAssetOutputs-GetAssetInfo);
FHoudiniApi::AssetInfo_Init(&AssetInfo);
bAssetInfoResult = HAPI_RESULT_SUCCESS == FHoudiniApi::GetAssetInfo(
FHoudiniEngine::Get().GetSession(), AssetId, &AssetInfo);
}

// Get the Asset NodeInfo
HAPI_NodeInfo AssetNodeInfo;
FHoudiniApi::NodeInfo_Init(&AssetNodeInfo);
HAPI_Result NodeResult = FHoudiniApi::GetNodeInfo(
FHoudiniEngine::Get().GetSession(), AssetId, &AssetNodeInfo);
HAPI_Result NodeResult = HAPI_RESULT_FAILURE;
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::GatherAllAssetOutputs-GetNodeInfo);
FHoudiniApi::NodeInfo_Init(&AssetNodeInfo);
NodeResult = FHoudiniApi::GetNodeInfo(
FHoudiniEngine::Get().GetSession(), AssetId, &AssetNodeInfo);
}

if (HAPI_RESULT_SUCCESS != NodeResult)
{
Expand Down Expand Up @@ -2379,6 +2407,7 @@ FHoudiniEngineUtils::GatherAllAssetOutputs(
int32 EditableNodeCount = 0;
if (bAssetHasChildren)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::GatherAllAssetOutputs-ComposeChildNodeList);
HOUDINI_CHECK_ERROR(FHoudiniApi::ComposeChildNodeList(
FHoudiniEngine::Get().GetSession(),
AssetId, HAPI_NODETYPE_SOP, HAPI_NODEFLAGS_EDITABLE,
Expand All @@ -2389,6 +2418,7 @@ FHoudiniEngineUtils::GatherAllAssetOutputs(
// of whether the subnet is considered visible or not.
if (EditableNodeCount > 0)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::GatherAllAssetOutputs-GetComposedChildNodeList);
TArray<HAPI_NodeId> EditableNodeIds;
EditableNodeIds.SetNumUninitialized(EditableNodeCount);
HOUDINI_CHECK_ERROR(FHoudiniApi::GetComposedChildNodeList(
Expand All @@ -2397,6 +2427,7 @@ FHoudiniEngineUtils::GatherAllAssetOutputs(

for (int32 nEditable = 0; nEditable < EditableNodeCount; nEditable++)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::GatherAllAssetOutputs-GetEditableGeoInfo);
HAPI_GeoInfo CurrentEditableGeoInfo;
FHoudiniApi::GeoInfo_Init(&CurrentEditableGeoInfo);
HOUDINI_CHECK_ERROR(FHoudiniApi::GetGeoInfo(
Expand Down Expand Up @@ -2451,6 +2482,7 @@ FHoudiniEngineUtils::GatherAllAssetOutputs(
TSet<HAPI_NodeId> AllObjectIds;
if (bUseOutputFromSubnets)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::GatherAllAssetOutputs-GetComposedChildNodeList2);
int NumObjSubnets;
TArray<HAPI_NodeId> ObjectIds;
HOUDINI_CHECK_ERROR_RETURN(
Expand All @@ -2464,6 +2496,7 @@ FHoudiniEngineUtils::GatherAllAssetOutputs(
),
false);

TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::GatherAllAssetOutputs-GetComposedChildNodeList2);
ObjectIds.SetNumUninitialized(NumObjSubnets);
HOUDINI_CHECK_ERROR_RETURN(
FHoudiniApi::GetComposedChildNodeList(
Expand Down Expand Up @@ -2556,6 +2589,8 @@ bool FHoudiniEngineUtils::GatherImmediateOutputGeoInfos(const HAPI_NodeId& InNod
TSet<HAPI_NodeId>& OutForceNodesCook
)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::GatherImmediateOutputGeoInfos);

TSet<HAPI_NodeId> GatheredNodeIds;

// NOTE: This function assumes that the incoming node is a Geometry container that contains immediate
Expand Down Expand Up @@ -2856,8 +2891,8 @@ FHoudiniEngineUtils::TranslateUnrealTransform(const FTransform& UnrealTransform,

void
FHoudiniEngineUtils::TranslateUnrealTransform(
const FTransform & UnrealTransform,
HAPI_TransformEuler & HapiTransformEuler)
const FTransform& UnrealTransform,
HAPI_TransformEuler& HapiTransformEuler)
{
FHoudiniApi::TransformEuler_Init(&HapiTransformEuler);

Expand Down Expand Up @@ -3014,6 +3049,7 @@ FHoudiniEngineUtils::UploadHACTransform(UHoudiniAssetComponent* HAC)
bool
FHoudiniEngineUtils::HapiSetAssetTransform(const HAPI_NodeId& AssetId, const FTransform & Transform)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::HapiSetAssetTransform);
if (AssetId < 0)
return false;

Expand Down Expand Up @@ -3066,6 +3102,8 @@ FHoudiniEngineUtils::HapiGetParentNodeId(const HAPI_NodeId& NodeId)
void
FHoudiniEngineUtils::AssignUniqueActorLabelIfNeeded(UHoudiniAssetComponent* HAC)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::AssignUniqueActorLabelIfNeeded);

if (!IsValid(HAC))
return;

Expand Down Expand Up @@ -6132,12 +6170,18 @@ FHoudiniEngineUtils::GetGenericAttributeList(


bool
FHoudiniEngineUtils::GetGenericPropertiesAttributes(const HAPI_NodeId& InGeoNodeId, const HAPI_PartId& InPartId,
const bool InbFindDetailAttributes, const int32& InFirstValidPrimIndex, const int32& InFirstValidVertexIndex, const int32& InFirstValidPointIndex,
FHoudiniEngineUtils::GetGenericPropertiesAttributes(
const HAPI_NodeId& InGeoNodeId,
const HAPI_PartId& InPartId,
const bool InbFindDetailAttributes,
const int32& InFirstValidPrimIndex,
const int32& InFirstValidVertexIndex,
const int32& InFirstValidPointIndex,
TArray<FHoudiniGenericAttribute>& OutPropertyAttributes)
{
int32 FoundCount = 0;
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::GetGenericPropertiesAttributes);

int32 FoundCount = 0;
// List all the generic property detail attributes ...
if (InbFindDetailAttributes)
{
Expand Down Expand Up @@ -6177,6 +6221,7 @@ FHoudiniEngineUtils::UpdateGenericPropertiesAttributes(
const bool bInDeferPostEditChangePropertyCalls,
const FHoudiniGenericAttribute::FFindPropertyFunctionType& InProcessFunction)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::UpdateGenericPropertiesAttributes);
if (!IsValid(InObject))
return false;

Expand Down Expand Up @@ -6942,6 +6987,8 @@ FHoudiniEngineUtils::CreateNode(
int32
FHoudiniEngineUtils::HapiGetCookCount(const HAPI_NodeId& InNodeId)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniEngineUtils::HapiGetCookCount);

// To reduce the "cost" of the call on big HDAs - limit or search to non bypassed SOP/OBJ nodes
int32 CookCount = -1;
if (HAPI_RESULT_FAILURE == FHoudiniApi::GetTotalCookCount(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ FHoudiniGeometryCollectionTranslator::SetupGeometryCollectionComponentFromOutput
const FHoudiniPackageParams& InPackageParams,
UWorld * InWorld)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FHoudiniGeometryCollectionTranslator::SetupGeometryCollectionComponentFromOutputs);

USceneComponent* ParentComponent = Cast<USceneComponent>(InOuterComponent);
if (!ParentComponent)
return;
Expand Down
Loading

0 comments on commit 18551a8

Please sign in to comment.