Performance warning: There are more than 100 preview scenes.

Why is Unity so absent here?

For anyone else encountering this problem, for me it was a result of using the TextureInspector’s PreviewGUI manually by calling UnityEditor.CreateEditor on a RenderTexture.
This editor’s previews create some preview scenes and doesn’t expose a way to clean them up when you’re launching the previews externally.

Due to the fact that I didn’t want to rewrite this feature from scratch, and because a large amount of functionality is locked behind internal classes which we don’t have access to, I decided to use reflection to acquire the MethodInfo for TextureInspector.OnDisable and called it in the appropriate places in my editor, such as in OnDisable and some other places that made sense in the context.

Obviously this wouldn’t be a supported approach and you shouldn’t leverage the existing TextureInspector in this way I just don’t care about dealing with the related maintenance issues.

1 Like

I’m doing the same thing but sporadically I still get the following error:

Performance warning: There are more than 100 preview scenes. There might be code not releasing the preview scene after creating it.
UnityEditor.Texture3DPreview:OnEnable ()

Any ideas?

Thank you.

I call this wrapper from an ObjectPreview, it works well except for the above message.

using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using JetBrains.Annotations;
using UnityEditor;
using UnityEngine;
using UnityEngine.Assertions;

namespace XYZ.Editors
{
    [PublicAPI]
    public sealed class TexturePreview
    {
        private readonly Dictionary<Object, Texture> Dictionary = new();

        private Editor Editor = null!;

        public void Initialize(Object[] targets, System.Func<Object, Texture> func)
        {
            foreach (var target in targets)
            {
                Dictionary.Add(target, func(target));
            }

            Assert.IsNull(Editor);

            Editor = Editor.CreateEditor(Dictionary.Values.Cast<Object>().ToArray());

            // BUG Performance warning: There are more than 100 preview scenes. There might be code not releasing the preview scene after creating it.
            Editor.GetType().GetMethod("OnEnable", BindingFlags.Instance | BindingFlags.NonPublic)!.Invoke(Editor, null);
        }

        public void Cleanup()
        {
            Assert.IsNotNull(Editor);

            // BUG Performance warning: There are more than 100 preview scenes. There might be code not releasing the preview scene after creating it.
            Editor.GetType().GetMethod("OnDisable", BindingFlags.Instance | BindingFlags.NonPublic)!.Invoke(Editor, null);

            Object.DestroyImmediate(Editor);

            foreach (var pair in Dictionary)
            {
                Object.DestroyImmediate(pair.Value);
            }

            Dictionary.Clear();
        }

        public string GetInfoString()
        {
            return Editor.GetInfoString();
        }

        public GUIContent GetPreviewTitle()
        {
            return Editor.GetPreviewTitle();
        }

        public bool HasPreviewGUI()
        {
            return Editor.HasPreviewGUI();
        }

        public bool MoveNextTarget()
        {
            return Editor.MoveNextTarget();
        }

        public void OnInteractivePreviewGUI(Rect r, GUIStyle background)
        {
            Editor.OnInteractivePreviewGUI(r, background);
        }

        public void OnPreviewSettings()
        {
            Editor.OnPreviewSettings();
        }

        public Texture2D RenderStaticPreview(string assetPath, Object[] subAssets, int width, int height)
        {
            return Editor.RenderStaticPreview(assetPath, subAssets, width, height);
        }

        public void ResetTarget()
        {
            Editor.ResetTarget();
        }
    }
}

I’d suggest not doing it to be honest. I had thought I resolved the problem but ended up recreating it when using this.
I opted to make a custom UIToolkit control which has the functionality I need (selecting rendering R,G,B, and A channels)
The important part was just to call these two EditorGUI methods to draw the texture using a ColorWriteMask to pick which to call.

if (previewMask == ColorWriteMask.Alpha)
  EditorGUI.DrawTextureAlpha(contentSize, image, ScaleMode.ScaleToFit);
else
{
  if (previewMask == 0) previewMask = ColorWriteMask.All;
  EditorGUI.DrawPreviewTexture(contentSize, image, null, ScaleMode.ScaleToFit, 0, -1, previewMask);
}
1 Like

I guess you’re right… Tried to track the error down, it comes from Texture3D preview internally and well, there really isn’t much that one can do.

I didn’t know that preview settings can be done using UI elements, have to look onto this!

Thank you.

1 Like

I also encountered this problem, in Unity 2021.3.27. I seem to be due to MeshPreview.

1 Like

Encountered the same issue, caused by a script that added padding to pixels of the blue channel of some Texture2D.
Unity 2022.2.1f1

