2021-09-02 16:45:15 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "DerivedDataInformation.h"
# include "SDerivedDataStatusBar.h"
# include "DerivedDataCacheUsageStats.h"
# include "DerivedDataCacheInterface.h"
2021-10-12 21:21:22 -04:00
# include "Settings/EditorProjectSettings.h"
# include "Settings/EditorSettings.h"
2021-09-02 16:45:15 -04:00
# include "ToolMenus.h"
# define LOCTEXT_NAMESPACE "DerivedDataEditor"
2021-09-13 08:04:41 -04:00
double FDerivedDataInformation : : LastGetTime = 0 ;
double FDerivedDataInformation : : LastPutTime = 0 ;
bool FDerivedDataInformation : : bIsDownloading = false ;
bool FDerivedDataInformation : : bIsUploading = false ;
2021-10-12 21:21:22 -04:00
FText FDerivedDataInformation : : RemoteCacheWarningMessage ;
2021-09-13 08:04:41 -04:00
ERemoteCacheState FDerivedDataInformation : : RemoteCacheState = ERemoteCacheState : : Unavailable ;
2021-12-16 19:56:56 -05:00
static TArray < TSharedRef < const FDerivedDataCacheStatsNode > > GetCacheUsageStats ( )
2021-09-02 16:45:15 -04:00
{
2021-12-16 19:56:56 -05:00
PRAGMA_DISABLE_DEPRECATION_WARNINGS ;
TSharedRef < FDerivedDataCacheStatsNode > RootUsage = GetDerivedDataCacheRef ( ) . GatherUsageStats ( ) ;
PRAGMA_ENABLE_DEPRECATION_WARNINGS ;
TArray < TSharedRef < const FDerivedDataCacheStatsNode > > LeafUsageStats ;
RootUsage - > ForEachDescendant ( [ & LeafUsageStats ] ( TSharedRef < const FDerivedDataCacheStatsNode > Node )
{
if ( Node - > Children . IsEmpty ( ) )
2021-09-02 16:45:15 -04:00
{
LeafUsageStats . Add ( Node ) ;
}
2021-12-16 19:56:56 -05:00
} ) ;
return LeafUsageStats ;
}
2021-09-02 16:45:15 -04:00
2021-12-16 19:56:56 -05:00
double FDerivedDataInformation : : GetCacheActivitySizeBytes ( bool bGet , bool bLocal )
{
2021-09-02 16:45:15 -04:00
int64 TotalBytes = 0 ;
2022-01-28 06:39:14 -05:00
# if ENABLE_COOK_STATS
2021-12-16 19:56:56 -05:00
for ( const TSharedRef < const FDerivedDataCacheStatsNode > & Usage : GetCacheUsageStats ( ) )
2021-09-02 16:45:15 -04:00
{
2021-12-16 19:56:56 -05:00
if ( Usage - > IsLocal ( ) ! = bLocal )
2022-01-28 06:39:14 -05:00
{
2021-09-02 16:45:15 -04:00
continue ;
2021-12-16 19:56:56 -05:00
}
2021-09-02 16:45:15 -04:00
2022-05-31 05:11:05 -04:00
for ( const auto & KVP : Usage - > UsageStats )
2021-09-02 16:45:15 -04:00
{
const FDerivedDataCacheUsageStats & Stats = KVP . Value ;
if ( bGet )
{
TotalBytes + = Stats . GetStats . GetAccumulatedValueAnyThread ( FCookStats : : CallStats : : EHitOrMiss : : Hit , FCookStats : : CallStats : : EStatType : : Bytes ) ;
}
else
{
TotalBytes + = Stats . PutStats . GetAccumulatedValueAnyThread ( FCookStats : : CallStats : : EHitOrMiss : : Hit , FCookStats : : CallStats : : EStatType : : Bytes ) ;
}
}
}
2022-01-28 06:39:14 -05:00
# endif // ENABLE_COOK_STATS
2021-09-02 16:45:15 -04:00
return TotalBytes ;
}
double FDerivedDataInformation : : GetCacheActivityTimeSeconds ( bool bGet , bool bLocal )
{
int64 TotalCycles = 0 ;
2022-01-28 06:39:14 -05:00
# if ENABLE_COOK_STATS
2021-12-16 19:56:56 -05:00
for ( const TSharedRef < const FDerivedDataCacheStatsNode > & Usage : GetCacheUsageStats ( ) )
2021-09-02 16:45:15 -04:00
{
2021-12-16 19:56:56 -05:00
if ( Usage - > IsLocal ( ) ! = bLocal )
2022-01-28 06:39:14 -05:00
{
2021-09-02 16:45:15 -04:00
continue ;
2021-12-16 19:56:56 -05:00
}
2021-09-02 16:45:15 -04:00
2022-05-31 05:11:05 -04:00
for ( const auto & KVP : Usage - > UsageStats )
2021-09-02 16:45:15 -04:00
{
const FDerivedDataCacheUsageStats & Stats = KVP . Value ;
if ( bGet )
{
TotalCycles + =
( Stats . GetStats . GetAccumulatedValueAnyThread ( FCookStats : : CallStats : : EHitOrMiss : : Hit , FCookStats : : CallStats : : EStatType : : Cycles ) +
Stats . GetStats . GetAccumulatedValueAnyThread ( FCookStats : : CallStats : : EHitOrMiss : : Miss , FCookStats : : CallStats : : EStatType : : Cycles ) ) ;
TotalCycles + =
( Stats . PrefetchStats . GetAccumulatedValueAnyThread ( FCookStats : : CallStats : : EHitOrMiss : : Hit , FCookStats : : CallStats : : EStatType : : Cycles ) +
Stats . PrefetchStats . GetAccumulatedValueAnyThread ( FCookStats : : CallStats : : EHitOrMiss : : Miss , FCookStats : : CallStats : : EStatType : : Cycles ) ) ;
}
else
{
TotalCycles + =
( Stats . PutStats . GetAccumulatedValueAnyThread ( FCookStats : : CallStats : : EHitOrMiss : : Hit , FCookStats : : CallStats : : EStatType : : Cycles ) +
Stats . PutStats . GetAccumulatedValueAnyThread ( FCookStats : : CallStats : : EHitOrMiss : : Miss , FCookStats : : CallStats : : EStatType : : Cycles ) ) ;
}
}
}
2022-01-28 06:39:14 -05:00
# endif // ENABLE_COOK_STATS
2021-09-02 16:45:15 -04:00
return ( double ) TotalCycles * FPlatformTime : : GetSecondsPerCycle ( ) ;
}
bool FDerivedDataInformation : : GetHasRemoteCache ( )
{
2021-12-16 19:56:56 -05:00
for ( const TSharedRef < const FDerivedDataCacheStatsNode > & Usage : GetCacheUsageStats ( ) )
{
2022-01-18 19:40:08 -05:00
if ( ! Usage - > IsLocal ( ) )
{
2021-09-02 16:45:15 -04:00
return true ;
2022-01-18 19:40:08 -05:00
}
2021-09-02 16:45:15 -04:00
}
return false ;
}
2021-11-07 23:43:01 -05:00
bool FDerivedDataInformation : : GetHasZenCache ( )
{
2021-12-16 19:56:56 -05:00
for ( const TSharedRef < const FDerivedDataCacheStatsNode > & Usage : GetCacheUsageStats ( ) )
{
2022-01-18 19:40:08 -05:00
if ( Usage - > GetCacheType ( ) . Equals ( TEXT ( " Zen " ) ) )
{
2021-11-07 23:43:01 -05:00
return true ;
2022-01-18 19:40:08 -05:00
}
2021-11-07 23:43:01 -05:00
}
return false ;
}
bool FDerivedDataInformation : : GetHasHordeStorageCache ( )
{
2021-12-16 19:56:56 -05:00
for ( const TSharedRef < const FDerivedDataCacheStatsNode > & Usage : GetCacheUsageStats ( ) )
{
2022-01-18 19:40:08 -05:00
if ( Usage - > GetCacheType ( ) . Equals ( TEXT ( " Horde Storage " ) ) )
{
2021-11-07 23:43:01 -05:00
return true ;
2022-01-18 19:40:08 -05:00
}
2021-11-07 23:43:01 -05:00
}
return false ;
}
2021-09-13 08:04:41 -04:00
void FDerivedDataInformation : : UpdateRemoteCacheState ( )
{
RemoteCacheState = ERemoteCacheState : : Unavailable ;
2022-01-18 19:40:08 -05:00
if ( GetHasRemoteCache ( ) )
2021-09-13 08:04:41 -04:00
{
const double OldLastGetTime = LastGetTime ;
const double OldLastPutTime = LastPutTime ;
2021-12-16 19:56:56 -05:00
LastGetTime = FDerivedDataInformation : : GetCacheActivityTimeSeconds ( /*bGet*/ true , /*bLocal*/ false ) ;
LastPutTime = FDerivedDataInformation : : GetCacheActivityTimeSeconds ( /*bGet*/ false , /*bLocal*/ false ) ;
2021-09-13 08:04:41 -04:00
if ( OldLastGetTime ! = 0.0 & & OldLastPutTime ! = 0.0 )
{
bIsDownloading = OldLastGetTime ! = LastGetTime ;
bIsUploading = OldLastPutTime ! = LastPutTime ;
}
if ( bIsUploading | | bIsDownloading )
{
RemoteCacheState = ERemoteCacheState : : Busy ;
}
else
{
RemoteCacheState = ERemoteCacheState : : Idle ;
}
}
2021-12-16 19:56:56 -05:00
if ( const UDDCProjectSettings * DDCProjectSettings = GetDefault < UDDCProjectSettings > ( ) ; DDCProjectSettings & & DDCProjectSettings - > EnableWarnings )
2021-10-12 21:21:22 -04:00
{
2022-01-18 19:40:08 -05:00
const UEditorSettings * EditorSettings = GetDefault < UEditorSettings > ( ) ;
if ( EditorSettings & & EditorSettings - > bEnableDDCNotifications )
2021-10-12 21:21:22 -04:00
{
2022-04-28 06:28:58 -04:00
if ( DDCProjectSettings - > RecommendEveryoneUseHordeStorage & & EditorSettings - > bNotifyUseHordeStorage & & ! GetHasZenCache ( ) & & ! GetHasHordeStorageCache ( ) & & ( FCString : : Stricmp ( GetDerivedDataCache ( ) - > GetGraphName ( ) , TEXT ( " NoJupiter " ) ) ! = 0 ) )
2021-10-25 20:05:28 -04:00
{
RemoteCacheState = ERemoteCacheState : : Warning ;
2021-11-07 23:43:01 -05:00
RemoteCacheWarningMessage = FText ( LOCTEXT ( " HordeStorageWarning " , " It is recommended that you use a DDC graph that supports Horde Storage. Please check any -ddc commandline overrides. " ) ) ;
2021-10-25 20:05:28 -04:00
}
2022-01-18 19:40:08 -05:00
else if ( DDCProjectSettings - > RecommendEveryoneSetupAGlobalLocalDDCPath & & EditorSettings - > bNotifySetupDDCPath & & EditorSettings - > GlobalLocalDDCPath . Path . IsEmpty ( ) )
2021-10-25 20:05:28 -04:00
{
RemoteCacheState = ERemoteCacheState : : Warning ;
RemoteCacheWarningMessage = FText ( LOCTEXT ( " GlobalLocalDDCPathWarning " , " It is recommended that you set up a valid Global Local DDC Path " ) ) ;
}
2022-01-18 19:40:08 -05:00
else if ( DDCProjectSettings - > RecommendEveryoneSetupAGlobalSharedDDCPath & & EditorSettings - > bNotifySetupDDCPath & & EditorSettings - > GlobalSharedDDCPath . Path . IsEmpty ( ) )
2021-11-07 23:43:01 -05:00
{
RemoteCacheState = ERemoteCacheState : : Warning ;
2022-03-04 16:10:23 -05:00
RemoteCacheWarningMessage = FText ( LOCTEXT ( " GlobalSharedDDCPathWarning " , " It is recommended that you set up a valid Global Shared DDC Path " ) ) ;
2021-11-07 23:43:01 -05:00
}
2022-01-18 19:40:08 -05:00
else if ( DDCProjectSettings - > RecommendEveryoneEnableS3DDC & & EditorSettings - > bNotifyEnableS3DD & & ! EditorSettings - > bEnableS3DDC )
2021-10-25 20:05:28 -04:00
{
RemoteCacheState = ERemoteCacheState : : Warning ;
RemoteCacheWarningMessage = FText ( LOCTEXT ( " AWSS3CacheEnabledWarning " , " It is recommended that you enable the AWS S3 Cache " ) ) ;
}
2022-01-18 19:40:08 -05:00
else if ( DDCProjectSettings - > RecommendEveryoneSetupAGlobalS3DDCPath & & EditorSettings - > bNotifySetupDDCPath & & EditorSettings - > GlobalS3DDCPath . Path . IsEmpty ( ) )
2021-10-25 20:05:28 -04:00
{
RemoteCacheState = ERemoteCacheState : : Warning ;
2022-01-18 19:40:08 -05:00
RemoteCacheWarningMessage = FText ( LOCTEXT ( " S3GloblaLocalPathWarning " , " It is recommended that you set up a valid Global Local S3 DDC Path " ) ) ;
2021-10-25 20:05:28 -04:00
}
2021-10-12 21:21:22 -04:00
}
}
2021-09-13 08:04:41 -04:00
}
2021-09-16 06:12:33 -04:00
FText FDerivedDataInformation : : GetRemoteCacheStateAsText ( )
{
switch ( FDerivedDataInformation : : GetRemoteCacheState ( ) )
{
case ERemoteCacheState : : Idle :
{
2021-10-12 21:21:22 -04:00
return FText ( LOCTEXT ( " DDCStateIdle " , " Idle " ) ) ;
2021-09-16 06:12:33 -04:00
break ;
}
case ERemoteCacheState : : Busy :
{
2021-10-12 21:21:22 -04:00
return FText ( LOCTEXT ( " DDCStateBusy " , " Busy " ) ) ;
2021-09-16 06:12:33 -04:00
break ;
}
case ERemoteCacheState : : Unavailable :
{
2021-10-12 21:21:22 -04:00
return FText ( LOCTEXT ( " DDCStateUnavailable " , " Unavailable " ) ) ;
2021-09-16 06:12:33 -04:00
break ;
}
default :
case ERemoteCacheState : : Warning :
{
2021-10-12 21:21:22 -04:00
return FText ( LOCTEXT ( " DDCStateWarning " , " Warning " ) ) ;
2021-09-16 06:12:33 -04:00
break ;
}
}
}
2021-09-02 16:45:15 -04:00
# undef LOCTEXT_NAMESPACE