From 82d0ba44cfcad086d9eb37b99c4af7f034905b5f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 15 Dec 2020 18:52:10 +0100 Subject: [PATCH] Switch to shared sampling map for convolution passes --- .../Convolution2PassProcessor{TPixel}.cs | 74 +++++++++---------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs index 3b9130f3b9..c2f3ec59a1 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Convolution2PassProcessor{TPixel}.cs @@ -67,45 +67,41 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution // for source and target bulk pixel conversion. var operationBounds = new Rectangle(interest.X, interest.Y, interest.Width * 2, interest.Height); - using (var mapX = new KernelSamplingMap(this.Configuration.MemoryAllocator)) - { - mapX.BuildSamplingOffsetMap(this.KernelX, interest); - - // Horizontal convolution - var horizontalOperation = new HorizontalConvolutionRowOperation( - interest, - firstPassPixels, - source.PixelBuffer, - mapX, - this.KernelX, - this.Configuration, - this.PreserveAlpha); - - ParallelRowIterator.IterateRows( - this.Configuration, - operationBounds, - in horizontalOperation); - } - - using (var mapY = new KernelSamplingMap(this.Configuration.MemoryAllocator)) - { - mapY.BuildSamplingOffsetMap(this.KernelY, interest); - - // Vertical convolution - var verticalOperation = new VerticalConvolutionRowOperation( - interest, - source.PixelBuffer, - firstPassPixels, - mapY, - this.KernelY, - this.Configuration, - this.PreserveAlpha); - - ParallelRowIterator.IterateRows( - this.Configuration, - operationBounds, - in verticalOperation); - } + // We can create a single sampling map with the size as if we were using the non separated 2D kernel + // the two 1D kernels represent, and reuse it across both convolution steps, like in the bokeh blur. + using var mapXY = new KernelSamplingMap(this.Configuration.MemoryAllocator); + + mapXY.BuildSamplingOffsetMap(this.KernelY.Rows, this.KernelX.Columns, interest); + + // Horizontal convolution + var horizontalOperation = new HorizontalConvolutionRowOperation( + interest, + firstPassPixels, + source.PixelBuffer, + mapXY, + this.KernelX, + this.Configuration, + this.PreserveAlpha); + + ParallelRowIterator.IterateRows( + this.Configuration, + operationBounds, + in horizontalOperation); + + // Vertical convolution + var verticalOperation = new VerticalConvolutionRowOperation( + interest, + source.PixelBuffer, + firstPassPixels, + mapXY, + this.KernelY, + this.Configuration, + this.PreserveAlpha); + + ParallelRowIterator.IterateRows( + this.Configuration, + operationBounds, + in verticalOperation); } ///