Skip to content

Commit

Permalink
Merge pull request #1196 from b-editor/feat/render-node
Browse files Browse the repository at this point in the history
Enhance rendering framework with new RenderNode architecture
  • Loading branch information
yuto-trd authored Dec 9, 2024
2 parents 33cbf9d + 1ccb01e commit e1c2622
Show file tree
Hide file tree
Showing 91 changed files with 3,218 additions and 2,520 deletions.
18 changes: 9 additions & 9 deletions src/Beutl.Engine/Graphics/Drawable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,11 @@ internal Matrix GetTransformMatrix(Size availableSize, Size coreBounds)
}
}

public virtual void Render(ICanvas canvas)
public virtual void Render(GraphicsContext2D context)
{
if (IsVisible)
{
Size availableSize = canvas.Size.ToSize(1);
Size availableSize = context.Size.ToSize(1);
Size size = MeasureCore(availableSize);
var rect = new Rect(size);
if (_filterEffect != null && !rect.IsInvalid)
Expand All @@ -208,13 +208,13 @@ public virtual void Render(ICanvas canvas)

Matrix transform = GetTransformMatrix(availableSize, size);
Rect transformedBounds = rect.IsInvalid ? Rect.Invalid : rect.TransformToAABB(transform);
using (canvas.PushBlendMode(BlendMode))
using (canvas.PushTransform(transform))
using (canvas.PushOpacity(Opacity / 100f))
using (_filterEffect == null ? new() : canvas.PushFilterEffect(_filterEffect))
using (OpacityMask == null ? new() : canvas.PushOpacityMask(OpacityMask, new Rect(size)))
using (context.PushBlendMode(BlendMode))
using (context.PushTransform(transform))
using (context.PushOpacity(Opacity / 100f))
using (_filterEffect == null ? new() : context.PushFilterEffect(_filterEffect))
using (OpacityMask == null ? new() : context.PushOpacityMask(OpacityMask, new Rect(size)))
{
OnDraw(canvas);
OnDraw(context);
}

Bounds = transformedBounds;
Expand All @@ -230,7 +230,7 @@ public override void ApplyAnimations(IClock clock)
(OpacityMask as Animatable)?.ApplyAnimations(clock);
}

protected abstract void OnDraw(ICanvas canvas);
protected abstract void OnDraw(GraphicsContext2D context);

private Point CalculateTranslate(Size bounds, Size canvasSize)
{
Expand Down
19 changes: 10 additions & 9 deletions src/Beutl.Engine/Graphics/DrawableDecorator.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.ComponentModel;
using Beutl.Graphics.Effects;
using Beutl.Graphics.Rendering;
using Beutl.Media;
using Beutl.Media.Immutable;

Expand Down Expand Up @@ -60,11 +61,11 @@ private Rect PrivateMeasureCore(Size availableSize)
}
}

public override void Render(ICanvas canvas)
public override void Render(GraphicsContext2D context)
{
if (IsVisible)
{
Size availableSize = canvas.Size.ToSize(1);
Size availableSize = context.Size.ToSize(1);
Rect rect = PrivateMeasureCore(availableSize);
if (FilterEffect != null && !rect.IsInvalid)
{
Expand All @@ -73,23 +74,23 @@ public override void Render(ICanvas canvas)

Matrix transform = GetTransformMatrix(availableSize);
Rect transformedBounds = rect.IsInvalid ? Rect.Invalid : rect.TransformToAABB(transform);
using (canvas.PushBlendMode(BlendMode))
using (canvas.PushTransform(transform))
using (FilterEffect == null ? new() : canvas.PushFilterEffect(FilterEffect))
using (OpacityMask == null ? new() : canvas.PushOpacityMask(OpacityMask, new Rect(rect.Size)))
using (context.PushBlendMode(BlendMode))
using (context.PushTransform(transform))
using (FilterEffect == null ? new() : context.PushFilterEffect(FilterEffect))
using (OpacityMask == null ? new() : context.PushOpacityMask(OpacityMask, new Rect(rect.Size)))
{
OnDraw(canvas);
OnDraw(context);
}

Bounds = transformedBounds;
}
}

protected override void OnDraw(ICanvas canvas)
protected override void OnDraw(GraphicsContext2D context)
{
if (Child != null)
{
canvas.DrawDrawable(Child);
context.DrawDrawable(Child);
}
}

Expand Down
23 changes: 12 additions & 11 deletions src/Beutl.Engine/Graphics/DrawableGroup.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Text.Json.Nodes;
using Beutl.Graphics.Effects;
using Beutl.Graphics.Rendering;
using Beutl.Serialization;

namespace Beutl.Graphics;
Expand Down Expand Up @@ -70,11 +71,11 @@ private Rect PrivateMeasureCore(Size availableSize)
return rect;
}

