diff --git a/src/Greenshot.Gfx/BoxBlurUnmanaged.cs b/src/Greenshot.Gfx/BoxBlurUnmanaged.cs index 661f05c33..a4174e7b2 100644 --- a/src/Greenshot.Gfx/BoxBlurUnmanaged.cs +++ b/src/Greenshot.Gfx/BoxBlurUnmanaged.cs @@ -18,7 +18,6 @@ // along with this program. If not, see . using System; -using System.Threading.Tasks; using Greenshot.Gfx.Structs; namespace Greenshot.Gfx @@ -89,61 +88,61 @@ namespace Greenshot.Gfx { var halfRange = range / 2; - Parallel.For(0, unmanagedBitmap.Height, y => + for(var y = 0; y averages = stackalloc Bgr32[range]; - var r = 0; - var g = 0; - var b = 0; - var hits = halfRange; - for (var x = 0; x < halfRange; x++) - { - ref Bgr32 color = ref rgb32[x]; + var rgb32 = unmanagedBitmap[y]; + Span averages = stackalloc Bgr32[range]; + var r = 0; + var g = 0; + var b = 0; + var hits = halfRange; + for (var x = 0; x < halfRange; x++) + { + ref var color = ref rgb32[x]; + r += color.R; + g += color.G; + b += color.B; + } + for (var x = 0; x < unmanagedBitmap.Width; x++) + { + var leftSide = x - halfRange - 1; + if (leftSide >= 0) + { + // Get value at the left side of range + ref var color = ref rgb32[leftSide]; + r -= color.R; + g -= color.G; + b -= color.B; + hits--; + } + + var rightSide = x + halfRange; + if (rightSide < unmanagedBitmap.Width) + { + ref var color = ref rgb32[rightSide]; r += color.R; g += color.G; b += color.B; + hits++; } - for (var x = 0; x < unmanagedBitmap.Width; x++) + + ref var average = ref averages[x % range]; + average.R = (byte)(r / hits); + average.G = (byte)(g / hits); + average.B = (byte)(b / hits); + + if (leftSide < 0) { - var leftSide = x - halfRange - 1; - if (leftSide >= 0) - { - // Get value at the left side of range - ref Bgr32 color = ref rgb32[leftSide]; - r -= color.R; - g -= color.G; - b -= color.B; - hits--; - } - - var rightSide = x + halfRange; - if (rightSide < unmanagedBitmap.Width) - { - ref Bgr32 color = ref rgb32[rightSide]; - r += color.R; - g += color.G; - b += color.B; - hits++; - } - - ref Bgr32 average = ref averages[x % range]; - average.R = (byte)(r / hits); - average.G = (byte)(g / hits); - average.B = (byte)(b / hits); - - if (leftSide >= 0) - { - // Now we can write the value from the calculated avarages - var readLocation = (leftSide % range); - - rgb32[leftSide] = averages[readLocation]; - } + continue; } + + // Now we can write the value from the calculated averages + var readLocation = (leftSide % range); + + rgb32[leftSide] = averages[readLocation]; } - }); + } } /// @@ -154,61 +153,61 @@ namespace Greenshot.Gfx private static void BoxBlurVertical(UnmanagedBitmap unmanagedBitmap, int range) { var halfRange = range / 2; - Parallel.For(0, unmanagedBitmap.Width, x => + for(var x = 0; x averages = stackalloc Bgr32[range]; - var hits = 0; - var r = 0; - var g = 0; - var b = 0; - for (var y = 0; y < halfRange; y++) + var rgb32 = unmanagedBitmap.Span; + Span averages = stackalloc Bgr32[range]; + var hits = 0; + var r = 0; + var g = 0; + var b = 0; + for (var y = 0; y < halfRange; y++) + { + ref var color = ref rgb32[(y * unmanagedBitmap.Width) + x]; + r += color.R; + g += color.G; + b += color.B; + hits++; + } + for (var y = 0; y < unmanagedBitmap.Height; y++) + { + var topSide = y - halfRange - 1; + if (topSide >= 0) { - ref Bgr32 color = ref rgb32[(y * unmanagedBitmap.Width) + x]; + // Get value at the top side of range + ref var color = ref rgb32[x + (topSide * unmanagedBitmap.Width)]; + r -= color.R; + g -= color.G; + b -= color.B; + hits--; + } + + var bottomSide = y + halfRange; + if (bottomSide < unmanagedBitmap.Height) + { + ref var color = ref rgb32[x + (bottomSide * unmanagedBitmap.Width)]; r += color.R; g += color.G; b += color.B; hits++; } - for (var y = 0; y < unmanagedBitmap.Height; y++) + + ref var average = ref averages[y % range]; + average.R = (byte)(r / hits); + average.G = (byte)(g / hits); + average.B = (byte)(b / hits); + + if (topSide < 0) { - var topSide = y - halfRange - 1; - if (topSide >= 0) - { - // Get value at the top side of range - ref Bgr32 color = ref rgb32[x + (topSide * unmanagedBitmap.Width)]; - r -= color.R; - g -= color.G; - b -= color.B; - hits--; - } - - var bottomSide = y + halfRange; - if (bottomSide < unmanagedBitmap.Height) - { - ref Bgr32 color = ref rgb32[x + (bottomSide * unmanagedBitmap.Width)]; - r += color.R; - g += color.G; - b += color.B; - hits++; - } - - ref Bgr32 average = ref averages[y % range]; - average.R = (byte)(r / hits); - average.G = (byte)(g / hits); - average.B = (byte)(b / hits); - - if (topSide >= 0) - { - // Write the value from the calculated avarages - var readLocation = topSide % range; - - rgb32[x + (topSide * unmanagedBitmap.Width)] = averages[readLocation]; - } + continue; } + + // Write the value from the calculated averages + var readLocation = topSide % range; + + rgb32[x + (topSide * unmanagedBitmap.Width)] = averages[readLocation]; } - }); + } } /// @@ -220,65 +219,65 @@ namespace Greenshot.Gfx { var halfRange = range / 2; - Parallel.For(0, unmanagedBitmap.Height, y => + for(var y = 0; y averages = stackalloc Bgra32[range]; - var a = 0; - var r = 0; - var g = 0; - var b = 0; - var hits = halfRange; - for (var x = 0; x < halfRange; x++) + var argb32 = unmanagedBitmap[y]; + Span averages = stackalloc Bgra32[range]; + var a = 0; + var r = 0; + var g = 0; + var b = 0; + var hits = halfRange; + for (var x = 0; x < halfRange; x++) + { + ref var color = ref argb32[x]; + a += color.A; + r += color.R; + g += color.G; + b += color.B; + } + for (var x = 0; x < unmanagedBitmap.Width; x++) + { + var leftSide = x - halfRange - 1; + if (leftSide >= 0) { - ref Bgra32 color = ref argb32[x]; + // Get value at the left side of range + ref var color = ref argb32[leftSide]; + a -= color.A; + r -= color.R; + g -= color.G; + b -= color.B; + hits--; + } + + var rightSide = x + halfRange; + if (rightSide < unmanagedBitmap.Width) + { + ref var color = ref argb32[rightSide]; a += color.A; r += color.R; g += color.G; b += color.B; + hits++; } - for (var x = 0; x < unmanagedBitmap.Width; x++) + + ref var average = ref averages[x % range]; + average.A = (byte)(a / hits); + average.R = (byte)(r / hits); + average.G = (byte)(g / hits); + average.B = (byte)(b / hits); + + if (leftSide < 0) { - var leftSide = x - halfRange - 1; - if (leftSide >= 0) - { - // Get value at the left side of range - ref Bgra32 color = ref argb32[leftSide]; - a -= color.A; - r -= color.R; - g -= color.G; - b -= color.B; - hits--; - } - - var rightSide = x + halfRange; - if (rightSide < unmanagedBitmap.Width) - { - ref Bgra32 color = ref argb32[rightSide]; - a += color.A; - r += color.R; - g += color.G; - b += color.B; - hits++; - } - - ref Bgra32 average = ref averages[x % range]; - average.A = (byte)(a / hits); - average.R = (byte)(r / hits); - average.G = (byte)(g / hits); - average.B = (byte)(b / hits); - - if (leftSide >= 0) - { - // Now we can write the value from the calculated avarages - var readLocation = leftSide % range; - - argb32[leftSide] = averages[readLocation]; - } + continue; } + + // Now we can write the value from the calculated averages + var readLocation = leftSide % range; + + argb32[leftSide] = averages[readLocation]; } - }); + } } /// @@ -289,67 +288,66 @@ namespace Greenshot.Gfx private static void BoxBlurVertical(UnmanagedBitmap unmanagedBitmap, int range) { var halfRange = range / 2; - Parallel.For(0, unmanagedBitmap.Width, x => + for(var x = 0; x averages = stackalloc Bgra32[range]; + var hits = 0; + var a = 0; + var r = 0; + var g = 0; + var b = 0; + for (var y = 0; y < halfRange; y++) { - var argb32 = unmanagedBitmap.Span; - Span averages = stackalloc Bgra32[range]; - var hits = 0; - var a = 0; - var r = 0; - var g = 0; - var b = 0; - for (var y = 0; y < halfRange; y++) + ref var color = ref argb32[x + (y * unmanagedBitmap.Width)]; + a += color.A; + r += color.R; + g += color.G; + b += color.B; + hits++; + } + for (var y = 0; y < unmanagedBitmap.Height; y++) + { + var topSide = y - halfRange - 1; + if (topSide >= 0) { - ref Bgra32 color = ref argb32[x + (y * unmanagedBitmap.Width)]; + // Get value at the top side of range + ref var color = ref argb32[x + (topSide * unmanagedBitmap.Width)]; + a -= color.A; + r -= color.R; + g -= color.G; + b -= color.B; + hits--; + } + + var bottomSide = y + halfRange; + if (bottomSide < unmanagedBitmap.Height) + { + ref var color = ref argb32[x + (bottomSide * unmanagedBitmap.Width)]; a += color.A; r += color.R; g += color.G; b += color.B; hits++; } - for (var y = 0; y < unmanagedBitmap.Height; y++) + + ref var average = ref averages[(y % range)]; + average.A = (byte)(a / hits); + average.R = (byte)(r / hits); + average.G = (byte)(g / hits); + average.B = (byte)(b / hits); + + if (topSide < 0) { - var topSide = y - halfRange - 1; - if (topSide >= 0) - { - // Get value at the top side of range - ref Bgra32 color = ref argb32[x + (topSide * unmanagedBitmap.Width)]; - a -= color.A; - r -= color.R; - g -= color.G; - b -= color.B; - hits--; - } - - var bottomSide = y + halfRange; - if (bottomSide < unmanagedBitmap.Height) - { - ref Bgra32 color = ref argb32[x + (bottomSide * unmanagedBitmap.Width)]; - a += color.A; - r += color.R; - g += color.G; - b += color.B; - hits++; - } - - ref Bgra32 average = ref averages[(y % range)]; - average.A = (byte)(a / hits); - average.R = (byte)(r / hits); - average.G = (byte)(g / hits); - average.B = (byte)(b / hits); - - if (topSide >= 0) - { - // Write the value from the calculated avarages - var readLocation = (topSide % range); - - argb32[x + (topSide * unmanagedBitmap.Width)] = averages[readLocation]; - } + continue; } + + // Write the value from the calculated averages + var readLocation = (topSide % range); + + argb32[x + (topSide * unmanagedBitmap.Width)] = averages[readLocation]; } - }); + } } } } diff --git a/src/Greenshot.Gfx/ScaleXUnmanaged.cs b/src/Greenshot.Gfx/ScaleXUnmanaged.cs index 02ac9fb28..3a12e4032 100644 --- a/src/Greenshot.Gfx/ScaleXUnmanaged.cs +++ b/src/Greenshot.Gfx/ScaleXUnmanaged.cs @@ -18,6 +18,7 @@ // along with this program. If not, see . using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Greenshot.Gfx @@ -44,45 +45,44 @@ namespace Greenshot.Gfx var sourceWidth = sourceBitmap.Width; var destinationWidth = destinationBitmap.Width; - ReadOnlySpan sourceSpan = MemoryMarshal.Cast(sourceBitmap.Span); - var destinationSpan = MemoryMarshal.Cast(destinationBitmap.Span); + ref var destinationPointer = ref Unsafe.As(ref destinationBitmap.Span.GetPinnableReference()); + ref var sourcePointer = ref Unsafe.As(ref sourceBitmap.Span.GetPinnableReference()); for (var y = 0; y < sourceBitmap.Height; y++) { var sourceYOffset = y * sourceWidth; var destinationYOffset = (y << 1) * destinationWidth; for (var x = 0; x < sourceWidth; x++) { - var sourceOffset = sourceYOffset + x; - ref readonly uint colorE = ref sourceSpan[sourceOffset]; + ref var colorE = ref Unsafe.Add(ref sourcePointer, sourceYOffset + x); - ref readonly uint colorB = ref colorE; + ref readonly var colorB = ref colorE; if (y != 0) { - colorB = ref sourceSpan[sourceOffset - sourceWidth]; + colorB = ref Unsafe.Subtract(ref colorE, sourceWidth); } - ref readonly uint colorH = ref colorE; + ref readonly var colorH = ref colorE; if (y != sourceBitmap.Height - 1) { - colorH = ref sourceSpan[sourceOffset + sourceWidth]; + colorH = ref Unsafe.Add(ref colorE, sourceWidth); } - ref readonly uint colorD = ref colorE; + ref readonly var colorD = ref colorE; if (x > 0) { - colorD = ref sourceSpan[sourceOffset - 1]; + colorD = ref Unsafe.Subtract(ref colorE, 1); } - ref readonly uint colorF = ref colorE; + ref readonly var colorF = ref colorE; if (x < sourceBitmap.Width - 1) { - colorF = ref sourceSpan[sourceOffset + 1]; + colorF = ref Unsafe.Add(ref colorE, 1); } - ref readonly uint colorE0 = ref colorE; - ref readonly uint colorE1 = ref colorE; - ref readonly uint colorE2 = ref colorE; - ref readonly uint colorE3 = ref colorE; + ref readonly var colorE0 = ref colorE; + ref readonly var colorE1 = ref colorE; + ref readonly var colorE2 = ref colorE; + ref readonly var colorE3 = ref colorE; if (colorB != colorH && colorD != colorF) { if (colorH == colorF) @@ -102,17 +102,19 @@ namespace Greenshot.Gfx colorE0 = ref colorD; } } - var destinationOffset = (x << 1) + destinationYOffset; - destinationSpan[destinationOffset + 1 + destinationWidth] = colorE3; - destinationSpan[destinationOffset + destinationWidth] = colorE2; - destinationSpan[destinationOffset + 1] = colorE1; - destinationSpan[destinationOffset] = colorE0; + + ref var destColorE0 = ref Unsafe.Add(ref destinationPointer, (x << 1) + destinationYOffset); + destColorE0 = colorE0; + Unsafe.Add(ref destColorE0, 1 + destinationWidth) = colorE3; + Unsafe.Add(ref destColorE0, destinationWidth) = colorE2; + Unsafe.Add(ref destColorE0, 1) = colorE1; } } return destinationBitmap; } + /// /// Use "Scale3x" algorithm to produce bitmap from the original. /// Every pixel from input texture produces 6 output pixels, for more details check out http://scale2x.sourceforge.net/algorithm.html @@ -128,133 +130,129 @@ namespace Greenshot.Gfx // Create destination bitmap, where the scaled image is written to var destinationBitmap = new UnmanagedBitmap(sourceBitmap.Width * 3, sourceBitmap.Height * 3); - ReadOnlySpan sourceSpan = MemoryMarshal.Cast(sourceBitmap.Span); - var destinationSpan = MemoryMarshal.Cast(destinationBitmap.Span); - var sourceWidth = sourceBitmap.Width; var destinationWidth = destinationBitmap.Width; - unchecked + ref var destinationPointer = ref Unsafe.As(ref destinationBitmap.Span.GetPinnableReference()); + ref var sourcePointer = ref Unsafe.As(ref sourceBitmap.Span.GetPinnableReference()); + + for (var y = 0; y < sourceBitmap.Height; y++) { - for (var y = 0; y < sourceBitmap.Height; y++) + var sourceYOffset = y * sourceWidth; + var destinationYOffset = y * 3 * destinationWidth; + for (var x = 0; x < sourceWidth; x++) { - var sourceYOffset = y * sourceWidth; - var destinationYOffset = y * 3 * destinationWidth; - for (var x = 0; x < sourceWidth; x++) + ref var colorE = ref Unsafe.Add(ref sourcePointer, sourceYOffset + x); + ref readonly var colorA = ref colorE; + ref readonly var colorB = ref colorE; + ref readonly var colorC = ref colorE; + ref readonly var colorD = ref colorE; + ref readonly var colorF = ref colorE; + ref readonly var colorG = ref colorE; + ref readonly var colorH = ref colorE; + ref readonly var colorI = ref colorE; + + if (y != 0 && x != 0) { - var sourceOffset = sourceYOffset + x; - ref readonly uint colorE = ref sourceSpan[sourceOffset]; - ref readonly uint colorA = ref colorE; - ref readonly uint colorB = ref colorE; - ref readonly uint colorC = ref colorE; - ref readonly uint colorD = ref colorE; - ref readonly uint colorF = ref colorE; - ref readonly uint colorG = ref colorE; - ref readonly uint colorH = ref colorE; - ref readonly uint colorI = ref colorE; - - if (y != 0 && x != 0) - { - colorA = ref sourceSpan[sourceOffset - 1 - sourceWidth]; - } - - if (y != 0) - { - colorB = ref sourceSpan[sourceOffset - sourceWidth]; - } - - if (x < sourceWidth - 1 && y != 0) - { - colorC = ref sourceSpan[sourceOffset + 1 - sourceWidth]; - } - - if (x != 0) - { - colorD = ref sourceSpan[sourceOffset - 1]; - } - - if (x < sourceWidth - 1) - { - colorF = ref sourceSpan[sourceOffset + 1]; - } - - if (x != 0 && y < sourceBitmap.Height - 1) - { - colorG = ref sourceSpan[sourceOffset - 1 + sourceWidth]; - } - - if (y < sourceBitmap.Height - 1) - { - colorH = ref sourceSpan[sourceOffset + sourceWidth]; - } - - if (x < sourceWidth - 1 && y < sourceBitmap.Height - 1) - { - colorI = ref sourceSpan[sourceOffset + 1 + sourceWidth]; - } - - ref readonly uint colorE0 = ref colorE; - ref readonly uint colorE1 = ref colorE; - ref readonly uint colorE2 = ref colorE; - ref readonly uint colorE3 = ref colorE; - ref readonly uint colorE4 = ref colorE; - ref readonly uint colorE5 = ref colorE; - ref readonly uint colorE6 = ref colorE; - ref readonly uint colorE7 = ref colorE; - ref readonly uint colorE8 = ref colorE; - if (colorB != colorH && colorD != colorF) - { - if (colorH == colorF) - { - colorE8 = ref colorF; - } - if (colorD == colorH && colorE != colorI || colorH == colorF && colorE != colorG) - { - colorE7 = ref colorH; - } - if (colorD == colorH) - { - colorE6 = ref colorD; - } - if (colorB == colorF && colorE != colorI || colorH == colorF && colorE != colorC) - { - colorE5 = ref colorF; - } - - if (colorD == colorB && colorE != colorG || colorD == colorH && colorE != colorA) - { - colorE3 = ref colorD; - } - if (colorB == colorF) - { - colorE2 = ref colorF; - } - if (colorD == colorB && colorE != colorC || colorB == colorF && colorE != colorA) - { - colorE1 = ref colorB; - } - if (colorD == colorB) - { - colorE0 = ref colorD; - } - } - - var destinationOffset = x * 3 + destinationYOffset; - - destinationSpan[destinationOffset] = colorE0; - destinationSpan[destinationOffset + 1] = colorE1; - destinationSpan[destinationOffset + 2] = colorE2; - - destinationOffset += destinationWidth; - destinationSpan[destinationOffset] = colorE3; - destinationSpan[destinationOffset + 1] = colorE4; - destinationSpan[destinationOffset + 2] = colorE5; - - destinationOffset += destinationWidth; - destinationSpan[destinationOffset] = colorE6; - destinationSpan[destinationOffset + 1] = colorE7; - destinationSpan[destinationOffset + 2] = colorE8; + colorA = ref Unsafe.Subtract(ref colorE, 1 + sourceWidth); } + + if (y != 0) + { + colorB = ref Unsafe.Subtract(ref colorE, sourceWidth); + } + + if (x < sourceWidth - 1 && y != 0) + { + colorC = ref Unsafe.Subtract(ref colorE, sourceWidth - 1); + } + + if (x != 0) + { + colorD = ref Unsafe.Subtract(ref colorE, 1); + } + + if (x < sourceWidth - 1) + { + colorF = ref Unsafe.Add(ref colorE, 1); + } + + if (x != 0 && y < sourceBitmap.Height - 1) + { + colorG = ref Unsafe.Add(ref colorE, sourceWidth - 1); + } + + if (y < sourceBitmap.Height - 1) + { + colorH = ref Unsafe.Add(ref colorE, sourceWidth); + } + + if (x < sourceWidth - 1 && y < sourceBitmap.Height - 1) + { + colorI = ref Unsafe.Add(ref colorE, sourceWidth + 1); + } + + ref readonly var colorE0 = ref colorE; + ref readonly var colorE1 = ref colorE; + ref readonly var colorE2 = ref colorE; + ref readonly var colorE3 = ref colorE; + ref readonly var colorE4 = ref colorE; + ref readonly var colorE5 = ref colorE; + ref readonly var colorE6 = ref colorE; + ref readonly var colorE7 = ref colorE; + ref readonly var colorE8 = ref colorE; + if (colorB != colorH && colorD != colorF) + { + if (colorH == colorF) + { + colorE8 = ref colorF; + } + if (colorD == colorH && colorE != colorI || colorH == colorF && colorE != colorG) + { + colorE7 = ref colorH; + } + if (colorD == colorH) + { + colorE6 = ref colorD; + } + if (colorB == colorF && colorE != colorI || colorH == colorF && colorE != colorC) + { + colorE5 = ref colorF; + } + + if (colorD == colorB && colorE != colorG || colorD == colorH && colorE != colorA) + { + colorE3 = ref colorD; + } + if (colorB == colorF) + { + colorE2 = ref colorF; + } + if (colorD == colorB && colorE != colorC || colorB == colorF && colorE != colorA) + { + colorE1 = ref colorB; + } + if (colorD == colorB) + { + colorE0 = ref colorD; + } + } + + var destinationOffset = x * 3 + destinationYOffset; + + Unsafe.Add(ref destinationPointer, destinationOffset) = colorE0; + Unsafe.Add(ref destinationPointer, destinationOffset + 1) = colorE1; + Unsafe.Add(ref destinationPointer, destinationOffset + 2) = colorE2; + + destinationOffset += destinationWidth; + Unsafe.Add(ref destinationPointer, destinationOffset) = colorE3; + Unsafe.Add(ref destinationPointer, destinationOffset + 1) = colorE4; + Unsafe.Add(ref destinationPointer, destinationOffset + 2) = colorE5; + + destinationOffset += destinationWidth; + Unsafe.Add(ref destinationPointer, destinationOffset) = colorE6; + Unsafe.Add(ref destinationPointer, destinationOffset + 1) = colorE7; + Unsafe.Add(ref destinationPointer, destinationOffset + 2) = colorE8; } } diff --git a/src/Greenshot.PerformanceTests/GfxPerformance.cs b/src/Greenshot.PerformanceTests/GfxPerformance.cs index d732a7a07..51146d1fc 100644 --- a/src/Greenshot.PerformanceTests/GfxPerformance.cs +++ b/src/Greenshot.PerformanceTests/GfxPerformance.cs @@ -21,8 +21,7 @@ namespace Greenshot.PerformanceTests { _unmanagedTestBitmap = new UnmanagedBitmap(400, 400); _unmanagedTestBitmap.Span.Fill(new Bgr32 { B = 255, G = 255, R = 255, Unused = 0}); - using (var bitmap = _unmanagedTestBitmap.NativeBitmap) - using (var graphics = Graphics.FromImage(bitmap)) + using (var graphics = Graphics.FromImage(_unmanagedTestBitmap.NativeBitmap)) using (var pen = new SolidBrush(Color.Blue)) { graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340)); @@ -57,7 +56,7 @@ namespace Greenshot.PerformanceTests } } - //[Benchmark] + [Benchmark] public void Blur_FastBitmap() { using (var bitmap = BitmapFactory.CreateEmpty(400, 400, PixelFormat.Format32bppRgb, Color.White)) @@ -71,14 +70,13 @@ namespace Greenshot.PerformanceTests } } - //[Benchmark] + [Benchmark] public void Blur_UnmanagedBitmap() { using (var unmanagedBitmap = new UnmanagedBitmap(400, 400)) { unmanagedBitmap.Span.Fill(new Bgr32 { B = 255, G = 255, R = 255 }); - using (var bitmap = unmanagedBitmap.NativeBitmap) - using (var graphics = Graphics.FromImage(bitmap)) + using (var graphics = Graphics.FromImage(unmanagedBitmap.NativeBitmap)) using (var pen = new SolidBrush(Color.Blue)) { graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340)); @@ -89,7 +87,7 @@ namespace Greenshot.PerformanceTests } - //[Benchmark] + [Benchmark] public void Blur_Old() { using (var bitmap = BitmapFactory.CreateEmpty(400, 400, PixelFormat.Format32bppRgb, Color.White)) @@ -121,19 +119,19 @@ namespace Greenshot.PerformanceTests _unmanagedTestBitmap.Scale2XReference().Dispose(); } - [Benchmark] + //[Benchmark] public void Scale3x_FastBitmap() { ScaleX.Scale3X(_unmanagedTestBitmap).Dispose(); } - [Benchmark] + //[Benchmark] public void Scale3x_Unmanaged() { _unmanagedTestBitmap.Scale3X().Dispose(); } - [Benchmark] + //[Benchmark] public void Scale3x_Unmanaged_Reference() { _unmanagedTestBitmap.Scale3XReference().Dispose(); diff --git a/src/Greenshot.PerformanceTests/Program.cs b/src/Greenshot.PerformanceTests/Program.cs index 0751610e9..bc15e4b61 100644 --- a/src/Greenshot.PerformanceTests/Program.cs +++ b/src/Greenshot.PerformanceTests/Program.cs @@ -30,8 +30,8 @@ namespace Greenshot.PerformanceTests // ReSharper disable once UnusedParameter.Local private static void Main(string[] args) { - //BenchmarkRunner.Run(); - BenchmarkRunner.Run(); + BenchmarkRunner.Run(); + //BenchmarkRunner.Run(); Console.ReadLine(); } } diff --git a/src/Greenshot.Tests/BlurTests.cs b/src/Greenshot.Tests/BlurTests.cs index 3a35bf55a..3efab433b 100644 --- a/src/Greenshot.Tests/BlurTests.cs +++ b/src/Greenshot.Tests/BlurTests.cs @@ -70,19 +70,18 @@ namespace Greenshot.Tests using (var pen = new SolidBrush(Color.Blue)) { graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340)); - BoxBlurOld.ApplyOldBoxBlur(bitmapOld, 10); } + BoxBlurOld.ApplyOldBoxBlur(bitmapOld, 10); bitmapOld.NativeBitmap.Save(@"old.png", ImageFormat.Png); bitmapNew.Span.Fill(new Bgr32 { B = 255, G = 255, R = 255 }); - using (var bitmap = bitmapNew.NativeBitmap) - using (var graphics = Graphics.FromImage(bitmap)) + using (var graphics = Graphics.FromImage(bitmapNew.NativeBitmap)) using (var pen = new SolidBrush(Color.Blue)) { graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340)); - bitmapNew.ApplyBoxBlur(10); - bitmap.Save(@"new.png", ImageFormat.Png); } + bitmapNew.ApplyBoxBlur(10); + bitmapNew.NativeBitmap.Save(@"new.png", ImageFormat.Png); Assert.True(bitmapOld.IsEqualTo(bitmapNew), "New blur doesn't compare to old."); } diff --git a/src/Greenshot.Tests/ScaleXTests.cs b/src/Greenshot.Tests/ScaleXTests.cs index 86c69972e..742e0643e 100644 --- a/src/Greenshot.Tests/ScaleXTests.cs +++ b/src/Greenshot.Tests/ScaleXTests.cs @@ -37,7 +37,7 @@ namespace Greenshot.Tests { LogSettings.RegisterDefaultLogger(LogLevels.Verbose, testOutputHelper); } - + [Fact] public void Test_Scale2X_UnmanagedBitmap() { @@ -50,8 +50,7 @@ namespace Greenshot.Tests graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340)); } bitmapNew.Span.Fill(new Bgr32 { B = 255, G = 255, R = 255, Unused = 0 }); - using (var bitmap = bitmapNew.NativeBitmap) - using (var graphics = Graphics.FromImage(bitmap)) + using (var graphics = Graphics.FromImage(bitmapNew.NativeBitmap)) using (var pen = new SolidBrush(Color.Blue)) { graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340)); @@ -78,13 +77,12 @@ namespace Greenshot.Tests graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340)); } bitmapNew.Span.Fill(new Bgr32 { B = 255, G = 255, R = 255, Unused = 0 }); - using (var bitmap = bitmapNew.NativeBitmap) - using (var graphics = Graphics.FromImage(bitmap)) + using (var graphics = Graphics.FromImage(bitmapNew.NativeBitmap)) using (var pen = new SolidBrush(Color.Blue)) { graphics.FillRectangle(pen, new Rectangle(30, 30, 340, 340)); using (var scaledUnmanagedBitmap = bitmapNew.Scale3X()) - using (var scaledBitmap = ScaleX.Scale2X(bitmapOld)) + using (var scaledBitmap = ScaleX.Scale3X(bitmapOld)) { scaledUnmanagedBitmap.NativeBitmap.Save(@"new3x.png", ImageFormat.Png); scaledBitmap.NativeBitmap.Save(@"old3x.png", ImageFormat.Png);