Skip to content

Commit

Permalink
update (en)
Browse files Browse the repository at this point in the history
  • Loading branch information
yuto-trd committed Dec 28, 2024
1 parent 7a81acd commit 69462e3
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 205 deletions.
10 changes: 1 addition & 9 deletions en/advanced/2.source-operator.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,4 @@ title: Source Operations
description: Explanation of the types of source operations
---

There are mainly two types of source operations.

**Publisher**
- Issues drawing objects such as shapes, images, and videos with specified properties.
- Retrieves elements below the current layer and issues their drawing objects.

**Transformer**
- Modifies drawing objects issued by the Publisher.
- Wraps drawing objects issued by the Publisher with newly created drawing objects.
Obsolete
64 changes: 18 additions & 46 deletions en/advanced/4.render-cache.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,28 @@
---
title: Caching
description: Explanation of the criteria for generating drawing caches in Beutl
title: Cache
description: Explanation of render cache generation in Beutl
---

## Cache
Consider the following nodes:
Consider the following nodes.
```
1. Drawing Node
1. Render Node
2. └ Transform Node
3.   └ Effect Node
4.     └ Shape Node
3.   └ Effect Node (Drop Shadow, with animation)
4.     └ Effect Node (Outline)
5.       └ Shape Node
```
Within the Effect Node:
```
3-1. Border
3-2. DropShadow (with animation)
```
The Transform Node and Shape Node do not have animation.

In conclusion, in this example, after a few frames are drawn, Beutl caches up to 3-1 within the Effect Node.
The reasoning behind this is explained below.

## Determining Cache Eligibility
Beutl determines that caching is possible if the state remains the same for three or more frames.

There are two methods for counting frames:
1. Automatic Counting
This method requires that the node remains unchanged, but it is very simple.
The frame count increments during rendering, and resets to zero if the node changes.
If the count reaches 3 or more, the node is deemed **cacheable**.

2. Manual Counting
This method applies to nodes implementing `ISupportRenderCache`.
These nodes report how much remained the same compared to the previous frame.
If the minimum value of the similarity over the last three frames is 1 or more, the node is deemed **cache-boundary eligible**.
If all three frames are the same, the node is deemed **cacheable**.
```
-> Frames
1 2 3 4
3-1. ■ ■ ■ ■
3-2. ○ ● ○ ●
```
In this case, the second frame and beyond would report `1/2`.

After the fourth frame is rendered, the node is deemed **cache-boundary eligible**.
> [!NOTE]
> **Nodes that are ancestors of a cache-boundary node cannot be cached.**
If a node is deemed **cache-boundary eligible** or **cacheable** and all its child nodes are **cacheable**, the drawing content of that node is cached.
Transform Node and Shape Node have no animation.

### Manual Control with ISupportRenderCache
In conclusion,
In this example, after a few frames are rendered,
Beutl will cache up to the 4th effect node.
Below is an explanation of why this happens.

Nodes implementing `ISupportRenderCache` can manually control whether to cache, the process of saving the cache, and rendering using the cache.
## Determining Cacheability
If the same state persists for 3 or more frames, it is considered cacheable.
During node rendering, a count is maintained, and if the node changes, the count is reset to zero.
When this count reaches 3 or more, it is considered **cacheable**.

This implementation allows partial caching of multiple effects, and is used within the Effect Node.
If a node is **cacheable** and all its child elements are **cacheable**,
the rendering content of that node is cached.
18 changes: 9 additions & 9 deletions en/extensions/2.create-csproj.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: Explanation of how to create an empty C# project for Beutl extensio
This article explains how to create an empty C# project for Beutl extensions.

This guide introduces the methods using __Visual Studio Code__ or __Visual Studio__.
The target Beutl version is `1.0.0-preview.6`.
The target Beutl version is `1.0.0-preview.11`.

## Visual Studio Code
1. Use the terminal to create a class library.
Expand All @@ -28,7 +28,7 @@ MyBeutlExtension
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Change the TargetFramework according to the Beutl version -->
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand All @@ -52,9 +52,9 @@ MyBeutlExtension
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Beutl.Extensibility" Version="1.0.0-preview.6" />
<PackageReference Include="Beutl.ProjectSystem" Version="1.0.0-preview.6" />
<PackageReference Include="Beutl.Operators" Version="1.0.0-preview.6" />
<PackageReference Include="Beutl.Extensibility" Version="1.0.0-preview.11" />
<PackageReference Include="Beutl.ProjectSystem" Version="1.0.0-preview.11" />
<PackageReference Include="Beutl.Operators" Version="1.0.0-preview.11" />
</ItemGroup>

