diff --git a/src/Avalonia.Base/Media/MediaContext.Compositor.cs b/src/Avalonia.Base/Media/MediaContext.Compositor.cs
index 4ddc2ea9eb..1c4c18838f 100644
--- a/src/Avalonia.Base/Media/MediaContext.Compositor.cs
+++ b/src/Avalonia.Base/Media/MediaContext.Compositor.cs
@@ -16,7 +16,7 @@ partial class MediaContext
/// Actually sends the current batch to the compositor and does the required housekeeping
/// This is the only place that should be allowed to call Commit
///
- private Batch CommitCompositor(Compositor compositor)
+ private CompositionBatch CommitCompositor(Compositor compositor)
{
var commit = compositor.Commit();
_requestedCommits.Remove(compositor);
@@ -29,7 +29,7 @@ partial class MediaContext
///
/// Handles batch completion, required to re-schedule a render pass if one was skipped due to compositor throttling
///
- private void CompositionBatchFinished(Compositor compositor, Batch batch)
+ private void CompositionBatchFinished(Compositor compositor, CompositionBatch batch)
{
// Check if it was the last commited batch, since sometimes we are forced to send a new
// one without waiting for the previous one to complete
diff --git a/src/Avalonia.Base/Media/MediaContext.cs b/src/Avalonia.Base/Media/MediaContext.cs
index 0a290052c7..af32406f03 100644
--- a/src/Avalonia.Base/Media/MediaContext.cs
+++ b/src/Avalonia.Base/Media/MediaContext.cs
@@ -22,7 +22,7 @@ internal partial class MediaContext : ICompositorScheduler
private readonly Action _render;
private readonly Action _inputMarkerHandler;
private readonly HashSet _requestedCommits = new();
- private readonly Dictionary _pendingCompositionBatches = new();
+ private readonly Dictionary _pendingCompositionBatches = new();
private record TopLevelInfo(Compositor Compositor, CompositingRenderer Renderer, ILayoutManager LayoutManager);
private List? _invokeOnRenderCallbacks;
diff --git a/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs b/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
index 4db14ba183..ca00b94eaf 100644
--- a/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
+++ b/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
@@ -8,6 +8,7 @@ using Avalonia.Collections;
using Avalonia.Collections.Pooled;
using Avalonia.Media;
using Avalonia.Rendering.Composition.Drawing;
+using Avalonia.Threading;
using Avalonia.VisualTree;
namespace Avalonia.Rendering.Composition;
@@ -25,6 +26,7 @@ internal class CompositingRenderer : IRendererWithCompositor, IHitTester
private readonly Action _update;
private bool _queuedUpdate;
+ private bool _queuedSceneInvalidation;
private bool _updating;
private bool _isDisposed;
@@ -172,13 +174,17 @@ internal class CompositingRenderer : IRendererWithCompositor, IHitTester
_recalculateChildren.Clear();
CompositionTarget.Size = _root.ClientSize;
CompositionTarget.Scaling = _root.RenderScaling;
- TriggerSceneInvalidatedOnBatchCompletion(_compositor.RequestCommitAsync());
- }
-
- private async void TriggerSceneInvalidatedOnBatchCompletion(Task batchCompletion)
- {
- await batchCompletion;
- SceneInvalidated?.Invoke(this, new SceneInvalidatedEventArgs(_root, new Rect(_root.ClientSize)));
+
+ var commit = _compositor.RequestCommitAsync();
+ if (!_queuedSceneInvalidation)
+ {
+ _queuedSceneInvalidation = true;
+ commit.ContinueWith(_ => Dispatcher.UIThread.Post(() =>
+ {
+ _queuedSceneInvalidation = false;
+ SceneInvalidated?.Invoke(this, new SceneInvalidatedEventArgs(_root, new Rect(_root.ClientSize)));
+ }, DispatcherPriority.Input));
+ }
}
public void TriggerSceneInvalidatedForUnitTests(Rect rect) =>
diff --git a/src/Avalonia.Base/Rendering/Composition/Compositor.cs b/src/Avalonia.Base/Rendering/Composition/Compositor.cs
index 902a195098..84bc7795f2 100644
--- a/src/Avalonia.Base/Rendering/Composition/Compositor.cs
+++ b/src/Avalonia.Base/Rendering/Composition/Compositor.cs
@@ -24,7 +24,7 @@ namespace Avalonia.Rendering.Composition
internal IRenderLoop Loop { get; }
internal bool UseUiThreadForSynchronousCommits { get; }
private ServerCompositor _server;
- private Batch? _nextCommit;
+ private CompositionBatch? _nextCommit;
private BatchStreamObjectPool