From 37c65262ac1db3f2cf89669253a44639adcd03fe Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Mon, 14 Jan 2019 11:25:56 +0300 Subject: [PATCH] [RENDER] Don't copy "resized" layer contents + properly remove unneded layers --- .../Rendering/DeferredRenderer.cs | 33 +++++++++++++++---- src/Avalonia.Visuals/Rendering/RenderLayer.cs | 12 +++---- .../Rendering/RenderLayers.cs | 6 ++-- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs b/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs index b48efaa34e..0a46abbf92 100644 --- a/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs +++ b/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs @@ -336,16 +336,34 @@ namespace Avalonia.Rendering private void RenderToLayers(Scene scene) { - if (scene.Layers.HasDirty) + foreach (var layer in scene.Layers) { - foreach (var layer in scene.Layers) - { - var renderTarget = Layers[layer.LayerRoot].Bitmap; - var node = (VisualNode)scene.FindNode(layer.LayerRoot); + var renderLayer = Layers[layer.LayerRoot]; + if (layer.Dirty.IsEmpty && !renderLayer.IsEmpty) + continue; + var renderTarget = renderLayer.Bitmap; + var node = (VisualNode)scene.FindNode(layer.LayerRoot); - if (node != null) + if (node != null) + { + using (var context = renderTarget.Item.CreateDrawingContext(this)) { - using (var context = renderTarget.Item.CreateDrawingContext(this)) + if (renderLayer.IsEmpty) + { + // Render entire layer root node + context.Clear(Colors.Transparent); + context.Transform = Matrix.Identity; + context.PushClip(node.ClipBounds); + Render(context, node, layer.LayerRoot, node.ClipBounds); + context.PopClip(); + if (DrawDirtyRects) + { + _dirtyRectsDisplay.Add(node.ClipBounds); + } + + renderLayer.IsEmpty = false; + } + else { foreach (var rect in layer.Dirty) { @@ -364,6 +382,7 @@ namespace Avalonia.Rendering } } } + } private void RenderOverlay(Scene scene, IDrawingContextImpl parentContent) diff --git a/src/Avalonia.Visuals/Rendering/RenderLayer.cs b/src/Avalonia.Visuals/Rendering/RenderLayer.cs index cd09bdee10..d6676e25ff 100644 --- a/src/Avalonia.Visuals/Rendering/RenderLayer.cs +++ b/src/Avalonia.Visuals/Rendering/RenderLayer.cs @@ -7,39 +7,39 @@ namespace Avalonia.Rendering { public class RenderLayer { - private readonly IDrawingContextImpl _drawingContext; - public RenderLayer( IDrawingContextImpl drawingContext, Size size, double scaling, IVisual layerRoot) { - _drawingContext = drawingContext; Bitmap = RefCountable.Create(drawingContext.CreateLayer(size)); Size = size; Scaling = scaling; LayerRoot = layerRoot; + IsEmpty = true; } public IRef Bitmap { get; private set; } + public bool IsEmpty { get; set; } public double Scaling { get; private set; } public Size Size { get; private set; } public IVisual LayerRoot { get; } - public void ResizeBitmap(Size size, double scaling) + public void RecreateBitmap(IDrawingContextImpl drawingContext, Size size, double scaling) { if (Size != size || Scaling != scaling) { - var resized = RefCountable.Create(_drawingContext.CreateLayer(size)); + var resized = RefCountable.Create(drawingContext.CreateLayer(size)); using (var context = resized.Item.CreateDrawingContext(null)) { context.Clear(Colors.Transparent); - context.DrawImage(Bitmap, 1, new Rect(Size), new Rect(Size)); Bitmap.Dispose(); Bitmap = resized; + Scaling = scaling; Size = size; + IsEmpty = true; } } } diff --git a/src/Avalonia.Visuals/Rendering/RenderLayers.cs b/src/Avalonia.Visuals/Rendering/RenderLayers.cs index 9b0ce944e7..0ff7862ab6 100644 --- a/src/Avalonia.Visuals/Rendering/RenderLayers.cs +++ b/src/Avalonia.Visuals/Rendering/RenderLayers.cs @@ -29,11 +29,11 @@ namespace Avalonia.Rendering } else { - layer.ResizeBitmap(scene.Size, scene.Scaling); + layer.RecreateBitmap(context, scene.Size, scene.Scaling); } } - for (var i = _inner.Count - 1; i >= 0; --i) + for (var i = 0; i < _inner.Count;) { var layer = _inner[i]; @@ -43,6 +43,8 @@ namespace Avalonia.Rendering _inner.RemoveAt(i); _index.Remove(layer.LayerRoot); } + else + i++; } }