Browse Source

Merge branch 'master' into fixes/2912-onewaytosource-stackoverflow

pull/2984/head
Jumar Macato 7 years ago
committed by GitHub
parent
commit
aad8ea12b3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 57
      src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
  2. 14
      src/Avalonia.Visuals/Rendering/RenderLoop.cs

57
src/Avalonia.Visuals/Rendering/DeferredRenderer.cs

@ -246,22 +246,7 @@ namespace Avalonia.Rendering
{ {
try try
{ {
IDrawingContextImpl GetContext() var (scene, updated) = UpdateRenderLayersAndConsumeSceneIfNeeded(ref context);
{
if (context != null)
return context;
if ((RenderTarget as IRenderTargetWithCorruptionInfo)?.IsCorrupted == true)
{
RenderTarget.Dispose();
RenderTarget = null;
}
if (RenderTarget == null)
RenderTarget = ((IRenderRoot)_root).CreateRenderTarget();
return context = RenderTarget.CreateDrawingContext(this);
}
var (scene, updated) = UpdateRenderLayersAndConsumeSceneIfNeeded(GetContext);
using (scene) using (scene)
{ {
@ -271,9 +256,9 @@ namespace Avalonia.Rendering
if (DrawDirtyRects) if (DrawDirtyRects)
_dirtyRectsDisplay.Tick(); _dirtyRectsDisplay.Tick();
if (overlay) if (overlay)
RenderOverlay(scene.Item, GetContext()); RenderOverlay(scene.Item, ref context);
if (updated || forceComposite || overlay) if (updated || forceComposite || overlay)
RenderComposite(scene.Item, GetContext()); RenderComposite(scene.Item, ref context);
} }
} }
} }
@ -291,7 +276,7 @@ namespace Avalonia.Rendering
} }
} }
private (IRef<Scene> scene, bool updated) UpdateRenderLayersAndConsumeSceneIfNeeded(Func<IDrawingContextImpl> contextFactory, private (IRef<Scene> scene, bool updated) UpdateRenderLayersAndConsumeSceneIfNeeded(ref IDrawingContextImpl context,
bool recursiveCall = false) bool recursiveCall = false)
{ {
IRef<Scene> sceneRef; IRef<Scene> sceneRef;
@ -304,7 +289,8 @@ namespace Avalonia.Rendering
var scene = sceneRef.Item; var scene = sceneRef.Item;
if (scene.Generation != _lastSceneId) if (scene.Generation != _lastSceneId)
{ {
var context = contextFactory(); EnsureDrawingContext(ref context);
Layers.Update(scene, context); Layers.Update(scene, context);
RenderToLayers(scene); RenderToLayers(scene);
@ -325,7 +311,7 @@ namespace Avalonia.Rendering
if (!recursiveCall && Dispatcher.UIThread.CheckAccess() && NeedsUpdate) if (!recursiveCall && Dispatcher.UIThread.CheckAccess() && NeedsUpdate)
{ {
UpdateScene(); UpdateScene();
var (rs, _) = UpdateRenderLayersAndConsumeSceneIfNeeded(contextFactory, true); var (rs, _) = UpdateRenderLayersAndConsumeSceneIfNeeded(ref context, true);
return (rs, true); return (rs, true);
} }
@ -432,8 +418,10 @@ namespace Avalonia.Rendering
} }
private void RenderOverlay(Scene scene, IDrawingContextImpl parentContent) private void RenderOverlay(Scene scene, ref IDrawingContextImpl parentContent)
{ {
EnsureDrawingContext(ref parentContent);
if (DrawDirtyRects) if (DrawDirtyRects)
{ {
var overlay = GetOverlay(parentContent, scene.Size, scene.Scaling); var overlay = GetOverlay(parentContent, scene.Size, scene.Scaling);
@ -460,8 +448,10 @@ namespace Avalonia.Rendering
} }
} }
private void RenderComposite(Scene scene, IDrawingContextImpl context) private void RenderComposite(Scene scene, ref IDrawingContextImpl context)
{ {
EnsureDrawingContext(ref context);
context.Clear(Colors.Transparent); context.Clear(Colors.Transparent);
var clientRect = new Rect(scene.Size); var clientRect = new Rect(scene.Size);
@ -503,6 +493,27 @@ namespace Avalonia.Rendering
} }
} }
private void EnsureDrawingContext(ref IDrawingContextImpl context)
{
if (context != null)
{
return;
}
if ((RenderTarget as IRenderTargetWithCorruptionInfo)?.IsCorrupted == true)
{
RenderTarget.Dispose();
RenderTarget = null;
}
if (RenderTarget == null)
{
RenderTarget = ((IRenderRoot)_root).CreateRenderTarget();
}
context = RenderTarget.CreateDrawingContext(this);
}
private void UpdateScene() private void UpdateScene()
{ {
Dispatcher.UIThread.VerifyAccess(); Dispatcher.UIThread.VerifyAccess();

14
src/Avalonia.Visuals/Rendering/RenderLoop.cs

@ -91,7 +91,19 @@ namespace Avalonia.Rendering
{ {
try try
{ {
if (_items.Any(item => item.NeedsUpdate) && bool needsUpdate = false;
foreach (IRenderLoopTask item in _items)
{
if (item.NeedsUpdate)
{
needsUpdate = true;
break;
}
}
if (needsUpdate &&
Interlocked.CompareExchange(ref _inUpdate, 1, 0) == 0) Interlocked.CompareExchange(ref _inUpdate, 1, 0) == 0)
{ {
_dispatcher.Post(() => _dispatcher.Post(() =>

Loading…
Cancel
Save