Browse Source

Do not update composition target when rendering is stopped (#21192)

* Do not update composition target when rendering is stopped

* Address copilot review
pull/21219/head
Julien Lebosquain 6 months ago
committed by GitHub
parent
commit
5ce4a3ddba
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 15
      src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
  2. 36
      tests/Avalonia.Base.UnitTests/Rendering/CompositorLifetimeTests.cs
  3. 4
      tests/Avalonia.UnitTests/CompositorTestServices.cs

15
src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs

@ -2,18 +2,13 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Numerics;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Collections;
using Avalonia.Collections.Pooled;
using Avalonia.Diagnostics;
using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Media;
using Avalonia.Rendering.Composition.Drawing;
using Avalonia.Threading;
using Avalonia.VisualTree;
namespace Avalonia.Rendering.Composition;
@ -201,6 +196,13 @@ internal class CompositingRenderer : IRendererWithCompositor, IHitTester
{
if(_updating)
return;
if (!CompositionTarget.IsEnabled)
{
_queuedUpdate = false;
return;
}
_updating = true;
try
{
@ -237,6 +239,9 @@ internal class CompositingRenderer : IRendererWithCompositor, IHitTester
return;
CompositionTarget.IsEnabled = true;
if (_dirty.Count > 0 || _recalculateChildren.Count > 0)
QueueUpdate();
}
/// <inheritdoc />

36
tests/Avalonia.Base.UnitTests/Rendering/CompositorLifetimeTests.cs

@ -0,0 +1,36 @@
using Avalonia.Rendering.Composition;
using Avalonia.UnitTests;
using Avalonia.VisualTree;
using Xunit;
namespace Avalonia.Base.UnitTests.Rendering;
public class CompositorLifetimeTests : CompositorTestsBase
{
[Fact]
public void InvalidateVisual_Does_Not_Update_RenderingTarget_When_Rendering_Stopped()
{
using var services = new CompositorTestServices(new Size(200, 200));
var presentationSource = services.TopLevel.GetPresentationSource();
Assert.NotNull(presentationSource);
var compositionTarget = ((CompositingRenderer)presentationSource.Renderer).CompositionTarget;
Assert.True(compositionTarget.IsEnabled);
Assert.Equal(new PixelSize(200, 200), compositionTarget.PixelSize);
// Stop rendering and invalidate a visual: this should not result in an update
services.TopLevel.StopRendering();
((CompositorTestServices.TopLevelImpl)services.TopLevel.PlatformImpl!).ClientSize = new Size(300, 300);
services.TopLevel.InvalidateVisual();
services.RunJobs();
Assert.Equal(new PixelSize(200, 200), compositionTarget.PixelSize);
// Check that restarting rendering re-queues the pending invalidation
services.TopLevel.StartRendering();
services.RunJobs();
Assert.Equal(new PixelSize(300, 300), compositionTarget.PixelSize);
}
}

4
tests/Avalonia.UnitTests/CompositorTestServices.cs

@ -142,7 +142,7 @@ public class CompositorTestServices : IDisposable
public void TriggerTick() => Tick?.Invoke(TimeSpan.Zero);
}
class TopLevelImpl : ITopLevelImpl
public class TopLevelImpl : ITopLevelImpl
{
private readonly Compositor _compositor;
@ -159,7 +159,7 @@ public class CompositorTestServices : IDisposable
public double DesktopScaling => 1;
public IPlatformHandle? Handle => null;
public Size ClientSize { get; }
public Size ClientSize { get; set; }
public double RenderScaling => 1;
public IPlatformRenderSurface[] Surfaces { get; } = [new DummyFramebufferSurface()];
public Action<RawInputEventArgs>? Input { get; set; }

Loading…
Cancel
Save