/*
- * 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.
// INTERNAL INCLUDES
#include <dali/integration-api/core.h>
+#include <dali/internal/common/owner-key-container.h>
+
#include <dali/internal/event/animation/animation-playlist.h>
#include <dali/internal/event/common/notification-manager.h>
#include <dali/internal/event/common/property-notifier.h>
* @param discardQueue to put the object to
* @param updateBufferIndex to use
*/
-template<class T>
-inline void EraseUsingDiscardQueue(OwnerContainer<T*>& container, T* object, DiscardQueue& discardQueue, BufferIndex updateBufferIndex)
+template<class Type>
+inline void EraseUsingDiscardQueue(OwnerContainer<Type*>& container, Type* object, DiscardQueue<Type*, OwnerContainer<Type*>>& discardQueue, BufferIndex updateBufferIndex)
{
DALI_ASSERT_DEBUG(object && "NULL object not allowed");
}
/**
+ * 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<class Type>
+inline void EraseUsingDiscardQueue(OwnerKeyContainer<Type>& container, const MemoryPoolKey<Type>& key, DiscardQueue<MemoryPoolKey<Type>, OwnerKeyContainer<Type>>& discardQueue, BufferIndex updateBufferIndex)
+{
+ DALI_ASSERT_DEBUG(key && "INVALID Key not allowed");
+
+ 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
*/
void SortSiblingNodesRecursively(Node& node)
{
NodeContainer& container = node.GetChildren();
- std::sort(container.Begin(), container.End(), [](Node* a, Node* b)
- { return a->GetDepthIndex() < b->GetDepthIndex(); });
+ std::sort(container.Begin(), container.End(), [](Node* a, Node* b) { return a->GetDepthIndex() < b->GetDepthIndex(); });
// Descend tree and sort as well
for(auto&& iter : container)
{
}
- ~SceneInfo() = default; ///< Default non-virtual destructor
- SceneInfo(SceneInfo&& rhs) = default; ///< Move constructor
- SceneInfo& operator=(SceneInfo&& rhs) = default; ///< Move assignment operator
- SceneInfo& operator=(const SceneInfo& rhs) = delete; ///< Assignment operator
- SceneInfo(const SceneInfo& rhs) = delete; ///< Copy constructor
+ ~SceneInfo() = default; ///< Default non-virtual destructor
+ SceneInfo(SceneInfo&& rhs) = default; ///< Move constructor
+ SceneInfo& operator=(SceneInfo&& rhs) = default; ///< Move assignment operator
+ SceneInfo& operator=(const SceneInfo& rhs) = delete; ///< Assignment operator
+ SceneInfo(const SceneInfo& rhs) = delete; ///< Copy constructor
Layer* root{nullptr}; ///< Root node (root is a layer). The layer is not stored in the node memory pool.
OwnerPointer<RenderTaskList> taskList; ///< Scene graph render task list
Impl(NotificationManager& notificationManager,
CompleteNotificationInterface& animationPlaylist,
PropertyNotifier& propertyNotifier,
- DiscardQueue& discardQueue,
RenderController& renderController,
RenderManager& renderManager,
RenderQueue& renderQueue,
animationPlaylist(animationPlaylist),
propertyNotifier(propertyNotifier),
shaderSaver(nullptr),
- discardQueue(discardQueue),
renderController(renderController),
sceneController(nullptr),
renderManager(renderManager),
renderersAdded(false),
renderingRequired(false)
{
- sceneController = new SceneControllerImpl(renderMessageDispatcher, renderQueue, discardQueue);
+ sceneController = new SceneControllerImpl(renderMessageDispatcher, renderQueue);
// create first 'dummy' node
nodes.PushBack(nullptr);
CompleteNotificationInterface& animationPlaylist; ///< Holds handles to all the animations
PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
ShaderSaver* shaderSaver; ///< Saves shader binaries.
- DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
RenderController& renderController; ///< render controller
SceneControllerImpl* sceneController; ///< scene controller
RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
OwnerContainer<NodeResetter*> nodeResetters; ///< A container of node resetters
OwnerContainer<Animation*> animations; ///< A container of owned animations
PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
- OwnerContainer<Renderer*> renderers; ///< A container of owned renderers
+ OwnerKeyContainer<Renderer> renderers; ///< A container of owned renderers
OwnerContainer<TextureSet*> textureSets; ///< A container of owned texture sets
OwnerContainer<Shader*> shaders; ///< A container of owned shaders
- OwnerPointer<PanGesture> panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager
+
+ DiscardQueue<Node*, OwnerContainer<Node*>> nodeDiscardQueue; ///< Nodes are added here when disconnected from the scene-graph.
+ DiscardQueue<Shader*, OwnerContainer<Shader*>> shaderDiscardQueue;
+ DiscardQueue<MemoryPoolKey<Renderer>, OwnerKeyContainer<Renderer>> rendererDiscardQueue;
+ DiscardQueue<Scene*, OwnerContainer<Scene*>> sceneDiscardQueue;
+
+ OwnerPointer<PanGesture> panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager
MessageQueue messageQueue; ///< The messages queued from the event-thread
std::vector<Internal::ShaderDataPtr> renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
UpdateManager::UpdateManager(NotificationManager& notificationManager,
CompleteNotificationInterface& animationFinishedNotifier,
PropertyNotifier& propertyNotifier,
- DiscardQueue& discardQueue,
RenderController& controller,
RenderManager& renderManager,
RenderQueue& renderQueue,
mImpl = new Impl(notificationManager,
animationFinishedNotifier,
propertyNotifier,
- discardQueue,
controller,
renderManager,
renderQueue,
Layer* rootLayer = layer.Release();
- DALI_ASSERT_DEBUG(std::find_if(mImpl->scenes.begin(), mImpl->scenes.end(), [rootLayer](Impl::SceneInfoPtr& scene)
- { return scene && scene->root == rootLayer; }) == mImpl->scenes.end() &&
+ DALI_ASSERT_DEBUG(std::find_if(mImpl->scenes.begin(), mImpl->scenes.end(), [rootLayer](Impl::SceneInfoPtr& scene) { return scene && scene->root == rootLayer; }) == mImpl->scenes.end() &&
"Root Node already installed");
rootLayer->CreateTransform(&mImpl->transformManager);
}
}
- mImpl->discardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), layer);
+ mImpl->nodeDiscardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), layer);
// Notify the layer about impending destruction
layer->OnDestroy();
RemoveCamera(static_cast<Camera*>(node));
}
- mImpl->discardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), node);
+ mImpl->nodeDiscardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), node);
// Notify the Node about impending destruction
node->OnDestroy();
{
if(sceneInfo && sceneInfo->scene && sceneInfo->scene.Get() == scene)
{
- mImpl->discardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), sceneInfo->scene.Release()); // take the address of the reference to a pointer
+ mImpl->sceneDiscardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), sceneInfo->scene.Release()); // take the address of the reference to a pointer
break;
}
}
void UpdateManager::RemoveShader(Shader* shader)
{
// Find the shader and destroy it
- EraseUsingDiscardQueue(mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
+ EraseUsingDiscardQueue(mImpl->shaders, shader, mImpl->shaderDiscardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
}
void UpdateManager::SaveBinary(Internal::ShaderDataPtr shaderData)
mImpl->shaderSaver = &upstream;
}
-void UpdateManager::AddRenderer(OwnerPointer<Renderer>& renderer)
+void UpdateManager::AddRenderer(const RendererKey& rendererKey)
{
- DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer.Get());
+ SceneGraph::Renderer* renderer = rendererKey.Get();
+
+ 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(const RendererKey& rendererKey)
{
- DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] RemoveRenderer\n", renderer);
+ DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] RemoveRenderer\n", rendererKey.Get());
// Find the renderer and destroy it
- EraseUsingDiscardQueue(mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
+ EraseUsingDiscardQueue(mImpl->renderers, rendererKey, mImpl->rendererDiscardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
// Need to remove the render object as well
- renderer->DisconnectFromSceneGraph(*mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex());
+ rendererKey->DisconnectFromSceneGraph(*mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex());
}
void UpdateManager::AttachRenderer(Node* node, Renderer* renderer)
{
- node->AddRenderer(renderer);
+ node->AddRenderer(Renderer::GetKey(renderer));
mImpl->renderersAdded = true;
}
void UpdateManager::UpdateRenderers(BufferIndex bufferIndex)
{
- for(auto&& renderer : mImpl->renderers)
+ for(const auto& rendererKey : mImpl->renderers)
{
// Apply constraints
+ auto renderer = rendererKey.Get();
ConstrainPropertyOwner(*renderer, bufferIndex);
mImpl->renderingRequired = renderer->PrepareRender(bufferIndex) || mImpl->renderingRequired;
const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
// Clear nodes/resources which were previously discarded
- mImpl->discardQueue.Clear(bufferIndex);
+ mImpl->nodeDiscardQueue.Clear(bufferIndex);
+ mImpl->shaderDiscardQueue.Clear(bufferIndex);
+ mImpl->rendererDiscardQueue.Clear(bufferIndex);
+ mImpl->sceneDiscardQueue.Clear(bufferIndex);
bool isAnimationRunning = IsAnimationRunning();
void UpdateManager::AddSampler(OwnerPointer<Render::Sampler>& sampler)
{
// Message has ownership of Sampler while in transit from update to render
- using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Sampler> >;
+ using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Sampler>>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
void UpdateManager::AddVertexBuffer(OwnerPointer<Render::VertexBuffer>& vertexBuffer)
{
// Message has ownership of format while in transit from update -> render
- using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::VertexBuffer> >;
+ using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::VertexBuffer>>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
void UpdateManager::SetVertexBufferFormat(Render::VertexBuffer* vertexBuffer, OwnerPointer<Render::VertexBuffer::Format>& format)
{
// Message has ownership of format while in transit from update -> render
- using DerivedType = MessageValue2<RenderManager, Render::VertexBuffer*, OwnerPointer<Render::VertexBuffer::Format> >;
+ using DerivedType = MessageValue2<RenderManager, Render::VertexBuffer*, OwnerPointer<Render::VertexBuffer::Format>>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetVertexBufferFormat, vertexBuffer, format);
}
-void UpdateManager::SetVertexBufferData(Render::VertexBuffer* vertexBuffer, OwnerPointer<Vector<uint8_t> >& data, uint32_t size)
+void UpdateManager::SetVertexBufferData(Render::VertexBuffer* vertexBuffer, OwnerPointer<Vector<uint8_t>>& data, uint32_t size)
{
// Message has ownership of format while in transit from update -> render
- using DerivedType = MessageValue3<RenderManager, Render::VertexBuffer*, OwnerPointer<Dali::Vector<uint8_t> >, uint32_t>;
+ using DerivedType = MessageValue3<RenderManager, Render::VertexBuffer*, OwnerPointer<Dali::Vector<uint8_t>>, uint32_t>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
void UpdateManager::AddGeometry(OwnerPointer<Render::Geometry>& geometry)
{
// Message has ownership of format while in transit from update -> render
- using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Geometry> >;
+ using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Geometry>>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, vertexBuffer);
}
-void UpdateManager::AddTexture(OwnerPointer<Render::Texture>& texture)
+void UpdateManager::AddTexture(const Render::TextureKey& texture)
{
- // Message has ownership of Texture while in transit from update -> render
- using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Texture> >;
+ using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AddTexture, texture);
}
-void UpdateManager::RemoveTexture(Render::Texture* texture)
+void UpdateManager::RemoveTexture(const Render::TextureKey& texture)
{
- using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
+ using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
new(slot) DerivedType(&mImpl->renderManager, &RenderManager::RemoveTexture, texture);
}
-void UpdateManager::UploadTexture(Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params)
+void UpdateManager::UploadTexture(const Render::TextureKey& texture, PixelDataPtr pixelData, const Texture::UploadParams& params)
{
- using DerivedType = MessageValue3<RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams>;
+ using DerivedType = MessageValue3<RenderManager, Render::TextureKey, PixelDataPtr, Texture::UploadParams>;
// Reserve some memory inside the message queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
new(slot) DerivedType(&mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params);
}
-void UpdateManager::GenerateMipmaps(Render::Texture* texture)
+void UpdateManager::GenerateMipmaps(const Render::TextureKey& texture)
{
- using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
+ using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
void UpdateManager::AddFrameBuffer(OwnerPointer<Render::FrameBuffer>& frameBuffer)
{
- using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::FrameBuffer> >;
+ using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::FrameBuffer>>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));