Merge "Make mTargetSizeDirtyFlag true when Animation changes Actor's Size" into devel...
authorSeungho BAEK <sbsh.baek@samsung.com>
Mon, 27 Feb 2023 23:08:32 +0000 (23:08 +0000)
committerGerrit Code Review <gerrit@review>
Mon, 27 Feb 2023 23:08:32 +0000 (23:08 +0000)
17 files changed:
automated-tests/src/dali/utc-Dali-Geometry.cpp
dali/internal/common/fixed-size-memory-pool.cpp
dali/internal/event/animation/animation-impl.cpp
dali/internal/event/animation/animation-impl.h
dali/internal/event/rendering/geometry-impl.cpp
dali/internal/event/rendering/geometry-impl.h
dali/internal/event/rendering/vertex-buffer-impl.cpp
dali/internal/render/common/render-manager.cpp
dali/internal/render/common/render-manager.h
dali/internal/render/renderers/render-geometry.cpp
dali/internal/render/renderers/render-geometry.h
dali/internal/update/animation/scene-graph-animation.cpp
dali/internal/update/animation/scene-graph-animation.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-manager.h
dali/public-api/rendering/geometry.cpp
dali/public-api/rendering/geometry.h

index 3654fdd..2243872 100644 (file)
@@ -351,6 +351,65 @@ int UtcDaliGeometrySetIndexBuffer(void)
   END_TEST;
 }
 
