Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More Span<T> and ReadOnlySpan<T> #2669

Draft
wants to merge 24 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e0de203
Use spans instead of arrays
mattleibow Sep 18, 2023
3a77f16
Add some tests
mattleibow Sep 18, 2023
7741e78
Convert many arrays to spans, or add span overloads where array overl…
ScrubN Nov 10, 2023
c87b9fa
Remove some unnecessary null checks.
ScrubN Nov 10, 2023
8d4bf7f
Fix duplicate SetRectRadii overloads
ScrubN Nov 6, 2024
8f77fcc
Swap out `new T[0]` for `Array.Empty<T> ()`
ScrubN Nov 10, 2023
8428942
Fix apparent memory leak when drawing vertices
ScrubN Nov 10, 2023
9f6f9ce
Minor memory improvements
ScrubN Nov 10, 2023
a70e287
Fix typo
ScrubN Nov 13, 2023
cc3fe2f
Add ReadOnlySpan<char> overloads to SKShaper.Shape and convert DrawSh…
ScrubN Nov 14, 2023
d4985d3
Add tests for SKShaper.Shape with ReadOnlySpan<char>
ScrubN Nov 14, 2023
47926c8
Minor adjustments
ScrubN Nov 14, 2023
535d4e3
Add some span-array overload comparison tests
ScrubN Nov 14, 2023
175fa00
Convert LINQ to code
ScrubN Nov 7, 2024
2b32428
Restore some array overloads & reduce duplicate code between span and…
ScrubN Nov 7, 2024
53d4f74
Restore more array overloads & add some missing span overloads
ScrubN Nov 7, 2024
8bb55f1
Fix method order to preserve blame
ScrubN Nov 7, 2024
1ae486a
Almost done restoring array methods
ScrubN Nov 7, 2024
f1336f0
Fix recursive method
ScrubN Nov 7, 2024
34b0dd6
Fix build
ScrubN Nov 7, 2024
3d355e3
Revert changes to SKStream
ScrubN Nov 7, 2024
590f43d
Restore even more array/string overloads
ScrubN Nov 7, 2024
27bd94d
Add missing DrawText* span overloads
ScrubN Nov 7, 2024
47479bf
Cleanup
ScrubN Nov 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion binding/SkiaSharp.Resources/ResourceProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ public FileResourceProvider (string baseDirectory, bool preDecode = false)

private static IntPtr Create (string baseDirectory, bool preDecode)
{
using var baseDir = new SKString(baseDirectory ?? throw new ArgumentNullException (nameof (baseDirectory)));
if (baseDirectory == null)
throw new ArgumentNullException (nameof (baseDirectory));

using var baseDir = new SKString (baseDirectory.AsSpan ());
return ResourcesApi.skresources_file_resource_provider_make (baseDir.Handle, preDecode);
}
}
Expand Down
113 changes: 97 additions & 16 deletions binding/SkiaSharp/SKCanvas.cs

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions binding/SkiaSharp/SKCodec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ public SKCodecResult GetPixels (SKImageInfo info, out byte[] pixels)
}

public SKCodecResult GetPixels (SKImageInfo info, byte[] pixels)
{
if (pixels == null)
throw new ArgumentNullException (nameof (pixels));

return GetPixels (info, pixels.AsSpan ());
}

public SKCodecResult GetPixels (SKImageInfo info, Span<byte> pixels)
{
if (pixels == null)
throw new ArgumentNullException (nameof (pixels));
Expand Down
30 changes: 6 additions & 24 deletions binding/SkiaSharp/SKColorFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,8 @@ public static SKColorFilter CreateCompose(SKColorFilter outer, SKColorFilter inn
return GetObject (SkiaApi.sk_colorfilter_new_compose(outer.Handle, inner.Handle));
}

public static SKColorFilter CreateColorMatrix(float[] matrix)
{
if (matrix == null)
throw new ArgumentNullException(nameof(matrix));
return CreateColorMatrix(matrix.AsSpan());
}
public static SKColorFilter CreateColorMatrix (float[] matrix) =>
CreateColorMatrix (matrix.AsSpan ());

public static SKColorFilter CreateColorMatrix(ReadOnlySpan<float> matrix)
{
Expand All @@ -57,12 +53,8 @@ public static SKColorFilter CreateLumaColor()
return GetObject (SkiaApi.sk_colorfilter_new_luma_color());
}

public static SKColorFilter CreateTable(byte[] table)
{
if (table == null)
throw new ArgumentNullException(nameof(table));
return CreateTable(table.AsSpan());
}
public static SKColorFilter CreateTable (byte[] table) =>
CreateTable (table.AsSpan ());

public static SKColorFilter CreateTable(ReadOnlySpan<byte> table)
{
Expand All @@ -73,18 +65,8 @@ public static SKColorFilter CreateTable(ReadOnlySpan<byte> table)
}
}

