Standalone uniform writes optimized 51/261151/3
authorAdam Bialogonski <adam.b@samsung.com>
Mon, 12 Jul 2021 10:04:00 +0000 (11:04 +0100)
committerAdam Bialogonski <adam.b@samsung.com>
Mon, 12 Jul 2021 11:14:50 +0000 (12:14 +0100)
- 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

dali/internal/graphics/gles-impl/gles-graphics-program.cpp

index 5c833f5..6fa3d8f 100644 (file)
@@ -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<class A, class B>
+inline bool memcmp4(A* a, B* b, uint32_t size)
+{
+  auto* pa = reinterpret_cast<const uint32_t*>(a);
+  auto* pb = reinterpret_cast<const uint32_t*>(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<const float*>(&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<const int*>(&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<const float*>(&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()