mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 22:28:32 +09:00
[Refactor] (MG_State/Framebuffer, MG_Backend/DirectGLES): Versioned framebuffer sync
This commit is contained in:
@@ -220,7 +220,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
const auto& currentFBO =
|
const auto& currentFBO =
|
||||||
MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject();
|
MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject();
|
||||||
if (currentFBO) {
|
if (currentFBO) {
|
||||||
for (const auto& attachment : currentFBO->GetAllAttachments()) {
|
for (const auto& attachment : currentFBO->GetAllAttachmentObjects()) {
|
||||||
if (!attachment.IsTexture()) continue;
|
if (!attachment.IsTexture()) continue;
|
||||||
auto textureObject = attachment.GetTexture();
|
auto textureObject = attachment.GetTexture();
|
||||||
if (textureObject) {
|
if (textureObject) {
|
||||||
|
|||||||
@@ -787,6 +787,42 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
MG_External::GLES::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_backendFBOId);
|
MG_External::GLES::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_backendFBOId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bool BackendFramebufferObject::SyncAttachmentObject(
|
||||||
|
GLenum glFBOTarget, const MG_State::GLState::FramebufferAttachmentObject& attachmentObject,
|
||||||
|
GLenum glBackendAttachment) {
|
||||||
|
if (attachmentObject.IsTexture()) {
|
||||||
|
const auto& textureObject = attachmentObject.GetTexture();
|
||||||
|
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject);
|
||||||
|
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) {
|
||||||
|
MGLOG_E("ReadBuffer: No backend texture found for FBO attachment, cannot bind texture.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto& backendTextureObject = backendTextureIt->second;
|
||||||
|
auto glTextureTarget = MG_Util::ConvertTextureTargetToGLEnum(textureObject->GetTarget());
|
||||||
|
backendTextureObject->Bind(glTextureTarget);
|
||||||
|
MG_External::GLES::glFramebufferTexture2D(glFBOTarget, glBackendAttachment, glTextureTarget,
|
||||||
|
backendTextureObject->GetBackendTextureId(),
|
||||||
|
static_cast<GLint>(attachmentObject.GetTextureLevel()));
|
||||||
|
} else if (attachmentObject.IsRenderbuffer()) {
|
||||||
|
const auto& renderbufferObject = attachmentObject.GetRenderbuffer();
|
||||||
|
const auto& backendRenderbufferIt =
|
||||||
|
RenderbufferImpl::g_backendRenderbufferObjects.find(renderbufferObject);
|
||||||
|
SharedPtr<RenderbufferImpl::BackendRenderbufferObject> backendRenderbufferObject;
|
||||||
|
if (backendRenderbufferIt == RenderbufferImpl::g_backendRenderbufferObjects.end()) {
|
||||||
|
backendRenderbufferObject = MakeShared<RenderbufferImpl::BackendRenderbufferObject>();
|
||||||
|
RenderbufferImpl::g_backendRenderbufferObjects[renderbufferObject] = backendRenderbufferObject;
|
||||||
|
} else {
|
||||||
|
backendRenderbufferObject = backendRenderbufferIt->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
backendRenderbufferObject->SyncToBackend(renderbufferObject);
|
||||||
|
backendRenderbufferObject->Bind();
|
||||||
|
MG_External::GLES::glFramebufferRenderbuffer(glFBOTarget, glBackendAttachment, GL_RENDERBUFFER,
|
||||||
|
backendRenderbufferObject->GetBackendRenderbufferId());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void BackendFramebufferObject::SyncToBackend(SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject,
|
void BackendFramebufferObject::SyncToBackend(SharedPtr<MG_State::GLState::FramebufferObject>& stateFBOObject,
|
||||||
FramebufferTarget asTarget) {
|
FramebufferTarget asTarget) {
|
||||||
#ifdef TRACY_ENABLE
|
#ifdef TRACY_ENABLE
|
||||||
@@ -801,60 +837,31 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
GLenum glFBOTarget = MG_Util::ConvertFramebufferTargetToGLEnum(asTarget);
|
GLenum glFBOTarget = MG_Util::ConvertFramebufferTargetToGLEnum(asTarget);
|
||||||
Bind(asTarget);
|
Bind(asTarget);
|
||||||
|
|
||||||
// Handle all attachments
|
FramebufferAttachmentType* frontendAttachmentToSync = nullptr;
|
||||||
const auto& attachments = stateFBOObject->GetAllAttachments();
|
GLenum* backendAttachmentToSync = nullptr;
|
||||||
for (SizeT i = 0; i < attachments.size(); ++i) {
|
Int frontendAttachmentToSyncCount = 0;
|
||||||
const auto& attachment = attachments[i];
|
switch (asTarget) {
|
||||||
if (!attachment.IsValid() || attachment.IsEmpty()) {
|
case FramebufferTarget::Draw: {
|
||||||
continue;
|
auto &stateDrawBuffers = stateFBOObject->GetDrawBuffers();
|
||||||
}
|
|
||||||
FramebufferAttachmentType type = static_cast<FramebufferAttachmentType>(i);
|
// Check if still clean, skip if clean
|
||||||
GLenum glAttachment = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(type);
|
if (memcmp(m_frontendDrawBuffers,
|
||||||
if (attachment.IsTexture()) {
|
stateDrawBuffers.data(),
|
||||||
const auto& textureObject = attachment.GetTexture();
|
FramebufferObject::MAX_DRAW_BUFFERS * sizeof(FramebufferAttachmentType)) == 0) {
|
||||||
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject);
|
break;
|
||||||
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) {
|
|
||||||
MGLOG_E("No backend texture found for FBO attachment, cannot bind texture.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const auto& backendTextureObject = backendTextureIt->second;
|
|
||||||
auto glTextureTarget = MG_Util::ConvertTextureTargetToGLEnum(textureObject->GetTarget());
|
|
||||||
backendTextureObject->Bind(glTextureTarget);
|
|
||||||
MG_External::GLES::glFramebufferTexture2D(glFBOTarget, glAttachment, glTextureTarget,
|
|
||||||
backendTextureObject->GetBackendTextureId(),
|
|
||||||
static_cast<GLint>(attachment.GetTextureLevel()));
|
|
||||||
} else if (attachment.IsRenderbuffer()) {
|
|
||||||
const auto& renderbufferObject = attachment.GetRenderbuffer();
|
|
||||||
const auto& backendRenderbufferIt =
|
|
||||||
RenderbufferImpl::g_backendRenderbufferObjects.find(renderbufferObject);
|
|
||||||
SharedPtr<RenderbufferImpl::BackendRenderbufferObject> backendRenderbufferObject;
|
|
||||||
if (backendRenderbufferIt == RenderbufferImpl::g_backendRenderbufferObjects.end()) {
|
|
||||||
backendRenderbufferObject = MakeShared<RenderbufferImpl::BackendRenderbufferObject>();
|
|
||||||
RenderbufferImpl::g_backendRenderbufferObjects[renderbufferObject] = backendRenderbufferObject;
|
|
||||||
} else {
|
|
||||||
backendRenderbufferObject = backendRenderbufferIt->second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
backendRenderbufferObject->SyncToBackend(renderbufferObject);
|
|
||||||
backendRenderbufferObject->Bind();
|
|
||||||
MG_External::GLES::glFramebufferRenderbuffer(glFBOTarget, glAttachment, GL_RENDERBUFFER,
|
|
||||||
backendRenderbufferObject->GetBackendRenderbufferId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Handle draw buffers for DRAW_FRAMEBUFFER
|
|
||||||
if (asTarget == FramebufferTarget::Draw) {
|
|
||||||
// Create mappings for draw buffers
|
// Create mappings for draw buffers
|
||||||
int nBuffers = 0;
|
int nBuffers = 0;
|
||||||
std::fill(m_frontendDrawBuffers,
|
std::fill(m_frontendDrawBuffers,
|
||||||
m_frontendDrawBuffers + MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS,
|
m_frontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS,
|
||||||
FramebufferAttachmentType::None);
|
FramebufferAttachmentType::None);
|
||||||
std::fill(m_compactedFrontendDrawBuffers,
|
std::fill(m_compactedFrontendDrawBuffers,
|
||||||
m_compactedFrontendDrawBuffers + MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS,
|
m_compactedFrontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS,
|
||||||
FramebufferAttachmentType::None);
|
FramebufferAttachmentType::None);
|
||||||
std::fill(m_backendDrawBuffers,
|
std::fill(m_backendDrawBuffers,
|
||||||
m_backendDrawBuffers + MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS, GL_NONE);
|
m_backendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS, GL_NONE);
|
||||||
auto& stateDrawBuffers = stateFBOObject->GetDrawBuffers();
|
for (GLint i = 0; i < FramebufferObject::MAX_DRAW_BUFFERS; ++i) {
|
||||||
for (GLint i = 0; i < MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS; ++i) {
|
|
||||||
if (stateDrawBuffers[i] == FramebufferAttachmentType::None) {
|
if (stateDrawBuffers[i] == FramebufferAttachmentType::None) {
|
||||||
m_frontendDrawBuffers[i] = FramebufferAttachmentType::None;
|
m_frontendDrawBuffers[i] = FramebufferAttachmentType::None;
|
||||||
continue;
|
continue;
|
||||||
@@ -867,51 +874,80 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
m_compactedFrontendDrawBuffers[nBuffers] = m_frontendDrawBuffers[i];
|
m_compactedFrontendDrawBuffers[nBuffers] = m_frontendDrawBuffers[i];
|
||||||
nBuffers++;
|
nBuffers++;
|
||||||
}
|
}
|
||||||
|
|
||||||
MG_External::GLES::glDrawBuffers(nBuffers, m_backendDrawBuffers);
|
MG_External::GLES::glDrawBuffers(nBuffers, m_backendDrawBuffers);
|
||||||
stateFBOObject->ClearDrawBuffersDirtyState();
|
|
||||||
|
frontendAttachmentToSync = m_compactedFrontendDrawBuffers;
|
||||||
|
backendAttachmentToSync = m_backendDrawBuffers;
|
||||||
|
frontendAttachmentToSyncCount = nBuffers;
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// Handle read buffer for READ_FRAMEBUFFER
|
case FramebufferTarget::Read: {
|
||||||
else if (asTarget == FramebufferTarget::Read) {
|
auto frontendReadBuf = stateFBOObject->GetReadBuffer();
|
||||||
m_frontendReadBuffer = stateFBOObject->GetReadBuffer();
|
if (frontendReadBuf == m_frontendReadBuffer)
|
||||||
GLenum frontendAtt = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(m_frontendReadBuffer);
|
break;
|
||||||
GLenum backendAtt = GL_NONE;
|
m_frontendReadBuffer = frontendReadBuf;
|
||||||
const auto& readAttachment = attachments[(SizeT)m_frontendReadBuffer];
|
|
||||||
GLenum glAttachment = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(m_frontendReadBuffer);
|
// For consistency, we need to find the compacted attachment index of this read buffer
|
||||||
if (!readAttachment.IsValid() || readAttachment.IsEmpty()) {
|
auto it = std::find(
|
||||||
|
m_compactedFrontendDrawBuffers,
|
||||||
|
m_compactedFrontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS,
|
||||||
|
frontendReadBuf);
|
||||||
|
|
||||||
|
Bool notFound = (it == m_compactedFrontendDrawBuffers + FramebufferObject::MAX_DRAW_BUFFERS);
|
||||||
|
if (notFound) {
|
||||||
|
MGLOG_D("%s: read buffer not found in draw buffer, use as in frontend", __func__);
|
||||||
|
}
|
||||||
|
auto backendReadBuffer = notFound ? frontendReadBuf : *it;
|
||||||
|
GLenum glBackendReadBuffer = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(backendReadBuffer);
|
||||||
|
if (m_backendReadBuffer == glBackendReadBuffer)
|
||||||
|
break;
|
||||||
|
m_backendReadBuffer = glBackendReadBuffer;
|
||||||
|
MG_External::GLES::glReadBuffer(glBackendReadBuffer);
|
||||||
|
|
||||||
|
frontendAttachmentToSync = &m_frontendReadBuffer;
|
||||||
|
backendAttachmentToSync = &m_backendReadBuffer;
|
||||||
|
frontendAttachmentToSyncCount = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
MOBILEGL_ASSERT(false, "%s: Unreachable!", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (readAttachment.IsTexture()) {
|
|
||||||
const auto& textureObject = readAttachment.GetTexture();
|
|
||||||
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject);
|
|
||||||
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) {
|
|
||||||
MGLOG_E("ReadBuffer: No backend texture found for FBO attachment, cannot bind texture.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto& backendTextureObject = backendTextureIt->second;
|
|
||||||
auto glTextureTarget = MG_Util::ConvertTextureTargetToGLEnum(textureObject->GetTarget());
|
|
||||||
backendTextureObject->Bind(glTextureTarget);
|
|
||||||
MG_External::GLES::glFramebufferTexture2D(glFBOTarget, glAttachment, glTextureTarget,
|
|
||||||
backendTextureObject->GetBackendTextureId(),
|
|
||||||
static_cast<GLint>(readAttachment.GetTextureLevel()));
|
|
||||||
} else if (readAttachment.IsRenderbuffer()) {
|
|
||||||
const auto& renderbufferObject = readAttachment.GetRenderbuffer();
|
|
||||||
const auto& backendRenderbufferIt =
|
|
||||||
RenderbufferImpl::g_backendRenderbufferObjects.find(renderbufferObject);
|
|
||||||
SharedPtr<RenderbufferImpl::BackendRenderbufferObject> backendRenderbufferObject;
|
|
||||||
if (backendRenderbufferIt == RenderbufferImpl::g_backendRenderbufferObjects.end()) {
|
|
||||||
backendRenderbufferObject = MakeShared<RenderbufferImpl::BackendRenderbufferObject>();
|
|
||||||
RenderbufferImpl::g_backendRenderbufferObjects[renderbufferObject] = backendRenderbufferObject;
|
|
||||||
} else {
|
|
||||||
backendRenderbufferObject = backendRenderbufferIt->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
backendRenderbufferObject->SyncToBackend(renderbufferObject);
|
// Sync texture/buffer to attachment
|
||||||
backendRenderbufferObject->Bind();
|
const auto& attachmentObjects = stateFBOObject->GetAllAttachmentObjects();
|
||||||
MG_External::GLES::glFramebufferRenderbuffer(glFBOTarget, glAttachment, GL_RENDERBUFFER,
|
auto& attachmentVersions = stateFBOObject->GetAllFramebufferAttachmentVersions();
|
||||||
backendRenderbufferObject->GetBackendRenderbufferId());
|
for (Int i = 0; i < frontendAttachmentToSyncCount; ++i) {
|
||||||
|
auto frontendAttachment = frontendAttachmentToSync[i];
|
||||||
|
if (attachmentVersions[(SizeT)frontendAttachment] == m_syncedAttachmentVersions[(SizeT)frontendAttachment]) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
MG_External::GLES::glReadBuffer(glAttachment);
|
m_syncedAttachmentVersions[(SizeT)frontendAttachment] = attachmentVersions[(SizeT)frontendAttachment];
|
||||||
|
|
||||||
|
const auto& attachmentObject = stateFBOObject->GetAttachment(frontendAttachment);
|
||||||
|
if (!attachmentObject.IsValid() || attachmentObject.IsEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto glBackendAttachment = backendAttachmentToSync[i];
|
||||||
|
SyncAttachmentObject(glFBOTarget, attachmentObject, glBackendAttachment);
|
||||||
|
}
|
||||||
|
|
||||||
|
FramebufferAttachmentType auxAtt[] = { FramebufferAttachmentType::Depth, FramebufferAttachmentType::Stencil };
|
||||||
|
for (auto & att : auxAtt) {
|
||||||
|
auto frontendAttachment = att;
|
||||||
|
if (attachmentVersions[(SizeT)frontendAttachment] == m_syncedAttachmentVersions[(SizeT)frontendAttachment]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
m_syncedAttachmentVersions[(SizeT)frontendAttachment] = attachmentVersions[(SizeT)frontendAttachment];
|
||||||
|
|
||||||
|
const auto& attachmentObject = stateFBOObject->GetAttachment(frontendAttachment);
|
||||||
|
if (!attachmentObject.IsValid() || attachmentObject.IsEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto glBackendAttachment = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(att);
|
||||||
|
SyncAttachmentObject(glFBOTarget, attachmentObject, glBackendAttachment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
FramebufferTarget asTarget);
|
FramebufferTarget asTarget);
|
||||||
Uint GetBackendFramebufferId() { return m_backendFBOId; }
|
Uint GetBackendFramebufferId() { return m_backendFBOId; }
|
||||||
void Bind(FramebufferTarget target);
|
void Bind(FramebufferTarget target);
|
||||||
|
bool SyncAttachmentObject(GLenum glFBOTarget,
|
||||||
|
const MG_State::GLState::FramebufferAttachmentObject& attachmentObject,
|
||||||
|
GLenum glBackendAttachment);
|
||||||
FramebufferAttachmentType GetCompactedAttachmentTypeAtDrawBufferIndex(Int index);
|
FramebufferAttachmentType GetCompactedAttachmentTypeAtDrawBufferIndex(Int index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -152,6 +155,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
|||||||
*/
|
*/
|
||||||
GLenum m_backendDrawBuffers[MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS] = {GL_NONE};
|
GLenum m_backendDrawBuffers[MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS] = {GL_NONE};
|
||||||
FramebufferAttachmentType m_frontendReadBuffer = FramebufferAttachmentType::Color0;
|
FramebufferAttachmentType m_frontendReadBuffer = FramebufferAttachmentType::Color0;
|
||||||
|
GLenum m_backendReadBuffer = GL_COLOR_ATTACHMENT0;
|
||||||
|
|
||||||
|
using FramebufferObject = MG_State::GLState::FramebufferObject;
|
||||||
|
FramebufferObject::FramebufferAttachmentVersionArray m_syncedAttachmentVersions = {0};
|
||||||
};
|
};
|
||||||
|
|
||||||
extern UnorderedMap<SharedPtr<MG_State::GLState::FramebufferObject>, SharedPtr<BackendFramebufferObject>>
|
extern UnorderedMap<SharedPtr<MG_State::GLState::FramebufferObject>, SharedPtr<BackendFramebufferObject>>
|
||||||
|
|||||||
@@ -77,48 +77,49 @@ namespace MobileGL {
|
|||||||
|
|
||||||
// FramebufferObject
|
// FramebufferObject
|
||||||
FramebufferObject::FramebufferObject(Uint externalIndex) : m_externalIndex(externalIndex) {
|
FramebufferObject::FramebufferObject(Uint externalIndex) : m_externalIndex(externalIndex) {
|
||||||
m_attachments.fill(FramebufferAttachmentObject(false));
|
m_attachmentObjects.fill(FramebufferAttachmentObject(false));
|
||||||
m_drawBuffers.fill(FramebufferAttachmentType::None);
|
m_drawBuffers.fill(FramebufferAttachmentType::None);
|
||||||
m_drawBuffers[0] = FramebufferAttachmentType::Color0;
|
m_drawBuffers[0] = FramebufferAttachmentType::Color0;
|
||||||
|
m_attachmentVersions.fill(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferObject::AttachTexture(FramebufferAttachmentType type, SharedPtr<ITextureObject> texture,
|
void FramebufferObject::AttachTexture(FramebufferAttachmentType type, SharedPtr<ITextureObject> texture,
|
||||||
int level) {
|
int level) {
|
||||||
m_attachments[static_cast<SizeT>(type)] = FramebufferAttachmentObject(std::move(texture), level);
|
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(std::move(texture), level);
|
||||||
m_drawBuffersDirty = true;
|
BumpAttachmentVersion(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferObject::AttachRenderbuffer(FramebufferAttachmentType type,
|
void FramebufferObject::AttachRenderbuffer(FramebufferAttachmentType type,
|
||||||
std::shared_ptr<RenderbufferObject> renderbuffer) {
|
std::shared_ptr<RenderbufferObject> renderbuffer) {
|
||||||
m_attachments[static_cast<SizeT>(type)] = FramebufferAttachmentObject(renderbuffer);
|
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(renderbuffer);
|
||||||
m_drawBuffersDirty = true;
|
BumpAttachmentVersion(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferObject::Detach(FramebufferAttachmentType type) {
|
void FramebufferObject::Detach(FramebufferAttachmentType type) {
|
||||||
m_attachments[static_cast<SizeT>(type)] = FramebufferAttachmentObject(false);
|
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(false);
|
||||||
m_drawBuffersDirty = true;
|
BumpAttachmentVersion(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FramebufferAttachmentObject& FramebufferObject::GetAttachment(FramebufferAttachmentType type) const {
|
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 {
|
const FramebufferObject::FramebufferAttachmentObjectArray& FramebufferObject::GetAllAttachmentObjects() const {
|
||||||
return m_attachments;
|
return m_attachmentObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bool FramebufferObject::CheckCompleteness() const {
|
Bool FramebufferObject::CheckCompleteness() const {
|
||||||
if (m_attachments.empty()) {
|
if (m_attachmentObjects.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Int width = -1, height = -1;
|
Int width = -1, height = -1;
|
||||||
Int validAttachmentCount = 0;
|
Int validAttachmentCount = 0;
|
||||||
for (SizeT i = 0; i < m_attachments.size(); ++i) {
|
for (SizeT i = 0; i < m_attachmentObjects.size(); ++i) {
|
||||||
if (!m_attachments[i].IsValid()) continue;
|
if (!m_attachmentObjects[i].IsValid()) continue;
|
||||||
|
|
||||||
++validAttachmentCount;
|
++validAttachmentCount;
|
||||||
const auto& attachment = m_attachments[i];
|
const auto& attachment = m_attachmentObjects[i];
|
||||||
auto attachmentSize = attachment.GetSize();
|
auto attachmentSize = attachment.GetSize();
|
||||||
Int w = attachmentSize.x();
|
Int w = attachmentSize.x();
|
||||||
Int h = attachmentSize.y();
|
Int h = attachmentSize.y();
|
||||||
@@ -141,18 +142,9 @@ namespace MobileGL {
|
|||||||
|
|
||||||
void FramebufferObject::SetDrawBuffer(Uint index, FramebufferAttachmentType buffer) {
|
void FramebufferObject::SetDrawBuffer(Uint index, FramebufferAttachmentType buffer) {
|
||||||
if (m_drawBuffers[index] == buffer) return;
|
if (m_drawBuffers[index] == buffer) return;
|
||||||
m_drawBuffersDirty = true;
|
|
||||||
m_drawBuffers[index] = buffer;
|
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 {
|
const FramebufferObject::FramebufferAttachmentArray& FramebufferObject::GetDrawBuffers() const {
|
||||||
return m_drawBuffers;
|
return m_drawBuffers;
|
||||||
}
|
}
|
||||||
@@ -160,6 +152,11 @@ namespace MobileGL {
|
|||||||
Uint FramebufferObject::GetExternalIndex() const {
|
Uint FramebufferObject::GetExternalIndex() const {
|
||||||
return m_externalIndex;
|
return m_externalIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FramebufferObject::BumpAttachmentVersion(FramebufferAttachmentType type) {
|
||||||
|
++m_attachmentVersions[static_cast<SizeT>(type)];
|
||||||
|
++m_objectVersion;
|
||||||
|
}
|
||||||
} // namespace GLState
|
} // namespace GLState
|
||||||
} // namespace MG_State
|
} // namespace MG_State
|
||||||
} // namespace MobileGL
|
} // namespace MobileGL
|
||||||
|
|||||||
@@ -100,6 +100,8 @@ namespace MobileGL {
|
|||||||
using FramebufferAttachmentObjectArray =
|
using FramebufferAttachmentObjectArray =
|
||||||
Array<FramebufferAttachmentObject, static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
|
Array<FramebufferAttachmentObject, static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
|
||||||
using FramebufferAttachmentArray = Array<FramebufferAttachmentType, MAX_DRAW_BUFFERS>;
|
using FramebufferAttachmentArray = Array<FramebufferAttachmentType, MAX_DRAW_BUFFERS>;
|
||||||
|
using FramebufferAttachmentVersionArray =
|
||||||
|
Array<Uint16, static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
|
||||||
|
|
||||||
FramebufferObject(Uint externalIndex);
|
FramebufferObject(Uint externalIndex);
|
||||||
|
|
||||||
@@ -108,24 +110,35 @@ namespace MobileGL {
|
|||||||
std::shared_ptr<RenderbufferObject> renderbuffer);
|
std::shared_ptr<RenderbufferObject> renderbuffer);
|
||||||
void Detach(FramebufferAttachmentType type);
|
void Detach(FramebufferAttachmentType type);
|
||||||
const FramebufferAttachmentObject& GetAttachment(FramebufferAttachmentType type) const;
|
const FramebufferAttachmentObject& GetAttachment(FramebufferAttachmentType type) const;
|
||||||
const FramebufferAttachmentObjectArray& GetAllAttachments() const;
|
const FramebufferAttachmentObjectArray& GetAllAttachmentObjects() const;
|
||||||
Bool CheckCompleteness() const;
|
Bool CheckCompleteness() const;
|
||||||
// aka. `buffer` as in glDrawBuffers/glReadBuffers
|
// aka. `buffer` as in glDrawBuffers/glReadBuffers
|
||||||
void SetDrawBuffer(Uint index, FramebufferAttachmentType buffer);
|
void SetDrawBuffer(Uint index, FramebufferAttachmentType buffer);
|
||||||
bool DrawBuffersIsDirty() const { return m_drawBuffersDirty; }
|
|
||||||
void ClearDrawBuffersDirtyState() { m_drawBuffersDirty = false; }
|
|
||||||
const FramebufferAttachmentArray& GetDrawBuffers() const;
|
const FramebufferAttachmentArray& GetDrawBuffers() const;
|
||||||
void SetReadBuffer(FramebufferAttachmentType buf) { m_readBuffer = buf; }
|
void SetReadBuffer(FramebufferAttachmentType buf) { m_readBuffer = buf; }
|
||||||
FramebufferAttachmentType GetReadBuffer() const { return m_readBuffer; }
|
FramebufferAttachmentType GetReadBuffer() const { return m_readBuffer; }
|
||||||
|
|
||||||
|
const FramebufferAttachmentVersionArray GetAllFramebufferAttachmentVersions() const {
|
||||||
|
return m_attachmentVersions;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint16 GetObjectVersion() const { return m_objectVersion; }
|
||||||
|
|
||||||
Uint GetExternalIndex() const;
|
Uint GetExternalIndex() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Uint m_externalIndex = 0;
|
void BumpAttachmentVersion(FramebufferAttachmentType type);
|
||||||
FramebufferAttachmentObjectArray m_attachments;
|
void BumpBufferAttachVersion();
|
||||||
FramebufferAttachmentArray m_drawBuffers;
|
|
||||||
FramebufferAttachmentType m_readBuffer = FramebufferAttachmentType::Color0;
|
|
||||||
|
|
||||||
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
|
} // namespace GLState
|
||||||
|
|||||||
Reference in New Issue
Block a user