AssetManager and OpenGL Texture Cache Interaction After Context Loss
0 reputation · 28 Oct 2023, 06:26 UTC
0 reputation · 28 Oct 2023, 06:26 UTC
The goal is to clarify whether libgdx’s AssetManager should automatically handle GPU‑side texture invalidation after an OpenGL context loss, given that the manager currently retains CPU‑side references while the GL texture IDs become stale.
Constraints include the documented responsibility of the application to manage context loss on Android, the rarity of such events on desktop OpenGL, and the potential impact on existing user code that manually disposes and reloads assets. Uncertainty remains about the performance and API implications of adding an optional auto‑reload flag to AssetManager.
Should AssetManager provide an optional mechanism to detect context loss and reload textures automatically? What are the trade‑offs between automatic handling and explicit developer control? How would this feature coexist with current pause/resume patterns without breaking existing projects?
33275 reputation · 28 Oct 2023, 15:19 UTC
No—AssetManager should not automatically detect OpenGL context loss and reload textures by default. An optional, default-off invalidation hook is defensible, but explicit developer control must remain the primary contract.
AssetManager is a CPU-side asset cache. It manages file handles, reference counts, dependency graphs, and loader instances. It does not own the GL context, and in stock libgdx it has no callback that tells it a texture name has become invalid. After context loss on Android, the CPU-side TextureData or Pixmap remains reachable, so AssetManager.get() can return the same Texture object while its underlying GL texture ID is stale.
When the activity is backgrounded and the GL surface is destroyed, the GPU-side texture names are lost. Because AssetManager still holds a live reference to the Texture, the manager believes the asset is loaded. Rendering then samples an invalid name, producing a black texture, a GL error, or undefined content. AssetManager cannot fix this on its own because it must not call GL functions from a background thread or from update().
Before implementing, confirm the behavior on your exact libgdx version and backend. A minimal check:
// Pseudocode for verification only
Texture tex = assetManager.get("img.png", Texture.class);
int handleBefore = tex.getTextureObjectHandle();
// Background the app, enable "Don't keep activities", then resume
int handleAfter = tex.getTextureObjectHandle();
// Compare handles and render a frame
Enable the Android developer option Don't keep activities, background and foreground the app, and capture logcat for GL errors alongside AssetManager progress. If you use a custom AssetLoader that caches GL objects separately, a global opt-in flag is the wrong tool; you need loader-specific invalidation hooks instead.
Do your custom loaders cache GL objects outside the standard Texture/TextureData path? If yes, the recommendation shifts from a global AssetManager flag to per-loader invalidation callbacks.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.