From ae1e3dd4218a7365112211b28a2d7a770bbcff2a Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Tue, 18 Dec 2018 13:24:08 +0300 Subject: [PATCH 1/4] Fixed some distortions on GL backend --- src/Skia/Avalonia.Skia/GlRenderTarget.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Skia/Avalonia.Skia/GlRenderTarget.cs b/src/Skia/Avalonia.Skia/GlRenderTarget.cs index 3360255dae..81c70e2be7 100644 --- a/src/Skia/Avalonia.Skia/GlRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/GlRenderTarget.cs @@ -35,6 +35,7 @@ namespace Avalonia.Skia gl.ClearStencil(0); gl.ClearColor(0, 0, 0, 0); gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + _grContext.ResetContext(); GRBackendRenderTarget renderTarget = new GRBackendRenderTarget(size.Width, size.Height, disp.SampleCount, disp.StencilSize, From d470461202a7f780f526eb9b932298406889bf77 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Tue, 18 Dec 2018 13:24:44 +0300 Subject: [PATCH 2/4] More thread safety and ownsImpl argument for DrawingContext --- .../Threading/ThreadSafeObjectPool.cs | 29 +++++++++++++++++ src/Avalonia.Visuals/Media/DrawingContext.cs | 31 +++++++++++++------ 2 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 src/Avalonia.Base/Threading/ThreadSafeObjectPool.cs diff --git a/src/Avalonia.Base/Threading/ThreadSafeObjectPool.cs b/src/Avalonia.Base/Threading/ThreadSafeObjectPool.cs new file mode 100644 index 0000000000..c6845485dc --- /dev/null +++ b/src/Avalonia.Base/Threading/ThreadSafeObjectPool.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; + +namespace Avalonia.Threading +{ + public class ThreadSafeObjectPool where T : class, new() + { + private Stack _stack = new Stack(); + private object _lock = new object(); + public static ThreadSafeObjectPool Default { get; } = new ThreadSafeObjectPool(); + + public T Get() + { + lock (_lock) + { + if(_stack.Count == 0) + return new T(); + return _stack.Pop(); + } + } + + public void Return(T obj) + { + lock (_stack) + { + _stack.Push(obj); + } + } + } +} diff --git a/src/Avalonia.Visuals/Media/DrawingContext.cs b/src/Avalonia.Visuals/Media/DrawingContext.cs index 6b19167381..9556cd9b26 100644 --- a/src/Avalonia.Visuals/Media/DrawingContext.cs +++ b/src/Avalonia.Visuals/Media/DrawingContext.cs @@ -2,23 +2,26 @@ using System; using System.Collections.Generic; using Avalonia.Media.Imaging; using Avalonia.Platform; +using Avalonia.Threading; using Avalonia.Visuals.Media.Imaging; namespace Avalonia.Media { public sealed class DrawingContext : IDisposable { + private readonly bool _ownsImpl; private int _currentLevel; - static readonly Stack> StateStackPool = new Stack>(); - static readonly Stack> TransformStackPool = new Stack>(); + private static readonly ThreadSafeObjectPool> StateStackPool = + ThreadSafeObjectPool>.Default; - private Stack _states = StateStackPool.Count == 0 ? new Stack() : StateStackPool.Pop(); + private static readonly ThreadSafeObjectPool> TransformStackPool = + ThreadSafeObjectPool>.Default; - private Stack _transformContainers = TransformStackPool.Count == 0 - ? new Stack() - : TransformStackPool.Pop(); + private Stack _states = StateStackPool.Get(); + + private Stack _transformContainers = TransformStackPool.Get(); readonly struct TransformContainer { @@ -35,6 +38,13 @@ namespace Avalonia.Media public DrawingContext(IDrawingContextImpl impl) { PlatformImpl = impl; + _ownsImpl = true; + } + + public DrawingContext(IDrawingContextImpl impl, bool ownsImpl) + { + _ownsImpl = ownsImpl; + PlatformImpl = impl; } public IDrawingContextImpl PlatformImpl { get; } @@ -299,11 +309,14 @@ namespace Avalonia.Media { while (_states.Count != 0) _states.Peek().Dispose(); - StateStackPool.Push(_states); + StateStackPool.Return(_states); _states = null; - TransformStackPool.Push(_transformContainers); + if (_transformContainers.Count != 0) + throw new InvalidOperationException("Transform container stack is non-empty"); + TransformStackPool.Return(_transformContainers); _transformContainers = null; - PlatformImpl.Dispose(); + if (_ownsImpl) + PlatformImpl.Dispose(); } private static bool PenIsVisible(Pen pen) From 01e2345251bb0c4eb7a5dadd3c69fde3d5ecc562 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Tue, 18 Dec 2018 18:30:59 +0300 Subject: [PATCH 3/4] Preserve LayoutBounds on visual node clone --- src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs index 8000d413ea..159c3cd0fa 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs @@ -220,6 +220,7 @@ namespace Avalonia.Rendering.SceneGraph Transform = Transform, ClipBounds = ClipBounds, ClipToBounds = ClipToBounds, + LayoutBounds = LayoutBounds, GeometryClip = GeometryClip, _opacity = Opacity, OpacityMask = OpacityMask, From e1a411d487095098708444b2118aa80af945f093 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Fri, 21 Dec 2018 17:02:06 +0300 Subject: [PATCH 4/4] fields to properties --- src/Avalonia.Visuals/Media/DrawingContext.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Avalonia.Visuals/Media/DrawingContext.cs b/src/Avalonia.Visuals/Media/DrawingContext.cs index 9556cd9b26..e7d6df5a93 100644 --- a/src/Avalonia.Visuals/Media/DrawingContext.cs +++ b/src/Avalonia.Visuals/Media/DrawingContext.cs @@ -13,10 +13,10 @@ namespace Avalonia.Media private int _currentLevel; - private static readonly ThreadSafeObjectPool> StateStackPool = + private static ThreadSafeObjectPool> StateStackPool { get; } = ThreadSafeObjectPool>.Default; - private static readonly ThreadSafeObjectPool> TransformStackPool = + private static ThreadSafeObjectPool> TransformStackPool { get; } = ThreadSafeObjectPool>.Default; private Stack _states = StateStackPool.Get();