FEventGraphData::FEventGraphData( const FProfilerSession * const InProfilerSession, const uint32 InFrameIndex )
	: FrameStartIndex( InFrameIndex )
	, FrameEndIndex( InFrameIndex+1 )
{
	static FTotalTimeAndCount Current(0.0f, 0);
	PROFILER_SCOPE_LOG_TIME( TEXT( "FEventGraphData::FEventGraphData" ), &Current );

	Description = FString::Printf( TEXT("%s: %i"), *InProfilerSession->GetShortName(), InFrameIndex );

	// @TODO: Duplicate is not needed, remove it later.
	const IDataProviderRef& SessionDataProvider = InProfilerSession->GetDataProvider(); 
	const IDataProviderRef DataProvider = SessionDataProvider->Duplicate<FArrayDataProvider>( FrameStartIndex );

	const double FrameDurationMS = DataProvider->GetFrameTimeMS( 0 ); 
	const FProfilerSample& RootProfilerSample = DataProvider->GetCollection()[0];

	RootEvent = FEventGraphSample::CreateNamedEvent( FEventGraphConsts::RootEvent );

	PopulateHierarchy_Recurrent( InProfilerSession, RootEvent, RootProfilerSample, DataProvider );

	// Root sample contains FrameDurationMS
	const FProfilerStatMetaDataRef& MetaData = InProfilerSession->GetMetaData();
	RootEvent->_InclusiveTimeMS = MetaData->ConvertCyclesToMS( RootProfilerSample.GetDurationCycles() );
	RootEvent->_MaxInclusiveTimeMS = RootEvent->_MinInclusiveTimeMS = RootEvent->_AvgInclusiveTimeMS = RootEvent->_InclusiveTimeMS;
	RootEvent->_InclusiveTimePct = 100.0f;

	RootEvent->_MinNumCallsPerFrame = RootEvent->_MaxNumCallsPerFrame = RootEvent->_AvgNumCallsPerFrame = RootEvent->_NumCallsPerFrame;

	// Set root and thread event.
	RootEvent->SetRootAndThreadForAllChildren();
	// Fix all children. 
	const double MyNumFrames = 1.0;
	RootEvent->FixChildrenTimesAndCalcAveragesForAllChildren( MyNumFrames );
}
示例#2
0
FProfilerManager::FProfilerManager( const ISessionManagerRef& InSessionManager )
	: SessionManager( InSessionManager )
	, CommandList( new FUICommandList() )
	, ProfilerActionManager( this )
	, Settings()

	, ProfilerType( EProfilerSessionTypes::InvalidOrMax )
	, bLivePreview( false )
	, bHasCaptureFileFullyProcessed( false )
{
	FEventGraphSample::InitializePropertyManagement();

#if	0
	// Performance tests.
	static FTotalTimeAndCount CurrentNative(0.0f, 0);
	static FTotalTimeAndCount CurrentPointer(0.0f, 0);
	static FTotalTimeAndCount CurrentShared(0.0f, 0);

	for( int32 Lx = 0; Lx < 16; ++Lx )
	{
		FRandomStream RandomStream( 666 );
		TArray<FEventGraphSample> EventsNative;
		TArray<FEventGraphSample*> EventsPointer;
		TArray<FEventGraphSamplePtr> EventsShared;

		const int32 NumEvents = 16384;
		for( int32 Nx = 0; Nx < NumEvents; ++Nx )
		{
			const double Rnd = RandomStream.FRandRange( 0.0f, 16384.0f );
			const FString EventName = TTypeToString<double>::ToString( Rnd );
			FEventGraphSample NativeEvent( *EventName );
			NativeEvent._InclusiveTimeMS = Rnd;

			FEventGraphSamplePtr SharedEvent = FEventGraphSample::CreateNamedEvent( *EventName );
			SharedEvent->_InclusiveTimeMS = Rnd;

			EventsNative.Add(NativeEvent);
			EventsPointer.Add(SharedEvent.Get());
			EventsShared.Add(SharedEvent);
		}

		{
			FProfilerScopedLogTime ScopedLog( TEXT("1.NativeSorting"), &CurrentNative );
			EventsNative.Sort( FEventGraphSampleLess() );
		}

		{
			FProfilerScopedLogTime ScopedLog( TEXT("2PointerSorting"), &CurrentPointer );
			EventsPointer.Sort( FEventGraphSampleLess() );
		}

		{
			FProfilerScopedLogTime ScopedLog( TEXT("3.SharedSorting"), &CurrentShared );
			FEventArraySorter::Sort( EventsShared, FEventGraphSample::GetEventPropertyByIndex(EEventPropertyIndex::InclusiveTimeMS).Name, EEventCompareOps::Less );
		}
	}
#endif // 0
}
void FEventGraphData::Finalize( const uint32 InFrameStartIndex, const uint32 InFrameEndIndex )
{
	FrameStartIndex = InFrameStartIndex;
	FrameEndIndex = InFrameEndIndex;
	const double NumFrames = (double)GetNumFrames();

	// Set root and thread event.
	RootEvent->SetRootAndThreadForAllChildren();
	// Fix all children. 
	RootEvent->FixChildrenTimesAndCalcAveragesForAllChildren( NumFrames );
}
FEventGraphData::FEventGraphData( const FEventGraphData& Source ) 
	: FrameStartIndex( Source.FrameStartIndex )
	, FrameEndIndex( Source.FrameEndIndex )
{
	RootEvent = Source.GetRoot()->DuplicateWithHierarchyPtr();
	RootEvent->SetRootAndThreadForAllChildren();
}
void FEventGraphData::PopulateHierarchy_Recurrent
( 
	const FProfilerSession * const ProfilerSession,
	const FEventGraphSamplePtr ParentEvent, 
	const FProfilerSample& ParentSample, 
	const IDataProviderRef DataProvider
)
{
	const FProfilerStatMetaDataRef& MetaData = ProfilerSession->GetMetaData();

	for( int32 ChildIndex = 0; ChildIndex < ParentSample.ChildrenIndices().Num(); ChildIndex++ )
	{
		const FProfilerSample& ChildSample = DataProvider->GetCollection()[ ParentSample.ChildrenIndices()[ChildIndex] ];

		const FProfilerStat& ProfilerThread = MetaData->GetStatByID( ChildSample.ThreadID() );
		const FName& ThreadName = ProfilerThread.Name();

		const FProfilerStat& ProfilerStat = MetaData->GetStatByID( ChildSample.StatID() );
		const FName& StatName = ProfilerStat.Name();
		const FName& GroupName = ProfilerStat.OwningGroup().Name();

		FEventGraphSample* ChildEvent = new FEventGraphSample
		(
			ThreadName,	GroupName, ChildSample.StatID(), StatName, 
			MetaData->ConvertCyclesToMS( ChildSample.GetDurationCycles() ), (double)ChildSample.GetCallCount(),
			ParentEvent
		);

		FEventGraphSamplePtr ChildEventPtr = MakeShareable( ChildEvent );
		ParentEvent->AddChildPtr( ChildEventPtr );

		PopulateHierarchy_Recurrent( ProfilerSession, ChildEventPtr, ChildSample, DataProvider );	
	}
}
void FEventGraphSample::SetMaximumTimesForAllChildren()
{
	struct FCopyMaximum
	{
		void operator()( FEventGraphSample* EventPtr, FEventGraphSample* RootEvent, FEventGraphSample* ThreadEvent )
		{
			EventPtr->CopyMaximum( RootEvent, ThreadEvent );
		}
	};

	FEventGraphSamplePtr RootEvent = AsShared();
	const int32 NumChildren = _ChildrenPtr.Num();
	for (int32 ChildIndex = 0; ChildIndex < NumChildren; ++ChildIndex)
	{
		const FEventGraphSamplePtr& ThreadEvent = _ChildrenPtr[ChildIndex];
		ThreadEvent->ExecuteOperationForAllChildren( FCopyMaximum(), (FEventGraphSample*)RootEvent.Get(), (FEventGraphSample*)ThreadEvent.Get() );
	}
}
void FEventGraphSample::Combine_Recurrent( const FEventGraphSamplePtr& Other )
{
	Combine( Other );

	// Check other children.
	for( int32 ChildIndex = 0; ChildIndex < Other->_ChildrenPtr.Num(); ++ChildIndex )
	{
		const FEventGraphSamplePtr& OtherChild = Other->_ChildrenPtr[ChildIndex];
		FEventGraphSamplePtr ThisChild = FindChildPtr( OtherChild );

		if( ThisChild.IsValid() )
		{
			ThisChild->Combine_Recurrent( OtherChild );
		}
		else
		{
			AddChildAndSetParentPtr( OtherChild->DuplicateWithHierarchyPtr() );
		}
	}
}
void FEventGraphData::SetAsAverage()
{
	struct FCopyAverage
	{
		void operator()( FEventGraphSample* EventPtr, const double NumFrames )
		{
			EventPtr->CopyAverage( NumFrames );
		}
	};

	const double NumFrames = (double)GetNumFrames();
	RootEvent->ExecuteOperationForAllChildren( FCopyAverage(), NumFrames );
	Description = FString::Printf( TEXT("Average: %i"), GetNumFrames() );
}
FEventGraphSamplePtr FEventGraphSample::FindChildPtr( const FEventGraphSamplePtr& OtherChild )
{
	FEventGraphSamplePtr FoundChildPtr;
	for( int32 ChildIndex = 0; ChildIndex < _ChildrenPtr.Num(); ++ChildIndex )
	{
		const FEventGraphSamplePtr& ThisChild = _ChildrenPtr[ChildIndex];

		const bool bTheSame = OtherChild->AreTheSamePtr( ThisChild );
		if( bTheSame )
		{
			FoundChildPtr = ThisChild;
			break;
		}
	}
	return FoundChildPtr;
}
void FEventGraphSample::SetRootAndThreadForAllChildren()
{
	struct FSetRootAndThread
	{
		void operator()( FEventGraphSample* EventPtr, FEventGraphSample* RootEvent, FEventGraphSample* ThreadEvent )
		{
			EventPtr->_RootPtr = RootEvent;
			EventPtr->_ThreadPtr = ThreadEvent;
		}
	};

	FEventGraphSamplePtr RootEvent = AsShared();
	const int32 NumChildren = _ChildrenPtr.Num();
	for (int32 ChildIndex = 0; ChildIndex < NumChildren; ++ChildIndex)
	{
		const FEventGraphSamplePtr& ThreadEvent = _ChildrenPtr[ChildIndex];
		ThreadEvent->ExecuteOperationForAllChildren( FSetRootAndThread(), (FEventGraphSample*)RootEvent.Get(), (FEventGraphSample*)ThreadEvent.Get() );
	}
}
void FEventGraphData::SetAsMaximim()
{
	RootEvent->SetMaximumTimesForAllChildren();
	Description = FString::Printf( TEXT( "Maximum: %i" ), GetNumFrames() );
}
void FEventGraphData::Combine( const FEventGraphData& Other )
{
	RootEvent->Combine_Recurrent( Other.GetRoot() );
	Description = FString::Printf( TEXT("Combine: %i"), GetNumFrames() );
}