/// <summary>Sweeps all marked entries as part of mark-and-sweep garbage collection.</summary> /// <remarks>This method should be called at the end of each frame.</remarks> public void RemoveUnusedEntries() { bool unusedEntriesFound; do { unusedEntriesFound = false; foreach (KeyValuePair <string, TextCacheEntry> dictionaryEntry in entries) { TextCacheEntry entry = dictionaryEntry.Value; if (entry.Unused) { for (int i = 0; i < entry.TexturePoolEntries.Length; ++i) { TexturePoolEntry poolEntry = entry.TexturePoolEntries[i]; poolEntry.StripeAllocated[entry.StripeIndexes[i]] = false; if (!poolEntry.Used) { poolEntry.Texture.Dispose(); texturePool.Remove(poolEntry); } } entries.Remove(dictionaryEntry.Key); unusedEntriesFound = true; break; // the iterator has been invalidated, so we need a new foreach loop } } } while(unusedEntriesFound); }
/// <summary>Finds a free stripe on a texture to store a text fragment.</summary> /// <param name="texturePoolEntry">Texture pool entry that contains the allocated stripe.</param> /// <param name="stripeIndex">Index of the stripe, from top to bottom.</param> /// <param name="textFragment">New text fragment.</param> private void allocateTextureFragment(out TexturePoolEntry texturePoolEntry, out int stripeIndex, out DXCachedTextFragment textFragment) { // look for a free stripe on an existing texture foreach (TexturePoolEntry poolEntry in texturePool) { for (int i = 0; i < poolEntry.StripeAllocated.Length; ++i) { if (!poolEntry.StripeAllocated[i]) { poolEntry.StripeAllocated[i] = true; texturePoolEntry = poolEntry; stripeIndex = i; textFragment.Texture = poolEntry.Texture; textFragment.TextureCoordinates = new RectangleF(0.0f, (textHeight * i) / 256.0f, 1.0f, textHeight / 256.0f); return; } } } // no stripe available -> allocate a whole new texture TexturePoolEntry newPoolEntry = new TexturePoolEntry(graphics, textHeight); texturePool.Add(newPoolEntry); newPoolEntry.StripeAllocated[0] = true; texturePoolEntry = newPoolEntry; stripeIndex = 0; textFragment.Texture = newPoolEntry.Texture; textFragment.TextureCoordinates = new RectangleF(0.0f, 0.0f, 1.0f, textHeight / 256.0f); }