diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index 076d69ae4a..fabfe2b225 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Threading; using Avalonia.Media; using Avalonia.Platform; using Avalonia.Rendering; @@ -20,7 +21,7 @@ namespace Avalonia.Skia /// public class DrawingContextImpl : IDrawingContextImpl { - private readonly IDisposable[] _disposables; + private IDisposable[] _disposables; private readonly Vector _dpi; private readonly Stack _maskStack = new Stack(); private readonly Stack _opacityStack = new Stack(); @@ -30,7 +31,7 @@ namespace Avalonia.Skia private readonly bool _canTextUseLcdRendering; private Matrix _currentTransform; private GRContext _grContext; - + private bool _disposed; /// /// Context create info. /// @@ -74,6 +75,8 @@ namespace Avalonia.Skia _disposables = disposables; _canTextUseLcdRendering = !createInfo.DisableTextLcdRendering; _grContext = createInfo.GrContext; + if (_grContext != null) + Monitor.Enter(_grContext); Canvas = createInfo.Canvas; @@ -257,14 +260,26 @@ namespace Avalonia.Skia /// public virtual void Dispose() { - if (_disposables == null) - { + if(_disposed) return; - } + try + { + if (_grContext != null) + { + Monitor.Exit(_grContext); + _grContext = null; + } - foreach (var disposable in _disposables) + if (_disposables != null) + { + foreach (var disposable in _disposables) + disposable?.Dispose(); + _disposables = null; + } + } + finally { - disposable?.Dispose(); + _disposed = true; } } diff --git a/src/Skia/Avalonia.Skia/GlRenderTarget.cs b/src/Skia/Avalonia.Skia/GlRenderTarget.cs index 81c70e2be7..7b28b87d56 100644 --- a/src/Skia/Avalonia.Skia/GlRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/GlRenderTarget.cs @@ -35,31 +35,36 @@ 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, - new GRGlFramebufferInfo((uint)fb, GRPixelConfig.Rgba8888.ToGlSizedFormat())); - var surface = SKSurface.Create(_grContext, renderTarget, - GRSurfaceOrigin.BottomLeft, - GRPixelConfig.Rgba8888.ToColorType()); - - var nfo = new DrawingContextImpl.CreateInfo + lock (_grContext) { - GrContext = _grContext, - Canvas = surface.Canvas, - Dpi = SkiaPlatform.DefaultDpi * scaling, - VisualBrushRenderer = visualBrushRenderer, - DisableTextLcdRendering = true - }; + _grContext.ResetContext(); - return new DrawingContextImpl(nfo, Disposable.Create(() => - { - surface.Canvas.Flush(); - surface.Dispose(); - renderTarget.Dispose(); - session.Dispose(); - })); + GRBackendRenderTarget renderTarget = + new GRBackendRenderTarget(size.Width, size.Height, disp.SampleCount, disp.StencilSize, + new GRGlFramebufferInfo((uint)fb, GRPixelConfig.Rgba8888.ToGlSizedFormat())); + var surface = SKSurface.Create(_grContext, renderTarget, + GRSurfaceOrigin.BottomLeft, + GRPixelConfig.Rgba8888.ToColorType()); + + var nfo = new DrawingContextImpl.CreateInfo + { + GrContext = _grContext, + Canvas = surface.Canvas, + Dpi = SkiaPlatform.DefaultDpi * scaling, + VisualBrushRenderer = visualBrushRenderer, + DisableTextLcdRendering = true + }; + + return new DrawingContextImpl(nfo, Disposable.Create(() => + { + + surface.Canvas.Flush(); + surface.Dispose(); + renderTarget.Dispose(); + _grContext.Flush(); + session.Dispose(); + })); + } } } }