internal Enumerator(ref DenseList <T> list) { Index = -1; Count = list.Count; HasList = list._HasList; if (HasList) { Item1 = Item2 = Item3 = Item4 = default(T); Items = list.Items.GetBuffer(); } else { Item1 = list.Item1; Item2 = list.Item2; Item3 = list.Item3; Item4 = list.Item4; Items = null; } }
public void PrepareMany(ref DenseList <Batch> batches, ref Batch.PrepareContext context) { if (batches.Count < 2) { if (batches.Count == 1) { Prepare(batches[0], ref context); } return; } var task = default(Task); task.Context = context; foreach (var b in batches) { ValidateBatch(b, true); if (b is IBatchContainer container) { container.PrepareChildren(ref context); } task.Batch = b; if (context.Async) { Queue.Enqueue(ref task, false); } else { task.Execute(); } task = new Task(b, ref context); } }
/// <summary> /// Scans over a list of batches and applies batch combiners to reduce the total number of batches sent to the GPU and /// improve batch preparation efficiency. Batches eliminated by combination are replaced with null. /// </summary> /// <param name="batches">The list of batches to perform a combination pass over.</param> /// <returns>The number of batches eliminated.</returns> public static int CombineBatches(ref DenseList <Batch> batches, List <Batch> batchesToRelease) { batches.Sort(BatchTypeSorter); int i = 0, j = i + 1, l = batches.Count, eliminatedCount = 0; Batch a, b; Type aType, bType; var isWritable = false; var _batches = batches.GetBuffer(false); while ((i < l) && (j < l)) { a = _batches[i]; if (a == null) { i += 1; j = i + 1; continue; } aType = a.GetType(); b = _batches[j]; if (b == null) { j += 1; continue; } bType = b.GetType(); if ((aType != bType) || (a.Layer != b.Layer)) { i = j; j = i + 1; } else { bool combined = false; foreach (var combiner in Combiners) { if (combined = combiner.CanCombine(a, b)) { if (!isWritable) { isWritable = true; _batches.Dispose(); _batches = batches.GetBuffer(true); } _batches[i] = combiner.Combine(a, b); _batches[i].Container = a.Container; lock (batchesToRelease) { if ((a != _batches[i]) && (a.ReleaseAfterDraw)) { batchesToRelease.Add(a); } } eliminatedCount += 1; break; } } j += 1; } } _batches.Dispose(); if (false && eliminatedCount > 0) { Console.WriteLine("Eliminated {0:0000} of {1:0000} batch(es)", eliminatedCount, batches.Count); } return(eliminatedCount); }
internal void PrepareMany <T> (DenseList <T> batches) where T : IBatch { Manager.PrepareMany(batches, this); }
public void AddRange( BitmapDrawCall[] items, int firstIndex, int count, Vector2?offset = null, Color?multiplyColor = null, Color?addColor = null, DrawCallSortKey?sortKey = null, Vector2?scale = null, Material material = null, Vector4?userData = null, float?multiplyOpacity = null ) { if (material != null) { throw new ArgumentException("Must be null because this is not a MultimaterialBitmapBatch", nameof(material)); } bool hasScale = (scale ?? Vector2.One) != Vector2.One, hasOffset = offset.HasValue, hasMultiplyColor = multiplyColor.HasValue, hasAddColor = addColor.HasValue, hasSortKey = sortKey.HasValue, hasUserData = userData.HasValue, hasOpacity = multiplyOpacity.HasValue; if ( !hasOffset && !hasMultiplyColor && !hasAddColor && !hasUserData && !hasSortKey && !hasScale && !hasOpacity ) { AddRange(items, firstIndex, count); return; } Vector2 _scale = scale ?? default(Vector2), _offset = offset ?? default(Vector2); Color _multiplyColor = multiplyColor ?? default(Color), _addColor = addColor ?? default(Color); var _sortKey = sortKey ?? default(DrawCallSortKey); var _userData = userData ?? default(Vector4); var _opacity = multiplyOpacity ?? 1.0f; var newCount = _DrawCalls.Count + count; _DrawCalls.EnsureCapacity(newCount); for (int i = 0; i < count; i++) { var item = items[i + firstIndex]; if (!BitmapDrawCall.CheckValid(ref item)) { continue; } if (hasScale) { item.Position.X *= _scale.X; item.Position.Y *= _scale.Y; item.Scale.X *= _scale.X; item.Scale.Y *= _scale.Y; } if (hasOffset) { item.Position.X += _offset.X; item.Position.Y += _offset.Y; } if (hasMultiplyColor) { if (hasOpacity) { item.MultiplyColor = _multiplyColor * _opacity; } else { item.MultiplyColor = _multiplyColor; } } else if (hasOpacity) { item.MultiplyColor *= _opacity; } if (hasAddColor) { item.AddColor = _addColor; } if (hasUserData) { item.UserData = _userData; } if (hasSortKey) { item.SortKey = _sortKey; } DenseList <BitmapDrawCall> .UnsafeAddWithKnownCapacity(ref _DrawCalls, ref item); } }
internal void PrepareMany(ref DenseList <Batch> batches) { Manager.PrepareMany(ref batches, ref this); }
public PrepareContext(PrepareManager manager, bool async) { Manager = manager; Async = async; BatchesToRelease = new DenseList <Batch>(); }