From 921214b6830ac95bcf2e3c48c0f4e3e9ab836748 Mon Sep 17 00:00:00 2001 From: Adam Bialogonski Date: Mon, 12 Jul 2021 11:04:00 +0100 Subject: [PATCH] Standalone uniform writes optimized - Removed memcmp (replaced with custom function working on 4-byte long types) - Only one memmove called at the end of update on the whole cache block Change-Id: Iecf1e0b774993ad703e953a617f7cd5e837e0239 --- .../graphics/gles-impl/gles-graphics-program.cpp | 51 ++++++++++++---------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/dali/internal/graphics/gles-impl/gles-graphics-program.cpp b/dali/internal/graphics/gles-impl/gles-graphics-program.cpp index 5c833f5..6fa3d8f 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-program.cpp +++ b/dali/internal/graphics/gles-impl/gles-graphics-program.cpp @@ -31,6 +31,21 @@ namespace Dali::Graphics::GLES using Integration::GlAbstraction; /** + * Memory compare working on 4-byte types. Since all types used in shaders are + * size of 4*N then no need for size and alignment checks. + */ +template +inline bool memcmp4(A* a, B* b, uint32_t size) +{ + auto* pa = reinterpret_cast(a); + auto* pb = reinterpret_cast(b); + size >>= 2; + while(size-- && *pa++ == *pb++) + ; + return (-1u == size); +}; + +/** * Structure stores pointer to the function * which will set the uniform of particular type */ @@ -228,42 +243,34 @@ void ProgramImpl::UpdateStandaloneUniformBlock(const char* ptr) for(const auto& info : extraInfos) { auto& setter = mImpl->uniformSetters[index++]; - - auto offset = info.offset; - switch(setter.type) + auto offset = info.offset; + if(!memcmp4(&cachePtr[offset], &ptr[offset], info.size * info.arraySize)) { - case UniformSetter::Type::FLOAT: + switch(setter.type) { - if(0 != memcmp(&cachePtr[offset], &ptr[offset], info.size * info.arraySize)) + case UniformSetter::Type::FLOAT: { (gl.*(setter.uniformfProc))(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - memcpy(&cachePtr[offset], &ptr[offset], info.size * info.arraySize); + break; } - break; - } - case UniformSetter::Type::INT: - { - if(0 != memcmp(&cachePtr[offset], &ptr[offset], info.size * info.arraySize)) + case UniformSetter::Type::INT: { (gl.*(setter.uniformiProc))(info.location, info.arraySize, reinterpret_cast(&ptr[offset])); - memcpy(&cachePtr[offset], &ptr[offset], info.size * info.arraySize); + break; } - break; - } - case UniformSetter::Type::MATRIX: - { - if(0 != memcmp(&cachePtr[offset], &ptr[offset], info.size * info.arraySize)) + case UniformSetter::Type::MATRIX: { (gl.*(setter.uniformMatrixProc))(info.location, info.arraySize, GL_FALSE, reinterpret_cast(&ptr[offset])); - memcpy(&cachePtr[offset], &ptr[offset], info.size * info.arraySize); + break; + } + case UniformSetter::Type::UNDEFINED: + { } - break; - } - case UniformSetter::Type::UNDEFINED: - { } } } + // Update caches + memmove(mImpl->uniformData.data(), ptr, mImpl->uniformData.size()); } void ProgramImpl::BuildStandaloneUniformCache() -- 2.7.4