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/public-api/common/stage.h>
23 #include <dali/devel-api/common/owner-container.h>
24 #include <dali/devel-api/threading/mutex.h>
26 #include <dali/integration-api/core.h>
27 #include <dali/integration-api/render-controller.h>
28 #include <dali/internal/common/shader-data.h>
29 #include <dali/integration-api/debug.h>
31 #include <dali/internal/common/core-impl.h>
32 #include <dali/internal/common/message.h>
34 #include <dali/internal/event/common/notification-manager.h>
35 #include <dali/internal/event/common/property-notification-impl.h>
36 #include <dali/internal/event/common/property-notifier.h>
37 #include <dali/internal/event/effects/shader-factory.h>
38 #include <dali/internal/event/animation/animation-playlist.h>
40 #include <dali/internal/update/animation/scene-graph-animator.h>
41 #include <dali/internal/update/animation/scene-graph-animation.h>
42 #include <dali/internal/update/common/discard-queue.h>
43 #include <dali/internal/update/common/scene-graph-buffers.h>
44 #include <dali/internal/update/controllers/render-message-dispatcher.h>
45 #include <dali/internal/update/controllers/scene-controller-impl.h>
46 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
47 #include <dali/internal/update/manager/frame-callback-processor.h>
48 #include <dali/internal/update/manager/render-task-processor.h>
49 #include <dali/internal/update/manager/sorted-layers.h>
50 #include <dali/internal/update/manager/scene-graph-frame-callback.h>
51 #include <dali/internal/update/manager/update-algorithms.h>
52 #include <dali/internal/update/manager/update-manager-debug.h>
53 #include <dali/internal/update/manager/transform-manager.h>
54 #include <dali/internal/update/nodes/node.h>
55 #include <dali/internal/update/nodes/scene-graph-layer.h>
56 #include <dali/internal/update/queue/update-message-queue.h>
57 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
58 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
59 #include <dali/internal/update/render-tasks/scene-graph-camera.h>
61 #include <dali/internal/render/common/render-instruction-container.h>
62 #include <dali/internal/render/common/render-manager.h>
63 #include <dali/internal/render/queue/render-queue.h>
64 #include <dali/internal/render/shaders/scene-graph-shader.h>
66 // Un-comment to enable node tree debug logging
67 //#define NODE_TREE_LOGGING 1
69 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
70 #define SNAPSHOT_NODE_LOGGING \
71 const uint32_t FRAME_COUNT_TRIGGER = 16;\
72 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
74 for( auto&& scene : mImpl->scenes )
76 if ( scene && scene->root )\
78 mImpl->frameCounter = 0;\
79 PrintNodeTree( *scene->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
83 mImpl->frameCounter++;
85 #define SNAPSHOT_NODE_LOGGING
88 #if defined(DEBUG_ENABLED)
89 extern Debug::Filter* gRenderTaskLogFilter;
92 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_UPDATE_MANAGER" );
93 } // unnamed namespace
97 using namespace Dali::Integration;
98 using Dali::Internal::Update::MessageQueue;
112 * Helper to Erase an object from OwnerContainer using discard queue
113 * @param container to remove from
114 * @param object to remove
115 * @param discardQueue to put the object to
116 * @param updateBufferIndex to use
119 inline void EraseUsingDiscardQueue( OwnerContainer<T*>& container, T* object, DiscardQueue& discardQueue, BufferIndex updateBufferIndex )
121 DALI_ASSERT_DEBUG( object && "NULL object not allowed" );
123 // need to use the reference version of auto as we need the pointer to the pointer for the Release call below
124 for( auto&& iter : container )
126 if ( iter == object )
128 // Transfer ownership to the discard queue, this keeps the object alive, until the render-thread has finished with it
129 discardQueue.Add( updateBufferIndex, container.Release( &iter ) ); // take the address of the reference to a pointer (iter)
130 return; // return as we only ever remove one object. Iterators to container are now invalidated as well so cannot continue
136 * Descends into node's hierarchy and sorts the children of each child according to their depth-index.
137 * @param[in] node The node whose hierarchy to descend
139 void SortSiblingNodesRecursively( Node& node )
141 NodeContainer& container = node.GetChildren();
142 std::sort( container.Begin(), container.End(),
143 []( Node* a, Node* b ) { return a->GetDepthIndex() < b->GetDepthIndex(); } );
145 // Descend tree and sort as well
146 for( auto&& iter : container )
148 SortSiblingNodesRecursively( *iter );
152 } // unnamed namespace
155 * Structure to contain UpdateManager internal data
157 struct UpdateManager::Impl
159 // SceneInfo keeps the root node of the Scene, its scene graph render task list, and the list of Layer pointers sorted by depth
162 SceneInfo( Layer* root ) ///< Constructor
167 ~SceneInfo() = default; ///< Default non-virtual destructor
168 SceneInfo( SceneInfo&& rhs ) = default; ///< Move constructor
169 SceneInfo& operator=( SceneInfo&& rhs ) = default; ///< Move assignment operator
170 SceneInfo& operator=( const SceneInfo& rhs ) = delete; ///< Assignment operator
171 SceneInfo( const SceneInfo& rhs ) = delete; ///< Copy constructor
173 Layer* root{ nullptr }; ///< Root node (root is a layer). The layer is not stored in the node memory pool.
174 OwnerPointer< RenderTaskList > taskList; ///< Scene graph render task list
175 SortedLayerPointers sortedLayerList; ///< List of Layer pointers sorted by depth (one list of sorted layers per root)
176 OwnerPointer< Scene > scene; ///< Scene graph object of the scene
179 Impl( NotificationManager& notificationManager,
180 CompleteNotificationInterface& animationPlaylist,
181 PropertyNotifier& propertyNotifier,
182 DiscardQueue& discardQueue,
183 RenderController& renderController,
184 RenderManager& renderManager,
185 RenderQueue& renderQueue,
186 SceneGraphBuffers& sceneGraphBuffers,
187 RenderTaskProcessor& renderTaskProcessor )
188 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
189 notificationManager( notificationManager ),
191 animationPlaylist( animationPlaylist ),
192 propertyNotifier( propertyNotifier ),
194 discardQueue( discardQueue ),
195 renderController( renderController ),
196 sceneController( NULL ),
197 renderManager( renderManager ),
198 renderQueue( renderQueue ),
199 renderTaskProcessor( renderTaskProcessor ),
200 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
204 panGestureProcessor( NULL ),
205 messageQueue( renderController, sceneGraphBuffers ),
206 frameCallbackProcessor( NULL ),
207 keepRenderingSeconds( 0.0f ),
208 nodeDirtyFlags( NodePropertyFlags::TRANSFORM ), // set to TransformFlag to ensure full update the first time through Update()
210 renderingBehavior( DevelStage::Rendering::IF_REQUIRED ),
211 animationFinishedDuringUpdate( false ),
212 previousUpdateScene( false ),
213 renderTaskWaiting( false ),
214 renderersAdded( false ),
215 surfaceRectChanged( false )
217 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
219 // create first 'dummy' node
225 // Disconnect render tasks from nodes, before destroying the nodes
226 for( auto&& scene : scenes )
228 if ( scene && scene->taskList )
230 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
231 for ( auto&& task : tasks )
233 task->SetSourceNode( NULL );
238 // UpdateManager owns the Nodes. Although Nodes are pool allocated they contain heap allocated parts
239 // like custom properties, which get released here
240 Vector<Node*>::Iterator iter = nodes.Begin()+1;
241 Vector<Node*>::Iterator endIter = nodes.End();
242 for(;iter!=endIter;++iter)
244 (*iter)->OnDestroy();
248 for( auto&& scene : scenes )
250 if ( scene && scene->root )
252 scene->root->OnDestroy();
253 Node::Delete( scene->root );
258 delete sceneController;
262 * Lazy init for FrameCallbackProcessor.
263 * @param[in] updateManager A reference to the update-manager
265 FrameCallbackProcessor& GetFrameCallbackProcessor( UpdateManager& updateManager )
267 if( ! frameCallbackProcessor )
269 frameCallbackProcessor = new FrameCallbackProcessor( updateManager, transformManager );
271 return *frameCallbackProcessor;
274 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
275 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
276 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
277 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
278 CompleteNotificationInterface& animationPlaylist; ///< Holds handles to all the animations
279 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
280 ShaderSaver* shaderSaver; ///< Saves shader binaries.
281 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
282 RenderController& renderController; ///< render controller
283 SceneControllerImpl* sceneController; ///< scene controller
284 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
285 RenderQueue& renderQueue; ///< Used to queue messages for the next render
286 RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
288 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
290 using SceneInfoPtr = std::unique_ptr< SceneInfo >;
291 std::vector< SceneInfoPtr > scenes; ///< A container of SceneInfo.
293 Vector<Node*> nodes; ///< A container of all instantiated nodes
295 OwnerContainer< Camera* > cameras; ///< A container of cameras
296 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
298 OwnerContainer< PropertyResetterBase* > propertyResetters; ///< A container of property resetters
299 OwnerContainer< Animation* > animations; ///< A container of owned animations
300 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
301 OwnerContainer< Renderer* > renderers; ///< A container of owned renderers
302 OwnerContainer< TextureSet* > textureSets; ///< A container of owned texture sets
303 OwnerContainer< Shader* > shaders; ///< A container of owned shaders
304 OwnerPointer< PanGesture > panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager
306 MessageQueue messageQueue; ///< The messages queued from the event-thread
307 std::vector<Internal::ShaderDataPtr> renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
308 std::vector<Internal::ShaderDataPtr> updateCompiledShaders; ///< Shaders to be sent from Update to Event
309 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
311 OwnerPointer<FrameCallbackProcessor> frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required.
313 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
314 NodePropertyFlags nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
315 uint32_t frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
317 DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior
319 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
320 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
321 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
322 bool renderersAdded; ///< Flag to keep track when renderers have been added to avoid unnecessary processing
323 bool surfaceRectChanged; ///< True if the default surface rect is changed
327 Impl( const Impl& ); ///< Undefined
328 Impl& operator=( const Impl& ); ///< Undefined
331 UpdateManager::UpdateManager( NotificationManager& notificationManager,
332 CompleteNotificationInterface& animationFinishedNotifier,
333 PropertyNotifier& propertyNotifier,
334 DiscardQueue& discardQueue,
335 RenderController& controller,
336 RenderManager& renderManager,
337 RenderQueue& renderQueue,
338 RenderTaskProcessor& renderTaskProcessor )
341 mImpl = new Impl( notificationManager,
342 animationFinishedNotifier,
349 renderTaskProcessor );
353 UpdateManager::~UpdateManager()
358 void UpdateManager::InstallRoot( OwnerPointer<Layer>& layer )
360 DALI_ASSERT_DEBUG( layer->IsLayer() );
361 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
363 Layer* rootLayer = layer.Release();
365 DALI_ASSERT_DEBUG( std::find_if( mImpl->scenes.begin(), mImpl->scenes.end(),
366 [rootLayer]( Impl::SceneInfoPtr& scene )
368 return scene && scene->root == rootLayer;
370 ) == mImpl->scenes.end() && "Root Node already installed" );
372 rootLayer->CreateTransform( &mImpl->transformManager );
373 rootLayer->SetRoot(true);
375 mImpl->scenes.emplace_back( new Impl::SceneInfo( rootLayer ) );
378 void UpdateManager::UninstallRoot( Layer* layer )
380 DALI_ASSERT_DEBUG( layer->IsLayer() );
381 DALI_ASSERT_DEBUG( layer->GetParent() == NULL );
383 for (auto iter = mImpl->scenes.begin(); iter != mImpl->scenes.end(); ++iter)
385 if( (*iter) && (*iter)->root == layer )
387 mImpl->scenes.erase( iter );
392 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), layer );
394 // Notify the layer about impending destruction
398 void UpdateManager::AddNode( OwnerPointer<Node>& node )
400 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
402 // Nodes must be sorted by pointer
403 Node* rawNode = node.Release();
404 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddNode\n", rawNode );
406 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
407 for( Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter )
409 if( rawNode > (*iter) )
411 mImpl->nodes.Insert((iter+1), rawNode );
412 rawNode->CreateTransform( &mImpl->transformManager );
418 void UpdateManager::ConnectNode( Node* parent, Node* node )
420 DALI_ASSERT_ALWAYS( NULL != parent );
421 DALI_ASSERT_ALWAYS( NULL != node );
422 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
424 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] ConnectNode\n", node );
426 parent->ConnectChild( node );
428 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
429 if( mImpl->frameCallbackProcessor )
431 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
435 void UpdateManager::DisconnectNode( Node* node )
437 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DisconnectNode\n", node );
439 Node* parent = node->GetParent();
440 DALI_ASSERT_ALWAYS( NULL != parent );
441 parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused
443 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
445 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
446 if( mImpl->frameCallbackProcessor )
448 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
452 void UpdateManager::DestroyNode( Node* node )
454 DALI_ASSERT_ALWAYS( NULL != node );
455 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
457 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DestroyNode\n", node );
459 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
460 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
461 for(;iter!=endIter;++iter)
465 mImpl->nodes.Erase(iter);
470 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
472 // Notify the Node about impending destruction
476 void UpdateManager::AddCamera( OwnerPointer< Camera >& camera )
478 mImpl->cameras.PushBack( camera.Release() ); // takes ownership
481 void UpdateManager::RemoveCamera( Camera* camera )
483 // Find the camera and destroy it
484 EraseUsingDiscardQueue( mImpl->cameras, camera, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
487 void UpdateManager::AddObject( OwnerPointer<PropertyOwner>& object )
489 mImpl->customObjects.PushBack( object.Release() );
492 void UpdateManager::RemoveObject( PropertyOwner* object )
494 mImpl->customObjects.EraseObject( object );
497 void UpdateManager::AddRenderTaskList( OwnerPointer<RenderTaskList>& taskList )
499 RenderTaskList* taskListPointer = taskList.Release();
500 taskListPointer->SetRenderMessageDispatcher( &mImpl->renderMessageDispatcher );
502 mImpl->scenes.back()->taskList = taskListPointer;
505 void UpdateManager::RemoveRenderTaskList( RenderTaskList* taskList )
507 for ( auto&& scene : mImpl->scenes )
509 if ( scene && scene->taskList == taskList )
511 scene->taskList.Reset();
517 void UpdateManager::AddScene( OwnerPointer< Scene >& scene )
519 mImpl->scenes.back()->scene = scene.Release();
521 // Initialize the context from render manager
522 typedef MessageValue1< RenderManager, SceneGraph::Scene* > DerivedType;
524 // Reserve some memory inside the render queue
525 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
527 // Construct message in the render queue memory; note that delete should not be called on the return value
528 SceneGraph::Scene& sceneObject = *mImpl->scenes.back()->scene;
529 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::InitializeScene, &sceneObject );
532 void UpdateManager::RemoveScene( Scene* scene )
534 // Initialize the context from render manager
535 typedef MessageValue1< RenderManager, SceneGraph::Scene* > DerivedType;
537 // Reserve some memory inside the render queue
538 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
540 // Construct message in the render queue memory; note that delete should not be called on the return value
541 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UninitializeScene, scene );
543 for ( auto&& sceneInfo : mImpl->scenes )
545 if ( sceneInfo && sceneInfo->scene && sceneInfo->scene.Get() == scene )
547 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), sceneInfo->scene.Release() ); // take the address of the reference to a pointer
553 void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation )
555 mImpl->animations.PushBack( animation.Release() );
558 void UpdateManager::StopAnimation( Animation* animation )
560 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
562 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
564 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
567 void UpdateManager::RemoveAnimation( Animation* animation )
569 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
571 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
573 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
576 bool UpdateManager::IsAnimationRunning() const
578 // Find any animation that isn't stopped or paused
579 for ( auto&& iter : mImpl->animations )
581 const Animation::State state = iter->GetState();
583 if (state != Animation::Stopped &&
584 state != Animation::Paused)
586 return true; // stop iteration as soon as first one is found
593 void UpdateManager::AddPropertyResetter( OwnerPointer<PropertyResetterBase>& propertyResetter )
595 propertyResetter->Initialize();
596 mImpl->propertyResetters.PushBack( propertyResetter.Release() );
599 void UpdateManager::AddPropertyNotification( OwnerPointer< PropertyNotification >& propertyNotification )
601 mImpl->propertyNotifications.PushBack( propertyNotification.Release() );
604 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
606 mImpl->propertyNotifications.EraseObject( propertyNotification );
609 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
611 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
612 propertyNotification->SetNotifyMode( notifyMode );
615 void UpdateManager::AddShader( OwnerPointer< Shader >& shader )
617 mImpl->shaders.PushBack( shader.Release() );
620 void UpdateManager::RemoveShader( Shader* shader )
622 // Find the shader and destroy it
623 EraseUsingDiscardQueue( mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
626 void UpdateManager::SetShaderProgram( Shader* shader,
627 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
632 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
634 // Reserve some memory inside the render queue
635 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
637 // Construct message in the render queue memory; note that delete should not be called on the return value
638 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
642 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
644 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
645 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
647 // lock as update might be sending previously compiled shaders to event thread
648 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
649 mImpl->renderCompiledShaders.push_back( shaderData );
653 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
655 mImpl->shaderSaver = &upstream;
658 void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer )
660 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer.Get() );
662 renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
663 mImpl->renderers.PushBack( renderer.Release() );
664 mImpl->renderersAdded = true;
667 void UpdateManager::RemoveRenderer( Renderer* renderer )
669 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] RemoveRenderer\n", renderer );
671 // Find the renderer and destroy it
672 EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
673 // Need to remove the render object as well
674 renderer->DisconnectFromSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
677 void UpdateManager::SetPanGestureProcessor( PanGesture* panGestureProcessor )
679 DALI_ASSERT_DEBUG( NULL != panGestureProcessor );
681 mImpl->panGestureProcessor = panGestureProcessor;
684 void UpdateManager::AddTextureSet( OwnerPointer< TextureSet >& textureSet )
686 mImpl->textureSets.PushBack( textureSet.Release() );
689 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
691 mImpl->textureSets.EraseObject( textureSet );
694 uint32_t* UpdateManager::ReserveMessageSlot( uint32_t size, bool updateScene )
696 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
699 void UpdateManager::EventProcessingStarted()
701 mImpl->messageQueue.EventProcessingStarted();
704 bool UpdateManager::FlushQueue()
706 return mImpl->messageQueue.FlushQueue();
709 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
711 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
712 mImpl->animationFinishedDuringUpdate = false;
714 // Reset all animating / constrained properties
715 std::vector<PropertyResetterBase*>toDelete;
716 for( auto&& element : mImpl->propertyResetters )
718 element->ResetToBaseValue( bufferIndex );
719 if( element->IsFinished() )
721 toDelete.push_back( element );
725 // If a resetter is no longer required (the animator or constraint has been removed), delete it.
726 for( auto&& elementPtr : toDelete )
728 mImpl->propertyResetters.EraseObject( elementPtr );
731 // Clear all root nodes dirty flags
732 for( auto& scene : mImpl->scenes )
734 auto root = scene->root;
735 root->ResetDirtyFlags( bufferIndex );
738 // Clear node dirty flags
739 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
740 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
741 for( ;iter != endIter; ++iter )
743 (*iter)->ResetDirtyFlags( bufferIndex );
747 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds )
749 bool gestureUpdated( false );
751 if( mImpl->panGestureProcessor )
753 // gesture processor only supports default properties
754 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
755 gestureUpdated |= mImpl->panGestureProcessor->UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
758 return gestureUpdated;
761 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
763 auto&& iter = mImpl->animations.Begin();
764 bool animationLooped = false;
766 while ( iter != mImpl->animations.End() )
768 Animation* animation = *iter;
769 bool finished = false;
771 bool progressMarkerReached = false;
772 animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
774 if ( progressMarkerReached )
776 mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
779 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
780 animationLooped = animationLooped || looped;
782 // Remove animations that had been destroyed but were still waiting for an update
783 if (animation->GetState() == Animation::Destroyed)
785 iter = mImpl->animations.Erase(iter);
793 // queue the notification on finished or looped (to update loop count)
794 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
796 // The application should be notified by NotificationManager, in another thread
797 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
801 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
803 //Constrain custom objects (in construction order)
804 for ( auto&& object : mImpl->customObjects )
806 ConstrainPropertyOwner( *object, bufferIndex );
810 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
812 // Constrain render-tasks
813 for ( auto&& scene : mImpl->scenes )
815 if ( scene && scene->taskList )
817 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
818 for ( auto&& task : tasks )
820 ConstrainPropertyOwner( *task, bufferIndex );
826 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
828 // constrain shaders... (in construction order)
829 for ( auto&& shader : mImpl->shaders )
831 ConstrainPropertyOwner( *shader, bufferIndex );
835 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
837 for( auto&& notification : mImpl->propertyNotifications )
839 bool valid = notification->Check( bufferIndex );
842 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
847 void UpdateManager::ForwardCompiledShadersToEventThread()
849 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
850 if( mImpl->shaderSaver )
852 // lock and swap the queues
854 // render might be attempting to send us more binaries at the same time
855 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
856 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
859 if( mImpl->updateCompiledShaders.size() > 0 )
861 ShaderSaver& factory = *mImpl->shaderSaver;
862 for( auto&& shader : mImpl->updateCompiledShaders )
864 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, shader ) );
866 // we don't need them in update anymore
867 mImpl->updateCompiledShaders.clear();
872 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
874 for( auto&& renderer : mImpl->renderers )
877 ConstrainPropertyOwner( *renderer, bufferIndex );
879 renderer->PrepareRender( bufferIndex );
883 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
885 mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
887 for ( auto&& scene : mImpl->scenes )
889 if ( scene && scene->root )
891 // Prepare resources, update shaders, for each node
892 // And add the renderers to the sorted layers. Start from root, which is also a layer
893 mImpl->nodeDirtyFlags |= UpdateNodeTree( *scene->root,
895 mImpl->renderQueue );
900 uint32_t UpdateManager::Update( float elapsedSeconds,
901 uint32_t lastVSyncTimeMilliseconds,
902 uint32_t nextVSyncTimeMilliseconds,
903 bool renderToFboEnabled,
904 bool isRenderingToFbo )
906 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
908 //Clear nodes/resources which were previously discarded
909 mImpl->discardQueue.Clear( bufferIndex );
911 //Process Touches & Gestures
912 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
914 bool updateScene = // The scene-graph requires an update if..
915 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
916 IsAnimationRunning() || // ..at least one animation is running OR
917 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
918 gestureUpdated; // ..a gesture property was updated
920 bool keepRendererRendering = false;
922 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
923 // values if the scene was updated in the previous frame.
924 if( updateScene || mImpl->previousUpdateScene )
926 //Reset properties from the previous update
927 ResetProperties( bufferIndex );
928 mImpl->transformManager.ResetToBaseValue();
931 // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
932 // between calling IsSceneUpdateRequired() above and here, so updateScene should
934 updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
936 //Forward compiled shader programs to event thread for saving
937 ForwardCompiledShadersToEventThread();
939 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
940 // renderer lists if the scene was updated in the previous frame.
941 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
942 if( updateScene || mImpl->previousUpdateScene )
945 Animate( bufferIndex, elapsedSeconds );
947 //Constraint custom objects
948 ConstrainCustomObjects( bufferIndex );
950 //Clear the lists of renderers from the previous update
951 for( auto&& scene : mImpl->scenes )
955 for( auto&& layer : scene->sortedLayerList )
959 layer->ClearRenderables();
965 // Call the frame-callback-processor if set
966 if( mImpl->frameCallbackProcessor )
968 mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
971 //Update node hierarchy, apply constraints and perform sorting / culling.
972 //This will populate each Layer with a list of renderers which are ready.
973 UpdateNodes( bufferIndex );
975 //Apply constraints to RenderTasks, shaders
976 ConstrainRenderTasks( bufferIndex );
977 ConstrainShaders( bufferIndex );
979 //Update renderers and apply constraints
980 UpdateRenderers( bufferIndex );
982 //Update the transformations of all the nodes
983 mImpl->transformManager.Update();
985 //Process Property Notifications
986 ProcessPropertyNotifications( bufferIndex );
989 for( auto&& cameraIterator : mImpl->cameras )
991 cameraIterator->Update( bufferIndex );
994 //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
995 //reset the update buffer index and make sure there is enough room in the instruction container
996 if( mImpl->renderersAdded )
998 // Calculate how many render tasks we have in total
999 std::size_t numberOfRenderTasks = 0;
1000 for (auto&& scene : mImpl->scenes )
1002 if ( scene && scene->taskList )
1004 numberOfRenderTasks += scene->taskList->GetTasks().Count();
1009 std::size_t numberOfRenderInstructions = 0;
1010 for ( auto&& scene : mImpl->scenes )
1012 if ( scene && scene->root && scene->taskList && scene->scene )
1014 scene->scene->GetRenderInstructions().ResetAndReserve( bufferIndex,
1015 static_cast<uint32_t>( scene->taskList->GetTasks().Count() ) );
1017 keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
1020 scene->sortedLayerList,
1021 *scene->scene->GetContext(),
1022 scene->scene->GetRenderInstructions(),
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 typedef MessageValue1< RenderManager, Rect<int32_t> > DerivedType;
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 typedef MessageValue1< RenderManager, Scene* > DerivedType;
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::KeepRendering( float durationSeconds )
1158 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1161 void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
1163 mImpl->renderingBehavior = renderingBehavior;
1166 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
1168 for ( auto&& scene : mImpl->scenes )
1170 if ( scene && scene->root == rootLayer )
1172 scene->sortedLayerList = layers;
1178 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1180 // note,this vector is already in depth order. It could be used as-is to
1181 // remove sorting in update algorithm. However, it lacks layer boundary markers.
1182 for( auto&& iter : nodeDepths->nodeDepths )
1184 iter.node->SetDepthIndex( iter.sortedDepth );
1187 for ( auto&& scene : mImpl->scenes )
1191 // Go through node hierarchy and rearrange siblings according to depth-index
1192 SortSiblingNodesRecursively( *scene->root );
1197 bool UpdateManager::IsDefaultSurfaceRectChanged()
1199 bool surfaceRectChanged = mImpl->surfaceRectChanged;
1202 mImpl->surfaceRectChanged = false;
1204 return surfaceRectChanged;
1207 void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode )
1209 mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode );
1212 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1214 mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback );
1217 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1219 // Message has ownership of Sampler while in transit from update to render
1220 typedef MessageValue1< RenderManager, OwnerPointer< 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::AddSampler, sampler );
1229 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1231 typedef MessageValue1< RenderManager, Render::Sampler* > 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::RemoveSampler, sampler );
1240 void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
1242 typedef MessageValue3< RenderManager, Render::Sampler*, 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::SetFilterMode, sampler, minFilterMode, magFilterMode );
1251 void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
1253 typedef MessageValue4< RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t > DerivedType;
1255 // Reserve some memory inside the render queue
1256 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1258 // Construct message in the render queue memory; note that delete should not be called on the return value
1259 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1262 void UpdateManager::AddPropertyBuffer( OwnerPointer< Render::PropertyBuffer >& propertyBuffer )
1264 // Message has ownership of format while in transit from update -> render
1265 typedef MessageValue1< RenderManager, OwnerPointer< 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::AddPropertyBuffer, propertyBuffer );
1274 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1276 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1278 // Reserve some memory inside the render queue
1279 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1281 // Construct message in the render queue memory; note that delete should not be called on the return value
1282 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1285 void UpdateManager::SetPropertyBufferFormat( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Render::PropertyBuffer::Format>& format )
1287 // Message has ownership of format while in transit from update -> render
1288 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType;
1290 // Reserve some memory inside the render queue
1291 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1293 // Construct message in the render queue memory; note that delete should not be called on the return value
1294 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1297 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
1299 // Message has ownership of format while in transit from update -> render
1300 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<uint8_t> >, uint32_t > DerivedType;
1302 // Reserve some memory inside the render queue
1303 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1305 // Construct message in the render queue memory; note that delete should not be called on the return value
1306 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1309 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1311 // Message has ownership of format while in transit from update -> render
1312 typedef MessageValue1< RenderManager, OwnerPointer< 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::AddGeometry, geometry );
1321 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1323 typedef MessageValue1< RenderManager, Render::Geometry* > 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::RemoveGeometry, geometry );
1332 void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
1334 typedef MessageValue2< RenderManager, Render::Geometry*, uint32_t > 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, &RenderManager::SetGeometryType, geometry, geometryType );
1343 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
1345 typedef IndexBufferMessage< RenderManager > 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, geometry, indices );
1354 void UpdateManager::RemoveVertexBuffer( 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::RemoveVertexBuffer, geometry, propertyBuffer );
1365 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1367 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1369 // Reserve some memory inside the render queue
1370 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1372 // Construct message in the render queue memory; note that delete should not be called on the return value
1373 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, propertyBuffer );
1376 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1378 // Message has ownership of Texture while in transit from update -> render
1379 typedef MessageValue1< RenderManager, OwnerPointer< 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::AddTexture, texture );
1388 void UpdateManager::RemoveTexture( Render::Texture* texture)
1390 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1392 // Reserve some memory inside the render queue
1393 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1395 // Construct message in the render queue memory; note that delete should not be called on the return value
1396 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1399 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1401 typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
1403 // Reserve some memory inside the message queue
1404 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1406 // Construct message in the message queue memory; note that delete should not be called on the return value
1407 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1410 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1412 typedef MessageValue1< RenderManager, Render::Texture* > 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::GenerateMipmaps, texture );
1421 void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
1423 typedef MessageValue1< RenderManager, OwnerPointer< 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::AddFrameBuffer, frameBuffer );
1432 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1434 typedef MessageValue1< RenderManager, Render::FrameBuffer* > 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::RemoveFrameBuffer, frameBuffer );
1443 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
1445 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, 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::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1454 void UpdateManager::AttachDepthTextureToFrameBuffer( 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::AttachDepthTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1465 void UpdateManager::AttachDepthStencilTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1467 typedef MessageValue3< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t > DerivedType;
1469 // Reserve some memory inside the render queue
1470 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1472 // Construct message in the render queue memory; note that delete should not be called on the return value
1473 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachDepthStencilTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1476 } // namespace SceneGraph
1478 } // namespace Internal