mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Feat] (State): give RenderbufferObject the never-reused lifetime id every other cache-keyable state object already has
- RenderbufferObject was the last state object a backend twin registry keys on that could only be identified by its heap address or its GL name - both of which recycle. BufferObject, VertexArrayObject and ProgramObject all carry a process-wide, never-reused id for exactly this; the renderbuffer's absence is named in plan B §10.4-5 as one of the two latent problems P0 closes. - Mirrors BufferObject.h:202-208 / BufferObject.cpp:19-24 verbatim in shape: a private static AllocateLifetimeId() over a namespace-scope std::atomic<Uint64> starting at 1 (so a zero-initialised memo slot can never carry a live object's id), a const member initialised from it at construction, and an inline const getter. The doc comment is the buffer one restated for the renderbuffer's own recycling sources. - Deliberately NO GetVersion(): plan B §11 P0 says the id only. A mutation counter would be a second, independent invalidation surface to keep correct, and nothing needs one yet - the renderbuffer's mutable content already reaches the backends through AllocateStorage / SetInternalFormat / SetSamples. - No caller yet, by design: the id exists so §4.7.3's D1 rekey (and the DirectGLES renderbuffer twin registry at Managers.h:1858) has something to key on. It is a pure addition - no existing field, signature or answer changes. - ObjectLifetimeIdTest gains the two cases the other two object types already have, so the renderbuffer is covered by the same allocator-reuse probe: an object rebuilt at a freed address must not answer to the dead one's id, and two live ones must differ. - Tested: cmake --build build-linux -j 24 (clean); ctest -R ObjectLifetimeId -> 6/6 passed (4 pre-existing + 2 new).
This commit is contained in:
@@ -9,9 +9,21 @@
|
|||||||
#include "RenderbufferObject.h"
|
#include "RenderbufferObject.h"
|
||||||
#include <MG_Util/Metrics/TextureMetrics.h>
|
#include <MG_Util/Metrics/TextureMetrics.h>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
namespace MobileGL {
|
namespace MobileGL {
|
||||||
namespace MG_State {
|
namespace MG_State {
|
||||||
namespace GLState {
|
namespace GLState {
|
||||||
|
namespace {
|
||||||
|
// Starts at 1 so a zero-initialized cache slot can never carry a live
|
||||||
|
// renderbuffer's id.
|
||||||
|
std::atomic<Uint64> g_nextRenderbufferLifetimeId{1};
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint64 RenderbufferObject::AllocateLifetimeId() {
|
||||||
|
return g_nextRenderbufferLifetimeId.fetch_add(1, std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
RenderbufferObject::RenderbufferObject(Uint externalIndex) : m_externalIndex(externalIndex) {}
|
RenderbufferObject::RenderbufferObject(Uint externalIndex) : m_externalIndex(externalIndex) {}
|
||||||
|
|
||||||
Uint RenderbufferObject::GetExternalIndex() const {
|
Uint RenderbufferObject::GetExternalIndex() const {
|
||||||
|
|||||||
@@ -42,9 +42,20 @@ namespace MobileGL {
|
|||||||
Int GetDepthSize() const;
|
Int GetDepthSize() const;
|
||||||
Int GetStencilSize() const;
|
Int GetStencilSize() const;
|
||||||
Int GetSamples() const;
|
Int GetSamples() const;
|
||||||
|
// Globally-unique, never-reused id for THIS object's lifetime - same contract
|
||||||
|
// and same motivation as BufferObject::GetLifetimeId(),
|
||||||
|
// ProgramObject::GetLifetimeId() and VertexArrayObject::GetLifetimeId(). A
|
||||||
|
// backend that folds a renderbuffer's IDENTITY into a cache key must use this,
|
||||||
|
// never the GL name (LIFO-recycled by glGenRenderbuffers) and never the heap
|
||||||
|
// address (recycled by the allocator): both let a deleted-and-recreated
|
||||||
|
// renderbuffer answer to a dead one's cache entry.
|
||||||
|
Uint64 GetLifetimeId() const { return m_lifetimeId; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static Uint64 AllocateLifetimeId();
|
||||||
|
|
||||||
Uint m_externalIndex = 0;
|
Uint m_externalIndex = 0;
|
||||||
|
const Uint64 m_lifetimeId = AllocateLifetimeId();
|
||||||
TextureInternalFormat m_internalFormat = TextureInternalFormat::RGBA;
|
TextureInternalFormat m_internalFormat = TextureInternalFormat::RGBA;
|
||||||
Int m_width = 0;
|
Int m_width = 0;
|
||||||
Int m_height = 0;
|
Int m_height = 0;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include "Includes.h"
|
#include "Includes.h"
|
||||||
|
|
||||||
#include <MG_State/GLState/BufferState/BufferObject.h>
|
#include <MG_State/GLState/BufferState/BufferObject.h>
|
||||||
|
#include <MG_State/GLState/RenderbufferState/RenderbufferObject.h>
|
||||||
#include <MG_State/GLState/VertexArrayState/VertexArrayObject.h>
|
#include <MG_State/GLState/VertexArrayState/VertexArrayObject.h>
|
||||||
|
|
||||||
using namespace MobileGL;
|
using namespace MobileGL;
|
||||||
@@ -138,3 +139,20 @@ TEST(ObjectLifetimeIdTest, LiveVertexArrayObjectsHaveDistinctLifetimeIds) {
|
|||||||
TEST(ObjectLifetimeIdTest, LiveBufferObjectsHaveDistinctLifetimeIds) {
|
TEST(ObjectLifetimeIdTest, LiveBufferObjectsHaveDistinctLifetimeIds) {
|
||||||
ExpectDistinctIdsWhileBothAlive<MG_State::GLState::BufferObject>("BufferObject");
|
ExpectDistinctIdsWhileBothAlive<MG_State::GLState::BufferObject>("BufferObject");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The renderbuffer had no lifetime id at all until plan B §11 P0 gave it one: it is
|
||||||
|
// the one FBO attachment source whose identity a backend twin registry can only have
|
||||||
|
// keyed on the heap address or the GL name, both of which recycle.
|
||||||
|
TEST(ObjectLifetimeIdTest, RenderbufferObjectAtARecycledAddressCarriesAFreshLifetimeId) {
|
||||||
|
using MG_State::GLState::RenderbufferObject;
|
||||||
|
const int reuseCount = ProbeLifetimeIdAcrossAddressReuse<RenderbufferObject>("RenderbufferObject");
|
||||||
|
if (reuseCount == 0) {
|
||||||
|
GTEST_SKIP() << "inconclusive, not proven: this allocator never handed the same address back across 64 "
|
||||||
|
"construct/destroy rounds, so the recycled-address case was never exercised";
|
||||||
|
}
|
||||||
|
RecordProperty("address_reuses_observed", reuseCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ObjectLifetimeIdTest, LiveRenderbufferObjectsHaveDistinctLifetimeIds) {
|
||||||
|
ExpectDistinctIdsWhileBothAlive<MG_State::GLState::RenderbufferObject>("RenderbufferObject");
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user