2 * Copyright (c) 2017 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/render-task-processor.h>
48 #include <dali/internal/update/manager/sorted-layers.h>
49 #include <dali/internal/update/manager/update-algorithms.h>
50 #include <dali/internal/update/manager/update-manager-debug.h>
51 #include <dali/internal/update/manager/transform-manager.h>
52 #include <dali/internal/update/nodes/node.h>
53 #include <dali/internal/update/nodes/scene-graph-layer.h>
54 #include <dali/internal/update/queue/update-message-queue.h>
55 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
56 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
57 #include <dali/internal/update/render-tasks/scene-graph-camera.h>
59 #include <dali/internal/render/common/render-instruction-container.h>
60 #include <dali/internal/render/common/render-manager.h>
61 #include <dali/internal/render/queue/render-queue.h>
62 #include <dali/internal/render/shaders/scene-graph-shader.h>
64 // Un-comment to enable node tree debug logging
65 //#define NODE_TREE_LOGGING 1
67 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
68 #define SNAPSHOT_NODE_LOGGING \
69 const int FRAME_COUNT_TRIGGER = 16;\
70 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
72 if ( NULL != mImpl->root )\
74 mImpl->frameCounter = 0;\
75 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
78 mImpl->frameCounter++;
80 #define SNAPSHOT_NODE_LOGGING
83 #if defined(DEBUG_ENABLED)
84 extern Debug::Filter* gRenderTaskLogFilter;
88 using namespace Dali::Integration;
89 using Dali::Internal::Update::MessageQueue;
103 * Helper to reset animate-able objects to base values
104 * @param container to iterate over
105 * @param updateBufferIndex to use
108 inline void ResetToBaseValues( OwnerContainer<T*>& container, BufferIndex updateBufferIndex )
110 // Reset animatable properties to base values
111 typename OwnerContainer<T*>::Iterator iter = container.Begin();
112 const typename OwnerContainer<T*>::ConstIterator endIter = container.End();
113 for ( ; iter != endIter; ++iter )
115 (*iter)->ResetToBaseValues( updateBufferIndex );
120 * Helper to Erase an object from OwnerContainer using discard queue
121 * @param container to remove from
122 * @param object to remove
123 * @param discardQueue to put the object to
124 * @param updateBufferIndex to use
127 inline void EraseUsingDiscardQueue( OwnerContainer<T*>& container, T* object, DiscardQueue& discardQueue, BufferIndex updateBufferIndex )
129 typename OwnerContainer<T*>::Iterator iter = container.Begin();
130 const typename OwnerContainer<T*>::ConstIterator endIter = container.End();
131 for ( ; iter != endIter; ++iter )
133 if ( *iter == object )
135 // Transfer ownership to the discard queue, this keeps the object alive, until the render-thread has finished with it
136 discardQueue.Add( updateBufferIndex, container.Release( iter ) );
144 typedef OwnerContainer< Shader* > ShaderOwner;
145 typedef ShaderOwner::Iterator ShaderIter;
146 typedef std::vector<Internal::ShaderDataPtr> ShaderDataBinaryQueue;
148 typedef OwnerContainer< TextureSet* > TextureSetOwner;
149 typedef TextureSetOwner::Iterator TextureSetIter;
151 typedef OwnerContainer<Renderer*> RendererOwner;
152 typedef RendererOwner::Iterator RendererIter;
154 typedef OwnerContainer< Camera* > CameraOwner;
155 typedef OwnerContainer< PropertyOwner* > CustomObjectOwner;
158 * Structure to contain UpdateManager internal data
160 struct UpdateManager::Impl
162 Impl( NotificationManager& notificationManager,
163 CompleteNotificationInterface& animationFinishedNotifier,
164 PropertyNotifier& propertyNotifier,
165 DiscardQueue& discardQueue,
166 RenderController& renderController,
167 RenderManager& renderManager,
168 RenderQueue& renderQueue,
169 SceneGraphBuffers& sceneGraphBuffers,
170 RenderTaskProcessor& renderTaskProcessor )
171 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
172 notificationManager( notificationManager ),
174 animationFinishedNotifier( animationFinishedNotifier ),
175 propertyNotifier( propertyNotifier ),
177 discardQueue( discardQueue ),
178 renderController( renderController ),
179 sceneController( NULL ),
180 renderManager( renderManager ),
181 renderQueue( renderQueue ),
182 renderInstructions( renderManager.GetRenderInstructionContainer() ),
183 renderTaskProcessor( renderTaskProcessor ),
184 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
185 taskList( renderMessageDispatcher ),
186 systemLevelTaskList( renderMessageDispatcher ),
188 systemLevelRoot( NULL ),
192 panGestureProcessor( NULL ),
193 messageQueue( renderController, sceneGraphBuffers ),
194 keepRenderingSeconds( 0.0f ),
195 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
197 animationFinishedDuringUpdate( false ),
198 previousUpdateScene( false ),
199 renderTaskWaiting( false )
201 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
203 // create first 'dummy' node
209 // Disconnect render tasks from nodes, before destroying the nodes
210 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
211 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
213 (*iter)->SetSourceNode( NULL );
215 // ..repeat for system level RenderTasks
216 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
217 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
219 (*iter)->SetSourceNode( NULL );
222 // UpdateManager owns the Nodes
223 Vector<Node*>::Iterator iter = nodes.Begin()+1;
224 Vector<Node*>::Iterator endIter = nodes.End();
225 for(;iter!=endIter;++iter)
227 (*iter)->OnDestroy();
231 // If there is root, reset it, otherwise do nothing as rendering was never started
236 Node::Delete( root );
240 if( systemLevelRoot )
242 systemLevelRoot->OnDestroy();
244 Node::Delete( systemLevelRoot );
245 systemLevelRoot = NULL;
248 delete sceneController;
251 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
252 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
253 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
254 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
255 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
256 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
257 ShaderSaver* shaderSaver; ///< Saves shader binaries.
258 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
259 RenderController& renderController; ///< render controller
260 SceneControllerImpl* sceneController; ///< scene controller
261 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
262 RenderQueue& renderQueue; ///< Used to queue messages for the next render
263 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
264 RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
266 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
268 RenderTaskList taskList; ///< The list of scene graph render-tasks
269 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
271 Layer* root; ///< The root node (root is a layer)
272 Layer* systemLevelRoot; ///< A separate root-node for system-level content
274 Vector<Node*> nodes; ///< A container of all instantiated nodes
276 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
277 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
279 CameraOwner cameras; ///< A container of cameras
280 CustomObjectOwner customObjects; ///< A container of owned objects (with custom properties)
282 AnimationContainer animations; ///< A container of owned animations
283 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
285 RendererOwner renderers; ///< A container of owned renderers
286 TextureSetOwner textureSets; ///< A container of owned texture sets
287 ShaderOwner shaders; ///< A container of owned shaders
288 OwnerPointer<PanGesture> panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager
290 MessageQueue messageQueue; ///< The messages queued from the event-thread
291 ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
292 ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event
293 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
295 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
296 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
297 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
299 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
300 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
301 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
305 Impl( const Impl& ); ///< Undefined
306 Impl& operator=( const Impl& ); ///< Undefined
309 UpdateManager::UpdateManager( NotificationManager& notificationManager,
310 CompleteNotificationInterface& animationFinishedNotifier,
311 PropertyNotifier& propertyNotifier,
312 DiscardQueue& discardQueue,
313 RenderController& controller,
314 RenderManager& renderManager,
315 RenderQueue& renderQueue,
316 RenderTaskProcessor& renderTaskProcessor )
319 mImpl = new Impl( notificationManager,
320 animationFinishedNotifier,
327 renderTaskProcessor );
331 UpdateManager::~UpdateManager()
336 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
338 DALI_ASSERT_DEBUG( layer->IsLayer() );
339 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
343 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
345 mImpl->root->CreateTransform( &mImpl->transformManager );
349 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
350 mImpl->systemLevelRoot = layer;
351 mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager );
354 layer->SetRoot(true);
357 void UpdateManager::AddNode( Node* node )
359 DALI_ASSERT_ALWAYS( NULL != node );
360 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
362 // Nodes must be sorted by pointer
363 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
364 for(Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter)
368 mImpl->nodes.Insert((iter+1), node);
369 node->CreateTransform( &mImpl->transformManager );
375 void UpdateManager::ConnectNode( Node* parent, Node* node )
377 DALI_ASSERT_ALWAYS( NULL != parent );
378 DALI_ASSERT_ALWAYS( NULL != node );
379 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
381 parent->ConnectChild( node );
384 void UpdateManager::DisconnectNode( Node* node )
386 Node* parent = node->GetParent();
387 DALI_ASSERT_ALWAYS( NULL != parent );
388 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
390 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
393 void UpdateManager::DestroyNode( Node* node )
395 DALI_ASSERT_ALWAYS( NULL != node );
396 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
398 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
399 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
400 for(;iter!=endIter;++iter)
404 mImpl->nodes.Erase(iter);
409 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
411 // Notify the Node about impending destruction
415 void UpdateManager::AddCamera( Camera* camera )
417 DALI_ASSERT_DEBUG( camera != NULL );
419 mImpl->cameras.PushBack( camera ); // takes ownership
422 void UpdateManager::RemoveCamera( const Camera* camera )
424 // Find the camera and destroy it
425 EraseUsingDiscardQueue( mImpl->cameras, const_cast<Camera*>( camera ), mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
428 void UpdateManager::AddObject( PropertyOwner* object )
430 DALI_ASSERT_DEBUG( NULL != object );
432 mImpl->customObjects.PushBack( object );
435 void UpdateManager::RemoveObject( PropertyOwner* object )
437 DALI_ASSERT_DEBUG( NULL != object );
439 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
441 // Find the object and destroy it
442 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
444 PropertyOwner* current = *iter;
445 if ( current == object )
447 customObjects.Erase( iter );
452 // Should not reach here
453 DALI_ASSERT_DEBUG(false);
456 void UpdateManager::AddAnimation( Animation* animation )
458 mImpl->animations.PushBack( animation );
461 void UpdateManager::StopAnimation( Animation* animation )
463 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
465 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
467 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
470 void UpdateManager::RemoveAnimation( Animation* animation )
472 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
474 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
476 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
479 bool UpdateManager::IsAnimationRunning() const
481 bool isRunning(false);
482 AnimationContainer& animations = mImpl->animations;
484 // Find any animation that isn't stopped or paused
486 const AnimationIter endIter = animations.End();
487 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
489 const Animation::State state = (*iter)->GetState();
491 if (state != Animation::Stopped &&
492 state != Animation::Paused)
501 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
503 mImpl->propertyNotifications.PushBack( propertyNotification );
506 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
508 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
509 PropertyNotificationIter iter = propertyNotifications.Begin();
511 while ( iter != propertyNotifications.End() )
513 if( *iter == propertyNotification )
515 propertyNotifications.Erase(iter);
522 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
524 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
525 propertyNotification->SetNotifyMode( notifyMode );
528 void UpdateManager::AddShader( Shader* shader )
530 DALI_ASSERT_DEBUG( NULL != shader );
532 mImpl->shaders.PushBack( shader );
535 void UpdateManager::RemoveShader( Shader* shader )
537 DALI_ASSERT_DEBUG(shader != NULL);
539 // Find the shader and destroy it
540 EraseUsingDiscardQueue( mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
543 void UpdateManager::SetShaderProgram( Shader* shader,
544 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
549 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
551 // Reserve some memory inside the render queue
552 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
554 // Construct message in the render queue memory; note that delete should not be called on the return value
555 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
559 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
561 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
562 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
564 // lock as update might be sending previously compiled shaders to event thread
565 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
566 mImpl->renderCompiledShaders.push_back( shaderData );
570 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
572 mImpl->shaderSaver = &upstream;
575 void UpdateManager::AddRenderer( Renderer* renderer )
577 DALI_ASSERT_DEBUG( renderer != NULL );
579 mImpl->renderers.PushBack( renderer );
581 renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
584 void UpdateManager::RemoveRenderer( Renderer* renderer )
586 DALI_ASSERT_DEBUG( renderer != NULL );
588 renderer->DisconnectFromSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
590 // Find the renderer and destroy it
591 EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
594 void UpdateManager::SetPanGestureProcessor( PanGesture* panGestureProcessor )
596 DALI_ASSERT_DEBUG( NULL != panGestureProcessor );
598 mImpl->panGestureProcessor = panGestureProcessor;
601 void UpdateManager::AddTextureSet( TextureSet* textureSet )
603 DALI_ASSERT_DEBUG( NULL != textureSet );
604 mImpl->textureSets.PushBack( textureSet );
607 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
609 DALI_ASSERT_DEBUG( textureSet != NULL );
611 // Find the texture and destroy it
612 TextureSetOwner& textures = mImpl->textureSets;
613 for ( TextureSetIter iter = textures.Begin(), endIter = textures.End(); iter != endIter; ++iter )
615 if ( *iter == textureSet )
617 textures.Erase( iter );
623 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
627 // copy the list, this is only likely to happen once in application life cycle
628 return &(mImpl->taskList);
632 // copy the list, this is only likely to happen once in application life cycle
633 return &(mImpl->systemLevelTaskList);
637 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
639 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
642 void UpdateManager::EventProcessingStarted()
644 mImpl->messageQueue.EventProcessingStarted();
647 bool UpdateManager::FlushQueue()
649 return mImpl->messageQueue.FlushQueue();
652 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
654 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
655 mImpl->animationFinishedDuringUpdate = false;
657 // Animated properties have to be reset to their original value each frame
659 // Reset root properties
662 mImpl->root->ResetToBaseValues( bufferIndex );
664 if ( mImpl->systemLevelRoot )
666 mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
669 // Reset all the nodes
670 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
671 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
672 for( ;iter != endIter; ++iter )
674 (*iter)->ResetToBaseValues( bufferIndex );
677 // Reset system-level render-task list properties to base values
678 ResetToBaseValues( mImpl->systemLevelTaskList.GetTasks(), bufferIndex );
680 // Reset render-task list properties to base values.
681 ResetToBaseValues( mImpl->taskList.GetTasks(), bufferIndex );
683 // Reset custom object properties to base values
684 ResetToBaseValues( mImpl->customObjects, bufferIndex );
686 // Reset animatable renderer properties to base values
687 ResetToBaseValues( mImpl->renderers, bufferIndex );
689 // Reset animatable shader properties to base values
690 ResetToBaseValues( mImpl->shaders, bufferIndex );
693 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
695 bool gestureUpdated( false );
697 if( mImpl->panGestureProcessor )
699 // gesture processor only supports default properties
700 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
701 gestureUpdated |= mImpl->panGestureProcessor->UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
704 return gestureUpdated;
707 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
709 AnimationContainer &animations = mImpl->animations;
710 AnimationIter iter = animations.Begin();
711 bool animationLooped = false;
712 while ( iter != animations.End() )
714 Animation* animation = *iter;
715 bool finished = false;
717 animation->Update( bufferIndex, elapsedSeconds, looped, finished );
719 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
720 animationLooped = animationLooped || looped;
722 // Remove animations that had been destroyed but were still waiting for an update
723 if (animation->GetState() == Animation::Destroyed)
725 iter = animations.Erase(iter);
733 // queue the notification on finished or looped (to update loop count)
734 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
736 // The application should be notified by NotificationManager, in another thread
737 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
741 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
743 //Constrain custom objects (in construction order)
744 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
745 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
746 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
748 PropertyOwner& object = **iter;
749 ConstrainPropertyOwner( object, bufferIndex );
753 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
755 // Constrain system-level render-tasks
756 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
757 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
759 RenderTask& task = **iter;
760 ConstrainPropertyOwner( task, bufferIndex );
763 // Constrain render-tasks
764 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
765 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
767 RenderTask& task = **iter;
768 ConstrainPropertyOwner( task, bufferIndex );
772 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
774 // constrain shaders... (in construction order)
775 ShaderOwner& shaders = mImpl->shaders;
776 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
778 Shader& shader = **iter;
779 ConstrainPropertyOwner( shader, bufferIndex );
783 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
785 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
786 PropertyNotificationIter iter = notifications.Begin();
788 while ( iter != notifications.End() )
790 PropertyNotification* notification = *iter;
791 bool valid = notification->Check( bufferIndex );
794 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
800 void UpdateManager::ForwardCompiledShadersToEventThread()
802 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
803 if( mImpl->shaderSaver )
805 // lock and swap the queues
807 // render might be attempting to send us more binaries at the same time
808 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
809 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
812 if( mImpl->updateCompiledShaders.size() > 0 )
814 ShaderSaver& factory = *mImpl->shaderSaver;
815 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
816 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
817 for( ; i != end; ++i )
819 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
821 // we don't need them in update anymore
822 mImpl->updateCompiledShaders.clear();
827 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
829 const unsigned int rendererCount = mImpl->renderers.Count();
830 for( unsigned int i = 0; i < rendererCount; ++i )
833 ConstrainPropertyOwner( *mImpl->renderers[i], bufferIndex );
835 mImpl->renderers[i]->PrepareRender( bufferIndex );
839 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
841 mImpl->nodeDirtyFlags = NothingFlag;
848 // Prepare resources, update shaders, for each node
849 // And add the renderers to the sorted layers. Start from root, which is also a layer
850 mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
852 mImpl->renderQueue );
854 if ( mImpl->systemLevelRoot )
856 mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
858 mImpl->renderQueue );
862 unsigned int UpdateManager::Update( float elapsedSeconds,
863 unsigned int lastVSyncTimeMilliseconds,
864 unsigned int nextVSyncTimeMilliseconds )
866 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
868 //Clear nodes/resources which were previously discarded
869 mImpl->discardQueue.Clear( bufferIndex );
871 //Process Touches & Gestures
872 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
874 bool updateScene = // The scene-graph requires an update if..
875 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
876 IsAnimationRunning() || // ..at least one animation is running OR
877 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
878 gestureUpdated; // ..a gesture property was updated
881 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
882 // values if the scene was updated in the previous frame.
883 if( updateScene || mImpl->previousUpdateScene )
885 //Reset properties from the previous update
886 ResetProperties( bufferIndex );
887 mImpl->transformManager.ResetToBaseValue();
890 // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
891 // between calling IsSceneUpdateRequired() above and here, so updateScene should
893 updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
895 //Forward compiled shader programs to event thread for saving
896 ForwardCompiledShadersToEventThread();
898 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
899 // renderer lists if the scene was updated in the previous frame.
900 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
901 if( updateScene || mImpl->previousUpdateScene )
904 Animate( bufferIndex, elapsedSeconds );
906 //Constraint custom objects
907 ConstrainCustomObjects( bufferIndex );
909 //Clear the lists of renderers from the previous update
910 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
912 mImpl->sortedLayers[i]->ClearRenderables();
915 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
917 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
920 //Update node hierarchy, apply constraints and perform sorting / culling.
921 //This will populate each Layer with a list of renderers which are ready.
922 UpdateNodes( bufferIndex );
924 //Apply constraints to RenderTasks, shaders
925 ConstrainRenderTasks( bufferIndex );
926 ConstrainShaders( bufferIndex );
928 //Update renderers and apply constraints
929 UpdateRenderers( bufferIndex );
931 //Update the trnasformations of all the nodes
932 mImpl->transformManager.Update();
934 //Process Property Notifications
935 ProcessPropertyNotifications( bufferIndex );
937 //Process the RenderTasks; this creates the instructions for rendering the next frame.
938 //reset the update buffer index and make sure there is enough room in the instruction container
939 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
940 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
942 if ( NULL != mImpl->root )
944 mImpl->renderTaskProcessor.Process( bufferIndex,
948 mImpl->renderInstructions );
950 // Process the system-level RenderTasks last
951 if ( NULL != mImpl->systemLevelRoot )
953 mImpl->renderTaskProcessor.Process( bufferIndex,
954 mImpl->systemLevelTaskList,
955 *mImpl->systemLevelRoot,
956 mImpl->systemLevelSortedLayers,
957 mImpl->renderInstructions );
962 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
963 bool doRenderOnceNotify = false;
964 mImpl->renderTaskWaiting = false;
965 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
966 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
967 endIter != iter; ++iter )
969 RenderTask& renderTask(*(*iter));
971 renderTask.UpdateState();
973 if( renderTask.IsWaitingToRender() &&
974 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
976 mImpl->renderTaskWaiting = true; // keep update/render threads alive
979 if( renderTask.HasRendered() )
981 doRenderOnceNotify = true;
985 if( doRenderOnceNotify )
987 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
988 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
991 // Macro is undefined in release build.
992 SNAPSHOT_NODE_LOGGING;
994 // A ResetProperties() may be required in the next frame
995 mImpl->previousUpdateScene = updateScene;
997 // Check whether further updates are required
998 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1000 // tell the update manager that we're done so the queue can be given to event thread
1001 mImpl->notificationManager.UpdateCompleted();
1003 // The update has finished; swap the double-buffering indices
1004 mSceneGraphBuffers.Swap();
1006 return keepUpdating;
1009 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1011 // Update the duration set via Stage::KeepRendering()
1012 if ( mImpl->keepRenderingSeconds > 0.0f )
1014 mImpl->keepRenderingSeconds -= elapsedSeconds;
1017 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1019 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1020 // Keep updating until no messages are received and no animations are running.
1021 // If an animation has just finished, update at least once more for Discard end-actions.
1022 // No need to check for renderQueue as there is always a render after update and if that
1023 // render needs another update it will tell the adaptor to call update again
1025 if ( mImpl->keepRenderingSeconds > 0.0f )
1027 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1030 if ( IsAnimationRunning() ||
1031 mImpl->animationFinishedDuringUpdate )
1033 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1036 if ( mImpl->renderTaskWaiting )
1038 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1041 return keepUpdatingRequest;
1044 void UpdateManager::SetBackgroundColor( const Vector4& color )
1046 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1048 // Reserve some memory inside the render queue
1049 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1051 // Construct message in the render queue memory; note that delete should not be called on the return value
1052 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1055 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1057 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1059 // Reserve some memory inside the render queue
1060 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1062 // Construct message in the render queue memory; note that delete should not be called on the return value
1063 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1066 void UpdateManager::KeepRendering( float durationSeconds )
1068 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1071 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1075 // just copy the vector of pointers
1076 mImpl->sortedLayers = layers;
1080 mImpl->systemLevelSortedLayers = layers;
1084 void UpdateManager::SetDepthIndices( NodeDepths* nodeDepths )
1088 // note,this vector is already in depth order. It could be used as-is to
1089 // remove sorting in update algorithm. However, it lacks layer boundary markers.
1090 for( std::vector<NodeDepthPair>::iterator iter = nodeDepths->nodeDepths.begin(),
1091 end = nodeDepths->nodeDepths.end() ;
1092 iter != end ; ++iter )
1094 iter->node->SetDepthIndex( iter->sortedDepth );
1099 void UpdateManager::AddSampler( Render::Sampler* sampler )
1101 // Message has ownership of Sampler while in transit from update to render
1102 typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > DerivedType;
1104 // Reserve some memory inside the render queue
1105 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1107 // Construct message in the render queue memory; note that delete should not be called on the return value
1108 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1111 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1113 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1115 // Reserve some memory inside the render queue
1116 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1118 // Construct message in the render queue memory; note that delete should not be called on the return value
1119 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1122 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1124 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1126 // Reserve some memory inside the render queue
1127 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1129 // Construct message in the render queue memory; note that delete should not be called on the return value
1130 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1133 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
1135 typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > DerivedType;
1137 // Reserve some memory inside the render queue
1138 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1140 // Construct message in the render queue memory; note that delete should not be called on the return value
1141 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1144 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1146 // Message has ownership of format while in transit from update -> render
1147 typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
1149 // Reserve some memory inside the render queue
1150 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1152 // Construct message in the render queue memory; note that delete should not be called on the return value
1153 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1156 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1158 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1160 // Reserve some memory inside the render queue
1161 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1163 // Construct message in the render queue memory; note that delete should not be called on the return value
1164 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1167 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1169 // Message has ownership of format while in transit from update -> render
1170 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType;
1172 // Reserve some memory inside the render queue
1173 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1175 // Construct message in the render queue memory; note that delete should not be called on the return value
1176 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1179 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data, size_t size )
1181 // Message has ownership of format while in transit from update -> render
1182 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<char> >, size_t > DerivedType;
1184 // Reserve some memory inside the render queue
1185 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1187 // Construct message in the render queue memory; note that delete should not be called on the return value
1188 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1191 void UpdateManager::AddGeometry( Render::Geometry* geometry )
1193 // Message has ownership of format while in transit from update -> render
1194 typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > DerivedType;
1196 // Reserve some memory inside the render queue
1197 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1199 // Construct message in the render queue memory; note that delete should not be called on the return value
1200 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1203 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1205 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1207 // Reserve some memory inside the render queue
1208 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1210 // Construct message in the render queue memory; note that delete should not be called on the return value
1211 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1214 void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
1216 typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType;
1218 // Reserve some memory inside the render queue
1219 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1221 // Construct message in the render queue memory; note that delete should not be called on the return value
1222 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1225 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
1227 typedef IndexBufferMessage< RenderManager > DerivedType;
1229 // Reserve some memory inside the render queue
1230 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1232 // Construct message in the render queue memory; note that delete should not be called on the return value
1233 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1236 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1238 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1240 // Reserve some memory inside the render queue
1241 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1243 // Construct message in the render queue memory; note that delete should not be called on the return value
1244 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1247 void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1249 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1251 // Reserve some memory inside the render queue
1252 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1254 // Construct message in the render queue memory; note that delete should not be called on the return value
1255 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, geometry, propertyBuffer );
1258 void UpdateManager::AddTexture( Render::Texture* texture )
1260 // Message has ownership of Texture while in transit from update -> render
1261 typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType;
1263 // Reserve some memory inside the render queue
1264 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1266 // Construct message in the render queue memory; note that delete should not be called on the return value
1267 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1270 void UpdateManager::RemoveTexture( Render::Texture* texture)
1272 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1274 // Reserve some memory inside the render queue
1275 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1277 // Construct message in the render queue memory; note that delete should not be called on the return value
1278 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1281 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1283 typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
1285 // Reserve some memory inside the message queue
1286 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1288 // Construct message in the message queue memory; note that delete should not be called on the return value
1289 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1292 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1294 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1296 // Reserve some memory inside the render queue
1297 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1299 // Construct message in the render queue memory; note that delete should not be called on the return value
1300 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1303 void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
1305 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1307 // Reserve some memory inside the render queue
1308 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1310 // Construct message in the render queue memory; note that delete should not be called on the return value
1311 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1314 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1316 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1318 // Reserve some memory inside the render queue
1319 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1321 // Construct message in the render queue memory; note that delete should not be called on the return value
1322 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1325 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, unsigned int mipmapLevel, unsigned int layer )
1327 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, unsigned int, unsigned int > DerivedType;
1329 // Reserve some memory inside the render queue
1330 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1332 // Construct message in the render queue memory; note that delete should not be called on the return value
1333 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1336 } // namespace SceneGraph
1338 } // namespace Internal