+int UtcDaliGeometrySetIndexBuffer32Bits(void)
+{
+  TestApplication application;
+  auto&           bufferTrace = application.GetGlAbstraction().GetBufferTrace();
+  bufferTrace.Enable(true);
+  bufferTrace.EnableLogging(true);
+
+  tet_infoline("Test SetIndexBuffer 32Bits");
+
+  VertexBuffer vertexBuffer = CreateVertexBuffer("aPosition", "aTexCoord");
+
+  Geometry geometry = Geometry::New();
+  geometry.AddVertexBuffer(vertexBuffer);
+
+  Shader   shader   = CreateShader();
+  Renderer renderer = Renderer::New(geometry, shader);
+  Actor    actor    = Actor::New();
+  actor.SetProperty(Actor::Property::SIZE, Vector3::ONE * 100.f);
+  actor.AddRenderer(renderer);
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+  application.Render(0);
+  application.Render();
+  application.SendNotification();
+
+  {
+    const TestGlAbstraction::BufferDataCalls& bufferDataCalls =
+      application.GetGlAbstraction().GetBufferDataCalls();
+
+    DALI_TEST_EQUALS(bufferDataCalls.size(), 3u, TEST_LOCATION);
+
+    DALI_TEST_EQUALS(bufferDataCalls[0], 4 * sizeof(TexturedQuadVertex), TEST_LOCATION);
+  }
+
+  // Set index buffer
+  application.GetGlAbstraction().ResetBufferDataCalls();
+
+  const uint32_t indexData32Bits[6] = {0, 3, 1, 0, 2, 3};
+  geometry.SetIndexBuffer(indexData32Bits, sizeof(indexData32Bits) / sizeof(indexData32Bits[0]));
+  application.SendNotification();
+  application.Render(0);
+  application.Render();
+  application.SendNotification();
+
+  {
+    const TestGlAbstraction::BufferDataCalls& bufferDataCalls =
+      application.GetGlAbstraction().GetBufferDataCalls();
+
+    //Only the index buffer should be uploaded
+    DALI_TEST_EQUALS(bufferDataCalls.size(), 1u, TEST_LOCATION);
+
+    // should be unsigned int instead of unsigned short
+    DALI_TEST_EQUALS(bufferDataCalls[0], 6 * sizeof(uint32_t), TEST_LOCATION);
+  }
+
+  END_TEST;
+}
+
 int UtcDaliGeometrySetGetGeometryType01(void)
 {
   TestApplication application;
index 878755c..44e0fd3 100644 (file)
@@ -40,9 +40,12 @@ struct FixedSizeMemoryPool::Impl
    */
   struct Block
   {
-    void*    blockMemory; ///< The allocated memory from which allocations can be made
-    Block*   nextBlock;   ///< The next block in the linked list
-    SizeType mBlockSize;  ///< Size of the block in bytes
+    void*  blockMemory; ///< The allocated memory from which allocations can be made
+    Block* nextBlock;   ///< The next block in the linked list
+#if defined(__LP64__)
+    KeyType mIndexOffset; ///< The Offset of this block's index
+#endif
+    SizeType mBlockSize; ///< Size of the block in bytes
 
     /**
      * @brief Construct a new block with given size
@@ -51,6 +54,9 @@ struct FixedSizeMemoryPool::Impl
      */
     Block(SizeType size)
     : nextBlock(nullptr),
+#if defined(__LP64__)
+      mIndexOffset(0),
+#endif
       mBlockSize(size)
     {
       blockMemory = ::operator new(size);
@@ -90,6 +96,7 @@ struct FixedSizeMemoryPool::Impl
     // We need enough room to store the deleted list in the data
     DALI_ASSERT_DEBUG(mFixedSize >= sizeof(void*));
 
+#if defined(__LP64__)
     if(mMaximumBlockCount < 0xffffffff)
     {
       // Only use mBlocks for key/ptr conversion with max number of blocks
@@ -102,6 +109,7 @@ struct FixedSizeMemoryPool::Impl
       mBlockIdMask = ((0x01 << bitCount) - 1) << mBlockShift;
       mIndexMask   = ~mBlockIdMask;
     }
+#endif
   }
 
   /**
@@ -134,17 +142,48 @@ struct FixedSizeMemoryPool::Impl
     mCurrentBlockCapacity = size;
 
     // Allocate
-    Block* block             = new Block(mCurrentBlockCapacity * mFixedSize);
-    mCurrentBlock->nextBlock = block; // Add to end of linked list
-    mCurrentBlock            = block;
-
-    mCurrentBlockSize = 0;
+    Block* block = new Block(mCurrentBlockCapacity * mFixedSize);
 
-    // Add to main list of blocks
-    if(mBlockShift)
+#if defined(__LP64__)
+    if(mBlockShift) // Key contains block id & index within block
     {
+      // Add to main list of blocks
       mBlocks.push_back(block);
+#endif
+      mCurrentBlock->nextBlock = block; // Add end of linked list
+      mCurrentBlock            = block;
+#if defined(__LP64__)
     }
+    else
+    {
+      // Heuristic optimization. Make bigger block positioned at front, instead of header.
+      // (Since change the Block value might be heavy)
+      if(mCurrentBlock == &mMemoryBlocks)
+      {
+        block->mIndexOffset = mMemoryBlocks.mBlockSize / mFixedSize;
+
+        // Add to end of linked list.
+        // Now mCurrentBlock is next block of header.
+        mCurrentBlock->nextBlock = block;
+        mCurrentBlock            = block;
+      }
+      else
+      {
+        block->mIndexOffset = mCurrentBlock->mIndexOffset + (mCurrentBlock->mBlockSize / mFixedSize);
+
+        // Add new block as next of header.
+        mMemoryBlocks.nextBlock = block;
+
+        // Make previous mCurrentBlock as next of new block.
+        block->nextBlock = mCurrentBlock;
+
+        // Keep mCurrentBlock is next block of mMemoryBlocks.
+        mCurrentBlock = block;
+      }
+    }
+#endif
+
+    mCurrentBlockSize = 0;
   }
 #ifdef DEBUG_ENABLED
 
@@ -179,16 +218,20 @@ struct FixedSizeMemoryPool::Impl
   Block    mMemoryBlocks;         ///< Linked list of allocated memory blocks
   SizeType mMaximumBlockCapacity; ///< The maximum allowed capacity of allocations in a new memory block
 
+#if defined(__LP64__)
   std::vector<Block*> mBlocks; ///< Address of each allocated block
+#endif
 
   Block*   mCurrentBlock;         ///< Pointer to the active block
   SizeType mCurrentBlockCapacity; ///< The maximum number of allocations that can be allocated for the current block
   SizeType mCurrentBlockSize;     ///< The number of allocations allocated to the current block
 
   SizeType mMaximumBlockCount{0xffffffff}; ///< Maximum number of blocks (or unlimited)
-  SizeType mBlockShift{0x0};               ///< number of bits to shift block id in key
-  SizeType mBlockIdMask{0x0};              ///< mask for key conversion
-  SizeType mIndexMask{0xffffffff};         ///< mask for key conversion
+#if defined(__LP64__)
+  SizeType mBlockShift{0x0};       ///< number of bits to shift block id in key
+  SizeType mBlockIdMask{0x0};      ///< mask for key conversion
+  SizeType mIndexMask{0xffffffff}; ///< mask for key conversion
+#endif
 
   void* mDeletedObjects; ///< Pointer to the head of the list of deleted objects. The addresses are stored in the allocated memory blocks.
 };
@@ -281,12 +324,12 @@ void* FixedSizeMemoryPool::GetPtrFromKey(FixedSizeMemoryPool::KeyType key)
     Impl::Block* block = &mImpl->mMemoryBlocks;
     while(block != nullptr)
     {
+      const uint32_t indexOffset   = block->mIndexOffset;
       const SizeType numberOfItems = (block->mBlockSize) / mImpl->mFixedSize;
-      if(index < numberOfItems)
+      if(indexOffset <= index && index < indexOffset + numberOfItems)
       {
-        return static_cast<uint8_t*>(block->blockMemory) + mImpl->mFixedSize * index;
+        return static_cast<uint8_t*>(block->blockMemory) + mImpl->mFixedSize * (index - indexOffset);
       }
-      index -= numberOfItems;
       block = block->nextBlock;
     }
   }
@@ -307,8 +350,13 @@ FixedSizeMemoryPool::KeyType FixedSizeMemoryPool::GetKeyFromPtr(void* ptr)
   // If block count is limited, the bit shift is non-zero.
   if(DALI_LIKELY(mImpl->mBlockShift))
   {
-    for(auto block : mImpl->mBlocks)
+    // Iterate backward so we can search at bigger blocks first.
+    blockId = mImpl->mBlocks.size();
+    for(auto iter = mImpl->mBlocks.rbegin(), iterEnd = mImpl->mBlocks.rend(); iter != iterEnd; ++iter)
     {
+      --blockId;
+      auto* block = *iter;
+
       const void* const endOfBlock = reinterpret_cast<char*>(block->blockMemory) + block->mBlockSize;
 
       if(block->blockMemory <= ptr && ptr < endOfBlock)
@@ -317,7 +365,6 @@ FixedSizeMemoryPool::KeyType FixedSizeMemoryPool::GetKeyFromPtr(void* ptr)
         found = true;
         break;
       }
-      ++blockId;
     }
   }
   else
@@ -330,11 +377,10 @@ FixedSizeMemoryPool::KeyType FixedSizeMemoryPool::GetKeyFromPtr(void* ptr)
 
       if(block->blockMemory <= ptr && ptr < endOfBlock)
       {
-        index += (static_cast<uint8_t*>(ptr) - static_cast<uint8_t*>(block->blockMemory)) / mImpl->mFixedSize;
+        index = block->mIndexOffset + (static_cast<uint8_t*>(ptr) - static_cast<uint8_t*>(block->blockMemory)) / mImpl->mFixedSize;
         found = true;
         break;
       }
-      index += block->mBlockSize / mImpl->mFixedSize;
       block = block->nextBlock;
     }
   }
index 6fdf660..60e54f9 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.
@@ -393,6 +393,7 @@ void Animation::Clear()
 
   // Reset the connector target values
   mConnectorTargetValues.clear();
+  mConnectorTargetValuesSortRequired = false;
 
   // Replace the old scene-object with a new one
   DestroySceneObject();
@@ -523,8 +524,8 @@ void Animation::AnimateBy(Property& target, Property::Value relativeValue, Alpha
       DALI_ASSERT_DEBUG(false && "Property  not supported");
     }
   }
-  // Store data to later notify the object that its property is being animated
-  mConnectorTargetValues.push_back({std::move(relativeValue), period, connectorIndex, Animation::BY});
+
+  AppendConnectorTargetValues({std::move(relativeValue), period, connectorIndex, Animation::BY});
 }
 
 void Animation::AnimateTo(Property& target, Property::Value destinationValue)
@@ -643,8 +644,8 @@ void Animation::AnimateTo(Property& target, Property::Value destinationValue, Al
       DALI_ASSERT_DEBUG(false && "Property  not supported");
     }
   }
-  // Store data to later notify the object that its property is being animated
-  mConnectorTargetValues.push_back({std::move(destinationValue), period, connectorIndex, Animation::TO});
+
+  AppendConnectorTargetValues({std::move(destinationValue), period, connectorIndex, Animation::TO});
 }
 
 void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames)
@@ -695,8 +696,7 @@ void Animation::AnimateBetween(Property target, const KeyFrames& keyFrames, Alph
 
   ExtendDuration(period);
 
-  // Store data to later notify the object that its property is being animated
-  mConnectorTargetValues.push_back({keyFrames.GetLastKeyFrameValue(), period, mConnectors.Count(), BETWEEN});
+  AppendConnectorTargetValues({keyFrames.GetLastKeyFrameValue(), period, mConnectors.Count(), BETWEEN});
 
   // using destination type so component animation gets correct type
   switch(destinationType)
@@ -1058,9 +1058,12 @@ void Animation::NotifyObjects(Animation::Notify notifyValueType)
   {
     // Sort according to end time with earlier end times coming first, if the end time is the same, then the connectors are not moved
     // Only do this if we're using the target value
-    if(notifyValueType == Notify::USE_TARGET_VALUE)
+    if(mConnectorTargetValuesSortRequired && notifyValueType == Notify::USE_TARGET_VALUE)
     {
       std::stable_sort(mConnectorTargetValues.begin(), mConnectorTargetValues.end(), CompareConnectorEndTimes);
+
+      // Now mConnectorTargetValues sorted. Reset flag.
+      mConnectorTargetValuesSortRequired = false;
     }
 
     // Loop through all connector target values sorted by increasing end time
@@ -1093,6 +1096,22 @@ void Animation::SendFinalProgressNotificationMessage()
   }
 }
 
+void Animation::AppendConnectorTargetValues(ConnectorTargetValues&& connectorTargetValues)
+{
+  // Check whether we need to sort mConnectorTargetValues or not.
+  // Sort will be required only if new item is smaller than last value of container.
+  if(!mConnectorTargetValuesSortRequired && !mConnectorTargetValues.empty())
+  {
+    if(CompareConnectorEndTimes(connectorTargetValues, mConnectorTargetValues.back()))
+    {
+      mConnectorTargetValuesSortRequired = true;
+    }
+  }
+
+  // Store data to later notify the object that its property is being animated
+  mConnectorTargetValues.push_back(std::move(connectorTargetValues));
+}
+
 } // namespace Internal
 
 } // namespace Dali
index 410929b..966638e 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_ANIMATION_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.
@@ -479,6 +479,24 @@ private:
     {
     }
 
+    // Move operations
+    ConnectorTargetValues(ConnectorTargetValues&& rhs) noexcept
+    : targetValue(std::move(rhs.targetValue)),
+      timePeriod(std::move(rhs.timePeriod)),
+      connectorIndex(rhs.connectorIndex),
+      animatorType(rhs.animatorType)
+    {
+    }
+
+    ConnectorTargetValues& operator=(ConnectorTargetValues&& rhs) noexcept
+    {
+      targetValue    = std::move(rhs.targetValue);
+      timePeriod     = std::move(rhs.timePeriod);
+      connectorIndex = rhs.connectorIndex;
+      animatorType   = rhs.animatorType;
+      return *this;
+    }
+
     Property::Value targetValue;
     TimePeriod      timePeriod{0.f};
     std::size_t     connectorIndex{0};
@@ -512,6 +530,13 @@ private:
    */
   void SendFinalProgressNotificationMessage();
 
+  /**
+   * @brief Append ConnectorTargetValues into the container.
+   *
+   * @param[in] connectorTargetValues moved ConnectorTargetValues that will be append end of container
+   */
+  void AppendConnectorTargetValues(ConnectorTargetValues&& connectorTargetValues);
+
 private:
   using AnimatorConnectorContainer     = OwnerContainer<AnimatorConnectorBase*>;
   using ConnectorTargetValuesContainer = std::vector<ConnectorTargetValues>;
@@ -539,7 +564,8 @@ private:
   EndAction              mEndAction;
   EndAction              mDisconnectAction;
   Dali::Animation::State mState{Dali::Animation::STOPPED};
-  bool                   mAutoReverseEnabled{false}; ///< Flag to identify that the looping mode is auto reverse.
+  bool                   mAutoReverseEnabled{false};                ///< Flag to identify that the looping mode is auto reverse.
+  bool                   mConnectorTargetValuesSortRequired{false}; ///< Flag to whether we need to sort mConnectorTargetValues or not
 };
 
 } // namespace Internal
