diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index ca9ab972..5823fe7b 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -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 +#include +#include #include #include #include #include #include +#include #include namespace MobileGL::MG_Backend::DirectGLES { namespace DebugImpl { void ErrorLopper::Loop(std::function 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 backendTextureObject; diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.cpp b/MobileGL/MG_Backend/DirectGLES/Managers.cpp index 0d915ab1..595a657a 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Managers.cpp @@ -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(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(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(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(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(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(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) diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.h b/MobileGL/MG_Backend/DirectGLES/Managers.h index 35a152ef..9fd2a5b9 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.h +++ b/MobileGL/MG_Backend/DirectGLES/Managers.h @@ -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 m_cacheSwizzleParams = {TextureSwizzleParam::Red, TextureSwizzleParam::Green, + TextureSwizzleParam::Blue, TextureSwizzleParam::Alpha}; }; extern UnorderedMap, SharedPtr>