X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Fmanager%2Fupdate-manager.cpp;h=4a2f1bb00fc3fc9547046042e094f0c4b35dd417;hb=59210c12884501e6e47525d82b1ea15455d06721;hp=c231eb8e252d54325f78fe39b4dc1fd213ad1a8d;hpb=d28979e5a4966c85c3fb6cf1d9f39c942e487fe8;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index c231eb8..4a2f1bb 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -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. @@ -21,6 +21,8 @@ // INTERNAL INCLUDES #include +#include + #include #include #include @@ -31,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -88,8 +91,8 @@ namespace * @param discardQueue to put the object to * @param updateBufferIndex to use */ -template -inline void EraseUsingDiscardQueue(OwnerContainer& container, T* object, DiscardQueue& discardQueue, BufferIndex updateBufferIndex) +template +inline void EraseUsingDiscardQueue(OwnerContainer& container, Type* object, DiscardQueue>& discardQueue, BufferIndex updateBufferIndex) { DALI_ASSERT_DEBUG(object && "NULL object not allowed"); @@ -106,18 +109,25 @@ inline void EraseUsingDiscardQueue(OwnerContainer& container, T* object, Dis } /** - * 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 + * 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 */ -void SortSiblingNodesRecursively(Node& node) +template +inline void EraseUsingDiscardQueue(OwnerKeyContainer& container, const MemoryPoolKey& key, DiscardQueue, OwnerKeyContainer>& discardQueue, BufferIndex updateBufferIndex) { - NodeContainer& container = node.GetChildren(); - std::sort(container.Begin(), container.End(), [](Node* a, Node* b) { return a->GetDepthIndex() < b->GetDepthIndex(); }); + DALI_ASSERT_DEBUG(key && "INVALID Key not allowed"); - // Descend tree and sort as well - for(auto&& iter : container) + for(auto iter = container.begin(), end = container.end(); iter != end; ++iter) { - SortSiblingNodesRecursively(*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 + } } } @@ -151,7 +161,6 @@ struct UpdateManager::Impl Impl(NotificationManager& notificationManager, CompleteNotificationInterface& animationPlaylist, PropertyNotifier& propertyNotifier, - DiscardQueue& discardQueue, RenderController& renderController, RenderManager& renderManager, RenderQueue& renderQueue, @@ -163,7 +172,6 @@ struct UpdateManager::Impl animationPlaylist(animationPlaylist), propertyNotifier(propertyNotifier), shaderSaver(nullptr), - discardQueue(discardQueue), renderController(renderController), sceneController(nullptr), renderManager(renderManager), @@ -186,7 +194,7 @@ struct UpdateManager::Impl renderersAdded(false), renderingRequired(false) { - sceneController = new SceneControllerImpl(renderMessageDispatcher, renderQueue, discardQueue); + sceneController = new SceneControllerImpl(renderMessageDispatcher, renderQueue); // create first 'dummy' node nodes.PushBack(nullptr); @@ -228,6 +236,10 @@ struct UpdateManager::Impl scenes.clear(); delete sceneController; + + // Ensure to clear renderers + renderers.Clear(); + shaders.Clear(); } /** @@ -250,7 +262,6 @@ struct UpdateManager::Impl 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" @@ -264,17 +275,26 @@ struct UpdateManager::Impl Vector nodes; ///< A container of all instantiated nodes - OwnerContainer cameras; ///< A container of cameras + Vector cameras; ///< A container of cameras. Note : these cameras are owned by Impl::nodes. + OwnerContainer customObjects; ///< A container of owned objects (with custom properties) - OwnerContainer propertyResetters; ///< A container of property resetters - OwnerContainer nodeResetters; ///< A container of node resetters + ResetterContainer propertyResetters; ///< A container of property resetters + ResetterContainer nodeResetters; ///< A container of node resetters + ResetterContainer rendererResetters; ///< A container of renderer resetters + OwnerContainer animations; ///< A container of owned animations - PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications. - OwnerContainer renderers; ///< A container of owned renderers + OwnerContainer propertyNotifications; ///< A container of owner property notifications. + OwnerKeyContainer renderers; ///< A container of owned renderers OwnerContainer textureSets; ///< A container of owned texture sets OwnerContainer shaders; ///< A container of owned shaders - OwnerPointer panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager + + DiscardQueue> nodeDiscardQueue; ///< Nodes are added here when disconnected from the scene-graph. + DiscardQueue> shaderDiscardQueue; + DiscardQueue, OwnerKeyContainer> rendererDiscardQueue; + DiscardQueue> sceneDiscardQueue; + + OwnerPointer panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager MessageQueue messageQueue; ///< The messages queued from the event-thread std::vector renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread. @@ -283,11 +303,11 @@ struct UpdateManager::Impl OwnerPointer frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required. - float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering - NodePropertyFlags nodeDirtyFlags; ///< cumulative node dirty flags from previous frame - uint32_t frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore. - - DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior + std::atomic renderInstructionCapacity{0u}; + float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering + NodePropertyFlags nodeDirtyFlags; ///< cumulative node dirty flags from previous frame + uint32_t frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore. + DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update() bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out) @@ -303,7 +323,6 @@ private: UpdateManager::UpdateManager(NotificationManager& notificationManager, CompleteNotificationInterface& animationFinishedNotifier, PropertyNotifier& propertyNotifier, - DiscardQueue& discardQueue, RenderController& controller, RenderManager& renderManager, RenderQueue& renderQueue, @@ -313,7 +332,6 @@ UpdateManager::UpdateManager(NotificationManager& notificationManager, mImpl = new Impl(notificationManager, animationFinishedNotifier, propertyNotifier, - discardQueue, controller, renderManager, renderQueue, @@ -333,15 +351,13 @@ void UpdateManager::InstallRoot(OwnerPointer& layer) 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); rootLayer->SetRoot(true); - AddNodeResetter(*rootLayer); + rootLayer->AddInitializeResetter(*this); mImpl->scenes.emplace_back(new Impl::SceneInfo(rootLayer)); } @@ -360,7 +376,7 @@ void UpdateManager::UninstallRoot(Layer* layer) } } - mImpl->discardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), layer); + mImpl->nodeDiscardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), layer); // Notify the layer about impending destruction layer->OnDestroy(); @@ -373,6 +389,12 @@ void UpdateManager::AddNode(OwnerPointer& node) Node* rawNode = node.Release(); DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] AddNode\n", rawNode); + // Add camera nodes occured rarely. + if(DALI_UNLIKELY(rawNode->IsCamera())) + { + AddCamera(static_cast(rawNode)); + } + mImpl->nodes.PushBack(rawNode); rawNode->CreateTransform(&mImpl->transformManager); } @@ -387,7 +409,7 @@ void UpdateManager::ConnectNode(Node* parent, Node* node) parent->ConnectChild(node); - AddNodeResetter(*node); + node->AddInitializeResetter(*this); // Inform the frame-callback-processor, if set, about the node-hierarchy changing if(mImpl->frameCallbackProcessor) @@ -431,21 +453,40 @@ void UpdateManager::DestroyNode(Node* node) } } - mImpl->discardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), node); + // Remove camera nodes occured rarely. + if(DALI_UNLIKELY(node->IsCamera())) + { + RemoveCamera(static_cast(node)); + } + + mImpl->nodeDiscardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), node); // Notify the Node about impending destruction node->OnDestroy(); } -void UpdateManager::AddCamera(OwnerPointer& camera) +void UpdateManager::AddCamera(Camera* camera) { - mImpl->cameras.PushBack(camera.Release()); // takes ownership + DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] AddCamera\n", camera); + + mImpl->cameras.PushBack(camera); } void UpdateManager::RemoveCamera(Camera* camera) { - // Find the camera and destroy it - EraseUsingDiscardQueue(mImpl->cameras, camera, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex()); + DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] RemoveCamera\n", camera); + + // Find the camera and remove it from list of cameras + Vector::Iterator iter = mImpl->cameras.Begin(); + Vector::Iterator endIter = mImpl->cameras.End(); + for(; iter != endIter; ++iter) + { + if((*iter) == camera) + { + mImpl->cameras.Erase(iter); + break; + } + } } void UpdateManager::AddObject(OwnerPointer& object) @@ -461,7 +502,7 @@ void UpdateManager::RemoveObject(PropertyOwner* object) void UpdateManager::AddRenderTaskList(OwnerPointer& taskList) { RenderTaskList* taskListPointer = taskList.Release(); - taskListPointer->SetRenderMessageDispatcher(&mImpl->renderMessageDispatcher); + taskListPointer->Initialize(*this, mImpl->renderMessageDispatcher); mImpl->scenes.back()->taskList = taskListPointer; } @@ -480,7 +521,11 @@ void UpdateManager::RemoveRenderTaskList(RenderTaskList* taskList) void UpdateManager::AddScene(OwnerPointer& scene) { - mImpl->scenes.back()->scene = scene.Release(); + auto& sceneInfo = mImpl->scenes.back(); + sceneInfo->scene = scene.Release(); + + // Set root to the Scene + sceneInfo->scene->SetRoot(sceneInfo->root); // Initialize the context from render manager typedef MessageValue1 DerivedType; @@ -489,7 +534,7 @@ void UpdateManager::AddScene(OwnerPointer& scene) 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 - SceneGraph::Scene& sceneObject = *mImpl->scenes.back()->scene; + SceneGraph::Scene& sceneObject = *sceneInfo->scene; new(slot) DerivedType(&mImpl->renderManager, &RenderManager::InitializeScene, &sceneObject); } @@ -504,11 +549,13 @@ void UpdateManager::RemoveScene(Scene* scene) // Construct message in the render queue memory; note that delete should not be called on the return value new(slot) DerivedType(&mImpl->renderManager, &RenderManager::UninitializeScene, scene); + scene->RemoveSurfaceRenderTarget(); + for(auto&& sceneInfo : mImpl->scenes) { 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; } } @@ -567,6 +614,13 @@ void UpdateManager::AddNodeResetter(const Node& node) mImpl->nodeResetters.PushBack(nodeResetter.Release()); } +void UpdateManager::AddRendererResetter(const Renderer& renderer) +{ + OwnerPointer rendererResetter = SceneGraph::RendererResetter::New(renderer); + rendererResetter->Initialize(); + mImpl->rendererResetters.PushBack(rendererResetter.Release()); +} + void UpdateManager::AddPropertyNotification(OwnerPointer& propertyNotification) { mImpl->propertyNotifications.PushBack(propertyNotification.Release()); @@ -591,7 +645,7 @@ void UpdateManager::AddShader(OwnerPointer& shader) 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) @@ -610,27 +664,31 @@ void UpdateManager::SetShaderSaver(ShaderSaver& upstream) mImpl->shaderSaver = &upstream; } -void UpdateManager::AddRenderer(OwnerPointer& 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()); + renderer->AddInitializeResetter(*this); + + 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; } @@ -643,6 +701,7 @@ void UpdateManager::SetPanGestureProcessor(PanGesture* panGestureProcessor) void UpdateManager::AddTextureSet(OwnerPointer& textureSet) { + textureSet->SetRenderMessageDispatcher(&mImpl->renderMessageDispatcher); mImpl->textureSets.PushBack(textureSet.Release()); } @@ -656,6 +715,21 @@ uint32_t* UpdateManager::ReserveMessageSlot(uint32_t size, bool updateScene) return mImpl->messageQueue.ReserveMessageSlot(size, updateScene); } +std::size_t UpdateManager::GetUpdateMessageQueueCapacity() const +{ + return mImpl->messageQueue.GetCapacity(); +} + +std::size_t UpdateManager::GetRenderMessageQueueCapacity() const +{ + return mImpl->renderQueue.GetCapacity(); +} + +std::size_t UpdateManager::GetRenderInstructionCapacity() const +{ + return mImpl->renderInstructionCapacity; +} + void UpdateManager::EventProcessingStarted() { mImpl->messageQueue.EventProcessingStarted(); @@ -672,38 +746,13 @@ void UpdateManager::ResetProperties(BufferIndex bufferIndex) mImpl->animationFinishedDuringUpdate = false; // Reset node properties - std::vector nodeResetterToDelete; - for(auto&& element : mImpl->nodeResetters) - { - element->ResetToBaseValue(bufferIndex); - if(element->IsFinished()) - { - nodeResetterToDelete.push_back(element); - } - } + mImpl->nodeResetters.ResetToBaseValues(bufferIndex); - // If a node resetter is no longer required, delete it. - for(auto&& elementPtr : nodeResetterToDelete) - { - mImpl->nodeResetters.EraseObject(elementPtr); - } + // Reset renderer properties + mImpl->rendererResetters.ResetToBaseValues(bufferIndex); // Reset all animating / constrained properties - std::vector propertyResettertoDelete; - for(auto&& element : mImpl->propertyResetters) - { - element->ResetToBaseValue(bufferIndex); - if(element->IsFinished()) - { - propertyResettertoDelete.push_back(element); - } - } - - // If a property resetter is no longer required (the animator or constraint has been removed), delete it. - for(auto&& elementPtr : propertyResettertoDelete) - { - mImpl->propertyResetters.EraseObject(elementPtr); - } + mImpl->propertyResetters.ResetToBaseValues(bufferIndex); // Clear all root nodes dirty flags for(auto& scene : mImpl->scenes) @@ -783,7 +832,7 @@ bool UpdateManager::Animate(BufferIndex bufferIndex, float elapsedSeconds) void UpdateManager::ConstrainCustomObjects(BufferIndex bufferIndex) { - //Constrain custom objects (in construction order) + // Constrain custom objects (in construction order) for(auto&& object : mImpl->customObjects) { ConstrainPropertyOwner(*object, bufferIndex); @@ -854,9 +903,10 @@ void UpdateManager::ForwardCompiledShadersToEventThread() void UpdateManager::UpdateRenderers(BufferIndex bufferIndex) { - for(auto&& renderer : mImpl->renderers) + for(const auto& rendererKey : mImpl->renderers) { - //Apply constraints + // Apply constraints + auto renderer = rendererKey.Get(); ConstrainPropertyOwner(*renderer, bufferIndex); mImpl->renderingRequired = renderer->PrepareRender(bufferIndex) || mImpl->renderingRequired; @@ -880,20 +930,35 @@ void UpdateManager::UpdateNodes(BufferIndex bufferIndex) } } +void UpdateManager::UpdateLayers(BufferIndex bufferIndex) +{ + for(auto&& scene : mImpl->scenes) + { + if(scene && scene->root) + { + SceneGraph::UpdateLayerTree(*scene->root, bufferIndex); + } + } +} + uint32_t UpdateManager::Update(float elapsedSeconds, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds, bool renderToFboEnabled, - bool isRenderingToFbo) + bool isRenderingToFbo, + bool uploadOnly) { const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex(); - //Clear nodes/resources which were previously discarded - mImpl->discardQueue.Clear(bufferIndex); + // Clear nodes/resources which were previously discarded + mImpl->nodeDiscardQueue.Clear(bufferIndex); + mImpl->shaderDiscardQueue.Clear(bufferIndex); + mImpl->rendererDiscardQueue.Clear(bufferIndex); + mImpl->sceneDiscardQueue.Clear(bufferIndex); bool isAnimationRunning = IsAnimationRunning(); - //Process Touches & Gestures + // Process Touches & Gestures const bool gestureUpdated = ProcessGestures(bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds); bool updateScene = // The scene-graph requires an update if.. @@ -910,7 +975,7 @@ uint32_t UpdateManager::Update(float elapsedSeconds, // values if the scene was updated in the previous frame. if(updateScene || mImpl->previousUpdateScene) { - //Reset properties from the previous update + // Reset properties from the previous update ResetProperties(bufferIndex); mImpl->transformManager.ResetToBaseValue(); } @@ -920,7 +985,7 @@ uint32_t UpdateManager::Update(float elapsedSeconds, // be set again updateScene |= mImpl->messageQueue.ProcessMessages(bufferIndex); - //Forward compiled shader programs to event thread for saving + // Forward compiled shader programs to event thread for saving ForwardCompiledShadersToEventThread(); // Although the scene-graph may not require an update, we still need to synchronize double-buffered @@ -928,13 +993,13 @@ uint32_t UpdateManager::Update(float elapsedSeconds, // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes if(updateScene || mImpl->previousUpdateScene) { - //Animate + // Animate bool animationActive = Animate(bufferIndex, elapsedSeconds); - //Constraint custom objects + // Constraint custom objects ConstrainCustomObjects(bufferIndex); - //Clear the lists of renderers from the previous update + // Clear the lists of renderers from the previous update for(auto&& scene : mImpl->scenes) { if(scene) @@ -955,34 +1020,36 @@ uint32_t UpdateManager::Update(float elapsedSeconds, mImpl->frameCallbackProcessor->Update(bufferIndex, elapsedSeconds); } - //Update node hierarchy, apply constraints and perform sorting / culling. - //This will populate each Layer with a list of renderers which are ready. + // Update node hierarchy, apply constraints, UpdateNodes(bufferIndex); - //Apply constraints to RenderTasks, shaders + // Apply constraints to RenderTasks, shaders ConstrainRenderTasks(bufferIndex); ConstrainShaders(bufferIndex); - //Update renderers and apply constraints + // Update renderers and apply constraints UpdateRenderers(bufferIndex); - //Update the transformations of all the nodes + // Update the transformations of all the nodes if(mImpl->transformManager.Update()) { mImpl->nodeDirtyFlags |= NodePropertyFlags::TRANSFORM; } - //Process Property Notifications + // Initialise layer renderable reuse + UpdateLayers(bufferIndex); + + // Process Property Notifications ProcessPropertyNotifications(bufferIndex); - //Update cameras + // Update cameras for(auto&& cameraIterator : mImpl->cameras) { cameraIterator->Update(bufferIndex); } - //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame. - //reset the update buffer index and make sure there is enough room in the instruction container + // Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame. + // reset the update buffer index and make sure there is enough room in the instruction container if(mImpl->renderersAdded) { // Calculate how many render tasks we have in total @@ -996,6 +1063,7 @@ uint32_t UpdateManager::Update(float elapsedSeconds, } std::size_t numberOfRenderInstructions = 0; + mImpl->renderInstructionCapacity = 0u; for(auto&& scene : mImpl->scenes) { if(scene && scene->root && scene->taskList && scene->scene) @@ -1015,6 +1083,7 @@ uint32_t UpdateManager::Update(float elapsedSeconds, renderToFboEnabled, isRenderingToFbo); + mImpl->renderInstructionCapacity += scene->scene->GetRenderInstructions().GetCapacity(); scene->scene->SetSkipRendering(false); } else @@ -1030,36 +1099,39 @@ uint32_t UpdateManager::Update(float elapsedSeconds, } } - for(auto&& scene : mImpl->scenes) + if(!uploadOnly) { - if(scene && scene->root && scene->taskList) + for(auto&& scene : mImpl->scenes) { - RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks(); - - // check the countdown and notify - bool doRenderOnceNotify = false; - mImpl->renderTaskWaiting = false; - for(auto&& renderTask : tasks) + if(scene && scene->root && scene->taskList) { - renderTask->UpdateState(); + RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks(); - if(renderTask->IsWaitingToRender() && - renderTask->ReadyToRender(bufferIndex) /*avoid updating forever when source actor is off-stage*/) + // check the countdown and notify + bool doRenderOnceNotify = false; + mImpl->renderTaskWaiting = false; + for(auto&& renderTask : tasks) { - mImpl->renderTaskWaiting = true; // keep update/render threads alive + renderTask->UpdateState(); + + if(renderTask->IsWaitingToRender() && + renderTask->ReadyToRender(bufferIndex) /*avoid updating forever when source actor is off-stage*/) + { + mImpl->renderTaskWaiting = true; // keep update/render threads alive + } + + if(renderTask->HasRendered()) + { + doRenderOnceNotify = true; + } } - if(renderTask->HasRendered()) + if(doRenderOnceNotify) { - doRenderOnceNotify = true; + DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n"); + mImpl->notificationManager.QueueCompleteNotification(scene->taskList->GetCompleteNotificationInterface()); } } - - if(doRenderOnceNotify) - { - DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n"); - mImpl->notificationManager.QueueCompleteNotification(scene->taskList->GetCompleteNotificationInterface()); - } } } @@ -1089,6 +1161,25 @@ uint32_t UpdateManager::Update(float elapsedSeconds, return keepUpdating; } +void UpdateManager::PostRender() +{ + // Reset dirty flag + for(auto&& renderer : mImpl->renderers) + { + renderer->ResetDirtyFlag(); + } + + for(auto&& shader : mImpl->shaders) + { + shader->SetUpdated(false); + } + + for(auto&& scene : mImpl->scenes) + { + scene->root->SetUpdatedTree(false); + } +} + uint32_t UpdateManager::KeepUpdatingCheck(float elapsedSeconds) const { // Update the duration set via Stage::KeepRendering() @@ -1166,19 +1257,18 @@ void UpdateManager::SetLayerDepths(const SortedLayerPointers& layers, const Laye void UpdateManager::SetDepthIndices(OwnerPointer& nodeDepths) { - // note,this vector is already in depth order. It could be used as-is to - // remove sorting in update algorithm. However, it lacks layer boundary markers. - for(auto&& iter : nodeDepths->nodeDepths) + // note, this vector is already in depth order. + // So if we reverse iterate, we can assume that + // my descendant node's depth index are updated. + for(auto rIter = nodeDepths->nodeDepths.rbegin(), rEndIter = nodeDepths->nodeDepths.rend(); rIter != rEndIter; rIter++) { - iter.node->SetDepthIndex(iter.sortedDepth); - } - - for(auto&& scene : mImpl->scenes) - { - if(scene) + auto* node = rIter->node; + node->SetDepthIndex(rIter->sortedDepth); + if(node->IsChildrenReorderRequired()) { - // Go through node hierarchy and rearrange siblings according to depth-index - SortSiblingNodesRecursively(*scene->root); + // Reorder children container only if sibiling order changed. + NodeContainer& container = node->GetChildren(); + std::sort(container.Begin(), container.End(), [](Node* a, Node* b) { return a->GetDepthIndex() < b->GetDepthIndex(); }); } } } @@ -1196,7 +1286,7 @@ void UpdateManager::RemoveFrameCallback(FrameCallbackInterface* frameCallback) void UpdateManager::AddSampler(OwnerPointer& sampler) { // Message has ownership of Sampler while in transit from update to render - using DerivedType = MessageValue1 >; + using DerivedType = MessageValue1>; // Reserve some memory inside the render queue uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType)); @@ -1241,7 +1331,7 @@ void UpdateManager::SetWrapMode(Render::Sampler* sampler, uint32_t rWrapMode, ui void UpdateManager::AddVertexBuffer(OwnerPointer& vertexBuffer) { // Message has ownership of format while in transit from update -> render - using DerivedType = MessageValue1 >; + using DerivedType = MessageValue1>; // Reserve some memory inside the render queue uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType)); @@ -1264,7 +1354,7 @@ void UpdateManager::RemoveVertexBuffer(Render::VertexBuffer* vertexBuffer) void UpdateManager::SetVertexBufferFormat(Render::VertexBuffer* vertexBuffer, OwnerPointer& format) { // Message has ownership of format while in transit from update -> render - using DerivedType = MessageValue2 >; + using DerivedType = MessageValue2>; // Reserve some memory inside the render queue uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType)); @@ -1273,10 +1363,10 @@ void UpdateManager::SetVertexBufferFormat(Render::VertexBuffer* vertexBuffer, Ow new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetVertexBufferFormat, vertexBuffer, format); } -void UpdateManager::SetVertexBufferData(Render::VertexBuffer* vertexBuffer, OwnerPointer >& data, uint32_t size) +void UpdateManager::SetVertexBufferData(Render::VertexBuffer* vertexBuffer, OwnerPointer>& data, uint32_t size) { // Message has ownership of format while in transit from update -> render - using DerivedType = MessageValue3 >, uint32_t>; + using DerivedType = MessageValue3>, uint32_t>; // Reserve some memory inside the render queue uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType)); @@ -1288,7 +1378,7 @@ void UpdateManager::SetVertexBufferData(Render::VertexBuffer* vertexBuffer, Owne void UpdateManager::AddGeometry(OwnerPointer& geometry) { // Message has ownership of format while in transit from update -> render - using DerivedType = MessageValue1 >; + using DerivedType = MessageValue1>; // Reserve some memory inside the render queue uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType)); @@ -1319,9 +1409,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& indices) +void UpdateManager::SetIndexBuffer(Render::Geometry* geometry, Render::Geometry::Uint16ContainerType& indices) { - using DerivedType = IndexBufferMessage; + using DerivedType = IndexBufferMessage; + + // 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; // Reserve some memory inside the render queue uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType)); @@ -1352,10 +1453,9 @@ void UpdateManager::AttachVertexBuffer(Render::Geometry* geometry, Render::Verte new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, vertexBuffer); } -void UpdateManager::AddTexture(OwnerPointer& texture) +void UpdateManager::AddTexture(const Render::TextureKey& texture) { - // Message has ownership of Texture while in transit from update -> render - using DerivedType = MessageValue1 >; + using DerivedType = MessageValue1; // Reserve some memory inside the render queue uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType)); @@ -1364,9 +1464,9 @@ void UpdateManager::AddTexture(OwnerPointer& texture) new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AddTexture, texture); } -void UpdateManager::RemoveTexture(Render::Texture* texture) +void UpdateManager::RemoveTexture(const Render::TextureKey& texture) { - using DerivedType = MessageValue1; + using DerivedType = MessageValue1; // Reserve some memory inside the render queue uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType)); @@ -1375,9 +1475,9 @@ void UpdateManager::RemoveTexture(Render::Texture* texture) 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; + using DerivedType = MessageValue3; // Reserve some memory inside the message queue uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType)); @@ -1386,9 +1486,9 @@ void UpdateManager::UploadTexture(Render::Texture* texture, PixelDataPtr pixelDa 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; + using DerivedType = MessageValue1; // Reserve some memory inside the render queue uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType)); @@ -1399,7 +1499,7 @@ void UpdateManager::GenerateMipmaps(Render::Texture* texture) void UpdateManager::AddFrameBuffer(OwnerPointer& frameBuffer) { - using DerivedType = MessageValue1 >; + using DerivedType = MessageValue1>; // Reserve some memory inside the render queue uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType)); @@ -1452,6 +1552,17 @@ void UpdateManager::AttachDepthStencilTextureToFrameBuffer(Render::FrameBuffer* new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AttachDepthStencilTextureToFrameBuffer, frameBuffer, texture, mipmapLevel); } +void UpdateManager::SetMultiSamplingLevelToFrameBuffer(Render::FrameBuffer* frameBuffer, uint8_t multiSamplingLevel) +{ + using DerivedType = MessageValue2; + + // 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, &RenderManager::SetMultiSamplingLevelToFrameBuffer, frameBuffer, multiSamplingLevel); +} + } // namespace SceneGraph } // namespace Internal