X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Fmanager%2Fupdate-manager.cpp;h=72304ef3e4f28ac408f5679b4a2591d20f30cde8;hb=4fc8109063295777c56c090736aedada518fcb2a;hp=abad3313adb14e716d805142d2f648cd9c15ea12;hpb=5abd8d9a30e5e1dfbd26cbec2c3d64d87128cd70;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 abad331..72304ef 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 @@ -44,20 +46,20 @@ //#define NODE_TREE_LOGGING 1 #if(defined(DEBUG_ENABLED) && defined(NODE_TREE_LOGGING)) -#define SNAPSHOT_NODE_LOGGING \ - const uint32_t FRAME_COUNT_TRIGGER = 16; \ - if(mImpl->frameCounter >= FRAME_COUNT_TRIGGER) \ - { \ - for(auto&& scene : mImpl->scenes) -{ - if(scene && scene->root) - { - mImpl->frameCounter = 0; - PrintNodeTree(*scene->root, mSceneGraphBuffers.GetUpdateBufferIndex(), ""); - } -} -} -mImpl->frameCounter++; +#define SNAPSHOT_NODE_LOGGING \ + const uint32_t FRAME_COUNT_TRIGGER = 16; \ + if(mImpl->frameCounter >= FRAME_COUNT_TRIGGER) \ + { \ + for(auto&& scene : mImpl->scenes) \ + { \ + if(scene && scene->root) \ + { \ + mImpl->frameCounter = 0; \ + PrintNodes(*scene->root, mSceneGraphBuffers.GetUpdateBufferIndex(), 0); \ + } \ + } \ + } \ + mImpl->frameCounter++; #else #define SNAPSHOT_NODE_LOGGING #endif @@ -88,8 +90,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 +108,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 +160,6 @@ struct UpdateManager::Impl Impl(NotificationManager& notificationManager, CompleteNotificationInterface& animationPlaylist, PropertyNotifier& propertyNotifier, - DiscardQueue& discardQueue, RenderController& renderController, RenderManager& renderManager, RenderQueue& renderQueue, @@ -163,7 +171,6 @@ struct UpdateManager::Impl animationPlaylist(animationPlaylist), propertyNotifier(propertyNotifier), shaderSaver(nullptr), - discardQueue(discardQueue), renderController(renderController), sceneController(nullptr), renderManager(renderManager), @@ -186,7 +193,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 +235,10 @@ struct UpdateManager::Impl scenes.clear(); delete sceneController; + + // Ensure to clear renderers + renderers.Clear(); + shaders.Clear(); } /** @@ -250,7 +261,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,16 +274,24 @@ 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 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 - 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. @@ -282,11 +300,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) @@ -302,7 +320,6 @@ private: UpdateManager::UpdateManager(NotificationManager& notificationManager, CompleteNotificationInterface& animationFinishedNotifier, PropertyNotifier& propertyNotifier, - DiscardQueue& discardQueue, RenderController& controller, RenderManager& renderManager, RenderQueue& renderQueue, @@ -312,7 +329,6 @@ UpdateManager::UpdateManager(NotificationManager& notificationManager, mImpl = new Impl(notificationManager, animationFinishedNotifier, propertyNotifier, - discardQueue, controller, renderManager, renderQueue, @@ -332,14 +348,14 @@ 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); + mImpl->scenes.emplace_back(new Impl::SceneInfo(rootLayer)); } @@ -357,7 +373,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(); @@ -370,6 +386,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); } @@ -384,6 +406,8 @@ void UpdateManager::ConnectNode(Node* parent, Node* node) parent->ConnectChild(node); + AddNodeResetter(*node); + // Inform the frame-callback-processor, if set, about the node-hierarchy changing if(mImpl->frameCallbackProcessor) { @@ -426,21 +450,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) @@ -475,7 +518,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; @@ -484,7 +531,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); } @@ -503,7 +550,7 @@ void UpdateManager::RemoveScene(Scene* scene) { 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; } } @@ -555,6 +602,13 @@ void UpdateManager::AddPropertyResetter(OwnerPointer& prop mImpl->propertyResetters.PushBack(propertyResetter.Release()); } +void UpdateManager::AddNodeResetter(const Node& node) +{ + OwnerPointer nodeResetter = SceneGraph::NodeResetter::New(node); + nodeResetter->Initialize(); + mImpl->nodeResetters.PushBack(nodeResetter.Release()); +} + void UpdateManager::AddPropertyNotification(OwnerPointer& propertyNotification) { mImpl->propertyNotifications.PushBack(propertyNotification.Release()); @@ -579,7 +633,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) @@ -598,27 +652,29 @@ 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()); + 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; } @@ -644,6 +700,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(); @@ -659,19 +730,36 @@ void UpdateManager::ResetProperties(BufferIndex bufferIndex) // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped mImpl->animationFinishedDuringUpdate = false; + // Reset node properties + std::vector nodeResetterToDelete; + for(auto&& element : mImpl->nodeResetters) + { + element->ResetToBaseValue(bufferIndex); + if(element->IsFinished()) + { + nodeResetterToDelete.push_back(element); + } + } + + // If a node resetter is no longer required, delete it. + for(auto&& elementPtr : nodeResetterToDelete) + { + mImpl->nodeResetters.EraseObject(elementPtr); + } + // Reset all animating / constrained properties - std::vector toDelete; + std::vector propertyResettertoDelete; for(auto&& element : mImpl->propertyResetters) { element->ResetToBaseValue(bufferIndex); if(element->IsFinished()) { - toDelete.push_back(element); + propertyResettertoDelete.push_back(element); } } - // If a resetter is no longer required (the animator or constraint has been removed), delete it. - for(auto&& elementPtr : toDelete) + // 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); } @@ -754,7 +842,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); @@ -825,9 +913,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; @@ -851,20 +940,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.. @@ -881,7 +985,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(); } @@ -891,7 +995,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 @@ -899,13 +1003,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) @@ -926,34 +1030,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 @@ -967,6 +1073,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) @@ -986,6 +1093,7 @@ uint32_t UpdateManager::Update(float elapsedSeconds, renderToFboEnabled, isRenderingToFbo); + mImpl->renderInstructionCapacity += scene->scene->GetRenderInstructions().GetCapacity(); scene->scene->SetSkipRendering(false); } else @@ -1001,36 +1109,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()); - } } } @@ -1060,6 +1171,20 @@ uint32_t UpdateManager::Update(float elapsedSeconds, return keepUpdating; } +void UpdateManager::PostRender() +{ + // Reset dirty flag + for(auto&& renderer : mImpl->renderers) + { + renderer->ResetDirtyFlag(); + } + + for(auto&& scene : mImpl->scenes) + { + scene->root->SetUpdatedTree(false); + } +} + uint32_t UpdateManager::KeepUpdatingCheck(float elapsedSeconds) const { // Update the duration set via Stage::KeepRendering() @@ -1137,19 +1262,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(); }); } } } @@ -1167,7 +1291,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)); @@ -1212,7 +1336,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)); @@ -1235,7 +1359,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)); @@ -1244,10 +1368,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)); @@ -1259,7 +1383,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)); @@ -1323,10 +1447,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)); @@ -1335,9 +1458,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)); @@ -1346,9 +1469,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)); @@ -1357,9 +1480,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)); @@ -1370,7 +1493,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)); @@ -1423,6 +1546,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