Browse Source
* Added Compositor.CreateCompositionVisualSnapshot API * Hurr durr api compat in [Unstable] interface --------- Co-authored-by: Max Katz <maxkatz6@outlook.com> #Conflicts: # api/Avalonia.Skia.nupkg.xml # samples/ControlCatalog/Pages/OpenGlPage.xaml # samples/ControlCatalog/Pages/OpenGlPage.xaml.csrelease/11.1.3
committed by
Max Katz
25 changed files with 315 additions and 63 deletions
@ -1,10 +1,16 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
<?xml version="1.0" encoding="utf-8"?> |
||||
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids --> |
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/package-validation/diagnostic-ids --> |
||||
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
||||
|
<Suppression> |
||||
|
<DiagnosticId>CP0006</DiagnosticId> |
||||
|
<Target>M:Avalonia.Skia.ISkiaGpuWithPlatformGraphicsContext.TryGetGrContext</Target> |
||||
|
<Left>baseline/netstandard2.0/Avalonia.Skia.dll</Left> |
||||
|
<Right>target/netstandard2.0/Avalonia.Skia.dll</Right> |
||||
|
</Suppression> |
||||
<Suppression> |
<Suppression> |
||||
<DiagnosticId>CP0006</DiagnosticId> |
<DiagnosticId>CP0006</DiagnosticId> |
||||
<Target>M:Avalonia.Skia.ISkiaSharpApiLease.TryLeasePlatformGraphicsApi</Target> |
<Target>M:Avalonia.Skia.ISkiaSharpApiLease.TryLeasePlatformGraphicsApi</Target> |
||||
<Left>baseline/netstandard2.0/Avalonia.Skia.dll</Left> |
<Left>baseline/netstandard2.0/Avalonia.Skia.dll</Left> |
||||
<Right>target/netstandard2.0/Avalonia.Skia.dll</Right> |
<Right>target/netstandard2.0/Avalonia.Skia.dll</Right> |
||||
</Suppression> |
</Suppression> |
||||
</Suppressions> |
</Suppressions> |
||||
|
|||||
@ -0,0 +1,44 @@ |
|||||
|
using System; |
||||
|
using System.Threading; |
||||
|
|
||||
|
namespace Avalonia.Platform; |
||||
|
|
||||
|
public interface IScopedResource<T> : IDisposable |
||||
|
{ |
||||
|
public T Value { get; } |
||||
|
} |
||||
|
|
||||
|
public class ScopedResource<T> : IScopedResource<T> |
||||
|
{ |
||||
|
private int _disposed = 0; |
||||
|
private T _value; |
||||
|
private Action? _dispose; |
||||
|
private ScopedResource(T value, Action dispose) |
||||
|
{ |
||||
|
_value = value; |
||||
|
_dispose = dispose; |
||||
|
} |
||||
|
|
||||
|
public static IScopedResource<T> Create(T value, Action dispose) => new ScopedResource<T>(value, dispose); |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
if (Interlocked.CompareExchange(ref _disposed, 1, 0) == 0) |
||||
|
{ |
||||
|
var disp = _dispose!; |
||||
|
_value = default!; |
||||
|
_dispose = null; |
||||
|
disp(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public T Value |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
if (_disposed == 1) |
||||
|
throw new ObjectDisposedException(this.GetType().FullName); |
||||
|
return _value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,75 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Avalonia.Platform; |
||||
|
|
||||
|
namespace Avalonia.Rendering.Composition.Server; |
||||
|
|
||||
|
internal class ServerVisualRenderContext |
||||
|
{ |
||||
|
public IDirtyRectTracker? DirtyRects { get; } |
||||
|
public bool DetachedRendering { get; } |
||||
|
public CompositorDrawingContextProxy Canvas { get; } |
||||
|
private readonly Stack<Matrix>? _transformStack; |
||||
|
|
||||
|
public ServerVisualRenderContext(CompositorDrawingContextProxy canvas, IDirtyRectTracker? dirtyRects, |
||||
|
bool detachedRendering) |
||||
|
{ |
||||
|
Canvas = canvas; |
||||
|
DirtyRects = dirtyRects; |
||||
|
DetachedRendering = detachedRendering; |
||||
|
if (detachedRendering) |
||||
|
{ |
||||
|
_transformStack = new(); |
||||
|
_transformStack.Push(canvas.Transform); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public bool ShouldRender(ServerCompositionVisual visual, LtrbRect currentTransformedClip) |
||||
|
{ |
||||
|
if (DetachedRendering) |
||||
|
return true; |
||||
|
if (currentTransformedClip.IsZeroSize) |
||||
|
return false; |
||||
|
if (DirtyRects?.Intersects(currentTransformedClip) == false) |
||||
|
return false; |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public bool ShouldRenderOwnContent(ServerCompositionVisual visual, LtrbRect currentTransformedClip) |
||||
|
{ |
||||
|
if (DetachedRendering) |
||||
|
return true; |
||||
|
return currentTransformedClip.Intersects(visual.TransformedOwnContentBounds) |
||||
|
&& DirtyRects?.Intersects(visual.TransformedOwnContentBounds) != false; |
||||
|
} |
||||
|
|
||||
|
public RestoreTransform SetOrPushTransform(ServerCompositionVisual visual) |
||||
|
{ |
||||
|
if (!DetachedRendering) |
||||
|
{ |
||||
|
Canvas.Transform = visual.GlobalTransformMatrix; |
||||
|
return default; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
var transform = visual.CombinedTransformMatrix * _transformStack!.Peek(); |
||||
|
Canvas.Transform = transform; |
||||
|
_transformStack.Push(transform); |
||||
|
return new RestoreTransform(this); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public struct RestoreTransform(ServerVisualRenderContext? parent) : IDisposable |
||||
|
{ |
||||
|
public void Dispose() |
||||
|
{ |
||||
|
if (parent != null) |
||||
|
{ |
||||
|
parent._transformStack!.Pop(); |
||||
|
parent.Canvas.Transform = parent._transformStack.Peek(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
Loading…
Reference in new issue