2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/update/manager/update-manager.h>
22 #include <dali/public-api/common/stage.h>
23 #include <dali/devel-api/common/set-wrapper.h>
24 #include <dali/devel-api/common/owner-container.h>
25 #include <dali/devel-api/threading/mutex.h>
27 #include <dali/integration-api/core.h>
28 #include <dali/integration-api/render-controller.h>
29 #include <dali/internal/common/shader-data.h>
30 #include <dali/integration-api/debug.h>
32 #include <dali/internal/common/core-impl.h>
33 #include <dali/internal/common/message.h>
35 #include <dali/internal/event/common/notification-manager.h>
36 #include <dali/internal/event/common/property-notification-impl.h>
37 #include <dali/internal/event/common/property-notifier.h>
38 #include <dali/internal/event/effects/shader-factory.h>
40 #include <dali/internal/update/animation/scene-graph-animator.h>
41 #include <dali/internal/update/animation/scene-graph-animation.h>
42 #include <dali/internal/update/common/discard-queue.h>
43 #include <dali/internal/update/common/scene-graph-buffers.h>
44 #include <dali/internal/update/common/texture-cache-dispatcher.h>
45 #include <dali/internal/update/controllers/render-message-dispatcher.h>
46 #include <dali/internal/update/controllers/scene-controller-impl.h>
47 #include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
48 #include <dali/internal/update/manager/object-owner-container.h>
49 #include <dali/internal/update/manager/render-task-processor.h>
50 #include <dali/internal/update/manager/sorted-layers.h>
51 #include <dali/internal/update/manager/update-algorithms.h>
52 #include <dali/internal/update/manager/update-manager-debug.h>
53 #include <dali/internal/update/manager/transform-manager.h>
54 #include <dali/internal/update/nodes/node.h>
55 #include <dali/internal/update/nodes/scene-graph-layer.h>
56 #include <dali/internal/update/queue/update-message-queue.h>
57 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
58 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
59 #include <dali/internal/update/rendering/scene-graph-texture-set.h>
60 #include <dali/internal/update/resources/resource-manager.h>
61 #include <dali/internal/update/manager/geometry-batcher.h>
62 #include <dali/internal/update/render-tasks/scene-graph-camera.h>
64 #include <dali/internal/render/common/render-instruction-container.h>
65 #include <dali/internal/render/common/render-manager.h>
66 #include <dali/internal/render/queue/render-queue.h>
67 #include <dali/internal/render/gl-resources/texture-cache.h>
68 #include <dali/internal/render/shaders/scene-graph-shader.h>
70 // Un-comment to enable node tree debug logging
71 //#define NODE_TREE_LOGGING 1
73 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
74 #define SNAPSHOT_NODE_LOGGING \
75 const int FRAME_COUNT_TRIGGER = 16;\
76 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
78 if ( NULL != mImpl->root )\
80 mImpl->frameCounter = 0;\
81 PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
84 mImpl->frameCounter++;
86 #define SNAPSHOT_NODE_LOGGING
89 #if defined(DEBUG_ENABLED)
90 extern Debug::Filter* gRenderTaskLogFilter;
94 using namespace Dali::Integration;
95 using Dali::Internal::Update::MessageQueue;
106 typedef OwnerContainer< Shader* > ShaderContainer;
107 typedef ShaderContainer::Iterator ShaderIter;
108 typedef ShaderContainer::ConstIterator ShaderConstIter;
110 typedef std::vector<Internal::ShaderDataPtr> ShaderDataBinaryQueue;
112 typedef OwnerContainer<PanGesture*> GestureContainer;
113 typedef GestureContainer::Iterator GestureIter;
114 typedef GestureContainer::ConstIterator GestureConstIter;
116 typedef OwnerContainer< TextureSet* > TextureSetContainer;
117 typedef TextureSetContainer::Iterator TextureSetIter;
118 typedef TextureSetContainer::ConstIterator TextureSetConstIter;
121 * Structure to contain UpdateManager internal data
123 struct UpdateManager::Impl
125 Impl( NotificationManager& notificationManager,
126 CompleteNotificationInterface& animationFinishedNotifier,
127 PropertyNotifier& propertyNotifier,
128 ResourceManager& resourceManager,
129 DiscardQueue& discardQueue,
130 RenderController& renderController,
131 RenderManager& renderManager,
132 RenderQueue& renderQueue,
133 SceneGraphBuffers& sceneGraphBuffers,
134 GeometryBatcher& geometryBatcher,
135 RenderTaskProcessor& renderTaskProcessor )
136 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
137 notificationManager( notificationManager ),
139 animationFinishedNotifier( animationFinishedNotifier ),
140 propertyNotifier( propertyNotifier ),
142 resourceManager( resourceManager ),
143 discardQueue( discardQueue ),
144 renderController( renderController ),
145 sceneController( NULL ),
146 renderManager( renderManager ),
147 renderQueue( renderQueue ),
148 renderInstructions( renderManager.GetRenderInstructionContainer() ),
149 geometryBatcher( geometryBatcher ),
150 renderTaskProcessor( renderTaskProcessor ),
151 backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
152 taskList( renderMessageDispatcher, resourceManager ),
153 systemLevelTaskList( renderMessageDispatcher, resourceManager ),
155 systemLevelRoot( NULL ),
156 renderers( sceneGraphBuffers, discardQueue ),
158 messageQueue( renderController, sceneGraphBuffers ),
159 keepRenderingSeconds( 0.0f ),
160 animationFinishedDuringUpdate( false ),
161 nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
162 previousUpdateScene( false ),
164 renderTaskWaiting( false )
166 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
168 renderers.SetSceneController( *sceneController );
170 discardQueue.SetGeometryBatcher( &geometryBatcher );
172 // create first 'dummy' node
178 // Disconnect render tasks from nodes, before destroying the nodes
179 RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
180 for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
182 (*iter)->SetSourceNode( NULL );
184 // ..repeat for system level RenderTasks
185 RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
186 for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
188 (*iter)->SetSourceNode( NULL );
191 // UpdateManager owns the Nodes
192 Vector<Node*>::Iterator iter = nodes.Begin()+1;
193 Vector<Node*>::Iterator endIter = nodes.End();
194 for(;iter!=endIter;++iter)
196 (*iter)->OnDestroy();
200 // If there is root, reset it, otherwise do nothing as rendering was never started
209 if( systemLevelRoot )
211 systemLevelRoot->OnDestroy();
213 delete systemLevelRoot;
214 systemLevelRoot = NULL;
217 delete sceneController;
220 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
221 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
222 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
223 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
224 CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished.
225 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
226 ShaderSaver* shaderSaver; ///< Saves shader binaries.
227 ResourceManager& resourceManager; ///< resource manager
228 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
229 RenderController& renderController; ///< render controller
230 SceneControllerImpl* sceneController; ///< scene controller
231 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
232 RenderQueue& renderQueue; ///< Used to queue messages for the next render
233 RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions
234 GeometryBatcher& geometryBatcher; ///< An instance of the GeometryBatcher
235 RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
237 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
239 RenderTaskList taskList; ///< The list of scene graph render-tasks
240 RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content
242 Layer* root; ///< The root node (root is a layer)
243 Layer* systemLevelRoot; ///< A separate root-node for system-level content
245 Vector<Node*> nodes; ///< A container of all instantiated nodes
247 SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
248 SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
250 OwnerContainer< Camera* > cameras; ///< A container of cameras
251 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
253 AnimationContainer animations; ///< A container of owned animations
254 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
256 ObjectOwnerContainer<Renderer> renderers;
257 TextureSetContainer textureSets; ///< A container of texture sets
259 ShaderContainer shaders; ///< A container of owned shaders
261 MessageQueue messageQueue; ///< The messages queued from the event-thread
262 ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
263 ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event
264 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
266 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
267 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
269 int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
270 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
272 int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
274 GestureContainer gestures; ///< A container of owned gesture detectors
275 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
279 Impl( const Impl& ); ///< Undefined
280 Impl& operator=( const Impl& ); ///< Undefined
283 UpdateManager::UpdateManager( NotificationManager& notificationManager,
284 CompleteNotificationInterface& animationFinishedNotifier,
285 PropertyNotifier& propertyNotifier,
286 ResourceManager& resourceManager,
287 DiscardQueue& discardQueue,
288 RenderController& controller,
289 RenderManager& renderManager,
290 RenderQueue& renderQueue,
291 TextureCacheDispatcher& textureCacheDispatcher,
292 GeometryBatcher& geometryBatcher,
293 RenderTaskProcessor& renderTaskProcessor )
296 mImpl = new Impl( notificationManager,
297 animationFinishedNotifier,
306 renderTaskProcessor );
308 textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers );
309 mImpl->geometryBatcher.SetUpdateManager( this );
312 UpdateManager::~UpdateManager()
317 void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
319 DALI_ASSERT_DEBUG( layer->IsLayer() );
320 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
324 DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" );
326 mImpl->root->CreateTransform( &mImpl->transformManager );
330 DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" );
331 mImpl->systemLevelRoot = layer;
332 mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager );
335 layer->SetRoot(true);
338 void UpdateManager::AddNode( Node* node )
340 DALI_ASSERT_ALWAYS( NULL != node );
341 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
343 // Nodes must be sorted by pointer
344 Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
345 for(Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter)
349 mImpl->nodes.Insert((iter+1), node);
350 node->CreateTransform( &mImpl->transformManager );
351 node->mGeometryBatcher = &mImpl->geometryBatcher;
357 void UpdateManager::ConnectNode( Node* parent, Node* node )
359 DALI_ASSERT_ALWAYS( NULL != parent );
360 DALI_ASSERT_ALWAYS( NULL != node );
361 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
363 parent->ConnectChild( node );
366 void UpdateManager::DisconnectNode( Node* node )
368 Node* parent = node->GetParent();
369 DALI_ASSERT_ALWAYS( NULL != parent );
370 parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
372 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
375 void UpdateManager::DestroyNode( Node* node )
377 DALI_ASSERT_ALWAYS( NULL != node );
378 DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
380 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
381 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
382 for(;iter!=endIter;++iter)
386 mImpl->nodes.Erase(iter);
391 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
393 // Notify the Node about impending destruction
397 void UpdateManager::AddCamera( Camera* camera )
399 DALI_ASSERT_DEBUG( camera != NULL );
401 mImpl->cameras.PushBack( camera ); // takes ownership
404 void UpdateManager::RemoveCamera( const Camera* camera )
407 OwnerContainer<Camera*>::Iterator iter = mImpl->cameras.Begin();
408 OwnerContainer<Camera*>::ConstIterator end = mImpl->cameras.End();
409 for ( ; iter != end; ++iter )
411 Camera* value = *iter;
412 if ( camera == value )
414 // Transfer ownership to the discard queue
415 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->cameras.Release( iter ) );
423 void UpdateManager::AddObject( PropertyOwner* object )
425 DALI_ASSERT_DEBUG( NULL != object );
427 mImpl->customObjects.PushBack( object );
430 void UpdateManager::RemoveObject( PropertyOwner* object )
432 DALI_ASSERT_DEBUG( NULL != object );
434 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
436 // Find the object and destroy it
437 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
439 PropertyOwner* current = *iter;
440 if ( current == object )
442 customObjects.Erase( iter );
447 // Should not reach here
448 DALI_ASSERT_DEBUG(false);
451 void UpdateManager::AddAnimation( Animation* animation )
453 mImpl->animations.PushBack( animation );
456 void UpdateManager::StopAnimation( Animation* animation )
458 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
460 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
462 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
465 void UpdateManager::RemoveAnimation( Animation* animation )
467 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
469 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
471 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
474 bool UpdateManager::IsAnimationRunning() const
476 bool isRunning(false);
477 AnimationContainer& animations = mImpl->animations;
479 // Find any animation that isn't stopped or paused
481 const AnimationIter endIter = animations.End();
482 for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter )
484 const Animation::State state = (*iter)->GetState();
486 if (state != Animation::Stopped &&
487 state != Animation::Paused)
496 void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification )
498 mImpl->propertyNotifications.PushBack( propertyNotification );
501 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
503 PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications;
504 PropertyNotificationIter iter = propertyNotifications.Begin();
506 while ( iter != propertyNotifications.End() )
508 if( *iter == propertyNotification )
510 propertyNotifications.Erase(iter);
517 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
519 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
520 propertyNotification->SetNotifyMode( notifyMode );
523 ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
525 return mImpl->renderers;
528 void UpdateManager::AddShader( Shader* shader )
530 DALI_ASSERT_DEBUG( NULL != shader );
532 if( mImpl->shaders.Count() == 0 )
534 // the first added shader becomes our default shader
535 // Construct message in the render queue memory; note that delete should not be called on the return value
536 typedef MessageValue1< RenderManager, Shader* > DerivedType;
538 // Reserve some memory inside the render queue
539 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
541 // Construct message in the render queue memory; note that delete should not be called on the return value
542 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader );
545 mImpl->shaders.PushBack( shader );
548 void UpdateManager::RemoveShader( Shader* shader )
550 DALI_ASSERT_DEBUG(shader != NULL);
552 ShaderContainer& shaders = mImpl->shaders;
554 // Find the shader and destroy it
555 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
557 Shader& current = **iter;
558 if ( ¤t == shader )
560 // Transfer ownership to the discard queue
561 // This keeps the shader alive, until the render-thread has finished with it
562 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) );
567 // Should not reach here
568 DALI_ASSERT_DEBUG(false);
571 void UpdateManager::SetShaderProgram( Shader* shader,
572 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
577 typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType;
579 // Reserve some memory inside the render queue
580 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
582 // Construct message in the render queue memory; note that delete should not be called on the return value
583 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
587 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
589 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
590 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
592 // lock as update might be sending previously compiled shaders to event thread
593 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
594 mImpl->renderCompiledShaders.push_back( shaderData );
598 RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
602 // copy the list, this is only likely to happen once in application life cycle
603 return &(mImpl->taskList);
607 // copy the list, this is only likely to happen once in application life cycle
608 return &(mImpl->systemLevelTaskList);
612 void UpdateManager::AddGesture( PanGesture* gesture )
614 DALI_ASSERT_DEBUG( NULL != gesture );
616 mImpl->gestures.PushBack( gesture );
619 void UpdateManager::RemoveGesture( PanGesture* gesture )
621 DALI_ASSERT_DEBUG( gesture != NULL );
623 GestureContainer& gestures = mImpl->gestures;
625 // Find the gesture and destroy it
626 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
628 PanGesture& current = **iter;
629 if ( ¤t == gesture )
631 mImpl->gestures.Erase( iter );
635 // Should not reach here
636 DALI_ASSERT_DEBUG(false);
639 void UpdateManager::AddTextureSet( TextureSet* textureSet )
641 DALI_ASSERT_DEBUG( NULL != textureSet );
642 mImpl->textureSets.PushBack( textureSet );
645 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
647 DALI_ASSERT_DEBUG(textureSet != NULL);
648 size_t textureSetCount( mImpl->textureSets.Size() );
649 for( size_t i(0); i<textureSetCount; ++i )
651 if( textureSet == mImpl->textureSets[i] )
653 mImpl->textureSets.Remove( mImpl->textureSets.Begin() + i );
659 unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
661 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
664 void UpdateManager::EventProcessingStarted()
666 mImpl->messageQueue.EventProcessingStarted();
669 bool UpdateManager::FlushQueue()
671 return mImpl->messageQueue.FlushQueue();
674 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
676 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
677 mImpl->animationFinishedDuringUpdate = false;
679 // Animated properties have to be reset to their original value each frame
681 // Reset root properties
684 mImpl->root->ResetToBaseValues( bufferIndex );
686 if ( mImpl->systemLevelRoot )
688 mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
691 // Reset all the nodes
692 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
693 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
694 for(;iter != endIter; ++iter)
696 (*iter)->ResetToBaseValues( bufferIndex );
699 // Reset system-level render-task list properties to base values
700 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
702 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter)
704 (*iter)->ResetToBaseValues( bufferIndex );
707 // Reset render-task list properties to base values.
708 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
710 for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter)
712 (*iter)->ResetToBaseValues( bufferIndex );
715 // Reset custom object properties to base values
716 for (OwnerContainer<PropertyOwner*>::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter)
718 (*iter)->ResetToBaseValues( bufferIndex );
721 mImpl->renderers.ResetToBaseValues( bufferIndex );
723 // Reset animatable shader properties to base values
724 for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter)
726 (*iter)->ResetToBaseValues( bufferIndex );
730 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
732 bool gestureUpdated( false );
734 // constrain gestures... (in construction order)
735 GestureContainer& gestures = mImpl->gestures;
737 for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter )
739 PanGesture& gesture = **iter;
740 gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
741 gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
744 return gestureUpdated;
747 void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
749 AnimationContainer &animations = mImpl->animations;
750 AnimationIter iter = animations.Begin();
751 bool animationLooped = false;
752 while ( iter != animations.End() )
754 Animation* animation = *iter;
755 bool finished = false;
757 animation->Update( bufferIndex, elapsedSeconds, looped, finished );
759 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
760 animationLooped = animationLooped || looped;
762 // Remove animations that had been destroyed but were still waiting for an update
763 if (animation->GetState() == Animation::Destroyed)
765 iter = animations.Erase(iter);
773 // queue the notification on finished or looped (to update loop count)
774 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
776 // The application should be notified by NotificationManager, in another thread
777 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
781 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
783 //Constrain custom objects (in construction order)
784 OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
785 const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End();
786 for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter )
788 PropertyOwner& object = **iter;
789 ConstrainPropertyOwner( object, bufferIndex );
793 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
795 // Constrain system-level render-tasks
796 const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
797 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
799 RenderTask& task = **iter;
800 ConstrainPropertyOwner( task, bufferIndex );
803 // Constrain render-tasks
804 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
805 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter )
807 RenderTask& task = **iter;
808 ConstrainPropertyOwner( task, bufferIndex );
812 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
814 // constrain shaders... (in construction order)
815 ShaderContainer& shaders = mImpl->shaders;
816 for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter )
818 Shader& shader = **iter;
819 ConstrainPropertyOwner( shader, bufferIndex );
823 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
825 PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications;
826 PropertyNotificationIter iter = notifications.Begin();
828 while ( iter != notifications.End() )
830 PropertyNotification* notification = *iter;
831 bool valid = notification->Check( bufferIndex );
834 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
840 void UpdateManager::PrepareTextureSets( BufferIndex bufferIndex )
842 size_t textureSetCount( mImpl->textureSets.Size() );
843 for( size_t i(0); i<textureSetCount; ++i )
845 //Prepare texture set
846 mImpl->textureSets[i]->Prepare( mImpl->resourceManager );
850 void UpdateManager::ForwardCompiledShadersToEventThread()
852 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
853 if( mImpl->shaderSaver )
855 // lock and swap the queues
857 // render might be attempting to send us more binaries at the same time
858 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
859 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
862 if( mImpl->updateCompiledShaders.size() > 0 )
864 ShaderSaver& factory = *mImpl->shaderSaver;
865 ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin();
866 ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end();
867 for( ; i != end; ++i )
869 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) );
871 // we don't need them in update anymore
872 mImpl->updateCompiledShaders.clear();
877 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
879 const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
880 unsigned int rendererCount( rendererContainer.Size() );
881 for( unsigned int i(0); i<rendererCount; ++i )
884 ConstrainPropertyOwner( *rendererContainer[i], bufferIndex );
886 rendererContainer[i]->PrepareRender( bufferIndex );
890 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
892 mImpl->nodeDirtyFlags = NothingFlag;
899 // Prepare resources, update shaders, for each node
900 // And add the renderers to the sorted layers. Start from root, which is also a layer
901 mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
903 mImpl->resourceManager,
904 mImpl->renderQueue );
906 if ( mImpl->systemLevelRoot )
908 mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
910 mImpl->resourceManager,
911 mImpl->renderQueue );
915 unsigned int UpdateManager::Update( float elapsedSeconds,
916 unsigned int lastVSyncTimeMilliseconds,
917 unsigned int nextVSyncTimeMilliseconds )
919 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
921 //Clear nodes/resources which were previously discarded
922 mImpl->discardQueue.Clear( bufferIndex );
924 //Grab any loaded resources
925 bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
927 //Process Touches & Gestures
928 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
930 const bool updateScene = // The scene-graph requires an update if..
931 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
932 IsAnimationRunning() || // ..at least one animation is running OR
933 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
934 resourceChanged || // ..one or more resources were updated/changed OR
935 gestureUpdated; // ..a gesture property was updated
938 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
939 // values if the scene was updated in the previous frame.
940 if( updateScene || mImpl->previousUpdateScene )
942 //Reset properties from the previous update
943 ResetProperties( bufferIndex );
944 mImpl->transformManager.ResetToBaseValue();
947 //Process the queued scene messages
948 mImpl->messageQueue.ProcessMessages( bufferIndex );
950 //Post Process Ids of resources updated by renderer
951 mImpl->resourceManager.PostProcessResources( bufferIndex );
953 //Forward compiled shader programs to event thread for saving
954 ForwardCompiledShadersToEventThread();
956 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
957 // renderer lists if the scene was updated in the previous frame.
958 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
959 if( updateScene || mImpl->previousUpdateScene )
962 Animate( bufferIndex, elapsedSeconds );
964 //Constraint custom objects
965 ConstrainCustomObjects( bufferIndex );
967 //Prepare texture sets and apply constraints to them
968 PrepareTextureSets( bufferIndex );
970 //Clear the lists of renderers from the previous update
971 for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
973 mImpl->sortedLayers[i]->ClearRenderables();
976 for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
978 mImpl->systemLevelSortedLayers[i]->ClearRenderables();
981 //Update node hierarchy, apply constraints and perform sorting / culling.
982 //This will populate each Layer with a list of renderers which are ready.
983 UpdateNodes( bufferIndex );
985 //Apply constraints to RenderTasks, shaders
986 ConstrainRenderTasks( bufferIndex );
987 ConstrainShaders( bufferIndex );
989 //Update renderers and apply constraints
990 UpdateRenderers( bufferIndex );
992 //Update the trnasformations of all the nodes
993 mImpl->transformManager.Update();
995 //Process Property Notifications
996 ProcessPropertyNotifications( bufferIndex );
998 //Update geometry batcher
999 mImpl->geometryBatcher.Update( bufferIndex );
1001 //Process the RenderTasks; this creates the instructions for rendering the next frame.
1002 //reset the update buffer index and make sure there is enough room in the instruction container
1003 mImpl->renderInstructions.ResetAndReserve( bufferIndex,
1004 mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
1006 if ( NULL != mImpl->root )
1008 mImpl->renderTaskProcessor.Process( bufferIndex,
1011 mImpl->sortedLayers,
1012 mImpl->geometryBatcher,
1013 mImpl->renderInstructions );
1015 // Process the system-level RenderTasks last
1016 if ( NULL != mImpl->systemLevelRoot )
1018 mImpl->renderTaskProcessor.Process( bufferIndex,
1019 mImpl->systemLevelTaskList,
1020 *mImpl->systemLevelRoot,
1021 mImpl->systemLevelSortedLayers,
1022 mImpl->geometryBatcher,
1023 mImpl->renderInstructions );
1028 // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks)
1029 bool doRenderOnceNotify = false;
1030 mImpl->renderTaskWaiting = false;
1031 const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
1032 for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End();
1033 endIter != iter; ++iter )
1035 RenderTask& renderTask(*(*iter));
1037 renderTask.UpdateState();
1039 if( renderTask.IsWaitingToRender() &&
1040 renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1042 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1045 if( renderTask.HasRendered() )
1047 doRenderOnceNotify = true;
1051 if( doRenderOnceNotify )
1053 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1054 mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
1057 // Macro is undefined in release build.
1058 SNAPSHOT_NODE_LOGGING;
1060 // A ResetProperties() may be required in the next frame
1061 mImpl->previousUpdateScene = updateScene;
1063 // Check whether further updates are required
1064 unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1066 // tell the update manager that we're done so the queue can be given to event thread
1067 mImpl->notificationManager.UpdateCompleted();
1069 // The update has finished; swap the double-buffering indices
1070 mSceneGraphBuffers.Swap();
1072 return keepUpdating;
1075 unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1077 // Update the duration set via Stage::KeepRendering()
1078 if ( mImpl->keepRenderingSeconds > 0.0f )
1080 mImpl->keepRenderingSeconds -= elapsedSeconds;
1083 unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1085 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1086 // Keep updating until no messages are received and no animations are running.
1087 // If an animation has just finished, update at least once more for Discard end-actions.
1088 // No need to check for renderQueue as there is always a render after update and if that
1089 // render needs another update it will tell the adaptor to call update again
1091 if ( mImpl->keepRenderingSeconds > 0.0f )
1093 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1096 if ( IsAnimationRunning() ||
1097 mImpl->animationFinishedDuringUpdate )
1099 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1102 if ( mImpl->renderTaskWaiting )
1104 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1107 return keepUpdatingRequest;
1110 void UpdateManager::SetBackgroundColor( const Vector4& color )
1112 typedef MessageValue1< RenderManager, Vector4 > DerivedType;
1114 // Reserve some memory inside the render queue
1115 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1117 // Construct message in the render queue memory; note that delete should not be called on the return value
1118 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
1121 void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
1123 typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
1125 // Reserve some memory inside the render queue
1126 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1128 // Construct message in the render queue memory; note that delete should not be called on the return value
1129 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1132 void UpdateManager::KeepRendering( float durationSeconds )
1134 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1137 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
1141 // just copy the vector of pointers
1142 mImpl->sortedLayers = layers;
1146 mImpl->systemLevelSortedLayers = layers;
1150 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
1152 mImpl->shaderSaver = &upstream;
1155 void UpdateManager::AddSampler( Render::Sampler* sampler )
1157 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1159 // Reserve some memory inside the render queue
1160 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1162 // Construct message in the render queue memory; note that delete should not be called on the return value
1163 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1166 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1168 typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
1170 // Reserve some memory inside the render queue
1171 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1173 // Construct message in the render queue memory; note that delete should not be called on the return value
1174 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1177 void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode )
1179 typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType;
1181 // Reserve some memory inside the render queue
1182 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1184 // Construct message in the render queue memory; note that delete should not be called on the return value
1185 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1188 void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
1190 typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > DerivedType;
1192 // Reserve some memory inside the render queue
1193 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1195 // Construct message in the render queue memory; note that delete should not be called on the return value
1196 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1199 void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1201 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1203 // Reserve some memory inside the render queue
1204 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1206 // Construct message in the render queue memory; note that delete should not be called on the return value
1207 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
1210 void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
1212 typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
1214 // Reserve some memory inside the render queue
1215 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1217 // Construct message in the render queue memory; note that delete should not be called on the return value
1218 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
1221 void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format )
1223 typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Render::PropertyBuffer::Format* > DerivedType;
1225 // Reserve some memory inside the render queue
1226 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1228 // Construct message in the render queue memory; note that delete should not be called on the return value
1229 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
1232 void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector<char>* data, size_t size )
1234 typedef MessageValue3< RenderManager, Render::PropertyBuffer*, Dali::Vector<char>*, size_t > DerivedType;
1236 // Reserve some memory inside the render queue
1237 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1239 // Construct message in the render queue memory; note that delete should not be called on the return value
1240 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
1243 void UpdateManager::AddGeometry( Render::Geometry* geometry )
1245 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1247 // Reserve some memory inside the render queue
1248 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1250 // Construct message in the render queue memory; note that delete should not be called on the return value
1251 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1254 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1256 typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
1258 // Reserve some memory inside the render queue
1259 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1261 // Construct message in the render queue memory; note that delete should not be called on the return value
1262 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1265 void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
1267 typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType;
1269 // Reserve some memory inside the render queue
1270 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1272 // Construct message in the render queue memory; note that delete should not be called on the return value
1273 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1276 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
1278 typedef IndexBufferMessage< RenderManager > DerivedType;
1280 // Reserve some memory inside the render queue
1281 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1283 // Construct message in the render queue memory; note that delete should not be called on the return value
1284 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1287 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1289 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1291 // Reserve some memory inside the render queue
1292 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1294 // Construct message in the render queue memory; note that delete should not be called on the return value
1295 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
1298 void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
1300 typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
1302 // Reserve some memory inside the render queue
1303 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1305 // Construct message in the render queue memory; note that delete should not be called on the return value
1306 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, geometry, propertyBuffer );
1309 void UpdateManager::AddTexture( Render::NewTexture* texture )
1311 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1313 // Reserve some memory inside the render queue
1314 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1316 // Construct message in the render queue memory; note that delete should not be called on the return value
1317 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1320 void UpdateManager::RemoveTexture( Render::NewTexture* texture)
1322 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1324 // Reserve some memory inside the render queue
1325 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1327 // Construct message in the render queue memory; note that delete should not be called on the return value
1328 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1331 void UpdateManager::UploadTexture( Render::NewTexture* texture, PixelDataPtr pixelData, const NewTexture::UploadParams& params )
1333 typedef MessageValue3< RenderManager, Render::NewTexture*, PixelDataPtr, NewTexture::UploadParams > DerivedType;
1335 // Reserve some memory inside the message queue
1336 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1338 // Construct message in the message queue memory; note that delete should not be called on the return value
1339 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1342 void UpdateManager::GenerateMipmaps( Render::NewTexture* texture )
1344 typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType;
1346 // Reserve some memory inside the render queue
1347 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1349 // Construct message in the render queue memory; note that delete should not be called on the return value
1350 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1353 void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
1355 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1357 // Reserve some memory inside the render queue
1358 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1360 // Construct message in the render queue memory; note that delete should not be called on the return value
1361 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1364 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1366 typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
1368 // Reserve some memory inside the render queue
1369 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1371 // Construct message in the render queue memory; note that delete should not be called on the return value
1372 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1375 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::NewTexture* texture, unsigned int mipmapLevel, unsigned int layer )
1377 typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::NewTexture*, unsigned int, unsigned int > DerivedType;
1379 // Reserve some memory inside the render queue
1380 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1382 // Construct message in the render queue memory; note that delete should not be called on the return value
1383 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1386 } // namespace SceneGraph
1388 } // namespace Internal