Browse Source

Fixed rare soft-"freezes" with OnRender(c) { ...; InvalidateVisual(); } pattern (#18901)

pull/18906/head
Nikita Tsukanov 9 months ago
committed by GitHub
parent
commit
486f8c797d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 19
      src/Avalonia.Base/Media/MediaContext.Compositor.cs

19
src/Avalonia.Base/Media/MediaContext.Compositor.cs

@ -1,4 +1,7 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Avalonia.Platform;
@ -11,16 +14,20 @@ namespace Avalonia.Media;
partial class MediaContext
{
private bool _scheduleCommitOnLastCompositionBatchCompletion;
/// <summary>
/// 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
/// </summary>
private CompositionBatch CommitCompositor(Compositor compositor)
{
var commit = compositor.Commit();
// Compositor is allowed to schedule the next batch during Commit procedure if update
// was requested while it was doing an update
// This can e. g. happen if InvalidateVisual is called from Visual.OnRender which is currently separate
// from our FireInvokeOnRenderCallbacks loop, so we clean the commit request flag before rendering so
// it can be set again
_requestedCommits.Remove(compositor);
var commit = compositor.Commit();
_pendingCompositionBatches[compositor] = commit;
commit.Processed.ContinueWith(_ =>
_dispatcher.Post(() => CompositionBatchFinished(compositor, commit), DispatcherPriority.Send),
@ -43,9 +50,8 @@ partial class MediaContext
_animationsAreWaitingForComposition = false;
// Check if we have uncommited changes
if (_scheduleCommitOnLastCompositionBatchCompletion)
if (_requestedCommits.Count != 0)
{
_scheduleCommitOnLastCompositionBatchCompletion = false;
if (!CommitCompositorsWithThrottling())
ScheduleRenderForAnimationsIfNeeded();
@ -69,10 +75,10 @@ partial class MediaContext
/// <returns>true if there are pending commits in-flight and there will be a "all-done" callback later</returns>
private bool CommitCompositorsWithThrottling()
{
Dispatcher.UIThread.VerifyAccess();
// Check if we are still waiting for previous composition batches
if (_pendingCompositionBatches.Count > 0)
{
_scheduleCommitOnLastCompositionBatchCompletion = true;
// Previous commit isn't handled yet
return true;
}
@ -84,7 +90,6 @@ partial class MediaContext
foreach (var c in _requestedCommits.ToArray())
CommitCompositor(c);
_requestedCommits.Clear();
return true;
}

Loading…
Cancel
Save