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(),
1019 scene->scene->SetSkipRendering( false );
1023 scene->scene->SetSkipRendering( true );
1026 numberOfRenderInstructions += scene->scene->GetRenderInstructions().Count( bufferIndex );
1030 DALI_LOG_INFO( gLogFilter, Debug::General,
1031 "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n",
1032 numberOfRenderTasks, numberOfRenderInstructions );
1036 for ( auto&& scene : mImpl->scenes )
1038 if ( scene && scene->root && scene->taskList )
1040 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
1042 // check the countdown and notify
1043 bool doRenderOnceNotify = false;
1044 mImpl->renderTaskWaiting = false;
1045 for ( auto&& renderTask : tasks )
1047 renderTask->UpdateState();
1049 if( renderTask->IsWaitingToRender() &&
1050 renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1052 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1055 if( renderTask->HasRendered() )
1057 doRenderOnceNotify = true;
1061 if( doRenderOnceNotify )
1063 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1064 mImpl->notificationManager.QueueCompleteNotification( scene->taskList->GetCompleteNotificationInterface() );
1069 // Macro is undefined in release build.
1070 SNAPSHOT_NODE_LOGGING;
1072 // A ResetProperties() may be required in the next frame
1073 mImpl->previousUpdateScene = updateScene;
1075 // Check whether further updates are required
1076 uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1078 if( keepRendererRendering )
1080 keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
1082 // Set dirty flags for next frame to continue rendering
1083 mImpl->nodeDirtyFlags |= RenderableUpdateFlags;
1086 // tell the update manager that we're done so the queue can be given to event thread
1087 mImpl->notificationManager.UpdateCompleted();
1089 // The update has finished; swap the double-buffering indices
1090 mSceneGraphBuffers.Swap();
1092 return keepUpdating;
1095 uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1097 // Update the duration set via Stage::KeepRendering()
1098 if ( mImpl->keepRenderingSeconds > 0.0f )
1100 mImpl->keepRenderingSeconds -= elapsedSeconds;
1103 uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1105 // If the rendering behavior is set to continuously render, then continue to render.
1106 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1107 // Keep updating until no messages are received and no animations are running.
1108 // If an animation has just finished, update at least once more for Discard end-actions.
1109 // No need to check for renderQueue as there is always a render after update and if that
1110 // render needs another update it will tell the adaptor to call update again
1112 if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
1113 ( mImpl->keepRenderingSeconds > 0.0f ) )
1115 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1118 if ( IsAnimationRunning() ||
1119 mImpl->animationFinishedDuringUpdate )
1121 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1124 if ( mImpl->renderTaskWaiting )
1126 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1129 return keepUpdatingRequest;
1132 void UpdateManager::SetDefaultSurfaceRect( const Rect<int32_t>& rect )
1134 mImpl->surfaceRectChanged = true;
1136 using DerivedType = MessageValue1<RenderManager, Rect<int32_t> >;
1138 // Reserve some memory inside the render queue
1139 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1141 // Construct message in the render queue memory; note that delete should not be called on the return value
1142 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1145 void UpdateManager::SurfaceReplaced( Scene* scene )
1147 using DerivedType = MessageValue1<RenderManager, Scene*>;
1149 // Reserve some memory inside the render queue
1150 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1152 // Construct message in the render queue memory; note that delete should not be called on the return value
1153 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SurfaceReplaced, scene );
1156 void UpdateManager::SetDefaultSurfaceOrientation(int orientation)
1158 using DerivedType = MessageValue1<RenderManager, int>;
1160 // Reserve some memory inside the render queue
1161 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1163 // Construct message in the render queue memory; note that delete should not be called on the return value
1164 new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetDefaultSurfaceOrientation, orientation);
1167 void UpdateManager::KeepRendering( float durationSeconds )
1169 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1172 void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
1174 mImpl->renderingBehavior = renderingBehavior;
1177 void UpdateManager::RequestRendering()
1179 mImpl->renderingRequired = true;
1182 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
1184 for ( auto&& scene : mImpl->scenes )
1186 if ( scene && scene->root == rootLayer )
1188 scene->sortedLayerList = layers;
1194 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1196 // note,this vector is already in depth order. It could be used as-is to
1197 // remove sorting in update algorithm. However, it lacks layer boundary markers.
1198 for( auto&& iter : nodeDepths->nodeDepths )
1200 iter.node->SetDepthIndex( iter.sortedDepth );
1203 for ( auto&& scene : mImpl->scenes )
1207 // Go through node hierarchy and rearrange siblings according to depth-index
1208 SortSiblingNodesRecursively( *scene->root );
1213 bool UpdateManager::IsDefaultSurfaceRectChanged()
1215 bool surfaceRectChanged = mImpl->surfaceRectChanged;
1218 mImpl->surfaceRectChanged = false;
1220 return surfaceRectChanged;
1223 void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode )
1225 mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode );
1228 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1230 mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback );
1233 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1235 // Message has ownership of Sampler while in transit from update to render
1236 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Sampler> >;
1238 // Reserve some memory inside the render queue
1239 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1241 // Construct message in the render queue memory; note that delete should not be called on the return value
1242 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1245 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1247 using DerivedType = MessageValue1<RenderManager, Render::Sampler*>;
1249 // Reserve some memory inside the render queue
1250 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1252 // Construct message in the render queue memory; note that delete should not be called on the return value
1253 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1256 void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
1258 using DerivedType = MessageValue3<RenderManager, Render::Sampler*, uint32_t, uint32_t>;
1260 // Reserve some memory inside the render queue
1261 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1263 // Construct message in the render queue memory; note that delete should not be called on the return value
1264 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1267 void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
1269 using DerivedType = MessageValue4<RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t>;
1271 // Reserve some memory inside the render queue
1272 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1274 // Construct message in the render queue memory; note that delete should not be called on the return value
1275 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1278 void UpdateManager::AddVertexBuffer( OwnerPointer< Render::VertexBuffer >& vertexBuffer )
1280 // Message has ownership of format while in transit from update -> render
1281 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::VertexBuffer> >;
1283 // Reserve some memory inside the render queue
1284 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1286 // Construct message in the render queue memory; note that delete should not be called on the return value
1287 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, vertexBuffer );
1290 void UpdateManager::RemoveVertexBuffer( Render::VertexBuffer* vertexBuffer )
1292 using DerivedType = MessageValue1<RenderManager, Render::VertexBuffer*>;
1294 // Reserve some memory inside the render queue
1295 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1297 // Construct message in the render queue memory; note that delete should not be called on the return value
1298 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, vertexBuffer );
1301 void UpdateManager::SetVertexBufferFormat( Render::VertexBuffer* vertexBuffer, OwnerPointer< Render::VertexBuffer::Format>& format )
1303 // Message has ownership of format while in transit from update -> render
1304 using DerivedType = MessageValue2<RenderManager, Render::VertexBuffer*, OwnerPointer<Render::VertexBuffer::Format> >;
1306 // Reserve some memory inside the render queue
1307 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1309 // Construct message in the render queue memory; note that delete should not be called on the return value
1310 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetVertexBufferFormat, vertexBuffer, format );
1313 void UpdateManager::SetVertexBufferData( Render::VertexBuffer* vertexBuffer, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
1315 // Message has ownership of format while in transit from update -> render
1316 using DerivedType = MessageValue3<RenderManager, Render::VertexBuffer*, OwnerPointer<Dali::Vector<uint8_t> >, uint32_t>;
1318 // Reserve some memory inside the render queue
1319 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1321 // Construct message in the render queue memory; note that delete should not be called on the return value
1322 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetVertexBufferData, vertexBuffer, data, size );
1325 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1327 // Message has ownership of format while in transit from update -> render
1328 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Geometry> >;
1330 // Reserve some memory inside the render queue
1331 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1333 // Construct message in the render queue memory; note that delete should not be called on the return value
1334 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1337 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1339 using DerivedType = MessageValue1<RenderManager, Render::Geometry*>;
1341 // Reserve some memory inside the render queue
1342 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1344 // Construct message in the render queue memory; note that delete should not be called on the return value
1345 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1348 void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
1350 using DerivedType = MessageValue2<RenderManager, Render::Geometry*, uint32_t>;
1352 // Reserve some memory inside the render queue
1353 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1355 // Construct message in the render queue memory; note that delete should not be called on the return value
1356 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1359 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
1361 using DerivedType = IndexBufferMessage<RenderManager>;
1363 // Reserve some memory inside the render queue
1364 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1366 // Construct message in the render queue memory; note that delete should not be called on the return value
1367 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1370 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
1372 using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1374 // Reserve some memory inside the render queue
1375 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1377 // Construct message in the render queue memory; note that delete should not be called on the return value
1378 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, vertexBuffer );
1381 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
1383 using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1385 // Reserve some memory inside the render queue
1386 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1388 // Construct message in the render queue memory; note that delete should not be called on the return value
1389 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, vertexBuffer );
1392 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1394 // Message has ownership of Texture while in transit from update -> render
1395 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Texture> >;
1397 // Reserve some memory inside the render queue
1398 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1400 // Construct message in the render queue memory; note that delete should not be called on the return value
1401 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1404 void UpdateManager::RemoveTexture( Render::Texture* texture)
1406 using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
1408 // Reserve some memory inside the render queue
1409 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1411 // Construct message in the render queue memory; note that delete should not be called on the return value
1412 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1415 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1417 using DerivedType = MessageValue3<RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams>;
1419 // Reserve some memory inside the message queue
1420 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1422 // Construct message in the message queue memory; note that delete should not be called on the return value
1423 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1426 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1428 using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
1430 // Reserve some memory inside the render queue
1431 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1433 // Construct message in the render queue memory; note that delete should not be called on the return value
1434 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1437 void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
1439 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::FrameBuffer> >;
1441 // Reserve some memory inside the render queue
1442 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1444 // Construct message in the render queue memory; note that delete should not be called on the return value
1445 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1448 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1450 using DerivedType = MessageValue1<RenderManager, Render::FrameBuffer*>;
1452 // Reserve some memory inside the render queue
1453 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1455 // Construct message in the render queue memory; note that delete should not be called on the return value
1456 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1459 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
1461 using DerivedType = MessageValue4<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t>;
1463 // Reserve some memory inside the render queue
1464 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1466 // Construct message in the render queue memory; note that delete should not be called on the return value
1467 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1470 void UpdateManager::AttachDepthTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1472 using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1474 // Reserve some memory inside the render queue
1475 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1477 // Construct message in the render queue memory; note that delete should not be called on the return value
1478 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachDepthTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1481 void UpdateManager::AttachDepthStencilTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1483 using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1485 // Reserve some memory inside the render queue
1486 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1488 // Construct message in the render queue memory; note that delete should not be called on the return value
1489 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachDepthStencilTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1492 } // namespace SceneGraph
1494 } // namespace Internal