Do not copy same UBODescriptor and TextureBinding at GLES::Context + Remove unused... 56/318556/8
authorEunki, Hong <eunkiki.hong@samsung.com>
Mon, 20 Jan 2025 10:25:13 +0000 (19:25 +0900)
committerEunki Hong <eunkiki.hong@samsung.com>
Sun, 26 Jan 2025 05:24:09 +0000 (14:24 +0900)
Some struct call std::fill_n internally when we call resize - for example : UniformBufferBindingDescriptor
But, we really don't need to use initialized value.

Let we make the container as Dali::Vector, so can skip useless initialize value.

Moreover, let we remove unused function, BindSamplers.

Change-Id: I66f2fa7e83fea89dfac1c5d20e003745991d4edc
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
dali/internal/graphics/gles-impl/gles-context.cpp
dali/internal/graphics/gles-impl/gles-graphics-command-buffer.cpp
dali/internal/graphics/gles-impl/gles-graphics-command-buffer.h

index ea3c6c457353adf202722e3c133fe5bfee43551a..a28ae0c99576b482cda4f6d46c4ff660d5f12275 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -243,9 +243,9 @@ struct Context::Impl
   const GLES::PipelineImpl* mCurrentPipeline{nullptr}; ///< Currently bound pipeline
   const GLES::PipelineImpl* mNewPipeline{nullptr};     ///< New pipeline to be set on flush
 
-  std::vector<Graphics::TextureBinding> mCurrentTextureBindings{};
-  std::vector<Graphics::SamplerBinding> mCurrentSamplerBindings{};
-  GLES::IndexBufferBindingDescriptor    mCurrentIndexBufferBinding{};
+  Dali::Vector<Graphics::TextureBinding> mCurrentTextureBindings{};
+
+  GLES::IndexBufferBindingDescriptor mCurrentIndexBufferBinding{};
 
   struct VertexBufferBinding
   {
@@ -257,8 +257,8 @@ struct Context::Impl
   std::vector<VertexBufferBindingDescriptor> mCurrentVertexBufferBindings{};
 
   // Currently bound UBOs (check if it's needed per program!)
-  std::vector<UniformBufferBindingDescriptor> mCurrentUBOBindings{};
-  UniformBufferBindingDescriptor              mCurrentStandaloneUBOBinding{};
+  Dali::Vector<UniformBufferBindingDescriptor> mCurrentUBOBindings{};
+  UniformBufferBindingDescriptor               mCurrentStandaloneUBOBinding{};
 
   // Current render pass and render target
   const GLES::RenderTarget* mCurrentRenderTarget{nullptr};
@@ -373,6 +373,8 @@ void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall, GLES::
       break;
     }
 
+    DALI_ASSERT_DEBUG(binding.texture && "GLES::Texture not assigned!");
+
     auto texture = const_cast<GLES::Texture*>(static_cast<const GLES::Texture*>(binding.texture));
 
     // Texture may not have been initialized yet...(tbm_surface timing issue?)
@@ -502,8 +504,8 @@ void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall, GLES::
         if(drawCall.draw.instanceCount == 0)
         {
           gl->DrawArrays(GLESTopology(ia->topology),
-                        drawCall.draw.firstVertex,
-                        drawCall.draw.vertexCount);
+                         drawCall.draw.firstVertex,
+                         drawCall.draw.vertexCount);
         }
         else
         {
@@ -533,9 +535,9 @@ void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall, GLES::
         if(drawCall.drawIndexed.instanceCount == 0)
         {
           gl->DrawElements(GLESTopology(ia->topology),
-                          drawCall.drawIndexed.indexCount,
-                          indexBufferFormat,
-                          reinterpret_cast<void*>(binding.offset));
+                           drawCall.drawIndexed.indexCount,
+                           indexBufferFormat,
+                           reinterpret_cast<void*>(binding.offset));
         }
         else
         {
@@ -566,19 +568,10 @@ void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall, GLES::
 
 void Context::BindTextures(const Graphics::TextureBinding* bindings, uint32_t count)
 {
-  // for each texture allocate slot
-  for(auto i = 0u; i < count; ++i)
-  {
-    auto& binding = bindings[i];
-
-    // Resize binding array if needed
-    if(mImpl->mCurrentTextureBindings.size() <= binding.binding)
-    {
-      mImpl->mCurrentTextureBindings.resize(binding.binding + 1);
-    }
-    // Store the binding details
-    mImpl->mCurrentTextureBindings[binding.binding] = binding;
-  }
+  // We can assume that bindings is sorted by binding number.
+  // So we can only copy the data
+  mImpl->mCurrentTextureBindings.Resize(count);
+  memcpy(mImpl->mCurrentTextureBindings.Begin(), bindings, sizeof(Graphics::TextureBinding) * count);
 }
 
 void Context::BindVertexBuffers(const GLES::VertexBufferBindingDescriptor* bindings, uint32_t count)
@@ -621,21 +614,15 @@ void Context::BindUniformBuffers(const UniformBufferBindingDescriptor* uboBindin
   {
     mImpl->mCurrentStandaloneUBOBinding = standaloneBindings;
   }
-
-  if(uboCount && uboCount > mImpl->mCurrentUBOBindings.size())
+  else
   {
-    mImpl->mCurrentUBOBindings.resize(uboCount);
+    mImpl->mCurrentStandaloneUBOBinding.buffer = nullptr;
   }
 
-  auto it = uboBindings;
-  for(auto i = 0u; i < uboCount; ++i)
-  {
-    if(it->buffer)
-    {
-      mImpl->mCurrentUBOBindings[i] = *it;
-    }
-    ++it;
-  }
+  // We can assume that bindings is sorted by binding number.
+  // So we can only copy the data
+  mImpl->mCurrentUBOBindings.Resize(uboCount);
+  memcpy(mImpl->mCurrentUBOBindings.Begin(), uboBindings, sizeof(UniformBufferBindingDescriptor) * uboCount);
 }
 
 void Context::ResolveBlendState()
@@ -772,7 +759,7 @@ void Context::ResolveUniformBuffers()
   {
     ResolveStandaloneUniforms();
   }
-  if(!mImpl->mCurrentUBOBindings.empty())
+  if(!mImpl->mCurrentUBOBindings.Empty())
   {
     ResolveGpuUniformBuffers();
   }
@@ -783,9 +770,12 @@ void Context::ResolveGpuUniformBuffers()
   if(auto* gl = mImpl->GetGL())
   {
     auto i = 0u;
-    for(auto& binding : mImpl->mCurrentUBOBindings)
+    for(const auto& binding : mImpl->mCurrentUBOBindings)
     {
-      gl->BindBufferRange(GL_UNIFORM_BUFFER, i++, binding.buffer->GetGLBuffer(), GLintptr(binding.offset), GLintptr(binding.dataSize));
+      if(DALI_LIKELY(binding.buffer && binding.dataSize > 0u))
+      {
+        gl->BindBufferRange(GL_UNIFORM_BUFFER, i++, binding.buffer->GetGLBuffer(), GLintptr(binding.offset), GLintptr(binding.dataSize));
+      }
     }
   }
 }