This is an old thread, but this issue occurred this morning when I imported a large (< 10K items) asset package that creates this error every time I install it. This editor log may help (this entry is repeated many times.It may have to do with the TextureImporter not releasing the Previews? Just a guess based on the below.

Note: asset is Super_Retro_Collection from the asset store.

2024-02-02T16:47:57.752Z|0x630c|Performance warning: There are more than 100 preview scenes. There might be code not releasing the preview scene after creating it.
UnityEngine.Debug:ExtractStackTraceNoAlloc (byte*,int,string)
UnityEngine.StackTraceUtility:ExtractStackTrace ()

UnityEditor.SceneManagement.EditorSceneManager:NewPreviewScene (bool,UnityEditor.SceneManagement.PreviewSceneFlags)
UnityEditor.SceneManagement.EditorSceneManager:NewPreviewScene ()

UnityEditor.PreviewScene:.ctor (string)
UnityEditor.PreviewRenderUtility:.ctor ()
UnityEditor.GameObjectInspector/PreviewData:.ctor (UnityEngine.Object,bool)
UnityEditor.GameObjectInspector:GetPreviewData (bool)
UnityEditor.GameObjectInspector:OnPreviewGUI (UnityEngine.Rect,UnityEngine.GUIStyle)
UnityEditor.Editor:OnInteractivePreviewGUI (UnityEngine.Rect,UnityEngine.GUIStyle)
UnityEditor.ObjectPreview:smile:rawPreview (UnityEditor.IPreviewable,UnityEngine.Rect,UnityEngine.Object[ ])
UnityEditor.AssetImporters.AssetImporterEditor:smile:rawPreview (UnityEngine.Rect)
UnityEditor.PropertyEditor:smile:rawPreview (UnityEditor.IPreviewable)
UnityEditor.PropertyEditor:smile:rawPreviewAndLabels ()
UnityEngine.UIElements.IMGUIContainer:smile:oOnGUI (UnityEngine.Event,UnityEngine.Matrix4x4,UnityEngine.Rect,bool,UnityEngine.Rect,System.Action,bool)
UnityEngine.UIElements.IMGUIContainer:HandleIMGUIEvent (UnityEngine.Event,UnityEngine.Matrix4x4,UnityEngine.Rect,System.Action,bool)
UnityEngine.UIElements.IMGUIContainer:smile:oIMGUIRepaint ()
UnityEngine.UIElements.UIR.RenderChainCommand:ExecuteNonDrawMesh (UnityEngine.UIElements.UIR.DrawParams,single,System.Exception&)
UnityEngine.UIElements.UIR.UIRenderDevice:EvaluateChain (UnityEngine.UIElements.UIR.RenderChainCommand,UnityEngine.Material,UnityEngine.Material,UnityEngine.Texture,UnityEngine.Texture,single,System.Exception&)
UnityEngine.UIElements.UIR.RenderChain:Render ()
UnityEngine.UIElements.UIRRepaintUpdater:Update ()
UnityEngine.UIElements.VisualTreeUpdater:UpdateVisualTreePhase (UnityEngine.UIElements.VisualTreeUpdatePhase)
UnityEngine.UIElements.Panel:UpdateForRepaint ()
UnityEngine.UIElements.Panel:Repaint (UnityEngine.Event)
UnityEngine.UIElements.UIElementsUtility:smile:oDispatch (UnityEngine.UIElements.BaseVisualElementPanel)
UnityEngine.UIElements.UIElementsUtility:UnityEngine.UIElements.IUIElementsUtility.ProcessEvent (int,intptr,bool&)
UnityEngine.UIElements.UIEventRegistration:ProcessEvent (int,intptr)
UnityEngine.UIElements.UIEventRegistration/<>c:<.cctor>b__1_2 (int,intptr)
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)

[C:\build\output\unity\unity\Editor\Src\SceneManager\EditorSceneManager.cpp line 686]

There’s also this. The GridPaintPaletteClipboard is the UIElement part of the Tile Palette which displays the palette prefab’s Tilemap. This message occurs every time I do a scripting reload. Again, I have third-party palettes, two of which are about 7K tiles each. This doesn’t occur when these two huge tilesets aren’t present in the Project.

Perhaps it’d be better for the PaletteClipboard to do this in a more lazy fashion? IDK.

Unity 2022.2.3

It appears to be harmless but no one likes spurious error/warning messages :slight_smile:

[./Library/PackageCache/com.unity.2d.tilemap@1.0.0/Editor/GridPaintPaletteClipboard.cs line 379]

