-
-
Notifications
You must be signed in to change notification settings - Fork 853
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
Weird wrong colors in gradients #1044
Comments
added unit test to reproduce the issue at https://github.com/jongleur1983/ImageSharp/tree/jongleur1983/1044-wrongPixelsInPathGradients : |
investigations:
|
I can't spot anything in our code that specifically that would cause thread safety issues, however, |
I'll try, thanks. |
Looks like there are some more relatively easy performance and memory improvements possible while removing Linq. |
@JimBobSquarePants removing LINQ and using arrays/for-loops doesn't solve the issue itself, yet. |
Very odd. I couldn’t see any other potential areas where multi threading would be an issue. Thanks for investigating this btw! |
You're welcome @JimBobSquarePants - as long as it could have been my "fault", at least I wanted to make sure it's not ;) |
Ignore the above commit message, it doesn't relate to this issue. |
@jongleur1983 I had another look at this and I've figured it out. This buffer which is created once when the edges are created during initialization of the applicator
Is updated during every call to
I have a fix locally with the following code. I'm curious on your thought regarding using public Intersection? FindIntersection(PointF start, PointF end, MemoryAllocator allocator)
{
// TODO: Would this ever be too big for stackalloc?
using (IMemoryOwner<PointF> memory = allocator.Allocate<PointF>(this.path.MaxIntersections))
{
Span<PointF> buffer = memory.Memory.Span;
int intersections = this.path.FindIntersections(start, end, buffer);
if (intersections == 0)
{
return null;
}
buffer = buffer.Slice(0, intersections);
Intersection? min = null;
for (int i = 0; i < buffer.Length; i++)
{
PointF point = buffer[i];
var current = new Intersection(point: point, distance: ((Vector2)(point - start)).LengthSquared());
if (min is null || min.Value.Distance > current.Distance)
{
min = current;
}
}
return min;
}
} |
Cool... Trying to construct a worst-case example though it could be a big one: As PointF has 2 floats and thus 8 bytes, that's 128*8=1024 byte - and that's a constructed case I guess not to be a real use case. |
Thanks @jongleur1983 that's really useful! Lets leave it using a pooled buffer for now then just in case. There's a lot of room for improvement performance-wise in the entirety of drawing code so I can revisit the solution when we start tackling that. |
Prerequisites
DEBUG
andRELEASE
modeDescription
This bug has been reported by @Wibble199 in Gitter on Oct, 29th 2019.
The following unit test (adapted from https://pastebin.com/RJQWm0za ) generates gradients with wrong colored pixels. Those pixels are at random(?) positions, not stable across re-running the same code.
Current sample output (two different test runs):
or
The expected result is a smooth gradient between the four colors on the corners instead.
Steps to Reproduce
see code sample above.
While investigating the cause for easier debugging I reduced the maxDegreeOfParallelism to 1 and the issue is gone.
Thus it looks like something going on when applying the brush in parallel.
System Configuration
The text was updated successfully, but these errors were encountered: