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;
*/
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
*/
Block(SizeType size)
: nextBlock(nullptr),
+#if defined(__LP64__)
+ mIndexOffset(0),
+#endif
mBlockSize(size)
{
blockMemory = ::operator new(size);
// 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
mBlockIdMask = ((0x01 << bitCount) - 1) << mBlockShift;
mIndexMask = ~mBlockIdMask;
}
+#endif
}
/**
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
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.
};
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;
}
}
// 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)
found = true;
break;
}
- ++blockId;
}
}
else
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;
}
}
/*
- * 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.
// Reset the connector target values
mConnectorTargetValues.clear();
+ mConnectorTargetValuesSortRequired = false;
// Replace the old scene-object with a new one
DestroySceneObject();
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)
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)
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)
{
// 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
}
}
+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
#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.
{
}
+ // 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};
*/
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>;
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
/*
- * 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.
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());
}
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);
// 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);
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);
}
* @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
/*
- * 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.
{
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),
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)
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;
}
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);
#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.
// 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>
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();
* 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
// VertexBuffers
Vector<Render::VertexBuffer*> mVertexBuffers;
- Dali::Vector<uint16_t> mIndices;
+ Uint16ContainerType mIndices;
OwnerPointer<GpuBuffer> mIndexBuffer;
+ IndexType mIndexType;
Type mGeometryType;
// Booleans
mState(Stopped),
mProgressReachedSignalRequired(false),
mAutoReverseEnabled(false),
+ mAnimatorSortRequired(false),
mIsActive{false}
{
}
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;
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());
}
{
//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);
}
}
#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.
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)
};
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));
* @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
}
// 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)
}
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));
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);
#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.
void RemoveVertexBuffer(std::size_t index);
/**
- * @brief Sets a 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.
*
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