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>
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 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 geometryBatcher( geometryBatcher ),
150 renderTaskProcessor( renderTaskProcessor ),
151 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
152 taskList( renderMessageDispatcher, resourceManager ),
153 systemLevelTaskList( renderMessageDispatcher, resourceManager ),
155 systemLevelRoot( NULL ),
156 renderers( sceneGraphBuffers, discardQueue ),
158 messageQueue( renderController, sceneGraphBuffers ),
159 keepRenderingSeconds( 0.0f ),
160 animationFinishedDuringUpdate( false ),
161 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
162 previousUpdateScene( false ),
164 renderTaskWaiting( false )
166 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
168 renderers.SetSceneController( *sceneController );
170 discardQueue.SetGeometryBatcher( &geometryBatcher );
172 // create first 'dummy' node
178 // Disconnect render tasks from nodes, before destroying the nodes
179 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
180 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
182 (*iter)->SetSourceNode( NULL );
184 // ..repeat for system level RenderTasks
185 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
186 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
188 (*iter)->SetSourceNode( NULL );
191 // UpdateManager owns the Nodes
192 Vector<Node*>::Iterator iter = nodes.Begin()+1;
193 Vector<Node*>::Iterator endIter = nodes.End();
194 for(;iter!=endIter;++iter)
196 (*iter)->OnDestroy();
200 // If there is root, reset it, otherwise do nothing as rendering was never started
209 if( systemLevelRoot )
211 systemLevelRoot->OnDestroy();
213 delete systemLevelRoot;
214 systemLevelRoot = NULL;
217 delete sceneController;
220 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
221 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
222 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
223 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
224 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
225 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
226 ShaderSaver* shaderSaver; ///< Saves shader binaries.
227 ResourceManager& resourceManager; ///< resource manager
228 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
229 RenderController& renderController; ///< render controller
230 SceneControllerImpl* sceneController; ///< scene controller
231 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
232 RenderQueue& renderQueue; ///< Used to queue messages for the next render
233 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
234 GeometryBatcher& geometryBatcher; ///< An instance of the GeometryBatcher
235 RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
237 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
239 RenderTaskList taskList; ///< The list of scene graph render-tasks
240 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
242 Layer* root; ///< The root node (root is a layer)
243 Layer* systemLevelRoot; ///< A separate root-node for system-level content
245 Vector<Node*> nodes; ///< A container of all instantiated nodes
247 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
248 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
250 OwnerContainer< Camera* > cameras; ///< A container of cameras
251 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
253 AnimationContainer animations; ///< A container of owned animations
254 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
256 ObjectOwnerContainer<Renderer> renderers;
257 TextureSetContainer textureSets; ///< A container of texture sets
259 ShaderContainer shaders; ///< A container of owned shaders
261 MessageQueue messageQueue; ///< The messages queued from the event-thread
262 ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
263 ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event
264 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
266 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
267 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
269 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
270 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
272 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
274 GestureContainer gestures; ///< A container of owned gesture detectors
275 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
278 UpdateManager::UpdateManager( NotificationManager& notificationManager,
279 CompleteNotificationInterface& animationFinishedNotifier,
280 PropertyNotifier& propertyNotifier,
281 ResourceManager& resourceManager,
282 DiscardQueue& discardQueue,
283 RenderController& controller,
284 RenderManager& renderManager,
285 RenderQueue& renderQueue,
286 TextureCacheDispatcher& textureCacheDispatcher,
287 GeometryBatcher& geometryBatcher,
288 RenderTaskProcessor& renderTaskProcessor )
291 mImpl = new Impl( notificationManager,
292 animationFinishedNotifier,
301 renderTaskProcessor );
303 textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers );
304 mImpl->geometryBatcher.SetUpdateManager( this );
307 UpdateManager::~UpdateManager()
312 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
314 DALI_ASSERT_DEBUG( layer->IsLayer() );
315 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
319 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
321 mImpl->root->CreateTransform( &mImpl->transformManager );
325 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
326 mImpl->systemLevelRoot = layer;
327 mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager );
330 layer->SetRoot(true);
333 void UpdateManager::AddNode( Node* node )
335 DALI_ASSERT_ALWAYS( NULL != node );
336 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
338 // Nodes must be sorted by pointer
339 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
340 for(Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter)
344 mImpl->nodes.Insert((iter+1), node);
345 node->CreateTransform( &mImpl->transformManager );
346 node->mGeometryBatcher = &mImpl->geometryBatcher;
352 void UpdateManager::ConnectNode( Node* parent, Node* node )
354 DALI_ASSERT_ALWAYS( NULL != parent );
355 DALI_ASSERT_ALWAYS( NULL != node );
356 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
358 parent->ConnectChild( node );
361 void UpdateManager::DisconnectNode( Node* node )
363 Node* parent = node->GetParent();
364 DALI_ASSERT_ALWAYS( NULL != parent );
365 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
367 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
370 void UpdateManager::DestroyNode( Node* node )
372 DALI_ASSERT_ALWAYS( NULL != node );
373 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
375 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
376 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
377 for(;iter!=endIter;++iter)
381 mImpl->nodes.Erase(iter);
386 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
388 // Notify the Node about impending destruction
392 void UpdateManager::AddCamera( Camera* camera )
394 DALI_ASSERT_DEBUG( camera != NULL );
396 mImpl->cameras.PushBack( camera ); // takes ownership
399 void UpdateManager::RemoveCamera( const Camera* camera )
402 OwnerContainer<Camera*>::Iterator iter = mImpl->cameras.Begin();
403 OwnerContainer<Camera*>::ConstIterator end = mImpl->cameras.End();
404 for ( ; iter != end; ++iter )
406 Camera* value = *iter;
407 if ( camera == value )
409 // Transfer ownership to the discard queue
410 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->cameras.Release( iter ) );
418 void UpdateManager::AddObject( PropertyOwner* object )
420 DALI_ASSERT_DEBUG( NULL != object );
422 mImpl->customObjects.PushBack( object );
425 void UpdateManager::RemoveObject( PropertyOwner* object )
427 DALI_ASSERT_DEBUG( NULL != object );
429 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
431 // Find the object and destroy it
432 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
434 PropertyOwner* current = *iter;
435 if ( current == object )
437 customObjects.Erase( iter );
442 // Should not reach here
443 DALI_ASSERT_DEBUG(false);
446 void UpdateManager::AddAnimation( Animation* animation )
448 mImpl->animations.PushBack( animation );
451 void UpdateManager::StopAnimation( Animation* animation )
453 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
455 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
457 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
460 void UpdateManager::RemoveAnimation( Animation* animation )
462 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
464 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
466 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
469 bool UpdateManager::IsAnimationRunning() const
471 bool isRunning(false);
472 AnimationContainer& animations = mImpl->animations;
474 // Find any animation that isn't stopped or paused
476 const AnimationIter endIter = animations.End();
477 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
479 const Animation::State state = (*iter)->GetState();
481 if (state != Animation::Stopped &&
482 state != Animation::Paused)
491 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
493 mImpl->propertyNotifications.PushBack( propertyNotification );
496 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
498 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
499 PropertyNotificationIter iter = propertyNotifications.Begin();
501 while ( iter != propertyNotifications.End() )
503 if( *iter == propertyNotification )
505 propertyNotifications.Erase(iter);
512 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
514 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
515 propertyNotification->SetNotifyMode( notifyMode );
518 ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
520 return mImpl->renderers;
523 void UpdateManager::AddShader( Shader* shader )
525 DALI_ASSERT_DEBUG( NULL != shader );
527 if( mImpl->shaders.Count() == 0 )
529 // the first added shader becomes our default shader
530 // Construct message in the render queue memory; note that delete should not be called on the return value
531 typedef MessageValue1< RenderManager, Shader* > DerivedType;
533 // Reserve some memory inside the render queue
534 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
536 // Construct message in the render queue memory; note that delete should not be called on the return value
537 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
540 mImpl->shaders.PushBack( shader );
543 void UpdateManager::RemoveShader( Shader* shader )
545 DALI_ASSERT_DEBUG(shader != NULL);
547 ShaderContainer& shaders = mImpl->shaders;
549 // Find the shader and destroy it
550 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
552 Shader& current = **iter;
553 if ( ¤t == shader )
555 // Transfer ownership to the discard queue
556 // This keeps the shader alive, until the render-thread has finished with it
557 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
562 // Should not reach here
563 DALI_ASSERT_DEBUG(false);
566 void UpdateManager::SetShaderProgram( Shader* shader,
567 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
572 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
574 // Reserve some memory inside the render queue
575 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
577 // Construct message in the render queue memory; note that delete should not be called on the return value
578 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
582 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
584 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
585 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
587 // lock as update might be sending previously compiled shaders to event thread
588 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
589 mImpl->renderCompiledShaders.push_back( shaderData );
593 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
597 // copy the list, this is only likely to happen once in application life cycle
598 return &(mImpl->taskList);
602 // copy the list, this is only likely to happen once in application life cycle
603 return &(mImpl->systemLevelTaskList);
607 void UpdateManager::AddGesture( PanGesture* gesture )
609 DALI_ASSERT_DEBUG( NULL != gesture );
611 mImpl->gestures.PushBack( gesture );
614 void UpdateManager::RemoveGesture( PanGesture* gesture )
616 DALI_ASSERT_DEBUG( gesture != NULL );
618 GestureContainer& gestures = mImpl->gestures;
620 // Find the gesture and destroy it
621 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
623 PanGesture& current = **iter;
624 if ( ¤t == gesture )
626 mImpl->gestures.Erase( iter );
630 // Should not reach here
631 DALI_ASSERT_DEBUG(false);
634 void UpdateManager::AddTextureSet( TextureSet* textureSet )
636 DALI_ASSERT_DEBUG( NULL != textureSet );
637 mImpl->textureSets.PushBack( textureSet );
640 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
642 DALI_ASSERT_DEBUG(textureSet != NULL);
643 size_t textureSetCount( mImpl->textureSets.Size() );
644 for( size_t i(0); i<textureSetCount; ++i )
646 if( textureSet == mImpl->textureSets[i] )
648 mImpl->textureSets.Remove( mImpl->textureSets.Begin() + i );
654 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
656 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
659 void UpdateManager::EventProcessingStarted()
661 mImpl->messageQueue.EventProcessingStarted();
664 bool UpdateManager::FlushQueue()
666 return mImpl->messageQueue.FlushQueue();
669 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
671 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
672 mImpl->animationFinishedDuringUpdate = false;
674 // Animated properties have to be reset to their original value each frame
676 // Reset root properties
679 mImpl->root->ResetToBaseValues( bufferIndex );
681 if ( mImpl->systemLevelRoot )
683 mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
686 // Reset all the nodes
687 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
688 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
689 for(;iter != endIter; ++iter)
691 (*iter)->ResetToBaseValues( bufferIndex );
694 // Reset system-level render-task list properties to base values
695 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
697 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
699 (*iter)->ResetToBaseValues( bufferIndex );
702 // Reset render-task list properties to base values.
703 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
705 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
707 (*iter)->ResetToBaseValues( bufferIndex );
710 // Reset custom object properties to base values
711 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
713 (*iter)->ResetToBaseValues( bufferIndex );
716 mImpl->renderers.ResetToBaseValues( bufferIndex );
718 // Reset animatable shader properties to base values
719 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
721 (*iter)->ResetToBaseValues( bufferIndex );
725 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
727 bool gestureUpdated( false );
729 // constrain gestures... (in construction order)
730 GestureContainer& gestures = mImpl->gestures;
732 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
734 PanGesture& gesture = **iter;
735 gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
736 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
739 return gestureUpdated;
742 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
744 AnimationContainer &animations = mImpl->animations;
745 AnimationIter iter = animations.Begin();
746 bool animationLooped = false;
747 while ( iter != animations.End() )
749 Animation* animation = *iter;
750 bool finished = false;
752 animation->Update( bufferIndex, elapsedSeconds, looped, finished );
754 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
755 animationLooped = animationLooped || looped;
757 // Remove animations that had been destroyed but were still waiting for an update
758 if (animation->GetState() == Animation::Destroyed)
760 iter = animations.Erase(iter);
768 // queue the notification on finished or looped (to update loop count)
769 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
771 // The application should be notified by NotificationManager, in another thread
772 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
776 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
778 //Constrain custom objects (in construction order)
779 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
780 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
781 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
783 PropertyOwner& object = **iter;
784 ConstrainPropertyOwner( object, bufferIndex );
788 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
790 // Constrain system-level render-tasks
791 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
792 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
794 RenderTask& task = **iter;
795 ConstrainPropertyOwner( task, bufferIndex );
798 // Constrain render-tasks
799 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
800 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
802 RenderTask& task = **iter;
803 ConstrainPropertyOwner( task, bufferIndex );
807 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
809 // constrain shaders... (in construction order)
810 ShaderContainer& shaders = mImpl->shaders;
811 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
813 Shader& shader = **iter;
814 ConstrainPropertyOwner( shader, bufferIndex );
818 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
820 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
821 PropertyNotificationIter iter = notifications.Begin();
823 while ( iter != notifications.End() )
825 PropertyNotification* notification = *iter;
826 bool valid = notification->Check( bufferIndex );
829 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
835 void UpdateManager::PrepareTextureSets( BufferIndex bufferIndex )
837 size_t textureSetCount( mImpl->textureSets.Size() );
838 for( size_t i(0); i<textureSetCount; ++i )
840 //Prepare texture set
841 mImpl->textureSets[i]->Prepare( mImpl->resourceManager );
845 void UpdateManager::ForwardCompiledShadersToEventThread()
847 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
848 if( mImpl->shaderSaver )
850 // lock and swap the queues
852 // render might be attempting to send us more binaries at the same time
853 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
854 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
857 if( mImpl->updateCompiledShaders.size() > 0 )
859 ShaderSaver& factory = *mImpl->shaderSaver;
860 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
861 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
862 for( ; i != end; ++i )
864 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
866 // we don't need them in update anymore
867 mImpl->updateCompiledShaders.clear();
872 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
874 const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
875 unsigned int rendererCount( rendererContainer.Size() );
876 for( unsigned int i(0); i<rendererCount; ++i )
879 ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
881 rendererContainer[i]->PrepareRender( bufferIndex );
885 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
887 mImpl->nodeDirtyFlags = NothingFlag;
894 // Prepare resources, update shaders, for each node
895 // And add the renderers to the sorted layers. Start from root, which is also a layer
896 mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
898 mImpl->resourceManager,
899 mImpl->renderQueue );
901 if ( mImpl->systemLevelRoot )
903 mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
905 mImpl->resourceManager,
906 mImpl->renderQueue );
910 unsigned int UpdateManager::Update( float elapsedSeconds,
911 unsigned int lastVSyncTimeMilliseconds,
912 unsigned int nextVSyncTimeMilliseconds )
914 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
916 //Clear nodes/resources which were previously discarded
917 mImpl->discardQueue.Clear( bufferIndex );
919 //Grab any loaded resources
920 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
922 //Process Touches & Gestures
923 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
925 const bool updateScene = // The scene-graph requires an update if..
926 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
927 IsAnimationRunning() || // ..at least one animation is running OR
928 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
929 resourceChanged || // ..one or more resources were updated/changed OR
930 gestureUpdated; // ..a gesture property was updated
933 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
934 // values if the scene was updated in the previous frame.
935 if( updateScene || mImpl->previousUpdateScene )
937 //Reset properties from the previous update
938 ResetProperties( bufferIndex );
939 mImpl->transformManager.ResetToBaseValue();
942 //Process the queued scene messages
943 mImpl->messageQueue.ProcessMessages( bufferIndex );
945 //Post Process Ids of resources updated by renderer
946 mImpl->resourceManager.PostProcessResources( bufferIndex );
948 //Forward compiled shader programs to event thread for saving
949 ForwardCompiledShadersToEventThread();
951 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
952 // renderer lists if the scene was updated in the previous frame.
953 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
954 if( updateScene || mImpl->previousUpdateScene )
957 Animate( bufferIndex, elapsedSeconds );
959 //Constraint custom objects
960 ConstrainCustomObjects( bufferIndex );
962 //Prepare texture sets and apply constraints to them
963 PrepareTextureSets( bufferIndex );
965 //Clear the lists of renderers from the previous update
966 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
968 mImpl->sortedLayers[i]->ClearRenderables();
971 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
973 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
976 //Update node hierarchy, apply constraints and perform sorting / culling.
977 //This will populate each Layer with a list of renderers which are ready.
978 UpdateNodes( bufferIndex );
980 //Apply constraints to RenderTasks, shaders
981 ConstrainRenderTasks( bufferIndex );
982 ConstrainShaders( bufferIndex );
984 //Update renderers and apply constraints
985 UpdateRenderers( bufferIndex );
987 //Update the trnasformations of all the nodes
988 mImpl->transformManager.Update();
990 //Process Property Notifications
991 ProcessPropertyNotifications( bufferIndex );
993 //Update geometry batcher
994 mImpl->geometryBatcher.Update( bufferIndex );
996 //Process the RenderTasks; this creates the instructions for rendering the next frame.
997 //reset the update buffer index and make sure there is enough room in the instruction container
998 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
999 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1001 if ( NULL != mImpl->root )
1003 mImpl->renderTaskProcessor.Process( bufferIndex,
1006 mImpl->sortedLayers,
1007 mImpl->geometryBatcher,
1008 mImpl->renderInstructions );
1010 // Process the system-level RenderTasks last
1011 if ( NULL != mImpl->systemLevelRoot )
1013 mImpl->renderTaskProcessor.Process( bufferIndex,
1014 mImpl->systemLevelTaskList,
1015 *mImpl->systemLevelRoot,
1016 mImpl->systemLevelSortedLayers,
1017 mImpl->geometryBatcher,
1018 mImpl->renderInstructions );
1023 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1024 bool doRenderOnceNotify = false;
1025 mImpl->renderTaskWaiting = false;
1026 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1027 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1028 endIter != iter; ++iter )
1030 RenderTask& renderTask(*(*iter));
1032 renderTask.UpdateState();
1034 if( renderTask.IsWaitingToRender() &&
1035 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1037 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1040 if( renderTask.HasRendered() )
1042 doRenderOnceNotify = true;
1046 if( doRenderOnceNotify )
1048 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1049 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1052 // Macro is undefined in release build.
1053 SNAPSHOT_NODE_LOGGING;
1055 // A ResetProperties() may be required in the next frame
1056 mImpl->previousUpdateScene = updateScene;
1058 // Check whether further updates are required
1059 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1061 // tell the update manager that we're done so the queue can be given to event thread
1062 mImpl->notificationManager.UpdateCompleted();
1064 // The update has finished; swap the double-buffering indices
1065 mSceneGraphBuffers.Swap();
1067 return keepUpdating;
1070 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1072 // Update the duration set via Stage::KeepRendering()
1073 if ( mImpl->keepRenderingSeconds > 0.0f )
1075 mImpl->keepRenderingSeconds -= elapsedSeconds;
1078 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1080 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1081 // Keep updating until no messages are received and no animations are running.
1082 // If an animation has just finished, update at least once more for Discard end-actions.
1083 // No need to check for renderQueue as there is always a render after update and if that
1084 // render needs another update it will tell the adaptor to call update again
1086 if ( mImpl->keepRenderingSeconds > 0.0f )
1088 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1091 if ( IsAnimationRunning() ||
1092 mImpl->animationFinishedDuringUpdate )
1094 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1097 if ( mImpl->renderTaskWaiting )
1099 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1102 return keepUpdatingRequest;
1105 void UpdateManager::SetBackgroundColor( const Vector4& color )
1107 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1109 // Reserve some memory inside the render queue
1110 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1112 // Construct message in the render queue memory; note that delete should not be called on the return value
1113 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1116 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1118 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1120 // Reserve some memory inside the render queue
1121 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1123 // Construct message in the render queue memory; note that delete should not be called on the return value
1124 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1127 void UpdateManager::KeepRendering( float durationSeconds )
1129 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1132 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1136 // just copy the vector of pointers
1137 mImpl->sortedLayers = layers;
1141 mImpl->systemLevelSortedLayers = layers;
1145 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1147 mImpl->shaderSaver = &upstream;
1150 void UpdateManager::AddSampler( Render::Sampler* sampler )
1152 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1154 // Reserve some memory inside the render queue
1155 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1157 // Construct message in the render queue memory; note that delete should not be called on the return value
1158 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1161 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1163 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1165 // Reserve some memory inside the render queue
1166 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1168 // Construct message in the render queue memory; note that delete should not be called on the return value
1169 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1172 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1174 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1176 // Reserve some memory inside the render queue
1177 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1179 // Construct message in the render queue memory; note that delete should not be called on the return value
1180 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1183 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
1185 typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > DerivedType;
1187 // Reserve some memory inside the render queue
1188 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1190 // Construct message in the render queue memory; note that delete should not be called on the return value
1191 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1194 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1196 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1198 // Reserve some memory inside the render queue
1199 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1201 // Construct message in the render queue memory; note that delete should not be called on the return value
1202 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1205 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1207 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1209 // Reserve some memory inside the render queue
1210 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1212 // Construct message in the render queue memory; note that delete should not be called on the return value
1213 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1216 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1218 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Render::PropertyBuffer::Format* > DerivedType;
1220 // Reserve some memory inside the render queue
1221 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1223 // Construct message in the render queue memory; note that delete should not be called on the return value
1224 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1227 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data, size_t size )
1229 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, Dali::Vector<char>*, size_t > DerivedType;
1231 // Reserve some memory inside the render queue
1232 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1234 // Construct message in the render queue memory; note that delete should not be called on the return value
1235 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1238 void UpdateManager::AddGeometry( Render::Geometry* geometry )
1240 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1242 // Reserve some memory inside the render queue
1243 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1245 // Construct message in the render queue memory; note that delete should not be called on the return value
1246 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1249 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1251 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1253 // Reserve some memory inside the render queue
1254 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1256 // Construct message in the render queue memory; note that delete should not be called on the return value
1257 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1260 void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
1262 typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType;
1264 // Reserve some memory inside the render queue
1265 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1267 // Construct message in the render queue memory; note that delete should not be called on the return value
1268 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1271 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
1273 typedef IndexBufferMessage< RenderManager > DerivedType;
1275 // Reserve some memory inside the render queue
1276 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1278 // Construct message in the render queue memory; note that delete should not be called on the return value
1279 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1282 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1284 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1286 // Reserve some memory inside the render queue
1287 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1289 // Construct message in the render queue memory; note that delete should not be called on the return value
1290 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1293 void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1295 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1297 // Reserve some memory inside the render queue
1298 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1300 // Construct message in the render queue memory; note that delete should not be called on the return value
1301 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, geometry, propertyBuffer );
1304 void UpdateManager::AddTexture( Render::NewTexture* texture )
1306 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1308 // Reserve some memory inside the render queue
1309 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1311 // Construct message in the render queue memory; note that delete should not be called on the return value
1312 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1315 void UpdateManager::RemoveTexture( Render::NewTexture* texture)
1317 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1319 // Reserve some memory inside the render queue
1320 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1322 // Construct message in the render queue memory; note that delete should not be called on the return value
1323 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1326 void UpdateManager::UploadTexture( Render::NewTexture* texture, PixelDataPtr pixelData, const NewTexture::UploadParams& params )
1328 typedef MessageValue3< RenderManager, Render::NewTexture*, PixelDataPtr, NewTexture::UploadParams > DerivedType;
1330 // Reserve some memory inside the message queue
1331 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1333 // Construct message in the message queue memory; note that delete should not be called on the return value
1334 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1337 void UpdateManager::GenerateMipmaps( Render::NewTexture* texture )
1339 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1341 // Reserve some memory inside the render queue
1342 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1344 // Construct message in the render queue memory; note that delete should not be called on the return value
1345 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1348 void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
1350 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1352 // Reserve some memory inside the render queue
1353 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1355 // Construct message in the render queue memory; note that delete should not be called on the return value
1356 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1359 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1361 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1363 // Reserve some memory inside the render queue
1364 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1366 // Construct message in the render queue memory; note that delete should not be called on the return value
1367 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1370 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::NewTexture* texture, unsigned int mipmapLevel, unsigned int layer )
1372 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::NewTexture*, unsigned int, unsigned int > DerivedType;
1374 // Reserve some memory inside the render queue
1375 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1377 // Construct message in the render queue memory; note that delete should not be called on the return value
1378 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1381 } // namespace SceneGraph
1383 } // namespace Internal