2016-01-07 08:17:16 -05:00
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
/*=============================================================================
RenderingThread . cpp : Rendering thread implementation .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# include "RenderCore.h"
# include "RenderingThread.h"
# include "RHI.h"
# include "TickableObjectRenderThread.h"
# include "ExceptionHandling.h"
# include "TaskGraphInterfaces.h"
2014-05-05 11:15:08 -04:00
# include "StatsData.h"
2014-03-14 14:13:41 -04:00
//
// Globals
//
RENDERCORE_API bool GIsThreadedRendering = false ;
RENDERCORE_API bool GUseThreadedRendering = false ;
2014-09-03 10:52:00 -04:00
RENDERCORE_API bool GUseRHIThread = false ;
2014-03-14 14:13:41 -04:00
# if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
RENDERCORE_API bool GMainThreadBlockedOnRenderThread = false ;
# endif // #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
2014-05-12 08:40:54 -04:00
2014-03-14 14:13:41 -04:00
static FRunnable * GRenderingThreadRunnable = NULL ;
/** If the rendering thread has been terminated by an unhandled exception, this contains the error message. */
FString GRenderingThreadError ;
/**
* Polled by the game thread to detect crashes in the rendering thread .
* If the rendering thread crashes , it sets this variable to false .
*/
volatile bool GIsRenderingThreadHealthy = true ;
/**
* Maximum rate the rendering thread will tick tickables when idle ( in Hz )
*/
float GRenderingThreadMaxIdleTickFrequency = 40.f ;
/** Function to stall the rendering thread **/
static void SuspendRendering ( )
{
FPlatformAtomics : : InterlockedIncrement ( & GIsRenderingThreadSuspended ) ;
FPlatformMisc : : MemoryBarrier ( ) ;
}
/** Function to wait and resume rendering thread **/
static void WaitAndResumeRendering ( )
{
while ( GIsRenderingThreadSuspended )
{
// Just sleep a little bit.
FPlatformProcess : : Sleep ( 0.001f ) ; //@todo this should be a more principled wait
}
2015-05-27 11:02:10 -04:00
// set the thread back to real time mode
FPlatformProcess : : SetRealTimeMode ( ) ;
2014-03-14 14:13:41 -04:00
}
/**
* Constructor that flushes and suspends the renderthread
* @ param bRecreateThread - Whether the rendering thread should be completely destroyed and recreated , or just suspended .
*/
FSuspendRenderingThread : : FSuspendRenderingThread ( bool bInRecreateThread )
{
2015-05-27 11:02:10 -04:00
// Suspend async loading thread so that it doesn't start queueing render commands
// while the render thread is suspended.
SuspendAsyncLoading ( ) ;
2014-03-14 14:13:41 -04:00
bRecreateThread = bInRecreateThread ;
bUseRenderingThread = GUseThreadedRendering ;
bWasRenderingThreadRunning = GIsThreadedRendering ;
if ( bRecreateThread )
{
StopRenderingThread ( ) ;
2015-07-14 13:03:11 -04:00
// GUseThreadedRendering should be set to false after StopRenderingThread call since
// otherwise a wrong context could be used.
GUseThreadedRendering = false ;
2014-03-14 14:13:41 -04:00
FPlatformAtomics : : InterlockedIncrement ( & GIsRenderingThreadSuspended ) ;
}
else
{
if ( GIsRenderingThreadSuspended = = 0 )
{
// First tell the render thread to finish up all pending commands and then suspend its activities.
// this ensures that async stuff will be completed too
FlushRenderingCommands ( ) ;
if ( GIsThreadedRendering )
{
2014-09-02 05:19:25 -04:00
DECLARE_CYCLE_STAT ( TEXT ( " FSimpleDelegateGraphTask.SuspendRendering " ) ,
STAT_FSimpleDelegateGraphTask_SuspendRendering ,
STATGROUP_TaskGraphTasks ) ;
2014-03-14 14:13:41 -04:00
FGraphEventRef CompleteHandle = FSimpleDelegateGraphTask : : CreateAndDispatchWhenReady (
FSimpleDelegateGraphTask : : FDelegate : : CreateStatic ( & SuspendRendering ) ,
2014-09-02 05:19:25 -04:00
GET_STATID ( STAT_FSimpleDelegateGraphTask_SuspendRendering ) , NULL , ENamedThreads : : RenderThread ) ;
2014-03-14 14:13:41 -04:00
// Busy wait while Kismet debugging, to avoid opportunistic execution of game thread tasks
// If the game thread is already executing tasks, then we have no choice but to spin
if ( GIntraFrameDebuggingGameThread | | FTaskGraphInterface : : Get ( ) . IsThreadProcessingTasks ( ENamedThreads : : GameThread ) )
{
while ( ! GIsRenderingThreadSuspended )
{
FPlatformProcess : : Sleep ( 0.0f ) ;
}
}
else
{
2015-03-04 08:31:40 -05:00
QUICK_SCOPE_CYCLE_COUNTER ( STAT_FSuspendRenderingThread ) ;
2014-03-14 14:13:41 -04:00
FTaskGraphInterface : : Get ( ) . WaitUntilTaskCompletes ( CompleteHandle , ENamedThreads : : GameThread ) ;
}
check ( GIsRenderingThreadSuspended ) ;
// Now tell the render thread to busy wait until it's resumed
2014-09-02 05:19:25 -04:00
DECLARE_CYCLE_STAT ( TEXT ( " FSimpleDelegateGraphTask.WaitAndResumeRendering " ) ,
STAT_FSimpleDelegateGraphTask_WaitAndResumeRendering ,
STATGROUP_TaskGraphTasks ) ;
2014-03-14 14:13:41 -04:00
FSimpleDelegateGraphTask : : CreateAndDispatchWhenReady (
FSimpleDelegateGraphTask : : FDelegate : : CreateStatic ( & WaitAndResumeRendering ) ,
2014-09-02 05:19:25 -04:00
GET_STATID ( STAT_FSimpleDelegateGraphTask_WaitAndResumeRendering ) , NULL , ENamedThreads : : RenderThread ) ;
2014-03-14 14:13:41 -04:00
}
else
{
SuspendRendering ( ) ;
}
}
else
{
// The render-thread is already suspended. Just bump the ref-count.
FPlatformAtomics : : InterlockedIncrement ( & GIsRenderingThreadSuspended ) ;
}
}
}
/** Destructor that starts the renderthread again */
FSuspendRenderingThread : : ~ FSuspendRenderingThread ( )
{
2014-11-24 12:51:18 -05:00
# if PLATFORM_MAC // On OS X Apple's context sharing is a strict interpretation of the spec. so a resource is only properly visible to other contexts
// in the share group after a flush. Thus we call RHIFlushResources which will flush the current context's commands to GL (but not wait for them).
ENQUEUE_UNIQUE_RENDER_COMMAND ( FlushCommand ,
RHIFlushResources ( ) ;
) ;
# endif
2014-03-14 14:13:41 -04:00
if ( bRecreateThread )
{
GUseThreadedRendering = bUseRenderingThread ;
FPlatformAtomics : : InterlockedDecrement ( & GIsRenderingThreadSuspended ) ;
if ( bUseRenderingThread & & bWasRenderingThreadRunning )
{
StartRenderingThread ( ) ;
// Now tell the render thread to set it self to real time mode
2014-09-02 05:19:25 -04:00
DECLARE_CYCLE_STAT ( TEXT ( " FSimpleDelegateGraphTask.SetRealTimeMode " ) ,
STAT_FSimpleDelegateGraphTask_SetRealTimeMode ,
STATGROUP_TaskGraphTasks ) ;
2014-03-14 14:13:41 -04:00
FSimpleDelegateGraphTask : : CreateAndDispatchWhenReady (
FSimpleDelegateGraphTask : : FDelegate : : CreateStatic ( & FPlatformProcess : : SetRealTimeMode ) ,
2014-09-02 05:19:25 -04:00
GET_STATID ( STAT_FSimpleDelegateGraphTask_SetRealTimeMode ) , NULL , ENamedThreads : : RenderThread
) ;
2014-03-14 14:13:41 -04:00
}
}
else
{
// Resume the render thread again.
FPlatformAtomics : : InterlockedDecrement ( & GIsRenderingThreadSuspended ) ;
}
2015-05-27 11:02:10 -04:00
ResumeAsyncLoading ( ) ;
2014-03-14 14:13:41 -04:00
}
/**
* Tick all rendering thread tickable objects
*/
/** Static array of tickable objects that are ticked from rendering thread*/
FTickableObjectRenderThread : : FRenderingThreadTickableObjectsArray FTickableObjectRenderThread : : RenderingThreadTickableObjects ;
2015-06-15 16:35:54 -04:00
FTickableObjectRenderThread : : FRenderingThreadTickableObjectsArray FTickableObjectRenderThread : : RenderingThreadHighFrequencyTickableObjects ;
void TickHighFrequencyTickables ( double CurTime )
{
static double LastHighFreqTime = FPlatformTime : : Seconds ( ) ;
float DeltaSecondsHighFreq = CurTime - LastHighFreqTime ;
// tick any high frequency rendering thread tickables.
for ( int32 ObjectIndex = 0 ; ObjectIndex < FTickableObjectRenderThread : : RenderingThreadHighFrequencyTickableObjects . Num ( ) ; ObjectIndex + + )
{
FTickableObjectRenderThread * TickableObject = FTickableObjectRenderThread : : RenderingThreadHighFrequencyTickableObjects [ ObjectIndex ] ;
// make sure it wants to be ticked and the rendering thread isn't suspended
if ( TickableObject - > IsTickable ( ) )
{
STAT ( FScopeCycleCounter ( TickableObject - > GetStatId ( ) ) ; )
TickableObject - > Tick ( DeltaSecondsHighFreq ) ;
}
}
LastHighFreqTime = CurTime ;
}
2014-03-14 14:13:41 -04:00
void TickRenderingTickables ( )
{
static double LastTickTime = FPlatformTime : : Seconds ( ) ;
2015-06-15 16:35:54 -04:00
2014-03-14 14:13:41 -04:00
// calc how long has passed since last tick
double CurTime = FPlatformTime : : Seconds ( ) ;
float DeltaSeconds = CurTime - LastTickTime ;
2015-06-15 16:35:54 -04:00
TickHighFrequencyTickables ( CurTime ) ;
2014-03-14 14:13:41 -04:00
if ( DeltaSeconds < ( 1.f / GRenderingThreadMaxIdleTickFrequency ) )
{
return ;
}
2014-05-12 08:40:54 -04:00
2014-03-14 14:13:41 -04:00
// tick any rendering thread tickables
for ( int32 ObjectIndex = 0 ; ObjectIndex < FTickableObjectRenderThread : : RenderingThreadTickableObjects . Num ( ) ; ObjectIndex + + )
{
FTickableObjectRenderThread * TickableObject = FTickableObjectRenderThread : : RenderingThreadTickableObjects [ ObjectIndex ] ;
// make sure it wants to be ticked and the rendering thread isn't suspended
if ( TickableObject - > IsTickable ( ) )
{
STAT ( FScopeCycleCounter ( TickableObject - > GetStatId ( ) ) ; )
TickableObject - > Tick ( DeltaSeconds ) ;
}
}
// update the last time we ticked
LastTickTime = CurTime ;
}
/** Accumulates how many cycles the renderthread has been idle. It's defined in RenderingThread.cpp. */
uint32 GRenderThreadIdle [ ERenderThreadIdleTypes : : Num ] = { 0 } ;
/** Accumulates how times renderthread was idle. It's defined in RenderingThread.cpp. */
uint32 GRenderThreadNumIdle [ ERenderThreadIdleTypes : : Num ] = { 0 } ;
/** How many cycles the renderthread used (excluding idle time). It's set once per frame in FViewport::Draw. */
uint32 GRenderThreadTime = 0 ;
2014-09-03 10:52:00 -04:00
/** The RHI thread runnable object. */
class FRHIThread : public FRunnable
{
public :
FRunnableThread * Thread ;
FRHIThread ( )
: Thread ( nullptr )
{
check ( IsInGameThread ( ) ) ;
}
virtual uint32 Run ( )
{
FTaskGraphInterface : : Get ( ) . AttachToThread ( ENamedThreads : : RHIThread ) ;
FTaskGraphInterface : : Get ( ) . ProcessThreadUntilRequestReturn ( ENamedThreads : : RHIThread ) ;
return 0 ;
}
static FRHIThread & Get ( )
{
static FRHIThread Singleton ;
return Singleton ;
}
void Start ( )
{
Thread = FRunnableThread : : Create ( this , TEXT ( " RHIThread " ) , 512 * 1024 , TPri_Normal ,
2015-01-22 11:26:35 -05:00
FPlatformAffinity : : GetRHIThreadMask ( )
2014-09-03 10:52:00 -04:00
) ;
check ( Thread ) ;
}
} ;
2014-03-14 14:13:41 -04:00
/** The rendering thread main loop */
void RenderingThreadMain ( FEvent * TaskGraphBoundSyncEvent )
{
ENamedThreads : : RenderThread = ENamedThreads : : Type ( ENamedThreads : : ActualRenderingThread ) ;
ENamedThreads : : RenderThread_Local = ENamedThreads : : Type ( ENamedThreads : : ActualRenderingThread_Local ) ;
FTaskGraphInterface : : Get ( ) . AttachToThread ( ENamedThreads : : RenderThread ) ;
FPlatformMisc : : MemoryBarrier ( ) ;
// Inform main thread that the render thread has been attached to the taskgraph and is ready to receive tasks
if ( TaskGraphBoundSyncEvent ! = NULL )
{
TaskGraphBoundSyncEvent - > Trigger ( ) ;
}
2014-04-23 20:08:25 -04:00
// set the thread back to real time mode
FPlatformProcess : : SetRealTimeMode ( ) ;
2014-10-27 07:55:33 -04:00
# if STATS
if ( FThreadStats : : WillEverCollectData ( ) )
{
FThreadStats : : ExplicitFlush ( ) ; // flush the stats and set update the scope so we don't flush again until a frame update, this helps prevent fragmentation
}
# endif
2014-03-14 14:13:41 -04:00
check ( GIsThreadedRendering ) ;
FTaskGraphInterface : : Get ( ) . ProcessThreadUntilRequestReturn ( ENamedThreads : : RenderThread ) ;
FPlatformMisc : : MemoryBarrier ( ) ;
check ( ! GIsThreadedRendering ) ;
2015-08-12 18:33:47 -04:00
# if STATS
if ( FThreadStats : : WillEverCollectData ( ) )
{
FThreadStats : : ExplicitFlush ( ) ; // Another explicit flush to clean up the ScopeCount established above for any stats lingering since the last frame
}
# endif
2014-03-14 14:13:41 -04:00
ENamedThreads : : RenderThread = ENamedThreads : : GameThread ;
ENamedThreads : : RenderThread_Local = ENamedThreads : : GameThread_Local ;
FPlatformMisc : : MemoryBarrier ( ) ;
}
/**
* Advances stats for the rendering thread .
*/
2014-06-12 12:09:36 -04:00
static void AdvanceRenderingThreadStats ( int64 StatsFrame , int32 MasterDisableChangeTagStartFrame )
2014-03-14 14:13:41 -04:00
{
# if STATS
int64 Frame = StatsFrame ;
if ( ! FThreadStats : : IsCollectingData ( ) | | MasterDisableChangeTagStartFrame ! = FThreadStats : : MasterDisableChangeTag ( ) )
{
Frame = - StatsFrame ; // mark this as a bad frame
}
2015-11-18 16:20:49 -05:00
FThreadStats : : AddMessage ( FStatConstants : : AdvanceFrame . GetEncodedName ( ) , EStatOperation : : AdvanceFrameEventRenderThread , Frame ) ;
2014-03-14 14:13:41 -04:00
if ( IsInActualRenderingThread ( ) )
{
FThreadStats : : ExplicitFlush ( ) ;
}
# endif
}
2014-06-12 12:09:36 -04:00
/**
* Advances stats for the rendering thread . Called from the game thread .
*/
void AdvanceRenderingThreadStatsGT ( bool bDiscardCallstack , int64 StatsFrame , int32 MasterDisableChangeTagStartFrame )
{
ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER
(
RenderingThreadTickCommand ,
int64 , SentStatsFrame , StatsFrame ,
int32 , SentMasterDisableChangeTagStartFrame , MasterDisableChangeTagStartFrame ,
{
AdvanceRenderingThreadStats ( SentStatsFrame , SentMasterDisableChangeTagStartFrame ) ;
}
) ;
if ( bDiscardCallstack )
{
// we need to flush the rendering thread here, otherwise it can get behind and then the stats will get behind.
FlushRenderingCommands ( ) ;
}
}
2014-03-14 14:13:41 -04:00
/** The rendering thread runnable object. */
class FRenderingThread : public FRunnable
{
public :
/**
* Sync event to make sure that render thread is bound to the task graph before main thread queues work against it .
*/
FEvent * TaskGraphBoundSyncEvent ;
2015-03-24 07:29:32 -04:00
FRenderingThread ( )
2014-03-14 14:13:41 -04:00
{
2015-01-28 07:31:10 -05:00
TaskGraphBoundSyncEvent = FPlatformProcess : : GetSynchEventFromPool ( true ) ;
2014-03-14 14:13:41 -04:00
RHIFlushResources ( ) ;
}
2015-01-28 07:31:10 -05:00
virtual ~ FRenderingThread ( )
{
FPlatformProcess : : ReturnSynchEventToPool ( TaskGraphBoundSyncEvent ) ;
TaskGraphBoundSyncEvent = nullptr ;
}
2014-03-14 14:13:41 -04:00
// FRunnable interface.
2015-03-24 07:29:32 -04:00
virtual bool Init ( void ) override
2014-03-14 14:13:41 -04:00
{
2014-11-13 12:59:53 -05:00
GRenderThreadId = FPlatformTLS : : GetCurrentThreadId ( ) ;
2014-03-14 14:13:41 -04:00
// Acquire rendering context ownership on the current thread
RHIAcquireThreadOwnership ( ) ;
return true ;
}
2015-03-24 07:29:32 -04:00
virtual void Exit ( void ) override
2014-03-14 14:13:41 -04:00
{
// Release rendering context ownership on the current thread
RHIReleaseThreadOwnership ( ) ;
2014-11-13 12:59:53 -05:00
GRenderThreadId = 0 ;
2014-03-14 14:13:41 -04:00
}
Copying //UE4/Orion-Staging to //UE4/Main (Origin: //Orion/Dev-General @2826496)
#lockdown Nick.Penwarden
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2826201 on 2016/01/13 by Zabir.Hoque
Add more verbose logging to try to understand #OR-11297
#lockdown Andrew.Grant
#CodeReview Marcus.Wassmer
#RB none
#TESTS compiled Win64 debug editor, ran agora_p
Change 2826170 on 2016/01/13 by Marcus.Wassmer
Flush unloaded resource properly in LoadMap
#codereview Gil.Gribb
#rb none
#test cycling game. memory is freed properly now.
#lockdown Andrew.Grant
Change 2826135 on 2016/01/12 by Michael.Noland
Orion: Improve login screen on PC to reduce the potential impact of framerate on data center ping calculation
- Disabled async streaming for the duration of the QOS ping measurement to avoid hitches
- Added a circular throbber in the top left corner of the login screen indicating that something is async streaming (as a diagnostic tool for users affected by the datacenter ping, can be removed in the future)
- Added logging of the current average frame time when the datacenter ping is finalized
- Added a 'Pick Ideal Settings' button to the login screen (note: on the actual screen, not the login widget, so it will not appear on PS4)
#jira OR-12453
#rb paul.moore
#tests Ran a QOS server and client and verified that the new logging is occurring, tried out the new benchmark button, etc...
Merging CL# 2826128 using //Orion/Main_to_//Orion/Dev-General
Change 2826131 on 2016/01/12 by Michael.Noland
#UE4 - added print out of MS/FPS during Qos ping evaluation
#rb michael.noland
#tests loaded up through login screen to see output
Merging CL# 2825678 using //Orion/Main_to_//Orion/Dev-General
Change 2826128 on 2016/01/12 by Michael.Noland
Orion: Improve login screen on PC to reduce the potential impact of framerate on data center ping calculation
- Disabled async streaming for the duration of the QOS ping measurement to avoid hitches
- Added a circular throbber in the top left corner of the login screen indicating that something is async streaming (as a diagnostic tool for users affected by the datacenter ping, can be removed in the future)
- Added logging of the current average frame time when the datacenter ping is finalized
- Added a 'Pick Ideal Settings' button to the login screen (note: on the actual screen, not the login widget, so it will not appear on PS4)
#jira OR-12453
#rb paul.moore
#tests Ran a QOS server and client and verified that the new logging is occurring, tried out the new benchmark button, etc...
Merging CL# 2826116 using //Orion/Release-Next->//Orion/Main
Change 2826116 on 2016/01/12 by Michael.Noland
Orion: Improve login screen on PC to reduce the potential impact of framerate on data center ping calculation
- Disabled async streaming for the duration of the QOS ping measurement to avoid hitches
- Added a circular throbber in the top left corner of the login screen indicating that something is async streaming (as a diagnostic tool for users affected by the datacenter ping, can be removed in the future)
- Added logging of the current average frame time when the datacenter ping is finalized
- Added a 'Pick Ideal Settings' button to the login screen (note: on the actual screen, not the login widget, so it will not appear on PS4)
#jira OR-12453
#rb paul.moore
#tests Ran a QOS server and client and verified that the new logging is occurring, tried out the new benchmark button, etc...
#lockdown andrew.grant
#codereview josh.markiewicz
Change 2825772 on 2016/01/12 by Dmitry.Rekman
Linux signal handling improvements.
- Switch crash handlers to use "crash malloc" (preallocated memory) on crash.
- Remove unnecessary memory allocations from graceful termination handler.
#rb none
#tests Run the Linux server and crashed it a few times.
#codereview David.Vossel, Michael.Trepka
Change 2825768 on 2016/01/12 by Josh.Markiewicz
#UE4 - added print out of MS/FPS during Qos ping evaluation
#rb michael.noland
#tests loaded up through login screen to see output
Change 2825703 on 2016/01/12 by Brian.Karis
Switched on new motion blur. Set temporal AA sharpness to 1.
#rb none
#TESTS editor
Change 2825689 on 2016/01/12 by Lina.Halper
Fix for get animation notify crash
https://jira.ol.epicgames.net/browse/OR-12248
https://jira.ol.epicgames.net/browse/OR-12348
- Also fixed the crash in preview of persona due to blend sample cache contains previous animation data
- Also fixed blend space player to reinitialize cache data
- The main issue is marker doesn't clamp the length, causing notifies ensure to trigger.
#rb : Laurent.Delayen
#tests: 10 Sparrows bot match for long time
#code review: Martin.Wilson
#lockdown: Andrew.Grant
Change 2825680 on 2016/01/12 by Martin.Mittring
fixed all cases with r.Tonemapper.ScreenPercentage, ScreenPercentage, Fringe, Vignette, ViewRect, flickering with transluceny (View members have been modified while other thread was reading)
#rb:Olaf.Piesche, David.Hill
#test: PC, many cases
Change 2825579 on 2016/01/12 by Chris.Bunner
Force shadow shape bone indices on the required update list.
#rb Lina.Halper, Rolando.Caloca
#tests Editor
#codereview Daniel.Wright
#jira OR-12339
Change 2825443 on 2016/01/12 by Martin.Mittring
2016-01-14 08:11:47 -05:00
# if PLATFORM_WINDOWS && !PLATFORM_SEH_EXCEPTIONS_DISABLED
static int32 FlushRHILogsAndReportCrash ( LPEXCEPTION_POINTERS ExceptionInfo )
{
if ( GDynamicRHI )
{
GDynamicRHI - > FlushPendingLogs ( ) ;
}
return ReportCrash ( ExceptionInfo ) ;
}
# endif
2015-03-24 07:29:32 -04:00
virtual uint32 Run ( void ) override
2014-03-14 14:13:41 -04:00
{
2014-06-17 18:27:26 -04:00
FPlatformProcess : : SetupGameOrRenderThread ( true ) ;
2014-03-14 14:13:41 -04:00
# if PLATFORM_WINDOWS
if ( ! FPlatformMisc : : IsDebuggerPresent ( ) | | GAlwaysReportCrash )
{
# if !PLATFORM_SEH_EXCEPTIONS_DISABLED
__try
# endif
{
RenderingThreadMain ( TaskGraphBoundSyncEvent ) ;
}
# if !PLATFORM_SEH_EXCEPTIONS_DISABLED
Copying //UE4/Orion-Staging to //UE4/Main (Origin: //Orion/Dev-General @2826496)
#lockdown Nick.Penwarden
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2826201 on 2016/01/13 by Zabir.Hoque
Add more verbose logging to try to understand #OR-11297
#lockdown Andrew.Grant
#CodeReview Marcus.Wassmer
#RB none
#TESTS compiled Win64 debug editor, ran agora_p
Change 2826170 on 2016/01/13 by Marcus.Wassmer
Flush unloaded resource properly in LoadMap
#codereview Gil.Gribb
#rb none
#test cycling game. memory is freed properly now.
#lockdown Andrew.Grant
Change 2826135 on 2016/01/12 by Michael.Noland
Orion: Improve login screen on PC to reduce the potential impact of framerate on data center ping calculation
- Disabled async streaming for the duration of the QOS ping measurement to avoid hitches
- Added a circular throbber in the top left corner of the login screen indicating that something is async streaming (as a diagnostic tool for users affected by the datacenter ping, can be removed in the future)
- Added logging of the current average frame time when the datacenter ping is finalized
- Added a 'Pick Ideal Settings' button to the login screen (note: on the actual screen, not the login widget, so it will not appear on PS4)
#jira OR-12453
#rb paul.moore
#tests Ran a QOS server and client and verified that the new logging is occurring, tried out the new benchmark button, etc...
Merging CL# 2826128 using //Orion/Main_to_//Orion/Dev-General
Change 2826131 on 2016/01/12 by Michael.Noland
#UE4 - added print out of MS/FPS during Qos ping evaluation
#rb michael.noland
#tests loaded up through login screen to see output
Merging CL# 2825678 using //Orion/Main_to_//Orion/Dev-General
Change 2826128 on 2016/01/12 by Michael.Noland
Orion: Improve login screen on PC to reduce the potential impact of framerate on data center ping calculation
- Disabled async streaming for the duration of the QOS ping measurement to avoid hitches
- Added a circular throbber in the top left corner of the login screen indicating that something is async streaming (as a diagnostic tool for users affected by the datacenter ping, can be removed in the future)
- Added logging of the current average frame time when the datacenter ping is finalized
- Added a 'Pick Ideal Settings' button to the login screen (note: on the actual screen, not the login widget, so it will not appear on PS4)
#jira OR-12453
#rb paul.moore
#tests Ran a QOS server and client and verified that the new logging is occurring, tried out the new benchmark button, etc...
Merging CL# 2826116 using //Orion/Release-Next->//Orion/Main
Change 2826116 on 2016/01/12 by Michael.Noland
Orion: Improve login screen on PC to reduce the potential impact of framerate on data center ping calculation
- Disabled async streaming for the duration of the QOS ping measurement to avoid hitches
- Added a circular throbber in the top left corner of the login screen indicating that something is async streaming (as a diagnostic tool for users affected by the datacenter ping, can be removed in the future)
- Added logging of the current average frame time when the datacenter ping is finalized
- Added a 'Pick Ideal Settings' button to the login screen (note: on the actual screen, not the login widget, so it will not appear on PS4)
#jira OR-12453
#rb paul.moore
#tests Ran a QOS server and client and verified that the new logging is occurring, tried out the new benchmark button, etc...
#lockdown andrew.grant
#codereview josh.markiewicz
Change 2825772 on 2016/01/12 by Dmitry.Rekman
Linux signal handling improvements.
- Switch crash handlers to use "crash malloc" (preallocated memory) on crash.
- Remove unnecessary memory allocations from graceful termination handler.
#rb none
#tests Run the Linux server and crashed it a few times.
#codereview David.Vossel, Michael.Trepka
Change 2825768 on 2016/01/12 by Josh.Markiewicz
#UE4 - added print out of MS/FPS during Qos ping evaluation
#rb michael.noland
#tests loaded up through login screen to see output
Change 2825703 on 2016/01/12 by Brian.Karis
Switched on new motion blur. Set temporal AA sharpness to 1.
#rb none
#TESTS editor
Change 2825689 on 2016/01/12 by Lina.Halper
Fix for get animation notify crash
https://jira.ol.epicgames.net/browse/OR-12248
https://jira.ol.epicgames.net/browse/OR-12348
- Also fixed the crash in preview of persona due to blend sample cache contains previous animation data
- Also fixed blend space player to reinitialize cache data
- The main issue is marker doesn't clamp the length, causing notifies ensure to trigger.
#rb : Laurent.Delayen
#tests: 10 Sparrows bot match for long time
#code review: Martin.Wilson
#lockdown: Andrew.Grant
Change 2825680 on 2016/01/12 by Martin.Mittring
fixed all cases with r.Tonemapper.ScreenPercentage, ScreenPercentage, Fringe, Vignette, ViewRect, flickering with transluceny (View members have been modified while other thread was reading)
#rb:Olaf.Piesche, David.Hill
#test: PC, many cases
Change 2825579 on 2016/01/12 by Chris.Bunner
Force shadow shape bone indices on the required update list.
#rb Lina.Halper, Rolando.Caloca
#tests Editor
#codereview Daniel.Wright
#jira OR-12339
Change 2825443 on 2016/01/12 by Martin.Mittring
2016-01-14 08:11:47 -05:00
__except ( FlushRHILogsAndReportCrash ( GetExceptionInformation ( ) ) )
2014-03-14 14:13:41 -04:00
{
GRenderingThreadError = GErrorHist ;
// Use a memory barrier to ensure that the game thread sees the write to GRenderingThreadError before
// the write to GIsRenderingThreadHealthy.
FPlatformMisc : : MemoryBarrier ( ) ;
GIsRenderingThreadHealthy = false ;
}
# endif
}
else
# endif // PLATFORM_WINDOWS
{
RenderingThreadMain ( TaskGraphBoundSyncEvent ) ;
}
return 0 ;
}
} ;
/**
* If the rendering thread is in its idle loop ( which ticks rendering tickables
*/
volatile bool GRunRenderingThreadHeartbeat = false ;
/** The rendering thread heartbeat runnable object. */
class FRenderingThreadTickHeartbeat : public FRunnable
{
public :
// FRunnable interface.
virtual bool Init ( void )
{
return true ;
}
virtual void Exit ( void )
{
}
virtual void Stop ( void )
{
}
virtual uint32 Run ( void )
{
while ( GRunRenderingThreadHeartbeat )
{
FPlatformProcess : : Sleep ( 1.f / ( 4.0f * GRenderingThreadMaxIdleTickFrequency ) ) ;
if ( ! GIsRenderingThreadSuspended )
{
ENQUEUE_UNIQUE_RENDER_COMMAND (
HeartbeatTickTickables ,
{
// make sure that rendering thread tickables get a chance to tick, even if the render thread is starving
if ( ! GIsRenderingThreadSuspended )
{
TickRenderingTickables ( ) ;
}
} ) ;
}
}
return 0 ;
}
} ;
FRunnableThread * GRenderingThreadHeartbeat = NULL ;
FRunnable * GRenderingThreadRunnableHeartbeat = NULL ;
// not done in the CVar system as we don't access to render thread specifics there
struct FConsoleRenderThreadPropagation : public IConsoleThreadPropagation
{
virtual void OnCVarChange ( int32 & Dest , int32 NewValue )
{
ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER (
OnCVarChange1 ,
int32 & , Dest , Dest ,
int32 , NewValue , NewValue ,
{
Dest = NewValue ;
} ) ;
}
virtual void OnCVarChange ( float & Dest , float NewValue )
{
ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER (
OnCVarChange2 ,
float & , Dest , Dest ,
float , NewValue , NewValue ,
{
Dest = NewValue ;
} ) ;
}
virtual void OnCVarChange ( FString & Dest , const FString & NewValue )
{
ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER (
OnCVarChange3 ,
FString & , Dest , Dest ,
const FString & , NewValue , NewValue ,
{
Dest = NewValue ;
} ) ;
}
static FConsoleRenderThreadPropagation & GetSingleton ( )
{
static FConsoleRenderThreadPropagation This ;
return This ;
}
} ;
2014-05-05 11:20:07 -04:00
static FString BuildRenderingThreadName ( uint32 ThreadIndex )
{
return FString : : Printf ( TEXT ( " %s %u " ) , * FName ( NAME_RenderThread ) . GetPlainNameString ( ) , ThreadIndex ) ;
}
2014-03-14 14:13:41 -04:00
void StartRenderingThread ( )
{
static uint32 ThreadCount = 0 ;
check ( ! GIsThreadedRendering & & GUseThreadedRendering ) ;
2014-09-03 10:52:00 -04:00
check ( ! GRHIThread )
if ( GUseRHIThread )
{
Copying //UE4/Dev-Rendering to Dev-Main (//UE4/Dev-Main)
#lockdown ben.marsh
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2733540 on 2015/10/19 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream
Capsule shadows
* Capsule shadows excel at extremely soft area shadows caused by a large light source angle, but don't support accurate self-shadowing
* Artists can setup a physics asset containing Spheres and Sphyls (capsules) for a skeletal mesh that will be used to represent the mesh's occlusion
* These shapes can then be used for direct shadowing (bCastCapsuleDirectShadow) on a skeletal mesh component, whose softness depends on the light source angle / radius
* The shapes can also be used to create an indirect shadow (bCastCapsuleIndirectShadow), whose direction and softness is derived from the precomputed sky occlusion (stationary sky light) or primary indirect lighting (static sky light)
* Capsule shadowing is computed at half res and uses tiled deferred culling for efficiency - only implemented for PC SM5 + PS4 so far
* Shadowing of movable skylights is not yet supported
Change 2735460 on 2015/10/20 by Uriel.Doyon@uriel.doyon_office_data
Basepass drawlist are now merged within a single drawlist.
Lighting policy parameters are now accessed through a uniform buffer.
Changed the global resource initialization so that InitRHI now comes before InitDynamicRHI
#codereview nick.penwarden
Change 2744741 on 2015/10/28 by Nick.Penwarden@nickp_streams
Remove unused RHI methods:
RHIIsDrawingViewport
RHIGpuTimeBegin
RHIGpuTimeEnd
Made default/empty versions of these calls and removed stubs from RHIs that don't use them:
RHISuspendRendering
RHIResumeRendering
RHIIsRenderingSuspended
Change 2745714 on 2015/10/28 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream
Lighting channels - each component and light can choose from 3 channels
* Primitives output their channel mask to stencil during the base pass, the masks are copied to a texture after the base pass, deferred lighting passes compare the primitive mask against the light's mask
* Dynamic shadow casting also respects the channels
* Only works on opaque materials, direct lighting, dynamic lighting
* Not implemented for tiled deferred atm
* This will replace CastsShadowsFromCinematicObjectsOnly in the future
#rb Martin.Mittring
Change 2746243 on 2015/10/29 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New
First pass at separate Async Compute Context
#codereview Lee.Clark,Daniel.Wright
#rb Gil.Gribb
Change 2746989 on 2015/10/29 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering
Removed a lot of complexity of the skeletal mesh motionblur code (better for multithreading, simpler, faster) but going from one large buffer to per mesh buffers. Upload of bones only needed once.
* GPUSkinCache didn't even work before (in this branch)
* tested BasePass velocity
* tested split screen
* tested editor pause
* matinee camera cut (no need, invalidates velocity)
* tested CPU Skin? (never has motionblur)
* tested CreateSceneProxy (recreation is prevented in CreteSceneProxy unless bone count changes)
* test ES2 -featureleveles2
#rb: Rolando.Caloca
Change 2750734 on 2015/11/02 by Uriel.Doyon@uriel.doyon_office_data
Embree integration into Lightmass
Can be enabled through Lightmass.ini [DevOptions.StaticLighting]bUseEmbree.
Also [DevOptions.StaticLighting]bVerifyEmbree will compare ray casting results.
Only usable on Win64 with this submit.
#review daniel.wright
Change 2752730 on 2015/11/03 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering
added SSAO CS version, can be enabled with
r.AmbientOcclusion.Compute 1
Not optimized yet
#rb:Olaf.Piesche
Change 2752766 on 2015/11/03 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream
Lightmass solver quality improvements
* IndirectLightingScale is no longer applied to photons, avoids splotchy artifacts when using small scales
* New 'Lightmass Portal' actor / component which tells the solver where to look for significant lighting. When lighting with a Static Skylight only, in a mostly indoor environment, setting up these portals is the only way to get high quality.
* Skylight bounce lighting is now much more accurate and leverages adaptive sampling
* Fixed a bug that effectively disabled adaptive sampling on high IndirectLightingQualities
* Shadow penumbras are also improved by IndirectLightingQuality
* Texel debugging is now a cvar 'r.TexelDebugging', instead of requiring a full recompile
Change 2754018 on 2015/11/04 by Uriel.Doyon@uriel.doyon_office_data
Quad Complexity ViewMode (PCD3D_SM5 only).
Shader Complexity with Quad Overhead ViewMode (PCD3D_SM5 only). Require ShaderComplexity ViewMode & Show.Visualize.QuadOverhead
#review brian.karis
Change 2754760 on 2015/11/04 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering
improved SSAO quality (less high frequency noise) to avoid TemporalAA smearing
Change 2756308 on 2015/11/05 by Rolando.Caloca@rolando.caloca_T3903_S
DevRendering - Enable removing unused outputs on PS4 shader pipelines, disable by default removing unused on D3D (toggable with r.D3DRemoveUnusedInterpolators)
#codereview Marcus.Wassmer
Change 2757063 on 2015/11/06 by Simon.Tovey@Simon.Tovey_Dev
Submitting pull request from user Pierdek.
Early out of particle collision module update if there are no active particles.
#github
#1614
Change 2757340 on 2015/11/06 by Gil.Gribb@Gil.Gribb_Z2439_Dev-Rendering
UE4 - Fixed the experimental r.RHICmdBalanceParallelLists 2 mode and renabled it for orion.
Change 2757343 on 2015/11/06 by Gil.Gribb@Gil.Gribb_Z2439_Dev-Rendering
UE4 - Added a path so that texture streaming can avoid flushing the RHI thread.
Change 2757985 on 2015/11/06 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream
Added new PrimitiveComponent setting bSingleSampleShadowFromStationaryLights
* When enabled, shadowing of a movable component from a stationary directional light will come from the Volume Lighting Samples precomputed by Lightmass
* This provides essentially free on/off shadow receiving on dynamic objects, with a fade over time between states
* Lighting has to be rebuilt once for this to work
#rb Rolando.Caloca
Change 2759058 on 2015/11/09 by Gil.Gribb@Gil.Gribb_Z2439_Dev-Rendering
UE4 - Dynamically set stream source to avoid creating a separate drawing policy for each static mesh with vertex colors.
#rb Daniel.Wright
Change 2760523 on 2015/11/10 by Uriel.Doyon@uriel.doyon_office_data
Enabled Embree by default
#review daniel.wright
==========================
ALL CHANGELISTS
==========================
Change 2720123 on 2015/10/07 by Rolando.Caloca@Rolando.Caloca_T4688_5331 'Dev-Rendering - 'integrate' Tem'
Change 2721682 on 2015/10/08 by Gil.Gribb@Gil.Gribb_Z2439_Dev-Rendering 'UE4 - Eliminated a fatal error '
Change 2721815 on 2015/10/08 by Rolando.Caloca@Rolando.Caloca_T4688_5331 'Dev-Rendering - Fix crash exiti'
Change 2724755 on 2015/10/12 by Rolando.Caloca@Rolando.Caloca_T4688_5331 'Dev-Rendering - D3D12 Fix Tier'
Change 2724781 on 2015/10/12 by Rolando.Caloca@Rolando.Caloca_T4688_5331 'Dev-Rendering - D3D12 Fix offse'
Change 2728317 on 2015/10/14 by Rolando.Caloca@Rolando.Caloca_T4688_5331 'Dev-Rendering - hlslcc - Fix fo'
Change 2729170 on 2015/10/14 by Chris.Bunner@Chris.Bunner_Dev_Stream 'Force Lightmass volume sample g'
Change 2732131 on 2015/10/16 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'fixed resource transition issue'
Change 2732218 on 2015/10/16 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'minor code cleanup '
Change 2733533 on 2015/10/19 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'Clear stencil to 0 after decals'
Change 2733540 on 2015/10/19 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'Capsule shadows * Capsule shado'
Change 2733546 on 2015/10/19 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'Light shaft targets are only al'
Change 2733602 on 2015/10/19 by Uriel.Doyon@uriel.doyon_office_data 'Decals not writing to Normal ca'
Change 2733627 on 2015/10/19 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'Fix for transition ensure. '
Change 2735292 on 2015/10/20 by Brian.Karis@Brian.Karis_T3247_Rendering 'Fix for dark lightmap precision'
Change 2735298 on 2015/10/20 by Brian.Karis@Brian.Karis_T3247_Rendering 'Fix for speedtree LOD transitio'
Change 2735460 on 2015/10/20 by Uriel.Doyon@uriel.doyon_office_data 'Basepass drawlist are now merge'
Change 2737214 on 2015/10/21 by Chris.Bunner@Chris.Bunner_Dev_Stream 'Expanded a warning when importi'
Change 2738581 on 2015/10/22 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'Updated comment on stencil usag'
Change 2738583 on 2015/10/22 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'Changed bound but not set scene'
Change 2738584 on 2015/10/22 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'Fixed skylight occlusion maps b'
Change 2738589 on 2015/10/22 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'Lightmap streaming fixes * Chan'
Change 2738593 on 2015/10/22 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'Fix from licensee for race cond'
Change 2738982 on 2015/10/22 by Olaf.Piesche@Olaf.Piesche_roaming 'Activating CanTickOnAnyThread f'
Change 2739032 on 2015/10/22 by Olaf.Piesche@Olaf.Piesche_roaming 'Fixing compiler barf with Clang'
Change 2741517 on 2015/10/26 by Rolando.Caloca@rolando.caloca_T3903_S 'DevRindering - D3D12 - Integrat'
Change 2743790 on 2015/10/27 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'Fixed texel debugging on static'
Change 2743958 on 2015/10/27 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'added comments '
Change 2744153 on 2015/10/27 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'Unity compile fix '
Change 2744741 on 2015/10/28 by Nick.Penwarden@nickp_streams 'Remove unused RHI methods: RHI'
Change 2745714 on 2015/10/28 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'Lighting channels - each compon'
Change 2746242 on 2015/10/29 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'Fix crashes on init by swapping'
Change 2746243 on 2015/10/29 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'First pass at separate Async Co'
Change 2746296 on 2015/10/29 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'Buffer label frees so we don't '
Change 2746297 on 2015/10/29 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'updated comment '
Change 2746343 on 2015/10/29 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'added comment '
Change 2746347 on 2015/10/29 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'added comment '
Change 2746811 on 2015/10/29 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'Draw event for compute commandl'
Change 2746989 on 2015/10/29 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'Removed a lot of complexity of '
Change 2747127 on 2015/10/29 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'Improved game console printout '
Change 2747702 on 2015/10/30 by Chris.Bunner@Chris.Bunner_Dev_Stream 'Bumped Lightmass StaticMesh imp'
Change 2747954 on 2015/10/30 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'Fix SubmitDone not called TRC e'
Change 2747979 on 2015/10/30 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'polish console autocomplete tex'
Change 2750719 on 2015/11/02 by Uriel.Doyon@uriel.doyon_office_data 'Add Embree 2.7.0 for Win64 and '
Change 2750734 on 2015/11/02 by Uriel.Doyon@uriel.doyon_office_data 'Embree integration into Lightma'
Change 2750872 on 2015/11/02 by Nick.Penwarden@nickp_streams 'Merging //UE4/Dev-Main to Dev-R'
Change 2751934 on 2015/11/03 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'Disambiguate template function '
Change 2752190 on 2015/11/03 by Gil.Gribb@Gil.Gribb_Z2439_Dev-Rendering 'UE4 - Fixed assert relating to '
Change 2752333 on 2015/11/03 by Rolando.Caloca@rolando.caloca_T3903_S 'DevRendering - Shader pipeline '
Change 2752655 on 2015/11/03 by Rolando.Caloca@Rolando.Caloca_T3903_S 'DevRendering - Fix Materials pa'
Change 2752710 on 2015/11/03 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'added comment '
Change 2752711 on 2015/11/03 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'added better comment/help text '
Change 2752730 on 2015/11/03 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'added SSAO CS version, can be e'
Change 2752766 on 2015/11/03 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'Lightmass solver quality improv'
Change 2752869 on 2015/11/03 by Rolando.Caloca@rolando.caloca_T3903_S 'DevRendering - Add shader pipel'
Change 2752882 on 2015/11/03 by Rolando.Caloca@Rolando.Caloca_T3903_S 'DevRendering - hlslcc - Metal -'
Change 2752899 on 2015/11/03 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'small SSAO GPU optimization mov'
Change 2752934 on 2015/11/03 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'minor GPU optimization for SSAO'
Change 2753109 on 2015/11/03 by Uriel.Doyon@uriel.doyon_office_data 'Fixed final build '
Change 2753669 on 2015/11/04 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'fixed SM4 compiling '
Change 2754002 on 2015/11/04 by Nick.Penwarden@nickp_streams 'test change '
Change 2754018 on 2015/11/04 by Uriel.Doyon@uriel.doyon_office_data 'Quad Complexity ViewMode (PCD3D'
Change 2754115 on 2015/11/04 by Gil.Gribb@Gil.Gribb_Z2439_Dev-Rendering 'UE4 - Fixed end of frame update'
Change 2754297 on 2015/11/04 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'PS4 compile fixes #codereview U'
Change 2754405 on 2015/11/04 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'minor SSAO ALU optimizations fi'
Change 2754512 on 2015/11/04 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'adjusted clamp for cvar '
Change 2754760 on 2015/11/04 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'improved SSAO quality (less hig'
Change 2755572 on 2015/11/05 by Rolando.Caloca@rolando.caloca_T3903_S 'DevRendering - PS4 warning fix '
Change 2755667 on 2015/11/05 by Gil.Gribb@Gil.Gribb_Z2439_Dev-Rendering 'UE4 - Fixed UE-22742, leak in t'
Change 2755722 on 2015/11/05 by Rolando.Caloca@rolando.caloca_T3903_S 'DevRendering - Remove unused co'
Change 2755814 on 2015/11/05 by Nick.Penwarden@nickp_streams 'Merging //UE4/Dev-Main to Dev-R'
Change 2755935 on 2015/11/05 by Rolando.Caloca@rolando.caloca_T3903_S 'DevRendering - Rebuild static m'
Change 2756003 on 2015/11/05 by Uriel.Doyon@uriel.doyon_office_data 'Reduce the number of precompute'
Change 2756145 on 2015/11/05 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'Temp fix for GPU crash #rb none'
Change 2756308 on 2015/11/05 by Rolando.Caloca@rolando.caloca_T3903_S 'DevRendering - Enable removing '
Change 2756435 on 2015/11/05 by Olaf.Piesche@Olaf.Piesche_roaming 'Disabling a check, to fix OR-85'
Change 2757063 on 2015/11/06 by Simon.Tovey@Simon.Tovey_Dev 'Submitting pull request from us'
Change 2757340 on 2015/11/06 by Gil.Gribb@Gil.Gribb_Z2439_Dev-Rendering 'UE4 - Fixed the experimental r.'
Change 2757341 on 2015/11/06 by Gil.Gribb@Gil.Gribb_Z2439_Dev-Rendering 'UE4 - Changed the RHI thread di'
Change 2757342 on 2015/11/06 by Gil.Gribb@Gil.Gribb_Z2439_Dev-Rendering 'UE4 - Fixed lazy uniform buffer'
Change 2757343 on 2015/11/06 by Gil.Gribb@Gil.Gribb_Z2439_Dev-Rendering 'UE4 - Added a path so that text'
Change 2757500 on 2015/11/06 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'Add FrameSync to externalprofil'
Change 2757650 on 2015/11/06 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'GBuffer should only be consider'
Change 2757665 on 2015/11/06 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'UE-22816 Instruction count is n'
Change 2757834 on 2015/11/06 by Michael.Trepka@Michael.Trepka_a4202_Dev-Rendering 'Embree integration into Lightma'
Change 2757930 on 2015/11/06 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'Fix UT ensure #rb Peter.Knepley'
Change 2757931 on 2015/11/06 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'Fix Ocean ensure #rb josh.ander'
Change 2757946 on 2015/11/06 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'Removed invalid Lightmass asser'
Change 2757985 on 2015/11/06 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'Added new PrimitiveComponent se'
Change 2758049 on 2015/11/06 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'OR-8600 CRASH: AllocationLeveli'
Change 2758059 on 2015/11/06 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'r.DumpTransitionsForResource #r'
Change 2758082 on 2015/11/06 by Rolando.Caloca@rolando.caloca_T3903_S 'DevRendering - Fix resource tra'
Change 2758879 on 2015/11/09 by Rolando.Caloca@rolando.caloca_T3903_S 'DevRendering - Fix PSSL names f'
Change 2758911 on 2015/11/09 by Gil.Gribb@Gil.Gribb_Z2439_Dev-Rendering 'UE4 - Fixed accidental force di'
Change 2758968 on 2015/11/09 by Uriel.Doyon@uriel.doyon_office_data 'Disabled single frame buffer us'
Change 2758991 on 2015/11/09 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'Fix togglerhithread crash #rb G'
Change 2759058 on 2015/11/09 by Gil.Gribb@Gil.Gribb_Z2439_Dev-Rendering 'UE4 - Dynamically set stream so'
Change 2759063 on 2015/11/09 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'fixed UE-22368 CLONE - GitHub 1'
Change 2759073 on 2015/11/09 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'minor code quality improvements'
Change 2759501 on 2015/11/09 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'Fix particle ensure. '
Change 2759522 on 2015/11/09 by Marcus.Wassmer@Marcus.Wassmer_DevRendering_New 'Fix decals using CustomStencil.'
Change 2759610 on 2015/11/09 by Daniel.Wright@Daniel.Wright_G5038_RenderingStream 'Fixed line light source shadows'
Change 2759634 on 2015/11/09 by Uriel.Doyon@uriel.doyon_office_data 'Refined GBufferA resolving when'
Change 2759657 on 2015/11/09 by Martin.Mittring@Martin.Mittring_Z3941_Dev_Rendering 'Fixed ResourceTransition with r'
Change 2759693 on 2015/11/09 by Rolando.Caloca@Rolando.Caloca_T4688_S 'DevRendering - Fixed global sha'
Change 2759771 on 2015/11/09 by Uriel.Doyon@uriel.doyon_office_data 'Fixed editor hit proxy renderin'
Change 2760188 on 2015/11/09 by Uriel.Doyon@uriel.doyon_office_data 'Disabled some more deferred dec'
Change 2760523 on 2015/11/10 by Uriel.Doyon@uriel.doyon_office_data 'Enabled Embree by default #revi'
[CL 2761339 by Nick Penwarden in Main branch]
2015-11-10 17:11:09 -05:00
FRHICommandListExecutor : : GetImmediateCommandList ( ) . ImmediateFlush ( EImmediateFlushType : : DispatchToRHIThread ) ;
2014-09-03 10:52:00 -04:00
if ( ! FTaskGraphInterface : : Get ( ) . IsThreadProcessingTasks ( ENamedThreads : : RHIThread ) )
{
FRHIThread : : Get ( ) . Start ( ) ;
}
DECLARE_CYCLE_STAT ( TEXT ( " Wait For RHIThread " ) , STAT_WaitForRHIThread , STATGROUP_TaskGraphTasks ) ;
FGraphEventRef CompletionEvent = TGraphTask < FNullGraphTask > : : CreateTask ( NULL , ENamedThreads : : GameThread ) . ConstructAndDispatchWhenReady ( GET_STATID ( STAT_WaitForRHIThread ) , ENamedThreads : : RHIThread ) ;
2015-03-04 08:31:40 -05:00
QUICK_SCOPE_CYCLE_COUNTER ( STAT_StartRenderingThread ) ;
2014-09-03 10:52:00 -04:00
FTaskGraphInterface : : Get ( ) . WaitUntilTaskCompletes ( CompletionEvent , ENamedThreads : : GameThread_Local ) ;
GRHIThread = FRHIThread : : Get ( ) . Thread ;
check ( GRHIThread ) ;
2014-10-09 14:05:15 -04:00
GRHICommandList . LatchBypass ( ) ;
2014-09-03 10:52:00 -04:00
}
2014-03-14 14:13:41 -04:00
// Turn on the threaded rendering flag.
GIsThreadedRendering = true ;
// Create the rendering thread.
GRenderingThreadRunnable = new FRenderingThread ( ) ;
2014-05-12 08:40:54 -04:00
GRenderingThread = FRunnableThread : : Create ( GRenderingThreadRunnable , * BuildRenderingThreadName ( ThreadCount ) , 0 , TPri_Normal , FPlatformAffinity : : GetRenderingThreadMask ( ) ) ;
2014-03-14 14:13:41 -04:00
// Wait for render thread to have taskgraph bound before we dispatch any tasks for it.
( ( FRenderingThread * ) GRenderingThreadRunnable ) - > TaskGraphBoundSyncEvent - > Wait ( ) ;
// register
IConsoleManager : : Get ( ) . RegisterThreadPropagation ( GRenderingThread - > GetThreadID ( ) , & FConsoleRenderThreadPropagation : : GetSingleton ( ) ) ;
// ensure the thread has actually started and is idling
FRenderCommandFence Fence ;
Fence . BeginFence ( ) ;
Fence . Wait ( ) ;
GRunRenderingThreadHeartbeat = true ;
// Create the rendering thread heartbeat
GRenderingThreadRunnableHeartbeat = new FRenderingThreadTickHeartbeat ( ) ;
2014-05-12 08:40:54 -04:00
GRenderingThreadHeartbeat = FRunnableThread : : Create ( GRenderingThreadRunnableHeartbeat , * FString : : Printf ( TEXT ( " RTHeartBeat %d " ) , ThreadCount ) , 16 * 1024 , TPri_AboveNormal , FPlatformAffinity : : GetRTHeartBeatMask ( ) ) ;
2014-03-14 14:13:41 -04:00
ThreadCount + + ;
}
void StopRenderingThread ( )
{
// This function is not thread-safe. Ensure it is only called by the main game thread.
check ( IsInGameThread ( ) ) ;
// unregister
IConsoleManager : : Get ( ) . RegisterThreadPropagation ( ) ;
// stop the render thread heartbeat first
if ( GRunRenderingThreadHeartbeat )
{
GRunRenderingThreadHeartbeat = false ;
// Wait for the rendering thread heartbeat to return.
GRenderingThreadHeartbeat - > WaitForCompletion ( ) ;
GRenderingThreadHeartbeat = NULL ;
delete GRenderingThreadRunnableHeartbeat ;
GRenderingThreadRunnableHeartbeat = NULL ;
}
if ( GIsThreadedRendering )
{
// Get the list of objects which need to be cleaned up when the rendering thread is done with them.
FPendingCleanupObjects * PendingCleanupObjects = GetPendingCleanupObjects ( ) ;
// Make sure we're not in the middle of streaming textures.
( * GFlushStreamingFunc ) ( ) ;
// Wait for the rendering thread to finish executing all enqueued commands.
FlushRenderingCommands ( ) ;
// The rendering thread may have already been stopped during the call to GFlushStreamingFunc or FlushRenderingCommands.
if ( GIsThreadedRendering )
{
2014-09-03 10:52:00 -04:00
if ( GRHIThread )
{
DECLARE_CYCLE_STAT ( TEXT ( " Wait For RHIThread Finish " ) , STAT_WaitForRHIThreadFinish , STATGROUP_TaskGraphTasks ) ;
FGraphEventRef FlushTask = TGraphTask < FNullGraphTask > : : CreateTask ( NULL , ENamedThreads : : GameThread ) . ConstructAndDispatchWhenReady ( GET_STATID ( STAT_WaitForRHIThreadFinish ) , ENamedThreads : : RHIThread ) ;
2015-03-04 08:31:40 -05:00
QUICK_SCOPE_CYCLE_COUNTER ( STAT_StopRenderingThread_RHIThread ) ;
2014-09-03 10:52:00 -04:00
FTaskGraphInterface : : Get ( ) . WaitUntilTaskCompletes ( FlushTask , ENamedThreads : : GameThread_Local ) ;
GRHIThread = nullptr ;
}
2014-03-14 14:13:41 -04:00
check ( GRenderingThread ) ;
check ( ! GIsRenderingThreadSuspended ) ;
// Turn off the threaded rendering flag.
GIsThreadedRendering = false ;
2014-09-03 10:52:00 -04:00
{
FGraphEventRef QuitTask = TGraphTask < FReturnGraphTask > : : CreateTask ( NULL , ENamedThreads : : GameThread ) . ConstructAndDispatchWhenReady ( ENamedThreads : : RenderThread ) ;
2014-03-14 14:13:41 -04:00
2014-09-03 10:52:00 -04:00
// Busy wait while BP debugging, to avoid opportunistic execution of game thread tasks
// If the game thread is already executing tasks, then we have no choice but to spin
if ( GIntraFrameDebuggingGameThread | | FTaskGraphInterface : : Get ( ) . IsThreadProcessingTasks ( ENamedThreads : : GameThread ) )
2014-03-14 14:13:41 -04:00
{
2014-09-03 10:52:00 -04:00
while ( ( QuitTask . GetReference ( ) ! = nullptr ) & & ! QuitTask - > IsComplete ( ) )
{
FPlatformProcess : : Sleep ( 0.0f ) ;
}
}
else
{
2015-03-04 08:31:40 -05:00
QUICK_SCOPE_CYCLE_COUNTER ( STAT_StopRenderingThread ) ;
2014-09-03 10:52:00 -04:00
FTaskGraphInterface : : Get ( ) . WaitUntilTaskCompletes ( QuitTask , ENamedThreads : : GameThread_Local ) ;
2014-03-14 14:13:41 -04:00
}
}
// Wait for the rendering thread to return.
GRenderingThread - > WaitForCompletion ( ) ;
// Destroy the rendering thread objects.
delete GRenderingThread ;
GRenderingThread = NULL ;
2015-07-21 14:31:06 -04:00
GRHICommandList . LatchBypass ( ) ;
2014-03-14 14:13:41 -04:00
delete GRenderingThreadRunnable ;
GRenderingThreadRunnable = NULL ;
}
// Delete the pending cleanup objects which were in use by the rendering thread.
delete PendingCleanupObjects ;
}
2014-09-03 10:52:00 -04:00
check ( ! GRHIThread ) ;
2014-03-14 14:13:41 -04:00
}
void CheckRenderingThreadHealth ( )
{
if ( ! GIsRenderingThreadHealthy )
{
GErrorHist [ 0 ] = 0 ;
GIsCriticalError = false ;
UE_LOG ( LogRendererCore , Fatal , TEXT ( " Rendering thread exception: \r \n %s " ) , * GRenderingThreadError ) ;
}
if ( IsInGameThread ( ) )
{
GLog - > FlushThreadedLogs ( ) ;
# if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
TGuardValue < bool > GuardMainThreadBlockedOnRenderThread ( GMainThreadBlockedOnRenderThread , true ) ;
# endif
SCOPE_CYCLE_COUNTER ( STAT_PumpMessages ) ;
FPlatformMisc : : PumpMessages ( false ) ;
}
}
bool IsRenderingThreadHealthy ( )
{
return GIsRenderingThreadHealthy ;
}
void FRenderCommandFence : : BeginFence ( )
{
if ( ! GIsThreadedRendering )
{
return ;
}
else
{
2014-09-02 05:19:25 -04:00
DECLARE_CYCLE_STAT ( TEXT ( " FNullGraphTask.FenceRenderCommand " ) ,
STAT_FNullGraphTask_FenceRenderCommand ,
STATGROUP_TaskGraphTasks ) ;
2014-03-14 14:13:41 -04:00
if ( IsFenceComplete ( ) )
{
2014-09-02 05:19:25 -04:00
CompletionEvent = TGraphTask < FNullGraphTask > : : CreateTask ( NULL , ENamedThreads : : GameThread ) . ConstructAndDispatchWhenReady (
GET_STATID ( STAT_FNullGraphTask_FenceRenderCommand ) , ENamedThreads : : RenderThread ) ;
2014-03-14 14:13:41 -04:00
}
else
{
// we already had a fence, so we will chain this one to the old one as a prerequisite
FGraphEventArray Prerequistes ;
Prerequistes . Add ( CompletionEvent ) ;
2014-09-02 05:19:25 -04:00
CompletionEvent = TGraphTask < FNullGraphTask > : : CreateTask ( & Prerequistes , ENamedThreads : : GameThread ) . ConstructAndDispatchWhenReady (
GET_STATID ( STAT_FNullGraphTask_FenceRenderCommand ) , ENamedThreads : : RenderThread ) ;
2014-03-14 14:13:41 -04:00
}
}
}
bool FRenderCommandFence : : IsFenceComplete ( ) const
{
if ( ! GIsThreadedRendering )
{
return true ;
}
2015-04-01 03:03:18 -04:00
check ( IsInGameThread ( ) | | IsInAsyncLoadingThread ( ) ) ;
2014-03-14 14:13:41 -04:00
CheckRenderingThreadHealth ( ) ;
if ( ! CompletionEvent . GetReference ( ) | | CompletionEvent - > IsComplete ( ) )
{
CompletionEvent = NULL ; // this frees the handle for other uses, the NULL state is considered completed
return true ;
}
return false ;
}
/** How many cycles the gamethread used (excluding idle time). It's set once per frame in FViewport::Draw. */
uint32 GGameThreadTime = 0 ;
/** How many cycles it took to swap buffers to present the frame. */
uint32 GSwapBufferTime = 0 ;
static int32 GTimeToBlockOnRenderFence = 1 ;
static FAutoConsoleVariableRef CVarTimeToBlockOnRenderFence (
TEXT ( " g.TimeToBlockOnRenderFence " ) ,
GTimeToBlockOnRenderFence ,
TEXT ( " Number of milliseconds the game thread should block when waiting on a render thread fence. " )
) ;
/**
* Block the game thread waiting for a task to finish on the rendering thread .
*/
static void GameThreadWaitForTask ( const FGraphEventRef & Task , bool bEmptyGameThreadTasks = false )
{
check ( IsInGameThread ( ) ) ;
check ( IsValidRef ( Task ) ) ;
if ( ! Task - > IsComplete ( ) )
{
SCOPE_CYCLE_COUNTER ( STAT_GameIdleTime ) ;
{
static int32 NumRecursiveCalls = 0 ;
2015-01-28 07:31:10 -05:00
2014-03-14 14:13:41 -04:00
// Check for recursion. It's not completely safe but because we pump messages while
// blocked it is expected.
NumRecursiveCalls + + ;
if ( NumRecursiveCalls > 1 )
{
UE_LOG ( LogRendererCore , Warning , TEXT ( " FlushRenderingCommands called recursively! %d calls on the stack. " ) , NumRecursiveCalls ) ;
}
if ( NumRecursiveCalls > 1 | | FTaskGraphInterface : : Get ( ) . IsThreadProcessingTasks ( ENamedThreads : : GameThread ) )
{
bEmptyGameThreadTasks = false ; // we don't do this on recursive calls or if we are at a blueprint breakpoint
}
// Grab an event from the pool and fire off a task to trigger it.
2015-01-28 07:31:10 -05:00
FEvent * Event = FPlatformProcess : : GetSynchEventFromPool ( ) ;
2014-03-14 14:13:41 -04:00
FTaskGraphInterface : : Get ( ) . TriggerEventWhenTaskCompletes ( Event , Task , ENamedThreads : : GameThread ) ;
// Check rendering thread health needs to be called from time to
// time in order to pump messages, otherwise the RHI may block
// on vsync causing a deadlock. Also we should make sure the
// rendering thread hasn't crashed :)
bool bDone ;
uint32 WaitTime = FMath : : Clamp < uint32 > ( GTimeToBlockOnRenderFence , 0 , 33 ) ;
do
{
CheckRenderingThreadHealth ( ) ;
if ( bEmptyGameThreadTasks )
{
2015-01-28 07:31:10 -05:00
// process gamethread tasks if there are any
2014-03-14 14:13:41 -04:00
FTaskGraphInterface : : Get ( ) . ProcessThreadUntilIdle ( ENamedThreads : : GameThread ) ;
}
bDone = Event - > Wait ( WaitTime ) ;
}
while ( ! bDone ) ;
// Return the event to the pool and decrement the recursion counter.
2015-01-28 07:31:10 -05:00
FPlatformProcess : : ReturnSynchEventToPool ( Event ) ;
Event = nullptr ;
2014-03-14 14:13:41 -04:00
NumRecursiveCalls - - ;
}
}
}
/**
* Waits for pending fence commands to retire .
*/
void FRenderCommandFence : : Wait ( bool bProcessGameThreadTasks ) const
{
if ( ! IsFenceComplete ( ) )
{
#if 0
// on most platforms this is a better solution because it doesn't spin
// windows needs to pump messages
if ( bProcessGameThreadTasks )
{
2015-03-04 08:31:40 -05:00
QUICK_SCOPE_CYCLE_COUNTER ( STAT_FRenderCommandFence_Wait ) ;
2014-03-14 14:13:41 -04:00
FTaskGraphInterface : : Get ( ) . WaitUntilTaskCompletes ( CompletionEvent , ENamedThreads : : GameThread ) ;
}
# endif
GameThreadWaitForTask ( CompletionEvent , bProcessGameThreadTasks ) ;
}
}
/**
* List of tasks that must be completed before we start a render frame
* Note , normally , you don ' t need the render command themselves in this list workers that queue render commands are usually sufficient
*/
static FCompletionList FrameRenderPrerequisites ;
/**
* Adds a task that must be completed either before the next scene draw or a flush rendering commands
* Note , normally , you don ' t need the render command themselves in this list workers that queue render commands are usually sufficient
* @ param TaskToAdd , task to add as a pending render thread task
*/
void AddFrameRenderPrerequisite ( const FGraphEventRef & TaskToAdd )
{
FrameRenderPrerequisites . Add ( TaskToAdd ) ;
}
/**
* Gather the frame render prerequisites and make sure all render commands are at least queued
*/
void AdvanceFrameRenderPrerequisite ( )
{
checkSlow ( IsInGameThread ( ) ) ;
2016-01-27 07:18:43 -05:00
FGraphEventRef PendingComplete = FrameRenderPrerequisites . CreatePrerequisiteCompletionHandle ( ENamedThreads : : GameThread ) ;
2014-03-14 14:13:41 -04:00
if ( PendingComplete . GetReference ( ) )
{
GameThreadWaitForTask ( PendingComplete ) ;
}
}
/**
* Waits for the rendering thread to finish executing all pending rendering commands . Should only be used from the game thread .
*/
void FlushRenderingCommands ( )
{
2014-09-11 09:38:38 -04:00
ENQUEUE_UNIQUE_RENDER_COMMAND (
FlushPendingDeleteRHIResources ,
{
GRHICommandList . GetImmediateCommandList ( ) . ImmediateFlush ( EImmediateFlushType : : FlushRHIThreadFlushResources ) ;
}
) ;
2014-07-15 07:34:34 -04:00
2014-03-14 14:13:41 -04:00
AdvanceFrameRenderPrerequisite ( ) ;
// Find the objects which may be cleaned up once the rendering thread command queue has been flushed.
FPendingCleanupObjects * PendingCleanupObjects = GetPendingCleanupObjects ( ) ;
// Issue a fence command to the rendering thread and wait for it to complete.
FRenderCommandFence Fence ;
Fence . BeginFence ( ) ;
Fence . Wait ( ) ;
// Delete the objects which were enqueued for deferred cleanup before the command queue flush.
delete PendingCleanupObjects ;
}
2014-07-15 07:34:34 -04:00
void FlushPendingDeleteRHIResources_GameThread ( )
{
2014-09-03 10:52:00 -04:00
if ( ! GRHIThread )
{
ENQUEUE_UNIQUE_RENDER_COMMAND (
FlushPendingDeleteRHIResources ,
2014-07-15 07:34:34 -04:00
{
FlushPendingDeleteRHIResources_RenderThread ( ) ;
}
2014-09-03 10:52:00 -04:00
) ;
}
2014-07-15 07:34:34 -04:00
}
void FlushPendingDeleteRHIResources_RenderThread ( )
{
2014-09-03 10:52:00 -04:00
if ( ! GRHIThread )
{
FRHIResource : : FlushPendingDeletes ( ) ;
}
2014-07-15 07:34:34 -04:00
}
2014-06-27 11:07:13 -04:00
FRHICommandListImmediate & GetImmediateCommandList_ForRenderCommand ( )
{
return FRHICommandListExecutor : : GetImmediateCommandList ( ) ;
}
2014-03-14 14:13:41 -04:00
/** The set of deferred cleanup objects which are pending cleanup. */
2016-01-27 07:18:43 -05:00
static TLockFreePointerListUnordered < FDeferredCleanupInterface , PLATFORM_CACHE_LINE_SIZE > PendingCleanupObjectsList ;
2014-03-14 14:13:41 -04:00
FPendingCleanupObjects : : FPendingCleanupObjects ( )
{
check ( IsInGameThread ( ) ) ;
PendingCleanupObjectsList . PopAll ( CleanupArray ) ;
}
FPendingCleanupObjects : : ~ FPendingCleanupObjects ( )
{
2015-03-04 08:31:40 -05:00
QUICK_SCOPE_CYCLE_COUNTER ( STAT_FPendingCleanupObjects_Destruct ) ;
2014-03-14 14:13:41 -04:00
for ( int32 ObjectIndex = 0 ; ObjectIndex < CleanupArray . Num ( ) ; ObjectIndex + + )
{
CleanupArray [ ObjectIndex ] - > FinishCleanup ( ) ;
}
}
void BeginCleanup ( FDeferredCleanupInterface * CleanupObject )
{
PendingCleanupObjectsList . Push ( CleanupObject ) ;
}
FPendingCleanupObjects * GetPendingCleanupObjects ( )
{
return new FPendingCleanupObjects ;
}