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/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 root : mImpl->roots )
78 mImpl->frameCounter = 0;\
79 PrintNodeTree( *root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
83 mImpl->frameCounter++;
85 #define SNAPSHOT_NODE_LOGGING
88 #if defined(DEBUG_ENABLED)
89 extern Debug::Filter* gRenderTaskLogFilter;
93 using namespace Dali::Integration;
94 using Dali::Internal::Update::MessageQueue;
108 * Helper to Erase an object from OwnerContainer using discard queue
109 * @param container to remove from
110 * @param object to remove
111 * @param discardQueue to put the object to
112 * @param updateBufferIndex to use
115 inline void EraseUsingDiscardQueue( OwnerContainer<T*>& container, T* object, DiscardQueue& discardQueue, BufferIndex updateBufferIndex )
117 DALI_ASSERT_DEBUG( object && "NULL object not allowed" );
119 // need to use the reference version of auto as we need the pointer to the pointer for the Release call below
120 for( auto&& iter : container )
122 if ( iter == object )
124 // Transfer ownership to the discard queue, this keeps the object alive, until the render-thread has finished with it
125 discardQueue.Add( updateBufferIndex, container.Release( &iter ) ); // take the address of the reference to a pointer (iter)
126 return; // return as we only ever remove one object. Iterators to container are now invalidated as well so cannot continue
132 * Descends into node's hierarchy and sorts the children of each child according to their depth-index.
133 * @param[in] node The node whose hierarchy to descend
135 void SortSiblingNodesRecursively( Node& node )
137 NodeContainer& container = node.GetChildren();
138 std::sort( container.Begin(), container.End(),
139 []( Node* a, Node* b ) { return a->GetDepthIndex() < b->GetDepthIndex(); } );
141 // Descend tree and sort as well
142 for( auto&& iter : container )
144 SortSiblingNodesRecursively( *iter );
148 } // unnamed namespace
151 * Structure to contain UpdateManager internal data
153 struct UpdateManager::Impl
155 Impl( NotificationManager& notificationManager,
156 CompleteNotificationInterface& animationPlaylist,
157 PropertyNotifier& propertyNotifier,
158 DiscardQueue& discardQueue,
159 RenderController& renderController,
160 RenderManager& renderManager,
161 RenderQueue& renderQueue,
162 SceneGraphBuffers& sceneGraphBuffers,
163 RenderTaskProcessor& renderTaskProcessor )
164 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
165 notificationManager( notificationManager ),
167 animationPlaylist( animationPlaylist ),
168 propertyNotifier( propertyNotifier ),
170 discardQueue( discardQueue ),
171 renderController( renderController ),
172 sceneController( NULL ),
173 renderManager( renderManager ),
174 renderQueue( renderQueue ),
175 renderInstructions( renderManager.GetRenderInstructionContainer() ),
176 renderTaskProcessor( renderTaskProcessor ),
177 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
181 panGestureProcessor( NULL ),
182 messageQueue( renderController, sceneGraphBuffers ),
183 frameCallbackProcessor( NULL ),
184 keepRenderingSeconds( 0.0f ),
185 nodeDirtyFlags( NodePropertyFlags::TRANSFORM ), // set to TransformFlag to ensure full update the first time through Update()
187 renderingBehavior( DevelStage::Rendering::IF_REQUIRED ),
188 animationFinishedDuringUpdate( false ),
189 previousUpdateScene( false ),
190 renderTaskWaiting( false ),
191 renderersAdded( false ),
192 surfaceRectChanged( false )
194 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
196 // create first 'dummy' node
202 // Disconnect render tasks from nodes, before destroying the nodes
203 for( auto taskList : taskLists )
205 RenderTaskList::RenderTaskContainer& tasks = taskList->GetTasks();
206 for ( auto&& task : tasks )
208 task->SetSourceNode( NULL );
212 // UpdateManager owns the Nodes. Although Nodes are pool allocated they contain heap allocated parts
213 // like custom properties, which get released here
214 Vector<Node*>::Iterator iter = nodes.Begin()+1;
215 Vector<Node*>::Iterator endIter = nodes.End();
216 for(;iter!=endIter;++iter)
218 (*iter)->OnDestroy();
222 for( auto root : roots )
228 delete sceneController;
232 * Lazy init for FrameCallbackProcessor.
233 * @param[in] updateManager A reference to the update-manager
235 FrameCallbackProcessor& GetFrameCallbackProcessor( UpdateManager& updateManager )
237 if( ! frameCallbackProcessor )
239 frameCallbackProcessor = new FrameCallbackProcessor( updateManager, transformManager );
241 return *frameCallbackProcessor;
244 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
245 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
246 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
247 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
248 CompleteNotificationInterface& animationPlaylist; ///< Holds handles to all the animations
249 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
250 ShaderSaver* shaderSaver; ///< Saves shader binaries.
251 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
252 RenderController& renderController; ///< render controller
253 SceneControllerImpl* sceneController; ///< scene controller
254 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
255 RenderQueue& renderQueue; ///< Used to queue messages for the next render
256 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
257 RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
259 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
261 OwnerContainer<RenderTaskList*> taskLists; ///< A container of scene graph render task lists
263 Vector<Layer*> roots; ///< A container of root nodes (root is a layer). The layers are not stored in the node memory pool.
265 Vector<Node*> nodes; ///< A container of all instantiated nodes
267 std::vector<SortedLayerPointers> sortedLayerLists; ///< A container of lists of Layer pointers sorted by depth (one list of sorted layers per root)
269 OwnerContainer< Camera* > cameras; ///< A container of cameras
270 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
272 OwnerContainer< PropertyResetterBase* > propertyResetters; ///< A container of property resetters
273 OwnerContainer< Animation* > animations; ///< A container of owned animations
274 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
275 OwnerContainer< Renderer* > renderers; ///< A container of owned renderers
276 OwnerContainer< TextureSet* > textureSets; ///< A container of owned texture sets
277 OwnerContainer< Shader* > shaders; ///< A container of owned shaders
278 OwnerPointer< PanGesture > panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager
280 MessageQueue messageQueue; ///< The messages queued from the event-thread
281 std::vector<Internal::ShaderDataPtr> renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
282 std::vector<Internal::ShaderDataPtr> updateCompiledShaders; ///< Shaders to be sent from Update to Event
283 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
285 OwnerPointer<FrameCallbackProcessor> frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required.
287 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
288 NodePropertyFlags nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
289 uint32_t frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
291 DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior
293 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
294 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
295 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
296 bool renderersAdded; ///< Flag to keep track when renderers have been added to avoid unnecessary processing
297 bool surfaceRectChanged; ///< True if the default surface rect is changed
301 Impl( const Impl& ); ///< Undefined
302 Impl& operator=( const Impl& ); ///< Undefined
305 UpdateManager::UpdateManager( NotificationManager& notificationManager,
306 CompleteNotificationInterface& animationFinishedNotifier,
307 PropertyNotifier& propertyNotifier,
308 DiscardQueue& discardQueue,
309 RenderController& controller,
310 RenderManager& renderManager,
311 RenderQueue& renderQueue,
312 RenderTaskProcessor& renderTaskProcessor )
315 mImpl = new Impl( notificationManager,
316 animationFinishedNotifier,
323 renderTaskProcessor );
327 UpdateManager::~UpdateManager()
332 void UpdateManager::InstallRoot( OwnerPointer<Layer>& layer )
334 DALI_ASSERT_DEBUG( layer->IsLayer() );
335 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
337 Layer* rootLayer = layer.Release();
339 DALI_ASSERT_DEBUG( std::find( mImpl->roots.begin(), mImpl->roots.end(), rootLayer ) == mImpl->roots.end() && "Root Node already installed" );
341 rootLayer->CreateTransform( &mImpl->transformManager );
342 rootLayer->SetRoot(true);
343 mImpl->roots.PushBack( rootLayer );
346 void UpdateManager::UninstallRoot( Layer* layer )
348 DALI_ASSERT_DEBUG( layer->IsLayer() );
349 DALI_ASSERT_DEBUG( layer->GetParent() == NULL );
351 for ( auto&& iter : mImpl->roots )
353 if( ( *iter ) == layer )
355 mImpl->roots.Erase( &iter );
360 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), layer );
362 // Notify the layer about impending destruction
366 void UpdateManager::AddNode( OwnerPointer<Node>& node )
368 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
370 // Nodes must be sorted by pointer
371 Node* rawNode = node.Release();
372 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
373 for( Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter )
375 if( rawNode > (*iter) )
377 mImpl->nodes.Insert((iter+1), rawNode );
378 rawNode->CreateTransform( &mImpl->transformManager );
384 void UpdateManager::ConnectNode( Node* parent, Node* node )
386 DALI_ASSERT_ALWAYS( NULL != parent );
387 DALI_ASSERT_ALWAYS( NULL != node );
388 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
390 parent->ConnectChild( node );
392 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
393 if( mImpl->frameCallbackProcessor )
395 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
399 void UpdateManager::DisconnectNode( Node* node )
401 Node* parent = node->GetParent();
402 DALI_ASSERT_ALWAYS( NULL != parent );
403 parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused
405 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
407 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
408 if( mImpl->frameCallbackProcessor )
410 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
414 void UpdateManager::DestroyNode( Node* node )
416 DALI_ASSERT_ALWAYS( NULL != node );
417 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
419 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
420 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
421 for(;iter!=endIter;++iter)
425 mImpl->nodes.Erase(iter);
430 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
432 // Notify the Node about impending destruction
436 void UpdateManager::AddCamera( OwnerPointer< Camera >& camera )
438 mImpl->cameras.PushBack( camera.Release() ); // takes ownership
441 void UpdateManager::RemoveCamera( Camera* camera )
443 // Find the camera and destroy it
444 EraseUsingDiscardQueue( mImpl->cameras, camera, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
447 void UpdateManager::AddObject( OwnerPointer<PropertyOwner>& object )
449 mImpl->customObjects.PushBack( object.Release() );
452 void UpdateManager::RemoveObject( PropertyOwner* object )
454 mImpl->customObjects.EraseObject( object );
457 void UpdateManager::AddRenderTaskList( OwnerPointer<RenderTaskList>& taskList )
459 RenderTaskList* taskListPointer = taskList.Release();
460 taskListPointer->SetRenderMessageDispatcher( &mImpl->renderMessageDispatcher );
461 mImpl->taskLists.PushBack( taskListPointer );
464 void UpdateManager::RemoveRenderTaskList( RenderTaskList* taskList )
466 mImpl->taskLists.EraseObject( taskList );
469 void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation )
471 mImpl->animations.PushBack( animation.Release() );
474 void UpdateManager::StopAnimation( Animation* animation )
476 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
478 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
480 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
483 void UpdateManager::RemoveAnimation( Animation* animation )
485 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
487 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
489 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
492 bool UpdateManager::IsAnimationRunning() const
494 // Find any animation that isn't stopped or paused
495 for ( auto&& iter : mImpl->animations )
497 const Animation::State state = iter->GetState();
499 if (state != Animation::Stopped &&
500 state != Animation::Paused)
502 return true; // stop iteration as soon as first one is found
509 void UpdateManager::AddPropertyResetter( OwnerPointer<PropertyResetterBase>& propertyResetter )
511 propertyResetter->Initialize();
512 mImpl->propertyResetters.PushBack( propertyResetter.Release() );
515 void UpdateManager::AddPropertyNotification( OwnerPointer< PropertyNotification >& propertyNotification )
517 mImpl->propertyNotifications.PushBack( propertyNotification.Release() );
520 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
522 mImpl->propertyNotifications.EraseObject( propertyNotification );
525 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
527 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
528 propertyNotification->SetNotifyMode( notifyMode );
531 void UpdateManager::AddShader( OwnerPointer< Shader >& shader )
533 mImpl->shaders.PushBack( shader.Release() );
536 void UpdateManager::RemoveShader( Shader* shader )
538 // Find the shader and destroy it
539 EraseUsingDiscardQueue( mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
542 void UpdateManager::SetShaderProgram( Shader* shader,
543 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
548 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
550 // Reserve some memory inside the render queue
551 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
553 // Construct message in the render queue memory; note that delete should not be called on the return value
554 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
558 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
560 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
561 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
563 // lock as update might be sending previously compiled shaders to event thread
564 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
565 mImpl->renderCompiledShaders.push_back( shaderData );
569 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
571 mImpl->shaderSaver = &upstream;
574 void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer )
576 renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
577 mImpl->renderers.PushBack( renderer.Release() );
578 mImpl->renderersAdded = true;
581 void UpdateManager::RemoveRenderer( Renderer* renderer )
583 // Find the renderer and destroy it
584 EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
585 // Need to remove the render object as well
586 renderer->DisconnectFromSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
589 void UpdateManager::SetPanGestureProcessor( PanGesture* panGestureProcessor )
591 DALI_ASSERT_DEBUG( NULL != panGestureProcessor );
593 mImpl->panGestureProcessor = panGestureProcessor;
596 void UpdateManager::AddTextureSet( OwnerPointer< TextureSet >& textureSet )
598 mImpl->textureSets.PushBack( textureSet.Release() );
601 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
603 mImpl->textureSets.EraseObject( textureSet );
606 uint32_t* UpdateManager::ReserveMessageSlot( uint32_t size, bool updateScene )
608 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
611 void UpdateManager::EventProcessingStarted()
613 mImpl->messageQueue.EventProcessingStarted();
616 bool UpdateManager::FlushQueue()
618 return mImpl->messageQueue.FlushQueue();
621 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
623 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
624 mImpl->animationFinishedDuringUpdate = false;
626 // Reset all animating / constrained properties
627 std::vector<PropertyResetterBase*>toDelete;
628 for( auto&& element : mImpl->propertyResetters )
630 element->ResetToBaseValue( bufferIndex );
631 if( element->IsFinished() )
633 toDelete.push_back( element );
637 // If a resetter is no longer required (the animator or constraint has been removed), delete it.
638 for( auto&& elementPtr : toDelete )
640 mImpl->propertyResetters.EraseObject( elementPtr );
643 // Clear node dirty flags
644 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
645 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
646 for( ;iter != endIter; ++iter )
648 (*iter)->ResetDirtyFlags( bufferIndex );
652 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds )
654 bool gestureUpdated( false );
656 if( mImpl->panGestureProcessor )
658 // gesture processor only supports default properties
659 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
660 gestureUpdated |= mImpl->panGestureProcessor->UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
663 return gestureUpdated;
666 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
668 auto&& iter = mImpl->animations.Begin();
669 bool animationLooped = false;
671 while ( iter != mImpl->animations.End() )
673 Animation* animation = *iter;
674 bool finished = false;
676 bool progressMarkerReached = false;
677 animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
679 if ( progressMarkerReached )
681 mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
684 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
685 animationLooped = animationLooped || looped;
687 // Remove animations that had been destroyed but were still waiting for an update
688 if (animation->GetState() == Animation::Destroyed)
690 iter = mImpl->animations.Erase(iter);
698 // queue the notification on finished or looped (to update loop count)
699 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
701 // The application should be notified by NotificationManager, in another thread
702 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
706 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
708 //Constrain custom objects (in construction order)
709 for ( auto&& object : mImpl->customObjects )
711 ConstrainPropertyOwner( *object, bufferIndex );
715 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
717 // Constrain render-tasks
718 for( auto taskList : mImpl->taskLists )
720 RenderTaskList::RenderTaskContainer& tasks = taskList->GetTasks();
721 for ( auto&& task : tasks )
723 ConstrainPropertyOwner( *task, bufferIndex );
728 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
730 // constrain shaders... (in construction order)
731 for ( auto&& shader : mImpl->shaders )
733 ConstrainPropertyOwner( *shader, bufferIndex );
737 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
739 for( auto&& notification : mImpl->propertyNotifications )
741 bool valid = notification->Check( bufferIndex );
744 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
749 void UpdateManager::ForwardCompiledShadersToEventThread()
751 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
752 if( mImpl->shaderSaver )
754 // lock and swap the queues
756 // render might be attempting to send us more binaries at the same time
757 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
758 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
761 if( mImpl->updateCompiledShaders.size() > 0 )
763 ShaderSaver& factory = *mImpl->shaderSaver;
764 for( auto&& shader : mImpl->updateCompiledShaders )
766 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, shader ) );
768 // we don't need them in update anymore
769 mImpl->updateCompiledShaders.clear();
774 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
776 for( auto&& renderer : mImpl->renderers )
779 ConstrainPropertyOwner( *renderer, bufferIndex );
781 renderer->PrepareRender( bufferIndex );
785 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
787 mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
789 for( auto&& rootLayer : mImpl->roots )
791 // Prepare resources, update shaders, for each node
792 // And add the renderers to the sorted layers. Start from root, which is also a layer
793 mImpl->nodeDirtyFlags |= UpdateNodeTree( *rootLayer,
795 mImpl->renderQueue );
799 uint32_t UpdateManager::Update( float elapsedSeconds,
800 uint32_t lastVSyncTimeMilliseconds,
801 uint32_t nextVSyncTimeMilliseconds,
802 bool renderToFboEnabled,
803 bool isRenderingToFbo )
805 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
807 //Clear nodes/resources which were previously discarded
808 mImpl->discardQueue.Clear( bufferIndex );
810 //Process Touches & Gestures
811 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
813 bool updateScene = // The scene-graph requires an update if..
814 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
815 IsAnimationRunning() || // ..at least one animation is running OR
816 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
817 gestureUpdated; // ..a gesture property was updated
819 bool keepRendererRendering = false;
821 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
822 // values if the scene was updated in the previous frame.
823 if( updateScene || mImpl->previousUpdateScene )
825 //Reset properties from the previous update
826 ResetProperties( bufferIndex );
827 mImpl->transformManager.ResetToBaseValue();
830 // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
831 // between calling IsSceneUpdateRequired() above and here, so updateScene should
833 updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
835 //Forward compiled shader programs to event thread for saving
836 ForwardCompiledShadersToEventThread();
838 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
839 // renderer lists if the scene was updated in the previous frame.
840 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
841 if( updateScene || mImpl->previousUpdateScene )
844 Animate( bufferIndex, elapsedSeconds );
846 //Constraint custom objects
847 ConstrainCustomObjects( bufferIndex );
849 //Clear the lists of renderers from the previous update
850 for( auto sortedLayers : mImpl->sortedLayerLists )
852 for( auto&& layer : sortedLayers )
854 layer->ClearRenderables();
858 // Call the frame-callback-processor if set
859 if( mImpl->frameCallbackProcessor )
861 mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
864 //Update node hierarchy, apply constraints and perform sorting / culling.
865 //This will populate each Layer with a list of renderers which are ready.
866 UpdateNodes( bufferIndex );
868 //Apply constraints to RenderTasks, shaders
869 ConstrainRenderTasks( bufferIndex );
870 ConstrainShaders( bufferIndex );
872 //Update renderers and apply constraints
873 UpdateRenderers( bufferIndex );
875 //Update the transformations of all the nodes
876 mImpl->transformManager.Update();
878 //Process Property Notifications
879 ProcessPropertyNotifications( bufferIndex );
882 for( auto&& cameraIterator : mImpl->cameras )
884 cameraIterator->Update( bufferIndex );
887 //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
888 //reset the update buffer index and make sure there is enough room in the instruction container
889 if( mImpl->renderersAdded )
891 // Calculate how many render tasks we have in total
892 VectorBase::SizeType numberOfRenderTasks = 0;
894 const VectorBase::SizeType taskListCount = mImpl->taskLists.Count();
895 for ( VectorBase::SizeType index = 0u; index < taskListCount; index++ )
897 numberOfRenderTasks += mImpl->taskLists[index]->GetTasks().Count();
900 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
901 static_cast<uint32_t>( numberOfRenderTasks ) );
903 for ( VectorBase::SizeType index = 0u; index < taskListCount; index++ )
905 if ( NULL != mImpl->roots[index] )
907 keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
908 *mImpl->taskLists[index],
909 *mImpl->roots[index],
910 mImpl->sortedLayerLists[index],
911 mImpl->renderInstructions,
919 for( auto taskList : mImpl->taskLists )
921 RenderTaskList::RenderTaskContainer& tasks = taskList->GetTasks();
923 // check the countdown and notify
924 bool doRenderOnceNotify = false;
925 mImpl->renderTaskWaiting = false;
926 for ( auto&& renderTask : tasks )
928 renderTask->UpdateState();
930 if( renderTask->IsWaitingToRender() &&
931 renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
933 mImpl->renderTaskWaiting = true; // keep update/render threads alive
936 if( renderTask->HasRendered() )
938 doRenderOnceNotify = true;
942 if( doRenderOnceNotify )
944 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
945 mImpl->notificationManager.QueueCompleteNotification( taskList->GetCompleteNotificationInterface() );
949 // Macro is undefined in release build.
950 SNAPSHOT_NODE_LOGGING;
952 // A ResetProperties() may be required in the next frame
953 mImpl->previousUpdateScene = updateScene;
955 // Check whether further updates are required
956 uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds );
958 if( keepRendererRendering )
960 keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
963 // tell the update manager that we're done so the queue can be given to event thread
964 mImpl->notificationManager.UpdateCompleted();
966 // The update has finished; swap the double-buffering indices
967 mSceneGraphBuffers.Swap();
972 uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
974 // Update the duration set via Stage::KeepRendering()
975 if ( mImpl->keepRenderingSeconds > 0.0f )
977 mImpl->keepRenderingSeconds -= elapsedSeconds;
980 uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
982 // If the rendering behavior is set to continuously render, then continue to render.
983 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
984 // Keep updating until no messages are received and no animations are running.
985 // If an animation has just finished, update at least once more for Discard end-actions.
986 // No need to check for renderQueue as there is always a render after update and if that
987 // render needs another update it will tell the adaptor to call update again
989 if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
990 ( mImpl->keepRenderingSeconds > 0.0f ) )
992 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
995 if ( IsAnimationRunning() ||
996 mImpl->animationFinishedDuringUpdate )
998 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1001 if ( mImpl->renderTaskWaiting )
1003 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1006 return keepUpdatingRequest;
1009 void UpdateManager::SetBackgroundColor( const Vector4& color )
1011 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1013 // Reserve some memory inside the render queue
1014 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1016 // Construct message in the render queue memory; note that delete should not be called on the return value
1017 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1020 void UpdateManager::SetDefaultSurfaceRect( const Rect<int32_t>& rect )
1022 mImpl->surfaceRectChanged = true;
1024 typedef MessageValue1< RenderManager, Rect<int32_t> > DerivedType;
1026 // Reserve some memory inside the render queue
1027 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1029 // Construct message in the render queue memory; note that delete should not be called on the return value
1030 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1033 void UpdateManager::KeepRendering( float durationSeconds )
1035 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1038 void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
1040 mImpl->renderingBehavior = renderingBehavior;
1043 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
1045 const VectorBase::SizeType rootCount = mImpl->roots.Count();
1047 // Make sure we reserve the correct size for the container so that
1048 // we can save the sorted layers in the same order as the root layer
1049 mImpl->sortedLayerLists.resize( rootCount );
1051 for ( VectorBase::SizeType rootIndex = 0u; rootIndex < rootCount; rootIndex++ )
1053 Layer* root = mImpl->roots[rootIndex];
1054 if ( root == rootLayer )
1056 mImpl->sortedLayerLists[rootIndex] = layers;
1062 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1064 // note,this vector is already in depth order. It could be used as-is to
1065 // remove sorting in update algorithm. However, it lacks layer boundary markers.
1066 for( auto&& iter : nodeDepths->nodeDepths )
1068 iter.node->SetDepthIndex( iter.sortedDepth );
1071 for( auto root : mImpl->roots )
1073 // Go through node hierarchy and rearrange siblings according to depth-index
1074 SortSiblingNodesRecursively( *root );
1078 bool UpdateManager::IsDefaultSurfaceRectChanged()
1080 bool surfaceRectChanged = mImpl->surfaceRectChanged;
1083 mImpl->surfaceRectChanged = false;
1085 return surfaceRectChanged;
1088 void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode )
1090 mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode );
1093 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1095 mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback );
1098 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1100 // Message has ownership of Sampler while in transit from update to render
1101 typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > DerivedType;
1103 // Reserve some memory inside the render queue
1104 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1106 // Construct message in the render queue memory; note that delete should not be called on the return value
1107 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1110 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1112 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1114 // Reserve some memory inside the render queue
1115 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1117 // Construct message in the render queue memory; note that delete should not be called on the return value
1118 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1121 void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
1123 typedef MessageValue3< RenderManager, Render::Sampler*, uint32_t, uint32_t > DerivedType;
1125 // Reserve some memory inside the render queue
1126 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1128 // Construct message in the render queue memory; note that delete should not be called on the return value
1129 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1132 void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
1134 typedef MessageValue4< RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t > DerivedType;
1136 // Reserve some memory inside the render queue
1137 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1139 // Construct message in the render queue memory; note that delete should not be called on the return value
1140 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1143 void UpdateManager::AddPropertyBuffer( OwnerPointer< Render::PropertyBuffer >& propertyBuffer )
1145 // Message has ownership of format while in transit from update -> render
1146 typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
1148 // Reserve some memory inside the render queue
1149 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1151 // Construct message in the render queue memory; note that delete should not be called on the return value
1152 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1155 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1157 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1159 // Reserve some memory inside the render queue
1160 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1162 // Construct message in the render queue memory; note that delete should not be called on the return value
1163 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1166 void UpdateManager::SetPropertyBufferFormat( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Render::PropertyBuffer::Format>& format )
1168 // Message has ownership of format while in transit from update -> render
1169 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType;
1171 // Reserve some memory inside the render queue
1172 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1174 // Construct message in the render queue memory; note that delete should not be called on the return value
1175 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1178 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
1180 // Message has ownership of format while in transit from update -> render
1181 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<uint8_t> >, uint32_t > DerivedType;
1183 // Reserve some memory inside the render queue
1184 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1186 // Construct message in the render queue memory; note that delete should not be called on the return value
1187 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1190 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1192 // Message has ownership of format while in transit from update -> render
1193 typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > DerivedType;
1195 // Reserve some memory inside the render queue
1196 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1198 // Construct message in the render queue memory; note that delete should not be called on the return value
1199 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1202 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1204 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1206 // Reserve some memory inside the render queue
1207 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1209 // Construct message in the render queue memory; note that delete should not be called on the return value
1210 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1213 void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
1215 typedef MessageValue2< RenderManager, Render::Geometry*, uint32_t > DerivedType;
1217 // Reserve some memory inside the render queue
1218 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1220 // Construct message in the render queue memory; note that delete should not be called on the return value
1221 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1224 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
1226 typedef IndexBufferMessage< RenderManager > DerivedType;
1228 // Reserve some memory inside the render queue
1229 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1231 // Construct message in the render queue memory; note that delete should not be called on the return value
1232 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1235 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1237 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1239 // Reserve some memory inside the render queue
1240 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1242 // Construct message in the render queue memory; note that delete should not be called on the return value
1243 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1246 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1248 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1250 // Reserve some memory inside the render queue
1251 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1253 // Construct message in the render queue memory; note that delete should not be called on the return value
1254 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, propertyBuffer );
1257 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1259 // Message has ownership of Texture while in transit from update -> render
1260 typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType;
1262 // Reserve some memory inside the render queue
1263 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1265 // Construct message in the render queue memory; note that delete should not be called on the return value
1266 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1269 void UpdateManager::RemoveTexture( Render::Texture* texture)
1271 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1273 // Reserve some memory inside the render queue
1274 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1276 // Construct message in the render queue memory; note that delete should not be called on the return value
1277 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1280 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1282 typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
1284 // Reserve some memory inside the message queue
1285 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1287 // Construct message in the message queue memory; note that delete should not be called on the return value
1288 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1291 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1293 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1295 // Reserve some memory inside the render queue
1296 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1298 // Construct message in the render queue memory; note that delete should not be called on the return value
1299 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1302 void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
1304 typedef MessageValue1< RenderManager, OwnerPointer< Render::FrameBuffer > > DerivedType;
1306 // Reserve some memory inside the render queue
1307 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1309 // Construct message in the render queue memory; note that delete should not be called on the return value
1310 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1313 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1315 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1317 // Reserve some memory inside the render queue
1318 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1320 // Construct message in the render queue memory; note that delete should not be called on the return value
1321 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1324 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
1326 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t > DerivedType;
1328 // Reserve some memory inside the render queue
1329 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1331 // Construct message in the render queue memory; note that delete should not be called on the return value
1332 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1335 } // namespace SceneGraph
1337 } // namespace Internal