| 203 | } |
| 204 | |
| 205 | TTFSurface* TTFSurfaceCacheGetOrAdd(TTF_Font* font, std::string_view text) |
| 206 | { |
| 207 | ttf_cache_entry* entry; |
| 208 | |
| 209 | uint32_t hash = TTFSurfaceCacheHash(font, text); |
| 210 | int32_t index = hash % kTTFSurfaceCacheSize; |
| 211 | |
| 212 | DrawingUniqueLock<std::mutex> lock(_mutex); |
| 213 | |
| 214 | for (int32_t i = 0; i < kTTFSurfaceCacheSize; i++) |
| 215 | { |
| 216 | entry = &_ttfSurfaceCache[index]; |
| 217 | |
| 218 | // Check if entry is a hit |
| 219 | if (entry->surface == nullptr) |
| 220 | break; |
| 221 | if (entry->font == font && String::equals(entry->text, text)) |
| 222 | { |
| 223 | _ttfSurfaceCacheHitCount++; |
| 224 | entry->lastUseTick = gCurrentDrawCount; |
| 225 | return entry->surface; |
| 226 | } |
| 227 | |
| 228 | // If entry hasn't been used for a while, replace it |
| 229 | if (entry->lastUseTick < gCurrentDrawCount - 64) |
| 230 | { |
| 231 | break; |
| 232 | } |
| 233 | |
| 234 | // Check if next entry is a hit |
| 235 | if (++index >= kTTFSurfaceCacheSize) |
| 236 | index = 0; |
| 237 | } |
| 238 | |
| 239 | // Cache miss, replace entry with new surface |
| 240 | entry = &_ttfSurfaceCache[index]; |
| 241 | TTFSurfaceCacheDispose(entry); |
| 242 | |
| 243 | TTFSurface* surface = TTFRender(font, text); |
| 244 | if (surface == nullptr) |
| 245 | { |
| 246 | return nullptr; |
| 247 | } |
| 248 | |
| 249 | _ttfSurfaceCacheMissCount++; |
| 250 | // printf("CACHE HITS: %d MISSES: %d)\n", _ttfSurfaceCacheHitCount, _ttfSurfaceCacheMissCount); |
| 251 | |
| 252 | _ttfSurfaceCacheCount++; |
| 253 | entry->surface = surface; |
| 254 | entry->font = font; |
| 255 | entry->text = text; |
| 256 | entry->lastUseTick = gCurrentDrawCount; |
| 257 | return entry->surface; |
| 258 | } |
| 259 | |
| 260 | static void TTFGetWidthCacheDispose(ttf_getwidth_cache_entry* entry) |
| 261 | { |
no test coverage detected