[Refactor] (MG_State/Framebuffer, MG_Backend/DirectGLES): Versioned framebuffer sync

This commit is contained in:
2026-02-03 16:50:20 +08:00
parent 751c5745b0
commit 202922613b
5 changed files with 187 additions and 134 deletions
@@ -77,48 +77,49 @@ namespace MobileGL {
// FramebufferObject
FramebufferObject::FramebufferObject(Uint externalIndex) : m_externalIndex(externalIndex) {
m_attachments.fill(FramebufferAttachmentObject(false));
m_attachmentObjects.fill(FramebufferAttachmentObject(false));
m_drawBuffers.fill(FramebufferAttachmentType::None);
m_drawBuffers[0] = FramebufferAttachmentType::Color0;
m_attachmentVersions.fill(0);
}
void FramebufferObject::AttachTexture(FramebufferAttachmentType type, SharedPtr<ITextureObject> texture,
int level) {
m_attachments[static_cast<SizeT>(type)] = FramebufferAttachmentObject(std::move(texture), level);
m_drawBuffersDirty = true;
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(std::move(texture), level);
BumpAttachmentVersion(type);
}
void FramebufferObject::AttachRenderbuffer(FramebufferAttachmentType type,
std::shared_ptr<RenderbufferObject> renderbuffer) {
m_attachments[static_cast<SizeT>(type)] = FramebufferAttachmentObject(renderbuffer);
m_drawBuffersDirty = true;
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(renderbuffer);
BumpAttachmentVersion(type);
}
void FramebufferObject::Detach(FramebufferAttachmentType type) {
m_attachments[static_cast<SizeT>(type)] = FramebufferAttachmentObject(false);
m_drawBuffersDirty = true;
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(false);
BumpAttachmentVersion(type);
}
const FramebufferAttachmentObject& FramebufferObject::GetAttachment(FramebufferAttachmentType type) const {
return m_attachments[static_cast<SizeT>(type)];
return m_attachmentObjects[static_cast<SizeT>(type)];
}
const FramebufferObject::FramebufferAttachmentObjectArray& FramebufferObject::GetAllAttachments() const {
return m_attachments;
const FramebufferObject::FramebufferAttachmentObjectArray& FramebufferObject::GetAllAttachmentObjects() const {
return m_attachmentObjects;
}
Bool FramebufferObject::CheckCompleteness() const {
if (m_attachments.empty()) {
if (m_attachmentObjects.empty()) {
return false;
}
Int width = -1, height = -1;
Int validAttachmentCount = 0;
for (SizeT i = 0; i < m_attachments.size(); ++i) {
if (!m_attachments[i].IsValid()) continue;
for (SizeT i = 0; i < m_attachmentObjects.size(); ++i) {
if (!m_attachmentObjects[i].IsValid()) continue;
++validAttachmentCount;
const auto& attachment = m_attachments[i];
const auto& attachment = m_attachmentObjects[i];
auto attachmentSize = attachment.GetSize();
Int w = attachmentSize.x();
Int h = attachmentSize.y();
@@ -141,18 +142,9 @@ namespace MobileGL {
void FramebufferObject::SetDrawBuffer(Uint index, FramebufferAttachmentType buffer) {
if (m_drawBuffers[index] == buffer) return;
m_drawBuffersDirty = true;
m_drawBuffers[index] = buffer;
}
// void FramebufferObject::SetDrawBuffers(const Vector<FramebufferAttachmentType>& buffers) {
// m_drawBuffers = buffers;
// m_drawBuffersDirty = true;
// }
// void SetDrawBuffer(Uint index, FramebufferAttachmentType buffer) {
//
// }
const FramebufferObject::FramebufferAttachmentArray& FramebufferObject::GetDrawBuffers() const {
return m_drawBuffers;
}
@@ -160,6 +152,11 @@ namespace MobileGL {
Uint FramebufferObject::GetExternalIndex() const {
return m_externalIndex;
}
void FramebufferObject::BumpAttachmentVersion(FramebufferAttachmentType type) {
++m_attachmentVersions[static_cast<SizeT>(type)];
++m_objectVersion;
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
@@ -100,6 +100,8 @@ namespace MobileGL {
using FramebufferAttachmentObjectArray =
Array<FramebufferAttachmentObject, static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
using FramebufferAttachmentArray = Array<FramebufferAttachmentType, MAX_DRAW_BUFFERS>;
using FramebufferAttachmentVersionArray =
Array<Uint16, static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
FramebufferObject(Uint externalIndex);
@@ -108,24 +110,35 @@ namespace MobileGL {
std::shared_ptr<RenderbufferObject> renderbuffer);
void Detach(FramebufferAttachmentType type);
const FramebufferAttachmentObject& GetAttachment(FramebufferAttachmentType type) const;
const FramebufferAttachmentObjectArray& GetAllAttachments() const;
const FramebufferAttachmentObjectArray& GetAllAttachmentObjects() const;
Bool CheckCompleteness() const;
// aka. `buffer` as in glDrawBuffers/glReadBuffers
void SetDrawBuffer(Uint index, FramebufferAttachmentType buffer);
bool DrawBuffersIsDirty() const { return m_drawBuffersDirty; }
void ClearDrawBuffersDirtyState() { m_drawBuffersDirty = false; }
const FramebufferAttachmentArray& GetDrawBuffers() const;
void SetReadBuffer(FramebufferAttachmentType buf) { m_readBuffer = buf; }
FramebufferAttachmentType GetReadBuffer() const { return m_readBuffer; }
const FramebufferAttachmentVersionArray GetAllFramebufferAttachmentVersions() const {
return m_attachmentVersions;
}
Uint16 GetObjectVersion() const { return m_objectVersion; }
Uint GetExternalIndex() const;
private:
const Uint m_externalIndex = 0;
FramebufferAttachmentObjectArray m_attachments;
FramebufferAttachmentArray m_drawBuffers;
FramebufferAttachmentType m_readBuffer = FramebufferAttachmentType::Color0;
void BumpAttachmentVersion(FramebufferAttachmentType type);
void BumpBufferAttachVersion();
Bool m_drawBuffersDirty = false;
const Uint m_externalIndex = 0;
FramebufferAttachmentObjectArray m_attachmentObjects;
FramebufferAttachmentVersionArray m_attachmentVersions;
FramebufferAttachmentArray m_drawBuffers; // Probably no versioning needed for this, just check equality
FramebufferAttachmentType m_readBuffer = FramebufferAttachmentType::Color0; // ditto
// This version will bump when draw/read buffer changes (by `glDrawBuffer(s)`/`glReadBuffer`)
Uint16 m_objectVersion = 0;
};
} // namespace GLState