@@ -969,8 +959,8 @@ void Context::ReadPixels(uint8_t* buffer)
 
 void Context::ClearState()
 {
-  mImpl->mCurrentTextureBindings.clear();
-  mImpl->mCurrentUBOBindings.clear();
+  mImpl->mCurrentTextureBindings.Clear();
+  mImpl->mCurrentUBOBindings.Clear();
 }
 
 void Context::ColorMask(bool enabled)
@@ -1366,14 +1356,12 @@ void Context::ResetGLESState()
   mImpl->mGlStateCache.ResetBufferCache();
   mImpl->mGlStateCache.ResetTextureCache();
   mImpl->mCurrentPipeline = nullptr;
-  mImpl->mCurrentUBOBindings.clear();
-  mImpl->mCurrentTextureBindings.clear();
+
   mImpl->mCurrentVertexBufferBindings.clear();
   mImpl->mCurrentRenderTarget       = nullptr;
   mImpl->mCurrentRenderPass         = nullptr;
   mImpl->mVertexBuffersChanged      = true;
   mImpl->mCurrentIndexBufferBinding = {};
-  mImpl->mCurrentSamplerBindings    = {};
   mImpl->mProgramVAOCurrentState    = 0;
 
   ClearState();
index 2798712bb4f9ca5ca28adec6e4dca6d4d5d1353b..b068d42d36a9ead5a597c551cd87e5d8ba7d5c45 100644 (file)
@@ -280,7 +280,7 @@ void CommandBuffer::BindUniformBuffers(const std::vector<Graphics::UniformBuffer
 
   static constexpr UniformBufferBindingDescriptor                 NULL_DESCRIPTOR{nullptr, 0, 0, 0, 0, false};
   static thread_local std::vector<UniformBufferBindingDescriptor> sTempBindings(MAX_UNIFORM_BUFFER_BINDINGS, NULL_DESCRIPTOR);
-  static std::vector<bool>                                        sTempBindingsUsed(MAX_UNIFORM_BUFFER_BINDINGS, false);
+  static thread_local std::vector<bool>                           sTempBindingsUsed(MAX_UNIFORM_BUFFER_BINDINGS, false);
 
   memset(&bindCmd.standaloneUniformsBufferBinding, 0, sizeof(UniformBufferBindingDescriptor));
 
@@ -340,22 +340,9 @@ void CommandBuffer::BindUniformBuffers(const std::vector<Graphics::UniformBuffer
     ++maxBinding;
 
     auto destBindings = mCommandPool->Allocate<UniformBufferBindingDescriptor>(maxBinding);
+
     // copy
-    const auto size = sizeof(UniformBufferBindingDescriptor) * (maxBinding);
-    if(!(size % sizeof(intptr_t)))
-    {
-      // Use iteration hardly, to avoid SIGBUS... (SIGBUS occurs when accessing unaligned memory)
-      auto* srcPtr = reinterpret_cast<intptr_t*>(&sTempBindings[0]);
-      auto* dstPtr = reinterpret_cast<intptr_t*>(destBindings.Ptr());
-      for(auto i = 0u; i < size / sizeof(intptr_t); ++i)
-      {
-        *dstPtr++ = *srcPtr++;
-      }
-    }
-    else
-    {
-      memcpy(destBindings.Ptr(), &sTempBindings[0], size);
-    }
+    memcpy(destBindings.Ptr(), &sTempBindings[0], sizeof(UniformBufferBindingDescriptor) * (maxBinding));
     bindCmd.uniformBufferBindings      = destBindings;
     bindCmd.uniformBufferBindingsCount = maxBinding;
   }
@@ -369,20 +356,41 @@ void CommandBuffer::BindPipeline(const Graphics::Pipeline& pipeline)
 
 void CommandBuffer::BindTextures(const std::vector<TextureBinding>& textureBindings)
 {
-  auto  command                        = mCommandPool->AllocateCommand(CommandType::BIND_TEXTURES);
-  auto& bindTexturesCmd                = command->bindTextures;
-  bindTexturesCmd.textureBindings      = mCommandPool->Allocate<TextureBinding>(textureBindings.size());
-  bindTexturesCmd.textureBindingsCount = textureBindings.size();
-  memcpy(bindTexturesCmd.textureBindings.Ptr(), textureBindings.data(), sizeof(TextureBinding) * textureBindings.size());
+  auto  command         = mCommandPool->AllocateCommand(CommandType::BIND_TEXTURES);
+  auto& bindTexturesCmd = command->bindTextures;
+
+  if(textureBindings.empty())
+  {
+    bindTexturesCmd.textureBindings      = nullptr;
+    bindTexturesCmd.textureBindingsCount = 0u;
+  }
+  else
+  {
+    const uint32_t bindingCount = static_cast<uint32_t>(textureBindings.size());
+
+    auto destBindings = mCommandPool->Allocate<TextureBinding>(bindingCount);
+
+    // copy
+    memcpy(destBindings.Ptr(), textureBindings.data(), sizeof(TextureBinding) * (bindingCount));
+
+    bindTexturesCmd.textureBindings      = destBindings;
+    bindTexturesCmd.textureBindingsCount = bindingCount;
+
+    // Check binding is continuous, and throw exception for debug mode
+#if defined(DEBUG_ENABLED)
+    uint32_t lastBinding = 0u;
+    for(const auto& binding : textureBindings)
+    {
+      DALI_ASSERT_DEBUG(lastBinding == binding.binding && "Texture binding order not matched!");
+      ++lastBinding;
+    }
+#endif
+  }
 }
 
 void CommandBuffer::BindSamplers(const std::vector<SamplerBinding>& samplerBindings)
 {
-  auto  command                        = mCommandPool->AllocateCommand(CommandType::BIND_SAMPLERS);
-  auto& bindSamplersCmd                = command->bindSamplers;
-  bindSamplersCmd.samplerBindings      = mCommandPool->Allocate<SamplerBinding>(samplerBindings.size());
-  bindSamplersCmd.samplerBindingsCount = samplerBindings.size();
-  memcpy(bindSamplersCmd.samplerBindings.Ptr(), samplerBindings.data(), sizeof(TextureBinding) * samplerBindings.size());
+  // Unused in core
 }
 
 void CommandBuffer::BindPushConstants(void*    data,
index 0f7e81bc46abf94c16b3cb81bfca53dffc611572..e24d414054f7231c020bd960cf2768227ae8c9b2 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_GRAPHICS_GLES_COMMAND_BUFFER_H
 
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -98,10 +98,10 @@ struct Command
    * @brief Copy constructor
    * @param[in] rhs Command
    */
-  Command(const Command& rhs)            = default;
+  Command(const Command& rhs) = default;
   Command& operator=(const Command& rhs) = default;
   Command(Command&& rhs) noexcept        = delete;
-  Command& operator=(Command&& rhs)      = delete;
+  Command& operator=(Command&& rhs) = delete;
 
   CommandType type{CommandType::FLUSH}; ///< Type of command
 
@@ -109,14 +109,14 @@ struct Command
   {
     struct
     {
-      IndirectPtr<Graphics::TextureBinding> textureBindings;
+      IndirectPtr<Graphics::TextureBinding> textureBindings; ///< Sorted by binding index.
       uint32_t                              textureBindingsCount;
     } bindTextures{};
 
     // BindSampler command
     struct
     {
-      IndirectPtr<Graphics::SamplerBinding> samplerBindings;
+      IndirectPtr<Graphics::SamplerBinding> samplerBindings; ///< Sorted by binding index.
       uint32_t                              samplerBindingsCount;
     } bindSamplers;
 
@@ -133,7 +133,7 @@ struct Command
 
     struct
     {
-      IndirectPtr<UniformBufferBindingDescriptor> uniformBufferBindings;
+      IndirectPtr<UniformBufferBindingDescriptor> uniformBufferBindings; ///< Sorted by binding index.
       uint32_t                                    uniformBufferBindingsCount;
       UniformBufferBindingDescriptor              standaloneUniformsBufferBinding{};
     } bindUniformBuffers;