public void NativeArraySharedValuesIndexCount([Values(1, 3, 1024, 1024 + 1023)] int count)
        {
            PrepareReverseHalf(count);

            //@TODO: @macton. It seems like this should be true? But maybe there is a reason why it shouldn't?
            //Assert.AreEqual(SharedValues.SharedValueCount, sharedCounts.Length);

            var sharedCounts = SharedValues.GetSharedValueIndexCountArray();

            for (int i = 0; i < SharedValues.SharedValueCount; i++)
            {
                if (sharedCounts[i] != 1 && sharedCounts[i] != 2)
                {
                    throw new AssertionException("Must be 1 or 2 but was: " + sharedCounts[i]);
                }
            }
        }
        public void CacheMeshBatchRendererGroup(FrozenRenderSceneTag tag, NativeArray <ArchetypeChunk> chunks,
                                                int chunkCount)
        {
            var RenderMeshType             = GetArchetypeChunkSharedComponentType <RenderMesh>();
            var meshInstanceFlippedTagType = GetArchetypeChunkComponentType <RenderMeshFlippedWindingTag>();
            var editorRenderDataType       = GetArchetypeChunkSharedComponentType <EditorRenderData>();

            Profiler.BeginSample("Sort Shared Renderers");
            var chunkRenderer =
                new NativeArray <int>(chunkCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var sortedChunks = new NativeArraySharedValues <int>(chunkRenderer, Allocator.TempJob);

            var gatherChunkRenderersJob = new GatherChunkRenderers
            {
                Chunks         = chunks,
                RenderMeshType = RenderMeshType,
                ChunkRenderer  = chunkRenderer
            };
            var gatherChunkRenderersJobHandle = gatherChunkRenderersJob.Schedule(chunkCount, 64);
            var sortedChunksJobHandle         = sortedChunks.Schedule(gatherChunkRenderersJobHandle);

            sortedChunksJobHandle.Complete();

            Profiler.EndSample();

            var sharedRenderCount    = sortedChunks.SharedValueCount;
            var sharedRendererCounts = sortedChunks.GetSharedValueIndexCountArray();
            var sortedChunkIndices   = sortedChunks.GetSortedIndices();

            m_InstancedRenderMeshBatchGroup.BeginBatchGroup();

            Profiler.BeginSample("Add New Batches");
            {
                NewMethod(tag, chunks, sharedRendererCounts, sortedChunkIndices, sharedRenderCount, meshInstanceFlippedTagType, editorRenderDataType, RenderMeshType);
                //OldMethod(tag, chunks, sharedRendererCounts, sortedChunkIndices, sharedRenderCount, meshInstanceFlippedTagType, editorRenderDataType, RenderMeshType);
            }
            Profiler.EndSample();
            m_InstancedRenderMeshBatchGroup.EndBatchGroup(tag, chunks, sortedChunkIndices);

            chunkRenderer.Dispose();
            sortedChunks.Dispose();
        }
        public void CacheMeshBatchRendererGroup(FrozenRenderSceneTag tag, NativeArray <ArchetypeChunk> chunks, int chunkCount)
        {
            var RenderMeshType             = GetArchetypeChunkSharedComponentType <RenderMesh>();
            var meshInstanceFlippedTagType = GetArchetypeChunkComponentType <RenderMeshFlippedWindingTag>();
            var editorRenderDataType       = GetArchetypeChunkSharedComponentType <EditorRenderData>();

            Profiler.BeginSample("Sort Shared Renderers");
            var chunkRenderer = new NativeArray <int>(chunkCount, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
            var sortedChunks  = new NativeArraySharedValues <int>(chunkRenderer, Allocator.TempJob);

            var gatherChunkRenderersJob = new GatherChunkRenderers
            {
                Chunks         = chunks,
                RenderMeshType = RenderMeshType,
                ChunkRenderer  = chunkRenderer
            };
            var gatherChunkRenderersJobHandle = gatherChunkRenderersJob.Schedule(chunkCount, 64);
            var sortedChunksJobHandle         = sortedChunks.Schedule(gatherChunkRenderersJobHandle);

            sortedChunksJobHandle.Complete();
            Profiler.EndSample();

            var sharedRenderCount    = sortedChunks.SharedValueCount;
            var sharedRendererCounts = sortedChunks.GetSharedValueIndexCountArray();
            var sortedChunkIndices   = sortedChunks.GetSortedIndices();

            m_InstancedRenderMeshBatchGroup.BeginBatchGroup();
            Profiler.BeginSample("Add New Batches");
            {
                var sortedChunkIndex = 0;
                for (int i = 0; i < sharedRenderCount; i++)
                {
                    var startSortedChunkIndex = sortedChunkIndex;
                    var endSortedChunkIndex   = startSortedChunkIndex + sharedRendererCounts[i];

                    while (sortedChunkIndex < endSortedChunkIndex)
                    {
                        var chunkIndex = sortedChunkIndices[sortedChunkIndex];
                        var chunk      = chunks[chunkIndex];
                        var rendererSharedComponentIndex = chunk.GetSharedComponentIndex(RenderMeshType);

                        var editorRenderDataIndex = chunk.GetSharedComponentIndex(editorRenderDataType);
                        var editorRenderData      = m_DefaultEditorRenderData;
                        if (editorRenderDataIndex != -1)
                        {
                            editorRenderData = EntityManager.GetSharedComponentData <EditorRenderData>(editorRenderDataIndex);
                        }

                        var remainingEntitySlots = 1023;
                        var flippedWinding       = chunk.Has(meshInstanceFlippedTagType);
                        int instanceCount        = chunk.Count;
                        int startSortedIndex     = sortedChunkIndex;
                        int batchChunkCount      = 1;

                        remainingEntitySlots -= chunk.Count;
                        sortedChunkIndex++;

                        while (remainingEntitySlots > 0)
                        {
                            if (sortedChunkIndex >= endSortedChunkIndex)
                            {
                                break;
                            }

                            var nextChunkIndex = sortedChunkIndices[sortedChunkIndex];
                            var nextChunk      = chunks[nextChunkIndex];
                            if (nextChunk.Count > remainingEntitySlots)
                            {
                                break;
                            }

                            var nextFlippedWinding = nextChunk.Has(meshInstanceFlippedTagType);
                            if (nextFlippedWinding != flippedWinding)
                            {
                                break;
                            }

#if UNITY_EDITOR
                            if (editorRenderDataIndex != nextChunk.GetSharedComponentIndex(editorRenderDataType))
                            {
                                break;
                            }
#endif

                            remainingEntitySlots -= nextChunk.Count;
                            instanceCount        += nextChunk.Count;
                            batchChunkCount++;
                            sortedChunkIndex++;
                        }

                        m_InstancedRenderMeshBatchGroup.AddBatch(tag, rendererSharedComponentIndex, instanceCount, chunks, sortedChunkIndices, startSortedIndex, batchChunkCount, flippedWinding, editorRenderData);
                    }
                }
            }
            Profiler.EndSample();
            m_InstancedRenderMeshBatchGroup.EndBatchGroup(tag, chunks, sortedChunkIndices);

            chunkRenderer.Dispose();
            sortedChunks.Dispose();
        }