Example #1
0
            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;
                }
            }
Example #2
0
        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);
            }
        }
Example #3
0
        /// <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);
        }
Example #4
0
 internal void PrepareMany <T> (DenseList <T> batches)
     where T : IBatch
 {
     Manager.PrepareMany(batches, this);
 }
Example #5
0
        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);
            }
        }
Example #6
0
 internal void PrepareMany(ref DenseList <Batch> batches)
 {
     Manager.PrepareMany(ref batches, ref this);
 }
Example #7
0
 public PrepareContext(PrepareManager manager, bool async)
 {
     Manager          = manager;
     Async            = async;
     BatchesToRelease = new DenseList <Batch>();
 }