Search Unity

Bug ARFoundation: ARCameraBackground CommandBuffer freezes Editor

Discussion in 'AR' started by FrankvHoof, Dec 9, 2020.

  1. FrankvHoof

    FrankvHoof

    Joined:
    Nov 3, 2014
    Posts:
    258
    The CommandBuffer in ARCameraBackground freezes the Editor after a reset (leaving and re-entering playmode).

    The exact method is
    Code (CSharp):
    1. internal static void AddBeforeBackgroundRenderHandler()
    2. {
    3.     commandBuffer.IssuePluginEvent(s_BeforeBackgroundRenderHandlerFuncPtr, 0);
    4. }
    If this method runs, and you leave and try to re-enter play mode, the editor remains stuck at 'Application.Reload' indefinitely.
     
    KyryloKuzyk likes this.
  2. KyryloKuzyk

    KyryloKuzyk

    Joined:
    Nov 4, 2013
    Posts:
    1,142
    I stumbled on this issue too in the development of my plugin. I ended up writing a script that will automatically apply this fix:
    Code (CSharp):
    1. // calling commandBuffer.IssuePluginEvent is crashing Unity Editor 2019.2 and freezing newer versions of Unity
    2. #if !UNITY_EDITOR
    3.     commandBuffer.IssuePluginEvent(s_BeforeBackgroundRenderHandlerFuncPtr, 0);
    4. #endif
     
    smithmw9 likes this.
  3. KyryloKuzyk

    KyryloKuzyk

    Joined:
    Nov 4, 2013
    Posts:
    1,142
    Here is a script to apply the fix automatically. This is not the perfect piece of code, but you can use it as an example :)
    Please place it inside the Editor folder.
    Code (CSharp):
    1. using System;
    2. using System.IO;
    3. using UnityEditor;
    4.  
    5.  
    6. [InitializeOnLoad]
    7. public static class ARCameraBackgroundFixer {
    8.     static ARCameraBackgroundFixer() {
    9.         if (ApplyFixIfNeeded()) {
    10.             AssetDatabase.Refresh();
    11.         }
    12.     }
    13.  
    14.     static bool ApplyFixIfNeeded() {
    15.         var path = "Packages/com.unity.xr.arfoundation/Runtime/AR/ARCameraBackground.cs";
    16.         var script = AssetDatabase.LoadAssetAtPath<MonoScript>(path);
    17.         var text = script.text;
    18.         if (text.Contains("AR_FOUNDATION_EDITOR_REMOTE")) {
    19.             return false;
    20.         }
    21.  
    22.         var index = text.IndexOf("commandBuffer.IssuePluginEvent(", StringComparison.Ordinal);
    23.         var withFix = text.Insert(index, @"// AR_FOUNDATION_EDITOR_REMOTE: calling commandBuffer.IssuePluginEvent is crashing Unity Editor 2019.2 and freezing newer versions of Unity
    24.            " + @"#if !UNITY_EDITOR
    25.            ");
    26.         withFix = withFix.Insert(withFix.IndexOf(";", index, StringComparison.Ordinal) + 1, @"
    27.            " + "#endif");
    28.         File.WriteAllText(AssetDatabase.GetAssetPath(script), withFix);
    29.         return true;
    30.     }
    31. }
    32.  
     
    Last edited: Dec 11, 2020
  4. FrankvHoof

    FrankvHoof

    Joined:
    Nov 3, 2014
    Posts:
    258
    Thanks @KirillKuzyk
    Your plugin is actually what led me to finding the bug.
    My own code would just freeze the editor whenever I did return a texture, and not freeze if I didn't.

    I'm currently creating a similar plugin to yours (but without the 'Remote'-part), and would like to not have to implement the same 'hacky' fixes you did (especially when looking at future compatibility), which is why I made this thread.
     
    KyryloKuzyk likes this.
  5. FrankvHoof

    FrankvHoof

    Joined:
    Nov 3, 2014
    Posts:
    258
    Ok, so after looking at ARCameraBackground.cs a bit more, three things stood out to me:



    This creates a pointer to a function in the native subsystem for the render-thread to call just before rendering.
    As neither mine nor @KirillKuzyk's XRCameraSubsystem exists in unmanaged code when Unity reloads before entering Play Mode the call to the static constructor of ARCameraBackground will attempt to re-marshall the pointer.
    This somehow puts the Editor into an infinite loop or await.

    Adding a #if !UNITY_EDITOR around the [MonoPInvokeCallback(typeof(Action<int>))]-Attribute allows for our managed XRSubsystems to work just fine, keeping the commandbuffer while gaining a call to subsystem.OnBeforeBackgroundRender in the process.
    Example:

    Code (CSharp):
    1. #if !UNITY_EDITOR
    2. [MonoPInvokeCallback(typeof(Action<int>))]
    3. #endif
    4. static void BeforeBackgroundRenderHandler(int eventId)
    5. {
    6.     if (s_CameraSubsystem != null)
    7.         s_CameraSubsystem.OnBeforeBackgroundRender(eventId);
    8. }
    Of course this is still a 'hacky' fix. Any 'natively' supported editor-attached XRDevice (as in native to the Unity team) would not run from within the Editor.
    A better fix would be for ARFoundation to provide built-in defines for managed vs unmanaged subsystems.
    Is there any way to file bugreports specifically to ARFoundation devs?
     
    KyryloKuzyk likes this.
  6. KyryloKuzyk

    KyryloKuzyk

    Joined:
    Nov 4, 2013
    Posts:
    1,142
    FrankvHoof likes this.
  7. baha95

    baha95

    Joined:
    Feb 3, 2019
    Posts:
    3
    Hi i just downloaded the new version of ARF remote and I get

    AR Foundation Remote. ARCameraBackground calls CommandBuffer.IssuePluginEvent which crashes/freezes some versions of Unity.

    Im using Unity 2022.2.1f
    and AR foundation 5.0
    any idea's how to fix this?
     
  8. baha95

    baha95

    Joined:
    Feb 3, 2019
    Posts:
    3
    Neverminded embeding the project fixed issue.
    however when i run it it's just black image on the phone and it's not tracking
     
  9. andyb-unity

    andyb-unity

    Unity Technologies

    Joined:
    Feb 10, 2022
    Posts:
    1,051
    @baha95 are you using URP or the built-in render pipeline? There is a bug in URP that causes a black screen on device that will be fixed in Unity 2022.2.2f1. As a temporary workaround you can set your ARCameraManager's Render Mode to After Opaques.
     
    newguy123 likes this.