From 4af87777c5a3d1339cf3530ed2bbe5d7c07cdebd Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 2 May 2020 19:25:50 +0300 Subject: [PATCH] Preemptively schedule a scene update when rendering an updated SceneInvalidated Effective FPS is now 60 instead of 30 --- .../Rendering/DeferredRenderer.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs b/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs index d5e361ca0e..24ff600ca9 100644 --- a/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs +++ b/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs @@ -318,17 +318,25 @@ namespace Avalonia.Rendering _lastSceneId = scene.Generation; + var isUiThread = Dispatcher.UIThread.CheckAccess(); // We have consumed the previously available scene, but there might be some dirty // rects since the last update. *If* we are on UI thread, we can force immediate scene // rebuild before rendering anything on-screen // We are calling the same method recursively here - if (!recursiveCall && Dispatcher.UIThread.CheckAccess() && NeedsUpdate) + if (!recursiveCall && isUiThread && NeedsUpdate) { UpdateScene(); var (rs, _) = UpdateRenderLayersAndConsumeSceneIfNeeded(ref context, true); return (rs, true); } + // We are rendering a new scene version, so it's highly likely + // that there is already a pending update for animations + // So we are scheduling an update call so UI thread could prepare a scene before + // the next render timer tick + if (!recursiveCall && !isUiThread) + Dispatcher.UIThread.InvokeAsync(UpdateSceneIfNeeded, DispatcherPriority.Render); + // Indicate that we have updated the layers return (sceneRef.Clone(), true); } @@ -534,6 +542,12 @@ namespace Avalonia.Rendering context = RenderTarget.CreateDrawingContext(this); } + private void UpdateSceneIfNeeded() + { + if(NeedsUpdate) + UpdateScene(); + } + private void UpdateScene() { Dispatcher.UIThread.VerifyAccess();