/// <summary> /// Called in order to let the specified <see cref="DrawDevice"/> collect all drawcalls from /// a set of renderers that was previously determined to be potentially visible. /// </summary> /// <param name="drawDevice"></param> /// <param name="visibleRenderers"></param> /// <param name="renderersSortedByType"></param> protected virtual void OnCollectRendererDrawcalls(DrawDevice drawDevice, RawList <ICmpRenderer> visibleRenderers, bool renderersSortedByType) { Type lastRendererType = null; Type rendererType = null; TimeCounter activeProfiler = null; ICmpRenderer[] data = visibleRenderers.Data; for (int i = 0; i < data.Length; i++) { if (i >= visibleRenderers.Count) { break; } // Manage profilers per Component type if (renderersSortedByType) { rendererType = data[i].GetType(); if (rendererType != lastRendererType) { if (activeProfiler != null) { activeProfiler.EndMeasure(); } activeProfiler = Profile.RequestCounter <TimeCounter>(Profile.TimeCollectDrawcalls.FullName + @"\" + rendererType.Name); activeProfiler.BeginMeasure(); lastRendererType = rendererType; } } // Collect Drawcalls from this Component data[i].Draw(drawDevice); } if (activeProfiler != null) { activeProfiler.EndMeasure(); } }
private void UpdateComponents <T>(Action <T> updateAction) where T : class { Profile.TimeUpdateSceneComponents.BeginMeasure(); // Gather a list of updatable Components RawList <Component> updatableComponents = new RawList <Component>(256); RawList <UpdateEntry> updateMap = new RawList <UpdateEntry>(); foreach (var pair in this.componentsByType) { // Skip Component types that aren't updatable anyway Component sampleComponent = pair.Value.FirstOrDefault(); if (!(sampleComponent is T)) { continue; } int oldCount = updatableComponents.Count; // Collect Components updatableComponents.Reserve(updatableComponents.Count + pair.Value.Count); for (int i = 0; i < pair.Value.Count; i++) { updatableComponents.Add(pair.Value[i]); } // Keep in mind how many Components of each type we have in what order if (updatableComponents.Count - oldCount > 0) { updateMap.Add(new UpdateEntry { Type = pair.Key, Count = updatableComponents.Count - oldCount, Profiler = Profile.RequestCounter <TimeCounter>(Profile.TimeUpdateScene.FullName + @"\" + pair.Key.Name) }); } } // Update all Components. They're still sorted by type. { int updateMapIndex = -1; int updateMapBegin = -1; TimeCounter activeProfiler = null; Component[] data = updatableComponents.Data; UpdateEntry[] updateData = updateMap.Data; for (int i = 0; i < data.Length; i++) { if (i >= updatableComponents.Count) { break; } // Manage profilers per Component type if (i == 0 || i - updateMapBegin >= updateData[updateMapIndex].Count) { // Note: // Since we're doing this based on index-count ranges, this needs to be // done before skipping inactive Components, so we don't run out of sync. updateMapIndex++; updateMapBegin = i; if (activeProfiler != null) { activeProfiler.EndMeasure(); } activeProfiler = updateData[updateMapIndex].Profiler; activeProfiler.BeginMeasure(); } // Skip inactive, disposed and detached Components if (!data[i].Active) { continue; } // Invoke the Component's update action updateAction(data[i] as T); } if (activeProfiler != null) { activeProfiler.EndMeasure(); } } Profile.TimeUpdateSceneComponents.EndMeasure(); }
private void CollectDrawcalls() { // If no visibility groups are met, don't bother looking for renderers. // This is important to allow efficient drawcall injection with additional // "dummy" renderpasses. CamViewStates render their overlays by temporarily // adding 3 - 4 of these passes. Iterating over all objects again would be // devastating for performance and at the same time pointless. if ((this.drawDevice.VisibilityMask & VisibilityFlag.AllGroups) == VisibilityFlag.None) { return; } // Query renderers IRendererVisibilityStrategy visibilityStrategy = Scene.Current.VisibilityStrategy; RawList <ICmpRenderer> visibleRenderers; { if (visibilityStrategy == null) { return; } Profile.TimeQueryVisibleRenderers.BeginMeasure(); visibleRenderers = new RawList <ICmpRenderer>(); visibilityStrategy.QueryVisibleRenderers(this.drawDevice, visibleRenderers); if (this.editorRenderFilter.Count > 0) { visibleRenderers.RemoveAll(r => { for (int i = 0; i < this.editorRenderFilter.Count; i++) { if (!this.editorRenderFilter[i](r)) { return(true); } } return(false); }); } Profile.TimeQueryVisibleRenderers.EndMeasure(); } // Collect drawcalls if (this.drawDevice.IsPicking) { this.pickingMap.AddRange(visibleRenderers); foreach (ICmpRenderer r in visibleRenderers) { r.Draw(this.drawDevice); this.drawDevice.PickingIndex++; } } else { bool profilePerType = visibilityStrategy.IsRendererQuerySorted; Profile.TimeCollectDrawcalls.BeginMeasure(); Type lastRendererType = null; Type rendererType = null; TimeCounter activeProfiler = null; ICmpRenderer[] data = visibleRenderers.Data; for (int i = 0; i < data.Length; i++) { if (i >= visibleRenderers.Count) { break; } // Manage profilers per Component type if (profilePerType) { rendererType = data[i].GetType(); if (rendererType != lastRendererType) { if (activeProfiler != null) { activeProfiler.EndMeasure(); } activeProfiler = Profile.RequestCounter <TimeCounter>(Profile.TimeCollectDrawcalls.FullName + @"\" + rendererType.Name); activeProfiler.BeginMeasure(); lastRendererType = rendererType; } } // Collect Drawcalls from this Component data[i].Draw(this.drawDevice); } if (activeProfiler != null) { activeProfiler.EndMeasure(); } Profile.TimeCollectDrawcalls.EndMeasure(); } }
private void UpdateComponents <T>(Action <T> updateAction) where T : class { Profile.TimeUpdateSceneComponents.BeginMeasure(); // Create a sorted list of updatable component types this.updateTypeOrder.Clear(); foreach (var pair in this.componentsByType) { // Skip Component types that aren't updatable anyway Component sampleComponent = pair.Value.Count > 0 ? pair.Value[0] : null; if (!(sampleComponent is T)) { continue; } this.updateTypeOrder.Add(pair.Key.AsType()); } Component.ExecOrder.SortTypes(this.updateTypeOrder, false); // Gather a list of updatable Components this.updatableComponents.Clear(); this.updateMap.Clear(); foreach (Type type in this.updateTypeOrder) { TypeInfo typeInfo = type.GetTypeInfo(); List <Component> components = this.componentsByType[typeInfo]; int oldCount = this.updatableComponents.Count; // Collect Components this.updatableComponents.Reserve(this.updatableComponents.Count + components.Count); for (int i = 0; i < components.Count; i++) { this.updatableComponents.Add(components[i]); } // Keep in mind how many Components of each type we have in what order if (this.updatableComponents.Count - oldCount > 0) { this.updateMap.Add(new UpdateEntry { Type = typeInfo, Count = this.updatableComponents.Count - oldCount, Profiler = Profile.RequestCounter <TimeCounter>(Profile.TimeUpdateScene.FullName + @"\" + typeInfo.Name) }); } } // Update all Components. They're still sorted by type. { int updateMapIndex = -1; int updateMapBegin = -1; TimeCounter activeProfiler = null; Component[] data = this.updatableComponents.Data; UpdateEntry[] updateData = this.updateMap.Data; for (int i = 0; i < data.Length; i++) { if (i >= this.updatableComponents.Count) { break; } // Manage profilers per Component type if (i == 0 || i - updateMapBegin >= updateData[updateMapIndex].Count) { // Note: // Since we're doing this based on index-count ranges, this needs to be // done before skipping inactive Components, so we don't run out of sync. updateMapIndex++; updateMapBegin = i; if (activeProfiler != null) { activeProfiler.EndMeasure(); } activeProfiler = updateData[updateMapIndex].Profiler; activeProfiler.BeginMeasure(); } // Skip inactive, disposed and detached Components if (!data[i].Active) { continue; } // Invoke the Component's update action updateAction(data[i] as T); } if (activeProfiler != null) { activeProfiler.EndMeasure(); } } Profile.TimeUpdateSceneComponents.EndMeasure(); }
private void CollectDrawcalls() { // If no visibility groups are met, don't bother looking for renderers if ((this.drawDevice.VisibilityMask & VisibilityFlag.AllGroups) == VisibilityFlag.None) { return; } // Query renderers IRendererVisibilityStrategy visibilityStrategy = Scene.Current.VisibilityStrategy; RawList <ICmpRenderer> visibleRenderers; { if (visibilityStrategy == null) { return; } Profile.TimeQueryVisibleRenderers.BeginMeasure(); visibleRenderers = new RawList <ICmpRenderer>(); visibilityStrategy.QueryVisibleRenderers(this.drawDevice, visibleRenderers); if (this.editorRenderFilter.Count > 0) { visibleRenderers.RemoveAll(r => { for (int i = 0; i < this.editorRenderFilter.Count; i++) { if (!this.editorRenderFilter[i](r)) { return(true); } } return(false); }); } Profile.TimeQueryVisibleRenderers.EndMeasure(); } // Collect drawcalls if (this.drawDevice.IsPicking) { this.pickingMap.AddRange(visibleRenderers); foreach (ICmpRenderer r in visibleRenderers) { r.Draw(this.drawDevice); this.drawDevice.PickingIndex++; } } else { bool profilePerType = visibilityStrategy.IsRendererQuerySorted; Profile.TimeCollectDrawcalls.BeginMeasure(); Type lastRendererType = null; Type rendererType = null; TimeCounter activeProfiler = null; ICmpRenderer[] data = visibleRenderers.Data; for (int i = 0; i < data.Length; i++) { if (i >= visibleRenderers.Count) { break; } // Manage profilers per Component type if (profilePerType) { rendererType = data[i].GetType(); if (rendererType != lastRendererType) { if (activeProfiler != null) { activeProfiler.EndMeasure(); } activeProfiler = Profile.RequestCounter <TimeCounter>(Profile.TimeCollectDrawcalls.FullName + @"\" + rendererType.Name); activeProfiler.BeginMeasure(); lastRendererType = rendererType; } } // Collect Drawcalls from this Component data[i].Draw(this.drawDevice); } if (activeProfiler != null) { activeProfiler.EndMeasure(); } Profile.TimeCollectDrawcalls.EndMeasure(); } }