Change the TextureSet Count when we set empty texture or sampler 70/298470/4
authorEunki, Hong <eunkiki.hong@samsung.com>
Thu, 7 Sep 2023 09:55:32 +0000 (18:55 +0900)
committerEunki Hong <eunkiki.hong@samsung.com>
Fri, 22 Sep 2023 06:09:12 +0000 (15:09 +0900)
Let we change the number of textures / samplers in TextureSet
when we setting empty texture / sampler.

It will ignore some useless new creation of TextureSet if we just want to
remove some textures.

And also, let we ignore useless Sampler nullptr setup. We can control
cases when sampler is nullptr.

Change-Id: Iddc99bf2d7ad934a39e12ebe831ebffa8a7882b3
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali/utc-Dali-TextureSet.cpp
dali/internal/event/rendering/texture-set-impl.cpp
dali/internal/event/rendering/texture-set-impl.h
dali/internal/render/renderers/render-renderer.cpp
dali/internal/update/rendering/scene-graph-texture-set.cpp
dali/internal/update/rendering/scene-graph-texture-set.h

index 00e5974..a06ae42 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -448,6 +448,71 @@ int UtcDaliTextureSetGetTextureCount1(void)
   END_TEST;
 }
 
+int UtcDaliTextureSetRemoveTextureAndGetTextureCount(void)
+{
+  TestApplication application;
+
+  TextureSet textureSet = CreateTextureSet();
+  DALI_TEST_EQUALS(textureSet.GetTextureCount(), 0u, TEST_LOCATION);
+
+  Texture image0 = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+  Texture image1 = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+  Texture image2 = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+
+  textureSet.SetTexture(0u, image0);
+  DALI_TEST_EQUALS(textureSet.GetTextureCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(textureSet.GetTexture(0u), image0, TEST_LOCATION);
+
+  textureSet.SetTexture(1u, image1);
+  DALI_TEST_EQUALS(textureSet.GetTextureCount(), 2u, TEST_LOCATION);
+  DALI_TEST_EQUALS(textureSet.GetTexture(0u), image0, TEST_LOCATION);
+  DALI_TEST_EQUALS(textureSet.GetTexture(1u), image1, TEST_LOCATION);
+
+  // Set empty texture so we can remove it.
+  textureSet.SetTexture(1u, Texture());
+
+  DALI_TEST_EQUALS(textureSet.GetTextureCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(textureSet.GetTexture(0u), image0, TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render();
+
+  textureSet.SetTexture(2u, image2);
+
+  DALI_TEST_EQUALS(textureSet.GetTextureCount(), 3u, TEST_LOCATION);
+  DALI_TEST_EQUALS(textureSet.GetTexture(0u), image0, TEST_LOCATION);
+  DALI_TEST_EQUALS(textureSet.GetTexture(1u), Texture(), TEST_LOCATION);
+  DALI_TEST_EQUALS(textureSet.GetTexture(2u), image2, TEST_LOCATION);
+
+  textureSet.SetTexture(1u, image1);
+
+  DALI_TEST_EQUALS(textureSet.GetTextureCount(), 3u, TEST_LOCATION);
+  DALI_TEST_EQUALS(textureSet.GetTexture(0u), image0, TEST_LOCATION);
+  DALI_TEST_EQUALS(textureSet.GetTexture(1u), image1, TEST_LOCATION);
+  DALI_TEST_EQUALS(textureSet.GetTexture(2u), image2, TEST_LOCATION);
+
+  // Set empty texture middle of textureset.
+  textureSet.SetTexture(1u, Texture());
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS(textureSet.GetTextureCount(), 3u, TEST_LOCATION);
+  DALI_TEST_EQUALS(textureSet.GetTexture(0u), image0, TEST_LOCATION);
+  DALI_TEST_EQUALS(textureSet.GetTexture(1u), Texture(), TEST_LOCATION);
+  DALI_TEST_EQUALS(textureSet.GetTexture(2u), image2, TEST_LOCATION);
+
+  // Set empty texture end of textureset.
+  textureSet.SetTexture(2u, Texture());
+
+  DALI_TEST_EQUALS(textureSet.GetTextureCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(textureSet.GetTexture(0u), image0, TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render();
+
+  END_TEST;
+}
 int UtcDaliTextureSetSetSamplerNegative(void)
 {
   TestApplication  application;
index 43ce456..61db3dc 100644 (file)
@@ -37,26 +37,10 @@ TextureSetPtr TextureSet::New()
 void TextureSet::SetTexture(uint32_t index, TexturePtr texture)
 {
   uint32_t textureCount = static_cast<uint32_t>(mTextures.size());
-  if(index >= textureCount)
-  {
-    mTextures.resize(index + 1);
-
-    bool samplerExist = true;
-    if(mSamplers.size() < index + 1)
-    {
-      mSamplers.resize(index + 1);
-      samplerExist = false;
-    }
-
-    for(uint32_t i(textureCount); i <= index; ++i)
-    {
-      mTextures[i] = nullptr;
 
-      if(!samplerExist)
-      {
-        mSamplers[i] = nullptr;
-      }
-    }
+  if(textureCount < index + 1)
+  {
+    SetTextureCount(index + 1);
   }
 
   mTextures[index] = texture;
@@ -68,6 +52,12 @@ void TextureSet::SetTexture(uint32_t index, TexturePtr texture)
   }
 
   SceneGraph::SetTextureMessage(mEventThreadServices, *mSceneObject, index, renderTexture);
+
+  if(!texture)
+  {
+    // Check wheter we need to pop back textures
+    TrimContainers();
+  }
 }
 
 Texture* TextureSet::GetTexture(uint32_t index) const
@@ -90,11 +80,7 @@ void TextureSet::SetSampler(uint32_t index, SamplerPtr sampler)
   uint32_t samplerCount = static_cast<uint32_t>(mSamplers.size());
   if(samplerCount < index + 1)
   {
-    mSamplers.resize(index + 1);
-    for(uint32_t i = samplerCount; i <= index; ++i)
-    {
-      mSamplers[i] = nullptr;
-    }
+    SetSamplerCount(index + 1);
   }
 
   mSamplers[index] = sampler;
@@ -106,6 +92,12 @@ void TextureSet::SetSampler(uint32_t index, SamplerPtr sampler)
   }
 
   SceneGraph::SetSamplerMessage(mEventThreadServices, *mSceneObject, index, renderSampler);
+
+  if(!sampler)
+  {
+    // Check wheter we need to pop back sampler
+    TrimContainers();
+  }
 }
 
 Sampler* TextureSet::GetSampler(uint32_t index) const
@@ -133,6 +125,51 @@ const SceneGraph::TextureSet* TextureSet::GetTextureSetSceneObject() const
   return mSceneObject;
 }
 
+void TextureSet::SetTextureCount(uint32_t count)
+{
+  uint32_t textureCount = static_cast<uint32_t>(mTextures.size());
+  if(textureCount != count)
+  {
+    mTextures.resize(count, nullptr);
+  }
+}
+
+void TextureSet::SetSamplerCount(uint32_t count)
+{
+  uint32_t samplerCount = static_cast<uint32_t>(mSamplers.size());
+  if(samplerCount != count)
+  {
+    mSamplers.resize(count, nullptr);
+  }
+}
+
+void TextureSet::TrimContainers()
+{
+  uint32_t textureCount = static_cast<uint32_t>(mTextures.size());
+  uint32_t samplerCount = static_cast<uint32_t>(mSamplers.size());
+
+  while(textureCount > 0u)
+  {
+    if(mTextures[textureCount - 1u])
+    {
+      break;
+    }
+    --textureCount;
+  }
+
+  while(samplerCount > 0u)
+  {
+    if(mSamplers[samplerCount - 1u])
+    {
+      break;
+    }
+    --samplerCount;
+  }
+
+  SetTextureCount(textureCount);
+  SetSamplerCount(samplerCount);
+}
+
 TextureSet::TextureSet()
 : mEventThreadServices(EventThreadServices::Get()),
   mSceneObject(nullptr)
index b88d7d7..260a485 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_TEXTURE_SET_H
 
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
@@ -93,6 +93,25 @@ private: // implementation
    */
   void Initialize();
 
+  /**
+   * @brief Change the count of texture and sampler. It will increase count automatically if we need more textures.
+   *
+   * @param[in] count The number of textures what this texture set want to hold
+   */
+  void SetTextureCount(uint32_t count);
+
+  /**
+   * @brief Change the count of sampler. It will increase count automatically if we need more samplers.
+   *
+   * @param[in] count The number of samplers what this texture set want to hold
+   */
+  void SetSamplerCount(uint32_t count);
+
+  /**
+   * @brief Remove empty textures and samplers at the back of container, and resize.
+   */
+  void TrimContainers();
+
 protected:
   /**
    * A reference counted object may only be deleted by calling Unreference()
index 38bcb5f..2762d44 100644 (file)
@@ -303,8 +303,8 @@ bool Renderer::BindTextures(Graphics::CommandBuffer& commandBuffer)
         //   if it's default, delete the graphics object
         //   otherwise re-initialize it if dirty
 
-        const Graphics::Sampler* graphicsSampler = samplers ? ((*samplers)[i] ? (*samplers)[i]->GetGraphicsObject()
-                                                                              : nullptr)
+        const Graphics::Sampler* graphicsSampler = samplers ? ((i < (*samplers).Size() && (*samplers)[i]) ? (*samplers)[i]->GetGraphicsObject()
+                                                                                                          : nullptr)
                                                             : nullptr;
 
         const Graphics::TextureBinding textureBinding{graphicsTexture, graphicsSampler, textureUnit};
index 80572a7..95aa84c 100644 (file)
@@ -48,6 +48,7 @@ TextureSet* TextureSet::New()
 
 TextureSet::TextureSet()
 : mSamplers(),
+  mTextures(),
   mHasAlpha(false)
 {
 }
@@ -66,11 +67,7 @@ void TextureSet::SetSampler(uint32_t index, Render::Sampler* sampler)
   const uint32_t samplerCount = static_cast<uint32_t>(mSamplers.Size());
   if(samplerCount < index + 1)
   {
-    mSamplers.Resize(index + 1);
-    for(uint32_t i(samplerCount); i <= index; ++i)
-    {
-      mSamplers[i] = nullptr;
-    }
+    SetSamplerCount(index + 1);
   }
 
   mSamplers[index] = sampler;
@@ -86,6 +83,12 @@ void TextureSet::SetSampler(uint32_t index, Render::Sampler* sampler)
     // Construct message in the render queue memory; note that delete should not be called on the return value
     new(slot) DerivedType(&mRenderMessageDispatcher->GetRenderManager(), &RenderManager::SetTextureUpdated, mTextures[index]);
   }
+
+  if(!sampler)
+  {
+    // Check wheter we need to pop back sampler
+    TrimContainers();
+  }
 }
 
 void TextureSet::SetTexture(uint32_t index, const Render::TextureKey& texture)
@@ -93,24 +96,7 @@ void TextureSet::SetTexture(uint32_t index, const Render::TextureKey& texture)
   const uint32_t textureCount = static_cast<uint32_t>(mTextures.Size());
   if(textureCount < index + 1)
   {
-    mTextures.Resize(index + 1);
-
-    bool samplerExist = true;
-    if(mSamplers.Size() < index + 1)
-    {
-      mSamplers.Resize(index + 1);
-      samplerExist = false;
-    }
-
-    for(uint32_t i(textureCount); i <= index; ++i)
-    {
-      mTextures[i] = Render::TextureKey{};
-
-      if(!samplerExist)
-      {
-        mSamplers[i] = nullptr;
-      }
-    }
+    SetTextureCount(index + 1);
   }
 
   mTextures[index] = texture;
@@ -127,6 +113,58 @@ void TextureSet::SetTexture(uint32_t index, const Render::TextureKey& texture)
     // Construct message in the render queue memory; note that delete should not be called on the return value
     new(slot) DerivedType(&mRenderMessageDispatcher->GetRenderManager(), &RenderManager::SetTextureUpdated, texture);
   }
+  else
+  {
+    // Check wheter we need to pop back textures
+    TrimContainers();
+  }
+}
+
+void TextureSet::SetTextureCount(uint32_t count)
+{
+  const uint32_t textureCount = static_cast<uint32_t>(mTextures.Size());
+
+  if(textureCount != count)
+  {
+    mTextures.Resize(count, Render::TextureKey{});
+  }
+}
+
+void TextureSet::SetSamplerCount(uint32_t count)
+{
+  const uint32_t samplerCount = static_cast<uint32_t>(mSamplers.Size());
+
+  if(samplerCount != count)
+  {
+    mSamplers.Resize(count, nullptr);
+  }
+}
+
+void TextureSet::TrimContainers()
+{
+  uint32_t textureCount = static_cast<uint32_t>(mTextures.Size());
+  uint32_t samplerCount = static_cast<uint32_t>(mSamplers.Size());
+
+  while(textureCount > 0u)
+  {
+    if(mTextures[textureCount - 1u])
+    {
+      break;
+    }
+    --textureCount;
+  }
+
+  while(samplerCount > 0u)
+  {
+    if(mSamplers[samplerCount - 1u])
+    {
+      break;
+    }
+    --samplerCount;
+  }
+
+  SetTextureCount(textureCount);
+  SetSamplerCount(samplerCount);
 }
 
 bool TextureSet::HasAlpha() const
index 25336fd..887d4da 100644 (file)
@@ -113,6 +113,26 @@ private:
   TextureSet();
 
 private:
+  /**
+   * @brief Change the count of texture set. It will increase count automatically if we need more textures.
+   *
+   * @param[in] count The number of textures what this texture set want to hold
+   */
+  void SetTextureCount(uint32_t count);
+
+  /**
+   * @brief Change the count of sampler set. It will increase count automatically if we need more samplers.
+   *
+   * @param[in] count The number of samplers what this texture set want to hold
+   */
+  void SetSamplerCount(uint32_t count);
+
+  /**
+   * @brief Remove empty textures and samplers at the back of container, and resize.
+   */
+  void TrimContainers();
+
+private:
   Vector<Render::Sampler*>   mSamplers;                         ///< List of samplers used by each texture. Not owned
   Vector<Render::TextureKey> mTextures;                         ///< List of Textures. Not owned
   RenderMessageDispatcher*   mRenderMessageDispatcher{nullptr}; ///< for sending messages to render thread. Not owned