public override void Render(ICanvas canvas)
public override void Render(GraphicsContext2D context)
{
if (IsVisible)
{
Size availableSize = canvas.Size.ToSize(1);
Size availableSize = context.Size.ToSize(1);
Rect rect = PrivateMeasureCore(availableSize);
if (FilterEffect != null && !rect.IsInvalid)
{
Expand All @@ -84,25 +85,25 @@ public override void Render(ICanvas canvas)
Matrix transform = GetTransformMatrix(availableSize);
Rect transformedBounds = rect.IsInvalid ? Rect.Invalid : rect.TransformToAABB(transform);

using (canvas.PushBlendMode(BlendMode))
using (canvas.PushLayer(transformedBounds.IsInvalid ? default : transformedBounds))
using (canvas.PushTransform(transform))
using (FilterEffect == null ? new() : canvas.PushFilterEffect(FilterEffect))
using (OpacityMask == null ? new() : canvas.PushOpacityMask(OpacityMask, new Rect(rect.Size)))
using (canvas.PushLayer())
using (context.PushBlendMode(BlendMode))
using (context.PushLayer(transformedBounds.IsInvalid ? default : transformedBounds))
using (context.PushTransform(transform))
using (FilterEffect == null ? new() : context.PushFilterEffect(FilterEffect))
using (OpacityMask == null ? new() : context.PushOpacityMask(OpacityMask, new Rect(rect.Size)))
using (context.PushLayer())
{
OnDraw(canvas);
OnDraw(context);
}

Bounds = transformedBounds;
}
}

protected override void OnDraw(ICanvas canvas)
protected override void OnDraw(GraphicsContext2D context)
{
foreach (Drawable item in _children.GetMarshal().Value)
{
canvas.DrawDrawable(item);
context.DrawDrawable(item);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Beutl.Engine/Graphics/DummyDrawable.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Nodes;

using Beutl.Graphics.Rendering;
using Beutl.Serialization;

namespace Beutl.Graphics;
Expand Down Expand Up @@ -29,7 +29,7 @@ protected override Size MeasureCore(Size availableSize)
return Size.Empty;
}

protected override void OnDraw(ICanvas canvas)
protected override void OnDraw(GraphicsContext2D context)
{
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using System.ComponentModel;
using Beutl.Animation;
using Beutl.Animation;

namespace Beutl.Graphics.Effects;

[Obsolete("Use FilterEffectGroup instead.")]
public sealed class CombinedFilterEffect : FilterEffect
{
public static readonly CoreProperty<FilterEffect?> FirstProperty;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
using System.Collections.Immutable;

using Beutl.Media.Source;

using Beutl.Media.Source;
using SkiaSharp;

namespace Beutl.Graphics.Effects;

public class CustomFilterEffectContext
{
internal readonly IImmediateCanvasFactory _factory;
internal readonly ImmutableArray<FEItemWrapper> _history;

internal CustomFilterEffectContext(
IImmediateCanvasFactory canvas,
EffectTargets targets,
ImmutableArray<FEItemWrapper> history)
internal CustomFilterEffectContext(IImmediateCanvasFactory canvas, EffectTargets targets)
{
Targets = targets;
_factory = canvas;
_history = history;
}

public EffectTargets Targets { get; }
Expand Down Expand Up @@ -65,17 +57,11 @@ public EffectTarget CreateTarget(Rect bounds)
if (surface != null)
{
using var surfaceRef = Ref<SKSurface>.Create(surface);
var obj = new EffectTarget(surfaceRef, bounds);

obj._history.AddRange(_history);
return obj;
return new EffectTarget(surfaceRef, bounds);
}
else
{
var obj = new EffectTarget();

obj._history.AddRange(_history);
return obj;
return new EffectTarget();
}
}

Expand Down
33 changes: 10 additions & 23 deletions src/Beutl.Engine/Graphics/FilterEffects/EffectTarget.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
using System.ComponentModel;

using Beutl.Collections.Pooled;
using Beutl.Graphics.Rendering;
using Beutl.Media.Source;

using SkiaSharp;

namespace Beutl.Graphics.Effects;
Expand All @@ -15,9 +13,7 @@ public sealed class EffectTarget : IDisposable

private object? _target;

internal readonly PooledList<FEItemWrapper> _history = [];

public EffectTarget(IGraphicNode node)
public EffectTarget(RenderNodeOperation node)
{
_target = node;
OriginalBounds = node.Bounds;
Expand All @@ -39,30 +35,21 @@ public EffectTarget()

public Rect Bounds { get; set; }

[Obsolete()]
[Obsolete]
[EditorBrowsable(EditorBrowsableState.Never)]
public Size Size => Bounds.Size;

public IGraphicNode? Node => _target as IGraphicNode;
public RenderNodeOperation? NodeOperation => _target as RenderNodeOperation;

public Ref<SKSurface>? Surface => _target as Ref<SKSurface>;

public bool IsEmpty => _target == null;

public EffectTarget Clone()
{
if (Node != null)
{
return this;
}
else if (Surface != null)
if (Surface != null)
{
var obj = new EffectTarget(Surface, OriginalBounds)
{
Bounds = Bounds
};
obj._history.AddRange(_history.Select(v => v.Inherit()));
return obj;
return new EffectTarget(Surface, OriginalBounds) { Bounds = Bounds };
}
else
{
Expand All @@ -73,20 +60,20 @@ public EffectTarget Clone()
public void Dispose()
{
Surface?.Dispose();
NodeOperation?.Dispose();
_target = null;
OriginalBounds = default;
_history.Dispose();
}

public void Draw(ImmediateCanvas canvas)
{
if (Node != null)
if (Surface != null)
{
canvas.DrawNode(Node);
canvas.DrawSurface(Surface.Value, default);
}
else if (Surface != null)
else if (NodeOperation != null)
{
canvas.DrawSurface(Surface.Value, default);
NodeOperation.Render(canvas);
}
}
}
6 changes: 2 additions & 4 deletions src/Beutl.Engine/Graphics/FilterEffects/FEImpl.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System.Collections.Immutable;

using SkiaSharp;
using SkiaSharp;

namespace Beutl.Graphics.Effects;

Expand Down Expand Up @@ -53,7 +51,7 @@ public void Accepts(CustomFilterEffectContext context)
{
using (target)
{
var innerContext = new FilterEffectCustomOperationContext(context._factory, target, [.. target._history]);
var innerContext = new FilterEffectCustomOperationContext(context._factory, target);
Action.Invoke(Data, innerContext);

innerContext.Target.Bounds = TransformBounds!(Data, innerContext.Target.Bounds);
Expand Down
Loading

0 comments on commit e1c2622

Please sign in to comment.