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/common/texture-cache-dispatcher.h>
45 #include <dali/internal/update/controllers/render-message-dispatcher.h>
46 #include <dali/internal/update/controllers/scene-controller-impl.h>
47 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
48 #include <dali/internal/update/manager/object-owner-container.h>
49 #include <dali/internal/update/manager/render-task-processor.h>
50 #include <dali/internal/update/manager/sorted-layers.h>
51 #include <dali/internal/update/manager/update-algorithms.h>
52 #include <dali/internal/update/manager/update-manager-debug.h>
53 #include <dali/internal/update/manager/transform-manager.h>
54 #include <dali/internal/update/nodes/node.h>
55 #include <dali/internal/update/nodes/scene-graph-layer.h>
56 #include <dali/internal/update/queue/update-message-queue.h>
57 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
58 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
59 #include <dali/internal/update/rendering/scene-graph-texture-set.h>
60 #include <dali/internal/update/resources/resource-manager.h>
62 #include <dali/internal/render/common/render-instruction-container.h>
63 #include <dali/internal/render/common/render-manager.h>
64 #include <dali/internal/render/queue/render-queue.h>
65 #include <dali/internal/render/gl-resources/texture-cache.h>
66 #include <dali/internal/render/shaders/scene-graph-shader.h>
67 #include <dali/internal/render/renderers/render-frame-buffer.h>
68 #include <dali/internal/render/renderers/render-sampler.h>
69 #include <dali/internal/update/render-tasks/scene-graph-camera.h>
71 // Un-comment to enable node tree debug logging
72 //#define NODE_TREE_LOGGING 1
74 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
75 #define SNAPSHOT_NODE_LOGGING \
76 const int FRAME_COUNT_TRIGGER = 16;\
77 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
79 if ( NULL != mImpl->root )\
81 mImpl->frameCounter = 0;\
82 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
85 mImpl->frameCounter++;
87 #define SNAPSHOT_NODE_LOGGING
90 #if defined(DEBUG_ENABLED)
91 extern Debug::Filter* gRenderTaskLogFilter;
95 using namespace Dali::Integration;
96 using Dali::Internal::Update::MessageQueue;
107 typedef OwnerContainer< Shader* > ShaderContainer;
108 typedef ShaderContainer::Iterator ShaderIter;
109 typedef ShaderContainer::ConstIterator ShaderConstIter;
111 typedef std::vector<Internal::ShaderDataPtr> ShaderDataBinaryQueue;
113 typedef OwnerContainer<PanGesture*> GestureContainer;
114 typedef GestureContainer::Iterator GestureIter;
115 typedef GestureContainer::ConstIterator GestureConstIter;
117 typedef OwnerContainer< TextureSet* > TextureSetContainer;
118 typedef TextureSetContainer::Iterator TextureSetIter;
119 typedef TextureSetContainer::ConstIterator TextureSetConstIter;
122 * Structure to contain UpdateManager internal data
124 struct UpdateManager::Impl
126 Impl( NotificationManager& notificationManager,
127 CompleteNotificationInterface& animationFinishedNotifier,
128 PropertyNotifier& propertyNotifier,
129 ResourceManager& resourceManager,
130 DiscardQueue& discardQueue,
131 RenderController& renderController,
132 RenderManager& renderManager,
133 RenderQueue& renderQueue,
134 SceneGraphBuffers& sceneGraphBuffers,
135 RenderTaskProcessor& renderTaskProcessor )
136 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
137 notificationManager( notificationManager ),
139 animationFinishedNotifier( animationFinishedNotifier ),
140 propertyNotifier( propertyNotifier ),
142 resourceManager( resourceManager ),
143 discardQueue( discardQueue ),
144 renderController( renderController ),
145 sceneController( NULL ),
146 renderManager( renderManager ),
147 renderQueue( renderQueue ),
148 renderInstructions( renderManager.GetRenderInstructionContainer() ),
149 renderTaskProcessor( renderTaskProcessor ),
150 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
151 taskList( renderMessageDispatcher, resourceManager ),
152 systemLevelTaskList( renderMessageDispatcher, resourceManager ),
154 systemLevelRoot( NULL ),
155 renderers( sceneGraphBuffers, discardQueue ),
157 messageQueue( renderController, sceneGraphBuffers ),
158 keepRenderingSeconds( 0.0f ),
159 animationFinishedDuringUpdate( false ),
160 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
161 previousUpdateScene( false ),
163 renderTaskWaiting( false )
165 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
167 renderers.SetSceneController( *sceneController );
169 // create first 'dummy' node
175 // Disconnect render tasks from nodes, before destroying the nodes
176 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
177 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
179 (*iter)->SetSourceNode( NULL );
181 // ..repeat for system level RenderTasks
182 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
183 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
185 (*iter)->SetSourceNode( NULL );
188 // UpdateManager owns the Nodes
189 Vector<Node*>::Iterator iter = nodes.Begin()+1;
190 Vector<Node*>::Iterator endIter = nodes.End();
191 for(;iter!=endIter;++iter)
193 (*iter)->OnDestroy();
197 // If there is root, reset it, otherwise do nothing as rendering was never started
202 Node::Delete( root );
206 if( systemLevelRoot )
208 systemLevelRoot->OnDestroy();
210 Node::Delete( systemLevelRoot );
211 systemLevelRoot = NULL;
214 delete sceneController;
217 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
218 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
219 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
220 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
221 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
222 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
223 ShaderSaver* shaderSaver; ///< Saves shader binaries.
224 ResourceManager& resourceManager; ///< resource manager
225 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
226 RenderController& renderController; ///< render controller
227 SceneControllerImpl* sceneController; ///< scene controller
228 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
229 RenderQueue& renderQueue; ///< Used to queue messages for the next render
230 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
231 RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
233 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
235 RenderTaskList taskList; ///< The list of scene graph render-tasks
236 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
238 Layer* root; ///< The root node (root is a layer)
239 Layer* systemLevelRoot; ///< A separate root-node for system-level content
241 Vector<Node*> nodes; ///< A container of all instantiated nodes
243 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
244 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
246 OwnerContainer< Camera* > cameras; ///< A container of cameras
247 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
249 AnimationContainer animations; ///< A container of owned animations
250 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
252 ObjectOwnerContainer<Renderer> renderers;
253 TextureSetContainer textureSets; ///< A container of texture sets
255 ShaderContainer shaders; ///< A container of owned shaders
257 MessageQueue messageQueue; ///< The messages queued from the event-thread
258 ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
259 ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event
260 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
262 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
263 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
265 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
266 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
268 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
270 GestureContainer gestures; ///< A container of owned gesture detectors
271 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
274 UpdateManager::UpdateManager( NotificationManager& notificationManager,
275 CompleteNotificationInterface& animationFinishedNotifier,
276 PropertyNotifier& propertyNotifier,
277 ResourceManager& resourceManager,
278 DiscardQueue& discardQueue,
279 RenderController& controller,
280 RenderManager& renderManager,
281 RenderQueue& renderQueue,
282 TextureCacheDispatcher& textureCacheDispatcher,
283 RenderTaskProcessor& renderTaskProcessor )
286 mImpl = new Impl( notificationManager,
287 animationFinishedNotifier,
295 renderTaskProcessor );
297 textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers );
300 UpdateManager::~UpdateManager()
305 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
307 DALI_ASSERT_DEBUG( layer->IsLayer() );
308 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
312 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
314 mImpl->root->CreateTransform( &mImpl->transformManager);
318 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
319 mImpl->systemLevelRoot = layer;
320 mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager);
323 layer->SetRoot(true);
326 void UpdateManager::AddNode( Node* node )
328 DALI_ASSERT_ALWAYS( NULL != node );
329 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
331 // Nodes must be sorted by pointer
332 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
333 for(Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter)
337 mImpl->nodes.Insert((iter+1), node);
338 node->CreateTransform( &mImpl->transformManager);
344 void UpdateManager::ConnectNode( Node* parent, Node* node )
346 DALI_ASSERT_ALWAYS( NULL != parent );
347 DALI_ASSERT_ALWAYS( NULL != node );
348 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
350 parent->ConnectChild( node );
353 void UpdateManager::DisconnectNode( Node* node )
355 Node* parent = node->GetParent();
356 DALI_ASSERT_ALWAYS( NULL != parent );
357 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
359 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
362 void UpdateManager::DestroyNode( Node* node )
364 DALI_ASSERT_ALWAYS( NULL != node );
365 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
367 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
368 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
369 for(;iter!=endIter;++iter)
373 mImpl->nodes.Erase(iter);
378 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
380 // Notify the Node about impending destruction
384 void UpdateManager::AddCamera( Camera* camera )
386 DALI_ASSERT_DEBUG( camera != NULL );
388 mImpl->cameras.PushBack( camera ); // takes ownership
391 void UpdateManager::RemoveCamera( const Camera* camera )
394 OwnerContainer<Camera*>::Iterator iter = mImpl->cameras.Begin();
395 OwnerContainer<Camera*>::ConstIterator end = mImpl->cameras.End();
396 for ( ; iter != end; ++iter )
398 Camera* value = *iter;
399 if ( camera == value )
401 // Transfer ownership to the discard queue
402 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->cameras.Release( iter ) );
410 void UpdateManager::AddObject( PropertyOwner* object )
412 DALI_ASSERT_DEBUG( NULL != object );
414 mImpl->customObjects.PushBack( object );
417 void UpdateManager::RemoveObject( PropertyOwner* object )
419 DALI_ASSERT_DEBUG( NULL != object );
421 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
423 // Find the object and destroy it
424 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
426 PropertyOwner* current = *iter;
427 if ( current == object )
429 customObjects.Erase( iter );
434 // Should not reach here
435 DALI_ASSERT_DEBUG(false);
438 void UpdateManager::AddAnimation( Animation* animation )
440 mImpl->animations.PushBack( animation );
443 void UpdateManager::StopAnimation( Animation* animation )
445 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
447 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
449 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
452 void UpdateManager::RemoveAnimation( Animation* animation )
454 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
456 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
458 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
461 bool UpdateManager::IsAnimationRunning() const
463 bool isRunning(false);
464 AnimationContainer& animations = mImpl->animations;
466 // Find any animation that isn't stopped or paused
468 const AnimationIter endIter = animations.End();
469 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
471 const Animation::State state = (*iter)->GetState();
473 if (state != Animation::Stopped &&
474 state != Animation::Paused)
483 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
485 mImpl->propertyNotifications.PushBack( propertyNotification );
488 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
490 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
491 PropertyNotificationIter iter = propertyNotifications.Begin();
493 while ( iter != propertyNotifications.End() )
495 if( *iter == propertyNotification )
497 propertyNotifications.Erase(iter);
504 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
506 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
507 propertyNotification->SetNotifyMode( notifyMode );
510 ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
512 return mImpl->renderers;
515 void UpdateManager::AddShader( Shader* shader )
517 DALI_ASSERT_DEBUG( NULL != shader );
519 if( mImpl->shaders.Count() == 0 )
521 // the first added shader becomes our default shader
522 // Construct message in the render queue memory; note that delete should not be called on the return value
523 typedef MessageValue1< RenderManager, Shader* > DerivedType;
525 // Reserve some memory inside the render queue
526 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
528 // Construct message in the render queue memory; note that delete should not be called on the return value
529 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
532 mImpl->shaders.PushBack( shader );
535 void UpdateManager::RemoveShader( Shader* shader )
537 DALI_ASSERT_DEBUG(shader != NULL);
539 ShaderContainer& shaders = mImpl->shaders;
541 // Find the shader and destroy it
542 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
544 Shader& current = **iter;
545 if ( ¤t == shader )
547 // Transfer ownership to the discard queue
548 // This keeps the shader alive, until the render-thread has finished with it
549 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
554 // Should not reach here
555 DALI_ASSERT_DEBUG(false);
558 void UpdateManager::SetShaderProgram( Shader* shader,
559 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
564 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
566 // Reserve some memory inside the render queue
567 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
569 // Construct message in the render queue memory; note that delete should not be called on the return value
570 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
574 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
576 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
577 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
579 // lock as update might be sending previously compiled shaders to event thread
580 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
581 mImpl->renderCompiledShaders.push_back( shaderData );
585 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
589 // copy the list, this is only likely to happen once in application life cycle
590 return &(mImpl->taskList);
594 // copy the list, this is only likely to happen once in application life cycle
595 return &(mImpl->systemLevelTaskList);
599 void UpdateManager::AddGesture( PanGesture* gesture )
601 DALI_ASSERT_DEBUG( NULL != gesture );
603 mImpl->gestures.PushBack( gesture );
606 void UpdateManager::RemoveGesture( PanGesture* gesture )
608 DALI_ASSERT_DEBUG( gesture != NULL );
610 GestureContainer& gestures = mImpl->gestures;
612 // Find the gesture and destroy it
613 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
615 PanGesture& current = **iter;
616 if ( ¤t == gesture )
618 mImpl->gestures.Erase( iter );
622 // Should not reach here
623 DALI_ASSERT_DEBUG(false);
626 void UpdateManager::AddTextureSet( TextureSet* textureSet )
628 DALI_ASSERT_DEBUG( NULL != textureSet );
629 mImpl->textureSets.PushBack( textureSet );
632 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
634 DALI_ASSERT_DEBUG(textureSet != NULL);
635 size_t textureSetCount( mImpl->textureSets.Size() );
636 for( size_t i(0); i<textureSetCount; ++i )
638 if( textureSet == mImpl->textureSets[i] )
640 mImpl->textureSets.Remove( mImpl->textureSets.Begin() + i );
642 // Update manager has ownership of the TextureSet
649 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
651 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
654 void UpdateManager::EventProcessingStarted()
656 mImpl->messageQueue.EventProcessingStarted();
659 bool UpdateManager::FlushQueue()
661 return mImpl->messageQueue.FlushQueue();
664 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
666 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
667 mImpl->animationFinishedDuringUpdate = false;
669 // Animated properties have to be reset to their original value each frame
671 // Reset root properties
674 mImpl->root->ResetToBaseValues( bufferIndex );
676 if ( mImpl->systemLevelRoot )
678 mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
681 // Reset all the nodes
682 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
683 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
684 for(;iter != endIter; ++iter)
686 (*iter)->ResetToBaseValues( bufferIndex );
689 // Reset system-level render-task list properties to base values
690 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
692 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
694 (*iter)->ResetToBaseValues( bufferIndex );
697 // Reset render-task list properties to base values.
698 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
700 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
702 (*iter)->ResetToBaseValues( bufferIndex );
705 // Reset custom object properties to base values
706 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
708 (*iter)->ResetToBaseValues( bufferIndex );
711 mImpl->renderers.ResetToBaseValues( bufferIndex );
713 // Reset animatable shader properties to base values
714 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
716 (*iter)->ResetToBaseValues( bufferIndex );
720 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
722 bool gestureUpdated( false );
724 // constrain gestures... (in construction order)
725 GestureContainer& gestures = mImpl->gestures;
727 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
729 PanGesture& gesture = **iter;
730 gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
731 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
734 return gestureUpdated;
737 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
739 AnimationContainer &animations = mImpl->animations;
740 AnimationIter iter = animations.Begin();
741 bool animationLooped = false;
742 while ( iter != animations.End() )
744 Animation* animation = *iter;
745 bool finished = false;
747 animation->Update( bufferIndex, elapsedSeconds, looped, finished );
749 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
750 animationLooped = animationLooped || looped;
752 // Remove animations that had been destroyed but were still waiting for an update
753 if (animation->GetState() == Animation::Destroyed)
755 iter = animations.Erase(iter);
763 // queue the notification on finished or looped (to update loop count)
764 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
766 // The application should be notified by NotificationManager, in another thread
767 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
771 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
773 //Constrain custom objects (in construction order)
774 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
775 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
776 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
778 PropertyOwner& object = **iter;
779 ConstrainPropertyOwner( object, bufferIndex );
783 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
785 // Constrain system-level render-tasks
786 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
787 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
789 RenderTask& task = **iter;
790 ConstrainPropertyOwner( task, bufferIndex );
793 // Constrain render-tasks
794 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
795 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
797 RenderTask& task = **iter;
798 ConstrainPropertyOwner( task, bufferIndex );
802 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
804 // constrain shaders... (in construction order)
805 ShaderContainer& shaders = mImpl->shaders;
806 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
808 Shader& shader = **iter;
809 ConstrainPropertyOwner( shader, bufferIndex );
813 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
815 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
816 PropertyNotificationIter iter = notifications.Begin();
818 while ( iter != notifications.End() )
820 PropertyNotification* notification = *iter;
821 bool valid = notification->Check( bufferIndex );
824 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
830 void UpdateManager::PrepareTextureSets( BufferIndex bufferIndex )
832 size_t textureSetCount( mImpl->textureSets.Size() );
833 for( size_t i(0); i<textureSetCount; ++i )
835 //Prepare texture set
836 mImpl->textureSets[i]->Prepare( mImpl->resourceManager );
840 void UpdateManager::ForwardCompiledShadersToEventThread()
842 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
843 if( mImpl->shaderSaver )
845 // lock and swap the queues
847 // render might be attempting to send us more binaries at the same time
848 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
849 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
852 if( mImpl->updateCompiledShaders.size() > 0 )
854 ShaderSaver& factory = *mImpl->shaderSaver;
855 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
856 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
857 for( ; i != end; ++i )
859 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
861 // we don't need them in update anymore
862 mImpl->updateCompiledShaders.clear();
867 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
869 const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
870 unsigned int rendererCount( rendererContainer.Size() );
871 for( unsigned int i(0); i<rendererCount; ++i )
874 ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
876 rendererContainer[i]->PrepareRender( bufferIndex );
880 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
882 mImpl->nodeDirtyFlags = NothingFlag;
889 // Prepare resources, update shaders, for each node
890 // And add the renderers to the sorted layers. Start from root, which is also a layer
891 mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
893 mImpl->resourceManager,
894 mImpl->renderQueue );
896 if ( mImpl->systemLevelRoot )
898 mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
900 mImpl->resourceManager,
901 mImpl->renderQueue );
905 unsigned int UpdateManager::Update( float elapsedSeconds,
906 unsigned int lastVSyncTimeMilliseconds,
907 unsigned int nextVSyncTimeMilliseconds )
909 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
911 //Clear nodes/resources which were previously discarded
912 mImpl->discardQueue.Clear( bufferIndex );
914 //Grab any loaded resources
915 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
917 //Process Touches & Gestures
918 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
920 const bool updateScene = // The scene-graph requires an update if..
921 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
922 IsAnimationRunning() || // ..at least one animation is running OR
923 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
924 resourceChanged || // ..one or more resources were updated/changed OR
925 gestureUpdated; // ..a gesture property was updated
928 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
929 // values if the scene was updated in the previous frame.
930 if( updateScene || mImpl->previousUpdateScene )
932 //Reset properties from the previous update
933 ResetProperties( bufferIndex );
934 mImpl->transformManager.ResetToBaseValue();
937 //Process the queued scene messages
938 mImpl->messageQueue.ProcessMessages( bufferIndex );
940 //Post Process Ids of resources updated by renderer
941 mImpl->resourceManager.PostProcessResources( bufferIndex );
943 //Forward compiled shader programs to event thread for saving
944 ForwardCompiledShadersToEventThread();
946 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
947 // renderer lists if the scene was updated in the previous frame.
948 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
949 if( updateScene || mImpl->previousUpdateScene )
952 Animate( bufferIndex, elapsedSeconds );
954 //Constraint custom objects
955 ConstrainCustomObjects( bufferIndex );
957 //Prepare texture sets and apply constraints to them
958 PrepareTextureSets( bufferIndex );
960 //Clear the lists of renderers from the previous update
961 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
963 mImpl->sortedLayers[i]->ClearRenderables();
966 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
968 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
971 //Update node hierarchy, apply constraints and perform sorting / culling.
972 //This will populate each Layer with a list of renderers which are ready.
973 UpdateNodes( bufferIndex );
975 //Apply constraints to RenderTasks, shaders
976 ConstrainRenderTasks( bufferIndex );
977 ConstrainShaders( bufferIndex );
979 //Update renderers and apply constraints
980 UpdateRenderers( bufferIndex );
982 //Update the trnasformations of all the nodes
983 mImpl->transformManager.Update();
985 //Process Property Notifications
986 ProcessPropertyNotifications( bufferIndex );
988 //Process the RenderTasks; this creates the instructions for rendering the next frame.
989 //reset the update buffer index and make sure there is enough room in the instruction container
990 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
991 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
993 if ( NULL != mImpl->root )
995 mImpl->renderTaskProcessor.Process( bufferIndex,
999 mImpl->renderInstructions );
1001 // Process the system-level RenderTasks last
1002 if ( NULL != mImpl->systemLevelRoot )
1004 mImpl->renderTaskProcessor.Process( bufferIndex,
1005 mImpl->systemLevelTaskList,
1006 *mImpl->systemLevelRoot,
1007 mImpl->systemLevelSortedLayers,
1008 mImpl->renderInstructions );
1013 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1014 bool doRenderOnceNotify = false;
1015 mImpl->renderTaskWaiting = false;
1016 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1017 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1018 endIter != iter; ++iter )
1020 RenderTask& renderTask(*(*iter));
1022 renderTask.UpdateState();
1024 if( renderTask.IsWaitingToRender() &&
1025 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1027 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1030 if( renderTask.HasRendered() )
1032 doRenderOnceNotify = true;
1036 if( doRenderOnceNotify )
1038 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1039 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1042 // Macro is undefined in release build.
1043 SNAPSHOT_NODE_LOGGING;
1045 // A ResetProperties() may be required in the next frame
1046 mImpl->previousUpdateScene = updateScene;
1048 // Check whether further updates are required
1049 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1051 // tell the update manager that we're done so the queue can be given to event thread
1052 mImpl->notificationManager.UpdateCompleted();
1054 // The update has finished; swap the double-buffering indices
1055 mSceneGraphBuffers.Swap();
1057 return keepUpdating;
1060 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1062 // Update the duration set via Stage::KeepRendering()
1063 if ( mImpl->keepRenderingSeconds > 0.0f )
1065 mImpl->keepRenderingSeconds -= elapsedSeconds;
1068 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1070 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1071 // Keep updating until no messages are received and no animations are running.
1072 // If an animation has just finished, update at least once more for Discard end-actions.
1073 // No need to check for renderQueue as there is always a render after update and if that
1074 // render needs another update it will tell the adaptor to call update again
1076 if ( mImpl->keepRenderingSeconds > 0.0f )
1078 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1081 if ( IsAnimationRunning() ||
1082 mImpl->animationFinishedDuringUpdate )
1084 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1087 if ( mImpl->renderTaskWaiting )
1089 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1092 return keepUpdatingRequest;
1095 void UpdateManager::SetBackgroundColor( const Vector4& color )
1097 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1099 // Reserve some memory inside the render queue
1100 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1102 // Construct message in the render queue memory; note that delete should not be called on the return value
1103 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1106 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1108 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1110 // Reserve some memory inside the render queue
1111 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1113 // Construct message in the render queue memory; note that delete should not be called on the return value
1114 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1117 void UpdateManager::KeepRendering( float durationSeconds )
1119 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1122 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1126 // just copy the vector of pointers
1127 mImpl->sortedLayers = layers;
1131 mImpl->systemLevelSortedLayers = layers;
1135 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1137 mImpl->shaderSaver = &upstream;
1140 void UpdateManager::AddSampler( Render::Sampler* sampler )
1142 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1144 // Reserve some memory inside the render queue
1145 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1147 // Construct message in the render queue memory; note that delete should not be called on the return value
1148 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1151 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1153 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1155 // Reserve some memory inside the render queue
1156 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1158 // Construct message in the render queue memory; note that delete should not be called on the return value
1159 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1162 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1164 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1166 // Reserve some memory inside the render queue
1167 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1169 // Construct message in the render queue memory; note that delete should not be called on the return value
1170 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1173 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
1175 typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > DerivedType;
1177 // Reserve some memory inside the render queue
1178 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1180 // Construct message in the render queue memory; note that delete should not be called on the return value
1181 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1184 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1186 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1188 // Reserve some memory inside the render queue
1189 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1191 // Construct message in the render queue memory; note that delete should not be called on the return value
1192 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1195 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1197 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1199 // Reserve some memory inside the render queue
1200 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1202 // Construct message in the render queue memory; note that delete should not be called on the return value
1203 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1206 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1208 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Render::PropertyBuffer::Format* > DerivedType;
1210 // Reserve some memory inside the render queue
1211 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1213 // Construct message in the render queue memory; note that delete should not be called on the return value
1214 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1217 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data, size_t size )
1219 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, Dali::Vector<char>*, size_t > DerivedType;
1221 // Reserve some memory inside the render queue
1222 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1224 // Construct message in the render queue memory; note that delete should not be called on the return value
1225 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1228 void UpdateManager::AddGeometry( Render::Geometry* geometry )
1230 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1232 // Reserve some memory inside the render queue
1233 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1235 // Construct message in the render queue memory; note that delete should not be called on the return value
1236 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1239 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1241 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1243 // Reserve some memory inside the render queue
1244 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1246 // Construct message in the render queue memory; note that delete should not be called on the return value
1247 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1250 void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
1252 typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType;
1254 // Reserve some memory inside the render queue
1255 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1257 // Construct message in the render queue memory; note that delete should not be called on the return value
1258 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1261 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
1263 typedef IndexBufferMessage< RenderManager > DerivedType;
1265 // Reserve some memory inside the render queue
1266 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1268 // Construct message in the render queue memory; note that delete should not be called on the return value
1269 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1272 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1274 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1276 // Reserve some memory inside the render queue
1277 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1279 // Construct message in the render queue memory; note that delete should not be called on the return value
1280 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1283 void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1285 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1287 // Reserve some memory inside the render queue
1288 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1290 // Construct message in the render queue memory; note that delete should not be called on the return value
1291 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, geometry, propertyBuffer );
1294 void UpdateManager::AddTexture( Render::NewTexture* texture )
1296 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1298 // Reserve some memory inside the render queue
1299 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1301 // Construct message in the render queue memory; note that delete should not be called on the return value
1302 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1305 void UpdateManager::RemoveTexture( Render::NewTexture* texture)
1307 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1309 // Reserve some memory inside the render queue
1310 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1312 // Construct message in the render queue memory; note that delete should not be called on the return value
1313 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1316 void UpdateManager::UploadTexture( Render::NewTexture* texture, PixelDataPtr pixelData, const NewTexture::UploadParams& params )
1318 typedef MessageValue3< RenderManager, Render::NewTexture*, PixelDataPtr, NewTexture::UploadParams > DerivedType;
1320 // Reserve some memory inside the message queue
1321 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1323 // Construct message in the message queue memory; note that delete should not be called on the return value
1324 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1327 void UpdateManager::GenerateMipmaps( Render::NewTexture* texture )
1329 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1331 // Reserve some memory inside the render queue
1332 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1334 // Construct message in the render queue memory; note that delete should not be called on the return value
1335 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1338 void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
1340 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1342 // Reserve some memory inside the render queue
1343 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1345 // Construct message in the render queue memory; note that delete should not be called on the return value
1346 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1349 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1351 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1353 // Reserve some memory inside the render queue
1354 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1356 // Construct message in the render queue memory; note that delete should not be called on the return value
1357 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1360 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::NewTexture* texture, unsigned int mipmapLevel, unsigned int layer )
1362 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::NewTexture*, unsigned int, unsigned int > DerivedType;
1364 // Reserve some memory inside the render queue
1365 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1367 // Construct message in the render queue memory; note that delete should not be called on the return value
1368 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1371 } // namespace SceneGraph
1373 } // namespace Internal