Skip to content

Introduce DrawingContext Push/PopRenderOptions #12734

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

Merged
merged 4 commits into from
Aug 31, 2023
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
20 changes: 19 additions & 1 deletion src/Avalonia.Base/Media/DrawingContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,8 @@ public enum PushedStateType
Opacity,
Clip,
GeometryClip,
OpacityMask
OpacityMask,
RenderOptions
}

public RestoreState(DrawingContext context, PushedStateType type)
Expand All @@ -308,6 +309,8 @@ public void Dispose()
_context.PopGeometryClipCore();
else if (_type == PushedStateType.OpacityMask)
_context.PopOpacityMaskCore();
else if (_type == PushedStateType.RenderOptions)
_context.PopRenderOptionsCore();
}
}

Expand Down Expand Up @@ -400,6 +403,20 @@ public PushedState PushTransform(Matrix matrix)
return new PushedState(this);
}

/// <summary>
/// Pushes render options.
/// </summary>
/// <param name="renderOptions">The render options.</param>
/// <returns>A disposable to undo the render options.</returns>
public PushedState PushRenderOptions(RenderOptions renderOptions)
{
PushRenderOptionsCore(renderOptions);
_states ??= StateStackPool.Get();
_states.Push(new RestoreState(this, RestoreState.PushedStateType.RenderOptions));
return new PushedState(this);
}
protected abstract void PushRenderOptionsCore(RenderOptions renderOptions);

[Obsolete("Use PushTransform"), EditorBrowsable(EditorBrowsableState.Never)]
public PushedState PushPreTransform(Matrix matrix) => PushTransform(matrix);
[Obsolete("Use PushTransform"), EditorBrowsable(EditorBrowsableState.Never)]
Expand All @@ -415,6 +432,7 @@ public PushedState PushTransform(Matrix matrix)
protected abstract void PopOpacityCore();
protected abstract void PopOpacityMaskCore();
protected abstract void PopTransformCore();
protected abstract void PopRenderOptionsCore();

private static bool PenIsVisible(IPen? pen)
{
Expand Down
14 changes: 14 additions & 0 deletions src/Avalonia.Base/Media/DrawingGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ public IBrush? OpacityMask
set => SetValue(OpacityMaskProperty, value);
}

internal RenderOptions? RenderOptions { get; set; }

/// <summary>
/// Gets or sets the collection that contains the child geometries.
/// </summary>
Expand All @@ -75,6 +77,7 @@ internal override void DrawCore(DrawingContext context)
using (context.PushOpacity(Opacity))
using (ClipGeometry != null ? context.PushGeometryClip(ClipGeometry) : default)
using (OpacityMask != null ? context.PushOpacityMask(OpacityMask, bounds) : default)
using (RenderOptions != null ? context.PushRenderOptions(RenderOptions.Value) : default)
{
foreach (var drawing in Children)
{
Expand Down Expand Up @@ -313,6 +316,15 @@ protected override void PushTransformCore(Matrix matrix)
drawingGroup.Transform = new MatrixTransform(matrix);
}

protected override void PushRenderOptionsCore(RenderOptions renderOptions)
{
// Instantiate a new drawing group and set it as the _currentDrawingGroup
var drawingGroup = PushNewDrawingGroup();

// Set the render options on the new DrawingGroup
drawingGroup.RenderOptions = renderOptions;
}

protected override void PopClipCore() => Pop();

protected override void PopGeometryClipCore() => Pop();
Expand All @@ -323,6 +335,8 @@ protected override void PushTransformCore(Matrix matrix)

protected override void PopTransformCore() => Pop();

protected override void PopRenderOptionsCore() => Pop();

/// <summary>
/// Creates a new DrawingGroup for a Push* call by setting the
/// _currentDrawingGroup to a newly instantiated DrawingGroup,
Expand Down
4 changes: 4 additions & 0 deletions src/Avalonia.Base/Media/PlatformDrawingContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ protected override void PushTransformCore(Matrix matrix)
_impl.Transform = matrix * current;
}

protected override void PushRenderOptionsCore(RenderOptions renderOptions) => _impl.PushRenderOptions(renderOptions);

protected override void PopClipCore() => _impl.PopClip();

protected override void PopGeometryClipCore() => _impl.PopGeometryClip();
Expand All @@ -102,6 +104,8 @@ protected override void PopTransformCore() =>
_impl.Transform =
(_transforms ?? throw new ObjectDisposedException(nameof(PlatformDrawingContext))).Pop();

protected override void PopRenderOptionsCore() => _impl.PopRenderOptions();

