private VectorInt3?AllocateTexture(RenderingTexture texture) { if (texture.To.X < texture.From.X || texture.To.Y < texture.From.Y) { throw new ArgumentOutOfRangeException(); // Avoid totally currupted texture allocator state. } for (int i = 0; i < Pages.Length; ++i) { VectorInt2?allocatedPos = Pages[i].Packer.TryAdd(VectorInt2.Max((texture.To - texture.From) + new VectorInt2(2), VectorInt2.One)); if (allocatedPos != null) { VectorInt3 pos = new VectorInt3(allocatedPos.Value.X, allocatedPos.Value.Y, i); if (texture.To.X == texture.From.X || texture.To.Y == texture.From.Y) { UploadTexture(ImageC.CreateNew(1, 1), pos); // Attempt to handle this situation } else { UploadTexture(texture, pos); } AvailableTextures.Add(texture, pos + new VectorInt3(1, 1, 0)); return(pos + new VectorInt3(1, 1, 0)); } } return(null); }
private VectorInt3 UpdateQuickAccess(ref RenderingTexture texture, VectorInt3 result) { if (LastUsedTextureIndex == 0) { QuickAccessTexture1 = new KeyValuePair <RenderingTexture, VectorInt3>(texture, result); LastUsedTextureIndex = 1; } else { QuickAccessTexture0 = new KeyValuePair <RenderingTexture, VectorInt3>(texture, result); LastUsedTextureIndex = 0; } return(result); }
/// <summary> /// RemoveUser must be called after the rendering texture is no longer used. /// </summary> public VectorInt3 Get(RenderingTexture texture) { // Check if it's the last used texture. // This speeds up the common case because oftentimes similar textures are used often if (texture == QuickAccessTexture0.Key) { LastUsedTextureIndex = 0; return(QuickAccessTexture0.Value); } if (texture == QuickAccessTexture1.Key) { LastUsedTextureIndex = 1; return(QuickAccessTexture1.Value); } // Look texture up in dictionary VectorInt3 result; if (AvailableTextures.TryGetValue(texture, out result)) { return(UpdateQuickAccess(ref texture, result)); } // Add texture VectorInt3?result2 = AllocateTexture(texture); if (result2.HasValue) { return(UpdateQuickAccess(ref texture, result2.Value)); } if (!GarbageCollect()) { return(new VectorInt3()); // Garbage collection failed and we have already established that there is not enough space as it is. } VectorInt3?result3 = AllocateTexture(texture); // Garbage collection succeeded, let's try again if (result3.HasValue) { return(UpdateQuickAccess(ref texture, result3.Value)); } return(new VectorInt3()); // Still not enough space but there is nothing we can do about it. }
protected abstract void UploadTexture(RenderingTexture Texture, VectorInt3 pos);
internal Entry(KeyValuePair <RenderingTexture, VectorInt3> availableTexture) { Texture = availableTexture.Key; Pos = availableTexture.Value; }