From 34227686d4e243e1e3e3daa349476c2ab00eb104 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 17 Nov 2016 21:12:57 +0100 Subject: [PATCH] Render child visual nodes explicitly. Render them in DeferredRenderer rather than in VisualNode. --- .../Rendering/DeferredRenderer.cs | 23 ++++++++++++++++++- .../Rendering/SceneGraph/IGeometryNode.cs | 5 ---- .../Rendering/SceneGraph/ISceneNode.cs | 2 ++ .../Rendering/SceneGraph/VisualNode.cs | 10 +++++++- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs b/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs index 3660265b4d..8f10b263f9 100644 --- a/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs +++ b/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs @@ -6,6 +6,7 @@ using Avalonia.Rendering.SceneGraph; using Avalonia.Threading; using Avalonia.VisualTree; using System.Collections.Generic; +using System.Collections.Concurrent; namespace Avalonia.Rendering { @@ -68,6 +69,26 @@ namespace Avalonia.Rendering { } + private void Render(IDrawingContextImpl context, IVisualNode node, Rect clipBounds) + { + clipBounds = node.Bounds.Intersect(clipBounds); + + if (!clipBounds.IsEmpty) + { + node.Render(context); + + foreach (var child in node.Children) + { + var visualChild = child as IVisualNode; + + if (visualChild != null) + { + Render(context, visualChild, clipBounds); + } + } + } + } + private void RenderFps(IDrawingContextImpl context) { var now = _stopwatch.Elapsed; @@ -141,7 +162,7 @@ namespace Avalonia.Rendering using (var context = _renderTarget.CreateDrawingContext()) { - _scene.Root.Render(context); + Render(context, _scene.Root, new Rect(_root.ClientSize)); if (DrawFps) { diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/IGeometryNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/IGeometryNode.cs index ee8c1aa81e..4a9daf0ec9 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/IGeometryNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/IGeometryNode.cs @@ -10,11 +10,6 @@ namespace Avalonia.Rendering.SceneGraph /// public interface IGeometryNode : ISceneNode { - /// - /// Gets the bounds of the node in global coordinates. - /// - Rect Bounds { get; } - /// /// Hit test the geometry in this node. /// diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/ISceneNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/ISceneNode.cs index 37fa5a9463..278bac97ba 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/ISceneNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/ISceneNode.cs @@ -11,6 +11,8 @@ namespace Avalonia.Rendering.SceneGraph /// public interface ISceneNode { + Rect Bounds { get; } + /// /// Renders the node to a drawing context. /// diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs index 9faaefa2aa..fc7ef78ec9 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs @@ -13,6 +13,8 @@ namespace Avalonia.Rendering.SceneGraph /// public class VisualNode : IVisualNode { + private Rect? _bounds; + /// /// Initializes a new instance of the class. /// @@ -42,6 +44,9 @@ namespace Avalonia.Rendering.SceneGraph /// public Matrix Transform { get; set; } + // TODO: Calculate real bounds. + public Rect Bounds => ClipBounds; + /// public Rect ClipBounds { get; set; } @@ -125,7 +130,10 @@ namespace Avalonia.Rendering.SceneGraph foreach (var child in Children) { - child.Render(context); + if (!(child is IVisualNode)) + { + child.Render(context); + } } if (ClipToBounds)