From 4e4c40fe9d0176f08e15947505552cff0c8f8bee Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Tue, 20 Dec 2022 13:50:59 +0900 Subject: [PATCH] [Tizen] Remove VAO cache if invalidate pipeline This is a combination of 2 commits. Cache VAO with the locations hash Signed-off-by: Eunki, Hong Remove VAO cache if invalidate pipeline Delete VAO cache map if pipeline destroied. So we can avoid equal ProgramImpl pointer which already destroyied program. Change-Id: I1fa614b07c4b80e13c2ca23f275950a9672b3542 Signed-off-by: Eunki, Hong --- dali/internal/graphics/gles-impl/gles-context.cpp | 64 +++++++++++++++++------ 1 file changed, 49 insertions(+), 15 deletions(-) diff --git a/dali/internal/graphics/gles-impl/gles-context.cpp b/dali/internal/graphics/gles-impl/gles-context.cpp index 9c5fa87..32f490d 100644 --- a/dali/internal/graphics/gles-impl/gles-context.cpp +++ b/dali/internal/graphics/gles-impl/gles-context.cpp @@ -34,6 +34,7 @@ #include #include #include +#include namespace Dali::Graphics::GLES { @@ -53,30 +54,35 @@ struct Context::Impl * that VertexInputState has been set correctly for the pipeline. * */ - void BindProgramVAO(GLES::ProgramImpl* program, const VertexInputState& vertexInputState) + void BindProgramVAO(const GLES::ProgramImpl* program, const VertexInputState& vertexInputState) { + // Calculate attributes location hash unordered. + std::size_t hash = 0; + for(const auto& attr : vertexInputState.attributes) + { + hash ^= std::hash{}(attr.location); + } + auto& gl = *mController.GetGL(); auto iter = mProgramVAOMap.find(program); if(iter != mProgramVAOMap.end()) { - if(mProgramVAOCurrentState != iter->second) - { - mProgramVAOCurrentState = iter->second; - gl.BindVertexArray(iter->second); - } - - // We should re-check enable attribute usage because geometry might be changed. - for(const auto& attr : vertexInputState.attributes) + auto attributeIter = iter->second.find(hash); + if(attributeIter != iter->second.end()) { - gl.EnableVertexAttribArray(attr.location); + if(mProgramVAOCurrentState != attributeIter->second) + { + mProgramVAOCurrentState = attributeIter->second; + gl.BindVertexArray(attributeIter->second); + } + return; } - return; } uint32_t vao; gl.GenVertexArrays(1, &vao); gl.BindVertexArray(vao); - mProgramVAOMap[program] = vao; + mProgramVAOMap[program][hash] = vao; for(const auto& attr : vertexInputState.attributes) { gl.EnableVertexAttribArray(attr.location); @@ -212,9 +218,9 @@ struct Context::Impl const GLES::RenderPass* mCurrentRenderPass{nullptr}; // Each context must have own VAOs as they cannot be shared - std::map mProgramVAOMap; ///< GL program-VAO map - uint32_t mProgramVAOCurrentState{0u}; ///< Currently bound VAO - GLStateCache mGlStateCache{}; ///< GL status cache + std::unordered_map> mProgramVAOMap; ///< GL program-VAO map + uint32_t mProgramVAOCurrentState{0u}; ///< Currently bound VAO + GLStateCache mGlStateCache{}; ///< GL status cache bool mGlContextCreated{false}; ///< True if the OpenGL context has been created @@ -1015,6 +1021,34 @@ void Context::InvalidateCachedPipeline(GLES::Pipeline* pipeline) { mImpl->mCurrentPipeline = nullptr; } + + // Remove cached VAO map + auto* gl = mImpl->mController.GetGL(); + if(gl) + { + const auto* program = pipeline->GetCreateInfo().programState->program; + if(program) + { + const auto* programImpl = static_cast(program)->GetImplementation(); + if(programImpl) + { + auto iter = mImpl->mProgramVAOMap.find(programImpl); + if(iter != mImpl->mProgramVAOMap.end()) + { + for(auto& attributeHashPair : iter->second) + { + auto vao = attributeHashPair.second; + gl->DeleteVertexArrays(1, &vao); + if(mImpl->mProgramVAOCurrentState == vao) + { + mImpl->mProgramVAOCurrentState = 0u; + } + } + mImpl->mProgramVAOMap.erase(iter); + } + } + } + } } void Context::PrepareForNativeRendering() -- 2.7.4