Skip to content
Draft
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
12 changes: 12 additions & 0 deletions api/Avalonia.nupkg.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@
<Left>baseline/netstandard2.0/Avalonia.Base.dll</Left>
<Right>target/netstandard2.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.IDrawingContextImplWithEffects.PopEffect</Target>
<Left>baseline/netstandard2.0/Avalonia.Base.dll</Left>
<Right>target/netstandard2.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.IDrawingContextImplWithEffects.PushEffect(Avalonia.Media.IEffect)</Target>
<Left>baseline/netstandard2.0/Avalonia.Base.dll</Left>
<Right>target/netstandard2.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Controls.Primitives.IPopupHost.ConfigurePosition(Avalonia.Visual,Avalonia.Controls.PlacementMode,Avalonia.Point,Avalonia.Controls.Primitives.PopupPositioning.PopupAnchor,Avalonia.Controls.Primitives.PopupPositioning.PopupGravity,Avalonia.Controls.Primitives.PopupPositioning.PopupPositionerConstraintAdjustment,System.Nullable{Avalonia.Rect})</Target>
Expand Down
5 changes: 3 additions & 2 deletions src/Avalonia.Base/Platform/IDrawingContextImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,10 @@ void DrawRectangle(IBrush? brush, IPen? pen, RoundedRect rect,
object? GetFeature(Type t);
}

public interface IDrawingContextImplWithEffects
[PrivateApi]
public interface IDrawingContextImplWithEffects : IDrawingContextImpl
{
void PushEffect(IEffect effect);
void PushEffect(Rect? clipRect, IEffect effect);
void PopEffect();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ struct PendingCommandDataUnion
[FieldOffset(0)] public bool IsRoundRect;
[FieldOffset(4)] public RoundedRect RoundRect;
[FieldOffset(4)] public Rect NormalRect;

// PushEffect
[FieldOffset(0)]
public Rect? EffectClipRect;
}

struct PendingCommand
Expand Down Expand Up @@ -140,7 +144,7 @@ void ExecCommand(ref PendingCommand cmd)
else if (cmd.Type == PendingCommandType.PushEffect)
{
if (_impl is IDrawingContextImplWithEffects effects)
effects.PushEffect(cmd.ObjectUnion.Effect!);
effects.PushEffect(cmd.DataUnion.EffectClipRect, cmd.ObjectUnion.Effect!);
}
else if (cmd.Type == PendingCommandType.PushRenderOptions)
_impl.PushRenderOptions(cmd.DataUnion.RenderOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,14 +285,18 @@ public void DrawRectangle(IExperimentalAcrylicMaterial material, RoundedRect rec
_impl.DrawRectangle(new ImmutableSolidColorBrush(material.FallbackColor), null, rect);
}

public void PushEffect(IEffect effect)
public void PushEffect(Rect? clipRect, IEffect effect)
{
AddCommand(new()
{
Type = PendingCommandType.PushEffect,
ObjectUnion =
{
Effect = effect
Effect = effect,
},
DataUnion =
{
EffectClipRect = clipRect
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public override UpdateResult Update(ServerCompositionTarget root, Matrix parentC
return new(_transformedContentBounds, oldInvalidated, newInvalidated);
}

protected override LtrbRect GetEffectBounds() => _transformedContentBounds ?? default;

void AddEffectPaddedDirtyRect(IImmutableEffect effect, LtrbRect transformedBounds)
{
var padding = effect.GetEffectOutputPadding();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,8 @@ public void Render(ServerVisualRenderContext context, LtrbRect? parentTransforme

if (applyRenderOptions)
canvas.PushRenderOptions(RenderOptions);
if (Effect != null)
canvas.PushEffect(Effect);

var needPopEffect = PushEffect(canvas);

if (Opacity != 1)
canvas.PushOpacity(Opacity, ClipToBounds ? boundsRect : null);
if (ClipToBounds && !HandlesClipToBounds)
Expand All @@ -87,12 +86,28 @@ public void Render(ServerVisualRenderContext context, LtrbRect? parentTransforme
if (Opacity != 1)
canvas.PopOpacity();

if (Effect != null)
if (needPopEffect)
canvas.PopEffect();
if(applyRenderOptions)
canvas.PopRenderOptions();
}

protected virtual LtrbRect GetEffectBounds() => TransformedOwnContentBounds;

private bool PushEffect(CompositorDrawingContextProxy canvas)
{
if (Effect == null)
return false;
var clip = GetEffectBounds();
if (clip.IsZeroSize)
return false;
var oldMatrix = canvas.Transform;
canvas.Transform = Matrix.Identity;
canvas.PushEffect(GetEffectBounds().ToRect(), Effect!);
canvas.Transform = oldMatrix;
return true;
}

protected virtual bool HandlesClipToBounds => false;

private ReadbackData _readback0, _readback1, _readback2;
Expand Down
7 changes: 5 additions & 2 deletions src/Skia/Avalonia.Skia/DrawingContextImpl.Effects.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ namespace Avalonia.Skia;
partial class DrawingContextImpl
{

public void PushEffect(IEffect effect)
public void PushEffect(Rect? effectClipRect, IEffect effect)
{
CheckLease();
using var filter = CreateEffect(effect);
var paint = SKPaintCache.Shared.Get();
paint.ImageFilter = filter;
Canvas.SaveLayer(paint);
if (effectClipRect.HasValue)
Canvas.SaveLayer(effectClipRect.Value.ToSKRect(), paint);
else
Canvas.SaveLayer(paint);
SKPaintCache.Shared.ReturnReset(paint);
}

Expand Down