2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/update/manager/update-manager.h>
22 #include <dali/public-api/common/stage.h>
23 #include <dali/devel-api/common/set-wrapper.h>
24 #include <dali/devel-api/common/owner-container.h>
25 #include <dali/devel-api/threading/mutex.h>
27 #include <dali/integration-api/core.h>
28 #include <dali/integration-api/render-controller.h>
29 #include <dali/internal/common/shader-data.h>
30 #include <dali/integration-api/debug.h>
32 #include <dali/internal/common/core-impl.h>
33 #include <dali/internal/common/message.h>
35 #include <dali/internal/event/common/notification-manager.h>
36 #include <dali/internal/event/common/property-notification-impl.h>
37 #include <dali/internal/event/common/property-notifier.h>
38 #include <dali/internal/event/effects/shader-factory.h>
40 #include <dali/internal/update/animation/scene-graph-animator.h>
41 #include <dali/internal/update/animation/scene-graph-animation.h>
42 #include <dali/internal/update/common/discard-queue.h>
43 #include <dali/internal/update/common/scene-graph-buffers.h>
44 #include <dali/internal/update/controllers/render-message-dispatcher.h>
45 #include <dali/internal/update/controllers/scene-controller-impl.h>
46 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
47 #include <dali/internal/update/manager/render-task-processor.h>
48 #include <dali/internal/update/manager/sorted-layers.h>
49 #include <dali/internal/update/manager/update-algorithms.h>
50 #include <dali/internal/update/manager/update-manager-debug.h>
51 #include <dali/internal/update/manager/transform-manager.h>
52 #include <dali/internal/update/nodes/node.h>
53 #include <dali/internal/update/nodes/scene-graph-layer.h>
54 #include <dali/internal/update/queue/update-message-queue.h>
55 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
56 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
57 #include <dali/internal/update/render-tasks/scene-graph-camera.h>
59 #include <dali/internal/render/common/render-instruction-container.h>
60 #include <dali/internal/render/common/render-manager.h>
61 #include <dali/internal/render/queue/render-queue.h>
62 #include <dali/internal/render/shaders/scene-graph-shader.h>
64 // Un-comment to enable node tree debug logging
65 //#define NODE_TREE_LOGGING 1
67 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
68 #define SNAPSHOT_NODE_LOGGING \
69 const int FRAME_COUNT_TRIGGER = 16;\
70 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
72 if ( NULL != mImpl->root )\
74 mImpl->frameCounter = 0;\
75 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
78 mImpl->frameCounter++;
80 #define SNAPSHOT_NODE_LOGGING
83 #if defined(DEBUG_ENABLED)
84 extern Debug::Filter* gRenderTaskLogFilter;
88 using namespace Dali::Integration;
89 using Dali::Internal::Update::MessageQueue;
103 * Helper to reset animate-able objects to base values
104 * @param container to iterate over
105 * @param updateBufferIndex to use
108 inline void ResetToBaseValues( OwnerContainer<T*>& container, BufferIndex updateBufferIndex )
110 // Reset animatable properties to base values
111 typename OwnerContainer<T*>::Iterator iter = container.Begin();
112 const typename OwnerContainer<T*>::ConstIterator endIter = container.End();
113 for ( ; iter != endIter; ++iter )
115 (*iter)->ResetToBaseValues( updateBufferIndex );
120 * Helper to Erase an object from OwnerContainer using discard queue
121 * @param container to remove from
122 * @param object to remove
123 * @param discardQueue to put the object to
124 * @param updateBufferIndex to use
127 inline void EraseUsingDiscardQueue( OwnerContainer<T*>& container, T* object, DiscardQueue& discardQueue, BufferIndex updateBufferIndex )
129 typename OwnerContainer<T*>::Iterator iter = container.Begin();
130 const typename OwnerContainer<T*>::ConstIterator endIter = container.End();
131 for ( ; iter != endIter; ++iter )
133 if ( *iter == object )
135 // Transfer ownership to the discard queue, this keeps the object alive, until the render-thread has finished with it
136 discardQueue.Add( updateBufferIndex, container.Release( iter ) );
144 typedef OwnerContainer< Shader* > ShaderOwner;
145 typedef ShaderOwner::Iterator ShaderIter;
146 typedef std::vector<Internal::ShaderDataPtr> ShaderDataBinaryQueue;
148 typedef OwnerContainer< TextureSet* > TextureSetOwner;
149 typedef TextureSetOwner::Iterator TextureSetIter;
151 typedef OwnerContainer<Renderer*> RendererOwner;
152 typedef RendererOwner::Iterator RendererIter;
154 typedef OwnerContainer<PanGesture*> GestureOwner;
155 typedef GestureOwner::Iterator GestureIter;
157 typedef OwnerContainer< Camera* > CameraOwner;
158 typedef OwnerContainer< PropertyOwner* > CustomObjectOwner;
161 * Structure to contain UpdateManager internal data
163 struct UpdateManager::Impl
165 Impl( NotificationManager& notificationManager,
166 CompleteNotificationInterface& animationFinishedNotifier,
167 PropertyNotifier& propertyNotifier,
168 DiscardQueue& discardQueue,
169 RenderController& renderController,
170 RenderManager& renderManager,
171 RenderQueue& renderQueue,
172 SceneGraphBuffers& sceneGraphBuffers,
173 RenderTaskProcessor& renderTaskProcessor )
174 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
175 notificationManager( notificationManager ),
177 animationFinishedNotifier( animationFinishedNotifier ),
178 propertyNotifier( propertyNotifier ),
180 discardQueue( discardQueue ),
181 renderController( renderController ),
182 sceneController( NULL ),
183 renderManager( renderManager ),
184 renderQueue( renderQueue ),
185 renderInstructions( renderManager.GetRenderInstructionContainer() ),
186 renderTaskProcessor( renderTaskProcessor ),
187 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
188 taskList( renderMessageDispatcher ),
189 systemLevelTaskList( renderMessageDispatcher ),
191 systemLevelRoot( NULL ),
196 messageQueue( renderController, sceneGraphBuffers ),
197 keepRenderingSeconds( 0.0f ),
198 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
200 animationFinishedDuringUpdate( false ),
201 previousUpdateScene( false ),
202 renderTaskWaiting( false )
204 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
206 // create first 'dummy' node
212 // Disconnect render tasks from nodes, before destroying the nodes
213 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
214 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
216 (*iter)->SetSourceNode( NULL );
218 // ..repeat for system level RenderTasks
219 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
220 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
222 (*iter)->SetSourceNode( NULL );
225 // UpdateManager owns the Nodes
226 Vector<Node*>::Iterator iter = nodes.Begin()+1;
227 Vector<Node*>::Iterator endIter = nodes.End();
228 for(;iter!=endIter;++iter)
230 (*iter)->OnDestroy();
234 // If there is root, reset it, otherwise do nothing as rendering was never started
239 Node::Delete( root );
243 if( systemLevelRoot )
245 systemLevelRoot->OnDestroy();
247 Node::Delete( systemLevelRoot );
248 systemLevelRoot = NULL;
251 delete sceneController;
254 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
255 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
256 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
257 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
258 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
259 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
260 ShaderSaver* shaderSaver; ///< Saves shader binaries.
261 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
262 RenderController& renderController; ///< render controller
263 SceneControllerImpl* sceneController; ///< scene controller
264 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
265 RenderQueue& renderQueue; ///< Used to queue messages for the next render
266 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
267 RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
269 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
271 RenderTaskList taskList; ///< The list of scene graph render-tasks
272 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
274 Layer* root; ///< The root node (root is a layer)
275 Layer* systemLevelRoot; ///< A separate root-node for system-level content
277 Vector<Node*> nodes; ///< A container of all instantiated nodes
279 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
280 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
282 CameraOwner cameras; ///< A container of cameras
283 CustomObjectOwner customObjects; ///< A container of owned objects (with custom properties)
285 AnimationContainer animations; ///< A container of owned animations
286 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
288 RendererOwner renderers; ///< A container of owned renderers
289 TextureSetOwner textureSets; ///< A container of owned texture sets
290 ShaderOwner shaders; ///< A container of owned shaders
291 GestureOwner gestures; ///< A container of owned gesture detectors
293 MessageQueue messageQueue; ///< The messages queued from the event-thread
294 ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
295 ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event
296 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
298 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
299 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
300 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
302 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
303 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
304 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
308 Impl( const Impl& ); ///< Undefined
309 Impl& operator=( const Impl& ); ///< Undefined
312 UpdateManager::UpdateManager( NotificationManager& notificationManager,
313 CompleteNotificationInterface& animationFinishedNotifier,
314 PropertyNotifier& propertyNotifier,
315 DiscardQueue& discardQueue,
316 RenderController& controller,
317 RenderManager& renderManager,
318 RenderQueue& renderQueue,
319 RenderTaskProcessor& renderTaskProcessor )
322 mImpl = new Impl( notificationManager,
323 animationFinishedNotifier,
330 renderTaskProcessor );
334 UpdateManager::~UpdateManager()
339 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
341 DALI_ASSERT_DEBUG( layer->IsLayer() );
342 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
346 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
348 mImpl->root->CreateTransform( &mImpl->transformManager );
352 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
353 mImpl->systemLevelRoot = layer;
354 mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager );
357 layer->SetRoot(true);
360 void UpdateManager::AddNode( Node* node )
362 DALI_ASSERT_ALWAYS( NULL != node );
363 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
365 // Nodes must be sorted by pointer
366 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
367 for(Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter)
371 mImpl->nodes.Insert((iter+1), node);
372 node->CreateTransform( &mImpl->transformManager );
378 void UpdateManager::ConnectNode( Node* parent, Node* node )
380 DALI_ASSERT_ALWAYS( NULL != parent );
381 DALI_ASSERT_ALWAYS( NULL != node );
382 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
384 parent->ConnectChild( node );
387 void UpdateManager::DisconnectNode( Node* node )
389 Node* parent = node->GetParent();
390 DALI_ASSERT_ALWAYS( NULL != parent );
391 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
393 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
396 void UpdateManager::DestroyNode( Node* node )
398 DALI_ASSERT_ALWAYS( NULL != node );
399 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
401 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
402 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
403 for(;iter!=endIter;++iter)
407 mImpl->nodes.Erase(iter);
412 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
414 // Notify the Node about impending destruction
418 void UpdateManager::AddCamera( Camera* camera )
420 DALI_ASSERT_DEBUG( camera != NULL );
422 mImpl->cameras.PushBack( camera ); // takes ownership
425 void UpdateManager::RemoveCamera( const Camera* camera )
427 // Find the camera and destroy it
428 EraseUsingDiscardQueue( mImpl->cameras, const_cast<Camera*>( camera ), mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
431 void UpdateManager::AddObject( PropertyOwner* object )
433 DALI_ASSERT_DEBUG( NULL != object );
435 mImpl->customObjects.PushBack( object );
438 void UpdateManager::RemoveObject( PropertyOwner* object )
440 DALI_ASSERT_DEBUG( NULL != object );
442 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
444 // Find the object and destroy it
445 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
447 PropertyOwner* current = *iter;
448 if ( current == object )
450 customObjects.Erase( iter );
455 // Should not reach here
456 DALI_ASSERT_DEBUG(false);
459 void UpdateManager::AddAnimation( Animation* animation )
461 mImpl->animations.PushBack( animation );
464 void UpdateManager::StopAnimation( Animation* animation )
466 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
468 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
470 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
473 void UpdateManager::RemoveAnimation( Animation* animation )
475 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
477 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
479 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
482 bool UpdateManager::IsAnimationRunning() const
484 bool isRunning(false);
485 AnimationContainer& animations = mImpl->animations;
487 // Find any animation that isn't stopped or paused
489 const AnimationIter endIter = animations.End();
490 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
492 const Animation::State state = (*iter)->GetState();
494 if (state != Animation::Stopped &&
495 state != Animation::Paused)
504 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
506 mImpl->propertyNotifications.PushBack( propertyNotification );
509 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
511 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
512 PropertyNotificationIter iter = propertyNotifications.Begin();
514 while ( iter != propertyNotifications.End() )
516 if( *iter == propertyNotification )
518 propertyNotifications.Erase(iter);
525 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
527 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
528 propertyNotification->SetNotifyMode( notifyMode );
531 void UpdateManager::AddShader( Shader* shader )
533 DALI_ASSERT_DEBUG( NULL != shader );
535 mImpl->shaders.PushBack( shader );
538 void UpdateManager::RemoveShader( Shader* shader )
540 DALI_ASSERT_DEBUG(shader != NULL);
542 // Find the shader and destroy it
543 EraseUsingDiscardQueue( mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
546 void UpdateManager::SetShaderProgram( Shader* shader,
547 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
552 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
554 // Reserve some memory inside the render queue
555 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
557 // Construct message in the render queue memory; note that delete should not be called on the return value
558 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
562 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
564 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
565 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
567 // lock as update might be sending previously compiled shaders to event thread
568 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
569 mImpl->renderCompiledShaders.push_back( shaderData );
573 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
575 mImpl->shaderSaver = &upstream;
578 void UpdateManager::AddRenderer( Renderer* renderer )
580 DALI_ASSERT_DEBUG( renderer != NULL );
582 mImpl->renderers.PushBack( renderer );
584 renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
587 void UpdateManager::RemoveRenderer( Renderer* renderer )
589 DALI_ASSERT_DEBUG( renderer != NULL );
591 renderer->DisconnectFromSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
593 // Find the renderer and destroy it
594 EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
597 void UpdateManager::AddGesture( PanGesture* gesture )
599 DALI_ASSERT_DEBUG( NULL != gesture );
601 mImpl->gestures.PushBack( gesture );
604 void UpdateManager::RemoveGesture( PanGesture* gesture )
606 DALI_ASSERT_DEBUG( gesture != NULL );
608 // Find the gesture and destroy it
609 GestureOwner& gestures = mImpl->gestures;
610 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
612 if ( *iter == gesture )
614 gestures.Erase( iter );
620 void UpdateManager::AddTextureSet( TextureSet* textureSet )
622 DALI_ASSERT_DEBUG( NULL != textureSet );
623 mImpl->textureSets.PushBack( textureSet );
626 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
628 DALI_ASSERT_DEBUG( textureSet != NULL );
630 // Find the texture and destroy it
631 TextureSetOwner& textures = mImpl->textureSets;
632 for ( TextureSetIter iter = textures.Begin(), endIter = textures.End(); iter != endIter; ++iter )
634 if ( *iter == textureSet )
636 textures.Erase( iter );
642 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
646 // copy the list, this is only likely to happen once in application life cycle
647 return &(mImpl->taskList);
651 // copy the list, this is only likely to happen once in application life cycle
652 return &(mImpl->systemLevelTaskList);
656 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
658 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
661 void UpdateManager::EventProcessingStarted()
663 mImpl->messageQueue.EventProcessingStarted();
666 bool UpdateManager::FlushQueue()
668 return mImpl->messageQueue.FlushQueue();
671 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
673 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
674 mImpl->animationFinishedDuringUpdate = false;
676 // Animated properties have to be reset to their original value each frame
678 // Reset root properties
681 mImpl->root->ResetToBaseValues( bufferIndex );
683 if ( mImpl->systemLevelRoot )
685 mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
688 // Reset all the nodes
689 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
690 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
691 for( ;iter != endIter; ++iter )
693 (*iter)->ResetToBaseValues( bufferIndex );
696 // Reset system-level render-task list properties to base values
697 ResetToBaseValues( mImpl->systemLevelTaskList.GetTasks(), bufferIndex );
699 // Reset render-task list properties to base values.
700 ResetToBaseValues( mImpl->taskList.GetTasks(), bufferIndex );
702 // Reset custom object properties to base values
703 ResetToBaseValues( mImpl->customObjects, bufferIndex );
705 // Reset animatable renderer properties to base values
706 ResetToBaseValues( mImpl->renderers, bufferIndex );
708 // Reset animatable shader properties to base values
709 ResetToBaseValues( mImpl->shaders, bufferIndex );
712 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
714 bool gestureUpdated( false );
716 // constrain gestures... (in construction order)
717 GestureOwner& gestures = mImpl->gestures;
719 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
721 PanGesture& gesture = **iter;
722 gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
723 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
726 return gestureUpdated;
729 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
731 AnimationContainer &animations = mImpl->animations;
732 AnimationIter iter = animations.Begin();
733 bool animationLooped = false;
734 while ( iter != animations.End() )
736 Animation* animation = *iter;
737 bool finished = false;
739 animation->Update( bufferIndex, elapsedSeconds, looped, finished );
741 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
742 animationLooped = animationLooped || looped;
744 // Remove animations that had been destroyed but were still waiting for an update
745 if (animation->GetState() == Animation::Destroyed)
747 iter = animations.Erase(iter);
755 // queue the notification on finished or looped (to update loop count)
756 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
758 // The application should be notified by NotificationManager, in another thread
759 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
763 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
765 //Constrain custom objects (in construction order)
766 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
767 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
768 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
770 PropertyOwner& object = **iter;
771 ConstrainPropertyOwner( object, bufferIndex );
775 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
777 // Constrain system-level render-tasks
778 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
779 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
781 RenderTask& task = **iter;
782 ConstrainPropertyOwner( task, bufferIndex );
785 // Constrain render-tasks
786 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
787 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
789 RenderTask& task = **iter;
790 ConstrainPropertyOwner( task, bufferIndex );
794 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
796 // constrain shaders... (in construction order)
797 ShaderOwner& shaders = mImpl->shaders;
798 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
800 Shader& shader = **iter;
801 ConstrainPropertyOwner( shader, bufferIndex );
805 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
807 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
808 PropertyNotificationIter iter = notifications.Begin();
810 while ( iter != notifications.End() )
812 PropertyNotification* notification = *iter;
813 bool valid = notification->Check( bufferIndex );
816 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
822 void UpdateManager::ForwardCompiledShadersToEventThread()
824 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
825 if( mImpl->shaderSaver )
827 // lock and swap the queues
829 // render might be attempting to send us more binaries at the same time
830 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
831 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
834 if( mImpl->updateCompiledShaders.size() > 0 )
836 ShaderSaver& factory = *mImpl->shaderSaver;
837 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
838 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
839 for( ; i != end; ++i )
841 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
843 // we don't need them in update anymore
844 mImpl->updateCompiledShaders.clear();
849 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
851 const unsigned int rendererCount = mImpl->renderers.Count();
852 for( unsigned int i = 0; i < rendererCount; ++i )
855 ConstrainPropertyOwner( *mImpl->renderers[i], bufferIndex );
857 mImpl->renderers[i]->PrepareRender( bufferIndex );
861 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
863 mImpl->nodeDirtyFlags = NothingFlag;
870 // Prepare resources, update shaders, for each node
871 // And add the renderers to the sorted layers. Start from root, which is also a layer
872 mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
874 mImpl->renderQueue );
876 if ( mImpl->systemLevelRoot )
878 mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
880 mImpl->renderQueue );
884 unsigned int UpdateManager::Update( float elapsedSeconds,
885 unsigned int lastVSyncTimeMilliseconds,
886 unsigned int nextVSyncTimeMilliseconds )
888 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
890 //Clear nodes/resources which were previously discarded
891 mImpl->discardQueue.Clear( bufferIndex );
893 //Process Touches & Gestures
894 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
896 bool updateScene = // The scene-graph requires an update if..
897 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
898 IsAnimationRunning() || // ..at least one animation is running OR
899 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
900 gestureUpdated; // ..a gesture property was updated
903 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
904 // values if the scene was updated in the previous frame.
905 if( updateScene || mImpl->previousUpdateScene )
907 //Reset properties from the previous update
908 ResetProperties( bufferIndex );
909 mImpl->transformManager.ResetToBaseValue();
912 // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
913 // between calling IsSceneUpdateRequired() above and here, so updateScene should
915 updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
917 //Forward compiled shader programs to event thread for saving
918 ForwardCompiledShadersToEventThread();
920 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
921 // renderer lists if the scene was updated in the previous frame.
922 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
923 if( updateScene || mImpl->previousUpdateScene )
926 Animate( bufferIndex, elapsedSeconds );
928 //Constraint custom objects
929 ConstrainCustomObjects( bufferIndex );
931 //Clear the lists of renderers from the previous update
932 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
934 mImpl->sortedLayers[i]->ClearRenderables();
937 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
939 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
942 //Update node hierarchy, apply constraints and perform sorting / culling.
943 //This will populate each Layer with a list of renderers which are ready.
944 UpdateNodes( bufferIndex );
946 //Apply constraints to RenderTasks, shaders
947 ConstrainRenderTasks( bufferIndex );
948 ConstrainShaders( bufferIndex );
950 //Update renderers and apply constraints
951 UpdateRenderers( bufferIndex );
953 //Update the trnasformations of all the nodes
954 mImpl->transformManager.Update();
956 //Process Property Notifications
957 ProcessPropertyNotifications( bufferIndex );
959 //Process the RenderTasks; this creates the instructions for rendering the next frame.
960 //reset the update buffer index and make sure there is enough room in the instruction container
961 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
962 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
964 if ( NULL != mImpl->root )
966 mImpl->renderTaskProcessor.Process( bufferIndex,
970 mImpl->renderInstructions );
972 // Process the system-level RenderTasks last
973 if ( NULL != mImpl->systemLevelRoot )
975 mImpl->renderTaskProcessor.Process( bufferIndex,
976 mImpl->systemLevelTaskList,
977 *mImpl->systemLevelRoot,
978 mImpl->systemLevelSortedLayers,
979 mImpl->renderInstructions );
984 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
985 bool doRenderOnceNotify = false;
986 mImpl->renderTaskWaiting = false;
987 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
988 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
989 endIter != iter; ++iter )
991 RenderTask& renderTask(*(*iter));
993 renderTask.UpdateState();
995 if( renderTask.IsWaitingToRender() &&
996 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
998 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1001 if( renderTask.HasRendered() )
1003 doRenderOnceNotify = true;
1007 if( doRenderOnceNotify )
1009 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1010 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1013 // Macro is undefined in release build.
1014 SNAPSHOT_NODE_LOGGING;
1016 // A ResetProperties() may be required in the next frame
1017 mImpl->previousUpdateScene = updateScene;
1019 // Check whether further updates are required
1020 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1022 // tell the update manager that we're done so the queue can be given to event thread
1023 mImpl->notificationManager.UpdateCompleted();
1025 // The update has finished; swap the double-buffering indices
1026 mSceneGraphBuffers.Swap();
1028 return keepUpdating;
1031 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1033 // Update the duration set via Stage::KeepRendering()
1034 if ( mImpl->keepRenderingSeconds > 0.0f )
1036 mImpl->keepRenderingSeconds -= elapsedSeconds;
1039 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1041 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1042 // Keep updating until no messages are received and no animations are running.
1043 // If an animation has just finished, update at least once more for Discard end-actions.
1044 // No need to check for renderQueue as there is always a render after update and if that
1045 // render needs another update it will tell the adaptor to call update again
1047 if ( mImpl->keepRenderingSeconds > 0.0f )
1049 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1052 if ( IsAnimationRunning() ||
1053 mImpl->animationFinishedDuringUpdate )
1055 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1058 if ( mImpl->renderTaskWaiting )
1060 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1063 return keepUpdatingRequest;
1066 void UpdateManager::SetBackgroundColor( const Vector4& color )
1068 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1070 // Reserve some memory inside the render queue
1071 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1073 // Construct message in the render queue memory; note that delete should not be called on the return value
1074 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1077 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1079 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1081 // Reserve some memory inside the render queue
1082 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1084 // Construct message in the render queue memory; note that delete should not be called on the return value
1085 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1088 void UpdateManager::KeepRendering( float durationSeconds )
1090 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1093 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1097 // just copy the vector of pointers
1098 mImpl->sortedLayers = layers;
1102 mImpl->systemLevelSortedLayers = layers;
1106 void UpdateManager::SetDepthIndices( NodeDepths* nodeDepths )
1110 // note,this vector is already in depth order. It could be used as-is to
1111 // remove sorting in update algorithm. However, it lacks layer boundary markers.
1112 for( std::vector<NodeDepthPair>::iterator iter = nodeDepths->nodeDepths.begin(),
1113 end = nodeDepths->nodeDepths.end() ;
1114 iter != end ; ++iter )
1116 iter->node->SetDepthIndex( iter->sortedDepth );
1121 void UpdateManager::AddSampler( Render::Sampler* sampler )
1123 // Message has ownership of Sampler while in transit from update to render
1124 typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > DerivedType;
1126 // Reserve some memory inside the render queue
1127 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1129 // Construct message in the render queue memory; note that delete should not be called on the return value
1130 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1133 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1135 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1137 // Reserve some memory inside the render queue
1138 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1140 // Construct message in the render queue memory; note that delete should not be called on the return value
1141 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1144 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1146 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1148 // Reserve some memory inside the render queue
1149 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1151 // Construct message in the render queue memory; note that delete should not be called on the return value
1152 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1155 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
1157 typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > DerivedType;
1159 // Reserve some memory inside the render queue
1160 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1162 // Construct message in the render queue memory; note that delete should not be called on the return value
1163 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1166 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1168 // Message has ownership of format while in transit from update -> render
1169 typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
1171 // Reserve some memory inside the render queue
1172 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1174 // Construct message in the render queue memory; note that delete should not be called on the return value
1175 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1178 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1180 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1182 // Reserve some memory inside the render queue
1183 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1185 // Construct message in the render queue memory; note that delete should not be called on the return value
1186 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1189 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1191 // Message has ownership of format while in transit from update -> render
1192 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType;
1194 // Reserve some memory inside the render queue
1195 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1197 // Construct message in the render queue memory; note that delete should not be called on the return value
1198 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1201 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data, size_t size )
1203 // Message has ownership of format while in transit from update -> render
1204 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<char> >, size_t > 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::SetPropertyBufferData, propertyBuffer, data, size );
1213 void UpdateManager::AddGeometry( Render::Geometry* geometry )
1215 // Message has ownership of format while in transit from update -> render
1216 typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > DerivedType;
1218 // Reserve some memory inside the render queue
1219 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1221 // Construct message in the render queue memory; note that delete should not be called on the return value
1222 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1225 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1227 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1229 // Reserve some memory inside the render queue
1230 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1232 // Construct message in the render queue memory; note that delete should not be called on the return value
1233 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1236 void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
1238 typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType;
1240 // Reserve some memory inside the render queue
1241 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1243 // Construct message in the render queue memory; note that delete should not be called on the return value
1244 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1247 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
1249 typedef IndexBufferMessage< RenderManager > DerivedType;
1251 // Reserve some memory inside the render queue
1252 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1254 // Construct message in the render queue memory; note that delete should not be called on the return value
1255 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1258 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1260 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1262 // Reserve some memory inside the render queue
1263 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1265 // Construct message in the render queue memory; note that delete should not be called on the return value
1266 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1269 void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1271 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1273 // Reserve some memory inside the render queue
1274 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1276 // Construct message in the render queue memory; note that delete should not be called on the return value
1277 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, geometry, propertyBuffer );
1280 void UpdateManager::AddTexture( Render::Texture* texture )
1282 // Message has ownership of Texture while in transit from update -> render
1283 typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType;
1285 // Reserve some memory inside the render queue
1286 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1288 // Construct message in the render queue memory; note that delete should not be called on the return value
1289 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1292 void UpdateManager::RemoveTexture( Render::Texture* texture)
1294 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1296 // Reserve some memory inside the render queue
1297 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1299 // Construct message in the render queue memory; note that delete should not be called on the return value
1300 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1303 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1305 typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
1307 // Reserve some memory inside the message queue
1308 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1310 // Construct message in the message queue memory; note that delete should not be called on the return value
1311 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1314 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1316 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1318 // Reserve some memory inside the render queue
1319 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1321 // Construct message in the render queue memory; note that delete should not be called on the return value
1322 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1325 void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
1327 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1329 // Reserve some memory inside the render queue
1330 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1332 // Construct message in the render queue memory; note that delete should not be called on the return value
1333 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1336 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1338 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1340 // Reserve some memory inside the render queue
1341 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1343 // Construct message in the render queue memory; note that delete should not be called on the return value
1344 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1347 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, unsigned int mipmapLevel, unsigned int layer )
1349 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, unsigned int, unsigned int > DerivedType;
1351 // Reserve some memory inside the render queue
1352 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1354 // Construct message in the render queue memory; note that delete should not be called on the return value
1355 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1358 } // namespace SceneGraph
1360 } // namespace Internal