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.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Numerics;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Collections;
using Avalonia.Collections.Pooled;
using Avalonia.Diagnostics; using Avalonia.Diagnostics;
using Avalonia.Platform;
using Avalonia.Platform.Surfaces; using Avalonia.Platform.Surfaces;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Rendering.Composition.Drawing; using Avalonia.Rendering.Composition.Drawing;
using Avalonia.Threading; using Avalonia.Threading;
using Avalonia.VisualTree;
namespace Avalonia.Rendering.Composition; namespace Avalonia.Rendering.Composition;
@ -201,6 +196,13 @@ internal class CompositingRenderer : IRendererWithCompositor, IHitTester
{ {
if(_updating) if(_updating)
return; return;
if (!CompositionTarget.IsEnabled)
{
_queuedUpdate = false;
return;
}
_updating = true; _updating = true;
try try
{ {
@ -237,6 +239,9 @@ internal class CompositingRenderer : IRendererWithCompositor, IHitTester
return; return;
CompositionTarget.IsEnabled = true; CompositionTarget.IsEnabled = true;
if (_dirty.Count > 0 || _recalculateChildren.Count > 0)
QueueUpdate();
} }
/// <inheritdoc /> /// <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); public void TriggerTick() => Tick?.Invoke(TimeSpan.Zero);
} }
class TopLevelImpl : ITopLevelImpl public class TopLevelImpl : ITopLevelImpl
{ {
private readonly Compositor _compositor; private readonly Compositor _compositor;
@ -159,7 +159,7 @@ public class CompositorTestServices : IDisposable
public double DesktopScaling => 1; public double DesktopScaling => 1;
public IPlatformHandle? Handle => null; public IPlatformHandle? Handle => null;
public Size ClientSize { get; } public Size ClientSize { get; set; }
public double RenderScaling => 1; public double RenderScaling => 1;
public IPlatformRenderSurface[] Surfaces { get; } = [new DummyFramebufferSurface()]; public IPlatformRenderSurface[] Surfaces { get; } = [new DummyFramebufferSurface()];
public Action<RawInputEventArgs>? Input { get; set; } public Action<RawInputEventArgs>? Input { get; set; }

Loading…
Cancel
Save