Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Propagate exceptions from compositor to unit/render tests #14808

Merged
merged 2 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/Avalonia.Base/Media/MediaContext.Compositor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private bool CommitCompositorsWithThrottling()
/// Executes a synchronous commit when we need to wait for composition jobs to be done
/// Is used in resize and TopLevel destruction scenarios
/// </summary>
private void SyncCommit(Compositor compositor, bool waitFullRender)
private void SyncCommit(Compositor compositor, bool waitFullRender, bool catchExceptions)
{
// Unit tests are assuming that they can call any API without setting up platforms
if (AvaloniaLocator.Current.GetService<IPlatformRenderInterface>() == null)
Expand All @@ -109,7 +109,7 @@ private void SyncCommit(Compositor compositor, bool waitFullRender)
else
{
CommitCompositor(compositor);
compositor.Server.Render();
compositor.Server.Render(catchExceptions);
}
}

Expand All @@ -118,9 +118,9 @@ private void SyncCommit(Compositor compositor, bool waitFullRender)
/// </summary>
// TODO: do we need to execute a render pass here too?
// We've previously tried that and it made the resize experience worse
public void ImmediateRenderRequested(CompositionTarget target)
public void ImmediateRenderRequested(CompositionTarget target, bool catchExceptions)
{
SyncCommit(target.Compositor, true);
SyncCommit(target.Compositor, true, catchExceptions);
}


Expand All @@ -133,7 +133,7 @@ public void SyncDisposeCompositionTarget(CompositionTarget compositionTarget)
compositionTarget.Dispose();

// TODO: introduce a way to skip any actual rendering for other targets and only do a dispose?
SyncCommit(compositionTarget.Compositor, false);
SyncCommit(compositionTarget.Compositor, false, true);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,15 @@ public void Resized(Size size)
}

/// <inheritdoc />
public void Paint(Rect rect)
public void Paint(Rect rect) => Paint(rect, true);
public void Paint(Rect rect, bool catchExceptions)
{
if (_isDisposed)
return;

QueueUpdate();
CompositionTarget.RequestRedraw();
MediaContext.Instance.ImmediateRenderRequested(CompositionTarget);
MediaContext.Instance.ImmediateRenderRequested(CompositionTarget, catchExceptions);
}

/// <inheritdoc />
Expand Down
19 changes: 8 additions & 11 deletions src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ void NotifyBatchesRendered()
_reusableToNotifyRenderedList.Clear();
}

public void Render()
public void Render() => Render(true);
public void Render(bool catchExceptions)
{
if (Dispatcher.UIThread.CheckAccess())
{
Expand All @@ -167,18 +168,18 @@ public void Render()
try
{
using (Dispatcher.UIThread.DisableProcessing())
RenderReentrancySafe();
RenderReentrancySafe(catchExceptions);
}
finally
{
_uiThreadIsInsideRender = false;
}
}
else
RenderReentrancySafe();
RenderReentrancySafe(catchExceptions);
}

private void RenderReentrancySafe()
private void RenderReentrancySafe(bool catchExceptions)
{
lock (_lock)
{
Expand All @@ -187,11 +188,7 @@ private void RenderReentrancySafe()
try
{
_safeThread = Thread.CurrentThread;
RenderCore();
}
catch (Exception e) when (RT_OnContextLostExceptionFilterObserver(e) && false)
// Will never get here, only using exception filter side effect
{
RenderCore(catchExceptions);
}
finally
{
Expand All @@ -205,7 +202,7 @@ private void RenderReentrancySafe()
}
}

private void RenderCore()
private void RenderCore(bool catchExceptions)
{
UpdateServerTime();
ApplyPendingBatches();
Expand All @@ -228,7 +225,7 @@ private void RenderCore()
foreach (var t in _activeTargets)
t.Render();
}
catch (Exception e)
catch (Exception e) when(RT_OnContextLostExceptionFilterObserver(e) && catchExceptions)
{
Logger.TryGet(LogEventLevel.Error, LogArea.Visual)?.Log(this, "Exception when rendering: {Error}", e);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Browser/Avalonia.Browser/AvaloniaView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ private void ForceBlit()

if (_topLevel.Renderer is CompositingRenderer dr)
{
MediaContext.Instance.ImmediateRenderRequested(dr.CompositionTarget);
MediaContext.Instance.ImmediateRenderRequested(dr.CompositionTarget, true);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public void AssertInvalidation<T>(T resource, Action cb)
Assert.True(Compositor.UnitTestIsRegisteredForSerialization(resource));

Compositor.Commit();
Compositor.Server.Render();
Compositor.Server.Render(false);

Assert.False(Compositor.UnitTestIsRegisteredForSerialization(resource));
cb();
Expand All @@ -52,4 +52,4 @@ public void AssertInvalidation<T>(T resource, Action cb)
}

public void Dispose() => Services.Dispose();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public TestContext(CompositorTestServices services)
public void ForceRender()
{
_compositor.Commit();
_compositor.Server.Render();
_compositor.Server.Render(false);
}

public Rect? GetBounds()
Expand Down
2 changes: 1 addition & 1 deletion tests/Avalonia.RenderTests/TestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ protected Task RenderToFile(Control target, [CallerMemberName] string testName =
root.Initialize(renderer, target);
renderer.Start();
Dispatcher.UIThread.RunJobs();
timer.TriggerTick();
renderer.Paint(new Rect(root.Bounds.Size), false);
}
writableBitmap.Save(compositedPath);
}
Expand Down