public BitmapRenderBlock(Dictionary <string, Texture> textureDictionary, string texturePath, ChunkPool pool, RenderSettings renderSettings, IGraphicsApi <TImage> graphics, int chunkSize, int chunksPerDimension, ExecutionDataflowBlockOptions options) { int tileSize = chunksPerDimension * chunkSize; graphics.SetPoolDimensions(tileSize, tileSize); int chunkRenderedCounter = 0; ThreadLocal <RendererCombi <TImage> > renderCombi = new ThreadLocal <RendererCombi <TImage> >(() => new RendererCombi <TImage>(textureDictionary, texturePath, renderSettings, graphics)); Block = new TransformBlock <IEnumerable <ChunkAndData>, ImageInfo <TImage> >(chunkAndData => { var b = graphics.GetPooledImage(); { var chunkList = chunkAndData.ToList(); var firstX = chunkList.First().C.X; var firstZ = chunkList.First().C.Z; var chunkRenderer = renderCombi.Value.ChunkRenderer; foreach (var chunk in chunkList) { var x = chunk.C.X % chunksPerDimension; var z = chunk.C.Z % chunksPerDimension; if (x < 0) { x += chunksPerDimension; } if (z < 0) { z += chunksPerDimension; } chunkRenderer.RenderChunk(b, chunk.C, x * chunkSize, z * chunkSize); pool?.Return(chunk.C); } var fx = CoordHelpers.GetGroupedCoordinate(firstX, chunksPerDimension); var fz = CoordHelpers.GetGroupedCoordinate(firstZ, chunksPerDimension); Interlocked.Increment(ref processedCount); Interlocked.Add(ref chunkRenderedCounter, chunkList.Count); if (chunkRenderedCounter >= 32) { var v = chunkRenderedCounter; ChunksRendered?.Invoke(this, new ChunksRenderedEventArgs(v)); Interlocked.Add(ref chunkRenderedCounter, -v); } return(new ImageInfo <TImage>() { Image = b, X = fx, Z = fz, Cd = chunkList.SelectMany(x => x.Cd) }); } }, options); }