2 * Copyright (c) 2016 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/set-wrapper.h>
24 #include <dali/devel-api/common/owner-container.h>
25 #include <dali/devel-api/threading/mutex.h>
27 #include <dali/integration-api/core.h>
28 #include <dali/integration-api/render-controller.h>
29 #include <dali/internal/common/shader-data.h>
30 #include <dali/integration-api/debug.h>
32 #include <dali/internal/common/core-impl.h>
33 #include <dali/internal/common/message.h>
35 #include <dali/internal/event/common/notification-manager.h>
36 #include <dali/internal/event/common/property-notification-impl.h>
37 #include <dali/internal/event/common/property-notifier.h>
38 #include <dali/internal/event/effects/shader-factory.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/object-owner-container.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/rendering/scene-graph-texture-set.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 int FRAME_COUNT_TRIGGER = 16;\
72 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
74 if ( NULL != mImpl->root )\
76 mImpl->frameCounter = 0;\
77 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
80 mImpl->frameCounter++;
82 #define SNAPSHOT_NODE_LOGGING
85 #if defined(DEBUG_ENABLED)
86 extern Debug::Filter* gRenderTaskLogFilter;
90 using namespace Dali::Integration;
91 using Dali::Internal::Update::MessageQueue;
102 typedef OwnerContainer< Shader* > ShaderContainer;
103 typedef ShaderContainer::Iterator ShaderIter;
104 typedef ShaderContainer::ConstIterator ShaderConstIter;
106 typedef std::vector<Internal::ShaderDataPtr> ShaderDataBinaryQueue;
108 typedef OwnerContainer<PanGesture*> GestureContainer;
109 typedef GestureContainer::Iterator GestureIter;
110 typedef GestureContainer::ConstIterator GestureConstIter;
112 typedef OwnerContainer< TextureSet* > TextureSetContainer;
113 typedef TextureSetContainer::Iterator TextureSetIter;
114 typedef TextureSetContainer::ConstIterator TextureSetConstIter;
117 * Structure to contain UpdateManager internal data
119 struct UpdateManager::Impl
121 Impl( NotificationManager& notificationManager,
122 CompleteNotificationInterface& animationFinishedNotifier,
123 PropertyNotifier& propertyNotifier,
124 DiscardQueue& discardQueue,
125 RenderController& renderController,
126 RenderManager& renderManager,
127 RenderQueue& renderQueue,
128 SceneGraphBuffers& sceneGraphBuffers,
129 RenderTaskProcessor& renderTaskProcessor )
130 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
131 notificationManager( notificationManager ),
133 animationFinishedNotifier( animationFinishedNotifier ),
134 propertyNotifier( propertyNotifier ),
136 discardQueue( discardQueue ),
137 renderController( renderController ),
138 sceneController( NULL ),
139 renderManager( renderManager ),
140 renderQueue( renderQueue ),
141 renderInstructions( renderManager.GetRenderInstructionContainer() ),
142 renderTaskProcessor( renderTaskProcessor ),
143 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
144 taskList( renderMessageDispatcher ),
145 systemLevelTaskList( renderMessageDispatcher ),
147 systemLevelRoot( NULL ),
148 renderers( sceneGraphBuffers, discardQueue ),
150 messageQueue( renderController, sceneGraphBuffers ),
151 keepRenderingSeconds( 0.0f ),
152 animationFinishedDuringUpdate( false ),
153 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
154 previousUpdateScene( false ),
156 renderTaskWaiting( false )
158 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
160 renderers.SetSceneController( *sceneController );
162 // create first 'dummy' node
168 // Disconnect render tasks from nodes, before destroying the nodes
169 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
170 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
172 (*iter)->SetSourceNode( NULL );
174 // ..repeat for system level RenderTasks
175 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
176 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
178 (*iter)->SetSourceNode( NULL );
181 // UpdateManager owns the Nodes
182 Vector<Node*>::Iterator iter = nodes.Begin()+1;
183 Vector<Node*>::Iterator endIter = nodes.End();
184 for(;iter!=endIter;++iter)
186 (*iter)->OnDestroy();
190 // If there is root, reset it, otherwise do nothing as rendering was never started
195 Node::Delete( root );
199 if( systemLevelRoot )
201 systemLevelRoot->OnDestroy();
203 Node::Delete( systemLevelRoot );
204 systemLevelRoot = NULL;
207 delete sceneController;
210 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
211 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
212 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
213 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
214 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
215 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
216 ShaderSaver* shaderSaver; ///< Saves shader binaries.
217 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
218 RenderController& renderController; ///< render controller
219 SceneControllerImpl* sceneController; ///< scene controller
220 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
221 RenderQueue& renderQueue; ///< Used to queue messages for the next render
222 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
223 RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
225 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
227 RenderTaskList taskList; ///< The list of scene graph render-tasks
228 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
230 Layer* root; ///< The root node (root is a layer)
231 Layer* systemLevelRoot; ///< A separate root-node for system-level content
233 Vector<Node*> nodes; ///< A container of all instantiated nodes
235 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
236 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
238 OwnerContainer< Camera* > cameras; ///< A container of cameras
239 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
241 AnimationContainer animations; ///< A container of owned animations
242 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
244 ObjectOwnerContainer<Renderer> renderers;
245 TextureSetContainer textureSets; ///< A container of texture sets
247 ShaderContainer shaders; ///< A container of owned shaders
249 MessageQueue messageQueue; ///< The messages queued from the event-thread
250 ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
251 ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event
252 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
254 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
255 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
257 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
258 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
260 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
262 GestureContainer gestures; ///< A container of owned gesture detectors
263 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
267 Impl( const Impl& ); ///< Undefined
268 Impl& operator=( const Impl& ); ///< Undefined
271 UpdateManager::UpdateManager( NotificationManager& notificationManager,
272 CompleteNotificationInterface& animationFinishedNotifier,
273 PropertyNotifier& propertyNotifier,
274 DiscardQueue& discardQueue,
275 RenderController& controller,
276 RenderManager& renderManager,
277 RenderQueue& renderQueue,
278 RenderTaskProcessor& renderTaskProcessor )
281 mImpl = new Impl( notificationManager,
282 animationFinishedNotifier,
289 renderTaskProcessor );
293 UpdateManager::~UpdateManager()
298 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
300 DALI_ASSERT_DEBUG( layer->IsLayer() );
301 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
305 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
307 mImpl->root->CreateTransform( &mImpl->transformManager );
311 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
312 mImpl->systemLevelRoot = layer;
313 mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager );
316 layer->SetRoot(true);
319 void UpdateManager::AddNode( Node* node )
321 DALI_ASSERT_ALWAYS( NULL != node );
322 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
324 // Nodes must be sorted by pointer
325 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
326 for(Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter)
330 mImpl->nodes.Insert((iter+1), node);
331 node->CreateTransform( &mImpl->transformManager );
337 void UpdateManager::ConnectNode( Node* parent, Node* node )
339 DALI_ASSERT_ALWAYS( NULL != parent );
340 DALI_ASSERT_ALWAYS( NULL != node );
341 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
343 parent->ConnectChild( node );
346 void UpdateManager::DisconnectNode( Node* node )
348 Node* parent = node->GetParent();
349 DALI_ASSERT_ALWAYS( NULL != parent );
350 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
352 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
355 void UpdateManager::DestroyNode( Node* node )
357 DALI_ASSERT_ALWAYS( NULL != node );
358 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
360 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
361 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
362 for(;iter!=endIter;++iter)
366 mImpl->nodes.Erase(iter);
371 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
373 // Notify the Node about impending destruction
377 void UpdateManager::AddCamera( Camera* camera )
379 DALI_ASSERT_DEBUG( camera != NULL );
381 mImpl->cameras.PushBack( camera ); // takes ownership
384 void UpdateManager::RemoveCamera( const Camera* camera )
387 OwnerContainer<Camera*>::Iterator iter = mImpl->cameras.Begin();
388 OwnerContainer<Camera*>::ConstIterator end = mImpl->cameras.End();
389 for ( ; iter != end; ++iter )
391 Camera* value = *iter;
392 if ( camera == value )
394 // Transfer ownership to the discard queue
395 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->cameras.Release( iter ) );
403 void UpdateManager::AddObject( PropertyOwner* object )
405 DALI_ASSERT_DEBUG( NULL != object );
407 mImpl->customObjects.PushBack( object );
410 void UpdateManager::RemoveObject( PropertyOwner* object )
412 DALI_ASSERT_DEBUG( NULL != object );
414 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
416 // Find the object and destroy it
417 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
419 PropertyOwner* current = *iter;
420 if ( current == object )
422 customObjects.Erase( iter );
427 // Should not reach here
428 DALI_ASSERT_DEBUG(false);
431 void UpdateManager::AddAnimation( Animation* animation )
433 mImpl->animations.PushBack( animation );
436 void UpdateManager::StopAnimation( Animation* animation )
438 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
440 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
442 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
445 void UpdateManager::RemoveAnimation( Animation* animation )
447 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
449 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
451 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
454 bool UpdateManager::IsAnimationRunning() const
456 bool isRunning(false);
457 AnimationContainer& animations = mImpl->animations;
459 // Find any animation that isn't stopped or paused
461 const AnimationIter endIter = animations.End();
462 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
464 const Animation::State state = (*iter)->GetState();
466 if (state != Animation::Stopped &&
467 state != Animation::Paused)
476 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
478 mImpl->propertyNotifications.PushBack( propertyNotification );
481 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
483 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
484 PropertyNotificationIter iter = propertyNotifications.Begin();
486 while ( iter != propertyNotifications.End() )
488 if( *iter == propertyNotification )
490 propertyNotifications.Erase(iter);
497 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
499 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
500 propertyNotification->SetNotifyMode( notifyMode );
503 ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
505 return mImpl->renderers;
508 void UpdateManager::AddShader( Shader* shader )
510 DALI_ASSERT_DEBUG( NULL != shader );
512 if( mImpl->shaders.Count() == 0 )
514 // the first added shader becomes our default shader
515 // Construct message in the render queue memory; note that delete should not be called on the return value
516 typedef MessageValue1< RenderManager, Shader* > DerivedType;
518 // Reserve some memory inside the render queue
519 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
521 // Construct message in the render queue memory; note that delete should not be called on the return value
522 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
525 mImpl->shaders.PushBack( shader );
528 void UpdateManager::RemoveShader( Shader* shader )
530 DALI_ASSERT_DEBUG(shader != NULL);
532 ShaderContainer& shaders = mImpl->shaders;
534 // Find the shader and destroy it
535 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
537 Shader& current = **iter;
538 if ( ¤t == shader )
540 // Transfer ownership to the discard queue
541 // This keeps the shader alive, until the render-thread has finished with it
542 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
547 // Should not reach here
548 DALI_ASSERT_DEBUG(false);
551 void UpdateManager::SetShaderProgram( Shader* shader,
552 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
557 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
559 // Reserve some memory inside the render queue
560 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
562 // Construct message in the render queue memory; note that delete should not be called on the return value
563 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
567 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
569 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
570 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
572 // lock as update might be sending previously compiled shaders to event thread
573 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
574 mImpl->renderCompiledShaders.push_back( shaderData );
578 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
582 // copy the list, this is only likely to happen once in application life cycle
583 return &(mImpl->taskList);
587 // copy the list, this is only likely to happen once in application life cycle
588 return &(mImpl->systemLevelTaskList);
592 void UpdateManager::AddGesture( PanGesture* gesture )
594 DALI_ASSERT_DEBUG( NULL != gesture );
596 mImpl->gestures.PushBack( gesture );
599 void UpdateManager::RemoveGesture( PanGesture* gesture )
601 DALI_ASSERT_DEBUG( gesture != NULL );
603 GestureContainer& gestures = mImpl->gestures;
605 // Find the gesture and destroy it
606 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
608 PanGesture& current = **iter;
609 if ( ¤t == gesture )
611 mImpl->gestures.Erase( iter );
615 // Should not reach here
616 DALI_ASSERT_DEBUG(false);
619 void UpdateManager::AddTextureSet( TextureSet* textureSet )
621 DALI_ASSERT_DEBUG( NULL != textureSet );
622 mImpl->textureSets.PushBack( textureSet );
625 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
627 DALI_ASSERT_DEBUG(textureSet != NULL);
628 size_t textureSetCount( mImpl->textureSets.Size() );
629 for( size_t i(0); i<textureSetCount; ++i )
631 if( textureSet == mImpl->textureSets[i] )
633 mImpl->textureSets.Remove( mImpl->textureSets.Begin() + i );
639 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
641 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
644 void UpdateManager::EventProcessingStarted()
646 mImpl->messageQueue.EventProcessingStarted();
649 bool UpdateManager::FlushQueue()
651 return mImpl->messageQueue.FlushQueue();
654 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
656 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
657 mImpl->animationFinishedDuringUpdate = false;
659 // Animated properties have to be reset to their original value each frame
661 // Reset root properties
664 mImpl->root->ResetToBaseValues( bufferIndex );
666 if ( mImpl->systemLevelRoot )
668 mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
671 // Reset all the nodes
672 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
673 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
674 for(;iter != endIter; ++iter)
676 (*iter)->ResetToBaseValues( bufferIndex );
679 // Reset system-level render-task list properties to base values
680 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
682 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
684 (*iter)->ResetToBaseValues( bufferIndex );
687 // Reset render-task list properties to base values.
688 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
690 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
692 (*iter)->ResetToBaseValues( bufferIndex );
695 // Reset custom object properties to base values
696 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
698 (*iter)->ResetToBaseValues( bufferIndex );
701 mImpl->renderers.ResetToBaseValues( bufferIndex );
703 // Reset animatable shader properties to base values
704 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
706 (*iter)->ResetToBaseValues( bufferIndex );
710 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
712 bool gestureUpdated( false );
714 // constrain gestures... (in construction order)
715 GestureContainer& gestures = mImpl->gestures;
717 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
719 PanGesture& gesture = **iter;
720 gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
721 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
724 return gestureUpdated;
727 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
729 AnimationContainer &animations = mImpl->animations;
730 AnimationIter iter = animations.Begin();
731 bool animationLooped = false;
732 while ( iter != animations.End() )
734 Animation* animation = *iter;
735 bool finished = false;
737 animation->Update( bufferIndex, elapsedSeconds, looped, finished );
739 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
740 animationLooped = animationLooped || looped;
742 // Remove animations that had been destroyed but were still waiting for an update
743 if (animation->GetState() == Animation::Destroyed)
745 iter = animations.Erase(iter);
753 // queue the notification on finished or looped (to update loop count)
754 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
756 // The application should be notified by NotificationManager, in another thread
757 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
761 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
763 //Constrain custom objects (in construction order)
764 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
765 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
766 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
768 PropertyOwner& object = **iter;
769 ConstrainPropertyOwner( object, bufferIndex );
773 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
775 // Constrain system-level render-tasks
776 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
777 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
779 RenderTask& task = **iter;
780 ConstrainPropertyOwner( task, bufferIndex );
783 // Constrain render-tasks
784 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
785 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
787 RenderTask& task = **iter;
788 ConstrainPropertyOwner( task, bufferIndex );
792 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
794 // constrain shaders... (in construction order)
795 ShaderContainer& shaders = mImpl->shaders;
796 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
798 Shader& shader = **iter;
799 ConstrainPropertyOwner( shader, bufferIndex );
803 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
805 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
806 PropertyNotificationIter iter = notifications.Begin();
808 while ( iter != notifications.End() )
810 PropertyNotification* notification = *iter;
811 bool valid = notification->Check( bufferIndex );
814 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
820 void UpdateManager::ForwardCompiledShadersToEventThread()
822 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
823 if( mImpl->shaderSaver )
825 // lock and swap the queues
827 // render might be attempting to send us more binaries at the same time
828 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
829 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
832 if( mImpl->updateCompiledShaders.size() > 0 )
834 ShaderSaver& factory = *mImpl->shaderSaver;
835 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
836 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
837 for( ; i != end; ++i )
839 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
841 // we don't need them in update anymore
842 mImpl->updateCompiledShaders.clear();
847 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
849 const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
850 unsigned int rendererCount( rendererContainer.Size() );
851 for( unsigned int i(0); i<rendererCount; ++i )
854 ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
856 rendererContainer[i]->PrepareRender( bufferIndex );
860 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
862 mImpl->nodeDirtyFlags = NothingFlag;
869 // Prepare resources, update shaders, for each node
870 // And add the renderers to the sorted layers. Start from root, which is also a layer
871 mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
873 mImpl->renderQueue );
875 if ( mImpl->systemLevelRoot )
877 mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
879 mImpl->renderQueue );
883 unsigned int UpdateManager::Update( float elapsedSeconds,
884 unsigned int lastVSyncTimeMilliseconds,
885 unsigned int nextVSyncTimeMilliseconds )
887 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
889 //Clear nodes/resources which were previously discarded
890 mImpl->discardQueue.Clear( bufferIndex );
892 //Process Touches & Gestures
893 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
895 const bool updateScene = // The scene-graph requires an update if..
896 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
897 IsAnimationRunning() || // ..at least one animation is running OR
898 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
899 gestureUpdated; // ..a gesture property was updated
902 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
903 // values if the scene was updated in the previous frame.
904 if( updateScene || mImpl->previousUpdateScene )
906 //Reset properties from the previous update
907 ResetProperties( bufferIndex );
908 mImpl->transformManager.ResetToBaseValue();
911 //Process the queued scene messages
912 mImpl->messageQueue.ProcessMessages( bufferIndex );
914 //Forward compiled shader programs to event thread for saving
915 ForwardCompiledShadersToEventThread();
917 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
918 // renderer lists if the scene was updated in the previous frame.
919 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
920 if( updateScene || mImpl->previousUpdateScene )
923 Animate( bufferIndex, elapsedSeconds );
925 //Constraint custom objects
926 ConstrainCustomObjects( bufferIndex );
928 //Clear the lists of renderers from the previous update
929 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
931 mImpl->sortedLayers[i]->ClearRenderables();
934 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
936 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
939 //Update node hierarchy, apply constraints and perform sorting / culling.
940 //This will populate each Layer with a list of renderers which are ready.
941 UpdateNodes( bufferIndex );
943 //Apply constraints to RenderTasks, shaders
944 ConstrainRenderTasks( bufferIndex );
945 ConstrainShaders( bufferIndex );
947 //Update renderers and apply constraints
948 UpdateRenderers( bufferIndex );
950 //Update the trnasformations of all the nodes
951 mImpl->transformManager.Update();
953 //Process Property Notifications
954 ProcessPropertyNotifications( bufferIndex );
956 //Process the RenderTasks; this creates the instructions for rendering the next frame.
957 //reset the update buffer index and make sure there is enough room in the instruction container
958 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
959 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
961 if ( NULL != mImpl->root )
963 mImpl->renderTaskProcessor.Process( bufferIndex,
967 mImpl->renderInstructions );
969 // Process the system-level RenderTasks last
970 if ( NULL != mImpl->systemLevelRoot )
972 mImpl->renderTaskProcessor.Process( bufferIndex,
973 mImpl->systemLevelTaskList,
974 *mImpl->systemLevelRoot,
975 mImpl->systemLevelSortedLayers,
976 mImpl->renderInstructions );
981 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
982 bool doRenderOnceNotify = false;
983 mImpl->renderTaskWaiting = false;
984 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
985 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
986 endIter != iter; ++iter )
988 RenderTask& renderTask(*(*iter));
990 renderTask.UpdateState();
992 if( renderTask.IsWaitingToRender() &&
993 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
995 mImpl->renderTaskWaiting = true; // keep update/render threads alive
998 if( renderTask.HasRendered() )
1000 doRenderOnceNotify = true;
1004 if( doRenderOnceNotify )
1006 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1007 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1010 // Macro is undefined in release build.
1011 SNAPSHOT_NODE_LOGGING;
1013 // A ResetProperties() may be required in the next frame
1014 mImpl->previousUpdateScene = updateScene;
1016 // Check whether further updates are required
1017 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1019 // tell the update manager that we're done so the queue can be given to event thread
1020 mImpl->notificationManager.UpdateCompleted();
1022 // The update has finished; swap the double-buffering indices
1023 mSceneGraphBuffers.Swap();
1025 return keepUpdating;
1028 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1030 // Update the duration set via Stage::KeepRendering()
1031 if ( mImpl->keepRenderingSeconds > 0.0f )
1033 mImpl->keepRenderingSeconds -= elapsedSeconds;
1036 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1038 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1039 // Keep updating until no messages are received and no animations are running.
1040 // If an animation has just finished, update at least once more for Discard end-actions.
1041 // No need to check for renderQueue as there is always a render after update and if that
1042 // render needs another update it will tell the adaptor to call update again
1044 if ( mImpl->keepRenderingSeconds > 0.0f )
1046 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1049 if ( IsAnimationRunning() ||
1050 mImpl->animationFinishedDuringUpdate )
1052 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1055 if ( mImpl->renderTaskWaiting )
1057 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1060 return keepUpdatingRequest;
1063 void UpdateManager::SetBackgroundColor( const Vector4& color )
1065 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1067 // Reserve some memory inside the render queue
1068 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1070 // Construct message in the render queue memory; note that delete should not be called on the return value
1071 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1074 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1076 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1078 // Reserve some memory inside the render queue
1079 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1081 // Construct message in the render queue memory; note that delete should not be called on the return value
1082 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1085 void UpdateManager::KeepRendering( float durationSeconds )
1087 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1090 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1094 // just copy the vector of pointers
1095 mImpl->sortedLayers = layers;
1099 mImpl->systemLevelSortedLayers = layers;
1103 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1105 mImpl->shaderSaver = &upstream;
1108 void UpdateManager::AddSampler( Render::Sampler* sampler )
1110 // Message has ownership of Sampler while in transit from update to render
1111 typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > DerivedType;
1113 // Reserve some memory inside the render queue
1114 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1116 // Construct message in the render queue memory; note that delete should not be called on the return value
1117 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1120 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1122 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1124 // Reserve some memory inside the render queue
1125 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1127 // Construct message in the render queue memory; note that delete should not be called on the return value
1128 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1131 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1133 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1135 // Reserve some memory inside the render queue
1136 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1138 // Construct message in the render queue memory; note that delete should not be called on the return value
1139 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1142 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
1144 typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > DerivedType;
1146 // Reserve some memory inside the render queue
1147 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1149 // Construct message in the render queue memory; note that delete should not be called on the return value
1150 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1153 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1155 // Message has ownership of format while in transit from update -> render
1156 typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
1158 // Reserve some memory inside the render queue
1159 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1161 // Construct message in the render queue memory; note that delete should not be called on the return value
1162 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1165 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1167 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1169 // Reserve some memory inside the render queue
1170 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1172 // Construct message in the render queue memory; note that delete should not be called on the return value
1173 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1176 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1178 // Message has ownership of format while in transit from update -> render
1179 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType;
1181 // Reserve some memory inside the render queue
1182 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1184 // Construct message in the render queue memory; note that delete should not be called on the return value
1185 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1188 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data, size_t size )
1190 // Message has ownership of format while in transit from update -> render
1191 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<char> >, size_t > DerivedType;
1193 // Reserve some memory inside the render queue
1194 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1196 // Construct message in the render queue memory; note that delete should not be called on the return value
1197 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1200 void UpdateManager::AddGeometry( Render::Geometry* geometry )
1202 // Message has ownership of format while in transit from update -> render
1203 typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > DerivedType;
1205 // Reserve some memory inside the render queue
1206 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1208 // Construct message in the render queue memory; note that delete should not be called on the return value
1209 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1212 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1214 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1216 // Reserve some memory inside the render queue
1217 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1219 // Construct message in the render queue memory; note that delete should not be called on the return value
1220 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1223 void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
1225 typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType;
1227 // Reserve some memory inside the render queue
1228 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1230 // Construct message in the render queue memory; note that delete should not be called on the return value
1231 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1234 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
1236 typedef IndexBufferMessage< RenderManager > DerivedType;
1238 // Reserve some memory inside the render queue
1239 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1241 // Construct message in the render queue memory; note that delete should not be called on the return value
1242 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1245 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1247 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1249 // Reserve some memory inside the render queue
1250 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1252 // Construct message in the render queue memory; note that delete should not be called on the return value
1253 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1256 void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1258 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1260 // Reserve some memory inside the render queue
1261 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1263 // Construct message in the render queue memory; note that delete should not be called on the return value
1264 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, geometry, propertyBuffer );
1267 void UpdateManager::AddTexture( Render::Texture* texture )
1269 // Message has ownership of Texture while in transit from update -> render
1270 typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType;
1272 // Reserve some memory inside the render queue
1273 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1275 // Construct message in the render queue memory; note that delete should not be called on the return value
1276 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1279 void UpdateManager::RemoveTexture( Render::Texture* texture)
1281 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1283 // Reserve some memory inside the render queue
1284 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1286 // Construct message in the render queue memory; note that delete should not be called on the return value
1287 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1290 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1292 typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
1294 // Reserve some memory inside the message queue
1295 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1297 // Construct message in the message queue memory; note that delete should not be called on the return value
1298 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1301 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1303 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1305 // Reserve some memory inside the render queue
1306 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1308 // Construct message in the render queue memory; note that delete should not be called on the return value
1309 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1312 void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
1314 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1316 // Reserve some memory inside the render queue
1317 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1319 // Construct message in the render queue memory; note that delete should not be called on the return value
1320 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1323 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1325 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1327 // Reserve some memory inside the render queue
1328 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1330 // Construct message in the render queue memory; note that delete should not be called on the return value
1331 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1334 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, unsigned int mipmapLevel, unsigned int layer )
1336 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, unsigned int, unsigned int > DerivedType;
1338 // Reserve some memory inside the render queue
1339 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1341 // Construct message in the render queue memory; note that delete should not be called on the return value
1342 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1345 } // namespace SceneGraph
1347 } // namespace Internal