[Perf|Fix] (MG_Backend/DirectGLES): Improve perf.

This commit is contained in:
BZLZHH
2025-11-29 01:21:34 +08:00
parent 936abafde9
commit 8ca8fa1520
3 changed files with 84 additions and 65 deletions
+43 -24
View File
@@ -1,32 +1,37 @@
#include "DirectGLES.h"
#include "Utils.h"
#include "Managers.h"
#include "MG_Util/Converters/GLToMG/TextureEnumConverter.h"
#include "MG_Util/Classifiers/TextureEnumClassifier.h"
#include "MG_Util/Metrics/TextureMetrics.h"
#include <MG_Util/Converters/GLToMG/TextureEnumConverter.h>
#include <MG_Util/Classifiers/TextureEnumClassifier.h>
#include <MG_Util/Metrics/TextureMetrics.h>
#include <MG_State/GLState/Core.h>
#include <MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h>
#include <MG_Util/BackendLoaders/OpenGL/Loader.h>
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
#include <MG_Util/Converters/MGToGL/TextureEnumConverter.h>
#include <MG_Util/Converters/MGToStr/TextureEnumConverter.h>
#include <MG_Util/Converters/MGToGL/RenderStateEnumConverter.h>
namespace MobileGL::MG_Backend::DirectGLES {
namespace DebugImpl {
void ErrorLopper::Loop(std::function<void(GLenum)> func) {
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG
GLenum err = MG_External::GLES::glGetError();
while (err != GL_NO_ERROR) {
func(err);
err = MG_External::GLES::glGetError();
}
#endif
}
void ErrorLopper::Clear() {
#if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG
GLenum err = MG_External::GLES::glGetError();
while (err != GL_NO_ERROR) {
MGLOG_D("Stray GL Error cleared: %s", MG_Util::ConvertGLEnumToString(err).c_str());
err = MG_External::GLES::glGetError();
}
#endif
}
ErrorLopper::ErrorLopper() {
@@ -37,7 +42,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
} // namespace DebugImpl
// TODO: deletion of deleted objects
// TODO: deletion for deleted objects
namespace BufferImpl {
void SyncNeccessaryBuffers() {
@@ -56,14 +61,20 @@ namespace MobileGL::MG_Backend::DirectGLES {
if (!attrib.Enabled) continue;
const auto& bufferObject = attrib.Buffer;
if (bufferObject) {
buffersToSync.push_back(bufferObject);
const auto& end = buffersToSync.end();
if (std::find(buffersToSync.begin(), end, bufferObject) == end) {
buffersToSync.push_back(bufferObject);
}
}
}
// IBO
const auto& possibleIBO = currentVAOObject->GetIndexBufferBindingSlot().GetBoundObject();
if (possibleIBO) {
buffersToSync.push_back(possibleIBO);
const auto& end = buffersToSync.end();
if (std::find(buffersToSync.begin(), end, possibleIBO) == end) {
buffersToSync.push_back(possibleIBO);
}
}
// UBO
@@ -71,7 +82,12 @@ namespace MobileGL::MG_Backend::DirectGLES {
for (SizeT i = 0; i < uboBindingPointCnt; ++i) {
auto& point = MG_State::pGLContext->GetBufferBindingPoint(BufferTarget::Uniform, i);
auto obj = point.GetBoundObject();
if (obj) buffersToSync.push_back(obj);
if (obj) {
const auto& end = buffersToSync.end();
if (std::find(buffersToSync.begin(), end, obj) == end) {
buffersToSync.push_back(obj);
}
}
}
// Do real sync
@@ -137,7 +153,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
for (const auto& bindingSlot : unit.GetAllBindingSlots()) {
const auto& textureObject = bindingSlot.GetBoundObject();
if (textureObject) {
texturesToSync.push_back(textureObject);
const auto& end = texturesToSync.end();
if (std::find(texturesToSync.begin(), end, textureObject) == end) {
texturesToSync.push_back(textureObject);
}
}
}
}
@@ -149,7 +168,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
if (!attachment.IsTexture()) continue;
const auto& textureObject = attachment.GetTexture();
if (textureObject) {
texturesToSync.push_back(textureObject);
const auto& end = texturesToSync.end();
if (std::find(texturesToSync.begin(), end, textureObject) == end) {
texturesToSync.push_back(textureObject);
}
}
}
}
@@ -333,28 +355,24 @@ namespace MobileGL::MG_Backend::DirectGLES {
const auto& textureObject = bindingSlot.GetBoundObject();
if (!textureObject) continue;
auto target = textureObject->GetTarget();
if (target == TextureTarget::TextureBuffer || target == TextureTarget::Texture1D ||
target == TextureTarget::TextureRectangle || target == TextureTarget::Texture2DMultisampleArray ||
target == TextureTarget::Texture1DArray || target == TextureTarget::Texture3D ||
target == TextureTarget::Texture2DMultisample || target == TextureTarget::Texture2DArray) {
MGLOG_D(" Texture target %s is not supported, skipping.",
MG_Util::ConvertTextureTargetToString(target).c_str());
continue;
}
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject);
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) continue;
GLenum target = MG_Util::ConvertTextureTargetToGLEnum(textureObject->GetTarget());
backendTextureIt->second->Bind(target);
const auto& samplerObj = textureObject->GetSamplerObject();
const auto minfilter = samplerObj->GetMinFilter();
const auto mipfilter = samplerObj->GetMipmapMode();
MG_External::GLES::glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
MG_Util::ConvertSamplerFilterModeToGLEnum(minfilter, mipfilter));
const auto magfilter = samplerObj->GetMagFilter();
MG_External::GLES::glTexParameteri(
target, GL_TEXTURE_MAG_FILTER,
MG_Util::ConvertSamplerFilterModeToGLEnum(magfilter, SamplerMipmapMode::None));
MG_External::GLES::glTexParameterf(target, GL_TEXTURE_MIN_LOD, samplerObj->GetMinLod());
MG_External::GLES::glTexParameterf(target, GL_TEXTURE_MAX_LOD, samplerObj->GetMaxLod());
}
}
Int originalActiveUnit = MG_State::pGLContext->GetActiveTextureUnit();
MG_External::GLES::glActiveTexture(GL_TEXTURE0 + originalActiveUnit);
const auto& currentProgram = MG_State::pGLContext->GetCurrentProgram();
if (currentProgram && currentProgram->GetLinkStatus()) {
@@ -623,10 +641,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
});
auto activeUnit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit());
Int unit = MG_State::pGLContext->GetActiveTextureUnit();
auto& activeUnit = MG_State::pGLContext->GetTextureUnitObject(unit);
TextureTarget textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
auto& bindingSlot = activeUnit.GetBindingSlot(textureTarget);
auto textureObject = bindingSlot.GetBoundObject();
const auto& textureObject = bindingSlot.GetBoundObject();
const auto& backendTextureIt = TextureImpl::g_backendTextureObjects.find(textureObject);
SharedPtr<TextureImpl::BackendTextureObject> backendTextureObject;
+37 -41
View File
@@ -256,6 +256,19 @@ namespace MobileGL::MG_Backend::DirectGLES {
stateTextureObject->GetExternalIndex());
GLenum target = MG_Util::ConvertTextureTargetToGLEnum(stateTextureObject->GetTarget());
auto targetInternal = stateTextureObject->GetTarget();
Uint currentUnit = TextureImpl::g_cachedActiveTextureUnit;
MGLOG_D(" Texture target for syncing is %s", MG_Util::ConvertTextureTargetToString(target).c_str());
if (targetInternal == TextureTarget::TextureBuffer || targetInternal == TextureTarget::Texture1D ||
targetInternal == TextureTarget::TextureRectangle ||
targetInternal == TextureTarget::Texture2DMultisampleArray ||
targetInternal == TextureTarget::Texture1DArray || targetInternal == TextureTarget::Texture3D ||
targetInternal == TextureTarget::Texture2DMultisample ||
targetInternal == TextureTarget::Texture2DArray) {
MGLOG_D(" Texture target %s is not supported, skipping.",
MG_Util::ConvertTextureTargetToString(target).c_str());
return;
}
// The texture needs to be regenerated completely with glTexImage* calls if:
// 1. Not initialized
@@ -360,8 +373,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
});
// SYNC_TEX_SAMPLER_PARAM_IF_CHANGED(minFilter, GL_TEXTURE_MIN_FILTER, FilterMode)
// SYNC_TEX_SAMPLER_PARAM_IF_CHANGED(magFilter, GL_TEXTURE_MAG_FILTER, FilterMode)
SYNC_TEX_SAMPLER_PARAM_IF_CHANGED(wrapS, GL_TEXTURE_WRAP_S, WrapMode)
SYNC_TEX_SAMPLER_PARAM_IF_CHANGED(wrapT, GL_TEXTURE_WRAP_T, WrapMode)
SYNC_TEX_SAMPLER_PARAM_IF_CHANGED(wrapR, GL_TEXTURE_WRAP_R, WrapMode)
@@ -385,11 +396,22 @@ namespace MobileGL::MG_Backend::DirectGLES {
MGLOG_D("Updating texture parameters for texture with ID: %u", m_backendTextureId);
const auto& levelRange = stateTextureObject->GetLevelRange();
MG_External::GLES::glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, static_cast<GLint>(levelRange.x()));
if (m_cacheLodRange.x() != levelRange.x()) {
BIND_CURRENT_TEXTURE_IF_NOT_BOUND();
MG_External::GLES::glTexParameteri(targetGL, GL_TEXTURE_BASE_LEVEL,
static_cast<GLint>(levelRange.x()));
m_cacheLodRange.x() = levelRange.x();
}
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
});
MG_External::GLES::glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, static_cast<GLint>(levelRange.y()));
if (m_cacheLodRange.y() != levelRange.y()) {
BIND_CURRENT_TEXTURE_IF_NOT_BOUND();
MG_External::GLES::glTexParameteri(targetGL, GL_TEXTURE_MAX_LEVEL,
static_cast<GLint>(levelRange.y()));
m_cacheLodRange.y() = levelRange.y();
}
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
});
@@ -423,9 +445,17 @@ namespace MobileGL::MG_Backend::DirectGLES {
MG_Util::ConvertGLEnumToString(swizzleParams[2]).c_str(),
MG_Util::ConvertGLEnumToString(swizzleParams[3]).c_str());
});
const auto& borderColor = stateTextureObject->GetBorderColor();
GLfloat borderColorArray[4] = {borderColor.x(), borderColor.y(), borderColor.z(), borderColor.w()};
MG_External::GLES::glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, borderColorArray);
if (m_cacheBorderColor != stateTextureObject->GetBorderColor()) {
const auto& borderColor = stateTextureObject->GetBorderColor();
GLfloat borderColorArray[4] = {borderColor.x(), borderColor.y(), borderColor.z(), borderColor.w()};
BIND_CURRENT_TEXTURE_IF_NOT_BOUND();
MG_External::GLES::glTexParameterfv(targetGL, GL_TEXTURE_BORDER_COLOR, borderColorArray);
m_cacheBorderColor = borderColor;
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__](GLenum err) {
MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
});
}
}
{ // Update all dirty mipmap levels
@@ -560,27 +590,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
MG_External::GLES::glDrawBuffers(nBuffers, m_backendDrawBuffers);
// Attach textures for compacted draw buffers
// for (int i = 0; i < nBuffers; ++i) {
// FramebufferAttachmentType frontendAttachmentType =
// MG_Util::ConvertGLEnumToFramebufferAttachmentType(m_compactedFrontendBuffers[i]);
// GLenum backendAttachment = m_backendBuffers[i];
// const auto& attachment = attachments[static_cast<SizeT>(frontendAttachmentType)];
// if (!attachment.IsTexture()) continue;
// const auto& textureObject = attachment.GetTexture();
// const auto& backendTextureIt =
// TextureImpl::g_backendTextureObjects.find(textureObject); if (backendTextureIt ==
// TextureImpl::g_backendTextureObjects.end()) continue; const auto&
// backendTextureObject = backendTextureIt->second; auto glTextureTarget =
// MG_Util::ConvertTextureTargetToGLEnum(textureObject->GetTarget());
// backendTextureObject->Bind(glTextureTarget);
// MG_External::GLES::glFramebufferTexture2D(glFBOTarget, backendAttachment,
// glTextureTarget,
// backendTextureObject->GetBackendTextureId(),
// static_cast<GLint>(attachment.GetTextureLevel()));
// }
stateFBOObject->ClearDrawBuffersDirtyState();
}
// Handle read buffer for READ_FRAMEBUFFER
@@ -588,16 +597,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
m_frontendReadBuffer = stateFBOObject->GetReadBuffer();
GLenum frontendAtt = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(m_frontendReadBuffer);
GLenum backendAtt = GL_NONE;
// Find corresponding backend attachment in compacted draw buffers
// for (SizeT i = 0; i < MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS; ++i) {
// if (m_compactedFrontendBuffers[i] == frontendAtt) {
// backendAtt = m_backendBuffers[i];
// break;
// }
// }
// if (backendAtt != GL_NONE) {
// MG_External::GLES::glReadBuffer(backendAtt);
// } else {
const auto& readAttachment = attachments[(SizeT)m_frontendReadBuffer];
GLenum glAttachment = MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(m_frontendReadBuffer);
if (!readAttachment.IsValid() || readAttachment.IsEmpty()) {
@@ -620,7 +619,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
// TODO: renderbuffer support
}
MG_External::GLES::glReadBuffer(glAttachment);
// }
}
}
@@ -839,8 +837,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
m_cacheSamplerParameters.magFilter = samplerParams.magFilter;
}
// SYNC_SAMPLER_PARAM_IF_CHANGED(minFilter, GL_TEXTURE_MIN_FILTER, FilterMode)
// SYNC_SAMPLER_PARAM_IF_CHANGED(magFilter, GL_TEXTURE_MAG_FILTER, FilterMode)
SYNC_SAMPLER_PARAM_IF_CHANGED(wrapS, GL_TEXTURE_WRAP_S, WrapMode)
SYNC_SAMPLER_PARAM_IF_CHANGED(wrapT, GL_TEXTURE_WRAP_T, WrapMode)
SYNC_SAMPLER_PARAM_IF_CHANGED(wrapR, GL_TEXTURE_WRAP_R, WrapMode)
@@ -75,6 +75,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
Bool m_isInitialized = false;
StateTextureBasicInfo m_prevTextureInfo;
SamplerParameters m_cacheSamplerParameters;
UintVec2 m_cacheLodRange = {0, 1000};
FloatVec4 m_cacheBorderColor = {0.0f, 0.0f, 0.0f, 0.0f};
Vec4<TextureSwizzleParam> m_cacheSwizzleParams = {TextureSwizzleParam::Red, TextureSwizzleParam::Green,
TextureSwizzleParam::Blue, TextureSwizzleParam::Alpha};
};
extern UnorderedMap<SharedPtr<MG_State::GLState::ITextureObject>, SharedPtr<BackendTextureObject>>