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 ); }
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() ); }