From bf3272d90cfeef8b36e3b71c30e0f2200c897a73 Mon Sep 17 00:00:00 2001 From: David Steele Date: Fri, 21 Oct 2022 12:10:35 +0100 Subject: [PATCH] Convert Renderer ptrs to 32 bit keys Change-Id: I9ac5971cd768da552c188909771a12b437e11435 --- dali/internal/common/fixed-size-memory-pool.cpp | 63 ++++++ dali/internal/common/fixed-size-memory-pool.h | 4 + .../internal/common/memory-pool-object-allocator.h | 14 ++ .../rendering/decorated-visual-renderer-impl.cpp | 7 +- dali/internal/event/rendering/renderer-impl.cpp | 12 +- .../event/rendering/visual-renderer-impl.cpp | 8 +- dali/internal/update/common/discard-queue.h | 8 - dali/internal/update/manager/owner-key-container.h | 236 +++++++++++++++++++++ .../update/manager/render-task-processor.cpp | 5 +- dali/internal/update/manager/update-algorithms.cpp | 3 +- dali/internal/update/manager/update-manager.cpp | 55 +++-- dali/internal/update/manager/update-manager.h | 16 +- dali/internal/update/nodes/node.cpp | 16 +- dali/internal/update/nodes/node.h | 16 +- .../update/rendering/scene-graph-renderer.cpp | 25 +++ .../update/rendering/scene-graph-renderer.h | 15 +- 16 files changed, 441 insertions(+), 62 deletions(-) create mode 100644 dali/internal/update/manager/owner-key-container.h diff --git a/dali/internal/common/fixed-size-memory-pool.cpp b/dali/internal/common/fixed-size-memory-pool.cpp index f225a8d..6c7a7b1 100644 --- a/dali/internal/common/fixed-size-memory-pool.cpp +++ b/dali/internal/common/fixed-size-memory-pool.cpp @@ -26,6 +26,10 @@ namespace Dali { namespace Internal { +const uint32_t POOL_KEY_BLOCK_ID_MASK = 0xF8000000; +const uint32_t POOL_KEY_BLOCK_ID_SHIFT = 27; +const uint32_t POOL_KEY_INDEX_MASK = 0x07FFFFFF; + /** * @brief Private implementation class */ @@ -231,6 +235,50 @@ void FixedSizeMemoryPool::FreeThreadSafe(void* memory) } } +void* FixedSizeMemoryPool::GetPtrToObject(uint32_t key) +{ + uint32_t blockId = (key & POOL_KEY_BLOCK_ID_MASK) >> POOL_KEY_BLOCK_ID_SHIFT; + uint32_t index = key & POOL_KEY_INDEX_MASK; + auto* block = &mImpl->mMemoryBlocks; + while(block && blockId > 0) + { + block = block->nextBlock; + --blockId; + } + if(block != nullptr) + { + return static_cast(block->blockMemory) + mImpl->mFixedSize * index; + } + return nullptr; +} + +uint32_t FixedSizeMemoryPool::GetIndexOfObject(void* ptr) +{ + uint32_t blockId = 0; + uint32_t index = 0; + auto* block = &mImpl->mMemoryBlocks; + bool found = false; + + while(block) + { + const void* const endOfBlock = reinterpret_cast(block->blockMemory) + block->mBlockSize; + if(block->blockMemory <= ptr && ptr <= endOfBlock) + { + index = (static_cast(ptr) - static_cast(block->blockMemory)) / mImpl->mFixedSize; + found = true; + break; + } + + block = block->nextBlock; + ++blockId; + } + if(found) + { + return blockId << POOL_KEY_BLOCK_ID_SHIFT | (index & POOL_KEY_INDEX_MASK); + } + return 0u; +} + uint32_t FixedSizeMemoryPool::GetCapacity() const { // Ignores deleted objects list, just returns currently allocated size @@ -247,6 +295,21 @@ uint32_t FixedSizeMemoryPool::GetCapacity() const return totalAllocation; } +/* + * + * Or, don't use index, create a key, which combines block id & offset in block... + * e.g. use top 5 bits for block id, lower 27 bits for offset. (can address 150m entries) + * + * FixedMemoryPool is a linked list, so still have to loop to find base block address. + * (Or cache in struct - Only need to cache 23 ptrs...) + * + * + * Algorithm to find index from address... + * Currently, we return a ptr from the allocation alg so that it can run a placement new... + * could store off the index in the allocated memory, so it can be retrieved before doing + * placement new... + */ + } // namespace Internal } // namespace Dali diff --git a/dali/internal/common/fixed-size-memory-pool.h b/dali/internal/common/fixed-size-memory-pool.h index 6e05ffe..01620ea 100644 --- a/dali/internal/common/fixed-size-memory-pool.h +++ b/dali/internal/common/fixed-size-memory-pool.h @@ -97,6 +97,10 @@ public: */ void FreeThreadSafe(void* memory); + void* GetPtrToObject(uint32_t key); + + uint32_t GetIndexOfObject(void* ptr); + /** * Get the current capacity of the memory pool * diff --git a/dali/internal/common/memory-pool-object-allocator.h b/dali/internal/common/memory-pool-object-allocator.h index 554ce9a..ebc14fc 100644 --- a/dali/internal/common/memory-pool-object-allocator.h +++ b/dali/internal/common/memory-pool-object-allocator.h @@ -155,6 +155,20 @@ public: } /** + * Get a pointer to the indexed item + * index must be valid. + */ + T* GetPtrToObject(uint32_t index) + { + return static_cast(mPool->GetPtrToObject(index)); + } + + uint32_t GetIndexOfObject(T* object) + { + return mPool->GetIndexOfObject(object); + } + + /** * @brief Get the capacity of the memory pool */ uint32_t GetCapacity() const diff --git a/dali/internal/event/rendering/decorated-visual-renderer-impl.cpp b/dali/internal/event/rendering/decorated-visual-renderer-impl.cpp index b6fc151..85f6a55 100644 --- a/dali/internal/event/rendering/decorated-visual-renderer-impl.cpp +++ b/dali/internal/event/rendering/decorated-visual-renderer-impl.cpp @@ -74,7 +74,7 @@ void SetValue(EventThreadServices& eventThreadServices, const Property::Value& p DecoratedVisualRendererPtr DecoratedVisualRenderer::New() { // create scene object first so it's guaranteed to exist for the event side - auto sceneObject = SceneGraph::Renderer::New(); + auto sceneObjectIndex = SceneGraph::Renderer::NewKey(); auto animatableVisualProperties = new SceneGraph::VisualRenderer::AnimatableVisualProperties(); auto animatableDecoratedVisualProperties = new SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties(); @@ -83,18 +83,17 @@ DecoratedVisualRendererPtr DecoratedVisualRenderer::New() animatableVisualProperties->mExtendedProperties = animatableDecoratedVisualProperties; animatableVisualProperties->mExtendedPropertiesDeleteFunction = SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties::DeleteFunction; + auto sceneObject = SceneGraph::Renderer::Get(sceneObjectIndex); sceneObject->SetVisualProperties(animatableVisualProperties); - OwnerPointer transferOwnership(sceneObject); // pass the pointer to base for message passing DecoratedVisualRendererPtr rendererPtr(new DecoratedVisualRenderer(sceneObject)); rendererPtr->AddUniformMappings(); // Ensure properties are mapped to uniforms - // transfer scene object ownership to update manager EventThreadServices& eventThreadServices = rendererPtr->GetEventThreadServices(); SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager(); - AddRendererMessage(updateManager, transferOwnership); + AddRendererMessage(updateManager, sceneObjectIndex); eventThreadServices.RegisterObject(rendererPtr.Get()); return rendererPtr; diff --git a/dali/internal/event/rendering/renderer-impl.cpp b/dali/internal/event/rendering/renderer-impl.cpp index ca336e1..3040904 100644 --- a/dali/internal/event/rendering/renderer-impl.cpp +++ b/dali/internal/event/rendering/renderer-impl.cpp @@ -194,14 +194,14 @@ TypeRegistration mType(typeid(Dali::Renderer), typeid(Dali::Handle), Create, Ren RendererPtr Renderer::New() { // create scene object first so it's guaranteed to exist for the event side - auto sceneObject = SceneGraph::Renderer::New(); - OwnerPointer transferOwnership(sceneObject); + auto sceneObjectKey = SceneGraph::Renderer::NewKey(); + // pass the pointer to base for message passing - RendererPtr rendererPtr(new Renderer(sceneObject)); - // transfer scene object ownership to update manager + RendererPtr rendererPtr(new Renderer(SceneGraph::Renderer::Get(sceneObjectKey))); + EventThreadServices& eventThreadServices = rendererPtr->GetEventThreadServices(); SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager(); - AddRendererMessage(updateManager, transferOwnership); + AddRendererMessage(updateManager, sceneObjectKey); eventThreadServices.RegisterObject(rendererPtr.Get()); return rendererPtr; @@ -805,7 +805,7 @@ Renderer::~Renderer() { EventThreadServices& eventThreadServices = GetEventThreadServices(); SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager(); - RemoveRendererMessage(updateManager, GetRendererSceneObject()); + RemoveRendererMessage(updateManager, SceneGraph::Renderer::GetIndex(GetRendererSceneObject())); eventThreadServices.UnregisterObject(this); } diff --git a/dali/internal/event/rendering/visual-renderer-impl.cpp b/dali/internal/event/rendering/visual-renderer-impl.cpp index a359d81..989d949 100644 --- a/dali/internal/event/rendering/visual-renderer-impl.cpp +++ b/dali/internal/event/rendering/visual-renderer-impl.cpp @@ -66,11 +66,11 @@ TypeRegistration mType(typeid(Dali::VisualRenderer), typeid(Dali::Renderer), Cre VisualRendererPtr VisualRenderer::New() { // create scene object first so it's guaranteed to exist for the event side - auto sceneObject = SceneGraph::Renderer::New(); + auto sceneObjectIndex = SceneGraph::Renderer::NewKey(); + auto sceneObject = SceneGraph::Renderer::Get(sceneObjectIndex); - sceneObject->SetVisualProperties(new SceneGraph::VisualRenderer::AnimatableVisualProperties()); + sceneObjectKey->SetVisualProperties(new SceneGraph::VisualRenderer::AnimatableVisualProperties()); - OwnerPointer transferOwnership(sceneObject); // pass the pointer to base for message passing VisualRendererPtr rendererPtr(new VisualRenderer(sceneObject)); @@ -79,7 +79,7 @@ VisualRendererPtr VisualRenderer::New() // transfer scene object ownership to update manager EventThreadServices& eventThreadServices = rendererPtr->GetEventThreadServices(); SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager(); - AddRendererMessage(updateManager, transferOwnership); + AddRendererMessage(updateManager, sceneObjectIndex); eventThreadServices.RegisterObject(rendererPtr.Get()); return rendererPtr; diff --git a/dali/internal/update/common/discard-queue.h b/dali/internal/update/common/discard-queue.h index e02a843..fcdee43 100644 --- a/dali/internal/update/common/discard-queue.h +++ b/dali/internal/update/common/discard-queue.h @@ -37,18 +37,10 @@ public: { mDiscardQueue[updateBufferIndex].PushBack(object); } - void add(BufferIndex updateBufferIndex, Type object) - { - mDiscardQueue[updateBufferIndex].push_back(object); - } void Clear(BufferIndex updateBufferIndex) { mDiscardQueue[updateBufferIndex].Clear(); } - void clear(BufferIndex updateBufferIndex) - { - mDiscardQueue[updateBufferIndex].clear(); - } private: TypeContainer mDiscardQueue[2]; diff --git a/dali/internal/update/manager/owner-key-container.h b/dali/internal/update/manager/owner-key-container.h new file mode 100644 index 0000000..fddeb64 --- /dev/null +++ b/dali/internal/update/manager/owner-key-container.h @@ -0,0 +1,236 @@ +#ifndef DALI_INTERNAL_OWNER_KEY_CONTAINER_H +#define DALI_INTERNAL_OWNER_KEY_CONTAINER_H + +/* + * Copyright (c) 2022 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include +#include + +namespace Dali::Internal +{ +/** + * OwnerKeyContainer is a vector which "owns" memory-pool allocated objects. + * Unlike vector this will call delete on the stored objects during destruction. + * + * @endcode + */ +template +class OwnerKeyContainer : public Dali::Vector +{ +public: + using KeyType = uint32_t; + using SizeType = typename Dali::Vector::SizeType; + using Iterator = typename Vector::Iterator; + using ConstIterator = typename Vector::ConstIterator; + + /** + * Create a pointer-container. + */ + OwnerKeyContainer() = default; + + /** + * Non-virtual destructor; OwnerKeyContainer is not suitable as base class. + */ + ~OwnerKeyContainer() + { + Clear(); + VectorBase::Release(); + } + + // Not copyable or movable + OwnerKeyContainer(const OwnerKeyContainer&) = delete; ///< Deleted copy constructor + OwnerKeyContainer(OwnerKeyContainer&&) = delete; ///< Deleted move constructor + OwnerKeyContainer& operator=(const OwnerKeyContainer&) = delete; ///< Deleted copy assignment operator + OwnerKeyContainer& operator=(OwnerKeyContainer&&) = delete; ///< Deleted move assignment operator + + /** + * Test whether the container is empty. + * @return True if the container is empty + */ + bool IsEmpty() const + { + return VectorBase::Count() == 0u; + } + + /** + * Erase an object from the container (delete from heap). + * @param[in] position A dereferencable iterator to an element in mContainer. + * @return iterator pointing to next element + */ + Iterator Erase(Iterator position) + { + Delete(*position); + return Vector::Erase(position); + } + + /** + * @brief Erases all elements that satisfy the predicate from the OwnerKeyContainer. + * + * @param[in] predicate The predicate + */ + template + void EraseIf(Predicate predicate) + { + auto begin = Vector::Begin(); + auto end = Vector::End(); + + auto function = [predicate](auto& key) { + if(predicate(ObjectType::Get(key))) + { + delete ObjectType::Get(key); + return true; + } + else + { + return false; + } + }; + + Vector::Erase(std::remove_if(begin, end, function), end); + } + + /** + * Erases a range of elements.(delete from heap). + */ + Iterator Erase(Iterator first, Iterator last) + { + auto itr = first; + while(itr < last) + { + Delete(*itr); + ++itr; + } + + return Vector::Erase(first, last); + } + + /** + * Erase an object from OwnerKeyContainer + * @param object to remove + */ + inline void EraseObject(ObjectType* object) + { + DALI_ASSERT_DEBUG(object && "NULL object not allowed"); + + KeyType key = ObjectType::GetIndex(object); + + Iterator iter = Vector::Begin(); + const ConstIterator endIter = Vector::End(); + for(; iter != endIter; ++iter) + { + if(*iter == key) + { + Erase(iter); + return; + } + } + } + + /** + * Release the ownership of an object, without deleting it. + * @param[in] position A dereferencable iterator to an element in mContainer. + * @post iterators are invalidated by this method. + * @return pointer to the released item + */ + KeyType Release(Iterator position) + { + KeyType key = *position; + Vector::Erase(position); + return key; + } + + /** + * Destroy all of the elements in the container. + */ + void Clear() + { + ConstIterator end = Vector::End(); + for(Iterator iter = Vector::Begin(); iter != end; ++iter) + { + Delete(*iter); + } + Vector::Clear(); + } + + /** + * Resizes the container to hold specific amount of elements + * @param size to resize to + */ + void Resize(SizeType size) + { + if(size < VectorBase::Count()) + { + // OwnerKeyContainer owns these heap-allocated objects + ConstIterator end = Vector::End(); + for(Iterator iter = Vector::Begin() + size; iter != end; ++iter) + { + Delete(*iter); + } + } + Vector::Resize(size); + } + + /** + * Move the ownership of objects from another OwnerKeyContainer to this one + * without deleting them. It will keep the original items here as well. + * @param[in] source where to move elements from to this OwnerKeyContainer + */ + void MoveFrom(OwnerKeyContainer& source) + { + typename Vector::SizeType sourceCount = source.Count(); + // if source is empty, nothing to move + if(sourceCount > 0u) + { + // Optimisation for the case that this is empty + if(IsEmpty()) + { + VectorBase::Swap(source); + } + else + { + // make space for new items + Vector::Reserve(VectorBase::Count() + sourceCount); + Iterator iter = source.Begin(); + ConstIterator end = source.End(); + for(; iter != end; ++iter) + { + KeyType key = *iter; + Vector::PushBack(key); + } + // cannot call Clear on OwnerKeyContainer as that deletes the elements + source.Vector::Clear(); + } + } + } + +private: + /** + * @brief delete the contents of the pointer + * Function provided to allow classes to provide a custom destructor through template specialisation + * @param pointer to the object + */ + void Delete(KeyType key) + { + delete ObjectType::Get(key); + } +}; + +} // namespace Dali::Internal + +#endif //DALI_INTERNAL_OWNER_KEY_CONTAINER_H diff --git a/dali/internal/update/manager/render-task-processor.cpp b/dali/internal/update/manager/render-task-processor.cpp index 0da46fc..6b6d25b 100644 --- a/dali/internal/update/manager/render-task-processor.cpp +++ b/dali/internal/update/manager/render-task-processor.cpp @@ -174,9 +174,10 @@ bool AddRenderablesForTask(BufferIndex updateBufferIndex, RenderableContainer& target = DALI_LIKELY(inheritedDrawMode == DrawMode::NORMAL) ? layer->colorRenderables : layer->overlayRenderables; for(uint32_t i = 0; i < count; ++i) { - SceneGraph::Renderer* renderer = node.GetRendererAt(i); - target.PushBack(Renderable(&node, renderer)); + SceneGraph::RendererIndex rendererIndex = node.GetRendererAt(i); + SceneGraph::Renderer* renderer = Renderer::Get(rendererIndex); + target.PushBack(Renderable(&node, renderer)); keepRendering = keepRendering || (renderer->GetRenderingBehavior() == DevelRenderer::Rendering::CONTINUOUSLY); } diff --git a/dali/internal/update/manager/update-algorithms.cpp b/dali/internal/update/manager/update-algorithms.cpp index 7cd6ac6..8aa5cd6 100644 --- a/dali/internal/update/manager/update-algorithms.cpp +++ b/dali/internal/update/manager/update-algorithms.cpp @@ -217,7 +217,8 @@ inline void UpdateLayers(Node& node, const uint32_t count = node.GetRendererCount(); for(uint32_t i = 0; i < count; ++i) { - SceneGraph::Renderer* renderer = node.GetRendererAt(i); + auto rendererIndex = node.GetRendererAt(i); + Renderer* renderer = Renderer::Get(rendererIndex); if(renderer->IsDirty()) { layer->SetReuseRenderers(updateBufferIndex, false); diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index d181771..2031536 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +107,31 @@ inline void EraseUsingDiscardQueue(OwnerContainer& container, Type* objec } /** + * Helper to Erase an object from std::vector using discard queue + * @param container to remove from + * @param object to remove + * @param discardQueue to put the object to + * @param updateBufferIndex to use + */ +template +inline void EraseUsingDiscardQueue(OwnerKeyContainer& container, Type* object, DiscardQueue>& discardQueue, BufferIndex updateBufferIndex) +{ + DALI_ASSERT_DEBUG(object && "NULL object not allowed"); + + auto key = Type::GetIndex(object); + + for(auto iter = container.begin(), end = container.end(); iter != end; ++iter) + { + if(*iter == key) + { + // Transfer ownership to the discard queue, this keeps the object alive, until the render-thread has finished with it + discardQueue.Add(updateBufferIndex, container.Release(iter)); + return; // return as we only ever remove one object. Iterators to container are now invalidated as well so cannot continue + } + } +} + +/** * Descends into node's hierarchy and sorts the children of each child according to their depth-index. * @param[in] node The node whose hierarchy to descend */ @@ -274,14 +300,14 @@ struct UpdateManager::Impl OwnerContainer nodeResetters; ///< A container of node resetters OwnerContainer animations; ///< A container of owned animations PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications. - OwnerContainer renderers; ///< A container of owned renderers + OwnerKeyContainer renderers; ///< A container of owned renderers OwnerContainer textureSets; ///< A container of owned texture sets OwnerContainer shaders; ///< A container of owned shaders - DiscardQueue> nodeDiscardQueue; ///< Nodes are added here when disconnected from the scene-graph. - DiscardQueue> shaderDiscardQueue; - DiscardQueue> rendererDiscardQueue; - DiscardQueue> sceneDiscardQueue; + DiscardQueue> nodeDiscardQueue; ///< Nodes are added here when disconnected from the scene-graph. + DiscardQueue> shaderDiscardQueue; + DiscardQueue> rendererDiscardQueue; + DiscardQueue> sceneDiscardQueue; OwnerPointer panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager @@ -645,16 +671,19 @@ void UpdateManager::SetShaderSaver(ShaderSaver& upstream) mImpl->shaderSaver = &upstream; } -void UpdateManager::AddRenderer(OwnerPointer& renderer) +void UpdateManager::AddRenderer(RendererIndex rendererKey) { - DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer.Get()); + SceneGraph::Renderer* renderer = SceneGraph::Renderer::Get(rendererKey); + + DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer); renderer->ConnectToSceneGraph(*mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex()); - mImpl->renderers.PushBack(renderer.Release()); + mImpl->renderers.PushBack(rendererKey); } -void UpdateManager::RemoveRenderer(Renderer* renderer) +void UpdateManager::RemoveRenderer(RendererIndex rendererKey) { + SceneGraph::Renderer* renderer = SceneGraph::Renderer::Get(rendererKey); DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] RemoveRenderer\n", renderer); // Find the renderer and destroy it @@ -665,7 +694,7 @@ void UpdateManager::RemoveRenderer(Renderer* renderer) void UpdateManager::AttachRenderer(Node* node, Renderer* renderer) { - node->AddRenderer(renderer); + node->AddRenderer(Renderer::GetIndex(renderer)); mImpl->renderersAdded = true; } @@ -904,9 +933,10 @@ void UpdateManager::ForwardCompiledShadersToEventThread() void UpdateManager::UpdateRenderers(BufferIndex bufferIndex) { - for(auto&& renderer : mImpl->renderers) + for(auto rendererKey : mImpl->renderers) { // Apply constraints + auto renderer = Renderer::Get(rendererKey); ConstrainPropertyOwner(*renderer, bufferIndex); mImpl->renderingRequired = renderer->PrepareRender(bufferIndex) || mImpl->renderingRequired; @@ -1164,8 +1194,9 @@ uint32_t UpdateManager::Update(float elapsedSeconds, void UpdateManager::PostRender() { // Reset dirty flag - for(auto&& renderer : mImpl->renderers) + for(auto&& rendererIndex : mImpl->renderers) { + Renderer* renderer = Renderer::Get(rendererIndex); renderer->ResetDirtyFlag(); } diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index a0714bc..677ea55 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -320,13 +320,13 @@ public: * Add a new renderer to scene * @param renderer to add */ - void AddRenderer(OwnerPointer& renderer); + void AddRenderer(RendererIndex renderer); /** * Add a renderer from scene * @param renderer to remove */ - void RemoveRenderer(Renderer* renderer); + void RemoveRenderer(RendererIndex renderer); /** * Attach a renderer to node @@ -1104,24 +1104,24 @@ inline void SetLayerDepthsMessage(UpdateManager& manager, const std::vector& object) +inline void AddRendererMessage(UpdateManager& manager, RendererIndex rendererIndex) { - using LocalType = MessageValue1>; + using LocalType = MessageValue1; // 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, &UpdateManager::AddRenderer, object); + new(slot) LocalType(&manager, &UpdateManager::AddRenderer, rendererIndex); } -inline void RemoveRendererMessage(UpdateManager& manager, const Renderer& object) +inline void RemoveRendererMessage(UpdateManager& manager, RendererIndex rendererIndex) { - using LocalType = MessageValue1; + using LocalType = MessageValue1; // 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, &UpdateManager::RemoveRenderer, const_cast(&object)); + new(slot) LocalType(&manager, &UpdateManager::RemoveRenderer, rendererIndex); } inline void AttachRendererMessage(UpdateManager& manager, const Node& node, const Renderer& renderer) diff --git a/dali/internal/update/nodes/node.cpp b/dali/internal/update/nodes/node.cpp index 87b4603..3936269 100644 --- a/dali/internal/update/nodes/node.cpp +++ b/dali/internal/update/nodes/node.cpp @@ -199,18 +199,18 @@ void Node::DisconnectChild(BufferIndex updateBufferIndex, Node& childNode) found->RecursiveDisconnectFromSceneGraph(updateBufferIndex); } -void Node::AddRenderer(Renderer* renderer) +void Node::AddRenderer(RendererIndex renderer) { // If it is the first renderer added, make sure the world transform will be calculated // in the next update as world transform is not computed if node has no renderers. - if(mRenderer.Empty()) + if(mRenderers.Empty()) { mDirtyFlags |= NodePropertyFlags::TRANSFORM; } else { // Check that it has not been already added. - for(auto&& existingRenderer : mRenderer) + for(auto&& existingRenderer : mRenderers) { if(existingRenderer == renderer) { @@ -222,18 +222,18 @@ void Node::AddRenderer(Renderer* renderer) SetUpdated(true); - mRenderer.PushBack(renderer); + mRenderers.PushBack(renderer); } -void Node::RemoveRenderer(const Renderer* renderer) +void Node::RemoveRenderer(const RendererIndex renderer) { - RendererContainer::SizeType rendererCount(mRenderer.Size()); + RendererContainer::SizeType rendererCount(mRenderers.Size()); for(RendererContainer::SizeType i = 0; i < rendererCount; ++i) { - if(mRenderer[i] == renderer) + if(mRenderers[i] == renderer) { SetUpdated(true); - mRenderer.Erase(mRenderer.Begin() + i); + mRenderers.Erase(mRenderers.Begin() + i); return; } } diff --git a/dali/internal/update/nodes/node.h b/dali/internal/update/nodes/node.h index c11c430..d0fb785 100644 --- a/dali/internal/update/nodes/node.h +++ b/dali/internal/update/nodes/node.h @@ -228,21 +228,21 @@ public: * Add a renderer to the node * @param[in] renderer The renderer added to the node */ - void AddRenderer(Renderer* renderer); + void AddRenderer(RendererIndex renderer); /** * Remove a renderer from the node * @param[in] renderer The renderer to be removed */ - void RemoveRenderer(const Renderer* renderer); + void RemoveRenderer(const RendererIndex renderer); /* * Get the renderer at the given index * @param[in] index */ - Renderer* GetRendererAt(uint32_t index) const + RendererIndex GetRendererAt(uint32_t index) const { - return mRenderer[index]; + return mRenderers[index]; } /** @@ -250,7 +250,7 @@ public: */ uint32_t GetRendererCount() const { - return static_cast(mRenderer.Size()); + return static_cast(mRenderers.Size()); } // Containment methods @@ -988,7 +988,7 @@ protected: Node* mParent; ///< Pointer to parent node (a child is owned by its parent) RenderTask* mExclusiveRenderTask; ///< Nodes can be marked as exclusive to a single RenderTask - RendererContainer mRenderer; ///< Container of renderers; not owned + RendererContainer mRenderers; ///< Container of renderers; not owned NodeContainer mChildren; ///< Container of children; not owned @@ -1103,13 +1103,13 @@ inline void SetTransparentMessage(EventThreadServices& eventThreadServices, cons inline void DetachRendererMessage(EventThreadServices& eventThreadServices, const Node& node, const Renderer& renderer) { - using LocalType = MessageValue1; + using LocalType = MessageValue1; // Reserve some memory inside the message queue uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType)); // Construct message in the message queue memory; note that delete should not be called on the return value - new(slot) LocalType(&node, &Node::RemoveRenderer, &renderer); + new(slot) LocalType(&node, &Node::RemoveRenderer, Renderer::GetIndex(renderer)); } inline void SetDepthIndexMessage(EventThreadServices& eventThreadServices, const Node& node, uint32_t depthIndex) diff --git a/dali/internal/update/rendering/scene-graph-renderer.cpp b/dali/internal/update/rendering/scene-graph-renderer.cpp index 8c0d502..0c33062 100644 --- a/dali/internal/update/rendering/scene-graph-renderer.cpp +++ b/dali/internal/update/rendering/scene-graph-renderer.cpp @@ -83,6 +83,16 @@ Renderer* Renderer::New() return new(gRendererMemoryPool.AllocateRawThreadSafe()) Renderer(); } +// Becomes + +RendererIndex Renderer::NewKey() +{ + void* ptr = gRendererMemoryPool.AllocateRawThreadSafe(); + auto key = gRendererMemoryPool.GetIndexOfObject(static_cast(ptr)); + new(ptr) Renderer(); + return key; +} + Renderer::Renderer() : mSceneController(nullptr), mRenderer(nullptr), @@ -119,6 +129,21 @@ void Renderer::operator delete(void* ptr) gRendererMemoryPool.FreeThreadSafe(static_cast(ptr)); } +Renderer* Renderer::Get(RendererIndex rendererIndex) +{ + return gRendererMemoryPool.GetPtrToObject(rendererIndex); +} + +RendererIndex Renderer::GetIndex(const Renderer& renderer) +{ + return gRendererMemoryPool.GetIndexOfObject(const_cast(&renderer)); +} + +RendererIndex Renderer::GetIndex(Renderer* renderer) +{ + return gRendererMemoryPool.GetIndexOfObject(renderer); +} + bool Renderer::PrepareRender(BufferIndex updateBufferIndex) { bool rendererUpdated = mResendFlag || mRenderingBehavior == DevelRenderer::Rendering::CONTINUOUSLY || mUpdateDecay > 0; diff --git a/dali/internal/update/rendering/scene-graph-renderer.h b/dali/internal/update/rendering/scene-graph-renderer.h index 49cd12b..93bfeb0 100644 --- a/dali/internal/update/rendering/scene-graph-renderer.h +++ b/dali/internal/update/rendering/scene-graph-renderer.h @@ -44,7 +44,8 @@ namespace SceneGraph class SceneController; class Renderer; -using RendererContainer = Dali::Vector; +using RendererIndex = uint32_t; +using RendererContainer = Dali::Vector; using RendererIter = RendererContainer::Iterator; using RendererConstIter = RendererContainer::ConstIterator; @@ -155,6 +156,8 @@ public: */ static Renderer* New(); + static RendererIndex NewKey(); + /** * Destructor */ @@ -167,6 +170,16 @@ public: void operator delete(void* ptr); /** + * Get pointer to a renderer at the given index. + * @param[in] rendererIndex Index of renderer to retrieve object + * @return The object's address, or nullptr if not found + */ + static Renderer* Get(RendererIndex rendererIndex); + + static RendererIndex GetIndex(const Renderer& renderer); + static RendererIndex GetIndex(Renderer* renderer); + + /** * Set the texture set for the renderer * @param[in] textureSet The texture set this renderer will use */ -- 2.7.4