void FStats::AdvanceFrame( bool bDiscardCallstack, const FOnAdvanceRenderingThreadStats& AdvanceRenderingThreadStatsDelegate /*= FOnAdvanceRenderingThreadStats()*/ ) { #if STATS check( IsInGameThread() ); static int32 MasterDisableChangeTagStartFrame = -1; FPlatformAtomics::InterlockedIncrement(&GameThreadStatsFrame); int64 Frame = GameThreadStatsFrame; if( bDiscardCallstack ) { FThreadStats::FrameDataIsIncomplete(); // we won't collect call stack stats this frame } if( MasterDisableChangeTagStartFrame == -1 ) { MasterDisableChangeTagStartFrame = FThreadStats::MasterDisableChangeTag(); } if( !FThreadStats::IsCollectingData() || MasterDisableChangeTagStartFrame != FThreadStats::MasterDisableChangeTag() ) { Frame = -GameThreadStatsFrame; // mark this as a bad frame } // Update the seconds per cycle. SET_FLOAT_STAT( STAT_SecondsPerCycle, FPlatformTime::GetSecondsPerCycle() ); static FStatNameAndInfo Adv( NAME_AdvanceFrame, "", "", TEXT( "" ), EStatDataType::ST_int64, true, false ); FThreadStats::AddMessage( Adv.GetEncodedName(), EStatOperation::AdvanceFrameEventGameThread, Frame ); // we need to flush here if we aren't collecting stats to make sure the meta data is up to date if( FPlatformProperties::IsServerOnly() ) { FThreadStats::AddMessage( Adv.GetEncodedName(), EStatOperation::AdvanceFrameEventRenderThread, Frame ); // we need to flush here if we aren't collecting stats to make sure the meta data is up to date } if( AdvanceRenderingThreadStatsDelegate.IsBound() ) { AdvanceRenderingThreadStatsDelegate.Execute( bDiscardCallstack, GameThreadStatsFrame, MasterDisableChangeTagStartFrame ); } else { // There is no rendering thread, so this message is sufficient to make stats happy and don't leak memory. FThreadStats::AddMessage( Adv.GetEncodedName(), EStatOperation::AdvanceFrameEventRenderThread, Frame ); } FThreadStats::ExplicitFlush( bDiscardCallstack ); FThreadStats::WaitForStats(); MasterDisableChangeTagStartFrame = FThreadStats::MasterDisableChangeTag(); #endif }
void FServiceConnection::Initialize( const FProfilerServiceAuthorize2& Message, const IMessageContextRef& Context ) { #if STATS ServiceAddress = Context->GetSender(); InstanceId = Message.InstanceId; CurrentData.Frame = 0; // add the supplied meta data FArrayReader ArrayReader(true); ArrayReader.Append(Message.Data); MetaData.CriticalSection = &CriticalSection; int64 Size = ArrayReader.TotalSize(); // read in the magic, at some point may need to know what it actually is uint32 Magic = 0; ArrayReader << Magic; // read in the data TArray<FStatMessage> StatMessages; { SCOPE_CYCLE_COUNTER(STAT_PC_ReadStatMessages); while(ArrayReader.Tell() < Size) { // read the message new (StatMessages) FStatMessage(Stream.ReadMessage(ArrayReader)); } static FStatNameAndInfo Adv(NAME_AdvanceFrame, "", TEXT(""), EStatDataType::ST_int64, true, false); new (StatMessages) FStatMessage(Adv.GetEncodedName(), EStatOperation::AdvanceFrameEventGameThread, 1LL, false); } // generate a thread state from the data { SCOPE_CYCLE_COUNTER(STAT_PC_AddStatMessages); CurrentThreadState.AddMessages(StatMessages); } UpdateMetaData(); #endif }