public static SKColorFilter CreateTable(byte[] tableA, byte[] tableR, byte[] tableG, byte[] tableB)
{
if (tableA == null)
throw new ArgumentNullException(nameof(tableA));
if (tableR == null)
throw new ArgumentNullException(nameof(tableR));
if (tableG == null)
throw new ArgumentNullException(nameof(tableG));
if (tableB == null)
throw new ArgumentNullException(nameof(tableB));
return CreateTable(tableA.AsSpan(), tableR.AsSpan(), tableG.AsSpan(), tableB.AsSpan());
}
public static SKColorFilter CreateTable(byte[] tableA, byte[] tableR, byte[] tableG, byte[] tableB) =>
CreateTable(tableA.AsSpan(), tableR.AsSpan(), tableG.AsSpan(), tableB.AsSpan());

public static SKColorFilter CreateTable(ReadOnlySpan<byte> tableA, ReadOnlySpan<byte> tableR, ReadOnlySpan<byte> tableG, ReadOnlySpan<byte> tableB)
{
Expand Down
5 changes: 4 additions & 1 deletion binding/SkiaSharp/SKColorSpace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ public static bool Equal (SKColorSpace left, SKColorSpace right)
public static SKColorSpace CreateIcc (IntPtr input, long length) =>
CreateIcc (SKColorSpaceIccProfile.Create (input, length));

public static SKColorSpace CreateIcc (byte[] input, long length)
public static SKColorSpace CreateIcc (byte[] input, long length) =>
CreateIcc (input.AsSpan (), length);

public static SKColorSpace CreateIcc (ReadOnlySpan<byte> input, long length)
ScrubN marked this conversation as resolved.
Show resolved Hide resolved
{
if (input == null)
throw new ArgumentNullException (nameof (input));
Expand Down
129 changes: 109 additions & 20 deletions binding/SkiaSharp/SKColorSpaceStructs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ public unsafe partial struct SKColorSpacePrimaries
public static readonly SKColorSpacePrimaries Empty;

public SKColorSpacePrimaries (float[] values)
: this (new ReadOnlySpan<float> (values))
{
}

public SKColorSpacePrimaries (ReadOnlySpan<float> values)
{
if (values == null)
throw new ArgumentNullException (nameof (values));
if (values.Length != 8)
throw new ArgumentException ("The values must have exactly 8 items, one for each of [RX, RY, GX, GY, BX, BY, WX, WY].", nameof (values));

Expand Down Expand Up @@ -41,6 +44,36 @@ public SKColorSpacePrimaries (float rx, float ry, float gx, float gy, float bx,
public readonly float[] Values =>
new[] { fRX, fRY, fGX, fGY, fBX, fBY, fWX, fWY };

public readonly void GetValues (Span<float> values)
{
if (values.Length != 8)
throw new ArgumentException ("The values must have exactly 8 items, one for each of [RX, RY, GX, GY, BX, BY, WX, WY].", nameof (values));

values[0] = fRX;
values[1] = fRY;
values[2] = fGX;
values[3] = fGY;
values[4] = fBX;
values[5] = fBY;
values[6] = fWX;
values[7] = fWY;
}

public void SetValues (ReadOnlySpan<float> values)
{
if (values.Length != 8)
throw new ArgumentException ("The values must have exactly 8 items, one for each of [RX, RY, GX, GY, BX, BY, WX, WY].", nameof (values));

fRX = values[0];
fRY = values[1];
fGX = values[2];
fGY = values[3];
fBX = values[4];
fBY = values[5];
fWX = values[6];
fWY = values[7];
}

public readonly bool ToColorSpaceXyz (out SKColorSpaceXyz toXyzD50)
{
fixed (SKColorSpacePrimaries* t = &this)
Expand Down Expand Up @@ -106,9 +139,12 @@ public static SKColorSpaceTransferFn Hlg {
public static readonly SKColorSpaceTransferFn Empty;

public SKColorSpaceTransferFn (float[] values)
: this (new ReadOnlySpan<float> (values))
{
}

public SKColorSpaceTransferFn (ReadOnlySpan<float> values)
{
if (values == null)
throw new ArgumentNullException (nameof (values));
if (values.Length != 7)
throw new ArgumentException ("The values must have exactly 7 items, one for each of [G, A, B, C, D, E, F].", nameof (values));

Expand All @@ -135,6 +171,35 @@ public SKColorSpaceTransferFn (float g, float a, float b, float c, float d, floa
public readonly float[] Values =>
new[] { fG, fA, fB, fC, fD, fE, fF };


public readonly void GetValues (Span<float> values)
{
if (values.Length != 7)
throw new ArgumentException ("The values must have exactly 7 items, one for each of [G, A, B, C, D, E, F].", nameof (values));

values[0] = fG;
values[1] = fA;
values[2] = fB;
values[3] = fC;
values[4] = fD;
values[5] = fE;
values[6] = fF;
}

public void SetValues (ReadOnlySpan<float> values)
{
if (values.Length != 8)
throw new ArgumentException ("The values must have exactly 7 items, one for each of [G, A, B, C, D, E, F].", nameof (values));

fG = values[0];
fA = values[1];
fB = values[2];
fC = values[3];
fD = values[4];
fE = values[5];
fF = values[6];
}

public readonly SKColorSpaceTransferFn Invert ()
{
SKColorSpaceTransferFn inverted;
Expand Down Expand Up @@ -218,11 +283,14 @@ public SKColorSpaceXyz (float value)
}

public SKColorSpaceXyz (float[] values)
: this (new ReadOnlySpan<float> (values))
{
}

public SKColorSpaceXyz (ReadOnlySpan<float> values)
{
if (values == null)
throw new ArgumentNullException (nameof (values));
if (values.Length != 9)
throw new ArgumentException ("The matrix array must have a length of 9.", nameof (values));
throw new ArgumentException ("The values must have a length of 9.", nameof (values));

fM00 = values[0];
fM01 = values[1];
Expand Down Expand Up @@ -261,22 +329,43 @@ public float[] Values {
fM10, fM11, fM12,
fM20, fM21, fM22,
};
set {
if (value.Length != 9)
throw new ArgumentException ("The matrix array must have a length of 9.", nameof (value));
set => SetValues (new ReadOnlySpan<float> (value));
}

fM00 = value[0];
fM01 = value[1];
fM02 = value[2];
public readonly void GetValues (Span<float> values)
{
if (values.Length != 9)
throw new ArgumentException ("The values must have a length of 9.", nameof(values));

fM10 = value[3];
fM11 = value[4];
fM12 = value[5];
values[0] = fM00;
values[1] = fM01;
values[2] = fM02;

fM20 = value[6];
fM21 = value[7];
fM22 = value[8];
}
values[3] = fM10;
values[4] = fM11;
values[5] = fM12;

values[6] = fM20;
values[7] = fM21;
values[8] = fM22;
}

public void SetValues (ReadOnlySpan<float> values)
{
if (values.Length != 9)
throw new ArgumentException ("The values must have a length of 9.", nameof(values));

fM00 = values[0];
fM01 = values[1];
fM02 = values[2];

fM10 = values[3];
fM11 = values[4];
fM12 = values[5];

fM20 = values[6];
fM21 = values[7];
fM22 = values[8];
}

public readonly float this[int x, int y] {
Expand Down
17 changes: 8 additions & 9 deletions binding/SkiaSharp/SKData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,15 @@ public static SKData CreateCopy (IntPtr bytes, ulong length)
}

public static SKData CreateCopy (byte[] bytes) =>
CreateCopy (bytes.AsSpan ());

public static SKData CreateCopy (ReadOnlySpan<byte> bytes) =>
CreateCopy (bytes, (ulong)bytes.Length);

public static SKData CreateCopy (byte[] bytes, ulong length)
{
fixed (byte* b = bytes) {
return GetObject (SkiaApi.sk_data_new_with_copy (b, (IntPtr)length));
}
}
public static SKData CreateCopy (byte[] bytes, ulong length) =>
CreateCopy (bytes.AsSpan (), length);

public static SKData CreateCopy (ReadOnlySpan<byte> bytes)
public static SKData CreateCopy (ReadOnlySpan<byte> bytes, ulong length)
{
fixed (byte* b = bytes) {
return CreateCopy ((IntPtr)b, (ulong)bytes.Length);
Expand Down Expand Up @@ -212,9 +211,9 @@ public static SKData Create (IntPtr address, int length, SKDataReleaseDelegate r
return GetObject (SkiaApi.sk_data_new_with_proc ((void*)address, (IntPtr)length, proxy, (void*)ctx));
}

internal static SKData FromCString (string str)
internal static SKData FromCString (ReadOnlySpan<char> str)
ScrubN marked this conversation as resolved.
Show resolved Hide resolved
{
var bytes = Encoding.ASCII.GetBytes (str ?? string.Empty);
var bytes = Encoding.ASCII.GetBytes (str);
return SKData.CreateCopy (bytes, (ulong)(bytes.Length + 1)); // + 1 for the terminating char
}

Expand Down
12 changes: 6 additions & 6 deletions binding/SkiaSharp/SKDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,12 @@ public static SKDocument CreatePdf (SKWStream stream, SKDocumentPdfMetadata meta
throw new ArgumentNullException (nameof (stream));
}

using var title = SKString.Create (metadata.Title);
using var author = SKString.Create (metadata.Author);
using var subject = SKString.Create (metadata.Subject);
using var keywords = SKString.Create (metadata.Keywords);
using var creator = SKString.Create (metadata.Creator);
using var producer = SKString.Create (metadata.Producer);
using var title = SKString.Create (metadata.Title.AsSpan ());
using var author = SKString.Create (metadata.Author.AsSpan ());
using var subject = SKString.Create (metadata.Subject.AsSpan ());
using var keywords = SKString.Create (metadata.Keywords.AsSpan ());
using var creator = SKString.Create (metadata.Creator.AsSpan ());
using var producer = SKString.Create (metadata.Producer.AsSpan ());

var cmetadata = new SKDocumentPdfMetadataInternal {
fTitle = title?.Handle ?? IntPtr.Zero,
Expand Down
Loading