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/process-render-tasks.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>
61 #include <dali/internal/update/manager/geometry-batcher.h>
62 #include <dali/internal/update/render-tasks/scene-graph-camera.h>
64 #include <dali/internal/render/common/render-instruction-container.h>
65 #include <dali/internal/render/common/render-manager.h>
66 #include <dali/internal/render/queue/render-queue.h>
67 #include <dali/internal/render/gl-resources/texture-cache.h>
68 #include <dali/internal/render/shaders/scene-graph-shader.h>
70 // Un-comment to enable node tree debug logging
71 //#define NODE_TREE_LOGGING 1
73 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
74 #define SNAPSHOT_NODE_LOGGING \
75 const int FRAME_COUNT_TRIGGER = 16;\
76 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
78 if ( NULL != mImpl->root )\
80 mImpl->frameCounter = 0;\
81 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
84 mImpl->frameCounter++;
86 #define SNAPSHOT_NODE_LOGGING
89 #if defined(DEBUG_ENABLED)
90 extern Debug::Filter* gRenderTaskLogFilter;
94 using namespace Dali::Integration;
95 using Dali::Internal::Update::MessageQueue;
106 typedef OwnerContainer< Shader* > ShaderContainer;
107 typedef ShaderContainer::Iterator ShaderIter;
108 typedef ShaderContainer::ConstIterator ShaderConstIter;
110 typedef std::vector<Internal::ShaderDataPtr> ShaderDataBinaryQueue;
112 typedef OwnerContainer<PanGesture*> GestureContainer;
113 typedef GestureContainer::Iterator GestureIter;
114 typedef GestureContainer::ConstIterator GestureConstIter;
116 typedef OwnerContainer< TextureSet* > TextureSetContainer;
117 typedef TextureSetContainer::Iterator TextureSetIter;
118 typedef TextureSetContainer::ConstIterator TextureSetConstIter;
121 * Structure to contain UpdateManager internal data
123 struct UpdateManager::Impl
125 Impl( NotificationManager& notificationManager,
126 CompleteNotificationInterface& animationFinishedNotifier,
127 PropertyNotifier& propertyNotifier,
128 ResourceManager& resourceManager,
129 DiscardQueue& discardQueue,
130 RenderController& renderController,
131 RenderManager& renderManager,
132 RenderQueue& renderQueue,
133 SceneGraphBuffers& sceneGraphBuffers,
134 GeometryBatcher& geometryBatcher )
135 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
136 notificationManager( notificationManager ),
138 animationFinishedNotifier( animationFinishedNotifier ),
139 propertyNotifier( propertyNotifier ),
141 resourceManager( resourceManager ),
142 discardQueue( discardQueue ),
143 renderController( renderController ),
144 sceneController( NULL ),
145 renderManager( renderManager ),
146 renderQueue( renderQueue ),
147 renderInstructions( renderManager.GetRenderInstructionContainer() ),
148 geometryBatcher( geometryBatcher ),
149 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
150 taskList( renderMessageDispatcher, resourceManager ),
151 systemLevelTaskList( renderMessageDispatcher, resourceManager ),
153 systemLevelRoot( NULL ),
154 renderers( sceneGraphBuffers, discardQueue ),
156 messageQueue( renderController, sceneGraphBuffers ),
157 keepRenderingSeconds( 0.0f ),
158 animationFinishedDuringUpdate( false ),
159 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
160 previousUpdateScene( false ),
162 renderSortingHelper(),
163 renderTaskWaiting( false )
165 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
167 renderers.SetSceneController( *sceneController );
169 discardQueue.SetGeometryBatcher( &geometryBatcher );
171 // create first 'dummy' node
177 // Disconnect render tasks from nodes, before destroying the nodes
178 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
179 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
181 (*iter)->SetSourceNode( NULL );
183 // ..repeat for system level RenderTasks
184 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
185 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
187 (*iter)->SetSourceNode( NULL );
190 // UpdateManager owns the Nodes
191 Vector<Node*>::Iterator iter = nodes.Begin()+1;
192 Vector<Node*>::Iterator endIter = nodes.End();
193 for(;iter!=endIter;++iter)
195 (*iter)->OnDestroy();
199 // If there is root, reset it, otherwise do nothing as rendering was never started
208 if( systemLevelRoot )
210 systemLevelRoot->OnDestroy();
212 delete systemLevelRoot;
213 systemLevelRoot = NULL;
216 delete sceneController;
219 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
220 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
221 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
222 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
223 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
224 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
225 ShaderSaver* shaderSaver; ///< Saves shader binaries.
226 ResourceManager& resourceManager; ///< resource manager
227 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
228 RenderController& renderController; ///< render controller
229 SceneControllerImpl* sceneController; ///< scene controller
230 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
231 RenderQueue& renderQueue; ///< Used to queue messages for the next render
232 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
233 GeometryBatcher& geometryBatcher; ///< An instance of the GeometryBatcher
235 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
237 RenderTaskList taskList; ///< The list of scene graph render-tasks
238 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
240 Layer* root; ///< The root node (root is a layer)
241 Layer* systemLevelRoot; ///< A separate root-node for system-level content
243 Vector<Node*> nodes; ///< A container of all instantiated nodes
245 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
246 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
248 OwnerContainer< Camera* > cameras; ///< A container of cameras
249 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
251 AnimationContainer animations; ///< A container of owned animations
252 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
254 ObjectOwnerContainer<Renderer> renderers;
255 TextureSetContainer textureSets; ///< A container of texture sets
257 ShaderContainer shaders; ///< A container of owned shaders
259 MessageQueue messageQueue; ///< The messages queued from the event-thread
260 ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
261 ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event
262 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
264 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
265 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
267 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
268 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
270 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
271 RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
273 GestureContainer gestures; ///< A container of owned gesture detectors
274 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
277 UpdateManager::UpdateManager( NotificationManager& notificationManager,
278 CompleteNotificationInterface& animationFinishedNotifier,
279 PropertyNotifier& propertyNotifier,
280 ResourceManager& resourceManager,
281 DiscardQueue& discardQueue,
282 RenderController& controller,
283 RenderManager& renderManager,
284 RenderQueue& renderQueue,
285 TextureCacheDispatcher& textureCacheDispatcher,
286 GeometryBatcher& geometryBatcher )
289 mImpl = new Impl( notificationManager,
290 animationFinishedNotifier,
300 textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers );
301 mImpl->geometryBatcher.SetUpdateManager( this );
304 UpdateManager::~UpdateManager()
309 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
311 DALI_ASSERT_DEBUG( layer->IsLayer() );
312 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
316 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
318 mImpl->root->CreateTransform( &mImpl->transformManager );
322 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
323 mImpl->systemLevelRoot = layer;
324 mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager );
327 layer->SetRoot(true);
330 void UpdateManager::AddNode( Node* node )
332 DALI_ASSERT_ALWAYS( NULL != node );
333 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
335 // Nodes must be sorted by pointer
336 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
337 for(Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter)
341 mImpl->nodes.Insert((iter+1), node);
342 node->CreateTransform( &mImpl->transformManager );
343 node->mGeometryBatcher = &mImpl->geometryBatcher;
349 void UpdateManager::ConnectNode( Node* parent, Node* node )
351 DALI_ASSERT_ALWAYS( NULL != parent );
352 DALI_ASSERT_ALWAYS( NULL != node );
353 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
355 parent->ConnectChild( node );
358 void UpdateManager::DisconnectNode( Node* node )
360 Node* parent = node->GetParent();
361 DALI_ASSERT_ALWAYS( NULL != parent );
362 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
364 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
367 void UpdateManager::DestroyNode( Node* node )
369 DALI_ASSERT_ALWAYS( NULL != node );
370 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
372 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
373 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
374 for(;iter!=endIter;++iter)
378 mImpl->nodes.Erase(iter);
383 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
385 // Notify the Node about impending destruction
389 void UpdateManager::AddCamera( Camera* camera )
391 DALI_ASSERT_DEBUG( camera != NULL );
393 mImpl->cameras.PushBack( camera ); // takes ownership
396 void UpdateManager::RemoveCamera( const Camera* camera )
399 OwnerContainer<Camera*>::Iterator iter = mImpl->cameras.Begin();
400 OwnerContainer<Camera*>::ConstIterator end = mImpl->cameras.End();
401 for ( ; iter != end; ++iter )
403 Camera* value = *iter;
404 if ( camera == value )
406 // Transfer ownership to the discard queue
407 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->cameras.Release( iter ) );
415 void UpdateManager::AddObject( PropertyOwner* object )
417 DALI_ASSERT_DEBUG( NULL != object );
419 mImpl->customObjects.PushBack( object );
422 void UpdateManager::RemoveObject( PropertyOwner* object )
424 DALI_ASSERT_DEBUG( NULL != object );
426 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
428 // Find the object and destroy it
429 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
431 PropertyOwner* current = *iter;
432 if ( current == object )
434 customObjects.Erase( iter );
439 // Should not reach here
440 DALI_ASSERT_DEBUG(false);
443 void UpdateManager::AddAnimation( Animation* animation )
445 mImpl->animations.PushBack( animation );
448 void UpdateManager::StopAnimation( Animation* animation )
450 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
452 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
454 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
457 void UpdateManager::RemoveAnimation( Animation* animation )
459 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
461 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
463 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
466 bool UpdateManager::IsAnimationRunning() const
468 bool isRunning(false);
469 AnimationContainer& animations = mImpl->animations;
471 // Find any animation that isn't stopped or paused
473 const AnimationIter endIter = animations.End();
474 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
476 const Animation::State state = (*iter)->GetState();
478 if (state != Animation::Stopped &&
479 state != Animation::Paused)
488 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
490 mImpl->propertyNotifications.PushBack( propertyNotification );
493 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
495 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
496 PropertyNotificationIter iter = propertyNotifications.Begin();
498 while ( iter != propertyNotifications.End() )
500 if( *iter == propertyNotification )
502 propertyNotifications.Erase(iter);
509 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
511 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
512 propertyNotification->SetNotifyMode( notifyMode );
515 ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
517 return mImpl->renderers;
520 void UpdateManager::AddShader( Shader* shader )
522 DALI_ASSERT_DEBUG( NULL != shader );
524 if( mImpl->shaders.Count() == 0 )
526 // the first added shader becomes our default shader
527 // Construct message in the render queue memory; note that delete should not be called on the return value
528 typedef MessageValue1< RenderManager, Shader* > DerivedType;
530 // Reserve some memory inside the render queue
531 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
533 // Construct message in the render queue memory; note that delete should not be called on the return value
534 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
537 mImpl->shaders.PushBack( shader );
540 void UpdateManager::RemoveShader( Shader* shader )
542 DALI_ASSERT_DEBUG(shader != NULL);
544 ShaderContainer& shaders = mImpl->shaders;
546 // Find the shader and destroy it
547 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
549 Shader& current = **iter;
550 if ( ¤t == shader )
552 // Transfer ownership to the discard queue
553 // This keeps the shader alive, until the render-thread has finished with it
554 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
559 // Should not reach here
560 DALI_ASSERT_DEBUG(false);
563 void UpdateManager::SetShaderProgram( Shader* shader,
564 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
569 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
571 // Reserve some memory inside the render queue
572 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
574 // Construct message in the render queue memory; note that delete should not be called on the return value
575 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
579 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
581 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
582 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
584 // lock as update might be sending previously compiled shaders to event thread
585 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
586 mImpl->renderCompiledShaders.push_back( shaderData );
590 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
594 // copy the list, this is only likely to happen once in application life cycle
595 return &(mImpl->taskList);
599 // copy the list, this is only likely to happen once in application life cycle
600 return &(mImpl->systemLevelTaskList);
604 void UpdateManager::AddGesture( PanGesture* gesture )
606 DALI_ASSERT_DEBUG( NULL != gesture );
608 mImpl->gestures.PushBack( gesture );
611 void UpdateManager::RemoveGesture( PanGesture* gesture )
613 DALI_ASSERT_DEBUG( gesture != NULL );
615 GestureContainer& gestures = mImpl->gestures;
617 // Find the gesture and destroy it
618 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
620 PanGesture& current = **iter;
621 if ( ¤t == gesture )
623 mImpl->gestures.Erase( iter );
627 // Should not reach here
628 DALI_ASSERT_DEBUG(false);
631 void UpdateManager::AddTextureSet( TextureSet* textureSet )
633 DALI_ASSERT_DEBUG( NULL != textureSet );
634 mImpl->textureSets.PushBack( textureSet );
637 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
639 DALI_ASSERT_DEBUG(textureSet != NULL);
640 size_t textureSetCount( mImpl->textureSets.Size() );
641 for( size_t i(0); i<textureSetCount; ++i )
643 if( textureSet == mImpl->textureSets[i] )
645 mImpl->textureSets.Remove( mImpl->textureSets.Begin() + i );
651 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
653 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
656 void UpdateManager::EventProcessingStarted()
658 mImpl->messageQueue.EventProcessingStarted();
661 bool UpdateManager::FlushQueue()
663 return mImpl->messageQueue.FlushQueue();
666 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
668 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
669 mImpl->animationFinishedDuringUpdate = false;
671 // Animated properties have to be reset to their original value each frame
673 // Reset root properties
676 mImpl->root->ResetToBaseValues( bufferIndex );
678 if ( mImpl->systemLevelRoot )
680 mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
683 // Reset all the nodes
684 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
685 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
686 for(;iter != endIter; ++iter)
688 (*iter)->ResetToBaseValues( bufferIndex );
691 // Reset system-level render-task list properties to base values
692 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
694 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
696 (*iter)->ResetToBaseValues( bufferIndex );
699 // Reset render-task list properties to base values.
700 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
702 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
704 (*iter)->ResetToBaseValues( bufferIndex );
707 // Reset custom object properties to base values
708 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
710 (*iter)->ResetToBaseValues( bufferIndex );
713 mImpl->renderers.ResetToBaseValues( bufferIndex );
715 // Reset animatable shader properties to base values
716 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
718 (*iter)->ResetToBaseValues( bufferIndex );
722 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
724 bool gestureUpdated( false );
726 // constrain gestures... (in construction order)
727 GestureContainer& gestures = mImpl->gestures;
729 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
731 PanGesture& gesture = **iter;
732 gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
733 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
736 return gestureUpdated;
739 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
741 AnimationContainer &animations = mImpl->animations;
742 AnimationIter iter = animations.Begin();
743 bool animationLooped = false;
744 while ( iter != animations.End() )
746 Animation* animation = *iter;
747 bool finished = false;
749 animation->Update( bufferIndex, elapsedSeconds, looped, finished );
751 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
752 animationLooped = animationLooped || looped;
754 // Remove animations that had been destroyed but were still waiting for an update
755 if (animation->GetState() == Animation::Destroyed)
757 iter = animations.Erase(iter);
765 // queue the notification on finished or looped (to update loop count)
766 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
768 // The application should be notified by NotificationManager, in another thread
769 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
773 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
775 //Constrain custom objects (in construction order)
776 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
777 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
778 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
780 PropertyOwner& object = **iter;
781 ConstrainPropertyOwner( object, bufferIndex );
785 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
787 // Constrain system-level render-tasks
788 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
789 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
791 RenderTask& task = **iter;
792 ConstrainPropertyOwner( task, bufferIndex );
795 // Constrain render-tasks
796 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
797 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
799 RenderTask& task = **iter;
800 ConstrainPropertyOwner( task, bufferIndex );
804 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
806 // constrain shaders... (in construction order)
807 ShaderContainer& shaders = mImpl->shaders;
808 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
810 Shader& shader = **iter;
811 ConstrainPropertyOwner( shader, bufferIndex );
815 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
817 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
818 PropertyNotificationIter iter = notifications.Begin();
820 while ( iter != notifications.End() )
822 PropertyNotification* notification = *iter;
823 bool valid = notification->Check( bufferIndex );
826 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
832 void UpdateManager::PrepareTextureSets( BufferIndex bufferIndex )
834 size_t textureSetCount( mImpl->textureSets.Size() );
835 for( size_t i(0); i<textureSetCount; ++i )
837 //Prepare texture set
838 mImpl->textureSets[i]->Prepare( mImpl->resourceManager );
842 void UpdateManager::ForwardCompiledShadersToEventThread()
844 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
845 if( mImpl->shaderSaver )
847 // lock and swap the queues
849 // render might be attempting to send us more binaries at the same time
850 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
851 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
854 if( mImpl->updateCompiledShaders.size() > 0 )
856 ShaderSaver& factory = *mImpl->shaderSaver;
857 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
858 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
859 for( ; i != end; ++i )
861 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
863 // we don't need them in update anymore
864 mImpl->updateCompiledShaders.clear();
869 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
871 const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
872 unsigned int rendererCount( rendererContainer.Size() );
873 for( unsigned int i(0); i<rendererCount; ++i )
876 ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
878 rendererContainer[i]->PrepareRender( bufferIndex );
882 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
884 mImpl->nodeDirtyFlags = NothingFlag;
891 // Prepare resources, update shaders, for each node
892 // And add the renderers to the sorted layers. Start from root, which is also a layer
893 mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
895 mImpl->resourceManager,
896 mImpl->renderQueue );
898 if ( mImpl->systemLevelRoot )
900 mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
902 mImpl->resourceManager,
903 mImpl->renderQueue );
907 unsigned int UpdateManager::Update( float elapsedSeconds,
908 unsigned int lastVSyncTimeMilliseconds,
909 unsigned int nextVSyncTimeMilliseconds )
911 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
913 //Clear nodes/resources which were previously discarded
914 mImpl->discardQueue.Clear( bufferIndex );
916 //Grab any loaded resources
917 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
919 //Process Touches & Gestures
920 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
922 const bool updateScene = // The scene-graph requires an update if..
923 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
924 IsAnimationRunning() || // ..at least one animation is running OR
925 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
926 resourceChanged || // ..one or more resources were updated/changed OR
927 gestureUpdated; // ..a gesture property was updated
930 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
931 // values if the scene was updated in the previous frame.
932 if( updateScene || mImpl->previousUpdateScene )
934 //Reset properties from the previous update
935 ResetProperties( bufferIndex );
936 mImpl->transformManager.ResetToBaseValue();
939 //Process the queued scene messages
940 mImpl->messageQueue.ProcessMessages( bufferIndex );
942 //Post Process Ids of resources updated by renderer
943 mImpl->resourceManager.PostProcessResources( bufferIndex );
945 //Forward compiled shader programs to event thread for saving
946 ForwardCompiledShadersToEventThread();
948 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
949 // renderer lists if the scene was updated in the previous frame.
950 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
951 if( updateScene || mImpl->previousUpdateScene )
954 Animate( bufferIndex, elapsedSeconds );
956 //Constraint custom objects
957 ConstrainCustomObjects( bufferIndex );
959 //Prepare texture sets and apply constraints to them
960 PrepareTextureSets( bufferIndex );
962 //Clear the lists of renderers from the previous update
963 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
965 mImpl->sortedLayers[i]->ClearRenderables();
968 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
970 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
973 //Update node hierarchy, apply constraints and perform sorting / culling.
974 //This will populate each Layer with a list of renderers which are ready.
975 UpdateNodes( bufferIndex );
977 //Apply constraints to RenderTasks, shaders
978 ConstrainRenderTasks( bufferIndex );
979 ConstrainShaders( bufferIndex );
981 //Update renderers and apply constraints
982 UpdateRenderers( bufferIndex );
984 //Update the trnasformations of all the nodes
985 mImpl->transformManager.Update();
987 //Process Property Notifications
988 ProcessPropertyNotifications( bufferIndex );
990 //Update geometry batcher
991 mImpl->geometryBatcher.Update( bufferIndex );
993 //Process the RenderTasks; this creates the instructions for rendering the next frame.
994 //reset the update buffer index and make sure there is enough room in the instruction container
995 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
996 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
998 if ( NULL != mImpl->root )
1000 ProcessRenderTasks( bufferIndex,
1003 mImpl->sortedLayers,
1004 mImpl->renderSortingHelper,
1005 mImpl->geometryBatcher,
1006 mImpl->renderInstructions );
1008 // Process the system-level RenderTasks last
1009 if ( NULL != mImpl->systemLevelRoot )
1011 ProcessRenderTasks( bufferIndex,
1012 mImpl->systemLevelTaskList,
1013 *mImpl->systemLevelRoot,
1014 mImpl->systemLevelSortedLayers,
1015 mImpl->renderSortingHelper,
1016 mImpl->geometryBatcher,
1017 mImpl->renderInstructions );
1022 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1023 bool doRenderOnceNotify = false;
1024 mImpl->renderTaskWaiting = false;
1025 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1026 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1027 endIter != iter; ++iter )
1029 RenderTask& renderTask(*(*iter));
1031 renderTask.UpdateState();
1033 if( renderTask.IsWaitingToRender() &&
1034 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1036 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1039 if( renderTask.HasRendered() )
1041 doRenderOnceNotify = true;
1045 if( doRenderOnceNotify )
1047 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1048 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1051 // Macro is undefined in release build.
1052 SNAPSHOT_NODE_LOGGING;
1054 // A ResetProperties() may be required in the next frame
1055 mImpl->previousUpdateScene = updateScene;
1057 // Check whether further updates are required
1058 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1060 // tell the update manager that we're done so the queue can be given to event thread
1061 mImpl->notificationManager.UpdateCompleted();
1063 // The update has finished; swap the double-buffering indices
1064 mSceneGraphBuffers.Swap();
1066 return keepUpdating;
1069 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1071 // Update the duration set via Stage::KeepRendering()
1072 if ( mImpl->keepRenderingSeconds > 0.0f )
1074 mImpl->keepRenderingSeconds -= elapsedSeconds;
1077 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1079 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1080 // Keep updating until no messages are received and no animations are running.
1081 // If an animation has just finished, update at least once more for Discard end-actions.
1082 // No need to check for renderQueue as there is always a render after update and if that
1083 // render needs another update it will tell the adaptor to call update again
1085 if ( mImpl->keepRenderingSeconds > 0.0f )
1087 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1090 if ( IsAnimationRunning() ||
1091 mImpl->animationFinishedDuringUpdate )
1093 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1096 if ( mImpl->renderTaskWaiting )
1098 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1101 return keepUpdatingRequest;
1104 void UpdateManager::SetBackgroundColor( const Vector4& color )
1106 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1108 // Reserve some memory inside the render queue
1109 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1111 // Construct message in the render queue memory; note that delete should not be called on the return value
1112 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1115 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1117 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1119 // Reserve some memory inside the render queue
1120 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1122 // Construct message in the render queue memory; note that delete should not be called on the return value
1123 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1126 void UpdateManager::KeepRendering( float durationSeconds )
1128 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1131 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1135 // just copy the vector of pointers
1136 mImpl->sortedLayers = layers;
1140 mImpl->systemLevelSortedLayers = layers;
1144 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1146 mImpl->shaderSaver = &upstream;
1149 void UpdateManager::AddSampler( Render::Sampler* sampler )
1151 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1153 // Reserve some memory inside the render queue
1154 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1156 // Construct message in the render queue memory; note that delete should not be called on the return value
1157 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1160 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1162 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1164 // Reserve some memory inside the render queue
1165 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1167 // Construct message in the render queue memory; note that delete should not be called on the return value
1168 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1171 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1173 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1175 // Reserve some memory inside the render queue
1176 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1178 // Construct message in the render queue memory; note that delete should not be called on the return value
1179 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1182 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
1184 typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > DerivedType;
1186 // Reserve some memory inside the render queue
1187 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1189 // Construct message in the render queue memory; note that delete should not be called on the return value
1190 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1193 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1195 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1197 // Reserve some memory inside the render queue
1198 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1200 // Construct message in the render queue memory; note that delete should not be called on the return value
1201 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1204 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1206 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1208 // Reserve some memory inside the render queue
1209 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1211 // Construct message in the render queue memory; note that delete should not be called on the return value
1212 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1215 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1217 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Render::PropertyBuffer::Format* > DerivedType;
1219 // Reserve some memory inside the render queue
1220 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1222 // Construct message in the render queue memory; note that delete should not be called on the return value
1223 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1226 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data, size_t size )
1228 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, Dali::Vector<char>*, size_t > DerivedType;
1230 // Reserve some memory inside the render queue
1231 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1233 // Construct message in the render queue memory; note that delete should not be called on the return value
1234 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1237 void UpdateManager::AddGeometry( Render::Geometry* geometry )
1239 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1241 // Reserve some memory inside the render queue
1242 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1244 // Construct message in the render queue memory; note that delete should not be called on the return value
1245 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1248 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1250 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1252 // Reserve some memory inside the render queue
1253 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1255 // Construct message in the render queue memory; note that delete should not be called on the return value
1256 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1259 void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
1261 typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > 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::SetGeometryType, geometry, geometryType );
1270 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
1272 typedef IndexBufferMessage< RenderManager > 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, geometry, indices );
1281 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1283 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1285 // Reserve some memory inside the render queue
1286 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1288 // Construct message in the render queue memory; note that delete should not be called on the return value
1289 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1292 void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1294 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > 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::AddVertexBuffer, geometry, propertyBuffer );
1303 void UpdateManager::AddTexture( Render::NewTexture* texture )
1305 typedef MessageValue1< RenderManager, Render::NewTexture* > 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::AddTexture, texture );
1314 void UpdateManager::RemoveTexture( Render::NewTexture* texture)
1316 typedef MessageValue1< RenderManager, Render::NewTexture* > 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::RemoveTexture, texture );
1325 void UpdateManager::UploadTexture( Render::NewTexture* texture, PixelDataPtr pixelData, const NewTexture::UploadParams& params )
1327 typedef MessageValue3< RenderManager, Render::NewTexture*, PixelDataPtr, NewTexture::UploadParams > DerivedType;
1329 // Reserve some memory inside the message queue
1330 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1332 // Construct message in the message queue memory; note that delete should not be called on the return value
1333 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1336 void UpdateManager::GenerateMipmaps( Render::NewTexture* texture )
1338 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1340 // Reserve some memory inside the render queue
1341 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1343 // Construct message in the render queue memory; note that delete should not be called on the return value
1344 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1347 void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
1349 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1351 // Reserve some memory inside the render queue
1352 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1354 // Construct message in the render queue memory; note that delete should not be called on the return value
1355 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1358 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1360 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1362 // Reserve some memory inside the render queue
1363 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1365 // Construct message in the render queue memory; note that delete should not be called on the return value
1366 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1369 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::NewTexture* texture, unsigned int mipmapLevel, unsigned int layer )
1371 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::NewTexture*, unsigned int, unsigned int > DerivedType;
1373 // Reserve some memory inside the render queue
1374 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1376 // Construct message in the render queue memory; note that delete should not be called on the return value
1377 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1380 } // namespace SceneGraph
1382 } // namespace Internal