2 * Copyright (c) 2018 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/update-algorithms.h>
51 #include <dali/internal/update/manager/update-manager-debug.h>
52 #include <dali/internal/update/manager/transform-manager.h>
53 #include <dali/internal/update/nodes/node.h>
54 #include <dali/internal/update/nodes/scene-graph-layer.h>
55 #include <dali/internal/update/queue/update-message-queue.h>
56 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
57 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
58 #include <dali/internal/update/render-tasks/scene-graph-camera.h>
60 #include <dali/internal/render/common/render-instruction-container.h>
61 #include <dali/internal/render/common/render-manager.h>
62 #include <dali/internal/render/queue/render-queue.h>
63 #include <dali/internal/render/shaders/scene-graph-shader.h>
65 // Un-comment to enable node tree debug logging
66 //#define NODE_TREE_LOGGING 1
68 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
69 #define SNAPSHOT_NODE_LOGGING \
70 const uint32_t FRAME_COUNT_TRIGGER = 16;\
71 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
73 if ( NULL != mImpl->root )\
75 mImpl->frameCounter = 0;\
76 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
79 mImpl->frameCounter++;
81 #define SNAPSHOT_NODE_LOGGING
84 #if defined(DEBUG_ENABLED)
85 extern Debug::Filter* gRenderTaskLogFilter;
89 using namespace Dali::Integration;
90 using Dali::Internal::Update::MessageQueue;
104 * Helper to reset animate-able objects to base values
105 * @param container to iterate over
106 * @param updateBufferIndex to use
109 inline void ResetToBaseValues( OwnerContainer<T*>& container, BufferIndex updateBufferIndex )
111 // Reset animatable properties to base values
112 // use reference to avoid extra copies of the iterator
113 for( auto&& iter : container )
115 iter->ResetToBaseValues( updateBufferIndex );
120 * Helper to Erase an object from OwnerContainer using discard queue
121 * @param container to remove from
122 * @param object to remove
123 * @param discardQueue to put the object to
124 * @param updateBufferIndex to use
127 inline void EraseUsingDiscardQueue( OwnerContainer<T*>& container, T* object, DiscardQueue& discardQueue, BufferIndex updateBufferIndex )
129 DALI_ASSERT_DEBUG( object && "NULL object not allowed" );
131 // need to use the reference version of auto as we need the pointer to the pointer for the Release call below
132 for( auto&& iter : container )
134 if ( iter == object )
136 // Transfer ownership to the discard queue, this keeps the object alive, until the render-thread has finished with it
137 discardQueue.Add( updateBufferIndex, container.Release( &iter ) ); // take the address of the reference to a pointer (iter)
138 return; // return as we only ever remove one object. Iterators to container are now invalidated as well so cannot continue
144 * Descends into node's hierarchy and sorts the children of each child according to their depth-index.
145 * @param[in] node The node whose hierarchy to descend
147 void SortSiblingNodesRecursively( Node& node )
149 NodeContainer& container = node.GetChildren();
150 std::sort( container.Begin(), container.End(),
151 []( Node* a, Node* b ) { return a->GetDepthIndex() < b->GetDepthIndex(); } );
153 // Descend tree and sort as well
154 for( auto&& iter : container )
156 SortSiblingNodesRecursively( *iter );
160 } // unnamed namespace
163 * Structure to contain UpdateManager internal data
165 struct UpdateManager::Impl
167 Impl( NotificationManager& notificationManager,
168 CompleteNotificationInterface& animationPlaylist,
169 PropertyNotifier& propertyNotifier,
170 DiscardQueue& discardQueue,
171 RenderController& renderController,
172 RenderManager& renderManager,
173 RenderQueue& renderQueue,
174 SceneGraphBuffers& sceneGraphBuffers,
175 RenderTaskProcessor& renderTaskProcessor )
176 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
177 notificationManager( notificationManager ),
179 animationPlaylist( animationPlaylist ),
180 propertyNotifier( propertyNotifier ),
182 discardQueue( discardQueue ),
183 renderController( renderController ),
184 sceneController( NULL ),
185 renderManager( renderManager ),
186 renderQueue( renderQueue ),
187 renderInstructions( renderManager.GetRenderInstructionContainer() ),
188 renderTaskProcessor( renderTaskProcessor ),
189 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
190 taskList( renderMessageDispatcher ),
191 systemLevelTaskList( renderMessageDispatcher ),
193 systemLevelRoot( NULL ),
197 panGestureProcessor( NULL ),
198 messageQueue( renderController, sceneGraphBuffers ),
199 frameCallbackProcessor( NULL ),
200 keepRenderingSeconds( 0.0f ),
201 nodeDirtyFlags( NodePropertyFlags::TRANSFORM ), // set to TransformFlag to ensure full update the first time through Update()
203 renderingBehavior( DevelStage::Rendering::IF_REQUIRED ),
204 animationFinishedDuringUpdate( false ),
205 previousUpdateScene( false ),
206 renderTaskWaiting( false ),
207 renderersAdded( false ),
208 surfaceRectChanged( false )
210 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
212 // create first 'dummy' node
218 // Disconnect render tasks from nodes, before destroying the nodes
219 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
220 for ( auto&& iter : tasks )
222 iter->SetSourceNode( NULL );
224 // ..repeat for system level RenderTasks
225 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
226 for ( auto&& iter : systemLevelTasks )
228 iter->SetSourceNode( NULL );
231 // UpdateManager owns the Nodes. Although Nodes are pool allocated they contain heap allocated parts
232 // like custom properties, which get released here
233 Vector<Node*>::Iterator iter = nodes.Begin()+1;
234 Vector<Node*>::Iterator endIter = nodes.End();
235 for(;iter!=endIter;++iter)
237 (*iter)->OnDestroy();
241 // If there is root, reset it, otherwise do nothing as rendering was never started
246 Node::Delete( root );
250 if( systemLevelRoot )
252 systemLevelRoot->OnDestroy();
254 Node::Delete( systemLevelRoot );
255 systemLevelRoot = NULL;
258 delete sceneController;
262 * Lazy init for FrameCallbackProcessor.
264 FrameCallbackProcessor& GetFrameCallbackProcessor()
266 if( ! frameCallbackProcessor )
268 frameCallbackProcessor = new FrameCallbackProcessor( transformManager );
270 return *frameCallbackProcessor;
273 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
274 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
275 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
276 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
277 CompleteNotificationInterface& animationPlaylist; ///< Holds handles to all the animations
278 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
279 ShaderSaver* shaderSaver; ///< Saves shader binaries.
280 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
281 RenderController& renderController; ///< render controller
282 SceneControllerImpl* sceneController; ///< scene controller
283 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
284 RenderQueue& renderQueue; ///< Used to queue messages for the next render
285 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
286 RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
288 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
290 RenderTaskList taskList; ///< The list of scene graph render-tasks
291 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
293 Layer* root; ///< The root node (root is a layer)
294 Layer* systemLevelRoot; ///< A separate root-node for system-level content
296 Vector<Node*> nodes; ///< A container of all instantiated nodes
298 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
299 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
301 OwnerContainer< Camera* > cameras; ///< A container of cameras
302 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
304 OwnerContainer< PropertyResetterBase* > propertyResetters; ///< A container of property resetters
305 AnimationContainer animations; ///< A container of owned animations
306 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
307 OwnerContainer< Renderer* > renderers; ///< A container of owned renderers
308 OwnerContainer< TextureSet* > textureSets; ///< A container of owned texture sets
309 OwnerContainer< Shader* > shaders; ///< A container of owned shaders
310 OwnerPointer< PanGesture > panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager
312 MessageQueue messageQueue; ///< The messages queued from the event-thread
313 std::vector<Internal::ShaderDataPtr> renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
314 std::vector<Internal::ShaderDataPtr> updateCompiledShaders; ///< Shaders to be sent from Update to Event
315 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
317 OwnerPointer<FrameCallbackProcessor> frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required.
319 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
320 NodePropertyFlags nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
321 uint32_t frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
323 DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior
325 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
326 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
327 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
328 bool renderersAdded; ///< Flag to keep track when renderers have been added to avoid unnecessary processing
329 bool surfaceRectChanged; ///< True if the default surface rect is changed
333 Impl( const Impl& ); ///< Undefined
334 Impl& operator=( const Impl& ); ///< Undefined
337 UpdateManager::UpdateManager( NotificationManager& notificationManager,
338 CompleteNotificationInterface& animationFinishedNotifier,
339 PropertyNotifier& propertyNotifier,
340 DiscardQueue& discardQueue,
341 RenderController& controller,
342 RenderManager& renderManager,
343 RenderQueue& renderQueue,
344 RenderTaskProcessor& renderTaskProcessor )
347 mImpl = new Impl( notificationManager,
348 animationFinishedNotifier,
355 renderTaskProcessor );
359 UpdateManager::~UpdateManager()
364 void UpdateManager::InstallRoot( OwnerPointer<Layer>& layer, bool systemLevel )
366 DALI_ASSERT_DEBUG( layer->IsLayer() );
367 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
371 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
372 mImpl->root = layer.Release();
373 mImpl->root->CreateTransform( &mImpl->transformManager );
374 mImpl->root->SetRoot(true);
378 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
379 mImpl->systemLevelRoot = layer.Release();
380 mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager );
381 mImpl->systemLevelRoot->SetRoot(true);
386 void UpdateManager::AddNode( OwnerPointer<Node>& node )
388 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
390 // Nodes must be sorted by pointer
391 Node* rawNode = node.Release();
392 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
393 for( Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter )
395 if( rawNode > (*iter) )
397 mImpl->nodes.Insert((iter+1), rawNode );
398 rawNode->CreateTransform( &mImpl->transformManager );
404 void UpdateManager::ConnectNode( Node* parent, Node* node )
406 DALI_ASSERT_ALWAYS( NULL != parent );
407 DALI_ASSERT_ALWAYS( NULL != node );
408 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
410 parent->ConnectChild( node );
412 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
413 if( mImpl->frameCallbackProcessor )
415 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
419 void UpdateManager::DisconnectNode( Node* node )
421 Node* parent = node->GetParent();
422 DALI_ASSERT_ALWAYS( NULL != parent );
423 parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused
425 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
427 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
428 if( mImpl->frameCallbackProcessor )
430 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
434 void UpdateManager::DestroyNode( Node* node )
436 DALI_ASSERT_ALWAYS( NULL != node );
437 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
439 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
440 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
441 for(;iter!=endIter;++iter)
445 mImpl->nodes.Erase(iter);
450 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
452 // Notify the Node about impending destruction
456 void UpdateManager::AddCamera( OwnerPointer< Camera >& camera )
458 mImpl->cameras.PushBack( camera.Release() ); // takes ownership
461 void UpdateManager::RemoveCamera( const Camera* camera )
463 // Find the camera and destroy it
464 EraseUsingDiscardQueue( mImpl->cameras, const_cast<Camera*>( camera ), mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
467 void UpdateManager::AddObject( OwnerPointer<PropertyOwner>& object )
469 mImpl->customObjects.PushBack( object.Release() );
472 void UpdateManager::RemoveObject( PropertyOwner* object )
474 mImpl->customObjects.EraseObject( object );
477 void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation )
479 mImpl->animations.PushBack( animation.Release() );
482 void UpdateManager::StopAnimation( Animation* animation )
484 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
486 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
488 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
491 void UpdateManager::RemoveAnimation( Animation* animation )
493 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
495 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
497 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
500 bool UpdateManager::IsAnimationRunning() const
502 // Find any animation that isn't stopped or paused
503 for ( auto&& iter : mImpl->animations )
505 const Animation::State state = iter->GetState();
507 if (state != Animation::Stopped &&
508 state != Animation::Paused)
510 return true; // stop iteration as soon as first one is found
517 void UpdateManager::AddPropertyResetter( OwnerPointer<PropertyResetterBase>& propertyResetter )
519 propertyResetter->Initialize();
520 mImpl->propertyResetters.PushBack( propertyResetter.Release() );
523 void UpdateManager::AddPropertyNotification( OwnerPointer< PropertyNotification >& propertyNotification )
525 mImpl->propertyNotifications.PushBack( propertyNotification.Release() );
528 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
530 mImpl->propertyNotifications.EraseObject( propertyNotification );
533 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
535 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
536 propertyNotification->SetNotifyMode( notifyMode );
539 void UpdateManager::AddShader( OwnerPointer< Shader >& shader )
541 mImpl->shaders.PushBack( shader.Release() );
544 void UpdateManager::RemoveShader( Shader* shader )
546 // Find the shader and destroy it
547 EraseUsingDiscardQueue( mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
550 void UpdateManager::SetShaderProgram( Shader* shader,
551 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
556 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
558 // Reserve some memory inside the render queue
559 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
561 // Construct message in the render queue memory; note that delete should not be called on the return value
562 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
566 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
568 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
569 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
571 // lock as update might be sending previously compiled shaders to event thread
572 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
573 mImpl->renderCompiledShaders.push_back( shaderData );
577 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
579 mImpl->shaderSaver = &upstream;
582 void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer )
584 renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
585 mImpl->renderers.PushBack( renderer.Release() );
586 mImpl->renderersAdded = true;
589 void UpdateManager::RemoveRenderer( Renderer* renderer )
591 // Find the renderer and destroy it
592 EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
593 // Need to remove the render object as well
594 renderer->DisconnectFromSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
597 void UpdateManager::SetPanGestureProcessor( PanGesture* panGestureProcessor )
599 DALI_ASSERT_DEBUG( NULL != panGestureProcessor );
601 mImpl->panGestureProcessor = panGestureProcessor;
604 void UpdateManager::AddTextureSet( OwnerPointer< TextureSet >& textureSet )
606 mImpl->textureSets.PushBack( textureSet.Release() );
609 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
611 mImpl->textureSets.EraseObject( textureSet );
614 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
618 // copy the list, this is only likely to happen once in application life cycle
619 return &(mImpl->taskList);
623 // copy the list, this is only likely to happen once in application life cycle
624 return &(mImpl->systemLevelTaskList);
628 uint32_t* UpdateManager::ReserveMessageSlot( uint32_t size, bool updateScene )
630 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
633 void UpdateManager::EventProcessingStarted()
635 mImpl->messageQueue.EventProcessingStarted();
638 bool UpdateManager::FlushQueue()
640 return mImpl->messageQueue.FlushQueue();
643 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
645 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
646 mImpl->animationFinishedDuringUpdate = false;
648 // Reset all animating / constrained properties
649 std::vector<PropertyResetterBase*>toDelete;
650 for( auto&& element : mImpl->propertyResetters )
652 element->ResetToBaseValue( bufferIndex );
653 if( element->IsFinished() )
655 toDelete.push_back( element );
659 // If a resetter is no longer required (the animator or constraint has been removed), delete it.
660 for( auto&& elementPtr : toDelete )
662 mImpl->propertyResetters.EraseObject( elementPtr );
665 // Clear node dirty flags
666 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
667 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
668 for( ;iter != endIter; ++iter )
670 (*iter)->ResetDirtyFlags( bufferIndex );
674 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds )
676 bool gestureUpdated( false );
678 if( mImpl->panGestureProcessor )
680 // gesture processor only supports default properties
681 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
682 gestureUpdated |= mImpl->panGestureProcessor->UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
685 return gestureUpdated;
688 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
690 AnimationContainer &animations = mImpl->animations;
691 AnimationIter iter = animations.Begin();
692 bool animationLooped = false;
694 while ( iter != animations.End() )
696 Animation* animation = *iter;
697 bool finished = false;
699 bool progressMarkerReached = false;
700 animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
702 if ( progressMarkerReached )
704 mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
707 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
708 animationLooped = animationLooped || looped;
710 // Remove animations that had been destroyed but were still waiting for an update
711 if (animation->GetState() == Animation::Destroyed)
713 iter = animations.Erase(iter);
721 // queue the notification on finished or looped (to update loop count)
722 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
724 // The application should be notified by NotificationManager, in another thread
725 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
729 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
731 //Constrain custom objects (in construction order)
732 for ( auto&& object : mImpl->customObjects )
734 ConstrainPropertyOwner( *object, bufferIndex );
738 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
740 // Constrain system-level render-tasks
741 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
742 for ( auto&& task : systemLevelTasks )
744 ConstrainPropertyOwner( *task, bufferIndex );
747 // Constrain render-tasks
748 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
749 for ( auto&& task : tasks )
751 ConstrainPropertyOwner( *task, bufferIndex );
755 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
757 // constrain shaders... (in construction order)
758 for ( auto&& shader : mImpl->shaders )
760 ConstrainPropertyOwner( *shader, bufferIndex );
764 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
766 for( auto&& notification : mImpl->propertyNotifications )
768 bool valid = notification->Check( bufferIndex );
771 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
776 void UpdateManager::ForwardCompiledShadersToEventThread()
778 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
779 if( mImpl->shaderSaver )
781 // lock and swap the queues
783 // render might be attempting to send us more binaries at the same time
784 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
785 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
788 if( mImpl->updateCompiledShaders.size() > 0 )
790 ShaderSaver& factory = *mImpl->shaderSaver;
791 for( auto&& shader : mImpl->updateCompiledShaders )
793 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, shader ) );
795 // we don't need them in update anymore
796 mImpl->updateCompiledShaders.clear();
801 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
803 for( auto&& renderer : mImpl->renderers )
806 ConstrainPropertyOwner( *renderer, bufferIndex );
808 renderer->PrepareRender( bufferIndex );
812 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
814 mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
821 // Prepare resources, update shaders, for each node
822 // And add the renderers to the sorted layers. Start from root, which is also a layer
823 mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
825 mImpl->renderQueue );
827 if ( mImpl->systemLevelRoot )
829 mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
831 mImpl->renderQueue );
835 uint32_t UpdateManager::Update( float elapsedSeconds,
836 uint32_t lastVSyncTimeMilliseconds,
837 uint32_t nextVSyncTimeMilliseconds,
838 bool renderToFboEnabled,
839 bool isRenderingToFbo )
841 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
843 //Clear nodes/resources which were previously discarded
844 mImpl->discardQueue.Clear( bufferIndex );
846 //Process Touches & Gestures
847 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
849 bool updateScene = // The scene-graph requires an update if..
850 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
851 IsAnimationRunning() || // ..at least one animation is running OR
852 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
853 gestureUpdated; // ..a gesture property was updated
856 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
857 // values if the scene was updated in the previous frame.
858 if( updateScene || mImpl->previousUpdateScene )
860 //Reset properties from the previous update
861 ResetProperties( bufferIndex );
862 mImpl->transformManager.ResetToBaseValue();
865 // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
866 // between calling IsSceneUpdateRequired() above and here, so updateScene should
868 updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
870 //Forward compiled shader programs to event thread for saving
871 ForwardCompiledShadersToEventThread();
873 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
874 // renderer lists if the scene was updated in the previous frame.
875 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
876 if( updateScene || mImpl->previousUpdateScene )
879 Animate( bufferIndex, elapsedSeconds );
881 //Constraint custom objects
882 ConstrainCustomObjects( bufferIndex );
884 //Clear the lists of renderers from the previous update
885 for( auto&& layer : mImpl->sortedLayers )
887 layer->ClearRenderables();
890 for( auto&& layer : mImpl->systemLevelSortedLayers )
892 layer->ClearRenderables();
895 //Update node hierarchy, apply constraints and perform sorting / culling.
896 //This will populate each Layer with a list of renderers which are ready.
897 UpdateNodes( bufferIndex );
899 //Apply constraints to RenderTasks, shaders
900 ConstrainRenderTasks( bufferIndex );
901 ConstrainShaders( bufferIndex );
903 //Update renderers and apply constraints
904 UpdateRenderers( bufferIndex );
906 // Call the frame-callback-processor if set
907 if( mImpl->frameCallbackProcessor )
909 mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
912 //Update the transformations of all the nodes
913 mImpl->transformManager.Update();
915 //Process Property Notifications
916 ProcessPropertyNotifications( bufferIndex );
919 for( auto&& cameraIterator : mImpl->cameras )
921 cameraIterator->Update( bufferIndex );
924 //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
925 //reset the update buffer index and make sure there is enough room in the instruction container
926 if( mImpl->renderersAdded )
928 mImpl->renderInstructions.ResetAndReserve( bufferIndex, mImpl->taskList.GetTaskCount() + mImpl->systemLevelTaskList.GetTaskCount() );
930 if ( NULL != mImpl->root )
932 mImpl->renderTaskProcessor.Process( bufferIndex,
936 mImpl->renderInstructions,
940 // Process the system-level RenderTasks last
941 if ( NULL != mImpl->systemLevelRoot )
943 mImpl->renderTaskProcessor.Process( bufferIndex,
944 mImpl->systemLevelTaskList,
945 *mImpl->systemLevelRoot,
946 mImpl->systemLevelSortedLayers,
947 mImpl->renderInstructions,
955 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
956 bool doRenderOnceNotify = false;
957 mImpl->renderTaskWaiting = false;
958 for ( auto&& renderTask : mImpl->taskList.GetTasks() )
960 renderTask->UpdateState();
962 if( renderTask->IsWaitingToRender() &&
963 renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
965 mImpl->renderTaskWaiting = true; // keep update/render threads alive
968 if( renderTask->HasRendered() )
970 doRenderOnceNotify = true;
974 if( doRenderOnceNotify )
976 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
977 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
980 // Macro is undefined in release build.
981 SNAPSHOT_NODE_LOGGING;
983 // A ResetProperties() may be required in the next frame
984 mImpl->previousUpdateScene = updateScene;
986 // Check whether further updates are required
987 uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds );
989 // tell the update manager that we're done so the queue can be given to event thread
990 mImpl->notificationManager.UpdateCompleted();
992 // The update has finished; swap the double-buffering indices
993 mSceneGraphBuffers.Swap();
998 uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1000 // Update the duration set via Stage::KeepRendering()
1001 if ( mImpl->keepRenderingSeconds > 0.0f )
1003 mImpl->keepRenderingSeconds -= elapsedSeconds;
1006 uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1008 // If the rendering behavior is set to continuously render, then continue to render.
1009 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1010 // Keep updating until no messages are received and no animations are running.
1011 // If an animation has just finished, update at least once more for Discard end-actions.
1012 // No need to check for renderQueue as there is always a render after update and if that
1013 // render needs another update it will tell the adaptor to call update again
1015 if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
1016 ( mImpl->keepRenderingSeconds > 0.0f ) )
1018 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1021 if ( IsAnimationRunning() ||
1022 mImpl->animationFinishedDuringUpdate )
1024 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1027 if ( mImpl->renderTaskWaiting )
1029 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1032 return keepUpdatingRequest;
1035 void UpdateManager::SetBackgroundColor( const Vector4& color )
1037 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1039 // Reserve some memory inside the render queue
1040 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1042 // Construct message in the render queue memory; note that delete should not be called on the return value
1043 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1046 void UpdateManager::SetDefaultSurfaceRect( const Rect<int32_t>& rect )
1048 mImpl->surfaceRectChanged = true;
1050 typedef MessageValue1< RenderManager, Rect<int32_t> > DerivedType;
1052 // Reserve some memory inside the render queue
1053 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1055 // Construct message in the render queue memory; note that delete should not be called on the return value
1056 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1059 void UpdateManager::KeepRendering( float durationSeconds )
1061 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1064 void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
1066 mImpl->renderingBehavior = renderingBehavior;
1069 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1073 // just copy the vector of pointers
1074 mImpl->sortedLayers = layers;
1078 mImpl->systemLevelSortedLayers = layers;
1082 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1084 // note,this vector is already in depth order. It could be used as-is to
1085 // remove sorting in update algorithm. However, it lacks layer boundary markers.
1086 for( auto&& iter : nodeDepths->nodeDepths )
1088 iter.node->SetDepthIndex( iter.sortedDepth );
1091 // Go through node hierarchy and rearrange siblings according to depth-index
1092 SortSiblingNodesRecursively( *( mImpl->root ) );
1095 bool UpdateManager::IsDefaultSurfaceRectChanged()
1097 bool surfaceRectChanged = mImpl->surfaceRectChanged;
1100 mImpl->surfaceRectChanged = false;
1102 return surfaceRectChanged;
1105 void UpdateManager::AddFrameCallback( FrameCallbackInterface* frameCallback, const Node* rootNode )
1107 mImpl->GetFrameCallbackProcessor().AddFrameCallback( frameCallback, rootNode );
1110 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1112 mImpl->GetFrameCallbackProcessor().RemoveFrameCallback( frameCallback );
1115 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1117 // Message has ownership of Sampler while in transit from update to render
1118 typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > DerivedType;
1120 // Reserve some memory inside the render queue
1121 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1123 // Construct message in the render queue memory; note that delete should not be called on the return value
1124 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1127 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1129 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1131 // Reserve some memory inside the render queue
1132 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1134 // Construct message in the render queue memory; note that delete should not be called on the return value
1135 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1138 void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
1140 typedef MessageValue3< RenderManager, Render::Sampler*, uint32_t, uint32_t > DerivedType;
1142 // Reserve some memory inside the render queue
1143 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1145 // Construct message in the render queue memory; note that delete should not be called on the return value
1146 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1149 void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
1151 typedef MessageValue4< RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t > DerivedType;
1153 // Reserve some memory inside the render queue
1154 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1156 // Construct message in the render queue memory; note that delete should not be called on the return value
1157 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1160 void UpdateManager::AddPropertyBuffer( OwnerPointer< Render::PropertyBuffer >& propertyBuffer )
1162 // Message has ownership of format while in transit from update -> render
1163 typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
1165 // Reserve some memory inside the render queue
1166 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1168 // Construct message in the render queue memory; note that delete should not be called on the return value
1169 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1172 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1174 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1176 // Reserve some memory inside the render queue
1177 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1179 // Construct message in the render queue memory; note that delete should not be called on the return value
1180 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1183 void UpdateManager::SetPropertyBufferFormat( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Render::PropertyBuffer::Format>& format )
1185 // Message has ownership of format while in transit from update -> render
1186 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType;
1188 // Reserve some memory inside the render queue
1189 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1191 // Construct message in the render queue memory; note that delete should not be called on the return value
1192 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1195 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
1197 // Message has ownership of format while in transit from update -> render
1198 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<uint8_t> >, uint32_t > DerivedType;
1200 // Reserve some memory inside the render queue
1201 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1203 // Construct message in the render queue memory; note that delete should not be called on the return value
1204 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1207 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1209 // Message has ownership of format while in transit from update -> render
1210 typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > DerivedType;
1212 // Reserve some memory inside the render queue
1213 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1215 // Construct message in the render queue memory; note that delete should not be called on the return value
1216 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1219 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1221 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1223 // Reserve some memory inside the render queue
1224 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1226 // Construct message in the render queue memory; note that delete should not be called on the return value
1227 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1230 void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
1232 typedef MessageValue2< RenderManager, Render::Geometry*, uint32_t > DerivedType;
1234 // Reserve some memory inside the render queue
1235 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1237 // Construct message in the render queue memory; note that delete should not be called on the return value
1238 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1241 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
1243 typedef IndexBufferMessage< RenderManager > DerivedType;
1245 // Reserve some memory inside the render queue
1246 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1248 // Construct message in the render queue memory; note that delete should not be called on the return value
1249 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1252 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1254 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1256 // Reserve some memory inside the render queue
1257 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1259 // Construct message in the render queue memory; note that delete should not be called on the return value
1260 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1263 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1265 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1267 // Reserve some memory inside the render queue
1268 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1270 // Construct message in the render queue memory; note that delete should not be called on the return value
1271 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, propertyBuffer );
1274 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1276 // Message has ownership of Texture while in transit from update -> render
1277 typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > 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::AddTexture, texture );
1286 void UpdateManager::RemoveTexture( Render::Texture* texture)
1288 typedef MessageValue1< RenderManager, Render::Texture* > 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::RemoveTexture, texture );
1297 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1299 typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
1301 // Reserve some memory inside the message queue
1302 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1304 // Construct message in the message queue memory; note that delete should not be called on the return value
1305 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1308 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1310 typedef MessageValue1< RenderManager, Render::Texture* > 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, &RenderManager::GenerateMipmaps, texture );
1319 void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
1321 typedef MessageValue1< RenderManager, Render::FrameBuffer* > 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::AddFrameBuffer, frameBuffer );
1330 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1332 typedef MessageValue1< RenderManager, Render::FrameBuffer* > 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::RemoveFrameBuffer, frameBuffer );
1341 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
1343 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t > DerivedType;
1345 // Reserve some memory inside the render queue
1346 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1348 // Construct message in the render queue memory; note that delete should not be called on the return value
1349 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1352 } // namespace SceneGraph
1354 } // namespace Internal