mirror of
https://github.com/greenshot/greenshot
synced 2025-08-22 22:34:27 -07:00
Some small fixes, removed Span<T> as a stackalloc replacement as on .NET 4.7.1 this slows down. Not sure why the memory usage doubled for the Scale3x_Unmanaged performance test though.
This commit is contained in:
parent
a6e13a6f32
commit
e91bf3f2d0
7 changed files with 132 additions and 105 deletions
|
@ -177,14 +177,14 @@ Task("EnableDNC30")
|
||||||
.Does(() =>
|
.Does(() =>
|
||||||
{
|
{
|
||||||
ReplaceRegexInFiles("./**/*.csproj", "<TargetFrameworks>.*</TargetFrameworks><!-- net472;netcoreapp3.0 -->", "<TargetFrameworks>net472;netcoreapp3.0</TargetFrameworks>");
|
ReplaceRegexInFiles("./**/*.csproj", "<TargetFrameworks>.*</TargetFrameworks><!-- net472;netcoreapp3.0 -->", "<TargetFrameworks>net472;netcoreapp3.0</TargetFrameworks>");
|
||||||
ReplaceRegexInFiles("./**/*.csproj", "<Project Sdk=\"MSBuild.Sdk.Extras/1.6.65\"><!-- Microsoft.NET.Sdk.WindowsDesktop -->", "<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">");
|
ReplaceRegexInFiles("./**/*.csproj", "<Project Sdk=\"Microsoft.NET.Sdk\"><!-- Microsoft.NET.Sdk.WindowsDesktop -->", "<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">");
|
||||||
});
|
});
|
||||||
|
|
||||||
Task("DisableDNC30")
|
Task("DisableDNC30")
|
||||||
.Does(() =>
|
.Does(() =>
|
||||||
{
|
{
|
||||||
ReplaceRegexInFiles("./**/*.csproj", "<TargetFrameworks>net472;netcoreapp3.0</TargetFrameworks>", "<TargetFrameworks>net472</TargetFrameworks><!-- net472;netcoreapp3.0 -->");
|
ReplaceRegexInFiles("./**/*.csproj", "<TargetFrameworks>net472;netcoreapp3.0</TargetFrameworks>", "<TargetFrameworks>net472</TargetFrameworks><!-- net472;netcoreapp3.0 -->");
|
||||||
ReplaceRegexInFiles("./**/*.csproj", "<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">", "<Project Sdk=\"MSBuild.Sdk.Extras/1.6.65\"><!-- Microsoft.NET.Sdk.WindowsDesktop -->");
|
ReplaceRegexInFiles("./**/*.csproj", "<Project Sdk=\"Microsoft.NET.Sdk.WindowsDesktop\">", "<Project Sdk=\"Microsoft.NET.Sdk\"><!-- Microsoft.NET.Sdk.WindowsDesktop -->");
|
||||||
});
|
});
|
||||||
|
|
||||||
Task("ChangeNETVersion")
|
Task("ChangeNETVersion")
|
||||||
|
|
|
@ -23,9 +23,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Greenshot.Gfx.Experimental;
|
|
||||||
|
|
||||||
namespace Greenshot.Gfx
|
namespace Greenshot.Gfx.Experimental
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the ScaleX code for the UnmanagedBitmap
|
/// This is the ScaleX code for the UnmanagedBitmap
|
||||||
|
@ -33,11 +32,11 @@ namespace Greenshot.Gfx
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class ScaleXUnmanaged
|
public static class ScaleXUnmanaged
|
||||||
{
|
{
|
||||||
private const int ColorB = 0;
|
private const byte ColorB = 0;
|
||||||
private const int ColorD = 1;
|
private const byte ColorD = 1;
|
||||||
private const int ColorE = 4;
|
private const byte ColorE = 4;
|
||||||
private const int ColorF = 2;
|
private const byte ColorF = 2;
|
||||||
private const int ColorH = 3;
|
private const byte ColorH = 3;
|
||||||
private const byte ColorA = 5;
|
private const byte ColorA = 5;
|
||||||
private const byte ColorC = 6;
|
private const byte ColorC = 6;
|
||||||
private const byte ColorG = 7;
|
private const byte ColorG = 7;
|
||||||
|
@ -59,11 +58,12 @@ namespace Greenshot.Gfx
|
||||||
|
|
||||||
var sourceWidth = sourceBitmap.Width;
|
var sourceWidth = sourceBitmap.Width;
|
||||||
var destinationWidth = destinationBitmap.Width;
|
var destinationWidth = destinationBitmap.Width;
|
||||||
ReadOnlySpan<int> sourceSpan = MemoryMarshal.Cast<TPixelLayout, int>(sourceBitmap.Span);
|
ReadOnlySpan<uint> sourceSpan = MemoryMarshal.Cast<TPixelLayout, uint>(sourceBitmap.Span);
|
||||||
var destinationSpan = MemoryMarshal.Cast<TPixelLayout, int>(destinationBitmap.Span);
|
var destinationSpan = MemoryMarshal.Cast<TPixelLayout, uint>(destinationBitmap.Span);
|
||||||
|
unsafe
|
||||||
Span<int> colors = stackalloc int[5];
|
{
|
||||||
Span<int> colorsE = stackalloc int[4];
|
var colors = stackalloc uint[5];
|
||||||
|
var colorsE = stackalloc uint[4];
|
||||||
for (var y = 0; y < sourceBitmap.Height; y++)
|
for (var y = 0; y < sourceBitmap.Height; y++)
|
||||||
{
|
{
|
||||||
var sourceYOffset = y * sourceWidth;
|
var sourceYOffset = y * sourceWidth;
|
||||||
|
@ -131,6 +131,8 @@ namespace Greenshot.Gfx
|
||||||
destinationSpan[destinationOffset] = colorsE[0];
|
destinationSpan[destinationOffset] = colorsE[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return destinationBitmap;
|
return destinationBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,18 +149,19 @@ namespace Greenshot.Gfx
|
||||||
throw new NotSupportedException("Only 4 byte unmanaged structs are supported.");
|
throw new NotSupportedException("Only 4 byte unmanaged structs are supported.");
|
||||||
}
|
}
|
||||||
var destinationBitmap = new UnmanagedBitmap<TPixelLayout>(sourceBitmap.Width * 3, sourceBitmap.Height * 3);
|
var destinationBitmap = new UnmanagedBitmap<TPixelLayout>(sourceBitmap.Width * 3, sourceBitmap.Height * 3);
|
||||||
ReadOnlySpan<int> sourceSpan = MemoryMarshal.Cast<TPixelLayout, int>(sourceBitmap.Span);
|
|
||||||
var destinationSpan = MemoryMarshal.Cast<TPixelLayout, int>(destinationBitmap.Span);
|
ReadOnlySpan<uint> sourceSpan = MemoryMarshal.Cast<TPixelLayout, uint>(sourceBitmap.Span);
|
||||||
|
var destinationSpan = MemoryMarshal.Cast<TPixelLayout, uint>(destinationBitmap.Span);
|
||||||
|
|
||||||
var sourceWidth = sourceBitmap.Width;
|
var sourceWidth = sourceBitmap.Width;
|
||||||
var destinationWidth = destinationBitmap.Width;
|
var destinationWidth = destinationBitmap.Width;
|
||||||
|
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
Span<int> colors = stackalloc int[9];
|
var colors = stackalloc uint[9];
|
||||||
Span<int> colorsE = stackalloc int[9];
|
var colorsE = stackalloc uint[9];
|
||||||
|
|
||||||
for (int y = 0; y < sourceBitmap.Height; y++)
|
for (var y = 0; y < sourceBitmap.Height; y++)
|
||||||
{
|
{
|
||||||
var sourceYOffset = y * sourceWidth;
|
var sourceYOffset = y * sourceWidth;
|
||||||
var destinationYOffset = y * 3 * destinationWidth;
|
var destinationYOffset = y * 3 * destinationWidth;
|
||||||
|
@ -166,10 +169,8 @@ namespace Greenshot.Gfx
|
||||||
{
|
{
|
||||||
var sourceOffset = sourceYOffset + x;
|
var sourceOffset = sourceYOffset + x;
|
||||||
|
|
||||||
//source.GetColorAt(x, y, colors[ColorE]);
|
|
||||||
colors[ColorE] = sourceSpan[sourceOffset];
|
colors[ColorE] = sourceSpan[sourceOffset];
|
||||||
|
|
||||||
//source.GetColorAt(x - 1, y - 1, colors[ColorA]);
|
|
||||||
if (y != 0 && x != 0)
|
if (y != 0 && x != 0)
|
||||||
{
|
{
|
||||||
colors[ColorA] = sourceSpan[(sourceOffset - 1) - sourceWidth];
|
colors[ColorA] = sourceSpan[(sourceOffset - 1) - sourceWidth];
|
||||||
|
@ -179,7 +180,6 @@ namespace Greenshot.Gfx
|
||||||
colors[ColorA] = colors[ColorE];
|
colors[ColorA] = colors[ColorE];
|
||||||
}
|
}
|
||||||
|
|
||||||
//source.GetColorAt(x, y - 1, colors[ColorB]);
|
|
||||||
if (y != 0)
|
if (y != 0)
|
||||||
{
|
{
|
||||||
colors[ColorB] = sourceSpan[sourceOffset - sourceWidth];
|
colors[ColorB] = sourceSpan[sourceOffset - sourceWidth];
|
||||||
|
@ -189,7 +189,6 @@ namespace Greenshot.Gfx
|
||||||
colors[ColorB] = colors[ColorE];
|
colors[ColorB] = colors[ColorE];
|
||||||
}
|
}
|
||||||
|
|
||||||
//source.GetColorAt(x + 1, y - 1, colors[ColorC]);
|
|
||||||
if (x < sourceWidth - 1 && y != 0)
|
if (x < sourceWidth - 1 && y != 0)
|
||||||
{
|
{
|
||||||
colors[ColorC] = sourceSpan[(sourceOffset + 1) - sourceWidth];
|
colors[ColorC] = sourceSpan[(sourceOffset + 1) - sourceWidth];
|
||||||
|
@ -199,7 +198,6 @@ namespace Greenshot.Gfx
|
||||||
colors[ColorC] = colors[ColorE];
|
colors[ColorC] = colors[ColorE];
|
||||||
}
|
}
|
||||||
|
|
||||||
//source.GetColorAt(x - 1, y, colors[ColorD]);
|
|
||||||
if (x != 0)
|
if (x != 0)
|
||||||
{
|
{
|
||||||
colors[ColorD] = sourceSpan[sourceOffset - 1];
|
colors[ColorD] = sourceSpan[sourceOffset - 1];
|
||||||
|
@ -209,7 +207,6 @@ namespace Greenshot.Gfx
|
||||||
colors[ColorD] = colors[ColorE];
|
colors[ColorD] = colors[ColorE];
|
||||||
}
|
}
|
||||||
|
|
||||||
//source.GetColorAt(x + 1, y, colors[ColorF]);
|
|
||||||
if (x < sourceWidth - 1)
|
if (x < sourceWidth - 1)
|
||||||
{
|
{
|
||||||
colors[ColorF] = sourceSpan[sourceOffset + 1];
|
colors[ColorF] = sourceSpan[sourceOffset + 1];
|
||||||
|
@ -219,7 +216,6 @@ namespace Greenshot.Gfx
|
||||||
colors[ColorF] = colors[ColorE];
|
colors[ColorF] = colors[ColorE];
|
||||||
}
|
}
|
||||||
|
|
||||||
//source.GetColorAt(x - 1, y + 1, colors[ColorG]);
|
|
||||||
if (x != 0 && y < sourceBitmap.Height - 1)
|
if (x != 0 && y < sourceBitmap.Height - 1)
|
||||||
{
|
{
|
||||||
colors[ColorG] = sourceSpan[(sourceOffset - 1) + sourceWidth];
|
colors[ColorG] = sourceSpan[(sourceOffset - 1) + sourceWidth];
|
||||||
|
@ -229,7 +225,6 @@ namespace Greenshot.Gfx
|
||||||
colors[ColorG] = colors[ColorE];
|
colors[ColorG] = colors[ColorE];
|
||||||
}
|
}
|
||||||
|
|
||||||
//source.GetColorAt(x, y + 1, colors[ColorH]);
|
|
||||||
if (y < sourceBitmap.Height - 1)
|
if (y < sourceBitmap.Height - 1)
|
||||||
{
|
{
|
||||||
colors[ColorH] = sourceSpan[sourceOffset + sourceWidth];
|
colors[ColorH] = sourceSpan[sourceOffset + sourceWidth];
|
||||||
|
@ -239,7 +234,6 @@ namespace Greenshot.Gfx
|
||||||
colors[ColorH] = colors[ColorE];
|
colors[ColorH] = colors[ColorE];
|
||||||
}
|
}
|
||||||
|
|
||||||
//source.GetColorAt(x + 1, y + 1, colors[ColorI]);
|
|
||||||
if (x < sourceWidth - 1 && y < sourceBitmap.Height - 1)
|
if (x < sourceWidth - 1 && y < sourceBitmap.Height - 1)
|
||||||
{
|
{
|
||||||
colors[ColorI] = sourceSpan[sourceOffset + 1 + sourceWidth];
|
colors[ColorI] = sourceSpan[sourceOffset + 1 + sourceWidth];
|
||||||
|
@ -251,22 +245,31 @@ namespace Greenshot.Gfx
|
||||||
|
|
||||||
if (colors[ColorB] != colors[ColorH] && colors[ColorD] != colors[ColorF])
|
if (colors[ColorB] != colors[ColorH] && colors[ColorD] != colors[ColorF])
|
||||||
{
|
{
|
||||||
colorsE[0] = colors[ColorD] == colors[ColorB] ? colors[ColorD] : colors[ColorE];
|
colorsE[8] = colors[ColorH] == colors[ColorF] ? colors[ColorF] : colors[ColorE];
|
||||||
colorsE[1] = colors[ColorD] == colors[ColorB] && colors[ColorE] != colors[ColorC] || colors[ColorB] == colors[ColorF] && colors[ColorE] != colors[ColorA] ? colors[ColorB] : colors[ColorE];
|
colorsE[7] = colors[ColorD] == colors[ColorH] && colors[ColorE] != colors[ColorI] || colors[ColorH] == colors[ColorF] && colors[ColorE] != colors[ColorG] ? colors[ColorH] : colors[ColorE];
|
||||||
colorsE[2] = colors[ColorB] == colors[ColorF] ? colors[ColorF]: colors[ColorE];
|
colorsE[6] = colors[ColorD] == colors[ColorH] ? colors[ColorD] : colors[ColorE];
|
||||||
colorsE[3] = colors[ColorD] == colors[ColorB] && colors[ColorE] != colors[ColorG] || colors[ColorD] == colors[ColorH] && colors[ColorE] != colors[ColorA] ? colors[ColorD] : colors[ColorE];
|
colorsE[5] = colors[ColorB] == colors[ColorF] && colors[ColorE] != colors[ColorI] || colors[ColorH] == colors[ColorF] && colors[ColorE] != colors[ColorC] ? colors[ColorF] : colors[ColorE];
|
||||||
|
|
||||||
colorsE[4] = colors[ColorE];
|
colorsE[4] = colors[ColorE];
|
||||||
colorsE[5] = colors[ColorB] == colors[ColorF] && colors[ColorE] != colors[ColorI] || colors[ColorH] == colors[ColorF] && colors[ColorE] != colors[ColorC] ? colors[ColorF] : colors[ColorE];
|
|
||||||
colorsE[6] = colors[ColorD] == colors[ColorH] ? colors[ColorD] : colors[ColorE];
|
colorsE[3] = colors[ColorD] == colors[ColorB] && colors[ColorE] != colors[ColorG] || colors[ColorD] == colors[ColorH] && colors[ColorE] != colors[ColorA] ? colors[ColorD] : colors[ColorE];
|
||||||
colorsE[7] = colors[ColorD] == colors[ColorH] && colors[ColorE] != colors[ColorI] || colors[ColorH] == colors[ColorF] && colors[ColorE] != colors[ColorG] ? colors[ColorH] : colors[ColorE];
|
colorsE[2] = colors[ColorB] == colors[ColorF] ? colors[ColorF] : colors[ColorE];
|
||||||
colorsE[8] = colors[ColorH] == colors[ColorF] ? colors[ColorF] : colors[ColorE];
|
colorsE[1] = colors[ColorD] == colors[ColorB] && colors[ColorE] != colors[ColorC] || colors[ColorB] == colors[ColorF] && colors[ColorE] != colors[ColorA] ? colors[ColorB] : colors[ColorE];
|
||||||
|
colorsE[0] = colors[ColorD] == colors[ColorB] ? colors[ColorD] : colors[ColorE];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
colorsE.Fill(colors[ColorE]);
|
colorsE[8] = colors[ColorE];
|
||||||
|
colorsE[7] = colors[ColorE];
|
||||||
|
colorsE[6] = colors[ColorE];
|
||||||
|
colorsE[5] = colors[ColorE];
|
||||||
|
colorsE[4] = colors[ColorE];
|
||||||
|
colorsE[3] = colors[ColorE];
|
||||||
|
colorsE[2] = colors[ColorE];
|
||||||
|
colorsE[1] = colors[ColorE];
|
||||||
|
colorsE[0] = colors[ColorE];
|
||||||
}
|
}
|
||||||
var destinationOffset = (x * 3) + destinationYOffset;
|
var destinationOffset = x * 3 + destinationYOffset;
|
||||||
|
|
||||||
destinationSpan[destinationOffset] = colorsE[0];
|
destinationSpan[destinationOffset] = colorsE[0];
|
||||||
destinationSpan[destinationOffset + 1] = colorsE[1];
|
destinationSpan[destinationOffset + 1] = colorsE[1];
|
||||||
|
@ -282,7 +285,6 @@ namespace Greenshot.Gfx
|
||||||
destinationSpan[destinationOffset + 1] = colorsE[7];
|
destinationSpan[destinationOffset + 1] = colorsE[7];
|
||||||
destinationSpan[destinationOffset + 2] = colorsE[8];
|
destinationSpan[destinationOffset + 2] = colorsE[8];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return destinationBitmap;
|
return destinationBitmap;
|
||||||
|
|
|
@ -22,13 +22,9 @@
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Greenshot.Gfx.Experimental;
|
|
||||||
using Greenshot.Gfx.Experimental.Structs;
|
|
||||||
|
|
||||||
namespace Greenshot.Gfx
|
namespace Greenshot.Gfx.Experimental
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the ScaleX code for the UnmanagedBitmap
|
/// This is the ScaleX code for the UnmanagedBitmap
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace Greenshot.Gfx.Experimental.Structs
|
||||||
public bool Equals(Bgr32 other) => (B, G, R) == (other.B, other.G, other.R);
|
public bool Equals(Bgr32 other) => (B, G, R) == (other.B, other.G, other.R);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override int GetHashCode() => HashCode.Combine(B, G, R);
|
public override int GetHashCode() => (B, G, R).GetHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,6 @@ namespace Greenshot.Gfx.Experimental.Structs
|
||||||
public bool Equals(Bgra32 other) => (B, G, R, A) == (other.B, other.G, other.R, other.A);
|
public bool Equals(Bgra32 other) => (B, G, R, A) == (other.B, other.G, other.R, other.A);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override int GetHashCode() => HashCode.Combine(B, G, R, A);
|
public override int GetHashCode() => (B, G, R, A).GetHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,46 @@
|
||||||
|
|
||||||
namespace Greenshot.Gfx.Experimental.Structs
|
namespace Greenshot.Gfx.Experimental.Structs
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
public class SpanInfo
|
public class SpanInfo
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Pointer to the memory
|
||||||
|
/// </summary>
|
||||||
public IntPtr Pointer;
|
public IntPtr Pointer;
|
||||||
|
/// <summary>
|
||||||
|
/// How many bytes are on a single line
|
||||||
|
/// </summary>
|
||||||
public int PixelStride;
|
public int PixelStride;
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
public int Height;
|
public int Height;
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
public int Width;
|
public int Width;
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
public int Left;
|
public int Left;
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
public int Right;
|
public int Right;
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
public int Top;
|
public int Top;
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
public int Bottom;
|
public int Bottom;
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
public int BitmapSize;
|
public int BitmapSize;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ namespace Greenshot.PerformanceTests
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Benchmark]
|
//[Benchmark]
|
||||||
public void Blur_Old()
|
public void Blur_Old()
|
||||||
{
|
{
|
||||||
using (var bitmap = BitmapFactory.CreateEmpty(400, 400, PixelFormat.Format32bppRgb, Color.White))
|
using (var bitmap = BitmapFactory.CreateEmpty(400, 400, PixelFormat.Format32bppRgb, Color.White))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue