public void Schedule(DrawingData gizmos, Camera camera) { if (type != Type.Static) { unsafe { buildJob = CommandBuilder.Build(gizmos, (MeshBuffers *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(temporaryMeshBuffers), camera, splitterJob); } } }
public void Release(DrawingData gizmos) { if (!isValid) { throw new System.InvalidOperationException(); } type = Type.Invalid; splitterJob.Complete(); buildJob.Complete(); PoolMeshes(gizmos); }
void PoolMeshes(DrawingData gizmos) { if (type != Type.CustomMeshes) { for (int i = 0; i < meshes.Count; i++) { gizmos.PoolMesh(meshes[i].mesh); } } meshes.Clear(); }
public void Submit(DrawingData gizmos) { if (state != State.Initialized) { throw new System.InvalidOperationException(); } meta.version = gizmos.version; // Command stream // split to static, dynamic and persistent // render static // render dynamic per camera // render persistent per camera int staticBuffer = gizmos.processedData.Reserve(ProcessedBuilderData.Type.Static, meta); int dynamicBuffer = gizmos.processedData.Reserve(ProcessedBuilderData.Type.Dynamic, meta); int persistentBuffer = gizmos.processedData.Reserve(ProcessedBuilderData.Type.Persistent, meta); unsafe { splitterJob = new CommandBuilder.StreamSplitter { inputBuffers = commandBuffers, staticBuffer = gizmos.processedData.Get(staticBuffer).splitterOutputPtr, dynamicBuffer = gizmos.processedData.Get(dynamicBuffer).splitterOutputPtr, persistentBuffer = gizmos.processedData.Get(persistentBuffer).splitterOutputPtr, }.Schedule(); } gizmos.processedData.Get(staticBuffer).SetSplitterJob(gizmos, splitterJob); gizmos.processedData.Get(dynamicBuffer).SetSplitterJob(gizmos, splitterJob); gizmos.processedData.Get(persistentBuffer).SetSplitterJob(gizmos, splitterJob); if (meshes.Count > 0) { var customMeshes = gizmos.processedData.Get(gizmos.processedData.Reserve(ProcessedBuilderData.Type.CustomMeshes, meta)).meshes; // Copy meshes to render for (int i = 0; i < meshes.Count; i++) { customMeshes.Add(new MeshWithType { mesh = meshes[i], lines = false }); } meshes.Clear(); } // TODO: Allocate 3 output objects and pipe splitter to them // Only meshes valid for all cameras have been submitted. // Meshes that depend on the specific camera will be submitted just before rendering // that camera. Line drawing depends on the exact camera. // In particular when drawing circles different number of segments // are used depending on the distance to the camera. state = State.WaitingForSplitter; }
public void BuildMeshes(DrawingData gizmos) { if ((type == Type.Static && submitted) || type == Type.CustomMeshes) { return; } buildJob.Complete(); unsafe { PoolMeshes(gizmos); CommandBuilder.BuildMesh(gizmos, meshes, (MeshBuffers *)temporaryMeshBuffers.GetUnsafePtr()); } submitted = true; }
public void ReleaseAllWithHash(DrawingData gizmos, Hasher hasher) { if (data == null) { return; } for (int i = 0; i < data.Length; i++) { if (data[i].isValid && data[i].meta.hasher.Hash == hasher.Hash) { Release(gizmos, i); } } }
public void ReleaseDataOlderThan(DrawingData gizmos, int version) { if (data == null) { return; } for (int i = 0; i < data.Length; i++) { if (data[i].isValid && data[i].meta.version < version) { Release(gizmos, i); } } }
public void Dispose(DrawingData gizmos) { if (data == null) { return; } for (int i = 0; i < data.Length; i++) { if (data[i].isValid) { Release(gizmos, i); } data[i].Dispose(); } // Ensures calling Dispose multiple times is a NOOP data = null; }
public void SetSplitterJob(DrawingData gizmos, JobHandle splitterJob) { this.splitterJob = splitterJob; if (type == Type.Static) { unsafe { buildJob = CommandBuilder.Build(gizmos, (MeshBuffers *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(temporaryMeshBuffers), null, splitterJob); } SubmittedJobs++; // ScheduleBatchedJobs is expensive, so only do it once in a while if (SubmittedJobs % 8 == 0) { Profiler.BeginSample("ScheduleJobs"); JobHandle.ScheduleBatchedJobs(); Profiler.EndSample(); } } }
public void SubmitMeshes(DrawingData gizmos, Camera camera, int versionThreshold, bool allowGizmos) { if (data == null) { return; } for (int i = 0; i < data.Length; i++) { if (data[i].isValid && data[i].meta.version >= versionThreshold && (allowGizmos || !data[i].meta.isGizmos)) { data[i].Schedule(gizmos, camera); } } for (int i = 0; i < data.Length; i++) { if (data[i].isValid && data[i].meta.version >= versionThreshold && (allowGizmos || !data[i].meta.isGizmos)) { data[i].BuildMeshes(gizmos); } } }
void OnEnable() { if (_instance == null) { _instance = this; } // Ensure we don't have duplicate managers if (_instance != this) { // We cannot destroy the object while it is being enabled, so we need to delay it a bit #if UNITY_EDITOR // This is only important in the editor to avoid a build-up of old managers. // In an actual game at most 1 (though in practice zero) old managers will be laying around. // It would be nice to use a coroutine for this instead, but unfortunately they do not work for objects marked with HideAndDontSave. EditorApplication.update += DelayedDestroy; #endif return; } actuallyEnabled = true; if (gizmos == null) { gizmos = new DrawingData(); } gizmos.frameRedrawScope = new RedrawScope(gizmos); Draw.builder = gizmos.GetBuiltInBuilder(false); Draw.ingame_builder = gizmos.GetBuiltInBuilder(true); commandBuffer = new CommandBuffer(); commandBuffer.name = "ALINE Gizmos"; // Callback when rendering with the built-in render pipeline Camera.onPostRender += PostRender; // Callback when rendering with a scriptable render pipeline UnityEngine.Rendering.RenderPipelineManager.beginFrameRendering += BeginFrameRendering; UnityEngine.Rendering.RenderPipelineManager.endCameraRendering += EndCameraRendering; #if UNITY_EDITOR EditorApplication.update += OnUpdate; #endif }
void Release(DrawingData gizmos, int i) { data[i].Release(gizmos); freeSlots.Push(i); }
public RedrawScope(DrawingData gizmos) { this.gizmos = gizmos; // Should be enough with 4 billion ids before they wrap around. id = idCounter++; }