protected override void DisposeCore()
{
if (_ownsImpl)
Expand Down
11 changes: 11 additions & 0 deletions src/Avalonia.Base/Platform/IDrawingContextImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,17 @@ void DrawRectangle(IBrush? brush, IPen? pen, RoundedRect rect,
/// </summary>
void PopGeometryClip();

/// <summary>
/// Pushes render options.
/// </summary>
/// <param name="renderOptions">The render options.</param>
void PushRenderOptions(RenderOptions renderOptions);

/// <summary>
/// Pops the latest render options.
/// </summary>
void PopRenderOptions();

/// <summary>
/// Attempts to get an optional feature from the drawing context implementation.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,18 @@ public void Collect(IRenderDataServerResourcesCollector collector)
public abstract Rect? Bounds { get; }
public abstract bool HitTest(Point p);
}

class RenderDataRenderOptionsNode : RenderDataPushNode
{
public RenderOptions RenderOptions { get; set; }

public override void Push(ref RenderDataNodeRenderContext context)
{
context.Context.PushRenderOptions(RenderOptions);
}

public override void Pop(ref RenderDataNodeRenderContext context)
{
context.Context.PopRenderOptions();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,12 @@ protected override void PushTransformCore(Matrix matrix)
});
}

protected override void PushRenderOptionsCore(RenderOptions renderOptions) => Push(new RenderDataRenderOptionsNode()
{
RenderOptions = renderOptions
});


protected override void PopClipCore() => Pop<RenderDataClipNode>();

protected override void PopGeometryClipCore() => Pop<RenderDataGeometryClipNode>();
Expand All @@ -269,6 +275,8 @@ protected override void PushTransformCore(Matrix matrix)

protected override void PopTransformCore() => Pop<RenderDataPushMatrixNode>();

protected override void PopRenderOptionsCore() => Pop<RenderDataRenderOptionsNode>();

internal override void DrawBitmap(IRef<IBitmapImpl>? source, double opacity, Rect sourceRect, Rect destRect)
{
if (source == null || sourceRect.IsEmpty() || destRect.IsEmpty())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ public void PushOpacityMask(IBrush mask, Rect bounds)
_impl.PushOpacityMask(mask, bounds);
}

public void PushRenderOptions(RenderOptions renderOptions)
{
_impl.PushRenderOptions(renderOptions);
}

public void PopOpacityMask()
{
_impl.PopOpacityMask();
Expand All @@ -137,6 +142,11 @@ public void PopGeometryClip()
_impl.PopGeometryClip();
}

public void PopRenderOptions()
{
_impl.PopRenderOptions();
}

public object? GetFeature(Type t) => _impl.GetFeature(t);


Expand Down
10 changes: 10 additions & 0 deletions src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,16 @@ public void PushClip(RoundedRect clip)
{

}

public void PushRenderOptions(RenderOptions renderOptions)
{

}

public void PopRenderOptions()
{

}
}

private class HeadlessRenderTarget : IRenderTarget
Expand Down
16 changes: 16 additions & 0 deletions src/Skia/Avalonia.Skia/DrawingContextImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ internal partial class DrawingContextImpl : IDrawingContextImpl,
private readonly Vector _dpi;
private readonly Stack<PaintWrapper> _maskStack = new();
private readonly Stack<double> _opacityStack = new();
private readonly Stack<RenderOptions> _renderOptionsStack = new();
private readonly Matrix? _postTransform;
private double _currentOpacity = 1.0f;
private readonly bool _disableSubpixelTextRendering;
Expand Down Expand Up @@ -634,6 +635,21 @@ public void PopOpacity()
_currentOpacity = _opacityStack.Pop();
}

/// <inheritdoc />
public void PushRenderOptions(RenderOptions renderOptions)
{
CheckLease();

_renderOptionsStack.Push(RenderOptions);

RenderOptions = RenderOptions.MergeWith(renderOptions);
}

public void PopRenderOptions()
{
RenderOptions = _renderOptionsStack.Pop();
}

/// <inheritdoc />
public virtual void Dispose()
{
Expand Down
14 changes: 14 additions & 0 deletions src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ internal class DrawingContextImpl : IDrawingContextImpl
private readonly SharpDX.DXGI.SwapChain1 _swapChain;
private readonly Action _finishedCallback;

private readonly Stack<RenderOptions> _renderOptionsStack = new();

/// <summary>
/// Initializes a new instance of the <see cref="DrawingContextImpl"/> class.
/// </summary>
Expand Down Expand Up @@ -488,6 +490,18 @@ public void PopOpacity()
PopLayer();
}

public void PushRenderOptions(RenderOptions renderOptions)
{
_renderOptionsStack.Push(RenderOptions);

RenderOptions = RenderOptions.MergeWith(renderOptions);
}

public void PopRenderOptions()
{
RenderOptions = _renderOptionsStack.Pop();
}

private void PopLayer()
{
var layer = _layers.Pop();
Expand Down