index 4b6ee13..3ec6362 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.
@@ -56,10 +56,22 @@ void Geometry::RemoveVertexBuffer(uint32_t index)
 
 void Geometry::SetIndexBuffer(const uint16_t* indices, uint32_t count)
 {
-  Dali::Vector<uint16_t> indexData;
+  Render::Geometry::Uint16ContainerType indexData;
   if(indices && count)
   {
-    indexData.Resize(count);
+    indexData.ResizeUninitialized(count);
+    std::copy(indices, indices + count, indexData.Begin());
+  }
+
+  SceneGraph::SetIndexBufferMessage(mEventThreadServices.GetUpdateManager(), *mRenderObject, indexData);
+}
+
+void Geometry::SetIndexBuffer(const uint32_t* indices, uint32_t count)
+{
+  Render::Geometry::Uint32ContainerType indexData;
+  if(indices && count)
+  {
+    indexData.ResizeUninitialized(count);
     std::copy(indices, indices + count, indexData.Begin());
   }
 
index 4663727..261ca3c 100644 (file)
@@ -76,6 +76,11 @@ public:
   void SetIndexBuffer(const uint16_t* indices, uint32_t count);
 
   /**
+   * @copydoc Dali::Geometry::SetIndexBuffer()
+   */
+  void SetIndexBuffer(const uint32_t* indices, uint32_t count);
+
+  /**
    * @copydoc Dali::Geometry::SetType()
    */
   void SetType(Dali::Geometry::Type geometryType);
index 462fc9c..689d703 100644 (file)
@@ -155,7 +155,7 @@ void VertexBuffer::SetData(const void* data, uint32_t size)
   // create a new DALi vector to store the buffer data
   // the heap allocated vector will end up being owned by Render::VertexBuffer
   OwnerPointer<Vector<uint8_t> > bufferCopy = new Dali::Vector<uint8_t>();
-  bufferCopy->Resize(bufferSize);
+  bufferCopy->ResizeUninitialized(bufferSize);
 
   // copy the data
   const uint8_t* source      = static_cast<const uint8_t*>(data);
index e54741f..b72ec9b 100644 (file)
@@ -369,7 +369,12 @@ void RenderManager::SetVertexBufferData(Render::VertexBuffer* vertexBuffer, Owne
   vertexBuffer->SetData(data.Release(), size);
 }
 
-void RenderManager::SetIndexBuffer(Render::Geometry* geometry, Dali::Vector<uint16_t>& indices)
+void RenderManager::SetIndexBuffer(Render::Geometry* geometry, Render::Geometry::Uint16ContainerType& indices)
+{
+  geometry->SetIndexBuffer(indices);
+}
+
+void RenderManager::SetIndexBuffer(Render::Geometry* geometry, Render::Geometry::Uint32ContainerType& indices)
 {
   geometry->SetIndexBuffer(indices);
 }
index 7f4843f..cf40117 100644 (file)
@@ -211,7 +211,14 @@ public:
    * @param[in] geometry The geometry
    * @param[in] data A vector containing the indices
    */
-  void SetIndexBuffer(Render::Geometry* geometry, Dali::Vector<uint16_t>& data);
+  void SetIndexBuffer(Render::Geometry* geometry, Render::Geometry::Uint16ContainerType& data);
+
+  /**
+   * Sets the data for the index buffer of an existing geometry
+   * @param[in] geometry The geometry
+   * @param[in] data A vector containing the indices
+   */
+  void SetIndexBuffer(Render::Geometry* geometry, Render::Geometry::Uint32ContainerType& data);
 
   /**
    * Set the geometry type of an existing render geometry
index e12f37b..feb6244 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.
@@ -28,9 +28,32 @@ namespace Internal
 {
 namespace Render
 {
+namespace
+{
+inline constexpr size_t GetSizeOfIndexFromIndexType(Dali::Graphics::Format graphicsFormat)
+{
+  switch(graphicsFormat)
+  {
+    case Dali::Graphics::Format::R16_UINT:
+    {
+      return sizeof(uint16_t);
+    }
+    case Dali::Graphics::Format::R32_UINT:
+    {
+      return sizeof(uint32_t);
+    }
+    default:
+    {
+      // TODO : Not implmeneted.
+      return sizeof(uint16_t);
+    }
+  }
+}
+} // unnamed namespace
 Geometry::Geometry()
 : mIndices(),
   mIndexBuffer(nullptr),
+  mIndexType(Dali::Graphics::Format::R16_UINT),
   mGeometryType(Dali::Geometry::TRIANGLES),
   mIndicesChanged(false),
   mHasBeenUpdated(false),
@@ -51,10 +74,20 @@ const Vector<Render::VertexBuffer*>& Geometry::GetVertexBuffers() const
   return mVertexBuffers;
 }
 
-void Geometry::SetIndexBuffer(Dali::Vector<uint16_t>& indices)
+void Geometry::SetIndexBuffer(Uint16ContainerType& indices)
 {
   mIndices.Swap(indices);
   mIndicesChanged = true;
+  mIndexType      = Graphics::Format::R16_UINT;
+}
+
+void Geometry::SetIndexBuffer(Uint32ContainerType& indices)
+{
+  // mIndices type is not matched with indices. Copy memory hardly.
+  mIndices.ResizeUninitialized(indices.Count() * 2);
+  memcpy(mIndices.Begin(), indices.Begin(), indices.Count() * sizeof(uint32_t));
+  mIndicesChanged = true;
+  mIndexType      = Graphics::Format::R32_UINT;
 }
 
 void Geometry::RemoveVertexBuffer(const Render::VertexBuffer* vertexBuffer)
@@ -154,12 +187,14 @@ bool Geometry::Draw(
   intptr_t firstIndexOffset(0u);
   if(mIndexBuffer)
   {
-    numIndices = static_cast<uint32_t>(mIndices.Size());
+    std::size_t sizeOfIndex = GetSizeOfIndexFromIndexType(mIndexType);
+
+    numIndices = static_cast<uint32_t>(mIndices.Size() * sizeof(uint16_t) / sizeOfIndex);
 
     if(elementBufferOffset != 0u)
     {
       elementBufferOffset = (elementBufferOffset >= numIndices) ? numIndices - 1 : elementBufferOffset;
-      firstIndexOffset    = intptr_t(elementBufferOffset * sizeof(uint16_t));
+      firstIndexOffset    = intptr_t(elementBufferOffset * sizeOfIndex);
       numIndices -= elementBufferOffset;
     }
 
@@ -176,7 +211,7 @@ bool Geometry::Draw(
     const Graphics::Buffer* ibo = mIndexBuffer->GetGraphicsObject();
     if(ibo)
     {
-      commandBuffer.BindIndexBuffer(*ibo, 0, Graphics::Format::R16_UINT);
+      commandBuffer.BindIndexBuffer(*ibo, 0, mIndexType);
     }
 
     commandBuffer.DrawIndexed(numIndices, 1, firstIndexOffset, 0, 0);
index 54d9ee4..a23c7a0 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_RENDER_GEOMETRY_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.
@@ -20,6 +20,7 @@
 // INTERNAL INCLUDES
 #include <dali/devel-api/common/owner-container.h>
 #include <dali/graphics-api/graphics-controller.h>
+#include <dali/graphics-api/graphics-types.h>
 #include <dali/internal/common/buffer-index.h>
 #include <dali/internal/common/owner-pointer.h>
 #include <dali/public-api/common/dali-vector.h>
@@ -44,7 +45,11 @@ class VertexBuffer;
 class Geometry
 {
 public:
-  using Type = Dali::Geometry::Type;
+  using Type      = Dali::Geometry::Type;
+  using IndexType = Dali::Graphics::Format;
+
+  using Uint16ContainerType = Dali::Vector<uint16_t>;
+  using Uint32ContainerType = Dali::Vector<uint32_t>;
 
   Geometry();
 
@@ -63,7 +68,13 @@ public:
    * Set the data for the index buffer to be used by the geometry
    * @param[in] indices A vector containing the indices
    */
-  void SetIndexBuffer(Dali::Vector<uint16_t>& indices);
+  void SetIndexBuffer(Uint16ContainerType& indices);
+
+  /**
+   * Set the data for the index buffer to be used by the geometry
+   * @param[in] indices A vector containing the indices
+   */
+  void SetIndexBuffer(Uint32ContainerType& indices);
 
   /**
    * Removes a VertexBuffer from the geometry
@@ -128,8 +139,9 @@ private:
   // VertexBuffers
   Vector<Render::VertexBuffer*> mVertexBuffers;
 
-  Dali::Vector<uint16_t>  mIndices;
+  Uint16ContainerType     mIndices;
   OwnerPointer<GpuBuffer> mIndexBuffer;
+  IndexType               mIndexType;
   Type                    mGeometryType;
 
   // Booleans
index 659547f..ec26435 100644 (file)
@@ -80,6 +80,7 @@ Animation::Animation(float durationSeconds, float speedFactor, const Vector2& pl
   mState(Stopped),
   mProgressReachedSignalRequired(false),
   mAutoReverseEnabled(false),
+  mAnimatorSortRequired(false),
   mIsActive{false}
 {
 }
@@ -151,8 +152,12 @@ void Animation::SetPlayRange(const Vector2& range)
 
 void Animation::Play()
 {
-  // Sort according to end time with earlier end times coming first, if the end time is the same, then the animators are not moved
-  std::stable_sort(mAnimators.Begin(), mAnimators.End(), CompareAnimatorEndTimes);
+  if(mAnimatorSortRequired)
+  {
+    // Sort according to end time with earlier end times coming first, if the end time is the same, then the animators are not moved
+    std::stable_sort(mAnimators.Begin(), mAnimators.End(), CompareAnimatorEndTimes);
+    mAnimatorSortRequired = false;
+  }
 
   mState = Playing;
 
@@ -299,6 +304,16 @@ void Animation::AddAnimator(OwnerPointer<AnimatorBase>& animator)
   animator->ConnectToSceneGraph();
   animator->SetDisconnectAction(mDisconnectAction);
 
+  // Check whether we need to sort mAnimators or not.
+  // Sort will be required only if new item is smaller than last value of container.
+  if(!mAnimatorSortRequired && !mAnimators.Empty())
+  {
+    if(CompareAnimatorEndTimes(animator.Get(), *(mAnimators.End() - 1u)))
+    {
+      mAnimatorSortRequired = true;
+    }
+  }
+
   mAnimators.PushBack(animator.Release());
 }
 
@@ -485,6 +500,10 @@ void Animation::UpdateAnimators(BufferIndex bufferIndex, bool bake, bool animati
   {
     //Remove animators whose PropertyOwner has been destroyed
     mAnimators.EraseIf([](auto& animator) { return animator->Orphan(); });
+
+    // Need to be re-sort if remained animators size is bigger than one.
+    // Note that if animator contains only zero or one items, It is already sorted case.
+    mAnimatorSortRequired = (mAnimators.Count() >= 2);
   }
 }
 
index 4119c15..6ae8fdd 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_SCENE_GRAPH_ANIMATION_H
 
 /*
- * Copyright (c) 2022 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.
@@ -352,6 +352,7 @@ protected:
 
   bool mProgressReachedSignalRequired; // Flag to indicate the progress marker was hit
   bool mAutoReverseEnabled;            // Flag to identify that the looping mode is auto reverse.
+  bool mAnimatorSortRequired;          // Flag to whether we need to sort animator or not.
   bool mIsActive[2];                   // Flag to indicate whether the animation is active in the current frame (which is double buffered)
 };
 
index 778a758..5b3bf16 100644 (file)
@@ -1390,9 +1390,20 @@ void UpdateManager::SetGeometryType(Render::Geometry* geometry, uint32_t geometr
   new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType);
 }
 
-void UpdateManager::SetIndexBuffer(Render::Geometry* geometry, Dali::Vector<uint16_t>& indices)
+void UpdateManager::SetIndexBuffer(Render::Geometry* geometry, Render::Geometry::Uint16ContainerType& indices)
 {
-  using DerivedType = IndexBufferMessage<RenderManager>;
+  using DerivedType = IndexBufferMessage<RenderManager, Render::Geometry::Uint16ContainerType>;
+
+  // Reserve some memory inside the render queue
+  uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
+
+  // Construct message in the render queue memory; note that delete should not be called on the return value
+  new(slot) DerivedType(&mImpl->renderManager, geometry, indices);
+}
+
+void UpdateManager::SetIndexBuffer(Render::Geometry* geometry, Render::Geometry::Uint32ContainerType& indices)
+{
+  using DerivedType = IndexBufferMessage<RenderManager, Render::Geometry::Uint32ContainerType>;
 
   // Reserve some memory inside the render queue
   uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
index ee5cf87..aacfe23 100644 (file)
@@ -498,7 +498,14 @@ public:
    * @param[in] geometry The geometry
    * @param[in] indices A vector containing the indices for the geometry
    */
-  void SetIndexBuffer(Render::Geometry* geometry, Dali::Vector<uint16_t>& indices);
+  void SetIndexBuffer(Render::Geometry* geometry, Render::Geometry::Uint16ContainerType& indices);
+
+  /**
+   * Sets the index buffer to be used by a geometry
+   * @param[in] geometry The geometry
+   * @param[in] indices A vector containing the indices for the geometry
+   */
+  void SetIndexBuffer(Render::Geometry* geometry, Render::Geometry::Uint32ContainerType& indices);
 
   /**
    * Adds a vertex buffer to a geometry
@@ -1297,14 +1304,14 @@ inline void RemoveVertexBufferMessage(UpdateManager& manager, Render::Geometry&
 }
 
 // Custom message type for SetIndexBuffer() used to move data with Vector::Swap()
-template<typename T>
+template<typename T, typename IndexContainerType>
 class IndexBufferMessage : public MessageBase
 {
 public:
   /**
    * Constructor which does a Vector::Swap()
    */
-  IndexBufferMessage(T* manager, Render::Geometry* geometry, Dali::Vector<uint16_t>& indices)
+  IndexBufferMessage(T* manager, Render::Geometry* geometry, IndexContainerType& indices)
   : MessageBase(),
     mManager(manager),
     mRenderGeometry(geometry)
@@ -1327,14 +1334,25 @@ public:
   }
 
 private:
