Skip to content

Add blittable color types Argb<T> and Rgba<T> to System.Numerics.Vectors#124663

Open
ViveliDuCh wants to merge 8 commits intodotnet:mainfrom
ViveliDuCh:blittable-color-pr
Open

Add blittable color types Argb<T> and Rgba<T> to System.Numerics.Vectors#124663
ViveliDuCh wants to merge 8 commits intodotnet:mainfrom
ViveliDuCh:blittable-color-pr

Conversation

@ViveliDuCh
Copy link
Member

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> and Rgba<T> color types are placed directly in System.Numerics.Vectors as compiled code within the partial facade, keeping the System.Numerics.Colors namespace unchanged.

Original work by @AlexRadch:

  • Argb<T>, Rgba<T> struct implementations with static helper methods
  • System.Drawing.Primitives integration (Color.FromArgb/ToArgbValue)
  • System.ComponentModel.TypeConverter support
  • Test coverage (324 tests)

Addressing review feedback:

  • Move all source/test files from System.Numerics.Colors into System.Numerics.Vectors
  • Configure ContractTypesPartiallyMoved=true so GenFacades forwards only existing Vector/Matrix types to CoreLib while Color types stay compiled in the DLL
  • Add separate ref file (System.Numerics.Colors.cs) with #if !BUILDING_CORELIB_REFERENCE guard
  • Remove 6 external references to the deleted System.Numerics.Colors project (NetCoreAppLibrary.props, netstandard shim, Drawing.Primitives, TypeConverter, crossgen2_comparison.py)
  • Fix csproj conventions (<ProjectReference> over bare <Reference>, remove redundant properties)

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.Color interop APIs (FromArgb(Argb<byte>), ToArgbValue(), and cast operators) and expand test coverage.
  • Update System.Numerics.Vectors ref 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.

Copilot AI review requested due to automatic review settings February 23, 2026 22:37
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 7 comments.

// Changes to this file must follow the https://aka.ms/api-review process.
// ------------------------------------------------------------------------------

#if !BUILDING_CORELIB_REFERENCE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@akoeplinger is this the best way to make this work with the whole corelib reference infra?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Member

@jkotas jkotas Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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".

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated 6 comments.

Copilot AI review requested due to automatic review settings February 25, 2026 00:54
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated 4 comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API Proposal: Add blittable Color to System.Numerics

7 participants