Actually, though the general rule is that the Unity API is off-limits in separate threads, there are notable exceptions… And the Color class is one of them. It’s also perfectly legal to access the static methods in Mathf, or writing into the console using Debug.Log, even though those are actually members of the UnityEngine namespace.
Study, for example, this wiki post by Eric5h5 which uses the Color class in separate threads while scaling a texture. You can do that just fine because it operates on “off-line” objects, so to speak. The offending part about separate threads and Unity only pertains to things that directly affect the real-time renderstate. That is, instantiating GameObjects, changing the transform of something, replacing a material, etc.
In your case, it looks to me like you’re trying to parallelize the deep-copying of one texture’s colors into another array, right? You can do that concurrently pretty easily by just instantiating a thread per row in the original texture. You already have the algorithm for accessing rows when flattened to a 1D array, and you don’t even need to synchronize the threads’ access to the array, because they won’t be writing to the same area of the array as they handle one row each.
Make a method that takes object as parameter and start threads using ParameterizedThreadStart, passing the y variable as the parameter. In the method, cast the object back to an int, then use that to calculate the row of indices which are the write targets for that particular thread. Then, in the mainthread, loop over the height (the y’s) and start a thread for each. It will look something pretty close to this:
Color[] dest, source;
Texture2D texture;
private void StartThreads()
{
for (int i = 0; i < texture.height; i++)
{
System.Threading.ParameterizedThreadStart pts = new System.Threading.ParameterizedThreadStart(ThreadedColorCopy);
System.Threading.Thread workerForOneRow = new System.Threading.Thread(pts);
workerForOneRow.Start(i);
}
}
private void ThreadedColorCopy(object yVariable)
{
int y = (int)yVariable;
for (int x = 0; x < texture.width; x++)
{
int sourceIndex = (y * texture.width) + x;
dest[sourceIndex].r = source[sourceIndex].r;
dest[sourceIndex].g = source[sourceIndex].g;
dest[sourceIndex].b = source[sourceIndex].b;
}
}
(The above is untested but might work out of the box)
Caveat: It strikes me that one thread per row might be a little too aggressively multithreaded, as it would create 512 separate threads for a 512x512 texture. Instead, it might be an idea to give each thread a region of multiple rows, i.e. one thread handles rows 0-19, thread two handles rows 20-39, etc. You get the idea. It will make the code slightly more complicated, but probably more robust.