|
|
|
@ -1,26 +1,33 @@ |
|
|
|
// Copyright (c) Six Labors and contributors.
|
|
|
|
// Licensed under the Apache License, Version 2.0.
|
|
|
|
|
|
|
|
|
|
|
|
using System.Linq; |
|
|
|
using System.Runtime.InteropServices; |
|
|
|
using SixLabors.ImageSharp.Memory; |
|
|
|
using Xunit; |
|
|
|
|
|
|
|
// ReSharper disable InconsistentNaming
|
|
|
|
namespace SixLabors.ImageSharp.Tests.Memory |
|
|
|
{ |
|
|
|
using SixLabors.ImageSharp.Memory; |
|
|
|
|
|
|
|
using Xunit; |
|
|
|
using System; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Tests the <see cref="PixelDataPool{T}"/> class.
|
|
|
|
/// </summary>
|
|
|
|
public class PixelDataPoolTests |
|
|
|
{ |
|
|
|
[Fact] |
|
|
|
public void PixelDataPoolRentsMinimumSize() |
|
|
|
private const int MaxPooledBufferSizeInBytes = PixelDataPool<byte>.MaxPooledBufferSizeInBytes; |
|
|
|
|
|
|
|
readonly object monitor = new object(); |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[InlineData(1)] |
|
|
|
[InlineData(1024)] |
|
|
|
public void PixelDataPoolRentsMinimumSize(int size) |
|
|
|
{ |
|
|
|
Rgba32[] pixels = PixelDataPool<Rgba32>.Rent(1024); |
|
|
|
Rgba32[] pixels = PixelDataPool<Rgba32>.Rent(size); |
|
|
|
|
|
|
|
Assert.True(pixels.Length >= 1024); |
|
|
|
Assert.True(pixels.Length >= size); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
@ -33,23 +40,66 @@ namespace SixLabors.ImageSharp.Tests.Memory |
|
|
|
Assert.True(pixels.Length >= 1024); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Rent 'n' buffers -> return all -> re-rent, verify if there is at least one in common.
|
|
|
|
/// </summary>
|
|
|
|
private bool CheckIsPooled<T>(int n, int count) |
|
|
|
where T : struct |
|
|
|
{ |
|
|
|
lock (this.monitor) |
|
|
|
{ |
|
|
|
T[][] original = new T[n][]; |
|
|
|
|
|
|
|
for (int i = 0; i < n; i++) |
|
|
|
{ |
|
|
|
original[i] = PixelDataPool<T>.Rent(count); |
|
|
|
} |
|
|
|
|
|
|
|
for (int i = 0; i < n; i++) |
|
|
|
{ |
|
|
|
PixelDataPool<T>.Return(original[i]); |
|
|
|
} |
|
|
|
|
|
|
|
T[][] verification = new T[n][]; |
|
|
|
|
|
|
|
for (int i = 0; i < n; i++) |
|
|
|
{ |
|
|
|
verification[i] = PixelDataPool<T>.Rent(count); |
|
|
|
} |
|
|
|
|
|
|
|
return original.Intersect(verification).Any(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[InlineData(32)] |
|
|
|
[InlineData(512)] |
|
|
|
[InlineData(MaxPooledBufferSizeInBytes-1)] |
|
|
|
public void SmallBuffersArePooled(int size) |
|
|
|
{ |
|
|
|
Assert.True(this.CheckIsPooled<byte>(5, size)); |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[InlineData(false)] |
|
|
|
[InlineData(true)] |
|
|
|
public void CalculateMaxArrayLength(bool isRawData) |
|
|
|
[InlineData(128 * 1024 * 1024)] |
|
|
|
[InlineData(MaxPooledBufferSizeInBytes+1)] |
|
|
|
public void LargeBuffersAreNotPooled_OfByte(int size) |
|
|
|
{ |
|
|
|
int max = isRawData ? PixelDataPool<int>.CalculateMaxArrayLength() |
|
|
|
: PixelDataPool<Rgba32>.CalculateMaxArrayLength(); |
|
|
|
Assert.False(this.CheckIsPooled<byte>(2, size)); |
|
|
|
} |
|
|
|
|
|
|
|
Assert.Equal(max > 1024 * 1024, !isRawData); |
|
|
|
[StructLayout(LayoutKind.Explicit, Size = 512)] |
|
|
|
struct TestStruct |
|
|
|
{ |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void RentNonIPixelData() |
|
|
|
public unsafe void LaregeBuffersAreNotPooled_OfBigValueType() |
|
|
|
{ |
|
|
|
byte[] data = PixelDataPool<byte>.Rent(16384); |
|
|
|
const int mb128 = 128 * 1024 * 1024; |
|
|
|
int count = mb128 / sizeof(TestStruct); |
|
|
|
|
|
|
|
Assert.True(data.Length >= 16384); |
|
|
|
Assert.False(this.CheckIsPooled<TestStruct>(2, count)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |