From c3fb89ee732cbeb93c5aced3b3f7472d95b2518f Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 5 Aug 2016 19:17:19 -0400 Subject: [PATCH] Add code to re-create a render target and re-render the frame when the render target gets corrupted. Should fix #521 --- .../Platform/ITopLevelRenderer.cs | 12 +++++++- .../Avalonia.SceneGraph.csproj | 1 + .../RenderTargetCorruptedException.cs | 30 +++++++++++++++++++ .../Media/DrawingContext.cs | 9 +++++- 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 src/Avalonia.SceneGraph/RenderTargetCorruptedException.cs diff --git a/src/Avalonia.Controls/Platform/ITopLevelRenderer.cs b/src/Avalonia.Controls/Platform/ITopLevelRenderer.cs index d81ff6efd1..41054e610e 100644 --- a/src/Avalonia.Controls/Platform/ITopLevelRenderer.cs +++ b/src/Avalonia.Controls/Platform/ITopLevelRenderer.cs @@ -38,7 +38,17 @@ namespace Avalonia.Controls.Platform topLevel.PlatformImpl.Paint = rect => { - viewport.Render(topLevel); + try + { + viewport.Render(topLevel); + } + catch (RenderTargetCorruptedException ex) + { + Logging.Logger.Error("Renderer", this, "Render target was corrupted. Exception: {0}", ex); + viewport.Dispose(); + viewport = PlatformManager.CreateRenderTarget(topLevel.PlatformImpl); + topLevel.PlatformImpl.Paint(rect); // Retry painting + } queueManager.RenderFinished(); }; diff --git a/src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj b/src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj index f6dc1c4f3c..25a79307e6 100644 --- a/src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj +++ b/src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj @@ -100,6 +100,7 @@ + diff --git a/src/Avalonia.SceneGraph/RenderTargetCorruptedException.cs b/src/Avalonia.SceneGraph/RenderTargetCorruptedException.cs new file mode 100644 index 0000000000..f67a866be2 --- /dev/null +++ b/src/Avalonia.SceneGraph/RenderTargetCorruptedException.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Avalonia +{ + public class RenderTargetCorruptedException : Exception + { + public RenderTargetCorruptedException() + { + } + + public RenderTargetCorruptedException(string message) + : base(message) + { + } + + public RenderTargetCorruptedException(Exception innerException) + : base(null, innerException) + { + } + + public RenderTargetCorruptedException(string message, Exception innerException) + : base(message, innerException) + { + } + } +} diff --git a/src/Windows/Avalonia.Direct2D1/Media/DrawingContext.cs b/src/Windows/Avalonia.Direct2D1/Media/DrawingContext.cs index 61ba43123b..75a0f43d9f 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DrawingContext.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/DrawingContext.cs @@ -57,7 +57,14 @@ namespace Avalonia.Direct2D1.Media { foreach (var layer in _layerPool) layer.Dispose(); - _renderTarget.EndDraw(); + try + { + _renderTarget.EndDraw(); + } + catch (SharpDXException ex) when((uint)ex.HResult == 0x8899000C) // D2DERR_RECREATE_TARGET + { + throw new RenderTargetCorruptedException(ex); + } } ///