source: binary-improvements/MapRendering/MapRendering/MapRenderBlockBuffer.cs@ 332

Last change on this file since 332 was 332, checked in by alloc, 7 years ago

*Latest optimizations

File size: 7.5 KB
Line 
1using System;
2using System.IO;
3using AllocsFixes.FileCache;
4using Unity.Collections;
5using UnityEngine;
6using UnityEngine.Profiling;
7
8namespace AllocsFixes.MapRendering {
9 public class MapRenderBlockBuffer {
10 private readonly Texture2D blockMap = new Texture2D (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE, Constants.DEFAULT_TEX_FORMAT, false);
11 private readonly MapTileCache cache;
12 private readonly NativeArray<int> emptyImageData;
13 private readonly Texture2D zoomBuffer = new Texture2D (Constants.MAP_BLOCK_SIZE / 2, Constants.MAP_BLOCK_SIZE / 2, Constants.DEFAULT_TEX_FORMAT, false);
14 private readonly int zoomLevel;
15 private readonly string folderBase;
16
17 private Vector2i currentBlockMapPos = new Vector2i (Int32.MinValue, Int32.MinValue);
18 private string currentBlockMapFolder = string.Empty;
19
20 public MapRenderBlockBuffer (int level, MapTileCache cache) {
21 zoomLevel = level;
22 this.cache = cache;
23 folderBase = Constants.MAP_DIRECTORY + "/" + zoomLevel + "/";
24
25 {
26 // Initialize empty tile data
27 Color nullColor = new Color (0, 0, 0, 0);
28 for (int x = 0; x < Constants.MAP_BLOCK_SIZE; x++) {
29 for (int y = 0; y < Constants.MAP_BLOCK_SIZE; y++) {
30 blockMap.SetPixel (x, y, nullColor);
31 }
32 }
33
34 NativeArray<int> blockMapData = blockMap.GetRawTextureData<int> ();
35 emptyImageData = new NativeArray<int> (blockMapData.Length, Allocator.Persistent,
36 NativeArrayOptions.UninitializedMemory);
37 blockMapData.CopyTo (emptyImageData);
38 }
39 }
40
41 public TextureFormat FormatSelf {
42 get { return blockMap.format; }
43 }
44
45 public void ResetBlock () {
46 currentBlockMapFolder = string.Empty;
47 currentBlockMapPos = new Vector2i (Int32.MinValue, Int32.MinValue);
48 }
49
50 public void SaveBlock () {
51 Profiler.BeginSample ("SaveBlock");
52 try {
53 saveTextureToFile ();
54 } catch (Exception e) {
55 Log.Warning ("Exception in MapRenderBlockBuffer.SaveBlock(): " + e);
56 }
57 Profiler.EndSample ();
58 }
59
60 public bool LoadBlock (Vector2i block) {
61 Profiler.BeginSample ("LoadBlock");
62 lock (blockMap) {
63 if (currentBlockMapPos != block) {
64 Profiler.BeginSample ("LoadBlock.Strings");
65 string folder;
66 if (currentBlockMapPos.x != block.x) {
67 folder = folderBase + block.x + '/';
68
69 Profiler.BeginSample ("LoadBlock.Directory");
70 Directory.CreateDirectory (folder);
71 Profiler.EndSample ();
72 } else {
73 folder = currentBlockMapFolder;
74 }
75
76 string fileName = folder + block.y + ".png";
77 Profiler.EndSample ();
78
79 SaveBlock ();
80 loadTextureFromFile (fileName);
81
82 currentBlockMapFolder = folder;
83 currentBlockMapPos = block;
84
85 Profiler.EndSample ();
86 return true;
87 }
88 }
89
90 Profiler.EndSample ();
91 return false;
92 }
93
94 public void SetPart (Vector2i offset, int partSize, Color32[] pixels) {
95 if (offset.x + partSize > Constants.MAP_BLOCK_SIZE || offset.y + partSize > Constants.MAP_BLOCK_SIZE) {
96 Log.Error (string.Format ("MapBlockBuffer[{0}].SetPart ({1}, {2}, {3}) has blockMap.size ({4}/{5})",
97 zoomLevel, offset, partSize, pixels.Length, Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE));
98 return;
99 }
100
101 Profiler.BeginSample ("SetPart");
102 blockMap.SetPixels32 (offset.x, offset.y, partSize, partSize, pixels);
103 Profiler.EndSample ();
104 }
105
106 public Color32[] GetHalfScaled () {
107 Profiler.BeginSample ("HalfScaled.ResizeBuffer");
108 zoomBuffer.Resize (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE);
109 Profiler.EndSample ();
110
111 Profiler.BeginSample ("HalfScaled.CopyPixels");
112 if (blockMap.format == zoomBuffer.format) {
113 Profiler.BeginSample ("Native");
114 NativeArray<byte> dataSrc = blockMap.GetRawTextureData<byte> ();
115 NativeArray<byte> dataZoom = zoomBuffer.GetRawTextureData<byte> ();
116 dataSrc.CopyTo (dataZoom);
117 Profiler.EndSample ();
118 } else {
119 Profiler.BeginSample ("GetSetPixels");
120 zoomBuffer.SetPixels32 (blockMap.GetPixels32 ());
121 Profiler.EndSample ();
122 }
123 Profiler.EndSample ();
124
125 Profiler.BeginSample ("HalfScaled.Scale");
126 TextureScale.Point (zoomBuffer, Constants.MAP_BLOCK_SIZE / 2, Constants.MAP_BLOCK_SIZE / 2);
127 Profiler.EndSample ();
128
129 Profiler.BeginSample ("HalfScaled.Return");
130 Color32[] result = zoomBuffer.GetPixels32 ();
131 Profiler.EndSample ();
132
133 return result;
134 }
135
136 public void SetPartNative (Vector2i offset, int partSize, NativeArray<int> pixels) {
137 if (offset.x + partSize > Constants.MAP_BLOCK_SIZE || offset.y + partSize > Constants.MAP_BLOCK_SIZE) {
138 Log.Error (string.Format ("MapBlockBuffer[{0}].SetPart ({1}, {2}, {3}) has blockMap.size ({4}/{5})",
139 zoomLevel, offset, partSize, pixels.Length, Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE));
140 return;
141 }
142
143 Profiler.BeginSample ("SetPartNative");
144 NativeArray<int> destData = blockMap.GetRawTextureData<int> ();
145
146 for (int y = 0; y < partSize; y++) {
147 int srcLineStartIdx = partSize * y;
148 int destLineStartIdx = blockMap.width * (offset.y + y) + offset.x;
149 for (int x = 0; x < partSize; x++) {
150 destData [destLineStartIdx + x] = pixels [srcLineStartIdx + x];
151 }
152 }
153 Profiler.EndSample ();
154 }
155
156 public NativeArray<int> GetHalfScaledNative () {
157 Profiler.BeginSample ("HalfScaledNative.ResizeBuffer");
158 if (zoomBuffer.format != blockMap.format || zoomBuffer.height != Constants.MAP_BLOCK_SIZE / 2 || zoomBuffer.width != Constants.MAP_BLOCK_SIZE / 2) {
159 zoomBuffer.Resize (Constants.MAP_BLOCK_SIZE / 2, Constants.MAP_BLOCK_SIZE / 2, blockMap.format, false);
160 }
161 Profiler.EndSample ();
162
163 Profiler.BeginSample ("HalfScaledNative.Scale");
164 ScaleNative (blockMap, zoomBuffer);
165 Profiler.EndSample ();
166
167 return zoomBuffer.GetRawTextureData<int> ();
168 }
169
170 private static void ScaleNative (Texture2D _sourceTex, Texture2D _targetTex) {
171 NativeArray<int> srcData = _sourceTex.GetRawTextureData<int> ();
172 NativeArray<int> targetData = _targetTex.GetRawTextureData<int> ();
173
174 int oldWidth = _sourceTex.width;
175 int oldHeight = _sourceTex.height;
176 int newWidth = _targetTex.width;
177 int newHeight = _targetTex.height;
178
179 float ratioX = ((float) oldWidth) / newWidth;
180 float ratioY = ((float) oldHeight) / newHeight;
181
182 for (var y = 0; y < newHeight; y++) {
183 var oldLineStart = (int) (ratioY * y) * oldWidth;
184 var newLineStart = y * newWidth;
185 for (var x = 0; x < newWidth; x++) {
186 targetData [newLineStart + x] = srcData [(int) (oldLineStart + ratioX * x)];
187 }
188 }
189 }
190
191 private void loadTextureFromFile (string _fileName) {
192 Profiler.BeginSample ("LoadTexture");
193
194 Profiler.BeginSample ("LoadFile");
195 byte[] array = cache.LoadTile (zoomLevel, _fileName);
196 Profiler.EndSample ();
197
198 Profiler.BeginSample ("LoadImage");
199 if (array != null && blockMap.LoadImage (array) && blockMap.height == Constants.MAP_BLOCK_SIZE &&
200 blockMap.width == Constants.MAP_BLOCK_SIZE) {
201 Profiler.EndSample ();
202
203 Profiler.EndSample ();
204 return;
205 }
206 Profiler.EndSample ();
207
208 if (array != null) {
209 Log.Error ("Map image tile " + _fileName + " has been corrupted, recreating tile");
210 }
211
212 if (blockMap.format != Constants.DEFAULT_TEX_FORMAT || blockMap.height != Constants.MAP_BLOCK_SIZE ||
213 blockMap.width != Constants.MAP_BLOCK_SIZE) {
214 blockMap.Resize (Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE, Constants.DEFAULT_TEX_FORMAT,
215 false);
216 }
217
218 blockMap.LoadRawTextureData (emptyImageData);
219
220 Profiler.EndSample ();
221 }
222
223 private void saveTextureToFile () {
224 Profiler.BeginSample ("EncodePNG");
225 byte[] array = blockMap.EncodeToPNG ();
226 Profiler.EndSample ();
227
228 cache.SaveTile (zoomLevel, array);
229 }
230 }
231}
Note: See TracBrowser for help on using the repository browser.