From 3d5d1377533be0322632944fadb4e15a783ba045 Mon Sep 17 00:00:00 2001 From: Jumar Macato Date: Thu, 18 Mar 2021 17:37:49 +0800 Subject: [PATCH] enable updates if there's a visual with render critical timing on it. --- .../Pages/TimeCriticalRenderPage.cs | 9 ++++++-- .../Rendering/DeferredRenderer.cs | 3 ++- .../Rendering/SceneGraph/Scene.cs | 12 +++++++--- .../Rendering/SceneGraph/SceneBuilder.cs | 22 ++++++++++++++++++- 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/samples/ControlCatalog/Pages/TimeCriticalRenderPage.cs b/samples/ControlCatalog/Pages/TimeCriticalRenderPage.cs index ddfedfa981..dad6a624c2 100644 --- a/samples/ControlCatalog/Pages/TimeCriticalRenderPage.cs +++ b/samples/ControlCatalog/Pages/TimeCriticalRenderPage.cs @@ -21,7 +21,7 @@ namespace ControlCatalog.Pages private Typeface _typeface = Typeface.Default; - public void ThreadSafeRender(DrawingContext context, Size logicalSize, double scaling) + public override void Render(DrawingContext context) { var nowTs = _st.Elapsed; var now = DateTime.Now; @@ -43,9 +43,14 @@ namespace ControlCatalog.Pages }; var back = new ImmutableSolidColorBrush(Colors.LightGray); var textBrush = new ImmutableSolidColorBrush(Colors.Black); - context.FillRectangle(back, new Rect(logicalSize)); + context.FillRectangle(back, new Rect(0,0,12,12)); context.DrawText(textBrush, new Point(5, 5), fmt); _frame++; } + + public void ThreadSafeRender(DrawingContext context, Size logicalSize, double scaling) + { + + } } } diff --git a/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs b/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs index 3bd8e05ee2..4c7968dcd9 100644 --- a/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs +++ b/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs @@ -250,7 +250,7 @@ namespace Avalonia.Rendering } } - bool NeedsUpdate => _dirty == null || _dirty.Count > 0; + private bool NeedsUpdate => _dirty == null || _dirty.Count > 0 || (_scene?.Item?.HasCriticalVisual ?? false); bool IRenderLoopTask.NeedsUpdate => NeedsUpdate; void IRenderLoopTask.Update(TimeSpan time) => UpdateScene(); @@ -631,6 +631,7 @@ namespace Avalonia.Rendering foreach (var visual in _recalculateChildren) { var node = scene.FindNode(visual); + ((VisualNode)node)?.SortChildren(scene); } diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs index 6a4c532d4a..2bdfb9758c 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/Scene.cs @@ -25,12 +25,14 @@ namespace Avalonia.Rendering.SceneGraph new VisualNode(rootVisual, null), new Dictionary(), new SceneLayers(rootVisual), - 0) + 0, + false) { _index.Add(rootVisual, Root); } - private Scene(VisualNode root, Dictionary index, SceneLayers layers, int generation) + private Scene(VisualNode root, Dictionary index, SceneLayers layers, int generation, + bool hasCriticalVisual) { Contract.Requires(root != null); @@ -41,6 +43,7 @@ namespace Avalonia.Rendering.SceneGraph Layers = layers; Generation = generation; root.LayerRoot = root.Visual; + HasCriticalVisual = hasCriticalVisual; } public Task Rendered => _rendered.Task; @@ -70,6 +73,9 @@ namespace Avalonia.Rendering.SceneGraph /// public double Scaling { get; set; } = 1; + public bool HasCriticalVisual { get; + set; } + /// /// Adds a node to the scene index. /// @@ -90,7 +96,7 @@ namespace Avalonia.Rendering.SceneGraph var index = new Dictionary(_index.Count); var root = Clone((VisualNode)Root, null, index); - var result = new Scene(root, index, Layers.Clone(), Generation + 1) + var result = new Scene(root, index, Layers.Clone(), Generation + 1, HasCriticalVisual) { Size = Size, Scaling = Scaling, diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs index 7d5d62a091..6e2bc58cb5 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs @@ -49,6 +49,11 @@ namespace Avalonia.Rendering.SceneGraph UpdateSize(scene); } + if (visual is IRenderTimeCriticalVisual criticalVisual) + { + ForceUpdateCriticalRender(scene, visual); + } + if (visual.VisualRoot == scene.Root.Visual) { if (node?.Parent != null && @@ -297,11 +302,20 @@ namespace Avalonia.Rendering.SceneGraph } } } - + + // TODO: Im clueless so im just copying the above method to force a dirty rect. + private void ForceUpdateCriticalRender(Scene scene, IVisual visual) + { + } + private static VisualNode CreateNode(Scene scene, IVisual visual, VisualNode parent) { var node = new VisualNode(visual, parent); node.LayerRoot = parent.LayerRoot; + if (visual is IRenderTimeCriticalVisual) + { + scene.HasCriticalVisual = true; + } scene.Add(node); return node; } @@ -315,6 +329,12 @@ namespace Avalonia.Rendering.SceneGraph Deindex(scene, visual); } } + + if (node.Visual is IRenderTimeCriticalVisual) + { + scene.HasCriticalVisual = false; + } + scene.Remove(node); node.SubTreeUpdated = true;