2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/update/manager/update-manager.h>
22 #include <dali/public-api/common/stage.h>
23 #include <dali/devel-api/common/set-wrapper.h>
24 #include <dali/devel-api/common/owner-container.h>
25 #include <dali/devel-api/threading/mutex.h>
27 #include <dali/integration-api/core.h>
28 #include <dali/integration-api/render-controller.h>
29 #include <dali/internal/common/shader-data.h>
30 #include <dali/integration-api/debug.h>
32 #include <dali/internal/common/core-impl.h>
33 #include <dali/internal/common/message.h>
35 #include <dali/internal/event/common/notification-manager.h>
36 #include <dali/internal/event/common/property-notification-impl.h>
37 #include <dali/internal/event/common/property-notifier.h>
38 #include <dali/internal/event/effects/shader-factory.h>
40 #include <dali/internal/update/animation/scene-graph-animator.h>
41 #include <dali/internal/update/animation/scene-graph-animation.h>
42 #include <dali/internal/update/common/discard-queue.h>
43 #include <dali/internal/update/common/scene-graph-buffers.h>
44 #include <dali/internal/update/common/texture-cache-dispatcher.h>
45 #include <dali/internal/update/controllers/render-message-dispatcher.h>
46 #include <dali/internal/update/controllers/scene-controller-impl.h>
47 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
48 #include <dali/internal/update/manager/object-owner-container.h>
49 #include <dali/internal/update/manager/render-task-processor.h>
50 #include <dali/internal/update/manager/sorted-layers.h>
51 #include <dali/internal/update/manager/update-algorithms.h>
52 #include <dali/internal/update/manager/update-manager-debug.h>
53 #include <dali/internal/update/manager/transform-manager.h>
54 #include <dali/internal/update/nodes/node.h>
55 #include <dali/internal/update/nodes/scene-graph-layer.h>
56 #include <dali/internal/update/queue/update-message-queue.h>
57 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
58 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
59 #include <dali/internal/update/rendering/scene-graph-texture-set.h>
60 #include <dali/internal/update/resources/resource-manager.h>
61 #include <dali/internal/update/render-tasks/scene-graph-camera.h>
63 #include <dali/internal/render/common/render-instruction-container.h>
64 #include <dali/internal/render/common/render-manager.h>
65 #include <dali/internal/render/queue/render-queue.h>
66 #include <dali/internal/render/gl-resources/texture-cache.h>
67 #include <dali/internal/render/shaders/scene-graph-shader.h>
69 // Un-comment to enable node tree debug logging
70 //#define NODE_TREE_LOGGING 1
72 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
73 #define SNAPSHOT_NODE_LOGGING \
74 const int FRAME_COUNT_TRIGGER = 16;\
75 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
77 if ( NULL != mImpl->root )\
79 mImpl->frameCounter = 0;\
80 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
83 mImpl->frameCounter++;
85 #define SNAPSHOT_NODE_LOGGING
88 #if defined(DEBUG_ENABLED)
89 extern Debug::Filter* gRenderTaskLogFilter;
93 using namespace Dali::Integration;
94 using Dali::Internal::Update::MessageQueue;
105 typedef OwnerContainer< Shader* > ShaderContainer;
106 typedef ShaderContainer::Iterator ShaderIter;
107 typedef ShaderContainer::ConstIterator ShaderConstIter;
109 typedef std::vector<Internal::ShaderDataPtr> ShaderDataBinaryQueue;
111 typedef OwnerContainer<PanGesture*> GestureContainer;
112 typedef GestureContainer::Iterator GestureIter;
113 typedef GestureContainer::ConstIterator GestureConstIter;
115 typedef OwnerContainer< TextureSet* > TextureSetContainer;
116 typedef TextureSetContainer::Iterator TextureSetIter;
117 typedef TextureSetContainer::ConstIterator TextureSetConstIter;
120 * Structure to contain UpdateManager internal data
122 struct UpdateManager::Impl
124 Impl( NotificationManager& notificationManager,
125 CompleteNotificationInterface& animationFinishedNotifier,
126 PropertyNotifier& propertyNotifier,
127 ResourceManager& resourceManager,
128 DiscardQueue& discardQueue,
129 RenderController& renderController,
130 RenderManager& renderManager,
131 RenderQueue& renderQueue,
132 SceneGraphBuffers& sceneGraphBuffers,
133 RenderTaskProcessor& renderTaskProcessor )
134 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
135 notificationManager( notificationManager ),
137 animationFinishedNotifier( animationFinishedNotifier ),
138 propertyNotifier( propertyNotifier ),
140 resourceManager( resourceManager ),
141 discardQueue( discardQueue ),
142 renderController( renderController ),
143 sceneController( NULL ),
144 renderManager( renderManager ),
145 renderQueue( renderQueue ),
146 renderInstructions( renderManager.GetRenderInstructionContainer() ),
147 renderTaskProcessor( renderTaskProcessor ),
148 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
149 taskList( renderMessageDispatcher, resourceManager ),
150 systemLevelTaskList( renderMessageDispatcher, resourceManager ),
152 systemLevelRoot( NULL ),
153 renderers( sceneGraphBuffers, discardQueue ),
155 messageQueue( renderController, sceneGraphBuffers ),
156 keepRenderingSeconds( 0.0f ),
157 animationFinishedDuringUpdate( false ),
158 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
159 previousUpdateScene( false ),
161 renderTaskWaiting( false )
163 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
165 renderers.SetSceneController( *sceneController );
167 // create first 'dummy' node
173 // Disconnect render tasks from nodes, before destroying the nodes
174 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
175 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
177 (*iter)->SetSourceNode( NULL );
179 // ..repeat for system level RenderTasks
180 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
181 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
183 (*iter)->SetSourceNode( NULL );
186 // UpdateManager owns the Nodes
187 Vector<Node*>::Iterator iter = nodes.Begin()+1;
188 Vector<Node*>::Iterator endIter = nodes.End();
189 for(;iter!=endIter;++iter)
191 (*iter)->OnDestroy();
195 // If there is root, reset it, otherwise do nothing as rendering was never started
204 if( systemLevelRoot )
206 systemLevelRoot->OnDestroy();
208 delete systemLevelRoot;
209 systemLevelRoot = NULL;
212 delete sceneController;
215 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
216 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
217 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
218 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
219 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
220 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
221 ShaderSaver* shaderSaver; ///< Saves shader binaries.
222 ResourceManager& resourceManager; ///< resource manager
223 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
224 RenderController& renderController; ///< render controller
225 SceneControllerImpl* sceneController; ///< scene controller
226 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
227 RenderQueue& renderQueue; ///< Used to queue messages for the next render
228 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
229 RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
231 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
233 RenderTaskList taskList; ///< The list of scene graph render-tasks
234 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
236 Layer* root; ///< The root node (root is a layer)
237 Layer* systemLevelRoot; ///< A separate root-node for system-level content
239 Vector<Node*> nodes; ///< A container of all instantiated nodes
241 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
242 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
244 OwnerContainer< Camera* > cameras; ///< A container of cameras
245 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
247 AnimationContainer animations; ///< A container of owned animations
248 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
250 ObjectOwnerContainer<Renderer> renderers;
251 TextureSetContainer textureSets; ///< A container of texture sets
253 ShaderContainer shaders; ///< A container of owned shaders
255 MessageQueue messageQueue; ///< The messages queued from the event-thread
256 ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
257 ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event
258 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
260 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
261 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
263 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
264 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
266 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
268 GestureContainer gestures; ///< A container of owned gesture detectors
269 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
273 Impl( const Impl& ); ///< Undefined
274 Impl& operator=( const Impl& ); ///< Undefined
277 UpdateManager::UpdateManager( NotificationManager& notificationManager,
278 CompleteNotificationInterface& animationFinishedNotifier,
279 PropertyNotifier& propertyNotifier,
280 ResourceManager& resourceManager,
281 DiscardQueue& discardQueue,
282 RenderController& controller,
283 RenderManager& renderManager,
284 RenderQueue& renderQueue,
285 TextureCacheDispatcher& textureCacheDispatcher,
286 RenderTaskProcessor& renderTaskProcessor )
289 mImpl = new Impl( notificationManager,
290 animationFinishedNotifier,
298 renderTaskProcessor );
300 textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers );
303 UpdateManager::~UpdateManager()
308 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
310 DALI_ASSERT_DEBUG( layer->IsLayer() );
311 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
315 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
317 mImpl->root->CreateTransform( &mImpl->transformManager );
321 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
322 mImpl->systemLevelRoot = layer;
323 mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager );
326 layer->SetRoot(true);
329 void UpdateManager::AddNode( Node* node )
331 DALI_ASSERT_ALWAYS( NULL != node );
332 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
334 // Nodes must be sorted by pointer
335 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
336 for(Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter)
340 mImpl->nodes.Insert((iter+1), node);
341 node->CreateTransform( &mImpl->transformManager );
347 void UpdateManager::ConnectNode( Node* parent, Node* node )
349 DALI_ASSERT_ALWAYS( NULL != parent );
350 DALI_ASSERT_ALWAYS( NULL != node );
351 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
353 parent->ConnectChild( node );
356 void UpdateManager::DisconnectNode( Node* node )
358 Node* parent = node->GetParent();
359 DALI_ASSERT_ALWAYS( NULL != parent );
360 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
362 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
365 void UpdateManager::DestroyNode( Node* node )
367 DALI_ASSERT_ALWAYS( NULL != node );
368 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
370 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
371 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
372 for(;iter!=endIter;++iter)
376 mImpl->nodes.Erase(iter);
381 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
383 // Notify the Node about impending destruction
387 void UpdateManager::AddCamera( Camera* camera )
389 DALI_ASSERT_DEBUG( camera != NULL );
391 mImpl->cameras.PushBack( camera ); // takes ownership
394 void UpdateManager::RemoveCamera( const Camera* camera )
397 OwnerContainer<Camera*>::Iterator iter = mImpl->cameras.Begin();
398 OwnerContainer<Camera*>::ConstIterator end = mImpl->cameras.End();
399 for ( ; iter != end; ++iter )
401 Camera* value = *iter;
402 if ( camera == value )
404 // Transfer ownership to the discard queue
405 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->cameras.Release( iter ) );
413 void UpdateManager::AddObject( PropertyOwner* object )
415 DALI_ASSERT_DEBUG( NULL != object );
417 mImpl->customObjects.PushBack( object );
420 void UpdateManager::RemoveObject( PropertyOwner* object )
422 DALI_ASSERT_DEBUG( NULL != object );
424 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
426 // Find the object and destroy it
427 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
429 PropertyOwner* current = *iter;
430 if ( current == object )
432 customObjects.Erase( iter );
437 // Should not reach here
438 DALI_ASSERT_DEBUG(false);
441 void UpdateManager::AddAnimation( Animation* animation )
443 mImpl->animations.PushBack( animation );
446 void UpdateManager::StopAnimation( Animation* animation )
448 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
450 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
452 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
455 void UpdateManager::RemoveAnimation( Animation* animation )
457 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
459 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
461 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
464 bool UpdateManager::IsAnimationRunning() const
466 bool isRunning(false);
467 AnimationContainer& animations = mImpl->animations;
469 // Find any animation that isn't stopped or paused
471 const AnimationIter endIter = animations.End();
472 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
474 const Animation::State state = (*iter)->GetState();
476 if (state != Animation::Stopped &&
477 state != Animation::Paused)
486 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
488 mImpl->propertyNotifications.PushBack( propertyNotification );
491 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
493 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
494 PropertyNotificationIter iter = propertyNotifications.Begin();
496 while ( iter != propertyNotifications.End() )
498 if( *iter == propertyNotification )
500 propertyNotifications.Erase(iter);
507 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
509 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
510 propertyNotification->SetNotifyMode( notifyMode );
513 ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
515 return mImpl->renderers;
518 void UpdateManager::AddShader( Shader* shader )
520 DALI_ASSERT_DEBUG( NULL != shader );
522 if( mImpl->shaders.Count() == 0 )
524 // the first added shader becomes our default shader
525 // Construct message in the render queue memory; note that delete should not be called on the return value
526 typedef MessageValue1< RenderManager, Shader* > DerivedType;
528 // Reserve some memory inside the render queue
529 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
531 // Construct message in the render queue memory; note that delete should not be called on the return value
532 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
535 mImpl->shaders.PushBack( shader );
538 void UpdateManager::RemoveShader( Shader* shader )
540 DALI_ASSERT_DEBUG(shader != NULL);
542 ShaderContainer& shaders = mImpl->shaders;
544 // Find the shader and destroy it
545 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
547 Shader& current = **iter;
548 if ( ¤t == shader )
550 // Transfer ownership to the discard queue
551 // This keeps the shader alive, until the render-thread has finished with it
552 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
557 // Should not reach here
558 DALI_ASSERT_DEBUG(false);
561 void UpdateManager::SetShaderProgram( Shader* shader,
562 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
567 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
569 // Reserve some memory inside the render queue
570 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
572 // Construct message in the render queue memory; note that delete should not be called on the return value
573 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
577 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
579 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
580 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
582 // lock as update might be sending previously compiled shaders to event thread
583 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
584 mImpl->renderCompiledShaders.push_back( shaderData );
588 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
592 // copy the list, this is only likely to happen once in application life cycle
593 return &(mImpl->taskList);
597 // copy the list, this is only likely to happen once in application life cycle
598 return &(mImpl->systemLevelTaskList);
602 void UpdateManager::AddGesture( PanGesture* gesture )
604 DALI_ASSERT_DEBUG( NULL != gesture );
606 mImpl->gestures.PushBack( gesture );
609 void UpdateManager::RemoveGesture( PanGesture* gesture )
611 DALI_ASSERT_DEBUG( gesture != NULL );
613 GestureContainer& gestures = mImpl->gestures;
615 // Find the gesture and destroy it
616 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
618 PanGesture& current = **iter;
619 if ( ¤t == gesture )
621 mImpl->gestures.Erase( iter );
625 // Should not reach here
626 DALI_ASSERT_DEBUG(false);
629 void UpdateManager::AddTextureSet( TextureSet* textureSet )
631 DALI_ASSERT_DEBUG( NULL != textureSet );
632 mImpl->textureSets.PushBack( textureSet );
635 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
637 DALI_ASSERT_DEBUG(textureSet != NULL);
638 size_t textureSetCount( mImpl->textureSets.Size() );
639 for( size_t i(0); i<textureSetCount; ++i )
641 if( textureSet == mImpl->textureSets[i] )
643 mImpl->textureSets.Remove( mImpl->textureSets.Begin() + i );
649 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
651 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
654 void UpdateManager::EventProcessingStarted()
656 mImpl->messageQueue.EventProcessingStarted();
659 bool UpdateManager::FlushQueue()
661 return mImpl->messageQueue.FlushQueue();
664 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
666 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
667 mImpl->animationFinishedDuringUpdate = false;
669 // Animated properties have to be reset to their original value each frame
671 // Reset root properties
674 mImpl->root->ResetToBaseValues( bufferIndex );
676 if ( mImpl->systemLevelRoot )
678 mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
681 // Reset all the nodes
682 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
683 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
684 for(;iter != endIter; ++iter)
686 (*iter)->ResetToBaseValues( bufferIndex );
689 // Reset system-level render-task list properties to base values
690 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
692 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
694 (*iter)->ResetToBaseValues( bufferIndex );
697 // Reset render-task list properties to base values.
698 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
700 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
702 (*iter)->ResetToBaseValues( bufferIndex );
705 // Reset custom object properties to base values
706 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
708 (*iter)->ResetToBaseValues( bufferIndex );
711 mImpl->renderers.ResetToBaseValues( bufferIndex );
713 // Reset animatable shader properties to base values
714 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
716 (*iter)->ResetToBaseValues( bufferIndex );
720 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
722 bool gestureUpdated( false );
724 // constrain gestures... (in construction order)
725 GestureContainer& gestures = mImpl->gestures;
727 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
729 PanGesture& gesture = **iter;
730 gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
731 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
734 return gestureUpdated;
737 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
739 AnimationContainer &animations = mImpl->animations;
740 AnimationIter iter = animations.Begin();
741 bool animationLooped = false;
742 while ( iter != animations.End() )
744 Animation* animation = *iter;
745 bool finished = false;
747 animation->Update( bufferIndex, elapsedSeconds, looped, finished );
749 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
750 animationLooped = animationLooped || looped;
752 // Remove animations that had been destroyed but were still waiting for an update
753 if (animation->GetState() == Animation::Destroyed)
755 iter = animations.Erase(iter);
763 // queue the notification on finished or looped (to update loop count)
764 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
766 // The application should be notified by NotificationManager, in another thread
767 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
771 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
773 //Constrain custom objects (in construction order)
774 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
775 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
776 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
778 PropertyOwner& object = **iter;
779 ConstrainPropertyOwner( object, bufferIndex );
783 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
785 // Constrain system-level render-tasks
786 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
787 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
789 RenderTask& task = **iter;
790 ConstrainPropertyOwner( task, bufferIndex );
793 // Constrain render-tasks
794 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
795 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
797 RenderTask& task = **iter;
798 ConstrainPropertyOwner( task, bufferIndex );
802 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
804 // constrain shaders... (in construction order)
805 ShaderContainer& shaders = mImpl->shaders;
806 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
808 Shader& shader = **iter;
809 ConstrainPropertyOwner( shader, bufferIndex );
813 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
815 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
816 PropertyNotificationIter iter = notifications.Begin();
818 while ( iter != notifications.End() )
820 PropertyNotification* notification = *iter;
821 bool valid = notification->Check( bufferIndex );
824 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
830 void UpdateManager::ForwardCompiledShadersToEventThread()
832 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
833 if( mImpl->shaderSaver )
835 // lock and swap the queues
837 // render might be attempting to send us more binaries at the same time
838 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
839 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
842 if( mImpl->updateCompiledShaders.size() > 0 )
844 ShaderSaver& factory = *mImpl->shaderSaver;
845 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
846 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
847 for( ; i != end; ++i )
849 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
851 // we don't need them in update anymore
852 mImpl->updateCompiledShaders.clear();
857 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
859 const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
860 unsigned int rendererCount( rendererContainer.Size() );
861 for( unsigned int i(0); i<rendererCount; ++i )
864 ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
866 rendererContainer[i]->PrepareRender( bufferIndex );
870 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
872 mImpl->nodeDirtyFlags = NothingFlag;
879 // Prepare resources, update shaders, for each node
880 // And add the renderers to the sorted layers. Start from root, which is also a layer
881 mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
883 mImpl->resourceManager,
884 mImpl->renderQueue );
886 if ( mImpl->systemLevelRoot )
888 mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
890 mImpl->resourceManager,
891 mImpl->renderQueue );
895 unsigned int UpdateManager::Update( float elapsedSeconds,
896 unsigned int lastVSyncTimeMilliseconds,
897 unsigned int nextVSyncTimeMilliseconds )
899 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
901 //Clear nodes/resources which were previously discarded
902 mImpl->discardQueue.Clear( bufferIndex );
904 //Grab any loaded resources
905 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
907 //Process Touches & Gestures
908 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
910 const bool updateScene = // The scene-graph requires an update if..
911 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
912 IsAnimationRunning() || // ..at least one animation is running OR
913 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
914 resourceChanged || // ..one or more resources were updated/changed OR
915 gestureUpdated; // ..a gesture property was updated
918 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
919 // values if the scene was updated in the previous frame.
920 if( updateScene || mImpl->previousUpdateScene )
922 //Reset properties from the previous update
923 ResetProperties( bufferIndex );
924 mImpl->transformManager.ResetToBaseValue();
927 //Process the queued scene messages
928 mImpl->messageQueue.ProcessMessages( bufferIndex );
930 //Forward compiled shader programs to event thread for saving
931 ForwardCompiledShadersToEventThread();
933 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
934 // renderer lists if the scene was updated in the previous frame.
935 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
936 if( updateScene || mImpl->previousUpdateScene )
939 Animate( bufferIndex, elapsedSeconds );
941 //Constraint custom objects
942 ConstrainCustomObjects( bufferIndex );
944 //Clear the lists of renderers from the previous update
945 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
947 mImpl->sortedLayers[i]->ClearRenderables();
950 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
952 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
955 //Update node hierarchy, apply constraints and perform sorting / culling.
956 //This will populate each Layer with a list of renderers which are ready.
957 UpdateNodes( bufferIndex );
959 //Apply constraints to RenderTasks, shaders
960 ConstrainRenderTasks( bufferIndex );
961 ConstrainShaders( bufferIndex );
963 //Update renderers and apply constraints
964 UpdateRenderers( bufferIndex );
966 //Update the trnasformations of all the nodes
967 mImpl->transformManager.Update();
969 //Process Property Notifications
970 ProcessPropertyNotifications( bufferIndex );
972 //Process the RenderTasks; this creates the instructions for rendering the next frame.
973 //reset the update buffer index and make sure there is enough room in the instruction container
974 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
975 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
977 if ( NULL != mImpl->root )
979 mImpl->renderTaskProcessor.Process( bufferIndex,
983 mImpl->renderInstructions );
985 // Process the system-level RenderTasks last
986 if ( NULL != mImpl->systemLevelRoot )
988 mImpl->renderTaskProcessor.Process( bufferIndex,
989 mImpl->systemLevelTaskList,
990 *mImpl->systemLevelRoot,
991 mImpl->systemLevelSortedLayers,
992 mImpl->renderInstructions );
997 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
998 bool doRenderOnceNotify = false;
999 mImpl->renderTaskWaiting = false;
1000 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1001 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1002 endIter != iter; ++iter )
1004 RenderTask& renderTask(*(*iter));
1006 renderTask.UpdateState();
1008 if( renderTask.IsWaitingToRender() &&
1009 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1011 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1014 if( renderTask.HasRendered() )
1016 doRenderOnceNotify = true;
1020 if( doRenderOnceNotify )
1022 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1023 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1026 // Macro is undefined in release build.
1027 SNAPSHOT_NODE_LOGGING;
1029 // A ResetProperties() may be required in the next frame
1030 mImpl->previousUpdateScene = updateScene;
1032 // Check whether further updates are required
1033 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1035 // tell the update manager that we're done so the queue can be given to event thread
1036 mImpl->notificationManager.UpdateCompleted();
1038 // The update has finished; swap the double-buffering indices
1039 mSceneGraphBuffers.Swap();
1041 return keepUpdating;
1044 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1046 // Update the duration set via Stage::KeepRendering()
1047 if ( mImpl->keepRenderingSeconds > 0.0f )
1049 mImpl->keepRenderingSeconds -= elapsedSeconds;
1052 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1054 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1055 // Keep updating until no messages are received and no animations are running.
1056 // If an animation has just finished, update at least once more for Discard end-actions.
1057 // No need to check for renderQueue as there is always a render after update and if that
1058 // render needs another update it will tell the adaptor to call update again
1060 if ( mImpl->keepRenderingSeconds > 0.0f )
1062 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1065 if ( IsAnimationRunning() ||
1066 mImpl->animationFinishedDuringUpdate )
1068 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1071 if ( mImpl->renderTaskWaiting )
1073 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1076 return keepUpdatingRequest;
1079 void UpdateManager::SetBackgroundColor( const Vector4& color )
1081 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1083 // Reserve some memory inside the render queue
1084 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1086 // Construct message in the render queue memory; note that delete should not be called on the return value
1087 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1090 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1092 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1094 // Reserve some memory inside the render queue
1095 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1097 // Construct message in the render queue memory; note that delete should not be called on the return value
1098 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1101 void UpdateManager::KeepRendering( float durationSeconds )
1103 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1106 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1110 // just copy the vector of pointers
1111 mImpl->sortedLayers = layers;
1115 mImpl->systemLevelSortedLayers = layers;
1119 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1121 mImpl->shaderSaver = &upstream;
1124 void UpdateManager::AddSampler( Render::Sampler* sampler )
1126 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1128 // Reserve some memory inside the render queue
1129 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1131 // Construct message in the render queue memory; note that delete should not be called on the return value
1132 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1135 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1137 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1139 // Reserve some memory inside the render queue
1140 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1142 // Construct message in the render queue memory; note that delete should not be called on the return value
1143 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1146 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1148 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > 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::SetFilterMode, sampler, minFilterMode, magFilterMode );
1157 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
1159 typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > 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::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1168 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1170 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1172 // Reserve some memory inside the render queue
1173 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1175 // Construct message in the render queue memory; note that delete should not be called on the return value
1176 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1179 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1181 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1183 // Reserve some memory inside the render queue
1184 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1186 // Construct message in the render queue memory; note that delete should not be called on the return value
1187 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1190 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1192 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, 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 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, Dali::Vector<char>*, size_t > DerivedType;
1205 // Reserve some memory inside the render queue
1206 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1208 // Construct message in the render queue memory; note that delete should not be called on the return value
1209 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1212 void UpdateManager::AddGeometry( Render::Geometry* geometry )
1214 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1216 // Reserve some memory inside the render queue
1217 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1219 // Construct message in the render queue memory; note that delete should not be called on the return value
1220 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1223 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1225 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1227 // Reserve some memory inside the render queue
1228 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1230 // Construct message in the render queue memory; note that delete should not be called on the return value
1231 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1234 void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
1236 typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType;
1238 // Reserve some memory inside the render queue
1239 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1241 // Construct message in the render queue memory; note that delete should not be called on the return value
1242 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1245 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
1247 typedef IndexBufferMessage< RenderManager > DerivedType;
1249 // Reserve some memory inside the render queue
1250 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1252 // Construct message in the render queue memory; note that delete should not be called on the return value
1253 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1256 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1258 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1260 // Reserve some memory inside the render queue
1261 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1263 // Construct message in the render queue memory; note that delete should not be called on the return value
1264 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1267 void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1269 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1271 // Reserve some memory inside the render queue
1272 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1274 // Construct message in the render queue memory; note that delete should not be called on the return value
1275 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, geometry, propertyBuffer );
1278 void UpdateManager::AddTexture( Render::NewTexture* texture )
1280 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1282 // Reserve some memory inside the render queue
1283 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1285 // Construct message in the render queue memory; note that delete should not be called on the return value
1286 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1289 void UpdateManager::RemoveTexture( Render::NewTexture* texture)
1291 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1293 // Reserve some memory inside the render queue
1294 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1296 // Construct message in the render queue memory; note that delete should not be called on the return value
1297 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1300 void UpdateManager::UploadTexture( Render::NewTexture* texture, PixelDataPtr pixelData, const NewTexture::UploadParams& params )
1302 typedef MessageValue3< RenderManager, Render::NewTexture*, PixelDataPtr, NewTexture::UploadParams > DerivedType;
1304 // Reserve some memory inside the message queue
1305 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1307 // Construct message in the message queue memory; note that delete should not be called on the return value
1308 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1311 void UpdateManager::GenerateMipmaps( Render::NewTexture* texture )
1313 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1315 // Reserve some memory inside the render queue
1316 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1318 // Construct message in the render queue memory; note that delete should not be called on the return value
1319 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1322 void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
1324 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1326 // Reserve some memory inside the render queue
1327 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1329 // Construct message in the render queue memory; note that delete should not be called on the return value
1330 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1333 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1335 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1337 // Reserve some memory inside the render queue
1338 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1340 // Construct message in the render queue memory; note that delete should not be called on the return value
1341 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1344 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::NewTexture* texture, unsigned int mipmapLevel, unsigned int layer )
1346 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::NewTexture*, unsigned int, unsigned int > DerivedType;
1348 // Reserve some memory inside the render queue
1349 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1351 // Construct message in the render queue memory; note that delete should not be called on the return value
1352 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1355 } // namespace SceneGraph
1357 } // namespace Internal