/*
- * Copyright (c) 2019 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.
#include <dali/internal/update/manager/update-manager.h>
// INTERNAL INCLUDES
-#include <dali/public-api/common/stage.h>
-#include <dali/devel-api/common/owner-container.h>
-#include <dali/devel-api/threading/mutex.h>
-
#include <dali/integration-api/core.h>
-#include <dali/integration-api/render-controller.h>
-#include <dali/internal/common/shader-data.h>
-#include <dali/integration-api/debug.h>
-
-#include <dali/internal/common/core-impl.h>
-#include <dali/internal/common/message.h>
#include <dali/internal/event/common/notification-manager.h>
-#include <dali/internal/event/common/property-notification-impl.h>
#include <dali/internal/event/common/property-notifier.h>
#include <dali/internal/event/effects/shader-factory.h>
#include <dali/internal/event/animation/animation-playlist.h>
-#include <dali/internal/update/animation/scene-graph-animator.h>
-#include <dali/internal/update/animation/scene-graph-animation.h>
#include <dali/internal/update/common/discard-queue.h>
-#include <dali/internal/update/common/scene-graph-buffers.h>
#include <dali/internal/update/controllers/render-message-dispatcher.h>
#include <dali/internal/update/controllers/scene-controller-impl.h>
-#include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
#include <dali/internal/update/manager/frame-callback-processor.h>
#include <dali/internal/update/manager/render-task-processor.h>
-#include <dali/internal/update/manager/sorted-layers.h>
-#include <dali/internal/update/manager/scene-graph-frame-callback.h>
#include <dali/internal/update/manager/update-algorithms.h>
#include <dali/internal/update/manager/update-manager-debug.h>
#include <dali/internal/update/manager/transform-manager.h>
#include <dali/internal/update/nodes/node.h>
-#include <dali/internal/update/nodes/scene-graph-layer.h>
#include <dali/internal/update/queue/update-message-queue.h>
-#include <dali/internal/update/render-tasks/scene-graph-render-task.h>
-#include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
-#include <dali/internal/update/render-tasks/scene-graph-camera.h>
-#include <dali/internal/render/common/render-instruction-container.h>
#include <dali/internal/render/common/render-manager.h>
#include <dali/internal/render/queue/render-queue.h>
-#include <dali/internal/render/shaders/scene-graph-shader.h>
// Un-comment to enable node tree debug logging
//#define NODE_TREE_LOGGING 1
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(), "" );\
}\
}\
}\
*/
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,
transformManager(),
animationPlaylist( animationPlaylist ),
propertyNotifier( propertyNotifier ),
- shaderSaver( NULL ),
+ shaderSaver( nullptr ),
discardQueue( discardQueue ),
renderController( renderController ),
- sceneController( NULL ),
+ sceneController( nullptr ),
renderManager( renderManager ),
renderQueue( renderQueue ),
- renderInstructions( renderManager.GetRenderInstructionContainer() ),
renderTaskProcessor( renderTaskProcessor ),
- backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
+ backgroundColor( Dali::DEFAULT_BACKGROUND_COLOR ),
renderers(),
textureSets(),
shaders(),
- panGestureProcessor( NULL ),
+ panGestureProcessor( nullptr ),
messageQueue( renderController, sceneGraphBuffers ),
- frameCallbackProcessor( NULL ),
+ frameCallbackProcessor( nullptr ),
keepRenderingSeconds( 0.0f ),
nodeDirtyFlags( NodePropertyFlags::TRANSFORM ), // set to TransformFlag to ensure full update the first time through Update()
frameCounter( 0 ),
renderTaskWaiting( false ),
renderersAdded( false ),
surfaceRectChanged( false ),
- nodeDisconnected( false )
+ renderingRequired( false )
{
sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
// create first 'dummy' node
- nodes.PushBack(0u);
+ nodes.PushBack(nullptr);
}
~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( nullptr );
+ }
}
}
Node::Delete(*iter);
}
- for( auto root : roots )
+ for( auto&& scene : scenes )
{
- root->OnDestroy();
- Node::Delete(root);
+ if ( scene && scene->root )
+ {
+ scene->root->OnDestroy();
+ Node::Delete( scene->root );
+ }
}
+ scenes.clear();
delete sceneController;
}
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<RenderTaskList*> taskLists; ///< A container of scene graph render task lists
-
- Vector<Layer*> 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<Node*> nodes; ///< A container of all instantiated nodes
- std::vector<SortedLayerPointers> 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)
bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
bool renderersAdded; ///< Flag to keep track when renderers have been added to avoid unnecessary processing
bool surfaceRectChanged; ///< True if the default surface rect is changed
- bool nodeDisconnected; ///< True if a node is disconnected in the current update
+ bool renderingRequired; ///< True if required to render the current frame
private:
RenderManager& renderManager,
RenderQueue& renderQueue,
RenderTaskProcessor& renderTaskProcessor )
- : mImpl(NULL)
+ : mImpl(nullptr)
{
mImpl = new Impl( notificationManager,
animationFinishedNotifier,
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->roots )
+ for (auto iter = mImpl->scenes.begin(); iter != mImpl->scenes.end(); ++iter)
{
- if( ( *iter ) == layer )
+ if( (*iter) && (*iter)->root == layer )
{
- mImpl->roots.Erase( &iter );
+ mImpl->scenes.erase( iter );
break;
}
}
void UpdateManager::AddNode( OwnerPointer<Node>& node )
{
- DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
+ DALI_ASSERT_ALWAYS( nullptr == node->GetParent() ); // Should not have a parent yet
// Nodes must be sorted by pointer
Node* rawNode = node.Release();
void UpdateManager::ConnectNode( Node* parent, Node* node )
{
- DALI_ASSERT_ALWAYS( NULL != parent );
- DALI_ASSERT_ALWAYS( NULL != node );
- DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
+ DALI_ASSERT_ALWAYS( nullptr != parent );
+ DALI_ASSERT_ALWAYS( nullptr != node );
+ DALI_ASSERT_ALWAYS( nullptr == node->GetParent() ); // Should not have a parent yet
DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] ConnectNode\n", node );
{
DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DisconnectNode\n", node );
- mImpl->nodeDisconnected = true;
-
Node* parent = node->GetParent();
- DALI_ASSERT_ALWAYS( NULL != parent );
+ DALI_ASSERT_ALWAYS( nullptr != parent );
parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused
parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
void UpdateManager::DestroyNode( Node* node )
{
- DALI_ASSERT_ALWAYS( NULL != node );
- DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
+ DALI_ASSERT_ALWAYS( nullptr != node );
+ DALI_ASSERT_ALWAYS( nullptr == node->GetParent() ); // Should have been disconnected
DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DestroyNode\n", node );
{
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
+ using DerivedType = MessageValue1<RenderManager, SceneGraph::Scene*>;
+
+ // 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 )
+ {
+ mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), sceneInfo->scene.Release() ); // take the address of the reference to a pointer
+ break;
+ }
+ }
}
void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation )
{
if( shaderData )
{
-
- typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
+ using DerivedType = MessageValue3<Shader, Internal::ShaderDataPtr, ProgramCache*, bool>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
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<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
Vector<Node*>::Iterator endIter = mImpl->nodes.End();
return gestureUpdated;
}
-void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
+bool UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
{
+ bool animationActive = false;
+
auto&& iter = mImpl->animations.Begin();
bool animationLooped = false;
bool progressMarkerReached = false;
animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
+ animationActive = animationActive || animation->IsActive();
+
if ( progressMarkerReached )
{
mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
// The application should be notified by NotificationManager, in another thread
mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
}
+
+ return animationActive;
}
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 );
+ }
}
}
}
//Apply constraints
ConstrainPropertyOwner( *renderer, bufferIndex );
- renderer->PrepareRender( bufferIndex );
+ mImpl->renderingRequired = renderer->PrepareRender( bufferIndex ) || mImpl->renderingRequired;
}
}
{
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 );
+ }
}
}
//Clear nodes/resources which were previously discarded
mImpl->discardQueue.Clear( bufferIndex );
+ bool isAnimationRunning = IsAnimationRunning();
+
//Process Touches & Gestures
const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
bool updateScene = // The scene-graph requires an update if..
(mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
- IsAnimationRunning() || // ..at least one animation is running OR
+ isAnimationRunning || // ..at least one animation is running OR
mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
+ mImpl->frameCallbackProcessor || // ..a frame callback processor is existed OR
gestureUpdated; // ..a gesture property was updated
bool keepRendererRendering = false;
+ mImpl->renderingRequired = 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.
if( updateScene || mImpl->previousUpdateScene )
{
//Animate
- Animate( bufferIndex, elapsedSeconds );
+ bool animationActive = Animate( bufferIndex, elapsedSeconds );
//Constraint custom objects
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();
+ }
+ }
}
}
UpdateRenderers( bufferIndex );
//Update the transformations of all the nodes
- mImpl->transformManager.Update();
+ if ( mImpl->transformManager.Update() )
+ {
+ mImpl->nodeDirtyFlags |= NodePropertyFlags::TRANSFORM;
+ }
//Process Property Notifications
ProcessPropertyNotifications( bufferIndex );
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<uint32_t>( 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 )
{
- keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
- *mImpl->taskLists[index],
- *mImpl->roots[index],
- mImpl->sortedLayerLists[index],
- mImpl->renderInstructions,
- renderToFboEnabled,
- isRenderingToFbo );
+ scene->scene->GetRenderInstructions().ResetAndReserve( bufferIndex,
+ static_cast<uint32_t>( scene->taskList->GetTasks().Count() ) );
+
+ // If there are animations running, only add render instruction if at least one animation is currently active (i.e. not delayed)
+ // or the nodes are dirty
+ if ( !isAnimationRunning || animationActive || mImpl->renderingRequired || (mImpl->nodeDirtyFlags & RenderableUpdateFlags) )
+ {
+ keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
+ *scene->taskList,
+ *scene->root,
+ scene->sortedLayerList,
+ scene->scene->GetRenderInstructions(),
+ renderToFboEnabled,
+ isRenderingToFbo );
+
+ }
+
+ numberOfRenderInstructions += scene->scene->GetRenderInstructions().Count( bufferIndex );
}
}
DALI_LOG_INFO( gLogFilter, Debug::General,
- "Update: numberOfRenderTasks(%d), taskListCount(%d), Render Instructions(%d)\n",
- numberOfRenderTasks, taskListCount, mImpl->renderInstructions.Count( bufferIndex ) );
-
- // If a node has been disconnected in this update and we do not have any instructions to send, then generate a dummy instruction to force another render
- if( mImpl->nodeDisconnected && ( mImpl->renderInstructions.Count( bufferIndex ) == 0 ) )
- {
- DALI_LOG_INFO( gLogFilter, Debug::General, "Node disconnected, creating dummy instruction\n" );
- mImpl->renderInstructions.GetNextInstruction( bufferIndex ); // This creates and adds an empty instruction. We do not need to modify it.
- }
-
- mImpl->nodeDisconnected = false;
+ "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.
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
return keepUpdatingRequest;
}
-void UpdateManager::SetBackgroundColor( const Vector4& color )
+void UpdateManager::SetDefaultSurfaceRect( const Rect<int32_t>& rect )
{
- typedef MessageValue1< RenderManager, Vector4 > DerivedType;
+ mImpl->surfaceRectChanged = true;
+
+ using DerivedType = MessageValue1<RenderManager, Rect<int32_t> >;
// 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<int32_t>& rect )
+void UpdateManager::SurfaceReplaced( Scene* scene )
{
- mImpl->surfaceRectChanged = true;
-
- typedef MessageValue1< RenderManager, Rect<int32_t> > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, Scene*>;
// 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::SetDefaultSurfaceOrientation(int orientation)
+{
+ using DerivedType = MessageValue1<RenderManager, int>;
+
+ // Reserve some memory inside the render queue
+ unsigned int* 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::SetDefaultSurfaceOrientation, orientation);
}
void UpdateManager::KeepRendering( float durationSeconds )
mImpl->renderingBehavior = renderingBehavior;
}
-void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
+void UpdateManager::RequestRendering()
{
- 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 );
+ mImpl->renderingRequired = true;
+}
- for ( VectorBase::SizeType rootIndex = 0u; rootIndex < rootCount; rootIndex++ )
+void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
+{
+ 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;
}
}
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 );
+ }
}
}
void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
{
// Message has ownership of Sampler while in transit from update to render
- typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > DerivedType;
+ 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::RemoveSampler( Render::Sampler* sampler )
{
- typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, Render::Sampler*>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
{
- typedef MessageValue3< RenderManager, Render::Sampler*, uint32_t, uint32_t > DerivedType;
+ using DerivedType = MessageValue3<RenderManager, Render::Sampler*, uint32_t, uint32_t>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
{
- typedef MessageValue4< RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t > DerivedType;
+ using DerivedType = MessageValue4<RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
}
-void UpdateManager::AddPropertyBuffer( OwnerPointer< Render::PropertyBuffer >& propertyBuffer )
+void UpdateManager::AddVertexBuffer( OwnerPointer< Render::VertexBuffer >& vertexBuffer )
{
// Message has ownership of format while in transit from update -> render
- typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::VertexBuffer> >;
// 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::AddPropertyBuffer, propertyBuffer );
+ new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, vertexBuffer );
}
-void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
+void UpdateManager::RemoveVertexBuffer( Render::VertexBuffer* vertexBuffer )
{
- typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, Render::VertexBuffer*>;
// 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::RemovePropertyBuffer, propertyBuffer );
+ new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, vertexBuffer );
}
-void UpdateManager::SetPropertyBufferFormat( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Render::PropertyBuffer::Format>& format )
+void UpdateManager::SetVertexBufferFormat( Render::VertexBuffer* vertexBuffer, OwnerPointer< Render::VertexBuffer::Format>& format )
{
// Message has ownership of format while in transit from update -> render
- typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType;
+ 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 ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
+ new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetVertexBufferFormat, vertexBuffer, format );
}
-void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, 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
- typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<uint8_t> >, uint32_t > DerivedType;
+ 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 ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
+ new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetVertexBufferData, vertexBuffer, data, size );
}
void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
{
// Message has ownership of format while in transit from update -> render
- typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Geometry> >;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
{
- typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, Render::Geometry*>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
{
- typedef MessageValue2< RenderManager, Render::Geometry*, uint32_t > DerivedType;
+ using DerivedType = MessageValue2<RenderManager, Render::Geometry*, uint32_t>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
{
- typedef IndexBufferMessage< RenderManager > DerivedType;
+ using DerivedType = IndexBufferMessage<RenderManager>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
}
-void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
+void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
{
- typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
+ using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
// 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::RemoveVertexBuffer, geometry, propertyBuffer );
+ new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, vertexBuffer );
}
-void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
+void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
{
- typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
+ using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
// 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::AttachVertexBuffer, geometry, propertyBuffer );
+ new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, vertexBuffer );
}
void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
{
// Message has ownership of Texture while in transit from update -> render
- typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Texture> >;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
void UpdateManager::RemoveTexture( Render::Texture* texture)
{
- typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
{
- typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
+ using DerivedType = MessageValue3<RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams>;
// Reserve some memory inside the message queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
void UpdateManager::GenerateMipmaps( Render::Texture* texture )
{
- typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
{
- typedef MessageValue1< RenderManager, OwnerPointer< Render::FrameBuffer > > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::FrameBuffer> >;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
{
- typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, Render::FrameBuffer*>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
{
- typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t > DerivedType;
+ using DerivedType = MessageValue4<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t>;
// Reserve some memory inside the render queue
uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
}
+void UpdateManager::AttachDepthTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
+{
+ using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
+
+ // 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::AttachDepthTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
+}
+
+void UpdateManager::AttachDepthStencilTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
+{
+ using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
+
+ // 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::AttachDepthStencilTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
+}
+
} // namespace SceneGraph
} // namespace Internal