Changeset 329 for binary-improvements


Ignore:
Timestamp:
Sep 5, 2018, 11:16:04 PM (9 months ago)
Author:
alloc
Message:

Some small optimizations to the map rendering stuff and added profiling instrumentation

Location:
binary-improvements
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • binary-improvements/7dtd-server-fixes/src/FileCache/MapTileCache.cs

    r326 r329  
    22using System.IO;
    33using UnityEngine;
     4using UnityEngine.Profiling;
    45using Object = UnityEngine.Object;
    56
     
    2627                public void SetZoomCount (int count) {
    2728                        cache = new CurrentZoomFile[count];
     29                        for (int i = 0; i < cache.Length; i++) {
     30                                cache [i] = new CurrentZoomFile ();
     31                        }
    2832                }
    2933
     
    3135                        try {
    3236                                lock (cache) {
    33                                         if (cache [zoomlevel].filename == null || !cache [zoomlevel].filename.Equals (filename)) {
    34                                                 cache [zoomlevel].filename = filename;
     37                                        CurrentZoomFile cacheEntry = cache [zoomlevel];
     38                                       
     39                                        if (cacheEntry.filename == null || !cacheEntry.filename.Equals (filename)) {
     40                                                cacheEntry.filename = filename;
    3541
    3642                                                if (!File.Exists (filename)) {
    37                                                         cache [zoomlevel].data = null;
     43                                                        cacheEntry.pngData = null;
    3844                                                        return null;
    3945                                                }
    4046
    41                                                 cache [zoomlevel].data = File.ReadAllBytes (filename);
     47                                                Profiler.BeginSample ("ReadPng");
     48                                                cacheEntry.pngData = File.ReadAllBytes (filename);
     49                                                Profiler.EndSample ();
    4250                                        }
    4351
    44                                         return cache [zoomlevel].data;
     52                                        return cacheEntry.pngData;
    4553                                }
    4654                        } catch (Exception e) {
    47                                 Log.Out ("Error in MapTileCache.LoadTile: " + e);
     55                                Log.Warning ("Error in MapTileCache.LoadTile: " + e);
    4856                        }
    4957
     
    5159                }
    5260
    53                 public void SaveTile (int zoomlevel, byte[] content) {
     61                public void SaveTile (int zoomlevel, byte[] contentPng) {
    5462                        try {
    5563                                lock (cache) {
    56                                         if (cache [zoomlevel].filename == null) {
     64                                        CurrentZoomFile cacheEntry = cache [zoomlevel];
     65                                       
     66                                        if (string.IsNullOrEmpty (cacheEntry.filename)) {
    5767                                                return;
    5868                                        }
     69                                       
     70                                        cacheEntry.pngData = contentPng;
    5971
    60                                         cache [zoomlevel].data = content;
    61                                         File.WriteAllBytes (cache [zoomlevel].filename, content);
     72                                        Profiler.BeginSample ("WritePng");
     73                                        File.WriteAllBytes (cacheEntry.filename, contentPng);
     74                                        Profiler.EndSample ();
    6275                                }
    6376                        } catch (Exception e) {
    64                                 Log.Out ("Error in MapTileCache.SaveTile: " + e);
     77                                Log.Warning ("Error in MapTileCache.SaveTile: " + e);
    6578                        }
    6679                }
     
    7184                                        foreach (CurrentZoomFile czf in cache) {
    7285                                                if (czf.filename != null && czf.filename.Equals (filename)) {
    73                                                         return czf.data;
     86                                                        return czf.pngData;
    7487                                                }
    7588                                        }
     
    8295                                }
    8396                        } catch (Exception e) {
    84                                 Log.Out ("Error in MapTileCache.GetFileContent: " + e);
     97                                Log.Warning ("Error in MapTileCache.GetFileContent: " + e);
    8598                        }
    8699
     
    88101                }
    89102
    90                 private struct CurrentZoomFile {
     103                private class CurrentZoomFile {
    91104                        public string filename;
    92                         public byte[] data;
     105                        public byte[] pngData;
    93106                }
    94107        }
  • binary-improvements/MapRendering/MapRendering/MapRenderBlockBuffer.cs

    r326 r329  
    22using System.IO;
    33using AllocsFixes.FileCache;
     4using Unity.Collections;
    45using UnityEngine;
     6using UnityEngine.Profiling;
    57
    68namespace AllocsFixes.MapRendering {
    79        public class MapRenderBlockBuffer {
    8                 private readonly Texture2D blockMap = new Texture2D (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE);
     10                private readonly Texture2D blockMap = new Texture2D (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE, TextureFormat.ARGB32, false);
    911                private readonly MapTileCache cache;
    1012                private readonly Color nullColor = new Color (0, 0, 0, 0);
    11                 private readonly Texture2D zoomBuffer = new Texture2D (1, 1);
     13                private readonly Texture2D zoomBuffer = new Texture2D (1, 1, TextureFormat.ARGB32, false);
    1214                private readonly int zoomLevel;
    13                 private string currentBlockMap = string.Empty;
     15                private readonly string folderBase;
     16               
     17                private Vector2i currentBlockMapPos = new Vector2i (Int32.MinValue, Int32.MinValue);
     18                private string currentBlockMapFolder = string.Empty;
     19                private string currentBlockMapFilename = string.Empty;
    1420
    1521                public MapRenderBlockBuffer (int level, MapTileCache cache) {
    1622                        zoomLevel = level;
    1723                        this.cache = cache;
     24                        folderBase = Constants.MAP_DIRECTORY + "/" + zoomLevel + "/";
     25                }
     26
     27                public TextureFormat FormatSelf {
     28                        get { return blockMap.format; }
     29                }
     30
     31                public TextureFormat FormatScaled {
     32                        get { return zoomBuffer.format; }
    1833                }
    1934
    2035                public void ResetBlock () {
    21                         currentBlockMap = string.Empty;
     36                        currentBlockMapFolder = string.Empty;
     37                        currentBlockMapFilename = string.Empty;
     38                        currentBlockMapPos = new Vector2i (Int32.MinValue, Int32.MinValue);
    2239                }
    2340
    2441                public void SaveBlock () {
    2542                        try {
    26                                 if (currentBlockMap.Length > 0) {
    27                                         saveTextureToFile (currentBlockMap);
     43                                if (currentBlockMapFilename.Length > 0) {
     44                                        saveTextureToFile (currentBlockMapFilename);
    2845                                }
    2946                        } catch (Exception e) {
    30                                 Log.Out ("Exception in MapRenderBlockBuffer.SaveBlock(): " + e);
     47                                Log.Warning ("Exception in MapRenderBlockBuffer.SaveBlock(): " + e);
    3148                        }
    3249                }
     
    3552                        bool res = false;
    3653                        lock (blockMap) {
    37                                 string folder = Constants.MAP_DIRECTORY + "/" + zoomLevel + "/" + block.x;
    38                                 string fileName = folder + "/" + block.y + ".png";
    39                                 Directory.CreateDirectory (folder);
    40                                 if (!fileName.Equals (currentBlockMap)) {
    41                                         res = true;
    42                                         SaveBlock ();
    43                                         loadTextureFromFile (fileName);
    44                                 }
    45 
    46                                 currentBlockMap = fileName;
     54                                if (currentBlockMapPos != block) {
     55                                        Profiler.BeginSample ("LoadBlock.Strings");
     56                                        string folder;
     57                                        if (currentBlockMapPos.x != block.x) {
     58                                                folder = folderBase + block.x;
     59
     60                                                Profiler.BeginSample ("LoadBlock.Directory");
     61                                                Directory.CreateDirectory (folder);
     62                                                Profiler.EndSample ();
     63                                        } else {
     64                                                folder = currentBlockMapFolder;
     65                                        }
     66
     67                                        string fileName = folder + "/" + block.y + ".png";
     68                                        Profiler.EndSample ();
     69                                       
     70                                        if (!fileName.Equals (currentBlockMapFilename)) {
     71                                                res = true;
     72                                                SaveBlock ();
     73                                                loadTextureFromFile (fileName);
     74                                        }
     75
     76                                        currentBlockMapFolder = folder;
     77                                        currentBlockMapPos = block;
     78                                        currentBlockMapFilename = fileName;
     79                                }
    4780                        }
    4881
     
    5184
    5285                public void SetPart (Vector2i offset, int partSize, Color32[] pixels) {
    53                         if (offset.x + partSize > blockMap.width || offset.y + partSize > blockMap.height) {
     86                        if (offset.x + partSize > Constants.MAP_BLOCK_SIZE || offset.y + partSize > Constants.MAP_BLOCK_SIZE) {
    5487                                Log.Error (string.Format ("MapBlockBuffer[{0}].SetPart ({1}, {2}, {3}) has blockMap.size ({4}/{5})",
    55                                         zoomLevel, offset, partSize, pixels.Length, blockMap.width, blockMap.height));
     88                                        zoomLevel, offset, partSize, pixels.Length, Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE));
    5689                                return;
    5790                        }
    5891
     92                        Profiler.BeginSample ("SetPart");
    5993                        blockMap.SetPixels32 (offset.x, offset.y, partSize, partSize, pixels);
     94                        Profiler.EndSample ();
    6095                }
    6196
    6297                public Color32[] GetHalfScaled () {
     98                        Profiler.BeginSample ("HalfScaled.ResizeBuffer");
    6399                        zoomBuffer.Resize (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE);
    64                         zoomBuffer.SetPixels32 (blockMap.GetPixels32 ());
    65 
     100                        Profiler.EndSample ();
     101
     102                        Profiler.BeginSample ("HalfScaled.CopyPixels");
     103                        if (blockMap.format == zoomBuffer.format) {
     104                                Profiler.BeginSample ("Native");
     105                                NativeArray<byte> dataSrc = blockMap.GetRawTextureData<byte> ();
     106                                NativeArray<byte> dataZoom = zoomBuffer.GetRawTextureData<byte> ();
     107                                dataSrc.CopyTo (dataZoom);
     108                                Profiler.EndSample ();
     109                        } else {
     110                                Profiler.BeginSample ("GetSetPixels");
     111                                zoomBuffer.SetPixels32 (blockMap.GetPixels32 ());
     112                                Profiler.EndSample ();
     113                        }
     114                        Profiler.EndSample ();
     115
     116                        Profiler.BeginSample ("HalfScaled.Scale");
    66117                        TextureScale.Point (zoomBuffer, Constants.MAP_BLOCK_SIZE / 2, Constants.MAP_BLOCK_SIZE / 2);
    67 
    68                         return zoomBuffer.GetPixels32 ();
     118                        Profiler.EndSample ();
     119
     120                        Profiler.BeginSample ("HalfScaled.Return");
     121                        Color32[] result = zoomBuffer.GetPixels32 ();
     122                        Profiler.EndSample ();
     123
     124                        return result;
     125                }
     126
     127                public void SetPartNative (Vector2i offset, int partSize, NativeArray<int> pixels) {
     128                        if (offset.x + partSize > Constants.MAP_BLOCK_SIZE || offset.y + partSize > Constants.MAP_BLOCK_SIZE) {
     129                                Log.Error (string.Format ("MapBlockBuffer[{0}].SetPart ({1}, {2}, {3}) has blockMap.size ({4}/{5})",
     130                                        zoomLevel, offset, partSize, pixels.Length, Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE));
     131                                return;
     132                        }
     133
     134                        Profiler.BeginSample ("SetPartNative");
     135                        NativeArray<int> destData = blockMap.GetRawTextureData<int> ();
     136                       
     137                        for (int y = 0; y < partSize; y++) {
     138                                int srcLineStartIdx = partSize * y;
     139                                int destLineStartIdx = blockMap.width * (offset.y + y) + offset.x;
     140                                for (int x = 0; x < partSize; x++) {
     141                                        destData [destLineStartIdx + x] = pixels [srcLineStartIdx + x];
     142                                }
     143                        }
     144                        Profiler.EndSample ();
     145                }
     146
     147                public NativeArray<int> GetHalfScaledNative () {
     148                        Profiler.BeginSample ("HalfScaledNative.ResizeBuffer");
     149                        zoomBuffer.Resize (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE);
     150                        Profiler.EndSample ();
     151
     152                        Profiler.BeginSample ("HalfScaledNative.CopyPixels");
     153                        if (blockMap.format == zoomBuffer.format) {
     154                                Profiler.BeginSample ("Native");
     155                                NativeArray<byte> dataSrc = blockMap.GetRawTextureData<byte> ();
     156                                NativeArray<byte> dataZoom = zoomBuffer.GetRawTextureData<byte> ();
     157                                dataSrc.CopyTo (dataZoom);
     158                                Profiler.EndSample ();
     159                        } else {
     160                                Profiler.BeginSample ("GetSetPixels");
     161                                zoomBuffer.SetPixels32 (blockMap.GetPixels32 ());
     162                                Profiler.EndSample ();
     163                        }
     164                        Profiler.EndSample ();
     165
     166                        Profiler.BeginSample ("HalfScaledNative.Scale");
     167                        TextureScale.Point (zoomBuffer, Constants.MAP_BLOCK_SIZE / 2, Constants.MAP_BLOCK_SIZE / 2);
     168                        Profiler.EndSample ();
     169
     170                        return zoomBuffer.GetRawTextureData<int> ();
    69171                }
    70172
    71173                private void loadTextureFromFile (string _fileName) {
     174                        Profiler.BeginSample ("LoadTexture");
     175
     176                        Profiler.BeginSample ("LoadFile");
    72177                        byte[] array = cache.LoadTile (zoomLevel, _fileName);
     178                        Profiler.EndSample ();
     179
     180                        Profiler.BeginSample ("LoadImage");
    73181                        if (array != null && blockMap.LoadImage (array) && blockMap.height == Constants.MAP_BLOCK_SIZE &&
    74182                            blockMap.width == Constants.MAP_BLOCK_SIZE) {
     183                                Profiler.EndSample ();
     184
     185                                Profiler.EndSample ();
    75186                                return;
    76187                        }
     188                        Profiler.EndSample ();
    77189
    78190                        if (array != null) {
     
    81193
    82194                        if (blockMap.height != Constants.MAP_BLOCK_SIZE || blockMap.width != Constants.MAP_BLOCK_SIZE) {
    83                                 blockMap.Resize (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE);
     195                                blockMap.Resize (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE, TextureFormat.ARGB32, false);
    84196                        }
    85197
     
    89201                                }
    90202                        }
     203                        Profiler.EndSample ();
    91204                }
    92205
    93206                private void saveTextureToFile (string _fileName) {
     207                        Profiler.BeginSample ("SaveTexture");
     208
     209                        Profiler.BeginSample ("EncodePNG");
    94210                        byte[] array = blockMap.EncodeToPNG ();
     211                        Profiler.EndSample ();
     212
    95213                        cache.SaveTile (zoomLevel, array);
     214                        Profiler.EndSample ();
    96215                }
    97216        }
  • binary-improvements/MapRendering/MapRendering/MapRendering.cs

    r326 r329  
    99using AllocsFixes.JSON;
    1010using UnityEngine;
     11using UnityEngine.Profiling;
    1112using Object = UnityEngine.Object;
    1213
     
    6768                public static void RenderSingleChunk (Chunk chunk) {
    6869                        if (renderingEnabled) {
     70                                // TODO: Replace with regular thread and a blocking queue / set
    6971                                ThreadPool.UnsafeQueueUserWorkItem (o => {
    7072                                        try {
     
    194196                        }
    195197                }
     198               
     199                private readonly WaitForSeconds coroutineDelay = new WaitForSeconds (0.2f);
    196200
    197201                private IEnumerator renderCoroutine () {
     
    203207
    204208                                        if (Time.time > renderTimeout || dirtyChunks.Count > 200) {
     209                                                Profiler.BeginSample ("RenderDirtyChunks");
    205210                                                RenderDirtyChunks ();
    206                                         }
    207                                 }
    208 
    209                                 yield return new WaitForSeconds (0.2f);
    210                         }
    211                 }
     211                                                Profiler.EndSample ();
     212                                        }
     213                                }
     214
     215                                yield return coroutineDelay;
     216                        }
     217                }
     218
     219                private readonly List<Vector2i> chunksToRender = new List<Vector2i> ();
     220                private readonly List<Vector2i> chunksRendered = new List<Vector2i> ();
    212221
    213222                private void RenderDirtyChunks () {
     
    218227                        }
    219228
    220                         List<Vector2i> keys = new List<Vector2i> (dirtyChunks.Keys);
    221                         List<Vector2i> chunksDone = new List<Vector2i> ();
    222 
    223                         Vector2i chunkPos = keys [0];
    224                         chunksDone.Add (chunkPos);
     229                        Profiler.BeginSample ("RenderDirtyChunks.Prepare");
     230                        chunksToRender.Clear ();
     231                        chunksRendered.Clear ();
     232
     233                        dirtyChunks.CopyKeysTo (chunksToRender);
     234
     235                        Vector2i chunkPos = chunksToRender [0];
     236                        chunksRendered.Add (chunkPos);
    225237
    226238                        //Log.Out ("Start Dirty: " + chunkPos);
     
    231243
    232244                        zoomLevelBuffers [Constants.ZOOMLEVELS - 1].LoadBlock (block);
    233 
     245                        Profiler.EndSample ();
     246
     247                        Profiler.BeginSample ("RenderDirtyChunks.Work");
    234248                        Vector2i v_block, v_blockOffset;
    235                         foreach (Vector2i v in keys) {
     249                        foreach (Vector2i v in chunksToRender) {
    236250                                getBlockNumber (v, out v_block, out v_blockOffset, Constants.MAP_BLOCK_TO_CHUNK_DIV,
    237251                                        Constants.MAP_CHUNK_SIZE);
    238252                                if (v_block.Equals (block)) {
    239253                                        //Log.Out ("Dirty: " + v + " render: true");
    240                                         chunksDone.Add (v);
     254                                        chunksRendered.Add (v);
    241255                                        if (dirtyChunks [v].Length != Constants.MAP_CHUNK_SIZE * Constants.MAP_CHUNK_SIZE) {
    242256                                                Log.Error (string.Format ("Rendering chunk has incorrect data size of {0} instead of {1}",
     
    248262                                }
    249263                        }
    250 
    251                         foreach (Vector2i v in chunksDone) {
     264                        Profiler.EndSample ();
     265
     266                        foreach (Vector2i v in chunksRendered) {
    252267                                dirtyChunks.Remove (v);
    253268                        }
     
    255270                        RenderZoomLevel (block);
    256271
     272                        Profiler.BeginSample ("RenderDirtyChunks.SaveAll");
    257273                        SaveAllBlockMaps ();
     274                        Profiler.EndSample ();
    258275                }
    259276
    260277                private void RenderZoomLevel (Vector2i innerBlock) {
     278                        Profiler.BeginSample ("RenderZoomLevel");
    261279                        int level = Constants.ZOOMLEVELS - 1;
    262280                        while (level > 0) {
     
    265283
    266284                                zoomLevelBuffers [level - 1].LoadBlock (block);
    267                                 zoomLevelBuffers [level - 1].SetPart (blockOffset, Constants.MAP_BLOCK_SIZE / 2, zoomLevelBuffers [level].GetHalfScaled ());
    268 
    269                                 level = level - 1;
     285
     286                                Profiler.BeginSample ("RenderZoomLevel.Transfer");
     287                                if ((zoomLevelBuffers [level].FormatScaled == TextureFormat.ARGB32 ||
     288                                     zoomLevelBuffers [level].FormatScaled == TextureFormat.RGBA32) &&
     289                                    zoomLevelBuffers [level].FormatScaled == zoomLevelBuffers [level - 1].FormatSelf) {
     290                                        zoomLevelBuffers [level - 1].SetPartNative (blockOffset, Constants.MAP_BLOCK_SIZE / 2, zoomLevelBuffers [level].GetHalfScaledNative ());
     291                                } else {
     292                                        zoomLevelBuffers [level - 1].SetPart (blockOffset, Constants.MAP_BLOCK_SIZE / 2, zoomLevelBuffers [level].GetHalfScaled ());
     293                                }
     294                                Profiler.EndSample ();
     295
     296                                level--;
    270297                                innerBlock = block;
    271298                        }
     299                        Profiler.EndSample ();
    272300                }
    273301
     
    374402                }
    375403
    376                 private static Color shortColorToColor (ushort col) {
    377                         return new Color (((col >> 10) & 31) / 31f, ((col >> 5) & 31) / 31f, (col & 31) / 31f, 255);
    378                 }
    379 
    380404                private static Color32 shortColorToColor32 (ushort col) {
    381405                        byte r = (byte) (256 * ((col >> 10) & 31) / 32);
Note: See TracChangeset for help on using the changeset viewer.