-  T*                     mManager;
-  Render::Geometry*      mRenderGeometry;
-  Dali::Vector<uint16_t> mIndices;
+  T*                 mManager;
+  Render::Geometry*  mRenderGeometry;
+  IndexContainerType mIndices;
 };
 
-inline void SetIndexBufferMessage(UpdateManager& manager, Render::Geometry& geometry, Dali::Vector<uint16_t>& indices)
+inline void SetIndexBufferMessage(UpdateManager& manager, Render::Geometry& geometry, Render::Geometry::Uint16ContainerType& indices)
+{
+  using LocalType = IndexBufferMessage<UpdateManager, Render::Geometry::Uint16ContainerType>;
+
+  // Reserve some memory inside the message queue
+  uint32_t* slot = manager.ReserveMessageSlot(sizeof(LocalType));
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new(slot) LocalType(&manager, &geometry, indices);
+}
+
+inline void SetIndexBufferMessage(UpdateManager& manager, Render::Geometry& geometry, Render::Geometry::Uint32ContainerType& indices)
 {
-  using LocalType = IndexBufferMessage<UpdateManager>;
+  using LocalType = IndexBufferMessage<UpdateManager, Render::Geometry::Uint32ContainerType>;
 
   // Reserve some memory inside the message queue
   uint32_t* slot = manager.ReserveMessageSlot(sizeof(LocalType));
index 6c82097..a810779 100644 (file)
@@ -67,6 +67,11 @@ void Geometry::SetIndexBuffer(const uint16_t* indices, size_t count)
   GetImplementation(*this).SetIndexBuffer(indices, static_cast<uint32_t>(count));
 }
 
