You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown Nick.Penwarden ========================== MAJOR FEATURES + CHANGES ========================== Change 3354003 on 2017/03/20 by Thomas.Sarkanen Back out changelist 3353914 Change 3355932 on 2017/03/21 by Thomas.Sarkanen Back out changelist 3354003 Reinstating merge from Main: Merging //UE4/Dev-Main to Dev-AnimPhys (//UE4/Dev-AnimPhys) @ CL 3353839 Change 3385512 on 2017/04/07 by Aaron.McLeran Bringing changes over from FN that fix audio streaming on PC/Mac/XboxOne/PS4 CL#3318457 - Fix crash when recycling PS4 sound sources. CL#3313213 - Allowing XboxOne to cook streaming audio CL#3313719 - GetWaveFormat now returns OPUS for streaming audio waves CL#3320066 - Added libopus for XboxOne CL#3320070 - libopus is now properly linked in XboxOne CL#3313219 - Allowing Mac to cook streaming audio CL#3315332 - Fixed audio streaming on Mac CL#3315335 - (additional file missed in previous CL) CL#3313207 - Sounds now register themselves with the audio streaming manager even if they are loaded before the audio device manager is created. CL#3313294 - Removed some accidental debugging code that was mistakenly added in CL#3313207 CL#3318530 - Fix threading issues in FAudioStreamingManager CL#3340718 - Fix for crash with audio streaming CL#3340844 - Fix for more thread safety in audio streaming manager CL#3343794 - Added a check in destructor of loaded chunk CL#3343794 - Removing check in stopping a source CL#3355393 - Moving audio streaming callbacks to use indices rather than ptrs to elements in dynamic array CL#3369020 - bumping up size of compressed chunks for AT9 files when doing stream chunk compression CL#3369131 - bumping up AT9 version number to get new AT9 cooks for larger chunks CL#3373626 - Fixing ps4 streaming CL#3375110 - Reverting some changes from 3373626 CL#3382078 - Making audio streaming decoding async to audio thread for xaudio2 CL#3383214 - Fixing buffer order issue for audio streaming Change 3386321 on 2017/04/10 by Lina.Halper #ANIM : preview - Attache preview mesh to use copy mesh pose #jira: UE-43114, UEAP-186 #rb: Thomas.Sarkanen Change 3386415 on 2017/04/10 by Ori.Cohen Improve the cost of UpdateKinematicBodies - added the ability to defer non simulating bodies. #JIRA UEAP-79 Change 3386418 on 2017/04/10 by Ori.Cohen Fix physx memory leak when a commandlet loads many assets without ticking scene #JIRA UE-43378 Change 3386569 on 2017/04/10 by dan.reynolds Updated dummy platform generated by standalone AEOverview tests to distinguish floor materials between the platform and the test zone. Change 3386714 on 2017/04/10 by Ori.Cohen Improve stats extensibility and expose it to the automation framework. Change 3386805 on 2017/04/10 by Lina.Halper Fix build error for editor #rb: none Change 3386854 on 2017/04/10 by Lina.Halper build fix for clang #rb:none Change 3387198 on 2017/04/10 by Aaron.McLeran #jira UE-43699 Deleting unused velocity variable. OpenAL's velocity is not supported in WebAudio. Removing dead code in AndroidAudioSource.cpp Change 3387346 on 2017/04/10 by Ori.Cohen Added performance regression map for physics (update kinematic bones and postBroadPhase) #JIRA UEAP-79 Change 3387409 on 2017/04/10 by Ori.Cohen Fix build, forgot to update this code Change 3387536 on 2017/04/10 by Lina.Halper Merging using AnimPhys-Fortnite-Main - fix preview mesh selection/animation #code review: Thomas.Sarkanen #rb: none #i_need_autocorrect Change 3387995 on 2017/04/11 by Martin.Wilson Live link updates - Refactor of provider api (separate update of hierarchy and transforms) - multi connection streaming from provider - provider maintains internal state so that new connections can be updated without interaction with streaming source. - Lifetime changes (connection timeout) Change 3388241 on 2017/04/11 by Lina.Halper Merging using AnimPhys-Fortnite-Main - merge CL of 3388238 #rb: Thomas.Sarkanen Change 3388294 on 2017/04/11 by Lina.Halper build fix #rb: none Change 3388341 on 2017/04/11 by Ori.Cohen Turn off vs2013 for physx Change 3389115 on 2017/04/11 by Ori.Cohen Forgot missing blueprint for perf test Change 3389224 on 2017/04/11 by Ori.Cohen Added sweep multi tests to perf regression #JIRA UEAP-79 Change 3389984 on 2017/04/12 by Martin.Wilson CIS Fix Change 3390315 on 2017/04/12 by Lina.Halper - fix on crash of component array when shutting down anim blueprint #jira: UE-43868 #rb: Thomas.Sarkanen Change 3390402 on 2017/04/12 by Martin.Wilson Fix update not being called on post process instances when the main anim instance does not do a parallel update #jira UE-43906 Change 3390772 on 2017/04/12 by Lina.Halper Fix crash on importing LOD with lesser # of joints #rb: Benn.Gallagher Change 3394850 on 2017/04/14 by Aaron.McLeran Adjusting how wavetable generation works for custom wavetables. - Changed wavetable creation to use a TSharedPtr vs a raw ptr. Change 3394853 on 2017/04/14 by Aaron.McLeran Bringing from Odin the ability to set the lowpass filter frequency on an audio component from BP Change 3395684 on 2017/04/17 by Ori.Cohen Make debugdraw for line traces const correct. Change 3396680 on 2017/04/17 by Ori.Cohen Added a total scene query stat and the ability to trace all scene queries Change 3397564 on 2017/04/18 by Benn.Gallagher Added clothing functional and performance test map + assets. Change 3397769 on 2017/04/18 by Thomas.Sarkanen CIS fix Fixup incorrect AudioStreaming.cpp merge when bringing Main into Dev-AnimPhys Change 3398518 on 2017/04/18 by Lina.Halper Mirroring fix on set world rotation #rb: Zak.Middleton #jira: UE-43830 Change 3400400 on 2017/04/19 by Chad.Garyet adding switch physx build to anim-phys Change 3400416 on 2017/04/19 by Chad.Garyet updated email targets to include switch Change 3402005 on 2017/04/20 by Ori.Cohen Pass stats into scene queries. Not all call sites are updated yet, waiting on Jon for uber search/replace script. Change 3402264 on 2017/04/20 by Ori.Cohen CIS fix Change 3402344 on 2017/04/20 by Ori.Cohen Turn off find unknown (was on by mistake) Change 3403311 on 2017/04/21 by Benn.Gallagher Clothing changes from Dev-General. Fixed LOD pops, mesh swap crashes and convex collision locations Change 3403399 on 2017/04/21 by Benn.Gallagher Lighting build, content cleanup and reorganization for clothing test map Change 3403401 on 2017/04/21 by Benn.Gallagher Clothing test ground truth updates after lighting build. Change 3403813 on 2017/04/21 by danny.bouimad Adding everything needed for our multiplat map TM-AnimPhys Change 3403900 on 2017/04/21 by mason.seay Added WIP text to tests that need fixup Change 3405383 on 2017/04/24 by Ori.Cohen Fix typo where complex flag was not being passed in to constructor. #JIRA UE-44278, UE-44279 Change 3405389 on 2017/04/24 by Martin.Wilson Live link: - Added support for sending curve data across live link and applying it via the Live Link node - Added pose snapshots which are built in the live link clients tick and read by the rest of the engine, save reading live data. Change 3405569 on 2017/04/24 by Martin.Wilson Missed file from CL 3405389 Change 3405810 on 2017/04/24 by Chad.Garyet fixing busted target for dev-animphys stream Change 3406566 on 2017/04/24 by Aaron.McLeran #jira UE-44272 Fixing granular synth with packaged builds - Changed the way granular synth component and wave table component get PCM data from USoundWave assets. No duplication, just precache directly. Change 3406694 on 2017/04/24 by Aaron.McLeran Update to phonon/steam audio plugin from valve Change 3407794 on 2017/04/25 by Aaron.McLeran #jira UE-44357 Fix for attenuation settings in sequencer Change 3407848 on 2017/04/25 by Jon.Nabozny Add stats to FCollisionQueryParams (continued from CL-3402005). Change 3407857 on 2017/04/25 by Jon.Nabozny Disable FIND_UNKNOWN_SCENE_QUERIES. Change 3407915 on 2017/04/25 by Lina.Halper Animation Automation Test for curve and simple notify Change 3408164 on 2017/04/25 by Ori.Cohen Expose the physx tree rebuild rate. Change 3408174 on 2017/04/25 by Lina.Halper - Changed 1, 2, 3, 4 for ordering of timing - Made sure the notify test takes more time between shots. Change 3408359 on 2017/04/25 by Jon.Nabozny Fix FConfigFile::Write for arrays of different sizes. (Looks like it is still broke for arrays of the same same, with different values). Change 3408633 on 2017/04/25 by Aaron.McLeran #jira UE-44297 Fix for animating sound cue graph when editor "non-realtime" button is checked - Fix is to explicitely register an active timer lambda that queries the preview audio component while the sound cue is playing Change 3408768 on 2017/04/25 by Aaron.McLeran Fixing UHT crash Change 3409225 on 2017/04/26 by Lina.Halper Increase tolerance for the shot test. It's very sensitive otherwise. Change 3409313 on 2017/04/26 by Benn.Gallagher Refactor of clothing paint tool framework to create a more extensible editor and get rid of some GDC techdebt Change 3409478 on 2017/04/26 by danny.bouimad Moved Text Actor forwards as it was causing zFighting Change 3409572 on 2017/04/26 by Benn.Gallagher CIS fix after cloth painter changes Change 3409585 on 2017/04/26 by danny.bouimad Updated Tm-AnimPhys to utilize the AEOverview maps, also found a crash with viewing shader complexity that only occurs on this map. Change 3410948 on 2017/04/27 by Martin.Wilson Live Link: - Add subject clearing support to client / message bus protocol - Update ref skeleton when subject changes. - Remove old classes Change 3413305 on 2017/04/28 by Danny.Bouimad Disabled audio tests on AnimPhys Testmap to hopefuly stop the lighting crashes during launch on (content problem) Change 3413408 on 2017/04/28 by mason.seay Resaving to clear empty engine version warnings Change 3413418 on 2017/04/28 by Benn.Gallagher CIS fix, #pragma once in wrong place (after an include) Change 3413737 on 2017/04/28 by Martin.Wilson Rename Live Link Message Bus messages to contain the word message to avoid future name clashes Change 3414121 on 2017/04/28 by Ori.Cohen Added task batching for physx tasks. Set fortnite to 8 as we already have a lot of thread contention during that time and it's best to just do it all in a single task. Change 3417833 on 2017/05/02 by Thomas.Sarkanen Fix bad merge in SynthComponentGranulator.cpp Change 3418174 on 2017/05/02 by Jon.Nabozny Fix memory leak in UDestructibleComponent::SetSkeletalMesh Change 3418907 on 2017/05/02 by Aaron.McLeran #jira UE-44599 Fixing active sound un-pause issue. - While paused, active sounds were updating their active playbacktime. Change 3419001 on 2017/05/02 by Ori.Cohen Added GetNumSimulatedAndAwake so that we can easily test for jitter. Change 3419079 on 2017/05/02 by Ori.Cohen Added a jitter automated test. Change 3419213 on 2017/05/02 by mason.seay Reaving content to remove empty engine version warnings Change 3419351 on 2017/05/02 by Ori.Cohen Added automated test for raycasting against landscape from underneath (JIRA UE-39819) It looks like this is currently broken Change 3419356 on 2017/05/02 by Ori.Cohen Updated test with associated JIRA where we first saw this Change 3419478 on 2017/05/02 by Ori.Cohen Added automated test for origin shift regression crash when using aggregates. Change 3420736 on 2017/05/03 by Ori.Cohen Added automated test for moving objects during an overlap callback for UE-41450 #rnx Change 3420803 on 2017/05/03 by Ori.Cohen Added automated test for JIRA UE-18019 #rnx Change 3420835 on 2017/05/03 by Jurre.deBaare Anim modifier BP for release notes Change 3421185 on 2017/05/03 by Ori.Cohen Missing file Change 3422673 on 2017/05/04 by danny.bouimad Fixed the cooked/uncooked lighting issue with AEO_StageFloor. The lights should no longer repeatidly spawn when loading in as sub levels. Change 3422898 on 2017/05/04 by Danny.Bouimad Updating QA Audio Content Change 3422908 on 2017/05/04 by Danny.Bouimad Fixing Automation CIS error 'Can't find file for asset. /Game/Tests/Physics/ISMCStaticSweep_BuiltData' Change 3423508 on 2017/05/04 by Danny.Bouimad Replacing ground truth and adding build data for nonissue Automation CIS failure OverlapCallback Change 3423634 on 2017/05/04 by danny.bouimad Made updates to TM-AnimPhys testmap Change 3423870 on 2017/05/04 by Ori.Cohen Fix wheels separating from vehicle due to world kinematic refactor. Added temp variable for now #jira UE-44624 Change 3423917 on 2017/05/04 by Ori.Cohen Assert_Equal for int returns a bool Change 3425267 on 2017/05/05 by Martin.Wilson Live Link - Add interpolation to subjects - Add connection settings that can be modified in client panel. All subjects modified by a connection use its connection settings - Give live link sources their client Guid so that they can send it with subject data Change 3425303 on 2017/05/05 by Martin.Wilson Missed file from CL 3425267 Change 3430351 on 2017/05/09 by Martin.Wilson Crash fix for live link interpolation Change 3430601 on 2017/05/09 by Benn.Gallagher Disabled clothing perf test temporarily due to stats issues Change 3432669 on 2017/05/10 by Ori.Cohen Temporarily turn off line trace under heightfield test. This is a known bug which won't be fixed until 4.17 Change 3432679 on 2017/05/10 by Ori.Cohen Temporarily turn off check during TLS release on Switch. Change 3434960 on 2017/05/11 by danny.bouimad Disabled content on TM-AnimPhys that was casuing a out of memory when drawing debug lines on switch. Change 3436639 on 2017/05/12 by Danny.Bouimad Updating ground truths and map for OverlapCallBack to fix CIS error. [CL 3437043 by Thomas Sarkanen in Main branch]
583 lines
19 KiB
C++
583 lines
19 KiB
C++
// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "AutomationBlueprintFunctionLibrary.h"
|
|
#include "HAL/IConsoleManager.h"
|
|
#include "Misc/AutomationTest.h"
|
|
#include "EngineGlobals.h"
|
|
#include "UnrealClient.h"
|
|
#include "Camera/CameraActor.h"
|
|
#include "Camera/PlayerCameraManager.h"
|
|
#include "Engine/Texture.h"
|
|
#include "Engine/GameViewportClient.h"
|
|
#include "Kismet/GameplayStatics.h"
|
|
#include "Engine/Engine.h"
|
|
#include "Tests/AutomationCommon.h"
|
|
#include "Logging/MessageLog.h"
|
|
#include "TakeScreenshotAfterTimeLatentAction.h"
|
|
#include "HighResScreenshot.h"
|
|
#include "Slate/SceneViewport.h"
|
|
#include "Tests/AutomationTestSettings.h"
|
|
#include "Slate/WidgetRenderer.h"
|
|
#include "DelayAction.h"
|
|
#include "Widgets/SViewport.h"
|
|
#include "Framework/Application/SlateApplication.h"
|
|
#include "ShaderCompiler.h"
|
|
#include "AutomationBlueprintFunctionLibrary.h"
|
|
#include "BufferVisualizationData.h"
|
|
#include "Engine/LocalPlayer.h"
|
|
#include "ContentStreaming.h"
|
|
#include "Stats/StatsData.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "Automation"
|
|
|
|
DEFINE_LOG_CATEGORY_STATIC(BlueprintAssertion, Error, Error)
|
|
DEFINE_LOG_CATEGORY_STATIC(AutomationFunctionLibrary, Log, Log)
|
|
|
|
static TAutoConsoleVariable<int32> CVarAutomationScreenshotResolutionWidth(
|
|
TEXT("AutomationScreenshotResolutionWidth"),
|
|
0,
|
|
TEXT("The width of automation screenshots."),
|
|
ECVF_Default);
|
|
|
|
static TAutoConsoleVariable<int32> CVarAutomationScreenshotResolutionHeight(
|
|
TEXT("AutomationScreenshotResolutionHeight"),
|
|
0,
|
|
TEXT("The height of automation screenshots."),
|
|
ECVF_Default);
|
|
|
|
|
|
void FinishLoadingBeforeScreenshot()
|
|
{
|
|
// Force all shader compiling to finish.
|
|
GShaderCompilingManager->FinishAllCompilation();
|
|
|
|
// Force all mip maps to load before taking the screenshot.
|
|
UTexture::ForceUpdateTextureStreaming();
|
|
|
|
IStreamingManager::Get().StreamAllResources(0.0f);
|
|
}
|
|
|
|
|
|
#if (WITH_DEV_AUTOMATION_TESTS || WITH_PERF_AUTOMATION_TESTS)
|
|
|
|
class FConsoleVariableSwapper
|
|
{
|
|
public:
|
|
FConsoleVariableSwapper(FString InConsoleVariableName)
|
|
: bModified(false)
|
|
, ConsoleVariableName(InConsoleVariableName)
|
|
{
|
|
}
|
|
|
|
void Set(int32 Value)
|
|
{
|
|
IConsoleVariable* ConsoleVariable = IConsoleManager::Get().FindConsoleVariable(*ConsoleVariableName);
|
|
if ( ensure(ConsoleVariable) )
|
|
{
|
|
if ( bModified == false )
|
|
{
|
|
bModified = true;
|
|
OriginalValue = ConsoleVariable->GetInt();
|
|
}
|
|
|
|
ConsoleVariable->Set(Value);
|
|
}
|
|
}
|
|
|
|
void Restore()
|
|
{
|
|
if ( bModified )
|
|
{
|
|
IConsoleVariable* ConsoleVariable = IConsoleManager::Get().FindConsoleVariable(*ConsoleVariableName);
|
|
if ( ensure(ConsoleVariable) )
|
|
{
|
|
ConsoleVariable->Set(OriginalValue);
|
|
}
|
|
|
|
bModified = false;
|
|
}
|
|
}
|
|
|
|
private:
|
|
bool bModified;
|
|
FString ConsoleVariableName;
|
|
|
|
int32 OriginalValue;
|
|
};
|
|
|
|
class FAutomationScreenshotTaker
|
|
{
|
|
public:
|
|
FAutomationScreenshotTaker(UWorld* InWorld, const FString& InName, FAutomationScreenshotOptions InOptions)
|
|
: World(InWorld)
|
|
, Name(InName)
|
|
, Options(InOptions)
|
|
, DefaultFeature_AntiAliasing(TEXT("r.DefaultFeature.AntiAliasing"))
|
|
, DefaultFeature_AutoExposure(TEXT("r.DefaultFeature.AutoExposure"))
|
|
, DefaultFeature_MotionBlur(TEXT("r.DefaultFeature.MotionBlur"))
|
|
, PostProcessAAQuality(TEXT("r.PostProcessAAQuality"))
|
|
, MotionBlurQuality(TEXT("r.MotionBlurQuality"))
|
|
, ScreenSpaceReflectionQuality(TEXT("r.SSR.Quality"))
|
|
, EyeAdaptationQuality(TEXT("r.EyeAdaptationQuality"))
|
|
, ContactShadows(TEXT("r.ContactShadows"))
|
|
{
|
|
GEngine->GameViewport->OnScreenshotCaptured().AddRaw(this, &FAutomationScreenshotTaker::GrabScreenShot);
|
|
|
|
check(IsInGameThread());
|
|
|
|
if ( Options.bDisableNoisyRenderingFeatures )
|
|
{
|
|
DefaultFeature_AntiAliasing.Set(0);
|
|
DefaultFeature_AutoExposure.Set(0);
|
|
DefaultFeature_MotionBlur.Set(0);
|
|
PostProcessAAQuality.Set(0);
|
|
MotionBlurQuality.Set(0);
|
|
ScreenSpaceReflectionQuality.Set(0);
|
|
EyeAdaptationQuality.Set(0);
|
|
ContactShadows.Set(0);
|
|
}
|
|
|
|
Options.SetToleranceAmounts(Options.Tolerance);
|
|
|
|
if ( UGameViewportClient* ViewportClient = GEngine->GameViewport )
|
|
{
|
|
static IConsoleVariable* ICVar = IConsoleManager::Get().FindConsoleVariable(FBufferVisualizationData::GetVisualizationTargetConsoleCommandName());
|
|
if ( ICVar )
|
|
{
|
|
if ( ViewportClient->GetEngineShowFlags() )
|
|
{
|
|
ViewportClient->GetEngineShowFlags()->SetVisualizeBuffer(InOptions.VisualizeBuffer == NAME_None ? false : true);
|
|
ViewportClient->GetEngineShowFlags()->SetTonemapper(InOptions.VisualizeBuffer == NAME_None ? true : false);
|
|
ICVar->Set(*InOptions.VisualizeBuffer.ToString());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual ~FAutomationScreenshotTaker()
|
|
{
|
|
check(IsInGameThread());
|
|
|
|
DefaultFeature_AntiAliasing.Restore();
|
|
DefaultFeature_AutoExposure.Restore();
|
|
DefaultFeature_MotionBlur.Restore();
|
|
PostProcessAAQuality.Restore();
|
|
MotionBlurQuality.Restore();
|
|
ScreenSpaceReflectionQuality.Restore();
|
|
EyeAdaptationQuality.Restore();
|
|
ContactShadows.Restore();
|
|
|
|
if ( UGameViewportClient* ViewportClient = GEngine->GameViewport )
|
|
{
|
|
static IConsoleVariable* ICVar = IConsoleManager::Get().FindConsoleVariable(FBufferVisualizationData::GetVisualizationTargetConsoleCommandName());
|
|
if ( ICVar )
|
|
{
|
|
if ( ViewportClient->GetEngineShowFlags() )
|
|
{
|
|
ViewportClient->GetEngineShowFlags()->SetVisualizeBuffer(false);
|
|
ViewportClient->GetEngineShowFlags()->SetTonemapper(true);
|
|
ICVar->Set(TEXT(""));
|
|
}
|
|
}
|
|
}
|
|
|
|
GEngine->GameViewport->OnScreenshotCaptured().RemoveAll(this);
|
|
|
|
FAutomationTestFramework::Get().NotifyScreenshotTakenAndCompared();
|
|
}
|
|
|
|
void GrabScreenShot(int32 InSizeX, int32 InSizeY, const TArray<FColor>& InImageData)
|
|
{
|
|
check(IsInGameThread());
|
|
|
|
FAutomationScreenshotData Data = AutomationCommon::BuildScreenshotData(GWorld->GetName(), Name, InSizeX, InSizeY);
|
|
|
|
// Copy the relevant data into the metadata for the screenshot.
|
|
Data.bHasComparisonRules = true;
|
|
Data.ToleranceRed = Options.ToleranceAmount.Red;
|
|
Data.ToleranceGreen = Options.ToleranceAmount.Green;
|
|
Data.ToleranceBlue = Options.ToleranceAmount.Blue;
|
|
Data.ToleranceAlpha = Options.ToleranceAmount.Alpha;
|
|
Data.ToleranceMinBrightness = Options.ToleranceAmount.MinBrightness;
|
|
Data.ToleranceMaxBrightness = Options.ToleranceAmount.MaxBrightness;
|
|
Data.bIgnoreAntiAliasing = Options.bIgnoreAntiAliasing;
|
|
Data.bIgnoreColors = Options.bIgnoreColors;
|
|
Data.MaximumLocalError = Options.MaximumLocalError;
|
|
Data.MaximumGlobalError = Options.MaximumGlobalError;
|
|
|
|
FAutomationTestFramework::Get().OnScreenshotCaptured().ExecuteIfBound(InImageData, Data);
|
|
|
|
UE_LOG(AutomationFunctionLibrary, Log, TEXT("Screenshot captured as %s"), *Data.Path);
|
|
|
|
if ( GIsAutomationTesting )
|
|
{
|
|
FAutomationTestFramework::Get().OnScreenshotCompared.AddRaw(this, &FAutomationScreenshotTaker::OnComparisonComplete);
|
|
}
|
|
else
|
|
{
|
|
delete this;
|
|
}
|
|
}
|
|
|
|
void OnComparisonComplete(bool bWasNew, bool bWasSimilar, double MaxLocalDifference, double GlobalDifference, FString ErrorMessage)
|
|
{
|
|
FAutomationTestFramework::Get().OnScreenshotCompared.RemoveAll(this);
|
|
|
|
if ( bWasNew )
|
|
{
|
|
UE_LOG(AutomationFunctionLibrary, Warning, TEXT("New Screenshot '%s' was discovered! Please add a ground truth version of it."), *Name);
|
|
}
|
|
else
|
|
{
|
|
if ( bWasSimilar )
|
|
{
|
|
UE_LOG(AutomationFunctionLibrary, Display, TEXT("Screenshot '%s' was similar! Global Difference = %f, Max Local Difference = %f"), *Name, GlobalDifference, MaxLocalDifference);
|
|
}
|
|
else
|
|
{
|
|
if ( ErrorMessage.IsEmpty() )
|
|
{
|
|
UE_LOG(AutomationFunctionLibrary, Error, TEXT("Screenshot '%s' test failed, Screnshots were different! Global Difference = %f, Max Local Difference = %f"), *Name, GlobalDifference, MaxLocalDifference);
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(AutomationFunctionLibrary, Error, TEXT("Screenshot '%s' test failed; Error = %s"), *Name, *ErrorMessage);
|
|
}
|
|
}
|
|
}
|
|
|
|
delete this;
|
|
}
|
|
|
|
private:
|
|
|
|
TWeakObjectPtr<UWorld> World;
|
|
|
|
FString Name;
|
|
FAutomationScreenshotOptions Options;
|
|
|
|
FConsoleVariableSwapper DefaultFeature_AntiAliasing;
|
|
FConsoleVariableSwapper DefaultFeature_AutoExposure;
|
|
FConsoleVariableSwapper DefaultFeature_MotionBlur;
|
|
FConsoleVariableSwapper PostProcessAAQuality;
|
|
FConsoleVariableSwapper MotionBlurQuality;
|
|
FConsoleVariableSwapper ScreenSpaceReflectionQuality;
|
|
FConsoleVariableSwapper EyeAdaptationQuality;
|
|
FConsoleVariableSwapper ContactShadows;
|
|
};
|
|
|
|
#endif
|
|
|
|
UAutomationBlueprintFunctionLibrary::UAutomationBlueprintFunctionLibrary(const class FObjectInitializer& Initializer)
|
|
: Super(Initializer)
|
|
{
|
|
}
|
|
|
|
bool UAutomationBlueprintFunctionLibrary::TakeAutomationScreenshotInternal(UObject* WorldContextObject, const FString& Name, FAutomationScreenshotOptions Options)
|
|
{
|
|
FinishLoadingBeforeScreenshot();
|
|
|
|
// Fallback resolution if all else fails for screenshots.
|
|
uint32 ResolutionX = 1280;
|
|
uint32 ResolutionY = 720;
|
|
|
|
// First get the default set for the project.
|
|
UAutomationTestSettings const* AutomationTestSettings = GetDefault<UAutomationTestSettings>();
|
|
if ( AutomationTestSettings->DefaultScreenshotResolution.GetMin() > 0 )
|
|
{
|
|
ResolutionX = (uint32)AutomationTestSettings->DefaultScreenshotResolution.X;
|
|
ResolutionY = (uint32)AutomationTestSettings->DefaultScreenshotResolution.Y;
|
|
}
|
|
|
|
// If there's an override resolution, use that instead.
|
|
if ( Options.Resolution.GetMin() > 0 )
|
|
{
|
|
ResolutionX = (uint32)Options.Resolution.X;
|
|
ResolutionY = (uint32)Options.Resolution.Y;
|
|
}
|
|
else
|
|
{
|
|
// Failing to find an override, look for a platform override that may have been provided through the
|
|
// device profiles setup, to configure the CVars for controlling the automation screenshot size.
|
|
int32 OverrideWidth = CVarAutomationScreenshotResolutionWidth.GetValueOnGameThread();
|
|
int32 OverrideHeight = CVarAutomationScreenshotResolutionHeight.GetValueOnGameThread();
|
|
|
|
if ( OverrideWidth > 0 )
|
|
{
|
|
ResolutionX = (uint32)OverrideWidth;
|
|
}
|
|
|
|
if ( OverrideHeight > 0 )
|
|
{
|
|
ResolutionY = (uint32)OverrideHeight;
|
|
}
|
|
}
|
|
|
|
#if (WITH_DEV_AUTOMATION_TESTS || WITH_PERF_AUTOMATION_TESTS)
|
|
FAutomationScreenshotTaker* TempObject = new FAutomationScreenshotTaker(WorldContextObject ? WorldContextObject->GetWorld() : nullptr, Name, Options);
|
|
#endif
|
|
|
|
//static IConsoleVariable* HighResScreenshotDelay = IConsoleManager::Get().FindConsoleVariable(TEXT("r.HighResScreenshotDelay"));
|
|
//check(HighResScreenshotDelay);
|
|
//HighResScreenshotDelay->Set(10);
|
|
|
|
if ( FPlatformProperties::HasFixedResolution() )
|
|
{
|
|
FScreenshotRequest::RequestScreenshot(false);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
FHighResScreenshotConfig& Config = GetHighResScreenshotConfig();
|
|
|
|
if ( Config.SetResolution(ResolutionX, ResolutionY, 1.0f) )
|
|
{
|
|
if ( !GEngine->GameViewport->GetGameViewport()->TakeHighResScreenShot() )
|
|
{
|
|
// If we failed to take the screenshot, we're going to need to cleanup the automation screenshot taker.
|
|
#if (WITH_DEV_AUTOMATION_TESTS || WITH_PERF_AUTOMATION_TESTS)
|
|
delete TempObject;
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
return true; //-V773
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void UAutomationBlueprintFunctionLibrary::TakeAutomationScreenshot(UObject* WorldContextObject, FLatentActionInfo LatentInfo, const FString& Name, const FAutomationScreenshotOptions& Options)
|
|
{
|
|
if ( GIsAutomationTesting )
|
|
{
|
|
if ( UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject) )
|
|
{
|
|
FLatentActionManager& LatentActionManager = World->GetLatentActionManager();
|
|
if ( LatentActionManager.FindExistingAction<FTakeScreenshotAfterTimeLatentAction>(LatentInfo.CallbackTarget, LatentInfo.UUID) == nullptr )
|
|
{
|
|
LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new FTakeScreenshotAfterTimeLatentAction(LatentInfo, Name, Options));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(AutomationFunctionLibrary, Log, TEXT("Screenshot not captured - screenshots are only taken during automation tests"));
|
|
}
|
|
}
|
|
|
|
void UAutomationBlueprintFunctionLibrary::TakeAutomationScreenshotAtCamera(UObject* WorldContextObject, FLatentActionInfo LatentInfo, ACameraActor* Camera, const FString& NameOverride, const FAutomationScreenshotOptions& Options)
|
|
{
|
|
if ( Camera == nullptr )
|
|
{
|
|
FMessageLog("PIE").Error(LOCTEXT("CameraRequired", "A camera is required to TakeAutomationScreenshotAtCamera"));
|
|
return;
|
|
}
|
|
|
|
APlayerController* PlayerController = UGameplayStatics::GetPlayerController(WorldContextObject, 0);
|
|
|
|
if ( PlayerController == nullptr )
|
|
{
|
|
FMessageLog("PIE").Error(LOCTEXT("PlayerRequired", "A player controller is required to TakeAutomationScreenshotAtCamera"));
|
|
return;
|
|
}
|
|
|
|
// Move the player, then queue up a screenshot.
|
|
// We need to delay before the screenshot so that the motion blur has time to stop.
|
|
PlayerController->SetViewTarget(Camera, FViewTargetTransitionParams());
|
|
FString ScreenshotName = Camera->GetName();
|
|
|
|
if ( !NameOverride.IsEmpty() )
|
|
{
|
|
ScreenshotName = NameOverride;
|
|
}
|
|
|
|
if ( UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject) )
|
|
{
|
|
ScreenshotName = FString::Printf(TEXT("%s_%s"), *World->GetName(), *ScreenshotName);
|
|
|
|
FLatentActionManager& LatentActionManager = World->GetLatentActionManager();
|
|
if ( LatentActionManager.FindExistingAction<FTakeScreenshotAfterTimeLatentAction>(LatentInfo.CallbackTarget, LatentInfo.UUID) == nullptr )
|
|
{
|
|
LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new FTakeScreenshotAfterTimeLatentAction(LatentInfo, ScreenshotName, Options));
|
|
}
|
|
}
|
|
}
|
|
|
|
void UAutomationBlueprintFunctionLibrary::TakeAutomationScreenshotOfUI(UObject* WorldContextObject, FLatentActionInfo LatentInfo, const FString& Name, const FAutomationScreenshotOptions& Options)
|
|
{
|
|
FinishLoadingBeforeScreenshot();
|
|
|
|
if ( UWorld* World = WorldContextObject->GetWorld() )
|
|
{
|
|
if ( UGameViewportClient* GameViewport = WorldContextObject->GetWorld()->GetGameViewport() )
|
|
{
|
|
TSharedPtr<SViewport> Viewport = GameViewport->GetGameViewportWidget();
|
|
if ( Viewport.IsValid() )
|
|
{
|
|
TArray<FColor> OutColorData;
|
|
FIntVector OutSize;
|
|
if ( FSlateApplication::Get().TakeScreenshot(Viewport.ToSharedRef(), OutColorData, OutSize) )
|
|
{
|
|
#if (WITH_DEV_AUTOMATION_TESTS || WITH_PERF_AUTOMATION_TESTS)
|
|
FAutomationScreenshotTaker* TempObject = new FAutomationScreenshotTaker(GEngine->GetWorldFromContextObject(WorldContextObject), Name, Options);
|
|
|
|
FAutomationScreenshotData Data = AutomationCommon::BuildScreenshotData(GWorld->GetName(), Name, OutSize.X, OutSize.Y);
|
|
|
|
// Copy the relevant data into the metadata for the screenshot.
|
|
Data.bHasComparisonRules = true;
|
|
Data.ToleranceRed = Options.ToleranceAmount.Red;
|
|
Data.ToleranceGreen = Options.ToleranceAmount.Green;
|
|
Data.ToleranceBlue = Options.ToleranceAmount.Blue;
|
|
Data.ToleranceAlpha = Options.ToleranceAmount.Alpha;
|
|
Data.ToleranceMinBrightness = Options.ToleranceAmount.MinBrightness;
|
|
Data.ToleranceMaxBrightness = Options.ToleranceAmount.MaxBrightness;
|
|
Data.bIgnoreAntiAliasing = Options.bIgnoreAntiAliasing;
|
|
Data.bIgnoreColors = Options.bIgnoreColors;
|
|
Data.MaximumLocalError = Options.MaximumLocalError;
|
|
Data.MaximumGlobalError = Options.MaximumGlobalError;
|
|
|
|
GEngine->GameViewport->OnScreenshotCaptured().Broadcast(OutSize.X, OutSize.Y, OutColorData);
|
|
#endif
|
|
} //-V773
|
|
|
|
FLatentActionManager& LatentActionManager = World->GetLatentActionManager();
|
|
if ( LatentActionManager.FindExistingAction<FTakeScreenshotAfterTimeLatentAction>(LatentInfo.CallbackTarget, LatentInfo.UUID) == nullptr )
|
|
{
|
|
LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, new FWaitForScreenshotComparisonLatentAction(LatentInfo));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void UAutomationBlueprintFunctionLibrary::EnableStatGroup(UObject* WorldContextObject, FName GroupName)
|
|
{
|
|
#if STATS
|
|
if (FGameThreadStatsData* StatsData = FLatestGameThreadStatsData::Get().Latest)
|
|
{
|
|
const FString GroupNameString = FString(TEXT("STATGROUP_")) + GroupName.ToString();
|
|
const FName GroupNameFull = FName(*GroupNameString, EFindName::FNAME_Find);
|
|
if(StatsData->GroupNames.Contains(GroupNameFull))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (APlayerController* TargetPC = UGameplayStatics::GetPlayerController(WorldContextObject, 0))
|
|
{
|
|
TargetPC->ConsoleCommand( FString(TEXT("stat ")) + GroupName.ToString() + FString(TEXT(" -nodisplay")), /*bWriteToLog=*/false);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void UAutomationBlueprintFunctionLibrary::DisableStatGroup(UObject* WorldContextObject, FName GroupName)
|
|
{
|
|
#if STATS
|
|
if (FGameThreadStatsData* StatsData = FLatestGameThreadStatsData::Get().Latest)
|
|
{
|
|
const FString GroupNameString = FString(TEXT("STATGROUP_")) + GroupName.ToString();
|
|
const FName GroupNameFull = FName(*GroupNameString, EFindName::FNAME_Find);
|
|
|
|
if (!StatsData->GroupNames.Contains(GroupNameFull))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (APlayerController* TargetPC = UGameplayStatics::GetPlayerController(WorldContextObject, 0))
|
|
{
|
|
TargetPC->ConsoleCommand(FString(TEXT("stat ")) + GroupName.ToString() + FString(TEXT(" -nodisplay")), /*bWriteToLog=*/false);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
template <EComplexStatField::Type ValueType, bool bCallCount = false>
|
|
float HelperGetStat(FName StatName)
|
|
{
|
|
#if STATS
|
|
if (FGameThreadStatsData* StatsData = FLatestGameThreadStatsData::Get().Latest)
|
|
{
|
|
if (const FComplexStatMessage* StatMessage = StatsData->GetStatData(StatName))
|
|
{
|
|
if(bCallCount)
|
|
{
|
|
return StatMessage->GetValue_CallCount(ValueType);
|
|
}
|
|
else
|
|
{
|
|
return FPlatformTime::ToMilliseconds(StatMessage->GetValue_Duration(ValueType));
|
|
}
|
|
}
|
|
}
|
|
|
|
#if WITH_EDITOR
|
|
FText WarningOut = FText::Format(LOCTEXT("StatNotFound", "Could not find stat data for {0}, did you call ToggleStatGroup with enough time to capture data?"), FText::FromName(StatName));
|
|
FMessageLog("PIE").Warning(WarningOut);
|
|
UE_LOG(AutomationFunctionLibrary, Warning, TEXT("%s"), *WarningOut.ToString());
|
|
#endif
|
|
|
|
#endif
|
|
|
|
return 0.f;
|
|
}
|
|
|
|
float UAutomationBlueprintFunctionLibrary::GetStatIncAverage(FName StatName)
|
|
{
|
|
return HelperGetStat<EComplexStatField::IncAve>(StatName);
|
|
}
|
|
|
|
float UAutomationBlueprintFunctionLibrary::GetStatIncMax(FName StatName)
|
|
{
|
|
|
|
return HelperGetStat<EComplexStatField::IncMax>(StatName);
|
|
}
|
|
|
|
float UAutomationBlueprintFunctionLibrary::GetStatExcAverage(FName StatName)
|
|
{
|
|
|
|
return HelperGetStat<EComplexStatField::ExcAve>(StatName);
|
|
}
|
|
|
|
float UAutomationBlueprintFunctionLibrary::GetStatExcMax(FName StatName)
|
|
{
|
|
|
|
return HelperGetStat<EComplexStatField::ExcMax>(StatName);
|
|
}
|
|
|
|
float UAutomationBlueprintFunctionLibrary::GetStatCallCount(FName StatName)
|
|
{
|
|
|
|
return HelperGetStat<EComplexStatField::IncAve, /*bCallCount=*/true>(StatName);
|
|
}
|
|
|
|
bool UAutomationBlueprintFunctionLibrary::AreAutomatedTestsRunning()
|
|
{
|
|
return GIsAutomationTesting;
|
|
}
|
|
|
|
FAutomationScreenshotOptions UAutomationBlueprintFunctionLibrary::GetDefaultScreenshotOptionsForGameplay(EComparisonTolerance Tolerance)
|
|
{
|
|
FAutomationScreenshotOptions Options;
|
|
Options.Tolerance = Tolerance;
|
|
Options.bDisableNoisyRenderingFeatures = true;
|
|
Options.bIgnoreAntiAliasing = true;
|
|
Options.SetToleranceAmounts(Tolerance);
|
|
|
|
return Options;
|
|
}
|
|
|
|
FAutomationScreenshotOptions UAutomationBlueprintFunctionLibrary::GetDefaultScreenshotOptionsForRendering(EComparisonTolerance Tolerance)
|
|
{
|
|
FAutomationScreenshotOptions Options;
|
|
Options.Tolerance = Tolerance;
|
|
Options.bDisableNoisyRenderingFeatures = true;
|
|
Options.bIgnoreAntiAliasing = true;
|
|
Options.SetToleranceAmounts(Tolerance);
|
|
|
|
return Options;
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE
|