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>
62 #include <dali/internal/render/common/render-instruction-container.h>
63 #include <dali/internal/render/common/render-manager.h>
64 #include <dali/internal/render/queue/render-queue.h>
65 #include <dali/internal/render/gl-resources/texture-cache.h>
66 #include <dali/internal/render/shaders/scene-graph-shader.h>
67 #include <dali/internal/render/renderers/render-frame-buffer.h>
68 #include <dali/internal/render/renderers/render-sampler.h>
69 #include <dali/internal/update/render-tasks/scene-graph-camera.h>
71 // Un-comment to enable node tree debug logging
72 //#define NODE_TREE_LOGGING 1
74 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
75 #define SNAPSHOT_NODE_LOGGING \
76 const int FRAME_COUNT_TRIGGER = 16;\
77 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
79 if ( NULL != mImpl->root )\
81 mImpl->frameCounter = 0;\
82 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
85 mImpl->frameCounter++;
87 #define SNAPSHOT_NODE_LOGGING
90 #if defined(DEBUG_ENABLED)
91 extern Debug::Filter* gRenderTaskLogFilter;
95 using namespace Dali::Integration;
96 using Dali::Internal::Update::MessageQueue;
107 typedef OwnerContainer< Shader* > ShaderContainer;
108 typedef ShaderContainer::Iterator ShaderIter;
109 typedef ShaderContainer::ConstIterator ShaderConstIter;
111 typedef std::vector<Internal::ShaderDataPtr> ShaderDataBinaryQueue;
113 typedef OwnerContainer<PanGesture*> GestureContainer;
114 typedef GestureContainer::Iterator GestureIter;
115 typedef GestureContainer::ConstIterator GestureConstIter;
117 typedef OwnerContainer< TextureSet* > TextureSetContainer;
118 typedef TextureSetContainer::Iterator TextureSetIter;
119 typedef TextureSetContainer::ConstIterator TextureSetConstIter;
122 * Structure to contain UpdateManager internal data
124 struct UpdateManager::Impl
126 Impl( NotificationManager& notificationManager,
127 CompleteNotificationInterface& animationFinishedNotifier,
128 PropertyNotifier& propertyNotifier,
129 ResourceManager& resourceManager,
130 DiscardQueue& discardQueue,
131 RenderController& renderController,
132 RenderManager& renderManager,
133 RenderQueue& renderQueue,
134 SceneGraphBuffers& sceneGraphBuffers )
135 : 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 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
149 taskList( renderMessageDispatcher, resourceManager ),
150 systemLevelTaskList( renderMessageDispatcher, resourceManager ),
152 systemLevelRoot( NULL ),
153 renderers( sceneGraphBuffers, discardQueue ),
155 messageQueue( renderController, sceneGraphBuffers ),
156 keepRenderingSeconds( 0.0f ),
157 animationFinishedDuringUpdate( false ),
158 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
159 previousUpdateScene( false ),
161 renderSortingHelper(),
162 renderTaskWaiting( false )
164 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
166 renderers.SetSceneController( *sceneController );
168 // create first 'dummy' node
174 // Disconnect render tasks from nodes, before destroying the nodes
175 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
176 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
178 (*iter)->SetSourceNode( NULL );
180 // ..repeat for system level RenderTasks
181 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
182 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
184 (*iter)->SetSourceNode( NULL );
187 // UpdateManager owns the Nodes
188 Vector<Node*>::Iterator iter = nodes.Begin()+1;
189 Vector<Node*>::Iterator endIter = nodes.End();
190 for(;iter!=endIter;++iter)
192 (*iter)->OnDestroy();
196 // If there is root, reset it, otherwise do nothing as rendering was never started
205 if( systemLevelRoot )
207 systemLevelRoot->OnDestroy();
209 delete systemLevelRoot;
210 systemLevelRoot = NULL;
213 delete sceneController;
216 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
217 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
218 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
219 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
220 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
221 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
222 ShaderSaver* shaderSaver; ///< Saves shader binaries.
223 ResourceManager& resourceManager; ///< resource manager
224 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
225 RenderController& renderController; ///< render controller
226 SceneControllerImpl* sceneController; ///< scene controller
227 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
228 RenderQueue& renderQueue; ///< Used to queue messages for the next render
229 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
231 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
233 RenderTaskList taskList; ///< The list of scene graph render-tasks
234 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
236 Layer* root; ///< The root node (root is a layer)
237 Layer* systemLevelRoot; ///< A separate root-node for system-level content
239 Vector<Node*> nodes; ///< A container of all instantiated nodes
241 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
242 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
244 OwnerContainer< Camera* > cameras; ///< A container of cameras
245 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
247 AnimationContainer animations; ///< A container of owned animations
248 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
250 ObjectOwnerContainer<Renderer> renderers;
251 TextureSetContainer textureSets; ///< A container of texture sets
253 ShaderContainer shaders; ///< A container of owned shaders
255 MessageQueue messageQueue; ///< The messages queued from the event-thread
256 ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
257 ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event
258 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
260 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
261 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
263 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
264 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
266 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
267 RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
269 GestureContainer gestures; ///< A container of owned gesture detectors
270 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
273 UpdateManager::UpdateManager( NotificationManager& notificationManager,
274 CompleteNotificationInterface& animationFinishedNotifier,
275 PropertyNotifier& propertyNotifier,
276 ResourceManager& resourceManager,
277 DiscardQueue& discardQueue,
278 RenderController& controller,
279 RenderManager& renderManager,
280 RenderQueue& renderQueue,
281 TextureCacheDispatcher& textureCacheDispatcher )
284 mImpl = new Impl( notificationManager,
285 animationFinishedNotifier,
292 mSceneGraphBuffers );
294 textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers );
297 UpdateManager::~UpdateManager()
302 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
304 DALI_ASSERT_DEBUG( layer->IsLayer() );
305 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
309 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
311 mImpl->root->CreateTransform( &mImpl->transformManager);
315 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
316 mImpl->systemLevelRoot = layer;
317 mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager);
320 layer->SetRoot(true);
323 void UpdateManager::AddNode( Node* node )
325 DALI_ASSERT_ALWAYS( NULL != node );
326 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
328 // Nodes must be sorted by pointer
329 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
330 for(Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter)
334 mImpl->nodes.Insert((iter+1), node);
335 node->CreateTransform( &mImpl->transformManager);
341 void UpdateManager::ConnectNode( Node* parent, Node* node )
343 DALI_ASSERT_ALWAYS( NULL != parent );
344 DALI_ASSERT_ALWAYS( NULL != node );
345 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
347 parent->ConnectChild( node );
350 void UpdateManager::DisconnectNode( Node* node )
352 Node* parent = node->GetParent();
353 DALI_ASSERT_ALWAYS( NULL != parent );
354 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
356 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
359 void UpdateManager::DestroyNode( Node* node )
361 DALI_ASSERT_ALWAYS( NULL != node );
362 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
364 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
365 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
366 for(;iter!=endIter;++iter)
370 mImpl->nodes.Erase(iter);
375 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
377 // Notify the Node about impending destruction
381 void UpdateManager::AddCamera( Camera* camera )
383 DALI_ASSERT_DEBUG( camera != NULL );
385 mImpl->cameras.PushBack( camera ); // takes ownership
388 void UpdateManager::RemoveCamera( const Camera* camera )
391 OwnerContainer<Camera*>::Iterator iter = mImpl->cameras.Begin();
392 OwnerContainer<Camera*>::ConstIterator end = mImpl->cameras.End();
393 for ( ; iter != end; ++iter )
395 Camera* value = *iter;
396 if ( camera == value )
398 // Transfer ownership to the discard queue
399 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->cameras.Release( iter ) );
407 void UpdateManager::AddObject( PropertyOwner* object )
409 DALI_ASSERT_DEBUG( NULL != object );
411 mImpl->customObjects.PushBack( object );
414 void UpdateManager::RemoveObject( PropertyOwner* object )
416 DALI_ASSERT_DEBUG( NULL != object );
418 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
420 // Find the object and destroy it
421 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
423 PropertyOwner* current = *iter;
424 if ( current == object )
426 customObjects.Erase( iter );
431 // Should not reach here
432 DALI_ASSERT_DEBUG(false);
435 void UpdateManager::AddAnimation( Animation* animation )
437 mImpl->animations.PushBack( animation );
440 void UpdateManager::StopAnimation( Animation* animation )
442 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
444 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
446 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
449 void UpdateManager::RemoveAnimation( Animation* animation )
451 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
453 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
455 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
458 bool UpdateManager::IsAnimationRunning() const
460 bool isRunning(false);
461 AnimationContainer& animations = mImpl->animations;
463 // Find any animation that isn't stopped or paused
465 const AnimationIter endIter = animations.End();
466 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
468 const Animation::State state = (*iter)->GetState();
470 if (state != Animation::Stopped &&
471 state != Animation::Paused)
480 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
482 mImpl->propertyNotifications.PushBack( propertyNotification );
485 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
487 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
488 PropertyNotificationIter iter = propertyNotifications.Begin();
490 while ( iter != propertyNotifications.End() )
492 if( *iter == propertyNotification )
494 propertyNotifications.Erase(iter);
501 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
503 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
504 propertyNotification->SetNotifyMode( notifyMode );
507 ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
509 return mImpl->renderers;
512 void UpdateManager::AddShader( Shader* shader )
514 DALI_ASSERT_DEBUG( NULL != shader );
516 if( mImpl->shaders.Count() == 0 )
518 // the first added shader becomes our default shader
519 // Construct message in the render queue memory; note that delete should not be called on the return value
520 typedef MessageValue1< RenderManager, Shader* > DerivedType;
522 // Reserve some memory inside the render queue
523 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
525 // Construct message in the render queue memory; note that delete should not be called on the return value
526 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
529 mImpl->shaders.PushBack( shader );
532 void UpdateManager::RemoveShader( Shader* shader )
534 DALI_ASSERT_DEBUG(shader != NULL);
536 ShaderContainer& shaders = mImpl->shaders;
538 // Find the shader and destroy it
539 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
541 Shader& current = **iter;
542 if ( ¤t == shader )
544 // Transfer ownership to the discard queue
545 // This keeps the shader alive, until the render-thread has finished with it
546 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
551 // Should not reach here
552 DALI_ASSERT_DEBUG(false);
555 void UpdateManager::SetShaderProgram( Shader* shader,
556 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
561 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
563 // Reserve some memory inside the render queue
564 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
566 // Construct message in the render queue memory; note that delete should not be called on the return value
567 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
571 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
573 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
574 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
576 // lock as update might be sending previously compiled shaders to event thread
577 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
578 mImpl->renderCompiledShaders.push_back( shaderData );
582 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
586 // copy the list, this is only likely to happen once in application life cycle
587 return &(mImpl->taskList);
591 // copy the list, this is only likely to happen once in application life cycle
592 return &(mImpl->systemLevelTaskList);
596 void UpdateManager::AddGesture( PanGesture* gesture )
598 DALI_ASSERT_DEBUG( NULL != gesture );
600 mImpl->gestures.PushBack( gesture );
603 void UpdateManager::RemoveGesture( PanGesture* gesture )
605 DALI_ASSERT_DEBUG( gesture != NULL );
607 GestureContainer& gestures = mImpl->gestures;
609 // Find the gesture and destroy it
610 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
612 PanGesture& current = **iter;
613 if ( ¤t == gesture )
615 mImpl->gestures.Erase( iter );
619 // Should not reach here
620 DALI_ASSERT_DEBUG(false);
623 void UpdateManager::AddTextureSet( TextureSet* textureSet )
625 DALI_ASSERT_DEBUG( NULL != textureSet );
626 mImpl->textureSets.PushBack( textureSet );
629 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
631 DALI_ASSERT_DEBUG(textureSet != NULL);
632 size_t textureSetCount( mImpl->textureSets.Size() );
633 for( size_t i(0); i<textureSetCount; ++i )
635 if( textureSet == mImpl->textureSets[i] )
637 mImpl->textureSets.Remove( mImpl->textureSets.Begin() + i );
643 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
645 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
648 void UpdateManager::EventProcessingStarted()
650 mImpl->messageQueue.EventProcessingStarted();
653 bool UpdateManager::FlushQueue()
655 return mImpl->messageQueue.FlushQueue();
658 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
660 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
661 mImpl->animationFinishedDuringUpdate = false;
663 // Animated properties have to be reset to their original value each frame
665 // Reset root properties
668 mImpl->root->ResetToBaseValues( bufferIndex );
670 if ( mImpl->systemLevelRoot )
672 mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
675 // Reset all the nodes
676 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
677 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
678 for(;iter != endIter; ++iter)
680 (*iter)->ResetToBaseValues( bufferIndex );
683 // Reset system-level render-task list properties to base values
684 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
686 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
688 (*iter)->ResetToBaseValues( bufferIndex );
691 // Reset render-task list properties to base values.
692 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
694 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
696 (*iter)->ResetToBaseValues( bufferIndex );
699 // Reset custom object properties to base values
700 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
702 (*iter)->ResetToBaseValues( bufferIndex );
705 mImpl->renderers.ResetToBaseValues( bufferIndex );
707 // Reset animatable shader properties to base values
708 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
710 (*iter)->ResetToBaseValues( bufferIndex );
714 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
716 bool gestureUpdated( false );
718 // constrain gestures... (in construction order)
719 GestureContainer& gestures = mImpl->gestures;
721 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
723 PanGesture& gesture = **iter;
724 gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
725 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
728 return gestureUpdated;
731 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
733 AnimationContainer &animations = mImpl->animations;
734 AnimationIter iter = animations.Begin();
735 bool animationLooped = false;
736 while ( iter != animations.End() )
738 Animation* animation = *iter;
739 bool finished = false;
741 animation->Update( bufferIndex, elapsedSeconds, looped, finished );
743 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
744 animationLooped = animationLooped || looped;
746 // Remove animations that had been destroyed but were still waiting for an update
747 if (animation->GetState() == Animation::Destroyed)
749 iter = animations.Erase(iter);
757 // queue the notification on finished or looped (to update loop count)
758 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
760 // The application should be notified by NotificationManager, in another thread
761 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
765 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
767 //Constrain custom objects (in construction order)
768 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
769 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
770 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
772 PropertyOwner& object = **iter;
773 ConstrainPropertyOwner( object, bufferIndex );
777 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
779 // Constrain system-level render-tasks
780 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
781 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
783 RenderTask& task = **iter;
784 ConstrainPropertyOwner( task, bufferIndex );
787 // Constrain render-tasks
788 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
789 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
791 RenderTask& task = **iter;
792 ConstrainPropertyOwner( task, bufferIndex );
796 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
798 // constrain shaders... (in construction order)
799 ShaderContainer& shaders = mImpl->shaders;
800 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
802 Shader& shader = **iter;
803 ConstrainPropertyOwner( shader, bufferIndex );
807 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
809 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
810 PropertyNotificationIter iter = notifications.Begin();
812 while ( iter != notifications.End() )
814 PropertyNotification* notification = *iter;
815 bool valid = notification->Check( bufferIndex );
818 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
824 void UpdateManager::PrepareTextureSets( BufferIndex bufferIndex )
826 size_t textureSetCount( mImpl->textureSets.Size() );
827 for( size_t i(0); i<textureSetCount; ++i )
829 //Prepare texture set
830 mImpl->textureSets[i]->Prepare( mImpl->resourceManager );
834 void UpdateManager::ForwardCompiledShadersToEventThread()
836 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
837 if( mImpl->shaderSaver )
839 // lock and swap the queues
841 // render might be attempting to send us more binaries at the same time
842 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
843 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
846 if( mImpl->updateCompiledShaders.size() > 0 )
848 ShaderSaver& factory = *mImpl->shaderSaver;
849 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
850 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
851 for( ; i != end; ++i )
853 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
855 // we don't need them in update anymore
856 mImpl->updateCompiledShaders.clear();
861 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
863 const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
864 unsigned int rendererCount( rendererContainer.Size() );
865 for( unsigned int i(0); i<rendererCount; ++i )
868 ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
870 rendererContainer[i]->PrepareRender( bufferIndex );
874 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
876 mImpl->nodeDirtyFlags = NothingFlag;
883 // Prepare resources, update shaders, for each node
884 // And add the renderers to the sorted layers. Start from root, which is also a layer
885 mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
887 mImpl->resourceManager,
888 mImpl->renderQueue );
890 if ( mImpl->systemLevelRoot )
892 mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
894 mImpl->resourceManager,
895 mImpl->renderQueue );
899 unsigned int UpdateManager::Update( float elapsedSeconds,
900 unsigned int lastVSyncTimeMilliseconds,
901 unsigned int nextVSyncTimeMilliseconds )
903 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
905 //Clear nodes/resources which were previously discarded
906 mImpl->discardQueue.Clear( bufferIndex );
908 //Grab any loaded resources
909 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
911 //Process Touches & Gestures
912 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
914 const bool updateScene = // The scene-graph requires an update if..
915 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
916 IsAnimationRunning() || // ..at least one animation is running OR
917 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
918 resourceChanged || // ..one or more resources were updated/changed OR
919 gestureUpdated; // ..a gesture property was updated
922 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
923 // values if the scene was updated in the previous frame.
924 if( updateScene || mImpl->previousUpdateScene )
926 //Reset properties from the previous update
927 ResetProperties( bufferIndex );
928 mImpl->transformManager.ResetToBaseValue();
931 //Process the queued scene messages
932 mImpl->messageQueue.ProcessMessages( bufferIndex );
934 //Post Process Ids of resources updated by renderer
935 mImpl->resourceManager.PostProcessResources( bufferIndex );
937 //Forward compiled shader programs to event thread for saving
938 ForwardCompiledShadersToEventThread();
940 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
941 // renderer lists if the scene was updated in the previous frame.
942 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
943 if( updateScene || mImpl->previousUpdateScene )
946 Animate( bufferIndex, elapsedSeconds );
948 //Constraint custom objects
949 ConstrainCustomObjects( bufferIndex );
951 //Prepare texture sets and apply constraints to them
952 PrepareTextureSets( bufferIndex );
954 //Clear the lists of renderers from the previous update
955 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
957 mImpl->sortedLayers[i]->ClearRenderables();
960 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
962 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
965 //Update node hierarchy, apply constraints and perform sorting / culling.
966 //This will populate each Layer with a list of renderers which are ready.
967 UpdateNodes( bufferIndex );
969 //Apply constraints to RenderTasks, shaders
970 ConstrainRenderTasks( bufferIndex );
971 ConstrainShaders( bufferIndex );
973 //Update renderers and apply constraints
974 UpdateRenderers( bufferIndex );
976 //Update the trnasformations of all the nodes
977 mImpl->transformManager.Update();
979 //Process Property Notifications
980 ProcessPropertyNotifications( bufferIndex );
982 //Process the RenderTasks; this creates the instructions for rendering the next frame.
983 //reset the update buffer index and make sure there is enough room in the instruction container
984 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
985 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
987 if ( NULL != mImpl->root )
989 ProcessRenderTasks( bufferIndex,
993 mImpl->renderSortingHelper,
994 mImpl->renderInstructions );
996 // Process the system-level RenderTasks last
997 if ( NULL != mImpl->systemLevelRoot )
999 ProcessRenderTasks( bufferIndex,
1000 mImpl->systemLevelTaskList,
1001 *mImpl->systemLevelRoot,
1002 mImpl->systemLevelSortedLayers,
1003 mImpl->renderSortingHelper,
1004 mImpl->renderInstructions );
1009 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1010 bool doRenderOnceNotify = false;
1011 mImpl->renderTaskWaiting = false;
1012 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1013 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1014 endIter != iter; ++iter )
1016 RenderTask& renderTask(*(*iter));
1018 renderTask.UpdateState();
1020 if( renderTask.IsWaitingToRender() &&
1021 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1023 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1026 if( renderTask.HasRendered() )
1028 doRenderOnceNotify = true;
1032 if( doRenderOnceNotify )
1034 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1035 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1038 // Macro is undefined in release build.
1039 SNAPSHOT_NODE_LOGGING;
1041 // A ResetProperties() may be required in the next frame
1042 mImpl->previousUpdateScene = updateScene;
1044 // Check whether further updates are required
1045 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1047 // tell the update manager that we're done so the queue can be given to event thread
1048 mImpl->notificationManager.UpdateCompleted();
1050 // The update has finished; swap the double-buffering indices
1051 mSceneGraphBuffers.Swap();
1053 return keepUpdating;
1056 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1058 // Update the duration set via Stage::KeepRendering()
1059 if ( mImpl->keepRenderingSeconds > 0.0f )
1061 mImpl->keepRenderingSeconds -= elapsedSeconds;
1064 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1066 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1067 // Keep updating until no messages are received and no animations are running.
1068 // If an animation has just finished, update at least once more for Discard end-actions.
1069 // No need to check for renderQueue as there is always a render after update and if that
1070 // render needs another update it will tell the adaptor to call update again
1072 if ( mImpl->keepRenderingSeconds > 0.0f )
1074 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1077 if ( IsAnimationRunning() ||
1078 mImpl->animationFinishedDuringUpdate )
1080 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1083 if ( mImpl->renderTaskWaiting )
1085 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1088 return keepUpdatingRequest;
1091 void UpdateManager::SetBackgroundColor( const Vector4& color )
1093 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1095 // Reserve some memory inside the render queue
1096 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1098 // Construct message in the render queue memory; note that delete should not be called on the return value
1099 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1102 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1104 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1106 // Reserve some memory inside the render queue
1107 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1109 // Construct message in the render queue memory; note that delete should not be called on the return value
1110 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1113 void UpdateManager::KeepRendering( float durationSeconds )
1115 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1118 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1122 // just copy the vector of pointers
1123 mImpl->sortedLayers = layers;
1127 mImpl->systemLevelSortedLayers = layers;
1131 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1133 mImpl->shaderSaver = &upstream;
1136 void UpdateManager::AddSampler( Render::Sampler* sampler )
1138 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1140 // Reserve some memory inside the render queue
1141 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1143 // Construct message in the render queue memory; note that delete should not be called on the return value
1144 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1147 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1149 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1151 // Reserve some memory inside the render queue
1152 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1154 // Construct message in the render queue memory; note that delete should not be called on the return value
1155 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1158 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1160 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1162 // Reserve some memory inside the render queue
1163 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1165 // Construct message in the render queue memory; note that delete should not be called on the return value
1166 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1169 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
1171 typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > DerivedType;
1173 // Reserve some memory inside the render queue
1174 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1176 // Construct message in the render queue memory; note that delete should not be called on the return value
1177 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1180 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1182 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1184 // Reserve some memory inside the render queue
1185 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1187 // Construct message in the render queue memory; note that delete should not be called on the return value
1188 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1191 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1193 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1195 // Reserve some memory inside the render queue
1196 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1198 // Construct message in the render queue memory; note that delete should not be called on the return value
1199 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1202 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1204 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Render::PropertyBuffer::Format* > DerivedType;
1206 // Reserve some memory inside the render queue
1207 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1209 // Construct message in the render queue memory; note that delete should not be called on the return value
1210 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1213 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data, size_t size )
1215 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, Dali::Vector<char>*, size_t > DerivedType;
1217 // Reserve some memory inside the render queue
1218 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1220 // Construct message in the render queue memory; note that delete should not be called on the return value
1221 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1224 void UpdateManager::AddGeometry( Render::Geometry* geometry )
1226 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1228 // Reserve some memory inside the render queue
1229 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1231 // Construct message in the render queue memory; note that delete should not be called on the return value
1232 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1235 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1237 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1239 // Reserve some memory inside the render queue
1240 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1242 // Construct message in the render queue memory; note that delete should not be called on the return value
1243 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1246 void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
1248 typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType;
1250 // Reserve some memory inside the render queue
1251 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1253 // Construct message in the render queue memory; note that delete should not be called on the return value
1254 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1257 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
1259 typedef IndexBufferMessage< RenderManager > DerivedType;
1261 // Reserve some memory inside the render queue
1262 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1264 // Construct message in the render queue memory; note that delete should not be called on the return value
1265 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1268 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1270 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1272 // Reserve some memory inside the render queue
1273 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1275 // Construct message in the render queue memory; note that delete should not be called on the return value
1276 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1279 void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1281 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1283 // Reserve some memory inside the render queue
1284 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1286 // Construct message in the render queue memory; note that delete should not be called on the return value
1287 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, geometry, propertyBuffer );
1290 void UpdateManager::AddTexture( Render::NewTexture* texture )
1292 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1294 // Reserve some memory inside the render queue
1295 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1297 // Construct message in the render queue memory; note that delete should not be called on the return value
1298 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1301 void UpdateManager::RemoveTexture( Render::NewTexture* texture)
1303 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1305 // Reserve some memory inside the render queue
1306 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1308 // Construct message in the render queue memory; note that delete should not be called on the return value
1309 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1312 void UpdateManager::UploadTexture( Render::NewTexture* texture, PixelDataPtr pixelData, const NewTexture::UploadParams& params )
1314 typedef MessageValue3< RenderManager, Render::NewTexture*, PixelDataPtr, NewTexture::UploadParams > DerivedType;
1316 // Reserve some memory inside the message queue
1317 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1319 // Construct message in the message queue memory; note that delete should not be called on the return value
1320 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1323 void UpdateManager::GenerateMipmaps( Render::NewTexture* texture )
1325 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1327 // Reserve some memory inside the render queue
1328 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1330 // Construct message in the render queue memory; note that delete should not be called on the return value
1331 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1334 void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
1336 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1338 // Reserve some memory inside the render queue
1339 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1341 // Construct message in the render queue memory; note that delete should not be called on the return value
1342 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1345 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1347 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1349 // Reserve some memory inside the render queue
1350 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1352 // Construct message in the render queue memory; note that delete should not be called on the return value
1353 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1356 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::NewTexture* texture, unsigned int mipmapLevel, unsigned int layer )
1358 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::NewTexture*, unsigned int, unsigned int > DerivedType;
1360 // Reserve some memory inside the render queue
1361 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1363 // Construct message in the render queue memory; note that delete should not be called on the return value
1364 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1367 } // namespace SceneGraph
1369 } // namespace Internal