</Project>
Expand Down Expand Up @@ -98,7 +98,7 @@ MyBeutlExtension
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Change the TargetFramework according to the Beutl version -->
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand All @@ -122,9 +122,9 @@ MyBeutlExtension
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Beutl.Extensibility" Version="1.0.0-preview.6" />
<PackageReference Include="Beutl.ProjectSystem" Version="1.0.0-preview.6" />
<PackageReference Include="Beutl.Operators" Version="1.0.0-preview.6" />
<PackageReference Include="Beutl.Extensibility" Version="1.0.0-preview.11" />
<PackageReference Include="Beutl.ProjectSystem" Version="1.0.0-preview.11" />
<PackageReference Include="Beutl.Operators" Version="1.0.0-preview.11" />
</ItemGroup>

</Project>
Expand Down
2 changes: 1 addition & 1 deletion en/extensions/3.available-extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ In Beutl, you can extend the following functionalities:
| EditorExtension | Adds a UI for editing files |
| OutputExtension | Adds a UI for output |
| [Extension](sample-extensions.md#sugarshaker) | Base class for extensions (override the Load method to register functionalities) |
| PageExtension | Adds pages that can be selected from the menu on the left side of the window |
| PageExtension | Adds a dialog that can be opened from the Window menu |
| ProjectItemExtension | Adds types of items to the project |
| PropertyEditorExtension | Adds a UI for editing specific property types |
| [ToolTabExtension](sample-extensions.md#ToolTabExtension) | Adds tabs to the scene editing screen |
77 changes: 21 additions & 56 deletions en/extensions/implement-drawing-object.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Create a `StarShape` class that inherits from the `Drawable` class as follows.

```cs
using Beutl.Graphics;
using Beutl.Graphics.Rendering;

namespace MyExtension;

Expand All @@ -29,7 +30,7 @@ public class StarShape : Drawable
throw new NotImplementedException();
}

protected override void OnDraw(ICanvas canvas)
protected override void OnDraw(GraphicsContext2D context)
{
throw new NotImplementedException();
}
Expand Down Expand Up @@ -112,10 +113,10 @@ public class StarShape : Drawable
return _geometry.Bounds.Size;
}

protected override void OnDraw(ICanvas canvas)
protected override void OnDraw(GraphicsContext2D context)
{
// Fill is defined in the Drawable class
canvas.DrawGeometry(_geometry, Fill, null);
context.DrawGeometry(_geometry, Fill, null);
}
}
```
Expand All @@ -127,6 +128,7 @@ Test if the star shape is drawn correctly.
```cs
using Beutl.Media;
using Beutl.Graphics;
using Beutl.Graphics.Rendering;
using MyExtension;

var shape = new StarShape()
Expand All @@ -135,48 +137,18 @@ var shape = new StarShape()
Fill = Brushes.White
};

using var canvas = new ImmediateCanvas(120, 120);
shape.Render(canvas);
using var renderTarget = RenderTarget.Create(120, 120);
using var canvas = new ImmediateCanvas(renderTarget);
canvas.DrawDrawable(shape);

using var bitmap = canvas.Snapshot();
using var bitmap = renderTarget.Snapshot();
bitmap.Save("star.png");
```

Run the following command to generate the image:
```sh
dotnet run -p:OutputType=Exe
```
<details>
<summary>If you want to use effects and draw in the console</summary>

```cs
using Beutl.Media;
using Beutl.Graphics;
using Beutl.Graphics.Rendering;
using MyExtension;

var shape = new StarShape()
{
Size = 100,
Fill = Brushes.White
};

var canvasSize = new PixelSize(120, 120);
var node = new ContainerNode();
using (var deferred = new DeferredCanvas(node, canvasSize))
{
shape.Render(deferred);
}
// Use using (...) { ... } or the Dispose method before rendering the node.
using var canvas = new ImmediateCanvas(canvasSize.Width, canvasSize.Height);
node.Render(canvas);

using var bitmap = canvas.Snapshot();
bitmap.Save("star.png");
```

</details>

## 2. Create the SourceOperator Class

Expand All @@ -187,28 +159,21 @@ using Beutl.Operators.Source;
using Beutl.Graphics.Effects;
using Beutl.Graphics.Transformation;
using Beutl.Media;
using Beutl.Styling;

namespace MyExtension;

public class StarShapeOperator : DrawablePublishOperator<StarShape>
{
public Setter<float> Size { get; set; } = new(StarShape.SizeProperty, 100);

public Setter<ITransform?> Transform { get; set; } = new(Drawable.TransformProperty, new TransformGroup());

public Setter<AlignmentX> AlignmentX { get; set; } = new(Drawable.AlignmentXProperty, Media.AlignmentX.Center);

public Setter<AlignmentY> AlignmentY { get; set; } = new(Drawable.AlignmentYProperty, Media.AlignmentY.Center);

public Setter<RelativePoint> TransformOrigin { get; set; } = new(Drawable.TransformOriginProperty, RelativePoint.Center);

public Setter<IBrush?> Fill { get; set; } = new(Drawable.FillProperty, new SolidColorBrush(Colors.White));

public Setter<FilterEffect?> FilterEffect { get; set; } = new(Drawable.FilterEffectProperty, new FilterEffectGroup());

public Setter<BlendMode> BlendMode { get; set; } = new(Drawable.BlendModeProperty, Graphics.BlendMode.SrcOver);
}
public class StarShapeOperator() : PublishOperator<StarShape>(
[
(StarShape.WidthProperty, 100),
(Drawable.TransformProperty, () => new TransformGroup()),
Drawable.AlignmentXProperty,
Drawable.AlignmentYProperty,
Drawable.TransformOriginProperty,
(Drawable.FillProperty, () => new SolidColorBrush(Colors.White)),
(Drawable.FilterEffectProperty, () => new FilterEffectGroup()),
Drawable.BlendModeProperty,
Drawable.OpacityProperty
]);
```

## 3. Create the Extension Class
Expand Down
40 changes: 22 additions & 18 deletions en/extensions/implement-effect.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,35 +71,39 @@ public class MyFilterEffect : FilterEffect
public override void ApplyTo(FilterEffectContext context)
{
// The data argument is passed to the action and transformBounds methods
// Specify a comparable value
context.Custom(
// Specify an equivalence-comparable value
context.CustomTom(
data: 0,
action: CustomEffectProcess,
transformBounds: (_, b) => b);
}

private static void CustomEffectProcess(int _, FilterEffectCustonOperationContext context)
private static void CustomEffectProcess(int _, CustomFilterEffectContext context)
{
// Obtain SKSurface
if (context.Target.Surface is { } surface)
for (int i = 0; i < context.Targets.Count; i++)
{
// Use SKCanvas
EffectTarget target = context.Targets[i];
RenderTarget renderTarget = target.RenderTarget!;
// When operating Skia directly
// 1. Get SKSurface
SKSurface surface = RenderTarget.GetSKSurface(renderTarget);
// 2. Get SKCanvas
SKCanvas skcanvas = surface.Value.Canvas;
// 3. Manipulate
skcanvas.Clear();
}

// Use Beutl's canvas
using (ImmediateCanvas canvas = context.Open(context.Target))
{
canvas.Clear();
}
// When using the Beutl wrapper
// 1. Create Canvas
using (var canvas = new ImmediateCanvas(renderTarget))
{
// 2. Manipulate
canvas.Clear();
}

// Replace the effect target
// (Change the image processed by subsequent effects)
// Using a reference counter, hence using 'using'.
using (var newTarget = context.CreateTarget(width: 100, height: 100))
{
context.ReplaceTarget(newTarget);
// If you want to change the image size
var newTarget = context.CreateTarget(width: 100, height: 100);
context.Targets[i] = newTarget;
target.Dispose();
}
}
}
Expand Down
21 changes: 13 additions & 8 deletions en/extensions/version-mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ description: List of Beutl versions and their corresponding dependencies, framew

This table lists the versions of Beutl along with their corresponding dependencies, frameworks, and library versions.

| Beutl | .NET | [Avalonia](https://github.com/AvaloniaUI/Avalonia) | FFmpeg |
| --------------- | ---- | -------------------------------------------------- | ------ |
| 1.0.0-preview.6 | 8.0 | 11.0.10 | 6.0 |
| 1.0.0-preview.5 | 8.0 | 11.0.9 | 6.0 |
| 1.0.0-preview.4 | 8.0 | 11.0.5 | 6.0 |
| 1.0.0-preview.3 | 7.0 | 11.0.4 | 6.0 |
| 1.0.0-preview.2 | 7.0 | 11.0.4 | 6.0 |
| 1.0.0-preview.1 | 7.0 | 11.0.4 | 6.0 |
| Beutl | .NET | [Avalonia](https://github.com/AvaloniaUI/Avalonia) | FFmpeg |
| ---------------- | ---- | -------------------------------------------------- | ------ |
| 1.0.0-preview.11 | 9.0 | 11.1.3 | 6.0 |
| 1.0.0-preview.10 | 8.0 | 11.1.3 | 6.0 |
| 1.0.0-preview.9 | 8.0 | 11.1.3 | 6.0 |
| 1.0.0-preview.8 | 8.0 | 11.0.11 | 6.0 |
| 1.0.0-preview.7 | 8.0 | 11.0.10 | 6.0 |
| 1.0.0-preview.6 | 8.0 | 11.0.10 | 6.0 |
| 1.0.0-preview.5 | 8.0 | 11.0.9 | 6.0 |
| 1.0.0-preview.4 | 8.0 | 11.0.5 | 6.0 |
| 1.0.0-preview.3 | 7.0 | 11.0.4 | 6.0 |
| 1.0.0-preview.2 | 7.0 | 11.0.4 | 6.0 |
| 1.0.0-preview.1 | 7.0 | 11.0.4 | 6.0 |
Loading

0 comments on commit 69462e3

Please sign in to comment.