Skip to content

Commit

Permalink
Remove unnecessary offset indirections
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio0694 committed Dec 13, 2020
1 parent 9fca028 commit 2e53a44
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,7 @@ public void Invoke(int y)
int kernelSize = this.kernel.Length;

Span<int> rowOffsets = this.map.GetRowOffsetSpan();
Span<int> columnOffsets = this.map.GetColumnOffsetSpan();
ref int sampleRowBase = ref Unsafe.Add(ref MemoryMarshal.GetReference(rowOffsets), (y - this.bounds.Y) * kernelSize);
ref int sampleColumnBase = ref MemoryMarshal.GetReference(columnOffsets);

// The target buffer is zeroed initially and then it accumulates the results
// of each partial convolution, so we don't have to clear it here as well
Expand All @@ -148,9 +146,8 @@ public void Invoke(int y)

for (int x = 0; x < boundsWidth; x++)
{
int sampleX = Unsafe.Add(ref sampleColumnBase, x) - boundsX;
ref Vector4 target = ref Unsafe.Add(ref targetBase, x);
ComplexVector4 sample = Unsafe.Add(ref sourceBase, sampleX);
ComplexVector4 sample = Unsafe.Add(ref sourceBase, x);
ComplexVector4 partial = factor * sample;

target += partial.WeightedSum(this.z, this.w);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,13 @@ private void OnFrameApplyCore(
// This is needed because the bokeh blur operates as TPixel -> complex -> TPixel, so we cannot
// convert back to standard pixels after each separate 1D convolution pass. Like in the gaussian
// blur though, we preallocate and compute the kernel sampling maps before processing each complex
// component, to avoid recomputing the same sampling map once per convolution pass.
using var mapX = new KernelSamplingMap(configuration.MemoryAllocator);
using var mapY = new KernelSamplingMap(configuration.MemoryAllocator);
// component, to avoid recomputing the same sampling map once per convolution pass. Since we are
// doing two 1D convolutions with the same kernel, we can use a single kernel sampling map as if
// we were using a 2D kernel with each dimension being the same as the length of our kernel, and
// use the two sampling offset spans resulting from this same map. This saves some extra work.
using var mapXY = new KernelSamplingMap(configuration.MemoryAllocator);

mapX.BuildSamplingOffsetMap(1, this.kernelSize, sourceRectangle);
mapY.BuildSamplingOffsetMap(this.kernelSize, 1, sourceRectangle);
mapXY.BuildSamplingOffsetMap(this.kernelSize, this.kernelSize, sourceRectangle);

ref Complex64[] baseRef = ref MemoryMarshal.GetReference(this.kernels.AsSpan());
ref Vector4 paramsRef = ref MemoryMarshal.GetReference(this.kernelParameters.AsSpan());
Expand All @@ -146,7 +147,7 @@ private void OnFrameApplyCore(
sourceRectangle,
firstPassBuffer,
source.PixelBuffer,
mapX,
mapXY,
kernel,
configuration);

Expand All @@ -160,7 +161,7 @@ private void OnFrameApplyCore(
sourceRectangle,
processingBuffer,
firstPassBuffer,
mapY,
mapXY,
kernel,
parameters.Z,
parameters.W);
Expand Down Expand Up @@ -209,22 +210,18 @@ public void Invoke(int y, Span<Vector4> span)
int boundsWidth = this.bounds.Width;
int kernelSize = this.kernel.Length;

Span<int> rowOffsets = this.map.GetRowOffsetSpan();
Span<int> columnOffsets = this.map.GetColumnOffsetSpan();
int sampleY = Unsafe.Add(ref MemoryMarshal.GetReference(rowOffsets), y - this.bounds.Y);
ref int sampleColumnBase = ref MemoryMarshal.GetReference(columnOffsets);

// Clear the target buffer for each row run
Span<ComplexVector4> targetBuffer = this.targetValues.GetRowSpan(y);
targetBuffer.Clear();
ref ComplexVector4 targetBase = ref MemoryMarshal.GetReference(targetBuffer);

// Execute the bulk pixel format conversion for the current row
Span<TPixel> sourceRow = this.sourcePixels.GetRowSpan(sampleY).Slice(boundsX, boundsWidth);
Span<TPixel> sourceRow = this.sourcePixels.GetRowSpan(y).Slice(boundsX, boundsWidth);
PixelOperations<TPixel>.Instance.ToVector4(this.configuration, sourceRow, span);

ref Vector4 sourceBase = ref MemoryMarshal.GetReference(span);
ref Complex64 kernelBase = ref this.kernel[0];
ref int sampleColumnBase = ref MemoryMarshal.GetReference(this.map.GetColumnOffsetSpan());

for (int x = 0; x < span.Length; x++)
{
Expand Down

0 comments on commit 2e53a44

Please sign in to comment.