Browse Source

introducing FakeBuffer<T> workaround

af/merge-core
Anton Firszov 8 years ago
parent
commit
6a2bd3d617
  1. 4
      src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs
  2. 6
      src/ImageSharp/Memory/ArrayPoolMemoryManager.cs
  3. 64
      src/ImageSharp/Memory/FakeBuffer.cs
  4. 16
      src/ImageSharp/Memory/MemoryManager.cs
  5. 4
      src/ImageSharp/Memory/SimpleManagedMemoryManager.cs

4
src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs

@ -99,8 +99,8 @@ namespace SixLabors.ImageSharp.Drawing.Processors
using (BrushApplicator<TPixel> applicator = this.Brush.CreateApplicator(source, rect, this.Options))
{
int scanlineWidth = maxX - minX;
using (var buffer = source.MemoryManager.Allocate<float>(maxIntersections))
using (var scanline = source.MemoryManager.Allocate<float>(scanlineWidth))
using (FakeBuffer<float> buffer = source.MemoryManager.AllocateFake<float>(maxIntersections))
using (FakeBuffer<float> scanline = source.MemoryManager.AllocateFake<float>(scanlineWidth))
{
bool scanlineDirty = true;
for (int y = minY; y < maxY; y++)

6
src/ImageSharp/Memory/ArrayPoolMemoryManager.cs

@ -38,13 +38,13 @@ namespace SixLabors.ImageSharp.Memory
}
/// <inheritdoc />
internal override Buffer<T> Allocate<T>(int itemCount, bool clear)
internal override Buffer<T> Allocate<T>(int length, bool clear)
{
int itemSizeBytes = Unsafe.SizeOf<T>();
int bufferSizeInBytes = itemCount * itemSizeBytes;
int bufferSizeInBytes = length * itemSizeBytes;
byte[] byteBuffer = this.pool.Rent(bufferSizeInBytes);
var buffer = new Buffer<T>(Unsafe.As<T[]>(byteBuffer), itemCount, this);
var buffer = new Buffer<T>(Unsafe.As<T[]>(byteBuffer), length, this);
if (clear)
{
buffer.Clear();

64
src/ImageSharp/Memory/FakeBuffer.cs

@ -0,0 +1,64 @@
using System;
using System.Runtime.CompilerServices;
namespace SixLabors.ImageSharp.Memory
{
/// <summary>
/// Temporal workaround providing a "Buffer" based on a generic array without the 'Unsafe.As()' hackery.
/// </summary>
internal class FakeBuffer<T> : IBuffer<T>
where T : struct
{
public FakeBuffer(T[] array)
{
this.Array = array;
}
public T[] Array { get; }
public Span<T> Span => this.Array;
public int Length => this.Array.Length;
/// <summary>
/// Returns a reference to specified element of the buffer.
/// </summary>
/// <param name="index">The index</param>
/// <returns>The reference to the specified element</returns>
public ref T this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
DebugGuard.MustBeLessThan(index, this.Length, nameof(index));
Span<T> span = this.Span;
return ref span[index];
}
}
/// <summary>
/// Converts <see cref="Buffer{T}"/> to an <see cref="ReadOnlySpan{T}"/>.
/// </summary>
/// <param name="buffer">The <see cref="Buffer{T}"/> to convert.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator ReadOnlySpan<T>(FakeBuffer<T> buffer)
{
return new ReadOnlySpan<T>(buffer.Array, 0, buffer.Length);
}
/// <summary>
/// Converts <see cref="Buffer{T}"/> to an <see cref="Span{T}"/>.
/// </summary>
/// <param name="buffer">The <see cref="Buffer{T}"/> to convert.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator Span<T>(FakeBuffer<T> buffer)
{
return new Span<T>(buffer.Array, 0, buffer.Length);
}
public void Dispose()
{
}
}
}

16
src/ImageSharp/Memory/MemoryManager.cs

@ -12,14 +12,14 @@ namespace SixLabors.ImageSharp.Memory
public abstract class MemoryManager
{
/// <summary>
/// Allocates a <see cref="Buffer{T}"/> of size <paramref name="size"/>, optionally
/// Allocates a <see cref="Buffer{T}"/> of size <paramref name="length"/>, optionally
/// clearing the buffer before it gets returned.
/// </summary>
/// <typeparam name="T">Type of the data stored in the buffer</typeparam>
/// <param name="size">Size of the buffer to allocate</param>
/// <param name="length">Size of the buffer to allocate</param>
/// <param name="clear">True to clear the backing memory of the buffer</param>
/// <returns>A buffer of values of type <typeparamref name="T"/>.</returns>
internal abstract Buffer<T> Allocate<T>(int size, bool clear)
internal abstract Buffer<T> Allocate<T>(int length, bool clear)
where T : struct;
/// <summary>
@ -30,5 +30,15 @@ namespace SixLabors.ImageSharp.Memory
/// <param name="buffer">The buffer to release</param>
internal abstract void Release<T>(Buffer<T> buffer)
where T : struct;
/// <summary>
/// Temporal workaround. A method providing a "Buffer" based on a generic array without the 'Unsafe.As()' hackery.
/// Should be replaced with 'Allocate()' as soon as SixLabors.Shapes has Span-based API-s!
/// </summary>
internal FakeBuffer<T> AllocateFake<T>(int length)
where T : struct
{
return new FakeBuffer<T>(new T[length]);
}
}
}

4
src/ImageSharp/Memory/SimpleManagedMemoryManager.cs

@ -6,9 +6,9 @@
public class SimpleManagedMemoryManager : MemoryManager
{
/// <inheritdoc />
internal override Buffer<T> Allocate<T>(int size, bool clear)
internal override Buffer<T> Allocate<T>(int length, bool clear)
{
return new Buffer<T>(new T[size], size);
return new Buffer<T>(new T[length], length);
}
/// <inheritdoc />

Loading…
Cancel
Save