mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 12:18:30 +09:00
[Perf|Fix] (MG_Backend/DirectGLES): Improve perf.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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>>
|
||||
|
||||
Reference in New Issue
Block a user