From d07c66c8a3df0d76427d49160426dfe531c499f9 Mon Sep 17 00:00:00 2001 From: Chris Tchou Date: Wed, 21 Jul 2021 12:35:38 -0700 Subject: [PATCH] [ShaderGraph][2021.2] Throttling animated preview framerate (#5164) Cherry picked from 19859298fde0d02ea548b8be2144241002fa708c # Conflicts: # com.unity.shadergraph/CHANGELOG.md # com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs --- com.unity.shadergraph/CHANGELOG.md | 3 ++ .../Editor/Drawing/PreviewManager.cs | 37 +++++++++++++++++-- .../Editor/Drawing/PreviewRate.cs | 9 ----- .../Editor/Drawing/PreviewRate.cs.meta | 3 -- .../Editor/Drawing/Views/GraphEditorView.cs | 4 +- 5 files changed, 39 insertions(+), 17 deletions(-) delete mode 100644 com.unity.shadergraph/Editor/Drawing/PreviewRate.cs delete mode 100644 com.unity.shadergraph/Editor/Drawing/PreviewRate.cs.meta diff --git a/com.unity.shadergraph/CHANGELOG.md b/com.unity.shadergraph/CHANGELOG.md index 5ceccf916f8..8b3761b7efb 100644 --- a/com.unity.shadergraph/CHANGELOG.md +++ b/com.unity.shadergraph/CHANGELOG.md @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [10.7.0] - 2021-07-02 +### Added + - Added a ShaderGraph animated preview framerate throttle. + ### Fixed - Fixed SubGraph SamplerState property defaults not being respected [1336119] - Fixed an issue where nested subgraphs with identical SamplerState property settings could cause compile failures [1336089] diff --git a/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs b/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs index 57016296b56..876f04be43f 100644 --- a/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs +++ b/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs @@ -37,6 +37,8 @@ class PreviewManager : IDisposable HashSet m_PreviewsToDraw = new HashSet(); // previews to re-render the texture (either because shader compile changed or property changed) HashSet m_TimedPreviews = new HashSet(); // previews that are dependent on a time node -- i.e. animated / need to redraw every frame + double m_LastTimedUpdateTime = 0.0f; + bool m_TopologyDirty; // indicates topology changed, used to rebuild timed node list and preview type (2D/3D) inheritance. HashSet m_MasterNodeTempBlocks = new HashSet(); // temp blocks used by the most recent master node preview generation. @@ -420,8 +422,36 @@ void AssignPerMaterialPreviewProperties(Material mat, List perM } } + bool TimedNodesShouldUpdate(EditorWindow editorWindow) + { + // get current screen FPS, clamp to what we consider a valid range + // this is probably not accurate for multi-monitor.. but should be relevant to at least one of the monitors + double monitorFPS = Screen.currentResolution.refreshRate + 1.0; // +1 to round up, since it is an integer and rounded down + if (Double.IsInfinity(monitorFPS) || Double.IsNaN(monitorFPS)) + monitorFPS = 60.0f; + monitorFPS = Math.Min(monitorFPS, 144.0); + monitorFPS = Math.Max(monitorFPS, 30.0); + + var curTime = EditorApplication.timeSinceStartup; + var deltaTime = curTime - m_LastTimedUpdateTime; + bool isFocusedWindow = (EditorWindow.focusedWindow == editorWindow); + + // we throttle the update rate, based on whether the window is focused and if unity is active + const double k_AnimatedFPS_WhenNotFocused = 10.0; + const double k_AnimatedFPS_WhenInactive = 2.0; + double maxAnimatedFPS = + (UnityEditorInternal.InternalEditorUtility.isApplicationActive ? + (isFocusedWindow ? monitorFPS : k_AnimatedFPS_WhenNotFocused) : + k_AnimatedFPS_WhenInactive); + + bool update = (deltaTime > (1.0 / maxAnimatedFPS)); + if (update) + m_LastTimedUpdateTime = curTime; + return update; + } + private static readonly ProfilerMarker RenderPreviewsMarker = new ProfilerMarker("RenderPreviews"); - public void RenderPreviews(bool requestShaders = true) + public void RenderPreviews(EditorWindow editorWindow, bool requestShaders = true) { using (RenderPreviewsMarker.Auto()) using (var renderList2D = PooledList.Get()) @@ -445,10 +475,11 @@ public void RenderPreviews(bool requestShaders = true) CollectPreviewProperties(m_NodesPropertyChanged, perMaterialPreviewProperties); m_NodesPropertyChanged.Clear(); - // timed nodes change every frame, so must be drawn + // timed nodes are animated, so they should be updated regularly (but not necessarily on every update) // (m_TimedPreviews has been pre-propagated downstream) // HOWEVER they do not need to collect properties. (the only property changing is time..) - m_PreviewsToDraw.UnionWith(m_TimedPreviews); + if (TimedNodesShouldUpdate(editorWindow)) + m_PreviewsToDraw.UnionWith(m_TimedPreviews); ForEachNodesPreview(nodesToDraw, p => m_PreviewsToDraw.Add(p)); diff --git a/com.unity.shadergraph/Editor/Drawing/PreviewRate.cs b/com.unity.shadergraph/Editor/Drawing/PreviewRate.cs deleted file mode 100644 index 6ffcb3e0a69..00000000000 --- a/com.unity.shadergraph/Editor/Drawing/PreviewRate.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace UnityEditor.ShaderGraph.Drawing -{ - enum PreviewRate - { - Full, - Throttled, - Off - } -} diff --git a/com.unity.shadergraph/Editor/Drawing/PreviewRate.cs.meta b/com.unity.shadergraph/Editor/Drawing/PreviewRate.cs.meta deleted file mode 100644 index d91be546579..00000000000 --- a/com.unity.shadergraph/Editor/Drawing/PreviewRate.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: fa070520993a4b839e705dcd7f22e4d6 -timeCreated: 1506421104 \ No newline at end of file diff --git a/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs b/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs index 32b923b1550..dadd7f982d5 100644 --- a/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs +++ b/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs @@ -121,7 +121,7 @@ public GraphEditorView(EditorWindow editorWindow, GraphData graph, MessageManage m_Graph = graph; m_MessageManager = messageManager; previewManager = new PreviewManager(graph, messageManager); - previewManager.RenderPreviews(false); + previewManager.RenderPreviews(m_EditorWindow, false); styleSheets.Add(Resources.Load("Styles/GraphEditorView")); @@ -649,7 +649,7 @@ public void HandleGraphChanges(bool wasUndoRedoPerformed) m_ColorManager.UpdateNodeViews(nodeList); } - previewManager.RenderPreviews(); + previewManager.RenderPreviews(m_EditorWindow); m_BlackboardProvider.HandleGraphChanges(wasUndoRedoPerformed); if (wasUndoRedoPerformed) m_InspectorView.Update(InspectorUpdateSource.GraphChanges);