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 // 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 node dirty flags
699 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
700 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
701 for( ;iter != endIter; ++iter )
703 (*iter)->ResetDirtyFlags( bufferIndex );
707 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds )
709 bool gestureUpdated( false );
711 if( mImpl->panGestureProcessor )
713 // gesture processor only supports default properties
714 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
715 gestureUpdated |= mImpl->panGestureProcessor->UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
718 return gestureUpdated;
721 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
723 auto&& iter = mImpl->animations.Begin();
724 bool animationLooped = false;
726 while ( iter != mImpl->animations.End() )
728 Animation* animation = *iter;
729 bool finished = false;
731 bool progressMarkerReached = false;
732 animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
734 if ( progressMarkerReached )
736 mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
739 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
740 animationLooped = animationLooped || looped;
742 // Remove animations that had been destroyed but were still waiting for an update
743 if (animation->GetState() == Animation::Destroyed)
745 iter = mImpl->animations.Erase(iter);
753 // queue the notification on finished or looped (to update loop count)
754 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
756 // The application should be notified by NotificationManager, in another thread
757 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
761 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
763 //Constrain custom objects (in construction order)
764 for ( auto&& object : mImpl->customObjects )
766 ConstrainPropertyOwner( *object, bufferIndex );
770 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
772 // Constrain render-tasks
773 for ( auto&& scene : mImpl->scenes )
775 if ( scene && scene->taskList )
777 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
778 for ( auto&& task : tasks )
780 ConstrainPropertyOwner( *task, bufferIndex );
786 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
788 // constrain shaders... (in construction order)
789 for ( auto&& shader : mImpl->shaders )
791 ConstrainPropertyOwner( *shader, bufferIndex );
795 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
797 for( auto&& notification : mImpl->propertyNotifications )
799 bool valid = notification->Check( bufferIndex );
802 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
807 void UpdateManager::ForwardCompiledShadersToEventThread()
809 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
810 if( mImpl->shaderSaver )
812 // lock and swap the queues
814 // render might be attempting to send us more binaries at the same time
815 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
816 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
819 if( mImpl->updateCompiledShaders.size() > 0 )
821 ShaderSaver& factory = *mImpl->shaderSaver;
822 for( auto&& shader : mImpl->updateCompiledShaders )
824 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, shader ) );
826 // we don't need them in update anymore
827 mImpl->updateCompiledShaders.clear();
832 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
834 for( auto&& renderer : mImpl->renderers )
837 ConstrainPropertyOwner( *renderer, bufferIndex );
839 renderer->PrepareRender( bufferIndex );
843 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
845 mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
847 for ( auto&& scene : mImpl->scenes )
849 if ( scene && scene->root )
851 // Prepare resources, update shaders, for each node
852 // And add the renderers to the sorted layers. Start from root, which is also a layer
853 mImpl->nodeDirtyFlags |= UpdateNodeTree( *scene->root,
855 mImpl->renderQueue );
860 uint32_t UpdateManager::Update( float elapsedSeconds,
861 uint32_t lastVSyncTimeMilliseconds,
862 uint32_t nextVSyncTimeMilliseconds,
863 bool renderToFboEnabled,
864 bool isRenderingToFbo )
866 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
868 //Clear nodes/resources which were previously discarded
869 mImpl->discardQueue.Clear( bufferIndex );
871 //Process Touches & Gestures
872 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
874 bool updateScene = // The scene-graph requires an update if..
875 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
876 IsAnimationRunning() || // ..at least one animation is running OR
877 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
878 gestureUpdated; // ..a gesture property was updated
880 bool keepRendererRendering = false;
882 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
883 // values if the scene was updated in the previous frame.
884 if( updateScene || mImpl->previousUpdateScene )
886 //Reset properties from the previous update
887 ResetProperties( bufferIndex );
888 mImpl->transformManager.ResetToBaseValue();
891 // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
892 // between calling IsSceneUpdateRequired() above and here, so updateScene should
894 updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
896 //Forward compiled shader programs to event thread for saving
897 ForwardCompiledShadersToEventThread();
899 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
900 // renderer lists if the scene was updated in the previous frame.
901 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
902 if( updateScene || mImpl->previousUpdateScene )
905 Animate( bufferIndex, elapsedSeconds );
907 //Constraint custom objects
908 ConstrainCustomObjects( bufferIndex );
910 //Clear the lists of renderers from the previous update
911 for( auto&& scene : mImpl->scenes )
915 for( auto&& layer : scene->sortedLayerList )
919 layer->ClearRenderables();
925 // Call the frame-callback-processor if set
926 if( mImpl->frameCallbackProcessor )
928 mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
931 //Update node hierarchy, apply constraints and perform sorting / culling.
932 //This will populate each Layer with a list of renderers which are ready.
933 UpdateNodes( bufferIndex );
935 //Apply constraints to RenderTasks, shaders
936 ConstrainRenderTasks( bufferIndex );
937 ConstrainShaders( bufferIndex );
939 //Update renderers and apply constraints
940 UpdateRenderers( bufferIndex );
942 //Update the transformations of all the nodes
943 mImpl->transformManager.Update();
945 //Process Property Notifications
946 ProcessPropertyNotifications( bufferIndex );
949 for( auto&& cameraIterator : mImpl->cameras )
951 cameraIterator->Update( bufferIndex );
954 //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
955 //reset the update buffer index and make sure there is enough room in the instruction container
956 if( mImpl->renderersAdded )
958 // Calculate how many render tasks we have in total
959 std::size_t numberOfRenderTasks = 0;
960 for (auto&& scene : mImpl->scenes )
962 if ( scene && scene->taskList )
964 numberOfRenderTasks += scene->taskList->GetTasks().Count();
968 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
969 static_cast<uint32_t>( numberOfRenderTasks ) );
971 for ( auto&& scene : mImpl->scenes )
973 if ( scene && scene->root && scene->taskList )
975 keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
978 scene->sortedLayerList,
979 mImpl->renderInstructions,
985 DALI_LOG_INFO( gLogFilter, Debug::General,
986 "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n",
987 numberOfRenderTasks, mImpl->renderInstructions.Count( bufferIndex ) );
991 for ( auto&& scene : mImpl->scenes )
993 if ( scene && scene->root && scene->taskList )
995 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
997 // check the countdown and notify
998 bool doRenderOnceNotify = false;
999 mImpl->renderTaskWaiting = false;
1000 for ( auto&& renderTask : tasks )
1002 renderTask->UpdateState();
1004 if( renderTask->IsWaitingToRender() &&
1005 renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1007 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1010 if( renderTask->HasRendered() )
1012 doRenderOnceNotify = true;
1016 if( doRenderOnceNotify )
1018 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1019 mImpl->notificationManager.QueueCompleteNotification( scene->taskList->GetCompleteNotificationInterface() );
1024 // Macro is undefined in release build.
1025 SNAPSHOT_NODE_LOGGING;
1027 // A ResetProperties() may be required in the next frame
1028 mImpl->previousUpdateScene = updateScene;
1030 // Check whether further updates are required
1031 uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1033 if( keepRendererRendering )
1035 keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
1038 // tell the update manager that we're done so the queue can be given to event thread
1039 mImpl->notificationManager.UpdateCompleted();
1041 // The update has finished; swap the double-buffering indices
1042 mSceneGraphBuffers.Swap();
1044 return keepUpdating;
1047 uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1049 // Update the duration set via Stage::KeepRendering()
1050 if ( mImpl->keepRenderingSeconds > 0.0f )
1052 mImpl->keepRenderingSeconds -= elapsedSeconds;
1055 uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1057 // If the rendering behavior is set to continuously render, then continue to render.
1058 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1059 // Keep updating until no messages are received and no animations are running.
1060 // If an animation has just finished, update at least once more for Discard end-actions.
1061 // No need to check for renderQueue as there is always a render after update and if that
1062 // render needs another update it will tell the adaptor to call update again
1064 if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
1065 ( mImpl->keepRenderingSeconds > 0.0f ) )
1067 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1070 if ( IsAnimationRunning() ||
1071 mImpl->animationFinishedDuringUpdate )
1073 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1076 if ( mImpl->renderTaskWaiting )
1078 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1081 return keepUpdatingRequest;
1084 void UpdateManager::SetBackgroundColor( const Vector4& color )
1086 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1088 // Reserve some memory inside the render queue
1089 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1091 // Construct message in the render queue memory; note that delete should not be called on the return value
1092 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1095 void UpdateManager::SetDefaultSurfaceRect( const Rect<int32_t>& rect )
1097 mImpl->surfaceRectChanged = true;
1099 typedef MessageValue1< RenderManager, Rect<int32_t> > DerivedType;
1101 // Reserve some memory inside the render queue
1102 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1104 // Construct message in the render queue memory; note that delete should not be called on the return value
1105 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1108 void UpdateManager::SetDefaultSurfaceOrientation( int orientation )
1110 typedef MessageValue1< RenderManager, int > DerivedType;
1112 // Reserve some memory inside the render queue
1113 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1115 // Construct message in the render queue memory; note that delete should not be called on the return value
1116 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceOrientation, orientation );
1119 void UpdateManager::KeepRendering( float durationSeconds )
1121 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1124 void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
1126 mImpl->renderingBehavior = renderingBehavior;
1129 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
1131 for ( auto&& scene : mImpl->scenes )
1133 if ( scene && scene->root == rootLayer )
1135 scene->sortedLayerList = layers;
1141 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1143 // note,this vector is already in depth order. It could be used as-is to
1144 // remove sorting in update algorithm. However, it lacks layer boundary markers.
1145 for( auto&& iter : nodeDepths->nodeDepths )
1147 iter.node->SetDepthIndex( iter.sortedDepth );
1150 for ( auto&& scene : mImpl->scenes )
1154 // Go through node hierarchy and rearrange siblings according to depth-index
1155 SortSiblingNodesRecursively( *scene->root );
1160 bool UpdateManager::IsDefaultSurfaceRectChanged()
1162 bool surfaceRectChanged = mImpl->surfaceRectChanged;
1165 mImpl->surfaceRectChanged = false;
1167 return surfaceRectChanged;
1170 void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode )
1172 mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode );
1175 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1177 mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback );
1180 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1182 // Message has ownership of Sampler while in transit from update to render
1183 typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > DerivedType;
1185 // Reserve some memory inside the render queue
1186 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1188 // Construct message in the render queue memory; note that delete should not be called on the return value
1189 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1192 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1194 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1196 // Reserve some memory inside the render queue
1197 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1199 // Construct message in the render queue memory; note that delete should not be called on the return value
1200 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1203 void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
1205 typedef MessageValue3< RenderManager, Render::Sampler*, uint32_t, uint32_t > DerivedType;
1207 // Reserve some memory inside the render queue
1208 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1210 // Construct message in the render queue memory; note that delete should not be called on the return value
1211 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1214 void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
1216 typedef MessageValue4< RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t > DerivedType;
1218 // Reserve some memory inside the render queue
1219 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1221 // Construct message in the render queue memory; note that delete should not be called on the return value
1222 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1225 void UpdateManager::AddPropertyBuffer( OwnerPointer< Render::PropertyBuffer >& propertyBuffer )
1227 // Message has ownership of format while in transit from update -> render
1228 typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
1230 // Reserve some memory inside the render queue
1231 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1233 // Construct message in the render queue memory; note that delete should not be called on the return value
1234 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1237 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1239 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1241 // Reserve some memory inside the render queue
1242 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1244 // Construct message in the render queue memory; note that delete should not be called on the return value
1245 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1248 void UpdateManager::SetPropertyBufferFormat( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Render::PropertyBuffer::Format>& format )
1250 // Message has ownership of format while in transit from update -> render
1251 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType;
1253 // Reserve some memory inside the render queue
1254 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1256 // Construct message in the render queue memory; note that delete should not be called on the return value
1257 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1260 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
1262 // Message has ownership of format while in transit from update -> render
1263 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<uint8_t> >, uint32_t > DerivedType;
1265 // Reserve some memory inside the render queue
1266 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1268 // Construct message in the render queue memory; note that delete should not be called on the return value
1269 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1272 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1274 // Message has ownership of format while in transit from update -> render
1275 typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > DerivedType;
1277 // Reserve some memory inside the render queue
1278 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1280 // Construct message in the render queue memory; note that delete should not be called on the return value
1281 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1284 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1286 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1288 // Reserve some memory inside the render queue
1289 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1291 // Construct message in the render queue memory; note that delete should not be called on the return value
1292 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1295 void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
1297 typedef MessageValue2< RenderManager, Render::Geometry*, uint32_t > DerivedType;
1299 // Reserve some memory inside the render queue
1300 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1302 // Construct message in the render queue memory; note that delete should not be called on the return value
1303 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1306 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
1308 typedef IndexBufferMessage< RenderManager > DerivedType;
1310 // Reserve some memory inside the render queue
1311 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1313 // Construct message in the render queue memory; note that delete should not be called on the return value
1314 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1317 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1319 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1321 // Reserve some memory inside the render queue
1322 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1324 // Construct message in the render queue memory; note that delete should not be called on the return value
1325 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1328 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1330 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1332 // Reserve some memory inside the render queue
1333 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1335 // Construct message in the render queue memory; note that delete should not be called on the return value
1336 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, propertyBuffer );
1339 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1341 // Message has ownership of Texture while in transit from update -> render
1342 typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType;
1344 // Reserve some memory inside the render queue
1345 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1347 // Construct message in the render queue memory; note that delete should not be called on the return value
1348 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1351 void UpdateManager::RemoveTexture( Render::Texture* texture)
1353 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1355 // Reserve some memory inside the render queue
1356 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1358 // Construct message in the render queue memory; note that delete should not be called on the return value
1359 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1362 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1364 typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
1366 // Reserve some memory inside the message queue
1367 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1369 // Construct message in the message queue memory; note that delete should not be called on the return value
1370 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1373 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1375 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1377 // Reserve some memory inside the render queue
1378 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1380 // Construct message in the render queue memory; note that delete should not be called on the return value
1381 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1384 void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
1386 typedef MessageValue1< RenderManager, OwnerPointer< Render::FrameBuffer > > DerivedType;
1388 // Reserve some memory inside the render queue
1389 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1391 // Construct message in the render queue memory; note that delete should not be called on the return value
1392 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1395 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1397 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1399 // Reserve some memory inside the render queue
1400 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1402 // Construct message in the render queue memory; note that delete should not be called on the return value
1403 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1406 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
1408 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t > DerivedType;
1410 // Reserve some memory inside the render queue
1411 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1413 // Construct message in the render queue memory; note that delete should not be called on the return value
1414 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1417 } // namespace SceneGraph
1419 } // namespace Internal