Search Unity

Texture#GetNativeTexturePtr may not return on M1 Mac

Discussion in 'Editor & General Support' started by homuler, Mar 26, 2022.

  1. homuler

    homuler

    Joined:
    May 6, 2020
    Posts:
    2
    When Texture#GetNativeTexturePtr is called repeatedly, the main thread freezes after a while on M1 Mac (Metal). I have never encountered this problem with Intel macs (nor Linux/Windows).

    Here is a sample code I used to test.
    Aside from efficiency, I don't think there's anything that would cause a deadlock, but is there?

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4.  
    5. using Mediapipe.Unity;
    6.  
    7. public class FreezeTest : MonoBehaviour
    8. {
    9.     [SerializeField] RawImage screen;
    10.     [SerializeField] int width;
    11.     [SerializeField] int height;
    12.     [SerializeField] int fps;
    13.  
    14.     WebCamTexture webCamTexture;
    15.     Color32[] pixelData;
    16.  
    17.     IEnumerator Start()
    18.     {
    19.         var webCamDevice = WebCamTexture.devices[0];
    20.         webCamTexture = new WebCamTexture(webCamDevice.name, width, height, fps);
    21.         webCamTexture.Play();
    22.  
    23.         yield return new WaitUntil(() => webCamTexture.width > 16);
    24.  
    25.         var texture = new Texture2D(width, height, TextureFormat.RGBA32, false);
    26.         pixelData = new Color32[width * height];
    27.         screen.texture = texture;
    28.  
    29.         while (true)
    30.         {
    31.           webCamTexture.GetPixels32(pixelData);
    32.           texture.SetPixels32(pixelData);
    33.           texture.Apply();
    34.           Debug.Log(texture.GetNativeTexturePtr()); // At some point, this line will no longer return.
    35.           yield return new WaitForEndOfFrame();
    36.         }
    37.     }
    38.  
    39.     void Destroy()
    40.     {
    41.         webCamTexture.Stop();
    42.     }
    43. }
    The steps to reproduce
    1. Create a new scene
    2. Create an empty object and attach FreezeTest to it
    3. Create a RawImage and set it to FreezeTest#screen
    4. Set the other fields (i.e. width, height, fps) of FreezeTest according to your camera's spec
    5. Play the scene
    6. Wait for a while (sometimes it takes a few seconds to reproduce, but sometimes several minutes)
    Below is a screenshot of the profiler just before UnityEditor freezes.
    Screen Shot 2022-03-26 at 16.03.00.png

    And here is an excerpt of the dtruss's output while UnityEditor freezes.
    There seems to be some sort of deadlock occurring.

    Code (txt):
    1. SYSCALL(args)         = return
    2. __semwait_signal(0x1403, 0x0, 0x1)        = -1 Err#60
    3. __semwait_signal(0x1403, 0x0, 0x1)        = -1 Err#60
    4. __semwait_signal(0x1403, 0x0, 0x1)        = -1 Err#60
    5. kevent_id(0x60000309DB00, 0x2D69B2B80, 0x1)        = 1 0
    6. bsdthread_ctl(0x100, 0x0, 0xE653)        = 0 0
    7. __semwait_signal(0x1403, 0x0, 0x1)        = -1 Err#60
    8. workq_kernreturn(0x100, 0x2D69B2B80, 0x2)        = 0 Err#-2
    9. kevent_id(0x60000309DB00, 0x2D69B2B80, 0x1)        = 1 0
    10. bsdthread_ctl(0x100, 0x0, 0xE657)        = 0 0
    11. kevent_id(0x6000030FF180, 0x2D69B1978, 0x1)        = 0 0
    12. ...
    Environment
    UnityEditor 2021.2.16f1
    macOS Monterey 12.3
    Mac mini (M1, 2020)
    Memory 16GB
     
    chenghaokan likes this.
  2. kassskata

    kassskata

    Joined:
    Sep 24, 2019
    Posts:
    16
    I reproduce the issue in Unity-Technologies/NativeRenderingPlugin.
    I add
    CreateTextureAndPassToPlugin()
    method inside a
    Update
    method.
    I reproduce it with 100% chance with the start of the game in the editor. Sometimes need a 5 seconds to freeze. Not freeze in the first updates.
    Code (CSharp):
    1. public void Update()
    2. {
    3.     CreateTextureAndPassToPlugin();
    4. }
    It's important to enable any kind of Anti Aliasing. upload_2022-12-9_12-36-35.png
    Why that assign of new texture pointer in the plugin freezes the game? Do you have workaround or solution?

    Environment:
    MacOS architecture M1 Ventura 13.0.1
    Xcode 14.1 (14B47b)
    Unity3D editors
    - 2021.3.14f1 (Silicon)
    - 2022.2.0b6 (Silicon)(Beta)
    Cannot reproduce it on architecture Intel editor.

    Thank you in advance.
     

    Attached Files:

    KyryloKuzyk likes this.
  3. AndyBlock

    AndyBlock

    Joined:
    Oct 12, 2016
    Posts:
    35
    For what it's worth, you are not alone - I'm seeing the same thing here. Just upgraded to an Apple Silicon laptop (M2 in my case), and a utility that always used to work without problems no long does so. Attaching a debugger I saw it was stuck in the same GetNativeTexturePtr method you mentioned. Did you file a bug report about it?
     
    KyryloKuzyk and kassskata like this.
  4. AndyBlock

    AndyBlock

    Joined:
    Oct 12, 2016
    Posts:
    35
  5. kassskata

    kassskata

    Joined:
    Sep 24, 2019
    Posts:
    16
    Thanks for the link, AndyBlock.
    Voted already. Need more votes.
     
    KyryloKuzyk likes this.
  6. KyryloKuzyk

    KyryloKuzyk

    Joined:
    Nov 4, 2013
    Posts:
    1,145
    Same issue here! Although the 'Anti Antialising' setting doesn't make a difference for me.

    I somewhat worked around the issue by caching the IntPtr returned from Texture2d.GetNativeTexturePtr().

    Texture2D.LoadImage/LoadRawTextureData() modify the underlying native texture pointer, so I had to create a temporary texture first, then copy it to my desired texture with Graphics.CopyTexture(). Graphics.CopyTexture() preserves the original texture pointer, so it can be cached and reused.

    Of course, this workaround has terrible performance, but in my case, it wasn't critical.