2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/update/manager/update-manager.h>
22 #include <dali/integration-api/core.h>
24 #include <dali/internal/event/common/notification-manager.h>
25 #include <dali/internal/event/common/property-notifier.h>
26 #include <dali/internal/event/effects/shader-factory.h>
27 #include <dali/internal/event/animation/animation-playlist.h>
29 #include <dali/internal/update/common/discard-queue.h>
30 #include <dali/internal/update/controllers/render-message-dispatcher.h>
31 #include <dali/internal/update/controllers/scene-controller-impl.h>
32 #include <dali/internal/update/manager/frame-callback-processor.h>
33 #include <dali/internal/update/manager/render-task-processor.h>
34 #include <dali/internal/update/manager/update-algorithms.h>
35 #include <dali/internal/update/manager/update-manager-debug.h>
36 #include <dali/internal/update/manager/transform-manager.h>
37 #include <dali/internal/update/nodes/node.h>
38 #include <dali/internal/update/queue/update-message-queue.h>
40 #include <dali/internal/render/common/render-manager.h>
41 #include <dali/internal/render/queue/render-queue.h>
43 // Un-comment to enable node tree debug logging
44 //#define NODE_TREE_LOGGING 1
46 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
47 #define SNAPSHOT_NODE_LOGGING \
48 const uint32_t FRAME_COUNT_TRIGGER = 16;\
49 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
51 for( auto&& scene : mImpl->scenes )
53 if ( scene && scene->root )\
55 mImpl->frameCounter = 0;\
56 PrintNodeTree( *scene->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
60 mImpl->frameCounter++;
62 #define SNAPSHOT_NODE_LOGGING
65 #if defined(DEBUG_ENABLED)
66 extern Debug::Filter* gRenderTaskLogFilter;
69 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_UPDATE_MANAGER" );
70 } // unnamed namespace
74 using namespace Dali::Integration;
75 using Dali::Internal::Update::MessageQueue;
89 * Helper to Erase an object from OwnerContainer using discard queue
90 * @param container to remove from
91 * @param object to remove
92 * @param discardQueue to put the object to
93 * @param updateBufferIndex to use
96 inline void EraseUsingDiscardQueue( OwnerContainer<T*>& container, T* object, DiscardQueue& discardQueue, BufferIndex updateBufferIndex )
98 DALI_ASSERT_DEBUG( object && "NULL object not allowed" );
100 // need to use the reference version of auto as we need the pointer to the pointer for the Release call below
101 for( auto&& iter : container )
103 if ( iter == object )
105 // Transfer ownership to the discard queue, this keeps the object alive, until the render-thread has finished with it
106 discardQueue.Add( updateBufferIndex, container.Release( &iter ) ); // take the address of the reference to a pointer (iter)
107 return; // return as we only ever remove one object. Iterators to container are now invalidated as well so cannot continue
113 * Descends into node's hierarchy and sorts the children of each child according to their depth-index.
114 * @param[in] node The node whose hierarchy to descend
116 void SortSiblingNodesRecursively( Node& node )
118 NodeContainer& container = node.GetChildren();
119 std::sort( container.Begin(), container.End(),
120 []( Node* a, Node* b ) { return a->GetDepthIndex() < b->GetDepthIndex(); } );
122 // Descend tree and sort as well
123 for( auto&& iter : container )
125 SortSiblingNodesRecursively( *iter );
129 } // unnamed namespace
132 * Structure to contain UpdateManager internal data
134 struct UpdateManager::Impl
136 // SceneInfo keeps the root node of the Scene, its scene graph render task list, and the list of Layer pointers sorted by depth
139 SceneInfo( Layer* root ) ///< Constructor
144 ~SceneInfo() = default; ///< Default non-virtual destructor
145 SceneInfo( SceneInfo&& rhs ) = default; ///< Move constructor
146 SceneInfo& operator=( SceneInfo&& rhs ) = default; ///< Move assignment operator
147 SceneInfo& operator=( const SceneInfo& rhs ) = delete; ///< Assignment operator
148 SceneInfo( const SceneInfo& rhs ) = delete; ///< Copy constructor
150 Layer* root{ nullptr }; ///< Root node (root is a layer). The layer is not stored in the node memory pool.
151 OwnerPointer< RenderTaskList > taskList; ///< Scene graph render task list
152 SortedLayerPointers sortedLayerList; ///< List of Layer pointers sorted by depth (one list of sorted layers per root)
153 OwnerPointer< Scene > scene; ///< Scene graph object of the scene
156 Impl( NotificationManager& notificationManager,
157 CompleteNotificationInterface& animationPlaylist,
158 PropertyNotifier& propertyNotifier,
159 DiscardQueue& discardQueue,
160 RenderController& renderController,
161 RenderManager& renderManager,
162 RenderQueue& renderQueue,
163 SceneGraphBuffers& sceneGraphBuffers,
164 RenderTaskProcessor& renderTaskProcessor )
165 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
166 notificationManager( notificationManager ),
168 animationPlaylist( animationPlaylist ),
169 propertyNotifier( propertyNotifier ),
170 shaderSaver( nullptr ),
171 discardQueue( discardQueue ),
172 renderController( renderController ),
173 sceneController( nullptr ),
174 renderManager( renderManager ),
175 renderQueue( renderQueue ),
176 renderTaskProcessor( renderTaskProcessor ),
177 backgroundColor( Dali::DEFAULT_BACKGROUND_COLOR ),
181 panGestureProcessor( nullptr ),
182 messageQueue( renderController, sceneGraphBuffers ),
183 frameCallbackProcessor( nullptr ),
184 keepRenderingSeconds( 0.0f ),
185 nodeDirtyFlags( NodePropertyFlags::TRANSFORM ), // set to TransformFlag to ensure full update the first time through Update()
187 renderingBehavior( DevelStage::Rendering::IF_REQUIRED ),
188 animationFinishedDuringUpdate( false ),
189 previousUpdateScene( false ),
190 renderTaskWaiting( false ),
191 renderersAdded( false ),
192 surfaceRectChanged( false ),
193 renderingRequired( false )
195 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
197 // create first 'dummy' node
198 nodes.PushBack(nullptr);
203 // Disconnect render tasks from nodes, before destroying the nodes
204 for( auto&& scene : scenes )
206 if ( scene && scene->taskList )
208 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
209 for ( auto&& task : tasks )
211 task->SetSourceNode( nullptr );
216 // UpdateManager owns the Nodes. Although Nodes are pool allocated they contain heap allocated parts
217 // like custom properties, which get released here
218 Vector<Node*>::Iterator iter = nodes.Begin()+1;
219 Vector<Node*>::Iterator endIter = nodes.End();
220 for(;iter!=endIter;++iter)
222 (*iter)->OnDestroy();
226 for( auto&& scene : scenes )
228 if ( scene && scene->root )
230 scene->root->OnDestroy();
231 Node::Delete( scene->root );
236 delete sceneController;
240 * Lazy init for FrameCallbackProcessor.
241 * @param[in] updateManager A reference to the update-manager
243 FrameCallbackProcessor& GetFrameCallbackProcessor( UpdateManager& updateManager )
245 if( ! frameCallbackProcessor )
247 frameCallbackProcessor = new FrameCallbackProcessor( updateManager, transformManager );
249 return *frameCallbackProcessor;
252 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
253 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
254 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
255 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
256 CompleteNotificationInterface& animationPlaylist; ///< Holds handles to all the animations
257 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
258 ShaderSaver* shaderSaver; ///< Saves shader binaries.
259 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
260 RenderController& renderController; ///< render controller
261 SceneControllerImpl* sceneController; ///< scene controller
262 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
263 RenderQueue& renderQueue; ///< Used to queue messages for the next render
264 RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
266 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
268 using SceneInfoPtr = std::unique_ptr< SceneInfo >;
269 std::vector< SceneInfoPtr > scenes; ///< A container of SceneInfo.
271 Vector<Node*> nodes; ///< A container of all instantiated nodes
273 OwnerContainer< Camera* > cameras; ///< A container of cameras
274 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
276 OwnerContainer< PropertyResetterBase* > propertyResetters; ///< A container of property resetters
277 OwnerContainer< Animation* > animations; ///< A container of owned animations
278 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
279 OwnerContainer< Renderer* > renderers; ///< A container of owned renderers
280 OwnerContainer< TextureSet* > textureSets; ///< A container of owned texture sets
281 OwnerContainer< Shader* > shaders; ///< A container of owned shaders
282 OwnerPointer< PanGesture > panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager
284 MessageQueue messageQueue; ///< The messages queued from the event-thread
285 std::vector<Internal::ShaderDataPtr> renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
286 std::vector<Internal::ShaderDataPtr> updateCompiledShaders; ///< Shaders to be sent from Update to Event
287 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
289 OwnerPointer<FrameCallbackProcessor> frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required.
291 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
292 NodePropertyFlags nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
293 uint32_t frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
295 DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior
297 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
298 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
299 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
300 bool renderersAdded; ///< Flag to keep track when renderers have been added to avoid unnecessary processing
301 bool surfaceRectChanged; ///< True if the default surface rect is changed
302 bool renderingRequired; ///< True if required to render the current frame
306 Impl( const Impl& ); ///< Undefined
307 Impl& operator=( const Impl& ); ///< Undefined
310 UpdateManager::UpdateManager( NotificationManager& notificationManager,
311 CompleteNotificationInterface& animationFinishedNotifier,
312 PropertyNotifier& propertyNotifier,
313 DiscardQueue& discardQueue,
314 RenderController& controller,
315 RenderManager& renderManager,
316 RenderQueue& renderQueue,
317 RenderTaskProcessor& renderTaskProcessor )
320 mImpl = new Impl( notificationManager,
321 animationFinishedNotifier,
328 renderTaskProcessor );
332 UpdateManager::~UpdateManager()
337 void UpdateManager::InstallRoot( OwnerPointer<Layer>& layer )
339 DALI_ASSERT_DEBUG( layer->IsLayer() );
340 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
342 Layer* rootLayer = layer.Release();
344 DALI_ASSERT_DEBUG( std::find_if( mImpl->scenes.begin(), mImpl->scenes.end(),
345 [rootLayer]( Impl::SceneInfoPtr& scene )
347 return scene && scene->root == rootLayer;
349 ) == mImpl->scenes.end() && "Root Node already installed" );
351 rootLayer->CreateTransform( &mImpl->transformManager );
352 rootLayer->SetRoot(true);
354 mImpl->scenes.emplace_back( new Impl::SceneInfo( rootLayer ) );
357 void UpdateManager::UninstallRoot( Layer* layer )
359 DALI_ASSERT_DEBUG( layer->IsLayer() );
360 DALI_ASSERT_DEBUG( layer->GetParent() == NULL );
362 for (auto iter = mImpl->scenes.begin(); iter != mImpl->scenes.end(); ++iter)
364 if( (*iter) && (*iter)->root == layer )
366 mImpl->scenes.erase( iter );
371 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), layer );
373 // Notify the layer about impending destruction
377 void UpdateManager::AddNode( OwnerPointer<Node>& node )
379 DALI_ASSERT_ALWAYS( nullptr == node->GetParent() ); // Should not have a parent yet
381 // Nodes must be sorted by pointer
382 Node* rawNode = node.Release();
383 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddNode\n", rawNode );
385 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
386 for( Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter )
388 if( rawNode > (*iter) )
390 mImpl->nodes.Insert((iter+1), rawNode );
391 rawNode->CreateTransform( &mImpl->transformManager );
397 void UpdateManager::ConnectNode( Node* parent, Node* node )
399 DALI_ASSERT_ALWAYS( nullptr != parent );
400 DALI_ASSERT_ALWAYS( nullptr != node );
401 DALI_ASSERT_ALWAYS( nullptr == node->GetParent() ); // Should not have a parent yet
403 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] ConnectNode\n", node );
405 parent->ConnectChild( node );
407 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
408 if( mImpl->frameCallbackProcessor )
410 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
414 void UpdateManager::DisconnectNode( Node* node )
416 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DisconnectNode\n", node );
418 Node* parent = node->GetParent();
419 DALI_ASSERT_ALWAYS( nullptr != parent );
420 parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused
422 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
424 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
425 if( mImpl->frameCallbackProcessor )
427 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
431 void UpdateManager::DestroyNode( Node* node )
433 DALI_ASSERT_ALWAYS( nullptr != node );
434 DALI_ASSERT_ALWAYS( nullptr == node->GetParent() ); // Should have been disconnected
436 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DestroyNode\n", node );
438 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
439 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
440 for(;iter!=endIter;++iter)
444 mImpl->nodes.Erase(iter);
449 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
451 // Notify the Node about impending destruction
455 void UpdateManager::AddCamera( OwnerPointer< Camera >& camera )
457 mImpl->cameras.PushBack( camera.Release() ); // takes ownership
460 void UpdateManager::RemoveCamera( Camera* camera )
462 // Find the camera and destroy it
463 EraseUsingDiscardQueue( mImpl->cameras, camera, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
466 void UpdateManager::AddObject( OwnerPointer<PropertyOwner>& object )
468 mImpl->customObjects.PushBack( object.Release() );
471 void UpdateManager::RemoveObject( PropertyOwner* object )
473 mImpl->customObjects.EraseObject( object );
476 void UpdateManager::AddRenderTaskList( OwnerPointer<RenderTaskList>& taskList )
478 RenderTaskList* taskListPointer = taskList.Release();
479 taskListPointer->SetRenderMessageDispatcher( &mImpl->renderMessageDispatcher );
481 mImpl->scenes.back()->taskList = taskListPointer;
484 void UpdateManager::RemoveRenderTaskList( RenderTaskList* taskList )
486 for ( auto&& scene : mImpl->scenes )
488 if ( scene && scene->taskList == taskList )
490 scene->taskList.Reset();
496 void UpdateManager::AddScene( OwnerPointer< Scene >& scene )
498 mImpl->scenes.back()->scene = scene.Release();
500 // Initialize the context from render manager
501 typedef MessageValue1< RenderManager, SceneGraph::Scene* > DerivedType;
503 // Reserve some memory inside the render queue
504 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
506 // Construct message in the render queue memory; note that delete should not be called on the return value
507 SceneGraph::Scene& sceneObject = *mImpl->scenes.back()->scene;
508 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::InitializeScene, &sceneObject );
511 void UpdateManager::RemoveScene( Scene* scene )
513 // Initialize the context from render manager
514 using DerivedType = MessageValue1<RenderManager, SceneGraph::Scene*>;
516 // Reserve some memory inside the render queue
517 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
519 // Construct message in the render queue memory; note that delete should not be called on the return value
520 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UninitializeScene, scene );
522 for ( auto&& sceneInfo : mImpl->scenes )
524 if ( sceneInfo && sceneInfo->scene && sceneInfo->scene.Get() == scene )
526 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), sceneInfo->scene.Release() ); // take the address of the reference to a pointer
532 void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation )
534 mImpl->animations.PushBack( animation.Release() );
537 void UpdateManager::StopAnimation( Animation* animation )
539 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
541 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
543 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
546 void UpdateManager::RemoveAnimation( Animation* animation )
548 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
550 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
552 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
555 bool UpdateManager::IsAnimationRunning() const
557 // Find any animation that isn't stopped or paused
558 for ( auto&& iter : mImpl->animations )
560 const Animation::State state = iter->GetState();
562 if (state != Animation::Stopped &&
563 state != Animation::Paused)
565 return true; // stop iteration as soon as first one is found
572 void UpdateManager::AddPropertyResetter( OwnerPointer<PropertyResetterBase>& propertyResetter )
574 propertyResetter->Initialize();
575 mImpl->propertyResetters.PushBack( propertyResetter.Release() );
578 void UpdateManager::AddPropertyNotification( OwnerPointer< PropertyNotification >& propertyNotification )
580 mImpl->propertyNotifications.PushBack( propertyNotification.Release() );
583 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
585 mImpl->propertyNotifications.EraseObject( propertyNotification );
588 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
590 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
591 propertyNotification->SetNotifyMode( notifyMode );
594 void UpdateManager::AddShader( OwnerPointer< Shader >& shader )
596 mImpl->shaders.PushBack( shader.Release() );
599 void UpdateManager::RemoveShader( Shader* shader )
601 // Find the shader and destroy it
602 EraseUsingDiscardQueue( mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
605 void UpdateManager::SetShaderProgram( Shader* shader,
606 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
610 using DerivedType = MessageValue3<Shader, Internal::ShaderDataPtr, ProgramCache*, bool>;
612 // Reserve some memory inside the render queue
613 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
615 // Construct message in the render queue memory; note that delete should not be called on the return value
616 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
620 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
622 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
623 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
625 // lock as update might be sending previously compiled shaders to event thread
626 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
627 mImpl->renderCompiledShaders.push_back( shaderData );
631 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
633 mImpl->shaderSaver = &upstream;
636 void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer )
638 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer.Get() );
640 renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
641 mImpl->renderers.PushBack( renderer.Release() );
642 mImpl->renderersAdded = true;
645 void UpdateManager::RemoveRenderer( Renderer* renderer )
647 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] RemoveRenderer\n", renderer );
649 // Find the renderer and destroy it
650 EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
651 // Need to remove the render object as well
652 renderer->DisconnectFromSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
655 void UpdateManager::SetPanGestureProcessor( PanGesture* panGestureProcessor )
657 DALI_ASSERT_DEBUG( NULL != panGestureProcessor );
659 mImpl->panGestureProcessor = panGestureProcessor;
662 void UpdateManager::AddTextureSet( OwnerPointer< TextureSet >& textureSet )
664 mImpl->textureSets.PushBack( textureSet.Release() );
667 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
669 mImpl->textureSets.EraseObject( textureSet );
672 uint32_t* UpdateManager::ReserveMessageSlot( uint32_t size, bool updateScene )
674 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
677 void UpdateManager::EventProcessingStarted()
679 mImpl->messageQueue.EventProcessingStarted();
682 bool UpdateManager::FlushQueue()
684 return mImpl->messageQueue.FlushQueue();
687 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
689 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
690 mImpl->animationFinishedDuringUpdate = false;
692 // Reset all animating / constrained properties
693 std::vector<PropertyResetterBase*>toDelete;
694 for( auto&& element : mImpl->propertyResetters )
696 element->ResetToBaseValue( bufferIndex );
697 if( element->IsFinished() )
699 toDelete.push_back( element );
703 // If a resetter is no longer required (the animator or constraint has been removed), delete it.
704 for( auto&& elementPtr : toDelete )
706 mImpl->propertyResetters.EraseObject( elementPtr );
709 // Clear all root nodes dirty flags
710 for( auto& scene : mImpl->scenes )
712 auto root = scene->root;
713 root->ResetDirtyFlags( bufferIndex );
716 // Clear node dirty flags
717 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
718 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
719 for( ;iter != endIter; ++iter )
721 (*iter)->ResetDirtyFlags( bufferIndex );
725 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds )
727 bool gestureUpdated( false );
729 if( mImpl->panGestureProcessor )
731 // gesture processor only supports default properties
732 mImpl->panGestureProcessor->ResetDefaultProperties( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
733 gestureUpdated |= mImpl->panGestureProcessor->UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
736 return gestureUpdated;
739 bool UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
741 bool animationActive = false;
743 auto&& iter = mImpl->animations.Begin();
744 bool animationLooped = false;
746 while ( iter != mImpl->animations.End() )
748 Animation* animation = *iter;
749 bool finished = false;
751 bool progressMarkerReached = false;
752 animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
754 animationActive = animationActive || animation->IsActive();
756 if ( progressMarkerReached )
758 mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
761 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
762 animationLooped = animationLooped || looped;
764 // Remove animations that had been destroyed but were still waiting for an update
765 if (animation->GetState() == Animation::Destroyed)
767 iter = mImpl->animations.Erase(iter);
775 // queue the notification on finished or looped (to update loop count)
776 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
778 // The application should be notified by NotificationManager, in another thread
779 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
782 return animationActive;
785 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
787 //Constrain custom objects (in construction order)
788 for ( auto&& object : mImpl->customObjects )
790 ConstrainPropertyOwner( *object, bufferIndex );
794 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
796 // Constrain render-tasks
797 for ( auto&& scene : mImpl->scenes )
799 if ( scene && scene->taskList )
801 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
802 for ( auto&& task : tasks )
804 ConstrainPropertyOwner( *task, bufferIndex );
810 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
812 // constrain shaders... (in construction order)
813 for ( auto&& shader : mImpl->shaders )
815 ConstrainPropertyOwner( *shader, bufferIndex );
819 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
821 for( auto&& notification : mImpl->propertyNotifications )
823 bool valid = notification->Check( bufferIndex );
826 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
831 void UpdateManager::ForwardCompiledShadersToEventThread()
833 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
834 if( mImpl->shaderSaver )
836 // lock and swap the queues
838 // render might be attempting to send us more binaries at the same time
839 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
840 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
843 if( mImpl->updateCompiledShaders.size() > 0 )
845 ShaderSaver& factory = *mImpl->shaderSaver;
846 for( auto&& shader : mImpl->updateCompiledShaders )
848 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, shader ) );
850 // we don't need them in update anymore
851 mImpl->updateCompiledShaders.clear();
856 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
858 for( auto&& renderer : mImpl->renderers )
861 ConstrainPropertyOwner( *renderer, bufferIndex );
863 mImpl->renderingRequired = renderer->PrepareRender( bufferIndex ) || mImpl->renderingRequired;
867 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
869 mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
871 for ( auto&& scene : mImpl->scenes )
873 if ( scene && scene->root )
875 // Prepare resources, update shaders, for each node
876 // And add the renderers to the sorted layers. Start from root, which is also a layer
877 mImpl->nodeDirtyFlags |= UpdateNodeTree( *scene->root,
879 mImpl->renderQueue );
884 uint32_t UpdateManager::Update( float elapsedSeconds,
885 uint32_t lastVSyncTimeMilliseconds,
886 uint32_t nextVSyncTimeMilliseconds,
887 bool renderToFboEnabled,
888 bool isRenderingToFbo )
890 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
892 //Clear nodes/resources which were previously discarded
893 mImpl->discardQueue.Clear( bufferIndex );
895 bool isAnimationRunning = IsAnimationRunning();
897 //Process Touches & Gestures
898 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
900 bool updateScene = // The scene-graph requires an update if..
901 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
902 isAnimationRunning || // ..at least one animation is running OR
903 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
904 mImpl->frameCallbackProcessor || // ..a frame callback processor is existed OR
905 gestureUpdated; // ..a gesture property was updated
907 bool keepRendererRendering = false;
908 mImpl->renderingRequired = false;
910 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
911 // values if the scene was updated in the previous frame.
912 if( updateScene || mImpl->previousUpdateScene )
914 //Reset properties from the previous update
915 ResetProperties( bufferIndex );
916 mImpl->transformManager.ResetToBaseValue();
919 // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
920 // between calling IsSceneUpdateRequired() above and here, so updateScene should
922 updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
924 //Forward compiled shader programs to event thread for saving
925 ForwardCompiledShadersToEventThread();
927 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
928 // renderer lists if the scene was updated in the previous frame.
929 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
930 if( updateScene || mImpl->previousUpdateScene )
933 bool animationActive = Animate( bufferIndex, elapsedSeconds );
935 //Constraint custom objects
936 ConstrainCustomObjects( bufferIndex );
938 //Clear the lists of renderers from the previous update
939 for( auto&& scene : mImpl->scenes )
943 for( auto&& layer : scene->sortedLayerList )
947 layer->ClearRenderables();
953 // Call the frame-callback-processor if set
954 if( mImpl->frameCallbackProcessor )
956 mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
959 //Update node hierarchy, apply constraints and perform sorting / culling.
960 //This will populate each Layer with a list of renderers which are ready.
961 UpdateNodes( bufferIndex );
963 //Apply constraints to RenderTasks, shaders
964 ConstrainRenderTasks( bufferIndex );
965 ConstrainShaders( bufferIndex );
967 //Update renderers and apply constraints
968 UpdateRenderers( bufferIndex );
970 //Update the transformations of all the nodes
971 if ( mImpl->transformManager.Update() )
973 mImpl->nodeDirtyFlags |= NodePropertyFlags::TRANSFORM;
976 //Process Property Notifications
977 ProcessPropertyNotifications( bufferIndex );
980 for( auto&& cameraIterator : mImpl->cameras )
982 cameraIterator->Update( bufferIndex );
985 //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
986 //reset the update buffer index and make sure there is enough room in the instruction container
987 if( mImpl->renderersAdded )
989 // Calculate how many render tasks we have in total
990 std::size_t numberOfRenderTasks = 0;
991 for (auto&& scene : mImpl->scenes )
993 if ( scene && scene->taskList )
995 numberOfRenderTasks += scene->taskList->GetTasks().Count();
999 std::size_t numberOfRenderInstructions = 0;
1000 for ( auto&& scene : mImpl->scenes )
1002 if ( scene && scene->root && scene->taskList && scene->scene )
1004 scene->scene->GetRenderInstructions().ResetAndReserve( bufferIndex,
1005 static_cast<uint32_t>( scene->taskList->GetTasks().Count() ) );
1007 // If there are animations running, only add render instruction if at least one animation is currently active (i.e. not delayed)
1008 // or the nodes are dirty
1009 if ( !isAnimationRunning || animationActive || mImpl->renderingRequired || (mImpl->nodeDirtyFlags & RenderableUpdateFlags) )
1011 keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
1014 scene->sortedLayerList,
1015 scene->scene->GetRenderInstructions(),
1021 numberOfRenderInstructions += scene->scene->GetRenderInstructions().Count( bufferIndex );
1025 DALI_LOG_INFO( gLogFilter, Debug::General,
1026 "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n",
1027 numberOfRenderTasks, numberOfRenderInstructions );
1031 for ( auto&& scene : mImpl->scenes )
1033 if ( scene && scene->root && scene->taskList )
1035 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
1037 // check the countdown and notify
1038 bool doRenderOnceNotify = false;
1039 mImpl->renderTaskWaiting = false;
1040 for ( auto&& renderTask : tasks )
1042 renderTask->UpdateState();
1044 if( renderTask->IsWaitingToRender() &&
1045 renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1047 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1050 if( renderTask->HasRendered() )
1052 doRenderOnceNotify = true;
1056 if( doRenderOnceNotify )
1058 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1059 mImpl->notificationManager.QueueCompleteNotification( scene->taskList->GetCompleteNotificationInterface() );
1064 // Macro is undefined in release build.
1065 SNAPSHOT_NODE_LOGGING;
1067 // A ResetProperties() may be required in the next frame
1068 mImpl->previousUpdateScene = updateScene;
1070 // Check whether further updates are required
1071 uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1073 if( keepRendererRendering )
1075 keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
1077 // Set dirty flags for next frame to continue rendering
1078 mImpl->nodeDirtyFlags |= RenderableUpdateFlags;
1081 // tell the update manager that we're done so the queue can be given to event thread
1082 mImpl->notificationManager.UpdateCompleted();
1084 // The update has finished; swap the double-buffering indices
1085 mSceneGraphBuffers.Swap();
1087 return keepUpdating;
1090 uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1092 // Update the duration set via Stage::KeepRendering()
1093 if ( mImpl->keepRenderingSeconds > 0.0f )
1095 mImpl->keepRenderingSeconds -= elapsedSeconds;
1098 uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1100 // If the rendering behavior is set to continuously render, then continue to render.
1101 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1102 // Keep updating until no messages are received and no animations are running.
1103 // If an animation has just finished, update at least once more for Discard end-actions.
1104 // No need to check for renderQueue as there is always a render after update and if that
1105 // render needs another update it will tell the adaptor to call update again
1107 if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
1108 ( mImpl->keepRenderingSeconds > 0.0f ) )
1110 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1113 if ( IsAnimationRunning() ||
1114 mImpl->animationFinishedDuringUpdate )
1116 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1119 if ( mImpl->renderTaskWaiting )
1121 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1124 return keepUpdatingRequest;
1127 void UpdateManager::SetDefaultSurfaceRect( const Rect<int32_t>& rect )
1129 mImpl->surfaceRectChanged = true;
1131 using DerivedType = MessageValue1<RenderManager, Rect<int32_t> >;
1133 // Reserve some memory inside the render queue
1134 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1136 // Construct message in the render queue memory; note that delete should not be called on the return value
1137 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1140 void UpdateManager::SurfaceReplaced( Scene* scene )
1142 using DerivedType = MessageValue1<RenderManager, Scene*>;
1144 // Reserve some memory inside the render queue
1145 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1147 // Construct message in the render queue memory; note that delete should not be called on the return value
1148 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SurfaceReplaced, scene );
1151 void UpdateManager::KeepRendering( float durationSeconds )
1153 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1156 void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
1158 mImpl->renderingBehavior = renderingBehavior;
1161 void UpdateManager::RequestRendering()
1163 mImpl->renderingRequired = true;
1166 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
1168 for ( auto&& scene : mImpl->scenes )
1170 if ( scene && scene->root == rootLayer )
1172 scene->sortedLayerList = layers;
1178 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1180 // note,this vector is already in depth order. It could be used as-is to
1181 // remove sorting in update algorithm. However, it lacks layer boundary markers.
1182 for( auto&& iter : nodeDepths->nodeDepths )
1184 iter.node->SetDepthIndex( iter.sortedDepth );
1187 for ( auto&& scene : mImpl->scenes )
1191 // Go through node hierarchy and rearrange siblings according to depth-index
1192 SortSiblingNodesRecursively( *scene->root );
1197 bool UpdateManager::IsDefaultSurfaceRectChanged()
1199 bool surfaceRectChanged = mImpl->surfaceRectChanged;
1202 mImpl->surfaceRectChanged = false;
1204 return surfaceRectChanged;
1207 void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode )
1209 mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode );
1212 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1214 mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback );
1217 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1219 // Message has ownership of Sampler while in transit from update to render
1220 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Sampler> >;
1222 // Reserve some memory inside the render queue
1223 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1225 // Construct message in the render queue memory; note that delete should not be called on the return value
1226 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1229 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1231 using DerivedType = MessageValue1<RenderManager, Render::Sampler*>;
1233 // Reserve some memory inside the render queue
1234 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1236 // Construct message in the render queue memory; note that delete should not be called on the return value
1237 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1240 void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
1242 using DerivedType = MessageValue3<RenderManager, Render::Sampler*, uint32_t, uint32_t>;
1244 // Reserve some memory inside the render queue
1245 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1247 // Construct message in the render queue memory; note that delete should not be called on the return value
1248 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1251 void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
1253 using DerivedType = MessageValue4<RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t>;
1255 // Reserve some memory inside the render queue
1256 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1258 // Construct message in the render queue memory; note that delete should not be called on the return value
1259 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1262 void UpdateManager::AddVertexBuffer( OwnerPointer< Render::VertexBuffer >& vertexBuffer )
1264 // Message has ownership of format while in transit from update -> render
1265 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::VertexBuffer> >;
1267 // Reserve some memory inside the render queue
1268 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1270 // Construct message in the render queue memory; note that delete should not be called on the return value
1271 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, vertexBuffer );
1274 void UpdateManager::RemoveVertexBuffer( Render::VertexBuffer* vertexBuffer )
1276 using DerivedType = MessageValue1<RenderManager, Render::VertexBuffer*>;
1278 // Reserve some memory inside the render queue
1279 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1281 // Construct message in the render queue memory; note that delete should not be called on the return value
1282 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, vertexBuffer );
1285 void UpdateManager::SetVertexBufferFormat( Render::VertexBuffer* vertexBuffer, OwnerPointer< Render::VertexBuffer::Format>& format )
1287 // Message has ownership of format while in transit from update -> render
1288 using DerivedType = MessageValue2<RenderManager, Render::VertexBuffer*, OwnerPointer<Render::VertexBuffer::Format> >;
1290 // Reserve some memory inside the render queue
1291 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1293 // Construct message in the render queue memory; note that delete should not be called on the return value
1294 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetVertexBufferFormat, vertexBuffer, format );
1297 void UpdateManager::SetVertexBufferData( Render::VertexBuffer* vertexBuffer, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
1299 // Message has ownership of format while in transit from update -> render
1300 using DerivedType = MessageValue3<RenderManager, Render::VertexBuffer*, OwnerPointer<Dali::Vector<uint8_t> >, uint32_t>;
1302 // Reserve some memory inside the render queue
1303 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1305 // Construct message in the render queue memory; note that delete should not be called on the return value
1306 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetVertexBufferData, vertexBuffer, data, size );
1309 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1311 // Message has ownership of format while in transit from update -> render
1312 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Geometry> >;
1314 // Reserve some memory inside the render queue
1315 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1317 // Construct message in the render queue memory; note that delete should not be called on the return value
1318 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1321 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1323 using DerivedType = MessageValue1<RenderManager, Render::Geometry*>;
1325 // Reserve some memory inside the render queue
1326 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1328 // Construct message in the render queue memory; note that delete should not be called on the return value
1329 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1332 void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
1334 using DerivedType = MessageValue2<RenderManager, Render::Geometry*, uint32_t>;
1336 // Reserve some memory inside the render queue
1337 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1339 // Construct message in the render queue memory; note that delete should not be called on the return value
1340 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1343 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
1345 using DerivedType = IndexBufferMessage<RenderManager>;
1347 // Reserve some memory inside the render queue
1348 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1350 // Construct message in the render queue memory; note that delete should not be called on the return value
1351 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1354 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
1356 using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1358 // Reserve some memory inside the render queue
1359 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1361 // Construct message in the render queue memory; note that delete should not be called on the return value
1362 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, vertexBuffer );
1365 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
1367 using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1369 // Reserve some memory inside the render queue
1370 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1372 // Construct message in the render queue memory; note that delete should not be called on the return value
1373 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, vertexBuffer );
1376 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1378 // Message has ownership of Texture while in transit from update -> render
1379 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Texture> >;
1381 // Reserve some memory inside the render queue
1382 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1384 // Construct message in the render queue memory; note that delete should not be called on the return value
1385 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1388 void UpdateManager::RemoveTexture( Render::Texture* texture)
1390 using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
1392 // Reserve some memory inside the render queue
1393 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1395 // Construct message in the render queue memory; note that delete should not be called on the return value
1396 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1399 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1401 using DerivedType = MessageValue3<RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams>;
1403 // Reserve some memory inside the message queue
1404 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1406 // Construct message in the message queue memory; note that delete should not be called on the return value
1407 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1410 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1412 using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
1414 // Reserve some memory inside the render queue
1415 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1417 // Construct message in the render queue memory; note that delete should not be called on the return value
1418 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1421 void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
1423 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::FrameBuffer> >;
1425 // Reserve some memory inside the render queue
1426 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1428 // Construct message in the render queue memory; note that delete should not be called on the return value
1429 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1432 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1434 using DerivedType = MessageValue1<RenderManager, Render::FrameBuffer*>;
1436 // Reserve some memory inside the render queue
1437 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1439 // Construct message in the render queue memory; note that delete should not be called on the return value
1440 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1443 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
1445 using DerivedType = MessageValue4<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t>;
1447 // Reserve some memory inside the render queue
1448 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1450 // Construct message in the render queue memory; note that delete should not be called on the return value
1451 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1454 void UpdateManager::AttachDepthTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1456 using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1458 // Reserve some memory inside the render queue
1459 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1461 // Construct message in the render queue memory; note that delete should not be called on the return value
1462 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachDepthTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1465 void UpdateManager::AttachDepthStencilTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1467 using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1469 // Reserve some memory inside the render queue
1470 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1472 // Construct message in the render queue memory; note that delete should not be called on the return value
1473 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachDepthStencilTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1476 } // namespace SceneGraph
1478 } // namespace Internal