2 * Copyright (c) 2019 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)
178 Impl( NotificationManager& notificationManager,
179 CompleteNotificationInterface& animationPlaylist,
180 PropertyNotifier& propertyNotifier,
181 DiscardQueue& discardQueue,
182 RenderController& renderController,
183 RenderManager& renderManager,
184 RenderQueue& renderQueue,
185 SceneGraphBuffers& sceneGraphBuffers,
186 RenderTaskProcessor& renderTaskProcessor )
187 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
188 notificationManager( notificationManager ),
190 animationPlaylist( animationPlaylist ),
191 propertyNotifier( propertyNotifier ),
193 discardQueue( discardQueue ),
194 renderController( renderController ),
195 sceneController( NULL ),
196 renderManager( renderManager ),
197 renderQueue( renderQueue ),
198 renderInstructions( renderManager.GetRenderInstructionContainer() ),
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 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
287 RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
289 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
291 using SceneInfoPtr = std::unique_ptr< SceneInfo >;
292 std::vector< SceneInfoPtr > scenes; ///< A container of SceneInfo.
294 Vector<Node*> nodes; ///< A container of all instantiated nodes
296 OwnerContainer< Camera* > cameras; ///< A container of cameras
297 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
299 OwnerContainer< PropertyResetterBase* > propertyResetters; ///< A container of property resetters
300 OwnerContainer< Animation* > animations; ///< A container of owned animations
301 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
302 OwnerContainer< Renderer* > renderers; ///< A container of owned renderers
303 OwnerContainer< TextureSet* > textureSets; ///< A container of owned texture sets
304 OwnerContainer< Shader* > shaders; ///< A container of owned shaders
305 OwnerPointer< PanGesture > panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager
307 MessageQueue messageQueue; ///< The messages queued from the event-thread
308 std::vector<Internal::ShaderDataPtr> renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
309 std::vector<Internal::ShaderDataPtr> updateCompiledShaders; ///< Shaders to be sent from Update to Event
310 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
312 OwnerPointer<FrameCallbackProcessor> frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required.
314 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
315 NodePropertyFlags nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
316 uint32_t frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
318 DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior
320 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
321 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
322 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
323 bool renderersAdded; ///< Flag to keep track when renderers have been added to avoid unnecessary processing
324 bool surfaceRectChanged; ///< True if the default surface rect is changed
328 Impl( const Impl& ); ///< Undefined
329 Impl& operator=( const Impl& ); ///< Undefined
332 UpdateManager::UpdateManager( NotificationManager& notificationManager,
333 CompleteNotificationInterface& animationFinishedNotifier,
334 PropertyNotifier& propertyNotifier,
335 DiscardQueue& discardQueue,
336 RenderController& controller,
337 RenderManager& renderManager,
338 RenderQueue& renderQueue,
339 RenderTaskProcessor& renderTaskProcessor )
342 mImpl = new Impl( notificationManager,
343 animationFinishedNotifier,
350 renderTaskProcessor );
354 UpdateManager::~UpdateManager()
359 void UpdateManager::InstallRoot( OwnerPointer<Layer>& layer )
361 DALI_ASSERT_DEBUG( layer->IsLayer() );
362 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
364 Layer* rootLayer = layer.Release();
366 DALI_ASSERT_DEBUG( std::find_if( mImpl->scenes.begin(), mImpl->scenes.end(),
367 [rootLayer]( Impl::SceneInfoPtr& scene )
369 return scene && scene->root == rootLayer;
371 ) == mImpl->scenes.end() && "Root Node already installed" );
373 rootLayer->CreateTransform( &mImpl->transformManager );
374 rootLayer->SetRoot(true);
376 mImpl->scenes.emplace_back( new Impl::SceneInfo( rootLayer ) );
379 void UpdateManager::UninstallRoot( Layer* layer )
381 DALI_ASSERT_DEBUG( layer->IsLayer() );
382 DALI_ASSERT_DEBUG( layer->GetParent() == NULL );
384 for (auto iter = mImpl->scenes.begin(); iter != mImpl->scenes.end(); ++iter)
386 if( (*iter) && (*iter)->root == layer )
388 mImpl->scenes.erase( iter );
393 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), layer );
395 // Notify the layer about impending destruction
399 void UpdateManager::AddNode( OwnerPointer<Node>& node )
401 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
403 // Nodes must be sorted by pointer
404 Node* rawNode = node.Release();
405 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddNode\n", rawNode );
407 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
408 for( Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter )
410 if( rawNode > (*iter) )
412 mImpl->nodes.Insert((iter+1), rawNode );
413 rawNode->CreateTransform( &mImpl->transformManager );
419 void UpdateManager::ConnectNode( Node* parent, Node* node )
421 DALI_ASSERT_ALWAYS( NULL != parent );
422 DALI_ASSERT_ALWAYS( NULL != node );
423 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
425 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] ConnectNode\n", node );
427 parent->ConnectChild( node );
429 parent->SetPropertyDirty( true );
431 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
432 if( mImpl->frameCallbackProcessor )
434 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
438 void UpdateManager::DisconnectNode( Node* node )
440 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DisconnectNode\n", node );
442 Node* parent = node->GetParent();
443 DALI_ASSERT_ALWAYS( NULL != parent );
444 parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused
446 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
448 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
449 if( mImpl->frameCallbackProcessor )
451 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
455 void UpdateManager::DestroyNode( Node* node )
457 DALI_ASSERT_ALWAYS( NULL != node );
458 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
460 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DestroyNode\n", node );
462 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
463 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
464 for(;iter!=endIter;++iter)
468 mImpl->nodes.Erase(iter);
473 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
475 // Notify the Node about impending destruction
479 void UpdateManager::AddCamera( OwnerPointer< Camera >& camera )
481 mImpl->cameras.PushBack( camera.Release() ); // takes ownership
484 void UpdateManager::RemoveCamera( Camera* camera )
486 // Find the camera and destroy it
487 EraseUsingDiscardQueue( mImpl->cameras, camera, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
490 void UpdateManager::AddObject( OwnerPointer<PropertyOwner>& object )
492 mImpl->customObjects.PushBack( object.Release() );
495 void UpdateManager::RemoveObject( PropertyOwner* object )
497 mImpl->customObjects.EraseObject( object );
500 void UpdateManager::AddRenderTaskList( OwnerPointer<RenderTaskList>& taskList )
502 RenderTaskList* taskListPointer = taskList.Release();
503 taskListPointer->SetRenderMessageDispatcher( &mImpl->renderMessageDispatcher );
505 mImpl->scenes.back()->taskList = taskListPointer;
508 void UpdateManager::RemoveRenderTaskList( RenderTaskList* taskList )
510 for ( auto&& scene : mImpl->scenes )
512 if ( scene && scene->taskList == taskList )
514 scene->taskList.Reset();
520 void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation )
522 mImpl->animations.PushBack( animation.Release() );
525 void UpdateManager::StopAnimation( Animation* animation )
527 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
529 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
531 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
534 void UpdateManager::RemoveAnimation( Animation* animation )
536 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
538 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
540 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
543 bool UpdateManager::IsAnimationRunning() const
545 // Find any animation that isn't stopped or paused
546 for ( auto&& iter : mImpl->animations )
548 const Animation::State state = iter->GetState();
550 if (state != Animation::Stopped &&
551 state != Animation::Paused)
553 return true; // stop iteration as soon as first one is found
560 void UpdateManager::AddPropertyResetter( OwnerPointer<PropertyResetterBase>& propertyResetter )
562 propertyResetter->Initialize();
563 mImpl->propertyResetters.PushBack( propertyResetter.Release() );
566 void UpdateManager::AddPropertyNotification( OwnerPointer< PropertyNotification >& propertyNotification )
568 mImpl->propertyNotifications.PushBack( propertyNotification.Release() );
571 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
573 mImpl->propertyNotifications.EraseObject( propertyNotification );
576 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
578 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
579 propertyNotification->SetNotifyMode( notifyMode );
582 void UpdateManager::AddShader( OwnerPointer< Shader >& shader )
584 mImpl->shaders.PushBack( shader.Release() );
587 void UpdateManager::RemoveShader( Shader* shader )
589 // Find the shader and destroy it
590 EraseUsingDiscardQueue( mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
593 void UpdateManager::SetShaderProgram( Shader* shader,
594 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
599 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
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 renderer->SetDirty( true );
640 // Find the renderer and destroy it
641 EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
642 // Need to remove the render object as well
643 renderer->DisconnectFromSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
646 void UpdateManager::SetPanGestureProcessor( PanGesture* panGestureProcessor )
648 DALI_ASSERT_DEBUG( NULL != panGestureProcessor );
650 mImpl->panGestureProcessor = panGestureProcessor;
653 void UpdateManager::AddTextureSet( OwnerPointer< TextureSet >& textureSet )
655 mImpl->textureSets.PushBack( textureSet.Release() );
658 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
660 mImpl->textureSets.EraseObject( textureSet );
663 uint32_t* UpdateManager::ReserveMessageSlot( uint32_t size, bool updateScene )
665 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
668 void UpdateManager::EventProcessingStarted()
670 mImpl->messageQueue.EventProcessingStarted();
673 bool UpdateManager::FlushQueue()
675 return mImpl->messageQueue.FlushQueue();
678 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
680 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
681 mImpl->animationFinishedDuringUpdate = false;
683 // Reset all animating / constrained properties
684 std::vector<PropertyResetterBase*>toDelete;
685 for( auto&& element : mImpl->propertyResetters )
687 element->ResetToBaseValue( bufferIndex );
688 if( element->IsFinished() )
690 toDelete.push_back( element );
694 // If a resetter is no longer required (the animator or constraint has been removed), delete it.
695 for( auto&& elementPtr : toDelete )
697 mImpl->propertyResetters.EraseObject( elementPtr );
700 // Clear node dirty flags
701 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
702 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
703 for( ;iter != endIter; ++iter )
705 (*iter)->ResetDirtyFlags( bufferIndex );
709 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds )
711 bool gestureUpdated( false );
713 if( mImpl->panGestureProcessor )
715 // gesture processor only supports default properties
716 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
717 gestureUpdated |= mImpl->panGestureProcessor->UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
720 return gestureUpdated;
723 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
725 auto&& iter = mImpl->animations.Begin();
726 bool animationLooped = false;
728 while ( iter != mImpl->animations.End() )
730 Animation* animation = *iter;
731 bool finished = false;
733 bool progressMarkerReached = false;
734 animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
736 if ( progressMarkerReached )
738 mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
741 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
742 animationLooped = animationLooped || looped;
744 // Remove animations that had been destroyed but were still waiting for an update
745 if (animation->GetState() == Animation::Destroyed)
747 iter = mImpl->animations.Erase(iter);
755 // queue the notification on finished or looped (to update loop count)
756 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
758 // The application should be notified by NotificationManager, in another thread
759 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
763 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
765 //Constrain custom objects (in construction order)
766 for ( auto&& object : mImpl->customObjects )
768 ConstrainPropertyOwner( *object, bufferIndex );
772 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
774 // Constrain render-tasks
775 for ( auto&& scene : mImpl->scenes )
777 if ( scene && scene->taskList )
779 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
780 for ( auto&& task : tasks )
782 ConstrainPropertyOwner( *task, bufferIndex );
788 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
790 // constrain shaders... (in construction order)
791 for ( auto&& shader : mImpl->shaders )
793 ConstrainPropertyOwner( *shader, bufferIndex );
797 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
799 for( auto&& notification : mImpl->propertyNotifications )
801 bool valid = notification->Check( bufferIndex );
804 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
809 void UpdateManager::ForwardCompiledShadersToEventThread()
811 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
812 if( mImpl->shaderSaver )
814 // lock and swap the queues
816 // render might be attempting to send us more binaries at the same time
817 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
818 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
821 if( mImpl->updateCompiledShaders.size() > 0 )
823 ShaderSaver& factory = *mImpl->shaderSaver;
824 for( auto&& shader : mImpl->updateCompiledShaders )
826 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, shader ) );
828 // we don't need them in update anymore
829 mImpl->updateCompiledShaders.clear();
834 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
836 for( auto&& renderer : mImpl->renderers )
839 ConstrainPropertyOwner( *renderer, bufferIndex );
841 renderer->PrepareRender( bufferIndex );
845 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
847 mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
849 for ( auto&& scene : mImpl->scenes )
851 if ( scene && scene->root )
853 // Prepare resources, update shaders, for each node
854 // And add the renderers to the sorted layers. Start from root, which is also a layer
855 mImpl->nodeDirtyFlags |= UpdateNodeTree( *scene->root,
857 mImpl->renderQueue );
862 uint32_t UpdateManager::Update( float elapsedSeconds,
863 uint32_t lastVSyncTimeMilliseconds,
864 uint32_t nextVSyncTimeMilliseconds,
865 bool renderToFboEnabled,
866 bool isRenderingToFbo )
868 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
870 //Clear nodes/resources which were previously discarded
871 mImpl->discardQueue.Clear( bufferIndex );
873 //Process Touches & Gestures
874 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
876 bool updateScene = // The scene-graph requires an update if..
877 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
878 IsAnimationRunning() || // ..at least one animation is running OR
879 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
880 gestureUpdated; // ..a gesture property was updated
882 bool keepRendererRendering = false;
884 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
885 // values if the scene was updated in the previous frame.
886 if( updateScene || mImpl->previousUpdateScene )
888 //Reset properties from the previous update
889 ResetProperties( bufferIndex );
890 mImpl->transformManager.ResetToBaseValue();
893 // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
894 // between calling IsSceneUpdateRequired() above and here, so updateScene should
896 updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
898 //Forward compiled shader programs to event thread for saving
899 ForwardCompiledShadersToEventThread();
901 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
902 // renderer lists if the scene was updated in the previous frame.
903 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
904 if( updateScene || mImpl->previousUpdateScene )
907 Animate( bufferIndex, elapsedSeconds );
909 //Constraint custom objects
910 ConstrainCustomObjects( bufferIndex );
912 //Clear the lists of renderers from the previous update
913 for( auto&& scene : mImpl->scenes )
917 for( auto&& layer : scene->sortedLayerList )
921 layer->ClearRenderables();
927 // Call the frame-callback-processor if set
928 if( mImpl->frameCallbackProcessor )
930 mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
933 //Update node hierarchy, apply constraints and perform sorting / culling.
934 //This will populate each Layer with a list of renderers which are ready.
935 UpdateNodes( bufferIndex );
937 //Apply constraints to RenderTasks, shaders
938 ConstrainRenderTasks( bufferIndex );
939 ConstrainShaders( bufferIndex );
941 //Update renderers and apply constraints
942 UpdateRenderers( bufferIndex );
944 //Update the transformations of all the nodes
945 mImpl->transformManager.Update();
947 //Process Property Notifications
948 ProcessPropertyNotifications( bufferIndex );
951 for( auto&& cameraIterator : mImpl->cameras )
953 cameraIterator->Update( bufferIndex );
956 //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
957 //reset the update buffer index and make sure there is enough room in the instruction container
958 if( mImpl->renderersAdded )
960 // Calculate how many render tasks we have in total
961 std::size_t numberOfRenderTasks = 0;
962 for (auto&& scene : mImpl->scenes )
964 if ( scene && scene->taskList )
966 numberOfRenderTasks += scene->taskList->GetTasks().Count();
970 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
971 static_cast<uint32_t>( numberOfRenderTasks ) );
973 for ( auto&& scene : mImpl->scenes )
975 if ( scene && scene->root && scene->taskList )
977 keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
980 scene->sortedLayerList,
981 mImpl->renderInstructions,
987 DALI_LOG_INFO( gLogFilter, Debug::General,
988 "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n",
989 numberOfRenderTasks, mImpl->renderInstructions.Count( bufferIndex ) );
993 for ( auto&& scene : mImpl->scenes )
995 if ( scene && scene->root && scene->taskList )
997 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
999 // check the countdown and notify
1000 bool doRenderOnceNotify = false;
1001 mImpl->renderTaskWaiting = false;
1002 for ( auto&& renderTask : tasks )
1004 renderTask->UpdateState();
1006 if( renderTask->IsWaitingToRender() &&
1007 renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1009 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1012 if( renderTask->HasRendered() )
1014 doRenderOnceNotify = true;
1018 if( doRenderOnceNotify )
1020 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1021 mImpl->notificationManager.QueueCompleteNotification( scene->taskList->GetCompleteNotificationInterface() );
1026 // Macro is undefined in release build.
1027 SNAPSHOT_NODE_LOGGING;
1029 // A ResetProperties() may be required in the next frame
1030 mImpl->previousUpdateScene = updateScene;
1032 // Check whether further updates are required
1033 uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1035 if( keepRendererRendering )
1037 keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
1040 // tell the update manager that we're done so the queue can be given to event thread
1041 mImpl->notificationManager.UpdateCompleted();
1043 // The update has finished; swap the double-buffering indices
1044 mSceneGraphBuffers.Swap();
1046 return keepUpdating;
1049 uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1051 // Update the duration set via Stage::KeepRendering()
1052 if ( mImpl->keepRenderingSeconds > 0.0f )
1054 mImpl->keepRenderingSeconds -= elapsedSeconds;
1057 uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1059 // If the rendering behavior is set to continuously render, then continue to render.
1060 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1061 // Keep updating until no messages are received and no animations are running.
1062 // If an animation has just finished, update at least once more for Discard end-actions.
1063 // No need to check for renderQueue as there is always a render after update and if that
1064 // render needs another update it will tell the adaptor to call update again
1066 if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
1067 ( mImpl->keepRenderingSeconds > 0.0f ) )
1069 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1072 if ( IsAnimationRunning() ||
1073 mImpl->animationFinishedDuringUpdate )
1075 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1078 if ( mImpl->renderTaskWaiting )
1080 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1083 return keepUpdatingRequest;
1086 void UpdateManager::SetBackgroundColor( const Vector4& color )
1088 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1090 // Reserve some memory inside the render queue
1091 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1093 // Construct message in the render queue memory; note that delete should not be called on the return value
1094 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1097 void UpdateManager::SetDefaultSurfaceRect( const Rect<int32_t>& rect )
1099 mImpl->surfaceRectChanged = true;
1101 typedef MessageValue1< RenderManager, Rect<int32_t> > DerivedType;
1103 // Reserve some memory inside the render queue
1104 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1106 // Construct message in the render queue memory; note that delete should not be called on the return value
1107 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1110 void UpdateManager::SetDefaultSurfaceOrientation( int orientation )
1112 typedef MessageValue1< RenderManager, int > DerivedType;
1114 // Reserve some memory inside the render queue
1115 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1117 // Construct message in the render queue memory; note that delete should not be called on the return value
1118 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceOrientation, orientation );
1121 void UpdateManager::KeepRendering( float durationSeconds )
1123 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1126 void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
1128 mImpl->renderingBehavior = renderingBehavior;
1131 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
1133 for ( auto&& scene : mImpl->scenes )
1135 if ( scene && scene->root == rootLayer )
1137 scene->sortedLayerList = layers;
1143 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1145 // note,this vector is already in depth order. It could be used as-is to
1146 // remove sorting in update algorithm. However, it lacks layer boundary markers.
1147 for( auto&& iter : nodeDepths->nodeDepths )
1149 iter.node->SetDepthIndex( iter.sortedDepth );
1152 for ( auto&& scene : mImpl->scenes )
1156 // Go through node hierarchy and rearrange siblings according to depth-index
1157 SortSiblingNodesRecursively( *scene->root );
1162 bool UpdateManager::IsDefaultSurfaceRectChanged()
1164 bool surfaceRectChanged = mImpl->surfaceRectChanged;
1167 mImpl->surfaceRectChanged = false;
1169 return surfaceRectChanged;
1172 void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode )
1174 mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode );
1177 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1179 mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback );
1182 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1184 // Message has ownership of Sampler while in transit from update to render
1185 typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > DerivedType;
1187 // Reserve some memory inside the render queue
1188 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1190 // Construct message in the render queue memory; note that delete should not be called on the return value
1191 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1194 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1196 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1198 // Reserve some memory inside the render queue
1199 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1201 // Construct message in the render queue memory; note that delete should not be called on the return value
1202 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1205 void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
1207 typedef MessageValue3< RenderManager, Render::Sampler*, uint32_t, uint32_t > DerivedType;
1209 // Reserve some memory inside the render queue
1210 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1212 // Construct message in the render queue memory; note that delete should not be called on the return value
1213 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1216 void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
1218 typedef MessageValue4< RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t > DerivedType;
1220 // Reserve some memory inside the render queue
1221 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1223 // Construct message in the render queue memory; note that delete should not be called on the return value
1224 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1227 void UpdateManager::AddPropertyBuffer( OwnerPointer< Render::PropertyBuffer >& propertyBuffer )
1229 // Message has ownership of format while in transit from update -> render
1230 typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
1232 // Reserve some memory inside the render queue
1233 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1235 // Construct message in the render queue memory; note that delete should not be called on the return value
1236 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1239 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1241 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1243 // Reserve some memory inside the render queue
1244 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1246 // Construct message in the render queue memory; note that delete should not be called on the return value
1247 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1250 void UpdateManager::SetPropertyBufferFormat( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Render::PropertyBuffer::Format>& format )
1252 // Message has ownership of format while in transit from update -> render
1253 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > 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::SetPropertyBufferFormat, propertyBuffer, format );
1262 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
1264 // Message has ownership of format while in transit from update -> render
1265 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<uint8_t> >, uint32_t > 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::SetPropertyBufferData, propertyBuffer, data, size );
1274 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1276 // Message has ownership of format while in transit from update -> render
1277 typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > DerivedType;
1279 // Reserve some memory inside the render queue
1280 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1282 // Construct message in the render queue memory; note that delete should not be called on the return value
1283 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1286 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1288 typedef MessageValue1< RenderManager, Render::Geometry* > 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::RemoveGeometry, geometry );
1297 void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
1299 typedef MessageValue2< RenderManager, Render::Geometry*, uint32_t > DerivedType;
1301 // Reserve some memory inside the render queue
1302 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1304 // Construct message in the render queue memory; note that delete should not be called on the return value
1305 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1308 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
1310 typedef IndexBufferMessage< RenderManager > DerivedType;
1312 // Reserve some memory inside the render queue
1313 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1315 // Construct message in the render queue memory; note that delete should not be called on the return value
1316 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1319 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1321 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1323 // Reserve some memory inside the render queue
1324 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1326 // Construct message in the render queue memory; note that delete should not be called on the return value
1327 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1330 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1332 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1334 // Reserve some memory inside the render queue
1335 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1337 // Construct message in the render queue memory; note that delete should not be called on the return value
1338 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, propertyBuffer );
1341 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1343 // Message has ownership of Texture while in transit from update -> render
1344 typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType;
1346 // Reserve some memory inside the render queue
1347 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1349 // Construct message in the render queue memory; note that delete should not be called on the return value
1350 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1353 void UpdateManager::RemoveTexture( Render::Texture* texture)
1355 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1357 // Reserve some memory inside the render queue
1358 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1360 // Construct message in the render queue memory; note that delete should not be called on the return value
1361 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1364 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1366 typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
1368 // Reserve some memory inside the message queue
1369 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1371 // Construct message in the message queue memory; note that delete should not be called on the return value
1372 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1375 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1377 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1379 // Reserve some memory inside the render queue
1380 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1382 // Construct message in the render queue memory; note that delete should not be called on the return value
1383 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1386 void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
1388 typedef MessageValue1< RenderManager, OwnerPointer< Render::FrameBuffer > > DerivedType;
1390 // Reserve some memory inside the render queue
1391 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1393 // Construct message in the render queue memory; note that delete should not be called on the return value
1394 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1397 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1399 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1401 // Reserve some memory inside the render queue
1402 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1404 // Construct message in the render queue memory; note that delete should not be called on the return value
1405 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1408 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
1410 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t > DerivedType;
1412 // Reserve some memory inside the render queue
1413 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1415 // Construct message in the render queue memory; note that delete should not be called on the return value
1416 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1419 } // namespace SceneGraph
1421 } // namespace Internal