Add blittable color types Argb<T> and Rgba<T> to System.Numerics.Vectors#124663
Add blittable color types Argb<T> and Rgba<T> to System.Numerics.Vectors#124663ViveliDuCh wants to merge 8 commits intodotnet:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces new blittable color primitives (Argb<T> and Rgba<T>) under System.Numerics.Colors, implemented directly in the System.Numerics.Vectors partial-facade assembly, and wires them into System.Drawing.Color for efficient interop-friendly conversions.
Changes:
- Add
System.Numerics.Colors.Argb<T>/Rgba<T>implementations plus uint endianness helpers. - Add
System.Drawing.Colorinterop APIs (FromArgb(Argb<byte>),ToArgbValue(), and cast operators) and expand test coverage. - Update
System.Numerics.Vectorsref surface and add new unit tests for the new types.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 29 comments.
Show a summary per file
| File | Description |
|---|---|
| src/libraries/System.Numerics.Vectors/src/System.Numerics.Vectors.csproj | Enables partial contract move + compiles new Colors types into the facade assembly. |
| src/libraries/System.Numerics.Vectors/src/System/ThrowHelper.cs | Adds argument-validation helper for span-based color APIs. |
| src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Argb.cs | Adds uint conversion helpers for Argb<byte>. |
| src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Argb.T.cs | Adds generic Argb<T> blittable struct implementation. |
| src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Rgba.cs | Adds uint conversion helpers for Rgba<byte>. |
| src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Rgba.T.cs | Adds generic Rgba<T> blittable struct implementation. |
| src/libraries/System.Numerics.Vectors/src/Resources/Strings.resx | Introduces resource string for span-length validation errors. |
| src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.csproj | Includes the new System.Numerics.Colors ref file in the ref assembly build. |
| src/libraries/System.Numerics.Vectors/ref/System.Numerics.Colors.cs | Declares the public ref surface for System.Numerics.Colors types. |
| src/libraries/System.Numerics.Vectors/tests/System.Numerics.Vectors.Tests.csproj | Adds the new Colors test files to the test project build. |
| src/libraries/System.Numerics.Vectors/tests/TestHelpers.cs | Adds shared test data + numeric helpers for the color tests. |
| src/libraries/System.Numerics.Vectors/tests/Argb.Tests.cs | Adds unit tests for Argb static endianness helpers. |
| src/libraries/System.Numerics.Vectors/tests/Argb.T.Tests.cs | Adds unit tests for Argb<T> struct behaviors. |
| src/libraries/System.Numerics.Vectors/tests/Rgba.Tests.cs | Adds unit tests for Rgba static endianness helpers. |
| src/libraries/System.Numerics.Vectors/tests/Rgba.T.Tests.cs | Adds unit tests for Rgba<T> struct behaviors. |
| src/libraries/System.Drawing.Primitives/src/System/Drawing/Color.cs | Adds conversion APIs between Color and Argb<byte>. |
| src/libraries/System.Drawing.Primitives/ref/System.Drawing.Primitives.cs | Updates the ref surface for new Color APIs. |
| src/libraries/System.Drawing.Primitives/tests/ColorTests.cs | Adds tests for the new Color <-> Argb<byte> APIs. |
| src/libraries/System.Drawing.Primitives/tests/ColorTranslatorTests.cs | Normalizes test namespace naming. |
| src/libraries/System.Drawing.Primitives/tests/PointTests.cs | Normalizes test namespace naming. |
| src/libraries/System.Drawing.Primitives/tests/PointFTests.cs | Normalizes test namespace naming. |
| src/libraries/System.Drawing.Primitives/tests/RectangleTests.cs | Normalizes test namespace naming. |
| src/libraries/System.Drawing.Primitives/tests/RectangleFTests.cs | Normalizes test namespace naming. |
| src/libraries/System.Drawing.Primitives/tests/SizeTests.cs | Normalizes test namespace naming. |
| src/libraries/System.Drawing.Primitives/tests/SizeFTests.cs | Normalizes test namespace naming. |
| src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj | Adds a project reference to System.Numerics.Vectors. |
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Argb.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/ref/System.Numerics.Colors.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Argb.T.cs
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Argb.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Argb.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Rgba.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Rgba.T.cs
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/ref/System.Numerics.Colors.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/ref/System.Numerics.Vectors.csproj
Outdated
Show resolved
Hide resolved
src/libraries/System.Drawing.Primitives/ref/System.Drawing.Primitives.cs
Show resolved
Hide resolved
src/libraries/System.Drawing.Primitives/src/System/Drawing/Color.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Drawing.Primitives/src/System/Drawing/Color.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Argb.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Argb.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Argb.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Argb.cs
Outdated
Show resolved
Hide resolved
d69511e to
936ddab
Compare
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Rgba.T.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Argb.T.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Argb.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Argb.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Argb.T.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Rgba.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Rgba.cs
Outdated
Show resolved
Hide resolved
| // Changes to this file must follow the https://aka.ms/api-review process. | ||
| // ------------------------------------------------------------------------------ | ||
|
|
||
| #if !BUILDING_CORELIB_REFERENCE |
There was a problem hiding this comment.
@akoeplinger is this the best way to make this work with the whole corelib reference infra?
There was a problem hiding this comment.
@ericstj this would be the correct way assuming we want to keep the code in System.Numerics.Vectors.dll. The PR description says this is intentional and I haven't read all the PR history but I don't immediately see why this shouldn't just be moved into Corelib though.
There was a problem hiding this comment.
moved
It doesn't need to be, so it isn't I suppose. Of course it could always be moved later. Thanks for the confirmation.
I didn't see any tricks folks are using to have GenAPI emit the ifdefs, or do a sepreate run to a different file. It looks like we just handle that by auditing the diff out of genapi and undoing any line changes that would remove the ifdefs. I'll add that to my list of features that would be nice to have to make GenAPI unsupervised.
There was a problem hiding this comment.
@ericstj it will emit the ifdef, via https://github.com/dotnet/arcade/blob/0831f9c135e88dd09993903ed5ac1a950285ac96/src/Microsoft.DotNet.GenAPI/GenAPITask.cs#L158-L162
I think I have a slight preference for moving the code into corelib, if only for the fact that we then don't need Strings.resx in the S.N.Vectors assembly (makes it smaller)
There was a problem hiding this comment.
I believe we intentionally don’t want to move code into corelib if not required. It increases cost and other considerations for all apps for something that doesn’t actually require special runtime support.
This has come up for other types as well recently and had input from @jkotas as well
There was a problem hiding this comment.
Notably, most of the types except for Vector<T> don't even need to be in S.P.Corelib anymore (strictly speaking), as they aren't directly JIT accelerated.
The main reason they are is because of the interchange with Vector128<T> and the Vector128.AsVector128(...) and Vector128.AsVector2/3/4(...) extension methods that exist in the System.Runtime.Intrinsics namespace.
There was a problem hiding this comment.
System.Drawing.Primitives would be an overall net negative and be much worse for the longevity of these types, particularly as one of the points is to be separate from System.Drawing and the general GDI+ concepts.
System.Drawing.Primitives was specifically created to carve out System.Drawing portion that does not depend on GDI+.
Users do not have a control over references to the individual libraries in NetCoreApp. I do not see why having these types in System.Drawing.Common affects longevity of these types. It is just our own internal layering consideration. We can always move them down if we find a good reason for it, but moving them up is not really possible.
There was a problem hiding this comment.
The layering consideration is that System.Drawing.Primitives is itself largely "tied" to System.Drawing and is a legacy thing that new code largely shouldn't be using
System.Numerics.Vectors on the other hand is "modern" and new, its the thing people want to use instead and in place of Drawing.Primitives outside of back-compat concerns like what WinForms has.
I'd rather it stay as part of the S.N.Vectors ref assembly accordingly and just move it into corelib if that's better for perf than the partial facade. -- It makes explaining what and where simpler: S.N.Vector == modern, S.D.Primitives == legacy
There was a problem hiding this comment.
The layering consideration is that System.Drawing.Primitives is itself largely "tied" to System.Drawing and is a legacy thing that new code largely shouldn't be using
I disagree. I think System.Drawing.Primitives should be the dumping ground for higher level graphics related stuff like colors that we think deserves to be in the NetCoreApp.
It makes explaining what and where simpler: S.N.Vector == modern, S.D.Primitives == legacy
We do not need to be explaining this. People reference NetCoreApp.
There was a problem hiding this comment.
I disagree. I think System.Drawing.Primitives should be the dumping ground for higher level graphics related stuff like colors that we think deserves to be in the NetCoreApp.
This is already not the case. Most high level graphics stuff, especially non-legacy, comes from S.N.Vectors.
We do not need to be explaining this. People reference NetCoreApp.
Its something that comes up regardless, especially for people working in this space across the range of stacks that graphics touches (which is probably one of the few domains that is largely not exclusive to our runtime today).
I'm not hard set here and it probably doesn't ultimately matter, but I really don't think the System.Drawing.Primitives ref assembly is the right place to put this API. System.Drawing in general is a legacy concept and one of the main purposes of these new types is so that users don't have to deal with the System.Drawing types anymore, because they are "bad".
936ddab to
b1ac543
Compare
b1ac543 to
eb4aa72
Compare
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Argb.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Numerics.Vectors/src/System/Numerics/Colors/Rgba.cs
Outdated
Show resolved
Hide resolved
eb4aa72 to
3825f8a
Compare
Closes #48615
This PR builds on @AlexRadch's original implementation in #106575 and addresses the review feedback to avoid introducing a new assembly. The
Argb<T>andRgba<T>color types are placed directly inSystem.Numerics.Vectorsas compiled code within the partial facade, keeping theSystem.Numerics.Colorsnamespace unchanged.Original work by @AlexRadch:
Argb<T>,Rgba<T>struct implementations with static helper methodsSystem.Drawing.Primitivesintegration (Color.FromArgb/ToArgbValue)System.ComponentModel.TypeConvertersupportAddressing review feedback:
System.Numerics.ColorsintoSystem.Numerics.VectorsContractTypesPartiallyMoved=trueso GenFacades forwards only existing Vector/Matrix types to CoreLib while Color types stay compiled in the DLLSystem.Numerics.Colors.cs) with#if !BUILDING_CORELIB_REFERENCEguardSystem.Numerics.Colorsproject (NetCoreAppLibrary.props, netstandard shim, Drawing.Primitives, TypeConverter, crossgen2_comparison.py)<ProjectReference>over bare<Reference>, remove redundant properties)