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 ),
171 discardQueue( discardQueue ),
172 renderController( renderController ),
173 sceneController( NULL ),
174 renderManager( renderManager ),
175 renderQueue( renderQueue ),
176 renderTaskProcessor( renderTaskProcessor ),
177 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
181 panGestureProcessor( NULL ),
182 messageQueue( renderController, sceneGraphBuffers ),
183 frameCallbackProcessor( NULL ),
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 )
194 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
196 // create first 'dummy' node
202 // Disconnect render tasks from nodes, before destroying the nodes
203 for( auto&& scene : scenes )
205 if ( scene && scene->taskList )
207 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
208 for ( auto&& task : tasks )
210 task->SetSourceNode( NULL );
215 // UpdateManager owns the Nodes. Although Nodes are pool allocated they contain heap allocated parts
216 // like custom properties, which get released here
217 Vector<Node*>::Iterator iter = nodes.Begin()+1;
218 Vector<Node*>::Iterator endIter = nodes.End();
219 for(;iter!=endIter;++iter)
221 (*iter)->OnDestroy();
225 for( auto&& scene : scenes )
227 if ( scene && scene->root )
229 scene->root->OnDestroy();
230 Node::Delete( scene->root );
235 delete sceneController;
239 * Lazy init for FrameCallbackProcessor.
240 * @param[in] updateManager A reference to the update-manager
242 FrameCallbackProcessor& GetFrameCallbackProcessor( UpdateManager& updateManager )
244 if( ! frameCallbackProcessor )
246 frameCallbackProcessor = new FrameCallbackProcessor( updateManager, transformManager );
248 return *frameCallbackProcessor;
251 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
252 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
253 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
254 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
255 CompleteNotificationInterface& animationPlaylist; ///< Holds handles to all the animations
256 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
257 ShaderSaver* shaderSaver; ///< Saves shader binaries.
258 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
259 RenderController& renderController; ///< render controller
260 SceneControllerImpl* sceneController; ///< scene controller
261 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
262 RenderQueue& renderQueue; ///< Used to queue messages for the next render
263 RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
265 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
267 using SceneInfoPtr = std::unique_ptr< SceneInfo >;
268 std::vector< SceneInfoPtr > scenes; ///< A container of SceneInfo.
270 Vector<Node*> nodes; ///< A container of all instantiated nodes
272 OwnerContainer< Camera* > cameras; ///< A container of cameras
273 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
275 OwnerContainer< PropertyResetterBase* > propertyResetters; ///< A container of property resetters
276 OwnerContainer< Animation* > animations; ///< A container of owned animations
277 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
278 OwnerContainer< Renderer* > renderers; ///< A container of owned renderers
279 OwnerContainer< TextureSet* > textureSets; ///< A container of owned texture sets
280 OwnerContainer< Shader* > shaders; ///< A container of owned shaders
281 OwnerPointer< PanGesture > panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager
283 MessageQueue messageQueue; ///< The messages queued from the event-thread
284 std::vector<Internal::ShaderDataPtr> renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
285 std::vector<Internal::ShaderDataPtr> updateCompiledShaders; ///< Shaders to be sent from Update to Event
286 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
288 OwnerPointer<FrameCallbackProcessor> frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required.
290 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
291 NodePropertyFlags nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
292 uint32_t frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
294 DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior
296 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
297 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
298 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
299 bool renderersAdded; ///< Flag to keep track when renderers have been added to avoid unnecessary processing
300 bool surfaceRectChanged; ///< True if the default surface rect is changed
304 Impl( const Impl& ); ///< Undefined
305 Impl& operator=( const Impl& ); ///< Undefined
308 UpdateManager::UpdateManager( NotificationManager& notificationManager,
309 CompleteNotificationInterface& animationFinishedNotifier,
310 PropertyNotifier& propertyNotifier,
311 DiscardQueue& discardQueue,
312 RenderController& controller,
313 RenderManager& renderManager,
314 RenderQueue& renderQueue,
315 RenderTaskProcessor& renderTaskProcessor )
318 mImpl = new Impl( notificationManager,
319 animationFinishedNotifier,
326 renderTaskProcessor );
330 UpdateManager::~UpdateManager()
335 void UpdateManager::InstallRoot( OwnerPointer<Layer>& layer )
337 DALI_ASSERT_DEBUG( layer->IsLayer() );
338 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
340 Layer* rootLayer = layer.Release();
342 DALI_ASSERT_DEBUG( std::find_if( mImpl->scenes.begin(), mImpl->scenes.end(),
343 [rootLayer]( Impl::SceneInfoPtr& scene )
345 return scene && scene->root == rootLayer;
347 ) == mImpl->scenes.end() && "Root Node already installed" );
349 rootLayer->CreateTransform( &mImpl->transformManager );
350 rootLayer->SetRoot(true);
352 mImpl->scenes.emplace_back( new Impl::SceneInfo( rootLayer ) );
355 void UpdateManager::UninstallRoot( Layer* layer )
357 DALI_ASSERT_DEBUG( layer->IsLayer() );
358 DALI_ASSERT_DEBUG( layer->GetParent() == NULL );
360 for (auto iter = mImpl->scenes.begin(); iter != mImpl->scenes.end(); ++iter)
362 if( (*iter) && (*iter)->root == layer )
364 mImpl->scenes.erase( iter );
369 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), layer );
371 // Notify the layer about impending destruction
375 void UpdateManager::AddNode( OwnerPointer<Node>& node )
377 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
379 // Nodes must be sorted by pointer
380 Node* rawNode = node.Release();
381 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddNode\n", rawNode );
383 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
384 for( Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter )
386 if( rawNode > (*iter) )
388 mImpl->nodes.Insert((iter+1), rawNode );
389 rawNode->CreateTransform( &mImpl->transformManager );
395 void UpdateManager::ConnectNode( Node* parent, Node* node )
397 DALI_ASSERT_ALWAYS( NULL != parent );
398 DALI_ASSERT_ALWAYS( NULL != node );
399 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
401 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] ConnectNode\n", node );
403 parent->ConnectChild( node );
405 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
406 if( mImpl->frameCallbackProcessor )
408 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
412 void UpdateManager::DisconnectNode( Node* node )
414 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DisconnectNode\n", node );
416 Node* parent = node->GetParent();
417 DALI_ASSERT_ALWAYS( NULL != parent );
418 parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused
420 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
422 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
423 if( mImpl->frameCallbackProcessor )
425 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
429 void UpdateManager::DestroyNode( Node* node )
431 DALI_ASSERT_ALWAYS( NULL != node );
432 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
434 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DestroyNode\n", node );
436 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
437 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
438 for(;iter!=endIter;++iter)
442 mImpl->nodes.Erase(iter);
447 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
449 // Notify the Node about impending destruction
453 void UpdateManager::AddCamera( OwnerPointer< Camera >& camera )
455 mImpl->cameras.PushBack( camera.Release() ); // takes ownership
458 void UpdateManager::RemoveCamera( Camera* camera )
460 // Find the camera and destroy it
461 EraseUsingDiscardQueue( mImpl->cameras, camera, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
464 void UpdateManager::AddObject( OwnerPointer<PropertyOwner>& object )
466 mImpl->customObjects.PushBack( object.Release() );
469 void UpdateManager::RemoveObject( PropertyOwner* object )
471 mImpl->customObjects.EraseObject( object );
474 void UpdateManager::AddRenderTaskList( OwnerPointer<RenderTaskList>& taskList )
476 RenderTaskList* taskListPointer = taskList.Release();
477 taskListPointer->SetRenderMessageDispatcher( &mImpl->renderMessageDispatcher );
479 mImpl->scenes.back()->taskList = taskListPointer;
482 void UpdateManager::RemoveRenderTaskList( RenderTaskList* taskList )
484 for ( auto&& scene : mImpl->scenes )
486 if ( scene && scene->taskList == taskList )
488 scene->taskList.Reset();
494 void UpdateManager::AddScene( OwnerPointer< Scene >& scene )
496 mImpl->scenes.back()->scene = scene.Release();
498 // Initialize the context from render manager
499 typedef MessageValue1< RenderManager, SceneGraph::Scene* > DerivedType;
501 // Reserve some memory inside the render queue
502 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
504 // Construct message in the render queue memory; note that delete should not be called on the return value
505 SceneGraph::Scene& sceneObject = *mImpl->scenes.back()->scene;
506 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::InitializeScene, &sceneObject );
509 void UpdateManager::RemoveScene( Scene* scene )
511 // Initialize the context from render manager
512 typedef MessageValue1< RenderManager, SceneGraph::Scene* > DerivedType;
514 // Reserve some memory inside the render queue
515 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
517 // Construct message in the render queue memory; note that delete should not be called on the return value
518 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UninitializeScene, scene );
520 for ( auto&& sceneInfo : mImpl->scenes )
522 if ( sceneInfo && sceneInfo->scene && sceneInfo->scene.Get() == scene )
524 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), sceneInfo->scene.Release() ); // take the address of the reference to a pointer
530 void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation )
532 mImpl->animations.PushBack( animation.Release() );
535 void UpdateManager::StopAnimation( Animation* animation )
537 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
539 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
541 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
544 void UpdateManager::RemoveAnimation( Animation* animation )
546 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
548 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
550 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
553 bool UpdateManager::IsAnimationRunning() const
555 // Find any animation that isn't stopped or paused
556 for ( auto&& iter : mImpl->animations )
558 const Animation::State state = iter->GetState();
560 if (state != Animation::Stopped &&
561 state != Animation::Paused)
563 return true; // stop iteration as soon as first one is found
570 void UpdateManager::AddPropertyResetter( OwnerPointer<PropertyResetterBase>& propertyResetter )
572 propertyResetter->Initialize();
573 mImpl->propertyResetters.PushBack( propertyResetter.Release() );
576 void UpdateManager::AddPropertyNotification( OwnerPointer< PropertyNotification >& propertyNotification )
578 mImpl->propertyNotifications.PushBack( propertyNotification.Release() );
581 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
583 mImpl->propertyNotifications.EraseObject( propertyNotification );
586 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
588 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
589 propertyNotification->SetNotifyMode( notifyMode );
592 void UpdateManager::AddShader( OwnerPointer< Shader >& shader )
594 mImpl->shaders.PushBack( shader.Release() );
597 void UpdateManager::RemoveShader( Shader* shader )
599 // Find the shader and destroy it
600 EraseUsingDiscardQueue( mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
603 void UpdateManager::SetShaderProgram( Shader* shader,
604 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
609 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
611 // Reserve some memory inside the render queue
612 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
614 // Construct message in the render queue memory; note that delete should not be called on the return value
615 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
619 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
621 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
622 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
624 // lock as update might be sending previously compiled shaders to event thread
625 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
626 mImpl->renderCompiledShaders.push_back( shaderData );
630 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
632 mImpl->shaderSaver = &upstream;
635 void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer )
637 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer.Get() );
639 renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
640 mImpl->renderers.PushBack( renderer.Release() );
641 mImpl->renderersAdded = true;
644 void UpdateManager::RemoveRenderer( Renderer* renderer )
646 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] RemoveRenderer\n", renderer );
648 // Find the renderer and destroy it
649 EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
650 // Need to remove the render object as well
651 renderer->DisconnectFromSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
654 void UpdateManager::SetPanGestureProcessor( PanGesture* panGestureProcessor )
656 DALI_ASSERT_DEBUG( NULL != panGestureProcessor );
658 mImpl->panGestureProcessor = panGestureProcessor;
661 void UpdateManager::AddTextureSet( OwnerPointer< TextureSet >& textureSet )
663 mImpl->textureSets.PushBack( textureSet.Release() );
666 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
668 mImpl->textureSets.EraseObject( textureSet );
671 uint32_t* UpdateManager::ReserveMessageSlot( uint32_t size, bool updateScene )
673 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
676 void UpdateManager::EventProcessingStarted()
678 mImpl->messageQueue.EventProcessingStarted();
681 bool UpdateManager::FlushQueue()
683 return mImpl->messageQueue.FlushQueue();
686 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
688 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
689 mImpl->animationFinishedDuringUpdate = false;
691 // Reset all animating / constrained properties
692 std::vector<PropertyResetterBase*>toDelete;
693 for( auto&& element : mImpl->propertyResetters )
695 element->ResetToBaseValue( bufferIndex );
696 if( element->IsFinished() )
698 toDelete.push_back( element );
702 // If a resetter is no longer required (the animator or constraint has been removed), delete it.
703 for( auto&& elementPtr : toDelete )
705 mImpl->propertyResetters.EraseObject( elementPtr );
708 // Clear all root nodes dirty flags
709 for( auto& scene : mImpl->scenes )
711 auto root = scene->root;
712 root->ResetDirtyFlags( bufferIndex );
715 // Clear node dirty flags
716 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
717 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
718 for( ;iter != endIter; ++iter )
720 (*iter)->ResetDirtyFlags( bufferIndex );
724 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds )
726 bool gestureUpdated( false );
728 if( mImpl->panGestureProcessor )
730 // gesture processor only supports default properties
731 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
732 gestureUpdated |= mImpl->panGestureProcessor->UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
735 return gestureUpdated;
738 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
740 auto&& iter = mImpl->animations.Begin();
741 bool animationLooped = false;
743 while ( iter != mImpl->animations.End() )
745 Animation* animation = *iter;
746 bool finished = false;
748 bool progressMarkerReached = false;
749 animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
751 if ( progressMarkerReached )
753 mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
756 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
757 animationLooped = animationLooped || looped;
759 // Remove animations that had been destroyed but were still waiting for an update
760 if (animation->GetState() == Animation::Destroyed)
762 iter = mImpl->animations.Erase(iter);
770 // queue the notification on finished or looped (to update loop count)
771 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
773 // The application should be notified by NotificationManager, in another thread
774 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
778 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
780 //Constrain custom objects (in construction order)
781 for ( auto&& object : mImpl->customObjects )
783 ConstrainPropertyOwner( *object, bufferIndex );
787 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
789 // Constrain render-tasks
790 for ( auto&& scene : mImpl->scenes )
792 if ( scene && scene->taskList )
794 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
795 for ( auto&& task : tasks )
797 ConstrainPropertyOwner( *task, bufferIndex );
803 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
805 // constrain shaders... (in construction order)
806 for ( auto&& shader : mImpl->shaders )
808 ConstrainPropertyOwner( *shader, bufferIndex );
812 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
814 for( auto&& notification : mImpl->propertyNotifications )
816 bool valid = notification->Check( bufferIndex );
819 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
824 void UpdateManager::ForwardCompiledShadersToEventThread()
826 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
827 if( mImpl->shaderSaver )
829 // lock and swap the queues
831 // render might be attempting to send us more binaries at the same time
832 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
833 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
836 if( mImpl->updateCompiledShaders.size() > 0 )
838 ShaderSaver& factory = *mImpl->shaderSaver;
839 for( auto&& shader : mImpl->updateCompiledShaders )
841 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, shader ) );
843 // we don't need them in update anymore
844 mImpl->updateCompiledShaders.clear();
849 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
851 for( auto&& renderer : mImpl->renderers )
854 ConstrainPropertyOwner( *renderer, bufferIndex );
856 renderer->PrepareRender( bufferIndex );
860 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
862 mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
864 for ( auto&& scene : mImpl->scenes )
866 if ( scene && scene->root )
868 // Prepare resources, update shaders, for each node
869 // And add the renderers to the sorted layers. Start from root, which is also a layer
870 mImpl->nodeDirtyFlags |= UpdateNodeTree( *scene->root,
872 mImpl->renderQueue );
877 uint32_t UpdateManager::Update( float elapsedSeconds,
878 uint32_t lastVSyncTimeMilliseconds,
879 uint32_t nextVSyncTimeMilliseconds,
880 bool renderToFboEnabled,
881 bool isRenderingToFbo )
883 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
885 //Clear nodes/resources which were previously discarded
886 mImpl->discardQueue.Clear( bufferIndex );
888 //Process Touches & Gestures
889 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
891 bool updateScene = // The scene-graph requires an update if..
892 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
893 IsAnimationRunning() || // ..at least one animation is running OR
894 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
895 (mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY) || // ..rendering behavior is DevelStage::Rendering::CONTINUOUSLY OR
896 gestureUpdated; // ..a gesture property was updated
898 bool keepRendererRendering = false;
900 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
901 // values if the scene was updated in the previous frame.
902 if( updateScene || mImpl->previousUpdateScene )
904 //Reset properties from the previous update
905 ResetProperties( bufferIndex );
906 mImpl->transformManager.ResetToBaseValue();
909 // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
910 // between calling IsSceneUpdateRequired() above and here, so updateScene should
912 updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
914 //Forward compiled shader programs to event thread for saving
915 ForwardCompiledShadersToEventThread();
917 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
918 // renderer lists if the scene was updated in the previous frame.
919 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
920 if( updateScene || mImpl->previousUpdateScene )
923 Animate( bufferIndex, elapsedSeconds );
925 //Constraint custom objects
926 ConstrainCustomObjects( bufferIndex );
928 //Clear the lists of renderers from the previous update
929 for( auto&& scene : mImpl->scenes )
933 for( auto&& layer : scene->sortedLayerList )
937 layer->ClearRenderables();
943 // Call the frame-callback-processor if set
944 if( mImpl->frameCallbackProcessor )
946 mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
949 //Update node hierarchy, apply constraints and perform sorting / culling.
950 //This will populate each Layer with a list of renderers which are ready.
951 UpdateNodes( bufferIndex );
953 //Apply constraints to RenderTasks, shaders
954 ConstrainRenderTasks( bufferIndex );
955 ConstrainShaders( bufferIndex );
957 //Update renderers and apply constraints
958 UpdateRenderers( bufferIndex );
960 //Update the transformations of all the nodes
961 mImpl->transformManager.Update();
963 //Process Property Notifications
964 ProcessPropertyNotifications( bufferIndex );
967 for( auto&& cameraIterator : mImpl->cameras )
969 cameraIterator->Update( bufferIndex );
972 //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
973 //reset the update buffer index and make sure there is enough room in the instruction container
974 if( mImpl->renderersAdded )
976 // Calculate how many render tasks we have in total
977 std::size_t numberOfRenderTasks = 0;
978 for (auto&& scene : mImpl->scenes )
980 if ( scene && scene->taskList )
982 numberOfRenderTasks += scene->taskList->GetTasks().Count();
987 std::size_t numberOfRenderInstructions = 0;
988 for ( auto&& scene : mImpl->scenes )
990 if ( scene && scene->root && scene->taskList && scene->scene )
992 scene->scene->GetRenderInstructions().ResetAndReserve( bufferIndex,
993 static_cast<uint32_t>( scene->taskList->GetTasks().Count() ) );
995 keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
998 scene->sortedLayerList,
999 *scene->scene->GetContext(),
1000 scene->scene->GetRenderInstructions(),
1004 numberOfRenderInstructions += scene->scene->GetRenderInstructions().Count( bufferIndex );
1008 DALI_LOG_INFO( gLogFilter, Debug::General,
1009 "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n",
1010 numberOfRenderTasks, numberOfRenderInstructions );
1014 for ( auto&& scene : mImpl->scenes )
1016 if ( scene && scene->root && scene->taskList )
1018 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
1020 // check the countdown and notify
1021 bool doRenderOnceNotify = false;
1022 mImpl->renderTaskWaiting = false;
1023 for ( auto&& renderTask : tasks )
1025 renderTask->UpdateState();
1027 if( renderTask->IsWaitingToRender() &&
1028 renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1030 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1033 if( renderTask->HasRendered() )
1035 doRenderOnceNotify = true;
1039 if( doRenderOnceNotify )
1041 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1042 mImpl->notificationManager.QueueCompleteNotification( scene->taskList->GetCompleteNotificationInterface() );
1047 // Macro is undefined in release build.
1048 SNAPSHOT_NODE_LOGGING;
1050 // A ResetProperties() may be required in the next frame
1051 mImpl->previousUpdateScene = updateScene;
1053 // Check whether further updates are required
1054 uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1056 if( keepRendererRendering )
1058 keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
1060 // Set dirty flags for next frame to continue rendering
1061 mImpl->nodeDirtyFlags |= RenderableUpdateFlags;
1064 // tell the update manager that we're done so the queue can be given to event thread
1065 mImpl->notificationManager.UpdateCompleted();
1067 // The update has finished; swap the double-buffering indices
1068 mSceneGraphBuffers.Swap();
1070 return keepUpdating;
1073 uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1075 // Update the duration set via Stage::KeepRendering()
1076 if ( mImpl->keepRenderingSeconds > 0.0f )
1078 mImpl->keepRenderingSeconds -= elapsedSeconds;
1081 uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1083 // If the rendering behavior is set to continuously render, then continue to render.
1084 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1085 // Keep updating until no messages are received and no animations are running.
1086 // If an animation has just finished, update at least once more for Discard end-actions.
1087 // No need to check for renderQueue as there is always a render after update and if that
1088 // render needs another update it will tell the adaptor to call update again
1090 if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
1091 ( mImpl->keepRenderingSeconds > 0.0f ) )
1093 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1096 if ( IsAnimationRunning() ||
1097 mImpl->animationFinishedDuringUpdate )
1099 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1102 if ( mImpl->renderTaskWaiting )
1104 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1107 return keepUpdatingRequest;
1110 void UpdateManager::SetDefaultSurfaceRect( const Rect<int32_t>& rect )
1112 mImpl->surfaceRectChanged = true;
1114 typedef MessageValue1< RenderManager, Rect<int32_t> > DerivedType;
1116 // Reserve some memory inside the render queue
1117 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1119 // Construct message in the render queue memory; note that delete should not be called on the return value
1120 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1123 void UpdateManager::SurfaceReplaced( Scene* scene )
1125 typedef MessageValue1< RenderManager, Scene* > DerivedType;
1127 // Reserve some memory inside the render queue
1128 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1130 // Construct message in the render queue memory; note that delete should not be called on the return value
1131 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SurfaceReplaced, scene );
1134 void UpdateManager::SetDefaultSurfaceOrientation( int orientation )
1136 typedef MessageValue1< RenderManager, int > DerivedType;
1138 // Reserve some memory inside the render queue
1139 unsigned int* 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::SetDefaultSurfaceOrientation, orientation );
1145 void UpdateManager::KeepRendering( float durationSeconds )
1147 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1150 void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
1152 mImpl->renderingBehavior = renderingBehavior;
1155 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
1157 for ( auto&& scene : mImpl->scenes )
1159 if ( scene && scene->root == rootLayer )
1161 scene->sortedLayerList = layers;
1167 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1169 // note,this vector is already in depth order. It could be used as-is to
1170 // remove sorting in update algorithm. However, it lacks layer boundary markers.
1171 for( auto&& iter : nodeDepths->nodeDepths )
1173 iter.node->SetDepthIndex( iter.sortedDepth );
1176 for ( auto&& scene : mImpl->scenes )
1180 // Go through node hierarchy and rearrange siblings according to depth-index
1181 SortSiblingNodesRecursively( *scene->root );
1186 bool UpdateManager::IsDefaultSurfaceRectChanged()
1188 bool surfaceRectChanged = mImpl->surfaceRectChanged;
1191 mImpl->surfaceRectChanged = false;
1193 return surfaceRectChanged;
1196 void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode )
1198 mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode );
1201 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1203 mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback );
1206 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1208 // Message has ownership of Sampler while in transit from update to render
1209 typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > DerivedType;
1211 // Reserve some memory inside the render queue
1212 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1214 // Construct message in the render queue memory; note that delete should not be called on the return value
1215 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1218 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1220 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
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::RemoveSampler, sampler );
1229 void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
1231 typedef MessageValue3< RenderManager, Render::Sampler*, uint32_t, uint32_t > DerivedType;
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::SetFilterMode, sampler, minFilterMode, magFilterMode );
1240 void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
1242 typedef MessageValue4< RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t > DerivedType;
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::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1251 void UpdateManager::AddPropertyBuffer( OwnerPointer< Render::PropertyBuffer >& propertyBuffer )
1253 // Message has ownership of format while in transit from update -> render
1254 typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
1256 // Reserve some memory inside the render queue
1257 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1259 // Construct message in the render queue memory; note that delete should not be called on the return value
1260 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1263 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1265 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
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::RemovePropertyBuffer, propertyBuffer );
1274 void UpdateManager::SetPropertyBufferFormat( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Render::PropertyBuffer::Format>& format )
1276 // Message has ownership of format while in transit from update -> render
1277 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType;
1279 // Reserve some memory inside the render queue
1280 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1282 // Construct message in the render queue memory; note that delete should not be called on the return value
1283 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1286 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
1288 // Message has ownership of format while in transit from update -> render
1289 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<uint8_t> >, uint32_t > DerivedType;
1291 // Reserve some memory inside the render queue
1292 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1294 // Construct message in the render queue memory; note that delete should not be called on the return value
1295 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1298 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1300 // Message has ownership of format while in transit from update -> render
1301 typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > DerivedType;
1303 // Reserve some memory inside the render queue
1304 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1306 // Construct message in the render queue memory; note that delete should not be called on the return value
1307 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1310 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1312 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
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::RemoveGeometry, geometry );
1321 void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
1323 typedef MessageValue2< RenderManager, Render::Geometry*, uint32_t > DerivedType;
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::SetGeometryType, geometry, geometryType );
1332 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
1334 typedef IndexBufferMessage< RenderManager > DerivedType;
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, geometry, indices );
1343 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1345 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
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, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1354 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1356 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
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::AttachVertexBuffer, geometry, propertyBuffer );
1365 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1367 // Message has ownership of Texture while in transit from update -> render
1368 typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType;
1370 // Reserve some memory inside the render queue
1371 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1373 // Construct message in the render queue memory; note that delete should not be called on the return value
1374 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1377 void UpdateManager::RemoveTexture( Render::Texture* texture)
1379 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
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::RemoveTexture, texture );
1388 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1390 typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
1392 // Reserve some memory inside the message queue
1393 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1395 // Construct message in the message queue memory; note that delete should not be called on the return value
1396 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1399 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1401 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1403 // Reserve some memory inside the render queue
1404 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1406 // Construct message in the render queue memory; note that delete should not be called on the return value
1407 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1410 void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
1412 typedef MessageValue1< RenderManager, OwnerPointer< Render::FrameBuffer > > DerivedType;
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::AddFrameBuffer, frameBuffer );
1421 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1423 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
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::RemoveFrameBuffer, frameBuffer );
1432 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
1434 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t > DerivedType;
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::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1443 void UpdateManager::AttachDepthTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1445 typedef MessageValue3< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t > DerivedType;
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::AttachDepthTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1454 void UpdateManager::AttachDepthStencilTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1456 typedef MessageValue3< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t > DerivedType;
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::AttachDepthStencilTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1465 } // namespace SceneGraph
1467 } // namespace Internal