From e5943a352352222fa5c73ed92a5830b875435e74 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 27 Jul 2019 15:49:12 +0300 Subject: [PATCH] Dispose GL drawing session if we were unable to create a drawing context --- src/Skia/Avalonia.Skia/GlRenderTarget.cs | 89 ++++++++++++++---------- 1 file changed, 51 insertions(+), 38 deletions(-) diff --git a/src/Skia/Avalonia.Skia/GlRenderTarget.cs b/src/Skia/Avalonia.Skia/GlRenderTarget.cs index a7c1d0a38b..61ccf09e52 100644 --- a/src/Skia/Avalonia.Skia/GlRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/GlRenderTarget.cs @@ -26,51 +26,64 @@ namespace Avalonia.Skia public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer) { var session = _surface.BeginDraw(); - var disp = session.Display; - var gl = disp.GlInterface; - gl.GetIntegerv(GL_FRAMEBUFFER_BINDING, out var fb); - - var size = session.Size; - var scaling = session.Scaling; - if (size.Width <= 0 || size.Height <= 0 || scaling < 0) - { - throw new InvalidOperationException( - $"Can't create drawing context for surface with {size} size and {scaling} scaling"); - } - - gl.Viewport(0, 0, size.Width, size.Height); - gl.ClearStencil(0); - gl.ClearColor(0, 0, 0, 0); - gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - lock (_grContext) + bool success = false; + try { - _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 disp = session.Display; + var gl = disp.GlInterface; + gl.GetIntegerv(GL_FRAMEBUFFER_BINDING, out var fb); - var nfo = new DrawingContextImpl.CreateInfo + var size = session.Size; + var scaling = session.Scaling; + if (size.Width <= 0 || size.Height <= 0 || scaling < 0) { - GrContext = _grContext, - Canvas = surface.Canvas, - Dpi = SkiaPlatform.DefaultDpi * scaling, - VisualBrushRenderer = visualBrushRenderer, - DisableTextLcdRendering = true - }; + session.Dispose(); + throw new InvalidOperationException( + $"Can't create drawing context for surface with {size} size and {scaling} scaling"); + } - return new DrawingContextImpl(nfo, Disposable.Create(() => + gl.Viewport(0, 0, size.Width, size.Height); + gl.ClearStencil(0); + gl.ClearColor(0, 0, 0, 0); + gl.Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + lock (_grContext) { + _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 + { + GrContext = _grContext, + Canvas = surface.Canvas, + Dpi = SkiaPlatform.DefaultDpi * scaling, + VisualBrushRenderer = visualBrushRenderer, + DisableTextLcdRendering = true + }; + - surface.Canvas.Flush(); - surface.Dispose(); - renderTarget.Dispose(); - _grContext.Flush(); + var ctx = new DrawingContextImpl(nfo, Disposable.Create(() => + { + + surface.Canvas.Flush(); + surface.Dispose(); + renderTarget.Dispose(); + _grContext.Flush(); + session.Dispose(); + })); + success = true; + return ctx; + } + } + finally + { + if(!success) session.Dispose(); - })); } } }