2024-02-02T17:21:40.282Z|0x630c|Performance warning: There are more than 100 preview scenes. There might be code not releasing the preview scene after creating it.
UnityEngine.Debug:ExtractStackTraceNoAlloc (byte*,int,string)
UnityEngine.StackTraceUtility:ExtractStackTrace ()
UnityEditor.SceneManagement.EditorSceneManager:NewPreviewScene (bool,UnityEditor.SceneManagement.PreviewSceneFlags)
UnityEditor.SceneManagement.EditorSceneManager:NewPreviewScene ()
UnityEditor.PreviewScene:.ctor (string)
UnityEditor.PreviewRenderUtility:.ctor ()
UnityEditor.PreviewRenderUtility:.ctor (bool,bool)
UnityEditor.Tilemaps.GridPaintPaletteClipboard:InitPreviewUtility () (at ./Library/PackageCache/com.unity.2d.tilemap@1.0.0/Editor/GridPaintPaletteClipboard.cs:379)
UnityEditor.Tilemaps.GridPaintPaletteClipboard:OnEnable () (at ./Library/PackageCache/com.unity.2d.tilemap@1.0.0/Editor/GridPaintPaletteClipboard.cs:644)
UnityEngine.ScriptableObject:CreateScriptableObjectInstanceFromType (System.Type,bool)
UnityEngine.ScriptableObject:CreateInstance (System.Type)
UnityEngine.ScriptableObject:CreateInstance<UnityEditor.Tilemaps.GridPaintPaletteClipboard> ()
UnityEditor.Tilemaps.TilePaletteClipboardElement:OnAttachedToPanel (UnityEngine.UIElements.AttachToPanelEvent) (at ./Library/PackageCache/com.unity.2d.tilemap@1.0.0/Editor/UI/TilePaletteClipboardElement.cs:75)
UnityEngine.UIElements.EventCallbackFunctor`1<UnityEngine.UIElements.AttachToPanelEvent>:Invoke (UnityEngine.UIElements.EventBase)
UnityEngine.UIElements.EventCallbackRegistry/DynamicCallbackList:Invoke (UnityEngine.UIElements.EventBase,UnityEngine.UIElements.BaseVisualElementPanel,UnityEngine.UIElements.VisualElement)
UnityEngine.UIElements.EventDispatchUtilities:HandleEvent_BubbleUpCallbacks (UnityEngine.UIElements.EventBase,UnityEngine.UIElements.BaseVisualElementPanel,UnityEngine.UIElements.VisualElement)
UnityEngine.UIElements.EventDispatchUtilities:HandleEventAtTargetAndDefaultPhase (UnityEngine.UIElements.EventBase,UnityEngine.UIElements.BaseVisualElementPanel,UnityEngine.UIElements.VisualElement)
UnityEngine.UIElements.VisualElement:HasChangedPanel (UnityEngine.UIElements.BaseVisualElementPanel)
UnityEngine.UIElements.VisualElement:SetPanel (UnityEngine.UIElements.BaseVisualElementPanel)
UnityEngine.UIElements.VisualElement/Hierarchy:SetParent (UnityEngine.UIElements.VisualElement)
UnityEngine.UIElements.VisualElement/Hierarchy:Insert (int,UnityEngine.UIElements.VisualElement)
UnityEngine.UIElements.VisualElement/Hierarchy:Add (UnityEngine.UIElements.VisualElement)
UnityEngine.UIElements.VisualElement:Add (UnityEngine.UIElements.VisualElement)
UnityEngine.UIElements.VisualElement:Add (UnityEngine.UIElements.VisualElement)
TilePlus.Editor.Painter.TilePlusPainterWindow:CreateGUI () (at Assets/Plugins/TilePlus/Editor/Painter/TilePlusPainterWindow.cs:1820)
TilePlus.TpLib/<DelayedCallback>d__155:MoveNext () (at Assets/Plugins/TilePlus/Runtime/StaticLib/TpLib.cs:2620)
System.Runtime.CompilerServices.AsyncMethodBuilderCore/MoveNextRunner:InvokeMoveNext (object)
System.Threading.ExecutionContext:RunInternal (System.Threading.ExecutionContext,System.Threading.ContextCallback,object,bool)
System.Threading.ExecutionContext:Run (System.Threading.ExecutionContext,System.Threading.ContextCallback,object,bool)
System.Runtime.CompilerServices.AsyncMethodBuilderCore/MoveNextRunner:Run ()
System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation/<>c:<.cctor>b__7_0 (object)
UnityEngine.UnitySynchronizationContext/WorkRequest:Invoke ()
UnityEngine.UnitySynchronizationContext:Exec ()
UnityEngine.UnitySynchronizationContext:ExecuteTasks ()

Facing the same error/warning in 6: 6000.0.25f1:

Performance warning: There are more than 100 preview scenes. There might be code not releasing the preview scene after creating it.
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)

Getting this exact warning spam in Unity 6000.0.29.
It would be super useful if Unity could provide extra details in the warning regarding the editor owner object name of the preview scene or even the preview scene object name. It would help track down the “leak”.

Same here! Unity 6000.0.29.