Files
UnrealEngineUWP/Engine/Source/Editor/VirtualizationEditor/Private/SVirtualAssetsStatistics.cpp

424 lines
12 KiB
C++
Raw Normal View History

// Copyright Epic Games, Inc. All Rights Reserved.
#include "SVirtualAssetsStatistics.h"
#include "Containers/Array.h"
#include "Containers/UnrealString.h"
#include "Delegates/Delegate.h"
#include "Fonts/SlateFontInfo.h"
#include "FrameNumberTimeEvaluator.h"
#include "Framework/Commands/UIAction.h"
#include "Framework/Notifications/NotificationManager.h"
#include "Framework/Text/TextLayout.h"
#include "HAL/PlatformCrt.h"
#include "HAL/PlatformTime.h"
#include "Internationalization/Internationalization.h"
#include "Internationalization/FastDecimalFormat.h"
#include "Layout/BasicLayoutWidgetSlot.h"
#include "Layout/Children.h"
#include "Layout/Margin.h"
Add an opt in entry to the asset context menu that allows the user to re-hydrate a virtualized package. #rb Sebastian.Nordgren #jira UE-159595 #rnx #preflight 62d13965a66919b6700c8069 ### SVirtualAssetsStatistics - We do not currently have a virtualization specific editor module and have been piggybacking onto the DDC editor module, so although this new code has nothing to do with the VA statistics panel it seems easier to keep the code in a single file and then split it later when we move it to a virtualization editor module. - At the moment if the files being hydrated are not checked out then the process will fail. Support for auto checkout will be added in a future submit. ### EditorExperimentalSettings - By default no change will be made to the context menu. The user must edit the experimental editor settings and opt in to be able to see it. - This is because the feature should not really be used in day to day workflows and is provided to either fix problems or to make it easier for people developing the virtualization system. ### PackageRehydrationProcess - Fixed some typos in error messages - Being unable to write to the package is considered an error rather than a warning. It was demoted to a warning when virtualizing to try and reduce the number of blocked submits but we do not have this problem with rehydration. - Added code to reset the loader of a package if it happens to be already loaded in the editor now that we can invoke it from the editor. [CL 21107763 by paul chipchase in ue5-main branch]
2022-07-15 06:38:07 -04:00
#include "Logging/MessageLog.h"
#include "Logging/TokenizedMessage.h"
#include "Misc/Attribute.h"
#include "Misc/Paths.h"
#include "Misc/ScopeLock.h"
#include "SlotBase.h"
#include "Styling/CoreStyle.h"
#include "Styling/SlateColor.h"
#include "Styling/StyleColors.h"
#include "Textures/SlateIcon.h"
#include "ToolMenu.h"
#include "ToolMenuDelegates.h"
#include "ToolMenuSection.h"
#include "Types/WidgetActiveTimerDelegate.h"
#include "UObject/UObjectGlobals.h"
#include "Virtualization/VirtualizationTypes.h"
#include "Widgets/Layout/SGridPanel.h"
#include "Widgets/Layout/SScrollBox.h"
#include "Widgets/Notifications/SNotificationList.h"
#include "Widgets/SBoxPanel.h"
#include "Widgets/Text/STextBlock.h"
class SWidget;
#define LOCTEXT_NAMESPACE "VirtualizationEditor"
namespace
{
FString SingleDecimalFormat(double Value)
{
const FNumberFormattingOptions NumberFormattingOptions = FNumberFormattingOptions()
.SetUseGrouping(true)
.SetMinimumFractionalDigits(1)
.SetMaximumFractionalDigits(1);
return FastDecimalFormat::NumberToString(Value, ExpressionParser::GetLocalizedNumberFormattingRules(), NumberFormattingOptions);
}
} //namespace
SVirtualAssetsStatisticsDialog::SVirtualAssetsStatisticsDialog()
{
using namespace UE::Virtualization;
Add a number of ways for the VA system to be changed to lazy initialize on first use. #rb Per.Larsson #jira UE-161296 #rnx #preflight 62fe3ce73d3fb466b229bcc0 - There are some usecases that require the VA system to initialize the first time it is accessed (usually the first time we attempt to pull a virtualized payload) rather than be initialized in the program start up. This change provides three different methods to achieve this: -- Setting the define 'UE_VIRTUALIZATION_SYSTEM_LAZY_INIT' to 1 in a programs .target.cs -- Setting [Core.ContentVirtualization]LazyInit=true in the Engine ini file -- Running with the commandline option -VA-LazyInit - If we detect that the source control backend is being initialized on a background thread we do not try to run the FConnect operation. The backend will still work but this does reduce the potential error checking on initialization. This is done because the FConnect operation currently only works on the main thread and to change this would be a bigger work item than we can schedule at the moment. - UE::Virtualization::Initialize functions now take a EInitializationFlags enum as a parameter. This enum allows the call to ignore all lazy init settings and force the initialization immediately. This is useful for programs like the Virtualization standalone tool which just needs to start the system when needed. -- The call to ::Initialize in LaunchEngineLoop passes in None and does not ignore lazy initialization. -- Calls to ::Initialize in the UnrealVirtualizationTool however all use EInitializationFlags::ForceInitialize and ignore lazy initialization settings. - Fixed an odd bug in UE::Virtualization::Initialize where the error path (if the config file cannot be found) was using a different start up code path. - Add asserts when assigning to GVirtualizationSystem to make sure that it is null. This is not 100% safe but should catch some potential threading issues, if any. - Add an assert after lazy initialization (IVirtualizationSystem::Get) to make sure that GVirtualizationSystem was assigned a valid object. - Improve how we check for legacy values in [Core.ContentVirtualization]. We now support multiple allowed values. - Added a way to poll if a VA system has been initialize yet or not, this allows us to avoid initializing a VA system if one has not yet been created and we try to: -- Dump VA profiling stats after cooking -- Send VA stats to studio analytics - Note that currently using lazy init loading will probably cause the VA statistics panel not to work, this will be fixed in future work where we will allow the panel to register for a callback when the system is initialized. [CL 21467510 by paul chipchase in ue5-main branch]
2022-08-19 19:15:42 -04:00
// TODO - need a way to make this work once the system is initialized
// Register our VA notification delegate with the event
Add a number of ways for the VA system to be changed to lazy initialize on first use. #rb Per.Larsson #jira UE-161296 #rnx #preflight 62fe3ce73d3fb466b229bcc0 - There are some usecases that require the VA system to initialize the first time it is accessed (usually the first time we attempt to pull a virtualized payload) rather than be initialized in the program start up. This change provides three different methods to achieve this: -- Setting the define 'UE_VIRTUALIZATION_SYSTEM_LAZY_INIT' to 1 in a programs .target.cs -- Setting [Core.ContentVirtualization]LazyInit=true in the Engine ini file -- Running with the commandline option -VA-LazyInit - If we detect that the source control backend is being initialized on a background thread we do not try to run the FConnect operation. The backend will still work but this does reduce the potential error checking on initialization. This is done because the FConnect operation currently only works on the main thread and to change this would be a bigger work item than we can schedule at the moment. - UE::Virtualization::Initialize functions now take a EInitializationFlags enum as a parameter. This enum allows the call to ignore all lazy init settings and force the initialization immediately. This is useful for programs like the Virtualization standalone tool which just needs to start the system when needed. -- The call to ::Initialize in LaunchEngineLoop passes in None and does not ignore lazy initialization. -- Calls to ::Initialize in the UnrealVirtualizationTool however all use EInitializationFlags::ForceInitialize and ignore lazy initialization settings. - Fixed an odd bug in UE::Virtualization::Initialize where the error path (if the config file cannot be found) was using a different start up code path. - Add asserts when assigning to GVirtualizationSystem to make sure that it is null. This is not 100% safe but should catch some potential threading issues, if any. - Add an assert after lazy initialization (IVirtualizationSystem::Get) to make sure that GVirtualizationSystem was assigned a valid object. - Improve how we check for legacy values in [Core.ContentVirtualization]. We now support multiple allowed values. - Added a way to poll if a VA system has been initialize yet or not, this allows us to avoid initializing a VA system if one has not yet been created and we try to: -- Dump VA profiling stats after cooking -- Send VA stats to studio analytics - Note that currently using lazy init loading will probably cause the VA statistics panel not to work, this will be fixed in future work where we will allow the panel to register for a callback when the system is initialized. [CL 21467510 by paul chipchase in ue5-main branch]
2022-08-19 19:15:42 -04:00
if (IVirtualizationSystem::IsInitialized())
{
IVirtualizationSystem& System = IVirtualizationSystem::Get();
System.GetNotificationEvent().AddRaw(this, &SVirtualAssetsStatisticsDialog::OnNotificationEvent);
}
}
SVirtualAssetsStatisticsDialog::~SVirtualAssetsStatisticsDialog()
{
using namespace UE::Virtualization;
// Unregister our VA notification delegate with the event
IVirtualizationSystem& System = IVirtualizationSystem::Get();
System.GetNotificationEvent().RemoveAll(this);
}
void SVirtualAssetsStatisticsDialog::OnNotificationEvent(UE::Virtualization::IVirtualizationSystem::ENotification Notification, const FIoHash& PayloadId)
{
using namespace UE::Virtualization;
FScopeLock SocpeLock(&NotificationCS);
switch (Notification)
{
case IVirtualizationSystem::ENotification::PullBegunNotification:
{
IsPulling = true;
NumPullRequests++;
break;
}
case IVirtualizationSystem::ENotification::PullEndedNotification:
{
if (IsPulling == true)
{
NumPullRequests--;
IsPulling = NumPullRequests!=0;
}
break;
}
case IVirtualizationSystem::ENotification::PullFailedNotification:
{
NumPullRequestFailures++;
break;
}
default:
break;
}
}
void SVirtualAssetsStatisticsDialog::Construct(const FArguments& InArgs)
{
this->ChildSlot
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
.Padding(0, 20, 0, 0)
.Expose(GridSlot)
[
SAssignNew(ScrollBox, SScrollBox)
.Orientation(EOrientation::Orient_Horizontal)
.ScrollBarAlwaysVisible(false)
+ SScrollBox::Slot()
[
GetGridPanel()
]
]
];
RegisterActiveTimer(0.25f, FWidgetActiveTimerDelegate::CreateSP(this, &SVirtualAssetsStatisticsDialog::UpdateGridPanels));
}
EActiveTimerReturnType SVirtualAssetsStatisticsDialog::UpdateGridPanels(double InCurrentTime, float InDeltaTime)
{
ScrollBox->ClearChildren();
ScrollBox->AddSlot()
[
GetGridPanel()
];
SlatePrepass(GetPrepassLayoutScaleMultiplier());
const float PullNotifactionTimeLimit=1.0f;
// Only show the pull notification if we have been pulling for more than a second..
if (NumPullRequests != 0)
{
PullNotificationTimer += InDeltaTime;
}
else
{
PullNotificationTimer = 0.0f;
}
if ( PullNotificationTimer>PullNotifactionTimeLimit && PullRequestNotificationItem.IsValid()==false )
{
// No existing notification or the existing one has finished
FNotificationInfo Info(LOCTEXT("PayloadSyncNotifcation", "Syncing Asset Payloads"));
Info.bFireAndForget = false;
Info.bUseLargeFont = false;
Info.bUseThrobber = false;
Info.FadeOutDuration = 0.5f;
Info.ExpireDuration = 0.0f;
PullRequestNotificationItem = FSlateNotificationManager::Get().AddNotification(Info);
if (PullRequestNotificationItem.IsValid())
{
PullRequestNotificationItem->SetCompletionState(SNotificationItem::CS_Pending);
}
}
if ( NumPullRequestFailures>0 && PullRequestFailedNotificationItem.IsValid()==false )
{
// No existing notification or the existing one has finished
FNotificationInfo Info(LOCTEXT("PayloadFailedNotifcation", "Failed to sync some Virtual Asset payloads from available backends.\nSome assets may no longer be usable.."));
Info.bFireAndForget = false;
Info.bUseLargeFont = false;
Info.bUseThrobber = false;
Info.FadeOutDuration = 0.5f;
Info.ExpireDuration = 0.0f;
Info.Image = FAppStyle::GetBrush(TEXT("MessageLog.Warning"));
Info.ButtonDetails.Add(FNotificationButtonInfo(LOCTEXT("PullFailedIgnore", "Ignore"), LOCTEXT("PullFailedIgnoreToolTip", "Ignore future warnings"), FSimpleDelegate::CreateSP(this, &SVirtualAssetsStatisticsDialog::OnWarningReasonIgnore), SNotificationItem::CS_None));
Info.ButtonDetails.Add(FNotificationButtonInfo(LOCTEXT("PullFailedOK", "Ok"), LOCTEXT("PullFailedOkToolTip", "Notify future warnings"), FSimpleDelegate::CreateSP(this, &SVirtualAssetsStatisticsDialog::OnWarningReasonOk), SNotificationItem::CS_None));
Info.HyperlinkText = LOCTEXT("PullFailed_ShowLog", "Show Message Log");
Info.Hyperlink = FSimpleDelegate::CreateStatic([]() { FMessageLog("LogVirtualization").Open(EMessageSeverity::Warning, true); });
PullRequestFailedNotificationItem = FSlateNotificationManager::Get().AddNotification(Info);
}
if ( NumPullRequests==0 && PullRequestNotificationItem.IsValid()==true )
{
PullRequestNotificationItem->SetCompletionState(SNotificationItem::CS_Success);
PullRequestNotificationItem->ExpireAndFadeout();
PullRequestNotificationItem.Reset();
}
return EActiveTimerReturnType::Continue;
}
void SVirtualAssetsStatisticsDialog::OnWarningReasonOk()
{
if (PullRequestFailedNotificationItem.IsValid() == true)
{
PullRequestFailedNotificationItem->ExpireAndFadeout();
PullRequestFailedNotificationItem.Reset();
NumPullRequestFailures = 0;
}
}
void SVirtualAssetsStatisticsDialog::OnWarningReasonIgnore()
{
if (PullRequestFailedNotificationItem.IsValid() == true)
{
PullRequestFailedNotificationItem->ExpireAndFadeout();
}
}
TSharedRef<SWidget> SVirtualAssetsStatisticsDialog::GetGridPanel()
{
using namespace UE::Virtualization;
const float RowMargin = 0.0f;
const float TitleMargin = 10.0f;
const float ColumnMargin = 10.0f;
const float BorderPadding = ColumnMargin / 2.0f;
const FMargin StdMargin(ColumnMargin, RowMargin);
const FSlateColor TitleColor = FStyleColors::AccentWhite;
const FSlateFontInfo TitleFont = FCoreStyle::GetDefaultFontStyle("Bold", 10);
FSlateColor Color = FStyleColors::Foreground;
FSlateFontInfo Font = FCoreStyle::GetDefaultFontStyle("Regular", 10);
struct FPanels
Add a number of ways for the VA system to be changed to lazy initialize on first use. #rb Per.Larsson #jira UE-161296 #rnx #preflight 62fe3ce73d3fb466b229bcc0 - There are some usecases that require the VA system to initialize the first time it is accessed (usually the first time we attempt to pull a virtualized payload) rather than be initialized in the program start up. This change provides three different methods to achieve this: -- Setting the define 'UE_VIRTUALIZATION_SYSTEM_LAZY_INIT' to 1 in a programs .target.cs -- Setting [Core.ContentVirtualization]LazyInit=true in the Engine ini file -- Running with the commandline option -VA-LazyInit - If we detect that the source control backend is being initialized on a background thread we do not try to run the FConnect operation. The backend will still work but this does reduce the potential error checking on initialization. This is done because the FConnect operation currently only works on the main thread and to change this would be a bigger work item than we can schedule at the moment. - UE::Virtualization::Initialize functions now take a EInitializationFlags enum as a parameter. This enum allows the call to ignore all lazy init settings and force the initialization immediately. This is useful for programs like the Virtualization standalone tool which just needs to start the system when needed. -- The call to ::Initialize in LaunchEngineLoop passes in None and does not ignore lazy initialization. -- Calls to ::Initialize in the UnrealVirtualizationTool however all use EInitializationFlags::ForceInitialize and ignore lazy initialization settings. - Fixed an odd bug in UE::Virtualization::Initialize where the error path (if the config file cannot be found) was using a different start up code path. - Add asserts when assigning to GVirtualizationSystem to make sure that it is null. This is not 100% safe but should catch some potential threading issues, if any. - Add an assert after lazy initialization (IVirtualizationSystem::Get) to make sure that GVirtualizationSystem was assigned a valid object. - Improve how we check for legacy values in [Core.ContentVirtualization]. We now support multiple allowed values. - Added a way to poll if a VA system has been initialize yet or not, this allows us to avoid initializing a VA system if one has not yet been created and we try to: -- Dump VA profiling stats after cooking -- Send VA stats to studio analytics - Note that currently using lazy init loading will probably cause the VA statistics panel not to work, this will be fixed in future work where we will allow the panel to register for a callback when the system is initialized. [CL 21467510 by paul chipchase in ue5-main branch]
2022-08-19 19:15:42 -04:00
{
TSharedPtr<SGridPanel> Names;
TSharedPtr<SGridPanel> Pull;
TSharedPtr<SGridPanel> Cache;
TSharedPtr<SGridPanel> Push;
Add a number of ways for the VA system to be changed to lazy initialize on first use. #rb Per.Larsson #jira UE-161296 #rnx #preflight 62fe3ce73d3fb466b229bcc0 - There are some usecases that require the VA system to initialize the first time it is accessed (usually the first time we attempt to pull a virtualized payload) rather than be initialized in the program start up. This change provides three different methods to achieve this: -- Setting the define 'UE_VIRTUALIZATION_SYSTEM_LAZY_INIT' to 1 in a programs .target.cs -- Setting [Core.ContentVirtualization]LazyInit=true in the Engine ini file -- Running with the commandline option -VA-LazyInit - If we detect that the source control backend is being initialized on a background thread we do not try to run the FConnect operation. The backend will still work but this does reduce the potential error checking on initialization. This is done because the FConnect operation currently only works on the main thread and to change this would be a bigger work item than we can schedule at the moment. - UE::Virtualization::Initialize functions now take a EInitializationFlags enum as a parameter. This enum allows the call to ignore all lazy init settings and force the initialization immediately. This is useful for programs like the Virtualization standalone tool which just needs to start the system when needed. -- The call to ::Initialize in LaunchEngineLoop passes in None and does not ignore lazy initialization. -- Calls to ::Initialize in the UnrealVirtualizationTool however all use EInitializationFlags::ForceInitialize and ignore lazy initialization settings. - Fixed an odd bug in UE::Virtualization::Initialize where the error path (if the config file cannot be found) was using a different start up code path. - Add asserts when assigning to GVirtualizationSystem to make sure that it is null. This is not 100% safe but should catch some potential threading issues, if any. - Add an assert after lazy initialization (IVirtualizationSystem::Get) to make sure that GVirtualizationSystem was assigned a valid object. - Improve how we check for legacy values in [Core.ContentVirtualization]. We now support multiple allowed values. - Added a way to poll if a VA system has been initialize yet or not, this allows us to avoid initializing a VA system if one has not yet been created and we try to: -- Dump VA profiling stats after cooking -- Send VA stats to studio analytics - Note that currently using lazy init loading will probably cause the VA statistics panel not to work, this will be fixed in future work where we will allow the panel to register for a callback when the system is initialized. [CL 21467510 by paul chipchase in ue5-main branch]
2022-08-19 19:15:42 -04:00
} Panels;
Add a number of ways for the VA system to be changed to lazy initialize on first use. #rb Per.Larsson #jira UE-161296 #rnx #preflight 62fe3ce73d3fb466b229bcc0 - There are some usecases that require the VA system to initialize the first time it is accessed (usually the first time we attempt to pull a virtualized payload) rather than be initialized in the program start up. This change provides three different methods to achieve this: -- Setting the define 'UE_VIRTUALIZATION_SYSTEM_LAZY_INIT' to 1 in a programs .target.cs -- Setting [Core.ContentVirtualization]LazyInit=true in the Engine ini file -- Running with the commandline option -VA-LazyInit - If we detect that the source control backend is being initialized on a background thread we do not try to run the FConnect operation. The backend will still work but this does reduce the potential error checking on initialization. This is done because the FConnect operation currently only works on the main thread and to change this would be a bigger work item than we can schedule at the moment. - UE::Virtualization::Initialize functions now take a EInitializationFlags enum as a parameter. This enum allows the call to ignore all lazy init settings and force the initialization immediately. This is useful for programs like the Virtualization standalone tool which just needs to start the system when needed. -- The call to ::Initialize in LaunchEngineLoop passes in None and does not ignore lazy initialization. -- Calls to ::Initialize in the UnrealVirtualizationTool however all use EInitializationFlags::ForceInitialize and ignore lazy initialization settings. - Fixed an odd bug in UE::Virtualization::Initialize where the error path (if the config file cannot be found) was using a different start up code path. - Add asserts when assigning to GVirtualizationSystem to make sure that it is null. This is not 100% safe but should catch some potential threading issues, if any. - Add an assert after lazy initialization (IVirtualizationSystem::Get) to make sure that GVirtualizationSystem was assigned a valid object. - Improve how we check for legacy values in [Core.ContentVirtualization]. We now support multiple allowed values. - Added a way to poll if a VA system has been initialize yet or not, this allows us to avoid initializing a VA system if one has not yet been created and we try to: -- Dump VA profiling stats after cooking -- Send VA stats to studio analytics - Note that currently using lazy init loading will probably cause the VA statistics panel not to work, this will be fixed in future work where we will allow the panel to register for a callback when the system is initialized. [CL 21467510 by paul chipchase in ue5-main branch]
2022-08-19 19:15:42 -04:00
// Early out if the system is disabled
if (IVirtualizationSystem::Get().IsEnabled() == false)
{
return SNew(STextBlock)
.Margin(FMargin(ColumnMargin, RowMargin))
.ColorAndOpacity(TitleColor)
.Font(TitleFont)
.Justification(ETextJustify::Center)
.Text(LOCTEXT("Disabled", "Virtual Assets Are Disabled For This Project"));
}
TSharedRef<SHorizontalBox> Panel = SNew(SHorizontalBox);
Panel->AddSlot()
.Padding(BorderPadding)
.AutoWidth()
[
SAssignNew(Panels.Names, SGridPanel)
+ SGridPanel::Slot(0, 0)
[
SNew(STextBlock)
.Margin(FMargin(ColumnMargin + (BorderPadding / 2.0f), RowMargin + (BorderPadding / 2.0f)))
.ColorAndOpacity(TitleColor)
.Font(TitleFont)
.Justification(ETextJustify::Left)
]
+SGridPanel::Slot(0, 1)
[
SNew(STextBlock)
.Margin(FMargin(ColumnMargin, RowMargin, 0.0f, TitleMargin))
.ColorAndOpacity(TitleColor)
.Font(TitleFont)
.Justification(ETextJustify::Left)
.Text(LOCTEXT("Backend", "Backend"))
]
];
Add a number of ways for the VA system to be changed to lazy initialize on first use. #rb Per.Larsson #jira UE-161296 #rnx #preflight 62fe3ce73d3fb466b229bcc0 - There are some usecases that require the VA system to initialize the first time it is accessed (usually the first time we attempt to pull a virtualized payload) rather than be initialized in the program start up. This change provides three different methods to achieve this: -- Setting the define 'UE_VIRTUALIZATION_SYSTEM_LAZY_INIT' to 1 in a programs .target.cs -- Setting [Core.ContentVirtualization]LazyInit=true in the Engine ini file -- Running with the commandline option -VA-LazyInit - If we detect that the source control backend is being initialized on a background thread we do not try to run the FConnect operation. The backend will still work but this does reduce the potential error checking on initialization. This is done because the FConnect operation currently only works on the main thread and to change this would be a bigger work item than we can schedule at the moment. - UE::Virtualization::Initialize functions now take a EInitializationFlags enum as a parameter. This enum allows the call to ignore all lazy init settings and force the initialization immediately. This is useful for programs like the Virtualization standalone tool which just needs to start the system when needed. -- The call to ::Initialize in LaunchEngineLoop passes in None and does not ignore lazy initialization. -- Calls to ::Initialize in the UnrealVirtualizationTool however all use EInitializationFlags::ForceInitialize and ignore lazy initialization settings. - Fixed an odd bug in UE::Virtualization::Initialize where the error path (if the config file cannot be found) was using a different start up code path. - Add asserts when assigning to GVirtualizationSystem to make sure that it is null. This is not 100% safe but should catch some potential threading issues, if any. - Add an assert after lazy initialization (IVirtualizationSystem::Get) to make sure that GVirtualizationSystem was assigned a valid object. - Improve how we check for legacy values in [Core.ContentVirtualization]. We now support multiple allowed values. - Added a way to poll if a VA system has been initialize yet or not, this allows us to avoid initializing a VA system if one has not yet been created and we try to: -- Dump VA profiling stats after cooking -- Send VA stats to studio analytics - Note that currently using lazy init loading will probably cause the VA statistics panel not to work, this will be fixed in future work where we will allow the panel to register for a callback when the system is initialized. [CL 21467510 by paul chipchase in ue5-main branch]
2022-08-19 19:15:42 -04:00
auto CreateGridPanels = [&](FText&& Label)
{
TSharedPtr<SGridPanel> GridPanel;
Panel->AddSlot()
.Padding(BorderPadding)
.AutoWidth()
[
SNew(SBorder)
.Padding(BorderPadding)
[
SAssignNew(GridPanel, SGridPanel)
+ SGridPanel::Slot(1, 0)
[
SNew(STextBlock)
.Margin(FMargin(ColumnMargin, RowMargin))
.ColorAndOpacity(TitleColor)
.Font(TitleFont)
.Justification(ETextJustify::Center)
.Text(MoveTemp(Label))
]
+ SGridPanel::Slot(0, 1)
[
SNew(STextBlock)
.Margin(FMargin(ColumnMargin, RowMargin, 0.0f, TitleMargin))
.ColorAndOpacity(TitleColor)
.Font(TitleFont)
.Justification(ETextJustify::Center)
.Text(LOCTEXT("Count", "Count"))
]
+ SGridPanel::Slot(1, 1)
[
SNew(STextBlock)
.Margin(FMargin(ColumnMargin, RowMargin, 0.0f, TitleMargin))
.ColorAndOpacity(TitleColor)
.Font(TitleFont)
.Justification(ETextJustify::Center)
.Text(LOCTEXT("Size", "Size (MiB)"))
]
+ SGridPanel::Slot(2, 1)
[
SNew(STextBlock)
.Margin(FMargin(ColumnMargin, RowMargin, 0.0f, TitleMargin))
.ColorAndOpacity(TitleColor)
.Font(TitleFont)
.Justification(ETextJustify::Center)
.Text(LOCTEXT("Time", "Avg (ms)"))
]
]
];
return GridPanel;
};
Panels.Pull = CreateGridPanels(LOCTEXT("Download", "Download"));
Panels.Cache = CreateGridPanels(LOCTEXT("Cache", "Cache"));
Panels.Push = CreateGridPanels(LOCTEXT("Upload", "Upload"));
int32 RowIndex = 2;
auto DisplayPayloadActivityInfo = [&StdMargin, &Color, &Font, &RowIndex, &Panels](const FString& Name, const FPayloadActivityInfo& PayloadActivityInfo)
{
Panels.Names->AddSlot(0, RowIndex)
[
SNew(STextBlock)
.Margin(StdMargin)
.ColorAndOpacity(Color)
.Font(Font)
.Justification(ETextJustify::Left)
.Text(FText::FromString(Name))
];
auto FillPanelDetails = [&StdMargin, &Color, &Font, &RowIndex](TSharedPtr<SGridPanel>& Panel, const FPayloadActivityInfo::FActivity& Activity)
{
Panel->AddSlot(0, RowIndex)
[
SNew(STextBlock)
.Margin(StdMargin)
.ColorAndOpacity(Color)
.Font(Font)
.Justification(ETextJustify::Center)
.Text(FText::FromString(FString::Printf(TEXT("%u"), Activity.PayloadCount)))
];
const double TotalBytesMiB = static_cast<double>(Activity.TotalBytes) / (1024.0 * 1024.0);
Panel->AddSlot(1, RowIndex)
[
SNew(STextBlock)
.Margin(StdMargin)
.ColorAndOpacity(Color)
.Font(Font)
.Justification(ETextJustify::Center)
.Text(FText::FromString(SingleDecimalFormat(TotalBytesMiB)))
];
const double TotalTime = static_cast<double>(FPlatformTime::ToMilliseconds64(Activity.CyclesSpent));
const double Avg = Activity.PayloadCount > 0 ? TotalTime / static_cast<double>(Activity.PayloadCount) : 0.0;
Panel->AddSlot(2, RowIndex)
[
SNew(STextBlock)
.Margin(StdMargin)
.ColorAndOpacity(Color)
.Font(Font)
.Justification(ETextJustify::Center)
.Text(FText::FromString(SingleDecimalFormat(Avg)))
];
};
FillPanelDetails(Panels.Pull, PayloadActivityInfo.Pull);
FillPanelDetails(Panels.Cache, PayloadActivityInfo.Cache);
FillPanelDetails(Panels.Push, PayloadActivityInfo.Push);
RowIndex++;
};
TArray<FBackendStats> BackendStats = IVirtualizationSystem::Get().GetBackendStatistics();
for (const FBackendStats& Stats : BackendStats)
{
DisplayPayloadActivityInfo(Stats.ConfigName, Stats.PayloadActivity);
}
FPayloadActivityInfo AccumulatedPayloadAcitvityInfo = IVirtualizationSystem::Get().GetSystemStatistics();
Color = TitleColor;
Font = TitleFont;
DisplayPayloadActivityInfo(FString("Total"), AccumulatedPayloadAcitvityInfo);
return Panel;
}
#undef LOCTEXT_NAMESPACE