Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Feedback New allocation free APIs?

Discussion in 'Scripting' started by Alloc, Jun 17, 2019.

  1. Alloc

    Alloc

    Joined:
    Jun 5, 2013
    Posts:
    241
    Hi,

    posted this before (here) but was told to put it in the appropriate section with the feedback prefix so I'll post this again here :)


    Would it be possible to get allocation free APIs for Texture2D.GetPixels(32)?
    Like void GetPixels32 (IList<Color32> target) and void GetPixels (IList<Color> target) etc?
    Also, GetPixels32 is currently missing the override to get just a specific area like GetPixels does ( Color[] GetPixels(int x, int y, int blockWidth, int blockHeight, int miplevel) ) which is quite annoying as you get 4 times the amount of data with the Color array vs a Color32 array. So it would be nice to get that for GetPixels32 too (as well as non-allocating versions for those two overrides) :)

    We're working with reading textures for a bunch of data a lot (maps related mostly) and having these APIs create arrays for up to 16k*16k images is obviously quite annoying ;)

    Regards,
    Chris
     
    Peter77 likes this.
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Not saying those wouldn't be useful...

    But in the meantime, if you're looking to eek out performance gains. Check out Texture2D.GetRawTextureData:
    https://docs.unity3d.com/ScriptReference/Texture2D.GetRawTextureData.html

    This returns a NativeArray (which is a struct so non-allocating) which directly points at the texture in memory so you can directly access the pixels by whichever color type you like (it takes the type as a generic).

    And if you really wanted a non-alloc version, you could just create extension methods that take in lists/collections and fills them by accessing the NativeArray.

    Something like:
    Code (csharp):
    1.  
    2.     public static class TextureUtils
    3.     {
    4.  
    5.         public static int GetPixels<T>(this Texture2D texture, List<T> lst) where T : struct
    6.         {
    7.             var arr = texture.GetRawTextureData<T>();
    8.             for(int i = 0; i < arr.Length; i++)
    9.             {
    10.                 lst.Add(arr[i]);
    11.             }
    12.             return arr.Length;
    13.         }
    14.  
    15.     }
    16.  
    //code is demonstrative and does not account for formatting or mipmaps
     
    Last edited: Jun 17, 2019
  3. Alloc

    Alloc

    Joined:
    Jun 5, 2013
    Posts:
    241
    Hi lordofduct,

    thanks for your reply :)

    We are aware of that API and actually use it for some purposes already, but it won't work here. The issue is that the native memory layout for pixels might be different than the layout of e.g. the Color32 struct. It might not even be a 4 byte per pixel format. The GetPixel* stuff on the other hand is guaranteed to work the same with any readable texture.

    Of course we could write code that first checks the Texture2D's TextureFormat and then handles the data accordingly ... but that's insane, even more so considering Unity has all this ready, they'd just need to take in a target array/List whatever and fill that instead of creating a new array to be filled ;)

    Regards,
    Chris
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Sure... but it's not available.

    I suggested this as a "in the meantime".

    Cause you know... in the meantime you could write such a thing in not much time at all. Rather than wait weeks/months/even years for Unity to add it. Which I would argue is even more insane.
     
  5. DaveL99

    DaveL99

    Joined:
    Jul 5, 2018
    Posts:
    22
    As requested by someone else in your original thread, I'd really really like a way to get the array of materials on a renderer without suffering GC allocs. Even if it was read-only, that'd be an improvement still (as where this is hitting my performance I'm only querying the materials for stuff - not modifying them).
     
  6. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Have you guys tried the performance of it with the new iterative GC?
     
    Joe-Censored and lordofduct like this.
  7. DaveL99

    DaveL99

    Joined:
    Jul 5, 2018
    Posts:
    22
    For me personally, the issue is not really at the point of collection - it's the unnecessary overhead of allocating garbage-collectable memory for something that could ideally just be a temporary stack allocation.

    Although admittedly, while I have my reasons for doing so, I am doing a frankly insane amount of accessing material arrays per-frame. :)
     
    Joe-Censored and hippocoder like this.
  8. Lesnikus5

    Lesnikus5

    Joined:
    May 20, 2016
    Posts:
    131
    Last edited: Feb 24, 2021