mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-09 04:38:30 +09:00
[Fix] (Espryt): treat an unbound vertex-elements record as a memo miss and record the applier-reset serial rule the twin's gate depends on
This commit is contained in:
@@ -600,13 +600,26 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
const auto& st = MG_Pipe::MGPipeApplier();
|
||||
const MG_Pipe::MGPipeHandle elements = st.BoundVertexElements;
|
||||
Uint64 elementsSerial = 0;
|
||||
Bool haveElementsRecord = false;
|
||||
if (!MG_Pipe::MGPipeHandleIsNull(elements) && elements.Slot < st.VertexElementsCsos.size()) {
|
||||
const auto& record = st.VertexElementsCsos[elements.Slot];
|
||||
if (record.Live && record.Gen == elements.Gen) elementsSerial = record.ContentSerial;
|
||||
if (record.Live && record.Gen == elements.Gen) {
|
||||
elementsSerial = record.ContentSerial;
|
||||
haveElementsRecord = true;
|
||||
}
|
||||
}
|
||||
const Uint64 buffersSerial = st.VertexBuffersSerial;
|
||||
|
||||
if (memo && memo->valid && memo->elementsHandle == elements &&
|
||||
// NO LIVE ELEMENTS RECORD IS A MISS, NEVER A HIT. With none, the key above is
|
||||
// {null, 0, buffersSerial} - a key that describes no configuration at all and that
|
||||
// NEVER CHANGES while the state stays that way, so a memo stamped with it would hit
|
||||
// on every later draw of a VAO whose attributes have moved. That state is reachable:
|
||||
// MGPipeApplierReset() empties VertexElementsCsos and BoundVertexElements at every
|
||||
// change of the current context, and the client re-emits only at its next
|
||||
// create/bind. The legacy arm's configuration version caught exactly this by moving.
|
||||
const Bool memoKeyIsMeaningful = haveElementsRecord;
|
||||
|
||||
if (memo && memo->valid && memoKeyIsMeaningful && memo->elementsHandle == elements &&
|
||||
memo->elementsSerial == elementsSerial && memo->buffersSerial == buffersSerial) {
|
||||
if (memo->vboCleanEpoch != bufferEpoch) {
|
||||
Bool allClean = true;
|
||||
@@ -660,7 +673,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
memo->elementsHandle = elements;
|
||||
memo->elementsSerial = elementsSerial;
|
||||
memo->buffersSerial = buffersSerial;
|
||||
memo->valid = true;
|
||||
// Only a key that describes a real configuration is worth remembering; see
|
||||
// memoKeyIsMeaningful above. The walk still ran and the buffers are ensured -
|
||||
// this only refuses to let the NEXT draw skip it.
|
||||
memo->valid = memoKeyIsMeaningful;
|
||||
// Rebuilt via EnsureBufferResource, not probed clean: the next probe pass
|
||||
// stamps the epoch.
|
||||
memo->vboCleanEpoch = 0;
|
||||
|
||||
@@ -3971,6 +3971,21 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
|
||||
const Uint64 currentBufferIdGeneration = BufferImpl::g_bufferBackendIdGeneration;
|
||||
const Bool bufferIdsRemitted = m_syncedBufferIdGeneration != currentBufferIdGeneration;
|
||||
// THIS GATE DEPENDS ON A SERIAL RULE THAT LIVES IN ANOTHER PACKAGE, and it is named
|
||||
// here because nothing else in this file would say it: MGPipeApplierReset() runs on
|
||||
// EVERY change of the current GLContext (MG_Impl/Pipe/Tracker.h's `if (m_context !=
|
||||
// &ctx) Reset();`, not only on a fresh one), while this twin SURVIVES the excursion -
|
||||
// BackendVertexArrayObject has no context-generation member and
|
||||
// OnBackendContextDestroyed runs on destroy, not on make-current. A reset that sent
|
||||
// VertexBuffersSerial and IndexBufferSerial back to ZERO would therefore walk them
|
||||
// back through values this twin has already stamped, and a memo could read clean over
|
||||
// state the applier had just cleared. MG_Pipe/PipeApply.cpp's reset must ADVANCE
|
||||
// those two serials instead (wire's C2), which is what makes
|
||||
// m_syncedVertexBuffersSerial below unable to match after a reset - and that in turn
|
||||
// forces the whole AND dirty, which is also what rescues the per-record ContentSerial
|
||||
// half (an applier reset is not a slot recycle, so a re-created CSO at the same
|
||||
// {slot, gen} restarts its ContentSerial at 1). If that rule is ever reverted, this
|
||||
// gate is unsafe on any application that changes contexts.
|
||||
const Bool attributesDirty = bufferIdsRemitted || !m_hasSyncedElements ||
|
||||
!(m_syncedElementsHandle == st.BoundVertexElements) ||
|
||||
m_syncedElementsSerial != rec->ContentSerial ||
|
||||
|
||||
Reference in New Issue
Block a user