X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Fmanager%2Fupdate-manager.cpp;h=ce42bd75741cdf4ea21e832c014c5faff08ec0a9;hb=79881246746f65474b24ea4fe14151ccef8df3f4;hp=dbc71256b4bd5e3022b74b749c41c9556fd41d5f;hpb=b836da3012e648299bf46f536ddf704794e8f5f1;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 dbc7125..ce42bd7 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 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. @@ -71,12 +71,12 @@ const uint32_t FRAME_COUNT_TRIGGER = 16;\ if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\ {\ - for( auto root : mImpl->roots ) + for( auto&& scene : mImpl->scenes ) {\ - if ( NULL != root )\ + if ( scene && scene->root )\ {\ mImpl->frameCounter = 0;\ - PrintNodeTree( *root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\ + PrintNodeTree( *scene->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\ }\ }\ }\ @@ -87,6 +87,10 @@ mImpl->frameCounter++; #if defined(DEBUG_ENABLED) extern Debug::Filter* gRenderTaskLogFilter; +namespace +{ +Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_UPDATE_MANAGER" ); +} // unnamed namespace #endif @@ -152,6 +156,26 @@ void SortSiblingNodesRecursively( Node& node ) */ struct UpdateManager::Impl { + // SceneInfo keeps the root node of the Scene, its scene graph render task list, and the list of Layer pointers sorted by depth + struct SceneInfo + { + SceneInfo( Layer* root ) ///< Constructor + : root( root ) + { + } + + ~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 + SortedLayerPointers sortedLayerList; ///< List of Layer pointers sorted by depth (one list of sorted layers per root) + OwnerPointer< Scene > scene; ///< Scene graph object of the scene + }; + Impl( NotificationManager& notificationManager, CompleteNotificationInterface& animationPlaylist, PropertyNotifier& propertyNotifier, @@ -172,7 +196,6 @@ struct UpdateManager::Impl sceneController( NULL ), renderManager( renderManager ), renderQueue( renderQueue ), - renderInstructions( renderManager.GetRenderInstructionContainer() ), renderTaskProcessor( renderTaskProcessor ), backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ), renderers(), @@ -200,12 +223,15 @@ struct UpdateManager::Impl ~Impl() { // Disconnect render tasks from nodes, before destroying the nodes - for( auto taskList : taskLists ) + for( auto&& scene : scenes ) { - RenderTaskList::RenderTaskContainer& tasks = taskList->GetTasks(); - for ( auto&& task : tasks ) + if ( scene && scene->taskList ) { - task->SetSourceNode( NULL ); + RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks(); + for ( auto&& task : tasks ) + { + task->SetSourceNode( NULL ); + } } } @@ -219,10 +245,15 @@ struct UpdateManager::Impl Node::Delete(*iter); } - for( auto root : roots ) + for( auto&& scene : scenes ) { - root->OnDestroy(); + if ( scene && scene->root ) + { + scene->root->OnDestroy(); + Node::Delete( scene->root ); + } } + scenes.clear(); delete sceneController; } @@ -252,19 +283,15 @@ struct UpdateManager::Impl SceneControllerImpl* sceneController; ///< scene controller RenderManager& renderManager; ///< This is responsible for rendering the results of each "update" RenderQueue& renderQueue; ///< Used to queue messages for the next render - RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame. - OwnerContainer taskLists; ///< A container of scene graph render task lists - - OwnerContainer roots; ///< A container of root nodes (root is a layer). The layers are not stored in the node memory pool. + using SceneInfoPtr = std::unique_ptr< SceneInfo >; + std::vector< SceneInfoPtr > scenes; ///< A container of SceneInfo. Vector nodes; ///< A container of all instantiated nodes - std::vector sortedLayerLists; ///< A container of lists of Layer pointers sorted by depth (one list of sorted layers per root) - OwnerContainer< Camera* > cameras; ///< A container of cameras OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties) @@ -335,11 +362,37 @@ void UpdateManager::InstallRoot( OwnerPointer& layer ) Layer* rootLayer = layer.Release(); - DALI_ASSERT_DEBUG( std::find( mImpl->roots.begin(), mImpl->roots.end(), rootLayer ) == mImpl->roots.end() && "Root Node already installed" ); + 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); - mImpl->roots.PushBack( rootLayer ); + + mImpl->scenes.emplace_back( new Impl::SceneInfo( rootLayer ) ); +} + +void UpdateManager::UninstallRoot( Layer* layer ) +{ + DALI_ASSERT_DEBUG( layer->IsLayer() ); + DALI_ASSERT_DEBUG( layer->GetParent() == NULL ); + + for (auto iter = mImpl->scenes.begin(); iter != mImpl->scenes.end(); ++iter) + { + if( (*iter) && (*iter)->root == layer ) + { + mImpl->scenes.erase( iter ); + break; + } + } + + mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), layer ); + + // Notify the layer about impending destruction + layer->OnDestroy(); } void UpdateManager::AddNode( OwnerPointer& node ) @@ -348,6 +401,8 @@ void UpdateManager::AddNode( OwnerPointer& node ) // Nodes must be sorted by pointer Node* rawNode = node.Release(); + DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddNode\n", rawNode ); + Vector::Iterator begin = mImpl->nodes.Begin(); for( Vector::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter ) { @@ -366,6 +421,8 @@ void UpdateManager::ConnectNode( Node* parent, Node* node ) DALI_ASSERT_ALWAYS( NULL != node ); DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet + DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] ConnectNode\n", node ); + parent->ConnectChild( node ); // Inform the frame-callback-processor, if set, about the node-hierarchy changing @@ -377,6 +434,8 @@ void UpdateManager::ConnectNode( Node* parent, Node* node ) void UpdateManager::DisconnectNode( Node* node ) { + DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DisconnectNode\n", node ); + Node* parent = node->GetParent(); DALI_ASSERT_ALWAYS( NULL != parent ); parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused @@ -395,6 +454,8 @@ void UpdateManager::DestroyNode( Node* node ) DALI_ASSERT_ALWAYS( NULL != node ); DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected + DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DestroyNode\n", node ); + Vector::Iterator iter = mImpl->nodes.Begin()+1; Vector::Iterator endIter = mImpl->nodes.End(); for(;iter!=endIter;++iter) @@ -437,12 +498,56 @@ void UpdateManager::AddRenderTaskList( OwnerPointer& taskList ) { RenderTaskList* taskListPointer = taskList.Release(); taskListPointer->SetRenderMessageDispatcher( &mImpl->renderMessageDispatcher ); - mImpl->taskLists.PushBack( taskListPointer ); + + mImpl->scenes.back()->taskList = taskListPointer; } void UpdateManager::RemoveRenderTaskList( RenderTaskList* taskList ) { - mImpl->taskLists.EraseObject( taskList ); + for ( auto&& scene : mImpl->scenes ) + { + if ( scene && scene->taskList == taskList ) + { + scene->taskList.Reset(); + break; + } + } +} + +void UpdateManager::AddScene( OwnerPointer< Scene >& scene ) +{ + mImpl->scenes.back()->scene = scene.Release(); + + // Initialize the context from render manager + typedef MessageValue1< RenderManager, SceneGraph::Scene* > DerivedType; + + // 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 + SceneGraph::Scene& sceneObject = *mImpl->scenes.back()->scene; + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::InitializeScene, &sceneObject ); +} + +void UpdateManager::RemoveScene( Scene* scene ) +{ + // Initialize the context from render manager + typedef MessageValue1< RenderManager, SceneGraph::Scene* > DerivedType; + + // 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::UninitializeScene, scene ); + + for ( auto&& sceneInfo : mImpl->scenes ) + { + if ( sceneInfo && sceneInfo->scene && sceneInfo->scene.Get() == scene ) + { + sceneInfo->scene.Reset(); + break; + } + } } void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation ) @@ -552,6 +657,8 @@ void UpdateManager::SetShaderSaver( ShaderSaver& upstream ) void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer ) { + DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer.Get() ); + renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() ); mImpl->renderers.PushBack( renderer.Release() ); mImpl->renderersAdded = true; @@ -559,6 +666,8 @@ void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer ) void UpdateManager::RemoveRenderer( Renderer* renderer ) { + DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] RemoveRenderer\n", renderer ); + // Find the renderer and destroy it EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() ); // Need to remove the render object as well @@ -619,6 +728,13 @@ void UpdateManager::ResetProperties( BufferIndex bufferIndex ) mImpl->propertyResetters.EraseObject( elementPtr ); } + // Clear all root nodes dirty flags + for( auto& scene : mImpl->scenes ) + { + auto root = scene->root; + root->ResetDirtyFlags( bufferIndex ); + } + // Clear node dirty flags Vector::Iterator iter = mImpl->nodes.Begin()+1; Vector::Iterator endIter = mImpl->nodes.End(); @@ -694,12 +810,15 @@ void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex ) void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex ) { // Constrain render-tasks - for( auto taskList : mImpl->taskLists ) + for ( auto&& scene : mImpl->scenes ) { - RenderTaskList::RenderTaskContainer& tasks = taskList->GetTasks(); - for ( auto&& task : tasks ) + if ( scene && scene->taskList ) { - ConstrainPropertyOwner( *task, bufferIndex ); + RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks(); + for ( auto&& task : tasks ) + { + ConstrainPropertyOwner( *task, bufferIndex ); + } } } } @@ -765,13 +884,16 @@ void UpdateManager::UpdateNodes( BufferIndex bufferIndex ) { mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING; - for( auto&& rootLayer : mImpl->roots ) + for ( auto&& scene : mImpl->scenes ) { - // Prepare resources, update shaders, for each node - // And add the renderers to the sorted layers. Start from root, which is also a layer - mImpl->nodeDirtyFlags |= UpdateNodeTree( *rootLayer, - bufferIndex, - mImpl->renderQueue ); + if ( scene && scene->root ) + { + // Prepare resources, update shaders, for each node + // And add the renderers to the sorted layers. Start from root, which is also a layer + mImpl->nodeDirtyFlags |= UpdateNodeTree( *scene->root, + bufferIndex, + mImpl->renderQueue ); + } } } @@ -795,6 +917,7 @@ uint32_t UpdateManager::Update( float elapsedSeconds, mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR gestureUpdated; // ..a gesture property was updated + bool keepRendererRendering = false; // Although the scene-graph may not require an update, we still need to synchronize double-buffered // values if the scene was updated in the previous frame. @@ -825,11 +948,17 @@ uint32_t UpdateManager::Update( float elapsedSeconds, ConstrainCustomObjects( bufferIndex ); //Clear the lists of renderers from the previous update - for( auto sortedLayers : mImpl->sortedLayerLists ) + for( auto&& scene : mImpl->scenes ) { - for( auto&& layer : sortedLayers ) + if ( scene ) { - layer->ClearRenderables(); + for( auto&& layer : scene->sortedLayerList ) + { + if ( layer ) + { + layer->ClearRenderables(); + } + } } } @@ -867,61 +996,74 @@ uint32_t UpdateManager::Update( float elapsedSeconds, if( mImpl->renderersAdded ) { // Calculate how many render tasks we have in total - VectorBase::SizeType numberOfRenderTasks = 0; - - const VectorBase::SizeType taskListCount = mImpl->taskLists.Count(); - for ( VectorBase::SizeType index = 0u; index < taskListCount; index++ ) + std::size_t numberOfRenderTasks = 0; + for (auto&& scene : mImpl->scenes ) { - numberOfRenderTasks += mImpl->taskLists[index]->GetTasks().Count(); + if ( scene && scene->taskList ) + { + numberOfRenderTasks += scene->taskList->GetTasks().Count(); + } } - mImpl->renderInstructions.ResetAndReserve( bufferIndex, - static_cast( numberOfRenderTasks ) ); - for ( VectorBase::SizeType index = 0u; index < taskListCount; index++ ) + std::size_t numberOfRenderInstructions = 0; + for ( auto&& scene : mImpl->scenes ) { - if ( NULL != mImpl->roots[index] ) + if ( scene && scene->root && scene->taskList && scene->scene ) { - mImpl->renderTaskProcessor.Process( bufferIndex, - *mImpl->taskLists[index], - *mImpl->roots[index], - mImpl->sortedLayerLists[index], - mImpl->renderInstructions, + scene->scene->GetRenderInstructions().ResetAndReserve( bufferIndex, + static_cast( scene->taskList->GetTasks().Count() ) ); + + keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex, + *scene->taskList, + *scene->root, + scene->sortedLayerList, + *scene->scene->GetContext(), + scene->scene->GetRenderInstructions(), renderToFboEnabled, isRenderingToFbo ); + + numberOfRenderInstructions += scene->scene->GetRenderInstructions().Count( bufferIndex ); } } + + DALI_LOG_INFO( gLogFilter, Debug::General, + "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n", + numberOfRenderTasks, numberOfRenderInstructions ); } } - for( auto taskList : mImpl->taskLists ) + for ( auto&& scene : mImpl->scenes ) { - RenderTaskList::RenderTaskContainer& tasks = 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( taskList->GetCompleteNotificationInterface() ); - } } // Macro is undefined in release build. @@ -933,6 +1075,14 @@ uint32_t UpdateManager::Update( float elapsedSeconds, // Check whether further updates are required uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds ); + if( keepRendererRendering ) + { + keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING; + + // Set dirty flags for next frame to continue rendering + mImpl->nodeDirtyFlags |= RenderableUpdateFlags; + } + // tell the update manager that we're done so the queue can be given to event thread mImpl->notificationManager.UpdateCompleted(); @@ -979,28 +1129,28 @@ uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const return keepUpdatingRequest; } -void UpdateManager::SetBackgroundColor( const Vector4& color ) +void UpdateManager::SetDefaultSurfaceRect( const Rect& rect ) { - typedef MessageValue1< RenderManager, Vector4 > DerivedType; + mImpl->surfaceRectChanged = true; + + typedef MessageValue1< RenderManager, Rect > DerivedType; // 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::SetBackgroundColor, color ); + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect ); } -void UpdateManager::SetDefaultSurfaceRect( const Rect& rect ) +void UpdateManager::SurfaceReplaced( Scene* scene ) { - mImpl->surfaceRectChanged = true; - - typedef MessageValue1< RenderManager, Rect > DerivedType; + typedef MessageValue1< RenderManager, Scene* > DerivedType; // 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::SetDefaultSurfaceRect, rect ); + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SurfaceReplaced, scene ); } void UpdateManager::KeepRendering( float durationSeconds ) @@ -1015,18 +1165,11 @@ void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavio void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer ) { - const VectorBase::SizeType rootCount = mImpl->roots.Count(); - - // Make sure we reserve the correct size for the container so that - // we can save the sorted layers in the same order as the root layer - mImpl->sortedLayerLists.resize( rootCount ); - - for ( VectorBase::SizeType rootIndex = 0u; rootIndex < rootCount; rootIndex++ ) + for ( auto&& scene : mImpl->scenes ) { - Layer* root = mImpl->roots[rootIndex]; - if ( root == rootLayer ) + if ( scene && scene->root == rootLayer ) { - mImpl->sortedLayerLists[rootIndex] = layers; + scene->sortedLayerList = layers; break; } } @@ -1041,10 +1184,13 @@ void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths ) iter.node->SetDepthIndex( iter.sortedDepth ); } - for( auto root : mImpl->roots ) + for ( auto&& scene : mImpl->scenes ) { - // Go through node hierarchy and rearrange siblings according to depth-index - SortSiblingNodesRecursively( *root ); + if ( scene ) + { + // Go through node hierarchy and rearrange siblings according to depth-index + SortSiblingNodesRecursively( *scene->root ); + } } } @@ -1272,9 +1418,9 @@ void UpdateManager::GenerateMipmaps( Render::Texture* texture ) new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture ); } -void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer ) +void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer ) { - typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType; + typedef MessageValue1< RenderManager, OwnerPointer< Render::FrameBuffer > > DerivedType; // Reserve some memory inside the render queue uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );