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/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/object-owner-container.h>
48 #include <dali/internal/update/manager/render-task-processor.h>
49 #include <dali/internal/update/manager/sorted-layers.h>
50 #include <dali/internal/update/manager/update-algorithms.h>
51 #include <dali/internal/update/manager/update-manager-debug.h>
52 #include <dali/internal/update/manager/transform-manager.h>
53 #include <dali/internal/update/nodes/node.h>
54 #include <dali/internal/update/nodes/scene-graph-layer.h>
55 #include <dali/internal/update/queue/update-message-queue.h>
56 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
57 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
58 #include <dali/internal/update/rendering/scene-graph-texture-set.h>
59 #include <dali/internal/update/render-tasks/scene-graph-camera.h>
61 #include <dali/internal/render/common/render-instruction-container.h>
62 #include <dali/internal/render/common/render-manager.h>
63 #include <dali/internal/render/queue/render-queue.h>
64 #include <dali/internal/render/shaders/scene-graph-shader.h>
66 // Un-comment to enable node tree debug logging
67 //#define NODE_TREE_LOGGING 1
69 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
70 #define SNAPSHOT_NODE_LOGGING \
71 const int FRAME_COUNT_TRIGGER = 16;\
72 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
74 if ( NULL != mImpl->root )\
76 mImpl->frameCounter = 0;\
77 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
80 mImpl->frameCounter++;
82 #define SNAPSHOT_NODE_LOGGING
85 #if defined(DEBUG_ENABLED)
86 extern Debug::Filter* gRenderTaskLogFilter;
90 using namespace Dali::Integration;
91 using Dali::Internal::Update::MessageQueue;
102 typedef OwnerContainer< Shader* > ShaderContainer;
103 typedef ShaderContainer::Iterator ShaderIter;
104 typedef ShaderContainer::ConstIterator ShaderConstIter;
106 typedef std::vector<Internal::ShaderDataPtr> ShaderDataBinaryQueue;
108 typedef OwnerContainer<PanGesture*> GestureContainer;
109 typedef GestureContainer::Iterator GestureIter;
110 typedef GestureContainer::ConstIterator GestureConstIter;
112 typedef OwnerContainer< TextureSet* > TextureSetContainer;
113 typedef TextureSetContainer::Iterator TextureSetIter;
114 typedef TextureSetContainer::ConstIterator TextureSetConstIter;
117 * Structure to contain UpdateManager internal data
119 struct UpdateManager::Impl
121 Impl( NotificationManager& notificationManager,
122 CompleteNotificationInterface& animationFinishedNotifier,
123 PropertyNotifier& propertyNotifier,
124 DiscardQueue& discardQueue,
125 RenderController& renderController,
126 RenderManager& renderManager,
127 RenderQueue& renderQueue,
128 SceneGraphBuffers& sceneGraphBuffers,
129 RenderTaskProcessor& renderTaskProcessor )
130 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
131 notificationManager( notificationManager ),
133 animationFinishedNotifier( animationFinishedNotifier ),
134 propertyNotifier( propertyNotifier ),
136 discardQueue( discardQueue ),
137 renderController( renderController ),
138 sceneController( NULL ),
139 renderManager( renderManager ),
140 renderQueue( renderQueue ),
141 renderInstructions( renderManager.GetRenderInstructionContainer() ),
142 renderTaskProcessor( renderTaskProcessor ),
143 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
144 taskList( renderMessageDispatcher ),
145 systemLevelTaskList( renderMessageDispatcher ),
147 systemLevelRoot( NULL ),
148 renderers( sceneGraphBuffers, discardQueue ),
150 messageQueue( renderController, sceneGraphBuffers ),
151 keepRenderingSeconds( 0.0f ),
152 animationFinishedDuringUpdate( false ),
153 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
154 previousUpdateScene( false ),
156 renderTaskWaiting( false )
158 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
160 renderers.SetSceneController( *sceneController );
162 // create first 'dummy' node
168 // Disconnect render tasks from nodes, before destroying the nodes
169 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
170 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
172 (*iter)->SetSourceNode( NULL );
174 // ..repeat for system level RenderTasks
175 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
176 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
178 (*iter)->SetSourceNode( NULL );
181 // UpdateManager owns the Nodes
182 Vector<Node*>::Iterator iter = nodes.Begin()+1;
183 Vector<Node*>::Iterator endIter = nodes.End();
184 for(;iter!=endIter;++iter)
186 (*iter)->OnDestroy();
190 // If there is root, reset it, otherwise do nothing as rendering was never started
195 Node::Delete( root );
199 if( systemLevelRoot )
201 systemLevelRoot->OnDestroy();
203 Node::Delete( systemLevelRoot );
204 systemLevelRoot = NULL;
207 delete sceneController;
210 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
211 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
212 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
213 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
214 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
215 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
216 ShaderSaver* shaderSaver; ///< Saves shader binaries.
217 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
218 RenderController& renderController; ///< render controller
219 SceneControllerImpl* sceneController; ///< scene controller
220 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
221 RenderQueue& renderQueue; ///< Used to queue messages for the next render
222 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
223 RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
225 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
227 RenderTaskList taskList; ///< The list of scene graph render-tasks
228 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
230 Layer* root; ///< The root node (root is a layer)
231 Layer* systemLevelRoot; ///< A separate root-node for system-level content
233 Vector<Node*> nodes; ///< A container of all instantiated nodes
235 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
236 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
238 OwnerContainer< Camera* > cameras; ///< A container of cameras
239 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
241 AnimationContainer animations; ///< A container of owned animations
242 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
244 ObjectOwnerContainer<Renderer> renderers;
245 TextureSetContainer textureSets; ///< A container of texture sets
247 ShaderContainer shaders; ///< A container of owned shaders
249 MessageQueue messageQueue; ///< The messages queued from the event-thread
250 ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
251 ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event
252 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
254 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
255 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
257 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
258 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
260 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
262 GestureContainer gestures; ///< A container of owned gesture detectors
263 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
267 Impl( const Impl& ); ///< Undefined
268 Impl& operator=( const Impl& ); ///< Undefined
271 UpdateManager::UpdateManager( NotificationManager& notificationManager,
272 CompleteNotificationInterface& animationFinishedNotifier,
273 PropertyNotifier& propertyNotifier,
274 DiscardQueue& discardQueue,
275 RenderController& controller,
276 RenderManager& renderManager,
277 RenderQueue& renderQueue,
278 RenderTaskProcessor& renderTaskProcessor )
281 mImpl = new Impl( notificationManager,
282 animationFinishedNotifier,
289 renderTaskProcessor );
293 UpdateManager::~UpdateManager()
298 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
300 DALI_ASSERT_DEBUG( layer->IsLayer() );
301 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
305 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
307 mImpl->root->CreateTransform( &mImpl->transformManager );
311 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
312 mImpl->systemLevelRoot = layer;
313 mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager );
316 layer->SetRoot(true);
319 void UpdateManager::AddNode( Node* node )
321 DALI_ASSERT_ALWAYS( NULL != node );
322 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
324 // Nodes must be sorted by pointer
325 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
326 for(Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter)
330 mImpl->nodes.Insert((iter+1), node);
331 node->CreateTransform( &mImpl->transformManager );
337 void UpdateManager::ConnectNode( Node* parent, Node* node )
339 DALI_ASSERT_ALWAYS( NULL != parent );
340 DALI_ASSERT_ALWAYS( NULL != node );
341 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
343 parent->ConnectChild( node );
346 void UpdateManager::DisconnectNode( Node* node )
348 Node* parent = node->GetParent();
349 DALI_ASSERT_ALWAYS( NULL != parent );
350 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
352 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
355 void UpdateManager::DestroyNode( Node* node )
357 DALI_ASSERT_ALWAYS( NULL != node );
358 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
360 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
361 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
362 for(;iter!=endIter;++iter)
366 mImpl->nodes.Erase(iter);
371 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
373 // Notify the Node about impending destruction
377 void UpdateManager::AddCamera( Camera* camera )
379 DALI_ASSERT_DEBUG( camera != NULL );
381 mImpl->cameras.PushBack( camera ); // takes ownership
384 void UpdateManager::RemoveCamera( const Camera* camera )
387 OwnerContainer<Camera*>::Iterator iter = mImpl->cameras.Begin();
388 OwnerContainer<Camera*>::ConstIterator end = mImpl->cameras.End();
389 for ( ; iter != end; ++iter )
391 Camera* value = *iter;
392 if ( camera == value )
394 // Transfer ownership to the discard queue
395 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->cameras.Release( iter ) );
403 void UpdateManager::AddObject( PropertyOwner* object )
405 DALI_ASSERT_DEBUG( NULL != object );
407 mImpl->customObjects.PushBack( object );
410 void UpdateManager::RemoveObject( PropertyOwner* object )
412 DALI_ASSERT_DEBUG( NULL != object );
414 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
416 // Find the object and destroy it
417 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
419 PropertyOwner* current = *iter;
420 if ( current == object )
422 customObjects.Erase( iter );
427 // Should not reach here
428 DALI_ASSERT_DEBUG(false);
431 void UpdateManager::AddAnimation( Animation* animation )
433 mImpl->animations.PushBack( animation );
436 void UpdateManager::StopAnimation( Animation* animation )
438 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
440 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
442 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
445 void UpdateManager::RemoveAnimation( Animation* animation )
447 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
449 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
451 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
454 bool UpdateManager::IsAnimationRunning() const
456 bool isRunning(false);
457 AnimationContainer& animations = mImpl->animations;
459 // Find any animation that isn't stopped or paused
461 const AnimationIter endIter = animations.End();
462 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
464 const Animation::State state = (*iter)->GetState();
466 if (state != Animation::Stopped &&
467 state != Animation::Paused)
476 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
478 mImpl->propertyNotifications.PushBack( propertyNotification );
481 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
483 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
484 PropertyNotificationIter iter = propertyNotifications.Begin();
486 while ( iter != propertyNotifications.End() )
488 if( *iter == propertyNotification )
490 propertyNotifications.Erase(iter);
497 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
499 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
500 propertyNotification->SetNotifyMode( notifyMode );
503 ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
505 return mImpl->renderers;
508 void UpdateManager::AddShader( Shader* shader )
510 DALI_ASSERT_DEBUG( NULL != shader );
512 mImpl->shaders.PushBack( shader );
515 void UpdateManager::RemoveShader( Shader* shader )
517 DALI_ASSERT_DEBUG(shader != NULL);
519 ShaderContainer& shaders = mImpl->shaders;
521 // Find the shader and destroy it
522 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
524 Shader& current = **iter;
525 if ( ¤t == shader )
527 // Transfer ownership to the discard queue
528 // This keeps the shader alive, until the render-thread has finished with it
529 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
534 // Should not reach here
535 DALI_ASSERT_DEBUG(false);
538 void UpdateManager::SetShaderProgram( Shader* shader,
539 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
544 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
546 // Reserve some memory inside the render queue
547 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
549 // Construct message in the render queue memory; note that delete should not be called on the return value
550 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
554 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
556 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
557 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
559 // lock as update might be sending previously compiled shaders to event thread
560 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
561 mImpl->renderCompiledShaders.push_back( shaderData );
565 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
569 // copy the list, this is only likely to happen once in application life cycle
570 return &(mImpl->taskList);
574 // copy the list, this is only likely to happen once in application life cycle
575 return &(mImpl->systemLevelTaskList);
579 void UpdateManager::AddGesture( PanGesture* gesture )
581 DALI_ASSERT_DEBUG( NULL != gesture );
583 mImpl->gestures.PushBack( gesture );
586 void UpdateManager::RemoveGesture( PanGesture* gesture )
588 DALI_ASSERT_DEBUG( gesture != NULL );
590 GestureContainer& gestures = mImpl->gestures;
592 // Find the gesture and destroy it
593 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
595 PanGesture& current = **iter;
596 if ( ¤t == gesture )
598 mImpl->gestures.Erase( iter );
602 // Should not reach here
603 DALI_ASSERT_DEBUG(false);
606 void UpdateManager::AddTextureSet( TextureSet* textureSet )
608 DALI_ASSERT_DEBUG( NULL != textureSet );
609 mImpl->textureSets.PushBack( textureSet );
612 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
614 DALI_ASSERT_DEBUG(textureSet != NULL);
615 size_t textureSetCount( mImpl->textureSets.Size() );
616 for( size_t i(0); i<textureSetCount; ++i )
618 if( textureSet == mImpl->textureSets[i] )
620 mImpl->textureSets.Remove( mImpl->textureSets.Begin() + i );
622 // Update manager has ownership of the TextureSet
629 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
631 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
634 void UpdateManager::EventProcessingStarted()
636 mImpl->messageQueue.EventProcessingStarted();
639 bool UpdateManager::FlushQueue()
641 return mImpl->messageQueue.FlushQueue();
644 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
646 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
647 mImpl->animationFinishedDuringUpdate = false;
649 // Animated properties have to be reset to their original value each frame
651 // Reset root properties
654 mImpl->root->ResetToBaseValues( bufferIndex );
656 if ( mImpl->systemLevelRoot )
658 mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
661 // Reset all the nodes
662 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
663 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
664 for(;iter != endIter; ++iter)
666 (*iter)->ResetToBaseValues( bufferIndex );
669 // Reset system-level render-task list properties to base values
670 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
672 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
674 (*iter)->ResetToBaseValues( bufferIndex );
677 // Reset render-task list properties to base values.
678 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
680 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
682 (*iter)->ResetToBaseValues( bufferIndex );
685 // Reset custom object properties to base values
686 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
688 (*iter)->ResetToBaseValues( bufferIndex );
691 mImpl->renderers.ResetToBaseValues( bufferIndex );
693 // Reset animatable shader properties to base values
694 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
696 (*iter)->ResetToBaseValues( bufferIndex );
700 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
702 bool gestureUpdated( false );
704 // constrain gestures... (in construction order)
705 GestureContainer& gestures = mImpl->gestures;
707 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
709 PanGesture& gesture = **iter;
710 gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
711 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
714 return gestureUpdated;
717 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
719 AnimationContainer &animations = mImpl->animations;
720 AnimationIter iter = animations.Begin();
721 bool animationLooped = false;
722 while ( iter != animations.End() )
724 Animation* animation = *iter;
725 bool finished = false;
727 animation->Update( bufferIndex, elapsedSeconds, looped, finished );
729 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
730 animationLooped = animationLooped || looped;
732 // Remove animations that had been destroyed but were still waiting for an update
733 if (animation->GetState() == Animation::Destroyed)
735 iter = animations.Erase(iter);
743 // queue the notification on finished or looped (to update loop count)
744 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
746 // The application should be notified by NotificationManager, in another thread
747 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
751 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
753 //Constrain custom objects (in construction order)
754 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
755 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
756 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
758 PropertyOwner& object = **iter;
759 ConstrainPropertyOwner( object, bufferIndex );
763 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
765 // Constrain system-level render-tasks
766 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
767 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
769 RenderTask& task = **iter;
770 ConstrainPropertyOwner( task, bufferIndex );
773 // Constrain render-tasks
774 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
775 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
777 RenderTask& task = **iter;
778 ConstrainPropertyOwner( task, bufferIndex );
782 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
784 // constrain shaders... (in construction order)
785 ShaderContainer& shaders = mImpl->shaders;
786 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
788 Shader& shader = **iter;
789 ConstrainPropertyOwner( shader, bufferIndex );
793 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
795 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
796 PropertyNotificationIter iter = notifications.Begin();
798 while ( iter != notifications.End() )
800 PropertyNotification* notification = *iter;
801 bool valid = notification->Check( bufferIndex );
804 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
810 void UpdateManager::ForwardCompiledShadersToEventThread()
812 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
813 if( mImpl->shaderSaver )
815 // lock and swap the queues
817 // render might be attempting to send us more binaries at the same time
818 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
819 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
822 if( mImpl->updateCompiledShaders.size() > 0 )
824 ShaderSaver& factory = *mImpl->shaderSaver;
825 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
826 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
827 for( ; i != end; ++i )
829 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
831 // we don't need them in update anymore
832 mImpl->updateCompiledShaders.clear();
837 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
839 const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
840 unsigned int rendererCount( rendererContainer.Size() );
841 for( unsigned int i(0); i<rendererCount; ++i )
844 ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
846 rendererContainer[i]->PrepareRender( bufferIndex );
850 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
852 mImpl->nodeDirtyFlags = NothingFlag;
859 // Prepare resources, update shaders, for each node
860 // And add the renderers to the sorted layers. Start from root, which is also a layer
861 mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
863 mImpl->renderQueue );
865 if ( mImpl->systemLevelRoot )
867 mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
869 mImpl->renderQueue );
873 unsigned int UpdateManager::Update( float elapsedSeconds,
874 unsigned int lastVSyncTimeMilliseconds,
875 unsigned int nextVSyncTimeMilliseconds )
877 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
879 //Clear nodes/resources which were previously discarded
880 mImpl->discardQueue.Clear( bufferIndex );
882 //Process Touches & Gestures
883 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
885 bool updateScene = // The scene-graph requires an update if..
886 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
887 IsAnimationRunning() || // ..at least one animation is running OR
888 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
889 gestureUpdated; // ..a gesture property was updated
892 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
893 // values if the scene was updated in the previous frame.
894 if( updateScene || mImpl->previousUpdateScene )
896 //Reset properties from the previous update
897 ResetProperties( bufferIndex );
898 mImpl->transformManager.ResetToBaseValue();
901 // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
902 // between calling IsSceneUpdateRequired() above and here, so updateScene should
904 updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
906 //Forward compiled shader programs to event thread for saving
907 ForwardCompiledShadersToEventThread();
909 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
910 // renderer lists if the scene was updated in the previous frame.
911 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
912 if( updateScene || mImpl->previousUpdateScene )
915 Animate( bufferIndex, elapsedSeconds );
917 //Constraint custom objects
918 ConstrainCustomObjects( bufferIndex );
920 //Clear the lists of renderers from the previous update
921 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
923 mImpl->sortedLayers[i]->ClearRenderables();
926 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
928 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
931 //Update node hierarchy, apply constraints and perform sorting / culling.
932 //This will populate each Layer with a list of renderers which are ready.
933 UpdateNodes( bufferIndex );
935 //Apply constraints to RenderTasks, shaders
936 ConstrainRenderTasks( bufferIndex );
937 ConstrainShaders( bufferIndex );
939 //Update renderers and apply constraints
940 UpdateRenderers( bufferIndex );
942 //Update the trnasformations of all the nodes
943 mImpl->transformManager.Update();
945 //Process Property Notifications
946 ProcessPropertyNotifications( bufferIndex );
948 //Process the RenderTasks; this creates the instructions for rendering the next frame.
949 //reset the update buffer index and make sure there is enough room in the instruction container
950 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
951 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
953 if ( NULL != mImpl->root )
955 mImpl->renderTaskProcessor.Process( bufferIndex,
959 mImpl->renderInstructions );
961 // Process the system-level RenderTasks last
962 if ( NULL != mImpl->systemLevelRoot )
964 mImpl->renderTaskProcessor.Process( bufferIndex,
965 mImpl->systemLevelTaskList,
966 *mImpl->systemLevelRoot,
967 mImpl->systemLevelSortedLayers,
968 mImpl->renderInstructions );
973 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
974 bool doRenderOnceNotify = false;
975 mImpl->renderTaskWaiting = false;
976 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
977 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
978 endIter != iter; ++iter )
980 RenderTask& renderTask(*(*iter));
982 renderTask.UpdateState();
984 if( renderTask.IsWaitingToRender() &&
985 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
987 mImpl->renderTaskWaiting = true; // keep update/render threads alive
990 if( renderTask.HasRendered() )
992 doRenderOnceNotify = true;
996 if( doRenderOnceNotify )
998 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
999 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1002 // Macro is undefined in release build.
1003 SNAPSHOT_NODE_LOGGING;
1005 // A ResetProperties() may be required in the next frame
1006 mImpl->previousUpdateScene = updateScene;
1008 // Check whether further updates are required
1009 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1011 // tell the update manager that we're done so the queue can be given to event thread
1012 mImpl->notificationManager.UpdateCompleted();
1014 // The update has finished; swap the double-buffering indices
1015 mSceneGraphBuffers.Swap();
1017 return keepUpdating;
1020 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1022 // Update the duration set via Stage::KeepRendering()
1023 if ( mImpl->keepRenderingSeconds > 0.0f )
1025 mImpl->keepRenderingSeconds -= elapsedSeconds;
1028 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1030 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1031 // Keep updating until no messages are received and no animations are running.
1032 // If an animation has just finished, update at least once more for Discard end-actions.
1033 // No need to check for renderQueue as there is always a render after update and if that
1034 // render needs another update it will tell the adaptor to call update again
1036 if ( mImpl->keepRenderingSeconds > 0.0f )
1038 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1041 if ( IsAnimationRunning() ||
1042 mImpl->animationFinishedDuringUpdate )
1044 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1047 if ( mImpl->renderTaskWaiting )
1049 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1052 return keepUpdatingRequest;
1055 void UpdateManager::SetBackgroundColor( const Vector4& color )
1057 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1059 // Reserve some memory inside the render queue
1060 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1062 // Construct message in the render queue memory; note that delete should not be called on the return value
1063 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1066 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1068 typedef MessageValue1< RenderManager, Rect<int> > 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::SetDefaultSurfaceRect, rect );
1077 void UpdateManager::KeepRendering( float durationSeconds )
1079 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1082 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1086 // just copy the vector of pointers
1087 mImpl->sortedLayers = layers;
1091 mImpl->systemLevelSortedLayers = layers;
1095 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1097 mImpl->shaderSaver = &upstream;
1100 void UpdateManager::AddSampler( Render::Sampler* sampler )
1102 // Message has ownership of Sampler while in transit from update to render
1103 typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > DerivedType;
1105 // Reserve some memory inside the render queue
1106 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1108 // Construct message in the render queue memory; note that delete should not be called on the return value
1109 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1112 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1114 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1116 // Reserve some memory inside the render queue
1117 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1119 // Construct message in the render queue memory; note that delete should not be called on the return value
1120 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1123 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1125 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1127 // Reserve some memory inside the render queue
1128 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1130 // Construct message in the render queue memory; note that delete should not be called on the return value
1131 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1134 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
1136 typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > DerivedType;
1138 // Reserve some memory inside the render queue
1139 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1141 // Construct message in the render queue memory; note that delete should not be called on the return value
1142 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1145 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1147 // Message has ownership of format while in transit from update -> render
1148 typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
1150 // Reserve some memory inside the render queue
1151 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1153 // Construct message in the render queue memory; note that delete should not be called on the return value
1154 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1157 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1159 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1161 // Reserve some memory inside the render queue
1162 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1164 // Construct message in the render queue memory; note that delete should not be called on the return value
1165 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1168 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1170 // Message has ownership of format while in transit from update -> render
1171 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > 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::SetPropertyBufferFormat, propertyBuffer, format );
1180 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data, size_t size )
1182 // Message has ownership of format while in transit from update -> render
1183 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<char> >, size_t > DerivedType;
1185 // Reserve some memory inside the render queue
1186 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1188 // Construct message in the render queue memory; note that delete should not be called on the return value
1189 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1192 void UpdateManager::AddGeometry( Render::Geometry* geometry )
1194 // Message has ownership of format while in transit from update -> render
1195 typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > DerivedType;
1197 // Reserve some memory inside the render queue
1198 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1200 // Construct message in the render queue memory; note that delete should not be called on the return value
1201 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1204 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1206 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1208 // Reserve some memory inside the render queue
1209 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1211 // Construct message in the render queue memory; note that delete should not be called on the return value
1212 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1215 void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
1217 typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType;
1219 // Reserve some memory inside the render queue
1220 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1222 // Construct message in the render queue memory; note that delete should not be called on the return value
1223 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1226 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
1228 typedef IndexBufferMessage< RenderManager > DerivedType;
1230 // Reserve some memory inside the render queue
1231 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1233 // Construct message in the render queue memory; note that delete should not be called on the return value
1234 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1237 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1239 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1241 // Reserve some memory inside the render queue
1242 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1244 // Construct message in the render queue memory; note that delete should not be called on the return value
1245 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1248 void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1250 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1252 // Reserve some memory inside the render queue
1253 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1255 // Construct message in the render queue memory; note that delete should not be called on the return value
1256 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, geometry, propertyBuffer );
1259 void UpdateManager::AddTexture( Render::Texture* texture )
1261 // Message has ownership of Texture while in transit from update -> render
1262 typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType;
1264 // Reserve some memory inside the render queue
1265 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1267 // Construct message in the render queue memory; note that delete should not be called on the return value
1268 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1271 void UpdateManager::RemoveTexture( Render::Texture* texture)
1273 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1275 // Reserve some memory inside the render queue
1276 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1278 // Construct message in the render queue memory; note that delete should not be called on the return value
1279 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1282 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1284 typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
1286 // Reserve some memory inside the message queue
1287 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1289 // Construct message in the message queue memory; note that delete should not be called on the return value
1290 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1293 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1295 typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
1297 // Reserve some memory inside the render queue
1298 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1300 // Construct message in the render queue memory; note that delete should not be called on the return value
1301 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1304 void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
1306 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1308 // Reserve some memory inside the render queue
1309 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1311 // Construct message in the render queue memory; note that delete should not be called on the return value
1312 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1315 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1317 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1319 // Reserve some memory inside the render queue
1320 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1322 // Construct message in the render queue memory; note that delete should not be called on the return value
1323 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1326 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, unsigned int mipmapLevel, unsigned int layer )
1328 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, unsigned int, unsigned int > DerivedType;
1330 // Reserve some memory inside the render queue
1331 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1333 // Construct message in the render queue memory; note that delete should not be called on the return value
1334 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1337 } // namespace SceneGraph
1339 } // namespace Internal