mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 20:28:32 +09:00
[Fix] (Espryt): do not return a reference through a null slot pointer, and stop a comment claiming a memo that is no longer there
- SyncTextureObjectToBackend re-resolves its slot after the nested glTextureView sync. The assert that it is still there is right - the caller holds the frontend object, so nothing can reclaim its slot - but the function returns a REFERENCE, and in a release build the assert is gone and the deref is not. It now falls back to GetOrCreate and puts the twin the caller is about to use back. - ResolveVaoTwin documents why its raw twin pointer survives the whole draw on both arms instead of pointing at TwinLookupMemo, which the handle arm does not compile.
This commit is contained in:
@@ -1218,8 +1218,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// the result to the buffer sync (resolved-buffers memo host), the VAO sync and
|
||||
// the draw-time bind, which each used to run their own registry Find. The raw
|
||||
// pointer stays valid for the whole draw: the frontend VAO is pinned by the
|
||||
// context binding, and a live object's registry entry is never erased nor its
|
||||
// twin replaced (see TwinLookupMemo's contract).
|
||||
// context binding, and a live object's twin is never erased nor replaced - on the
|
||||
// legacy arm that is TwinLookupMemo's contract, and on the {slot, gen} arm it is
|
||||
// simply that nothing but the sweep frees a slot and the sweep only takes slots
|
||||
// whose frontend object is already gone.
|
||||
BackendVertexArrayObject* ResolveVaoTwin(const SharedPtr<MG_State::GLState::VertexArrayObject>& vao) {
|
||||
#ifdef TRACY_ENABLE
|
||||
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
|
||||
@@ -1390,7 +1392,17 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
auto* slot = g_backendTextureObjects.Find(textureObject.get());
|
||||
MOBILEGL_ASSERT(slot != nullptr && *slot != nullptr,
|
||||
"the texture twin resolved at entry is gone after its own sync");
|
||||
return *slot;
|
||||
if (slot != nullptr && *slot != nullptr) {
|
||||
return *slot;
|
||||
}
|
||||
// Cannot happen - the caller holds the frontend object, so its slot cannot be
|
||||
// reclaimed underneath this call - but the return is a reference, and a null
|
||||
// deref in a release build is a worse way to learn that than a re-created twin.
|
||||
auto& repaired = g_backendTextureObjects.GetOrCreate(textureObject);
|
||||
if (!repaired) {
|
||||
repaired = backendObj;
|
||||
}
|
||||
return repaired;
|
||||
}
|
||||
#endif
|
||||
auto* refreshedSlot = g_backendTextureObjects.Find(textureObject.get());
|
||||
|
||||
Reference in New Issue
Block a user