+void Geometry::SetIndexBuffer(const uint32_t* indices, size_t count)
+{
+  GetImplementation(*this).SetIndexBuffer(indices, static_cast<uint32_t>(count));
+}
+
 void Geometry::SetType(Type geometryType)
 {
   GetImplementation(*this).SetType(geometryType);
index cfb0f15..81e0421 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_GEOMETRY_H
 
 /*
- * Copyright (c) 2020 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.
@@ -156,7 +156,7 @@ public:
   void RemoveVertexBuffer(std::size_t index);
 
   /**
-   * @brief Sets the index data to be used as a source of indices for the geometry
+   * @brief Sets the index data to be used as a source of indices for the geometry
    * Setting this buffer will cause the geometry to be rendered using indices.
    * To unset call SetIndexBuffer with a null pointer or count 0.
    *
@@ -167,6 +167,17 @@ public:
   void SetIndexBuffer(const uint16_t* indices, size_t count);
 
   /**
+   * @brief Sets the 32bits index data to be used as a source of indices for the geometry
+   * Setting this buffer will cause the geometry to be rendered using indices.
+   * To unset call SetIndexBuffer with a null pointer or count 0.
+   *
+   * @SINCE_2_2.16
+   * @param[in] indices Array of indices with uint32_t elements.
+   * @param[in] count Number of indices in the array
+   */
+  void SetIndexBuffer(const uint32_t* indices, size_t count);
+
+  /**
    * @brief Sets the type of primitives this geometry contains.
    *
    * @SINCE_1_1.43