2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/update/manager/update-manager.h>
22 #include <dali/integration-api/core.h>
24 #include <dali/internal/event/common/notification-manager.h>
25 #include <dali/internal/event/common/property-notifier.h>
26 #include <dali/internal/event/effects/shader-factory.h>
27 #include <dali/internal/event/animation/animation-playlist.h>
29 #include <dali/internal/update/common/discard-queue.h>
30 #include <dali/internal/update/controllers/render-message-dispatcher.h>
31 #include <dali/internal/update/controllers/scene-controller-impl.h>
32 #include <dali/internal/update/manager/frame-callback-processor.h>
33 #include <dali/internal/update/manager/render-task-processor.h>
34 #include <dali/internal/update/manager/update-algorithms.h>
35 #include <dali/internal/update/manager/update-manager-debug.h>
36 #include <dali/internal/update/manager/transform-manager.h>
37 #include <dali/internal/update/nodes/node.h>
38 #include <dali/internal/update/queue/update-message-queue.h>
40 #include <dali/internal/render/common/render-manager.h>
41 #include <dali/internal/render/queue/render-queue.h>
43 // Un-comment to enable node tree debug logging
44 //#define NODE_TREE_LOGGING 1
46 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
47 #define SNAPSHOT_NODE_LOGGING \
48 const uint32_t FRAME_COUNT_TRIGGER = 16;\
49 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
51 for( auto&& scene : mImpl->scenes )
53 if ( scene && scene->root )\
55 mImpl->frameCounter = 0;\
56 PrintNodeTree( *scene->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
60 mImpl->frameCounter++;
62 #define SNAPSHOT_NODE_LOGGING
65 #if defined(DEBUG_ENABLED)
66 extern Debug::Filter* gRenderTaskLogFilter;
69 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_UPDATE_MANAGER" );
70 } // unnamed namespace
74 using namespace Dali::Integration;
75 using Dali::Internal::Update::MessageQueue;
89 * Helper to Erase an object from OwnerContainer using discard queue
90 * @param container to remove from
91 * @param object to remove
92 * @param discardQueue to put the object to
93 * @param updateBufferIndex to use
96 inline void EraseUsingDiscardQueue( OwnerContainer<T*>& container, T* object, DiscardQueue& discardQueue, BufferIndex updateBufferIndex )
98 DALI_ASSERT_DEBUG( object && "NULL object not allowed" );
100 // need to use the reference version of auto as we need the pointer to the pointer for the Release call below
101 for( auto&& iter : container )
103 if ( iter == object )
105 // Transfer ownership to the discard queue, this keeps the object alive, until the render-thread has finished with it
106 discardQueue.Add( updateBufferIndex, container.Release( &iter ) ); // take the address of the reference to a pointer (iter)
107 return; // return as we only ever remove one object. Iterators to container are now invalidated as well so cannot continue
113 * Descends into node's hierarchy and sorts the children of each child according to their depth-index.
114 * @param[in] node The node whose hierarchy to descend
116 void SortSiblingNodesRecursively( Node& node )
118 NodeContainer& container = node.GetChildren();
119 std::sort( container.Begin(), container.End(),
120 []( Node* a, Node* b ) { return a->GetDepthIndex() < b->GetDepthIndex(); } );
122 // Descend tree and sort as well
123 for( auto&& iter : container )
125 SortSiblingNodesRecursively( *iter );
129 } // unnamed namespace
132 * Structure to contain UpdateManager internal data
134 struct UpdateManager::Impl
136 // SceneInfo keeps the root node of the Scene, its scene graph render task list, and the list of Layer pointers sorted by depth
139 SceneInfo( Layer* root ) ///< Constructor
144 ~SceneInfo() = default; ///< Default non-virtual destructor
145 SceneInfo( SceneInfo&& rhs ) = default; ///< Move constructor
146 SceneInfo& operator=( SceneInfo&& rhs ) = default; ///< Move assignment operator
147 SceneInfo& operator=( const SceneInfo& rhs ) = delete; ///< Assignment operator
148 SceneInfo( const SceneInfo& rhs ) = delete; ///< Copy constructor
150 Layer* root{ nullptr }; ///< Root node (root is a layer). The layer is not stored in the node memory pool.
151 OwnerPointer< RenderTaskList > taskList; ///< Scene graph render task list
152 SortedLayerPointers sortedLayerList; ///< List of Layer pointers sorted by depth (one list of sorted layers per root)
153 OwnerPointer< Scene > scene; ///< Scene graph object of the scene
156 Impl( NotificationManager& notificationManager,
157 CompleteNotificationInterface& animationPlaylist,
158 PropertyNotifier& propertyNotifier,
159 DiscardQueue& discardQueue,
160 RenderController& renderController,
161 RenderManager& renderManager,
162 RenderQueue& renderQueue,
163 SceneGraphBuffers& sceneGraphBuffers,
164 RenderTaskProcessor& renderTaskProcessor )
165 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
166 notificationManager( notificationManager ),
168 animationPlaylist( animationPlaylist ),
169 propertyNotifier( propertyNotifier ),
170 shaderSaver( nullptr ),
171 discardQueue( discardQueue ),
172 renderController( renderController ),
173 sceneController( nullptr ),
174 renderManager( renderManager ),
175 renderQueue( renderQueue ),
176 renderTaskProcessor( renderTaskProcessor ),
177 backgroundColor( Dali::DEFAULT_BACKGROUND_COLOR ),
181 panGestureProcessor( nullptr ),
182 messageQueue( renderController, sceneGraphBuffers ),
183 frameCallbackProcessor( nullptr ),
184 keepRenderingSeconds( 0.0f ),
185 nodeDirtyFlags( NodePropertyFlags::TRANSFORM ), // set to TransformFlag to ensure full update the first time through Update()
187 renderingBehavior( DevelStage::Rendering::IF_REQUIRED ),
188 animationFinishedDuringUpdate( false ),
189 previousUpdateScene( false ),
190 renderTaskWaiting( false ),
191 renderersAdded( false ),
192 renderingRequired( false )
194 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
196 // create first 'dummy' node
197 nodes.PushBack(nullptr);
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( nullptr );
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 renderingRequired; ///< True if required to render the current frame
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( nullptr == node->GetParent() ); // Should not have a parent yet
379 Node* rawNode = node.Release();
380 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddNode\n", rawNode );
382 mImpl->nodes.PushBack(rawNode);
383 rawNode->CreateTransform(&mImpl->transformManager);
386 void UpdateManager::ConnectNode( Node* parent, Node* node )
388 DALI_ASSERT_ALWAYS( nullptr != parent );
389 DALI_ASSERT_ALWAYS( nullptr != node );
390 DALI_ASSERT_ALWAYS( nullptr == node->GetParent() ); // Should not have a parent yet
392 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] ConnectNode\n", node );
394 parent->ConnectChild( node );
396 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
397 if( mImpl->frameCallbackProcessor )
399 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
403 void UpdateManager::DisconnectNode( Node* node )
405 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DisconnectNode\n", node );
407 Node* parent = node->GetParent();
408 DALI_ASSERT_ALWAYS( nullptr != parent );
409 parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused
411 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
413 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
414 if( mImpl->frameCallbackProcessor )
416 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
420 void UpdateManager::DestroyNode( Node* node )
422 DALI_ASSERT_ALWAYS( nullptr != node );
423 DALI_ASSERT_ALWAYS( nullptr == node->GetParent() ); // Should have been disconnected
425 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DestroyNode\n", node );
427 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
428 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
429 for(;iter!=endIter;++iter)
433 mImpl->nodes.Erase(iter);
438 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
440 // Notify the Node about impending destruction
444 void UpdateManager::AddCamera( OwnerPointer< Camera >& camera )
446 mImpl->cameras.PushBack( camera.Release() ); // takes ownership
449 void UpdateManager::RemoveCamera( Camera* camera )
451 // Find the camera and destroy it
452 EraseUsingDiscardQueue( mImpl->cameras, camera, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
455 void UpdateManager::AddObject( OwnerPointer<PropertyOwner>& object )
457 mImpl->customObjects.PushBack( object.Release() );
460 void UpdateManager::RemoveObject( PropertyOwner* object )
462 mImpl->customObjects.EraseObject( object );
465 void UpdateManager::AddRenderTaskList( OwnerPointer<RenderTaskList>& taskList )
467 RenderTaskList* taskListPointer = taskList.Release();
468 taskListPointer->SetRenderMessageDispatcher( &mImpl->renderMessageDispatcher );
470 mImpl->scenes.back()->taskList = taskListPointer;
473 void UpdateManager::RemoveRenderTaskList( RenderTaskList* taskList )
475 for ( auto&& scene : mImpl->scenes )
477 if ( scene && scene->taskList == taskList )
479 scene->taskList.Reset();
485 void UpdateManager::AddScene( OwnerPointer< Scene >& scene )
487 mImpl->scenes.back()->scene = scene.Release();
489 // Initialize the context from render manager
490 typedef MessageValue1< RenderManager, SceneGraph::Scene* > DerivedType;
492 // Reserve some memory inside the render queue
493 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
495 // Construct message in the render queue memory; note that delete should not be called on the return value
496 SceneGraph::Scene& sceneObject = *mImpl->scenes.back()->scene;
497 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::InitializeScene, &sceneObject );
500 void UpdateManager::RemoveScene( Scene* scene )
502 // Initialize the context from render manager
503 using DerivedType = MessageValue1<RenderManager, SceneGraph::Scene*>;
505 // Reserve some memory inside the render queue
506 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
508 // Construct message in the render queue memory; note that delete should not be called on the return value
509 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UninitializeScene, scene );
511 for ( auto&& sceneInfo : mImpl->scenes )
513 if ( sceneInfo && sceneInfo->scene && sceneInfo->scene.Get() == scene )
515 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), sceneInfo->scene.Release() ); // take the address of the reference to a pointer
521 void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation )
523 mImpl->animations.PushBack( animation.Release() );
526 void UpdateManager::StopAnimation( Animation* animation )
528 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
530 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
532 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
535 void UpdateManager::RemoveAnimation( Animation* animation )
537 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
539 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
541 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
544 bool UpdateManager::IsAnimationRunning() const
546 // Find any animation that isn't stopped or paused
547 for ( auto&& iter : mImpl->animations )
549 const Animation::State state = iter->GetState();
551 if (state != Animation::Stopped &&
552 state != Animation::Paused)
554 return true; // stop iteration as soon as first one is found
561 void UpdateManager::AddPropertyResetter( OwnerPointer<PropertyResetterBase>& propertyResetter )
563 propertyResetter->Initialize();
564 mImpl->propertyResetters.PushBack( propertyResetter.Release() );
567 void UpdateManager::AddPropertyNotification( OwnerPointer< PropertyNotification >& propertyNotification )
569 mImpl->propertyNotifications.PushBack( propertyNotification.Release() );
572 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
574 mImpl->propertyNotifications.EraseObject( propertyNotification );
577 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
579 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
580 propertyNotification->SetNotifyMode( notifyMode );
583 void UpdateManager::AddShader( OwnerPointer< Shader >& shader )
585 mImpl->shaders.PushBack( shader.Release() );
588 void UpdateManager::RemoveShader( Shader* shader )
590 // Find the shader and destroy it
591 EraseUsingDiscardQueue( mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
594 void UpdateManager::SetShaderProgram( Shader* shader,
595 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
599 using DerivedType = MessageValue3<Shader, Internal::ShaderDataPtr, ProgramCache*, bool>;
601 // Reserve some memory inside the render queue
602 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
604 // Construct message in the render queue memory; note that delete should not be called on the return value
605 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
609 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
611 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
612 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
614 // lock as update might be sending previously compiled shaders to event thread
615 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
616 mImpl->renderCompiledShaders.push_back( shaderData );
620 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
622 mImpl->shaderSaver = &upstream;
625 void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer )
627 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer.Get() );
629 renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
630 mImpl->renderers.PushBack( renderer.Release() );
631 mImpl->renderersAdded = true;
634 void UpdateManager::RemoveRenderer( Renderer* renderer )
636 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] RemoveRenderer\n", renderer );
638 // Find the renderer and destroy it
639 EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
640 // Need to remove the render object as well
641 renderer->DisconnectFromSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
644 void UpdateManager::SetPanGestureProcessor( PanGesture* panGestureProcessor )
646 DALI_ASSERT_DEBUG( NULL != panGestureProcessor );
648 mImpl->panGestureProcessor = panGestureProcessor;
651 void UpdateManager::AddTextureSet( OwnerPointer< TextureSet >& textureSet )
653 mImpl->textureSets.PushBack( textureSet.Release() );
656 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
658 mImpl->textureSets.EraseObject( textureSet );
661 uint32_t* UpdateManager::ReserveMessageSlot( uint32_t size, bool updateScene )
663 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
666 void UpdateManager::EventProcessingStarted()
668 mImpl->messageQueue.EventProcessingStarted();
671 bool UpdateManager::FlushQueue()
673 return mImpl->messageQueue.FlushQueue();
676 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
678 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
679 mImpl->animationFinishedDuringUpdate = false;
681 // Reset all animating / constrained properties
682 std::vector<PropertyResetterBase*>toDelete;
683 for( auto&& element : mImpl->propertyResetters )
685 element->ResetToBaseValue( bufferIndex );
686 if( element->IsFinished() )
688 toDelete.push_back( element );
692 // If a resetter is no longer required (the animator or constraint has been removed), delete it.
693 for( auto&& elementPtr : toDelete )
695 mImpl->propertyResetters.EraseObject( elementPtr );
698 // Clear all root nodes dirty flags
699 for( auto& scene : mImpl->scenes )
701 auto root = scene->root;
702 root->ResetDirtyFlags( bufferIndex );
705 // Clear node dirty flags
706 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
707 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
708 for( ;iter != endIter; ++iter )
710 (*iter)->ResetDirtyFlags( bufferIndex );
714 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds )
716 bool gestureUpdated( false );
718 if( mImpl->panGestureProcessor )
720 // gesture processor only supports default properties
721 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
722 gestureUpdated |= mImpl->panGestureProcessor->UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
725 return gestureUpdated;
728 bool UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
730 bool animationActive = false;
732 auto&& iter = mImpl->animations.Begin();
733 bool animationLooped = false;
735 while ( iter != mImpl->animations.End() )
737 Animation* animation = *iter;
738 bool finished = false;
740 bool progressMarkerReached = false;
741 animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
743 animationActive = animationActive || animation->IsActive();
745 if ( progressMarkerReached )
747 mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
750 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
751 animationLooped = animationLooped || looped;
753 // Remove animations that had been destroyed but were still waiting for an update
754 if (animation->GetState() == Animation::Destroyed)
756 iter = mImpl->animations.Erase(iter);
764 // queue the notification on finished or looped (to update loop count)
765 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
767 // The application should be notified by NotificationManager, in another thread
768 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
771 return animationActive;
774 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
776 //Constrain custom objects (in construction order)
777 for ( auto&& object : mImpl->customObjects )
779 ConstrainPropertyOwner( *object, bufferIndex );
783 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
785 // Constrain render-tasks
786 for ( auto&& scene : mImpl->scenes )
788 if ( scene && scene->taskList )
790 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
791 for ( auto&& task : tasks )
793 ConstrainPropertyOwner( *task, bufferIndex );
799 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
801 // constrain shaders... (in construction order)
802 for ( auto&& shader : mImpl->shaders )
804 ConstrainPropertyOwner( *shader, bufferIndex );
808 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
810 for( auto&& notification : mImpl->propertyNotifications )
812 bool valid = notification->Check( bufferIndex );
815 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
820 void UpdateManager::ForwardCompiledShadersToEventThread()
822 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
823 if( mImpl->shaderSaver )
825 // lock and swap the queues
827 // render might be attempting to send us more binaries at the same time
828 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
829 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
832 if( mImpl->updateCompiledShaders.size() > 0 )
834 ShaderSaver& factory = *mImpl->shaderSaver;
835 for( auto&& shader : mImpl->updateCompiledShaders )
837 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, shader ) );
839 // we don't need them in update anymore
840 mImpl->updateCompiledShaders.clear();
845 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
847 for( auto&& renderer : mImpl->renderers )
850 ConstrainPropertyOwner( *renderer, bufferIndex );
852 mImpl->renderingRequired = renderer->PrepareRender( bufferIndex ) || mImpl->renderingRequired;
856 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
858 mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
860 for ( auto&& scene : mImpl->scenes )
862 if ( scene && scene->root )
864 // Prepare resources, update shaders, for each node
865 // And add the renderers to the sorted layers. Start from root, which is also a layer
866 mImpl->nodeDirtyFlags |= UpdateNodeTree( *scene->root,
868 mImpl->renderQueue );
873 uint32_t UpdateManager::Update( float elapsedSeconds,
874 uint32_t lastVSyncTimeMilliseconds,
875 uint32_t nextVSyncTimeMilliseconds,
876 bool renderToFboEnabled,
877 bool isRenderingToFbo )
879 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
881 //Clear nodes/resources which were previously discarded
882 mImpl->discardQueue.Clear( bufferIndex );
884 bool isAnimationRunning = IsAnimationRunning();
886 //Process Touches & Gestures
887 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
889 bool updateScene = // The scene-graph requires an update if..
890 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
891 isAnimationRunning || // ..at least one animation is running OR
892 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
893 mImpl->frameCallbackProcessor || // ..a frame callback processor is existed OR
894 gestureUpdated; // ..a gesture property was updated
896 bool keepRendererRendering = false;
897 mImpl->renderingRequired = false;
899 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
900 // values if the scene was updated in the previous frame.
901 if( updateScene || mImpl->previousUpdateScene )
903 //Reset properties from the previous update
904 ResetProperties( bufferIndex );
905 mImpl->transformManager.ResetToBaseValue();
908 // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
909 // between calling IsSceneUpdateRequired() above and here, so updateScene should
911 updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
913 //Forward compiled shader programs to event thread for saving
914 ForwardCompiledShadersToEventThread();
916 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
917 // renderer lists if the scene was updated in the previous frame.
918 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
919 if( updateScene || mImpl->previousUpdateScene )
922 bool animationActive = Animate( bufferIndex, elapsedSeconds );
924 //Constraint custom objects
925 ConstrainCustomObjects( bufferIndex );
927 //Clear the lists of renderers from the previous update
928 for( auto&& scene : mImpl->scenes )
932 for( auto&& layer : scene->sortedLayerList )
936 layer->ClearRenderables();
942 // Call the frame-callback-processor if set
943 if( mImpl->frameCallbackProcessor )
945 mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
948 //Update node hierarchy, apply constraints and perform sorting / culling.
949 //This will populate each Layer with a list of renderers which are ready.
950 UpdateNodes( bufferIndex );
952 //Apply constraints to RenderTasks, shaders
953 ConstrainRenderTasks( bufferIndex );
954 ConstrainShaders( bufferIndex );
956 //Update renderers and apply constraints
957 UpdateRenderers( bufferIndex );
959 //Update the transformations of all the nodes
960 if ( mImpl->transformManager.Update() )
962 mImpl->nodeDirtyFlags |= NodePropertyFlags::TRANSFORM;
965 //Process Property Notifications
966 ProcessPropertyNotifications( bufferIndex );
969 for( auto&& cameraIterator : mImpl->cameras )
971 cameraIterator->Update( bufferIndex );
974 //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
975 //reset the update buffer index and make sure there is enough room in the instruction container
976 if( mImpl->renderersAdded )
978 // Calculate how many render tasks we have in total
979 std::size_t numberOfRenderTasks = 0;
980 for (auto&& scene : mImpl->scenes )
982 if ( scene && scene->taskList )
984 numberOfRenderTasks += scene->taskList->GetTasks().Count();
988 std::size_t numberOfRenderInstructions = 0;
989 for ( auto&& scene : mImpl->scenes )
991 if ( scene && scene->root && scene->taskList && scene->scene )
993 scene->scene->GetRenderInstructions().ResetAndReserve( bufferIndex,
994 static_cast<uint32_t>( scene->taskList->GetTasks().Count() ) );
996 // If there are animations running, only add render instruction if at least one animation is currently active (i.e. not delayed)
997 // or the nodes are dirty
998 if ( !isAnimationRunning || animationActive || mImpl->renderingRequired || (mImpl->nodeDirtyFlags & RenderableUpdateFlags) )
1000 keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
1003 scene->sortedLayerList,
1004 scene->scene->GetRenderInstructions(),
1008 scene->scene->SetSkipRendering( false );
1012 scene->scene->SetSkipRendering( true );
1015 numberOfRenderInstructions += scene->scene->GetRenderInstructions().Count( bufferIndex );
1019 DALI_LOG_INFO( gLogFilter, Debug::General,
1020 "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n",
1021 numberOfRenderTasks, numberOfRenderInstructions );
1025 for ( auto&& scene : mImpl->scenes )
1027 if ( scene && scene->root && scene->taskList )
1029 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
1031 // check the countdown and notify
1032 bool doRenderOnceNotify = false;
1033 mImpl->renderTaskWaiting = false;
1034 for ( auto&& renderTask : tasks )
1036 renderTask->UpdateState();
1038 if( renderTask->IsWaitingToRender() &&
1039 renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1041 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1044 if( renderTask->HasRendered() )
1046 doRenderOnceNotify = true;
1050 if( doRenderOnceNotify )
1052 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1053 mImpl->notificationManager.QueueCompleteNotification( scene->taskList->GetCompleteNotificationInterface() );
1058 // Macro is undefined in release build.
1059 SNAPSHOT_NODE_LOGGING;
1061 // A ResetProperties() may be required in the next frame
1062 mImpl->previousUpdateScene = updateScene;
1064 // Check whether further updates are required
1065 uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1067 if( keepRendererRendering )
1069 keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
1071 // Set dirty flags for next frame to continue rendering
1072 mImpl->nodeDirtyFlags |= RenderableUpdateFlags;
1075 // tell the update manager that we're done so the queue can be given to event thread
1076 mImpl->notificationManager.UpdateCompleted();
1078 // The update has finished; swap the double-buffering indices
1079 mSceneGraphBuffers.Swap();
1081 return keepUpdating;
1084 uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1086 // Update the duration set via Stage::KeepRendering()
1087 if ( mImpl->keepRenderingSeconds > 0.0f )
1089 mImpl->keepRenderingSeconds -= elapsedSeconds;
1092 uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1094 // If the rendering behavior is set to continuously render, then continue to render.
1095 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1096 // Keep updating until no messages are received and no animations are running.
1097 // If an animation has just finished, update at least once more for Discard end-actions.
1098 // No need to check for renderQueue as there is always a render after update and if that
1099 // render needs another update it will tell the adaptor to call update again
1101 if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
1102 ( mImpl->keepRenderingSeconds > 0.0f ) )
1104 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1107 if ( IsAnimationRunning() ||
1108 mImpl->animationFinishedDuringUpdate )
1110 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1113 if ( mImpl->renderTaskWaiting )
1115 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1118 return keepUpdatingRequest;
1121 void UpdateManager::SurfaceReplaced( Scene* scene )
1123 using DerivedType = MessageValue1<RenderManager, Scene*>;
1125 // Reserve some memory inside the render queue
1126 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1128 // Construct message in the render queue memory; note that delete should not be called on the return value
1129 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SurfaceReplaced, scene );
1132 void UpdateManager::KeepRendering( float durationSeconds )
1134 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1137 void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
1139 mImpl->renderingBehavior = renderingBehavior;
1142 void UpdateManager::RequestRendering()
1144 mImpl->renderingRequired = true;
1147 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
1149 for ( auto&& scene : mImpl->scenes )
1151 if ( scene && scene->root == rootLayer )
1153 scene->sortedLayerList = layers;
1159 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1161 // note,this vector is already in depth order. It could be used as-is to
1162 // remove sorting in update algorithm. However, it lacks layer boundary markers.
1163 for( auto&& iter : nodeDepths->nodeDepths )
1165 iter.node->SetDepthIndex( iter.sortedDepth );
1168 for ( auto&& scene : mImpl->scenes )
1172 // Go through node hierarchy and rearrange siblings according to depth-index
1173 SortSiblingNodesRecursively( *scene->root );
1178 void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode )
1180 mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode );
1183 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1185 mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback );
1188 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1190 // Message has ownership of Sampler while in transit from update to render
1191 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Sampler> >;
1193 // Reserve some memory inside the render queue
1194 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1196 // Construct message in the render queue memory; note that delete should not be called on the return value
1197 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1200 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1202 using DerivedType = MessageValue1<RenderManager, Render::Sampler*>;
1204 // Reserve some memory inside the render queue
1205 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1207 // Construct message in the render queue memory; note that delete should not be called on the return value
1208 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1211 void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
1213 using DerivedType = MessageValue3<RenderManager, Render::Sampler*, uint32_t, uint32_t>;
1215 // Reserve some memory inside the render queue
1216 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1218 // Construct message in the render queue memory; note that delete should not be called on the return value
1219 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1222 void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
1224 using DerivedType = MessageValue4<RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t>;
1226 // Reserve some memory inside the render queue
1227 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1229 // Construct message in the render queue memory; note that delete should not be called on the return value
1230 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1233 void UpdateManager::AddVertexBuffer( OwnerPointer< Render::VertexBuffer >& vertexBuffer )
1235 // Message has ownership of format while in transit from update -> render
1236 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::VertexBuffer> >;
1238 // Reserve some memory inside the render queue
1239 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1241 // Construct message in the render queue memory; note that delete should not be called on the return value
1242 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, vertexBuffer );
1245 void UpdateManager::RemoveVertexBuffer( Render::VertexBuffer* vertexBuffer )
1247 using DerivedType = MessageValue1<RenderManager, Render::VertexBuffer*>;
1249 // Reserve some memory inside the render queue
1250 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1252 // Construct message in the render queue memory; note that delete should not be called on the return value
1253 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, vertexBuffer );
1256 void UpdateManager::SetVertexBufferFormat( Render::VertexBuffer* vertexBuffer, OwnerPointer< Render::VertexBuffer::Format>& format )
1258 // Message has ownership of format while in transit from update -> render
1259 using DerivedType = MessageValue2<RenderManager, Render::VertexBuffer*, OwnerPointer<Render::VertexBuffer::Format> >;
1261 // Reserve some memory inside the render queue
1262 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1264 // Construct message in the render queue memory; note that delete should not be called on the return value
1265 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetVertexBufferFormat, vertexBuffer, format );
1268 void UpdateManager::SetVertexBufferData( Render::VertexBuffer* vertexBuffer, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
1270 // Message has ownership of format while in transit from update -> render
1271 using DerivedType = MessageValue3<RenderManager, Render::VertexBuffer*, OwnerPointer<Dali::Vector<uint8_t> >, uint32_t>;
1273 // Reserve some memory inside the render queue
1274 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1276 // Construct message in the render queue memory; note that delete should not be called on the return value
1277 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetVertexBufferData, vertexBuffer, data, size );
1280 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1282 // Message has ownership of format while in transit from update -> render
1283 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Geometry> >;
1285 // Reserve some memory inside the render queue
1286 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1288 // Construct message in the render queue memory; note that delete should not be called on the return value
1289 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1292 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1294 using DerivedType = MessageValue1<RenderManager, Render::Geometry*>;
1296 // Reserve some memory inside the render queue
1297 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1299 // Construct message in the render queue memory; note that delete should not be called on the return value
1300 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1303 void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
1305 using DerivedType = MessageValue2<RenderManager, Render::Geometry*, uint32_t>;
1307 // Reserve some memory inside the render queue
1308 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1310 // Construct message in the render queue memory; note that delete should not be called on the return value
1311 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1314 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
1316 using DerivedType = IndexBufferMessage<RenderManager>;
1318 // Reserve some memory inside the render queue
1319 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1321 // Construct message in the render queue memory; note that delete should not be called on the return value
1322 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1325 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
1327 using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1329 // Reserve some memory inside the render queue
1330 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1332 // Construct message in the render queue memory; note that delete should not be called on the return value
1333 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, vertexBuffer );
1336 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
1338 using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1340 // Reserve some memory inside the render queue
1341 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1343 // Construct message in the render queue memory; note that delete should not be called on the return value
1344 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, vertexBuffer );
1347 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1349 // Message has ownership of Texture while in transit from update -> render
1350 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Texture> >;
1352 // Reserve some memory inside the render queue
1353 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1355 // Construct message in the render queue memory; note that delete should not be called on the return value
1356 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1359 void UpdateManager::RemoveTexture( Render::Texture* texture)
1361 using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
1363 // Reserve some memory inside the render queue
1364 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1366 // Construct message in the render queue memory; note that delete should not be called on the return value
1367 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1370 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1372 using DerivedType = MessageValue3<RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams>;
1374 // Reserve some memory inside the message queue
1375 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1377 // Construct message in the message queue memory; note that delete should not be called on the return value
1378 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1381 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1383 using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
1385 // Reserve some memory inside the render queue
1386 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1388 // Construct message in the render queue memory; note that delete should not be called on the return value
1389 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1392 void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
1394 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::FrameBuffer> >;
1396 // Reserve some memory inside the render queue
1397 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1399 // Construct message in the render queue memory; note that delete should not be called on the return value
1400 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1403 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1405 using DerivedType = MessageValue1<RenderManager, Render::FrameBuffer*>;
1407 // Reserve some memory inside the render queue
1408 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1410 // Construct message in the render queue memory; note that delete should not be called on the return value
1411 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1414 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
1416 using DerivedType = MessageValue4<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t>;
1418 // Reserve some memory inside the render queue
1419 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1421 // Construct message in the render queue memory; note that delete should not be called on the return value
1422 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1425 void UpdateManager::AttachDepthTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1427 using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1429 // Reserve some memory inside the render queue
1430 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1432 // Construct message in the render queue memory; note that delete should not be called on the return value
1433 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachDepthTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1436 void UpdateManager::AttachDepthStencilTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1438 using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1440 // Reserve some memory inside the render queue
1441 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1443 // Construct message in the render queue memory; note that delete should not be called on the return value
1444 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachDepthStencilTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1447 } // namespace SceneGraph
1449 } // namespace Internal