using System; using UnityEngine.Rendering; using UnityEngine.Profiling; namespace UnityEngine.Experimental.Rendering { public struct ProfilingSample : IDisposable { readonly CommandBuffer m_Cmd; readonly string m_Name; bool m_Disposed; CustomSampler m_Sampler; public ProfilingSample(CommandBuffer cmd, string name, CustomSampler sampler = null) { m_Cmd = cmd; m_Name = name; m_Disposed = false; cmd.BeginSample(name); m_Sampler = sampler; if (m_Sampler != null) m_Sampler.Begin(); } // Shortcut to string.Format() using only one argument (reduces Gen0 GC pressure) public ProfilingSample(CommandBuffer cmd, string format, object arg) : this(cmd, string.Format(format, arg)) { } // Shortcut to string.Format() with variable amount of arguments - for performance critical // code you should pre-build & cache the marker name instead of using this public ProfilingSample(CommandBuffer cmd, string format, params object[] args) : this(cmd, string.Format(format, args)) { } public void Dispose() { Dispose(true); } // Protected implementation of Dispose pattern. void Dispose(bool disposing) { if (m_Disposed) return; // As this is a struct, it could have been initialized using an empty constructor so we // need to make sure `cmd` isn't null to avoid a crash. Switching to a class would fix // this but will generate garbage on every frame (and this struct is used quite a lot). if (disposing && m_Cmd != null) { m_Cmd.EndSample(m_Name); if (m_Sampler != null) m_Sampler.End(); } m_Disposed = true; } } }