2 * Copyright (c) 2020 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/integration-api/core.h>
24 #include <dali/internal/event/common/notification-manager.h>
25 #include <dali/internal/event/common/property-notifier.h>
26 #include <dali/internal/event/effects/shader-factory.h>
27 #include <dali/internal/event/animation/animation-playlist.h>
29 #include <dali/internal/update/common/discard-queue.h>
30 #include <dali/internal/update/controllers/render-message-dispatcher.h>
31 #include <dali/internal/update/controllers/scene-controller-impl.h>
32 #include <dali/internal/update/manager/frame-callback-processor.h>
33 #include <dali/internal/update/manager/render-task-processor.h>
34 #include <dali/internal/update/manager/update-algorithms.h>
35 #include <dali/internal/update/manager/update-manager-debug.h>
36 #include <dali/internal/update/manager/transform-manager.h>
37 #include <dali/internal/update/nodes/node.h>
38 #include <dali/internal/update/queue/update-message-queue.h>
40 #include <dali/internal/render/common/render-manager.h>
41 #include <dali/internal/render/queue/render-queue.h>
43 // Un-comment to enable node tree debug logging
44 //#define NODE_TREE_LOGGING 1
46 #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) )
47 #define SNAPSHOT_NODE_LOGGING \
48 const uint32_t FRAME_COUNT_TRIGGER = 16;\
49 if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
51 for( auto&& scene : mImpl->scenes )
53 if ( scene && scene->root )\
55 mImpl->frameCounter = 0;\
56 PrintNodeTree( *scene->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
60 mImpl->frameCounter++;
62 #define SNAPSHOT_NODE_LOGGING
65 #if defined(DEBUG_ENABLED)
66 extern Debug::Filter* gRenderTaskLogFilter;
69 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_UPDATE_MANAGER" );
70 } // unnamed namespace
74 using namespace Dali::Integration;
75 using Dali::Internal::Update::MessageQueue;
89 * Helper to Erase an object from OwnerContainer using discard queue
90 * @param container to remove from
91 * @param object to remove
92 * @param discardQueue to put the object to
93 * @param updateBufferIndex to use
96 inline void EraseUsingDiscardQueue( OwnerContainer<T*>& container, T* object, DiscardQueue& discardQueue, BufferIndex updateBufferIndex )
98 DALI_ASSERT_DEBUG( object && "NULL object not allowed" );
100 // need to use the reference version of auto as we need the pointer to the pointer for the Release call below
101 for( auto&& iter : container )
103 if ( iter == object )
105 // Transfer ownership to the discard queue, this keeps the object alive, until the render-thread has finished with it
106 discardQueue.Add( updateBufferIndex, container.Release( &iter ) ); // take the address of the reference to a pointer (iter)
107 return; // return as we only ever remove one object. Iterators to container are now invalidated as well so cannot continue
113 * Descends into node's hierarchy and sorts the children of each child according to their depth-index.
114 * @param[in] node The node whose hierarchy to descend
116 void SortSiblingNodesRecursively( Node& node )
118 NodeContainer& container = node.GetChildren();
119 std::sort( container.Begin(), container.End(),
120 []( Node* a, Node* b ) { return a->GetDepthIndex() < b->GetDepthIndex(); } );
122 // Descend tree and sort as well
123 for( auto&& iter : container )
125 SortSiblingNodesRecursively( *iter );
129 } // unnamed namespace
132 * Structure to contain UpdateManager internal data
134 struct UpdateManager::Impl
136 // SceneInfo keeps the root node of the Scene, its scene graph render task list, and the list of Layer pointers sorted by depth
139 SceneInfo( Layer* root ) ///< Constructor
144 ~SceneInfo() = default; ///< Default non-virtual destructor
145 SceneInfo( SceneInfo&& rhs ) = default; ///< Move constructor
146 SceneInfo& operator=( SceneInfo&& rhs ) = default; ///< Move assignment operator
147 SceneInfo& operator=( const SceneInfo& rhs ) = delete; ///< Assignment operator
148 SceneInfo( const SceneInfo& rhs ) = delete; ///< Copy constructor
150 Layer* root{ nullptr }; ///< Root node (root is a layer). The layer is not stored in the node memory pool.
151 OwnerPointer< RenderTaskList > taskList; ///< Scene graph render task list
152 SortedLayerPointers sortedLayerList; ///< List of Layer pointers sorted by depth (one list of sorted layers per root)
153 OwnerPointer< Scene > scene; ///< Scene graph object of the scene
156 Impl( NotificationManager& notificationManager,
157 CompleteNotificationInterface& animationPlaylist,
158 PropertyNotifier& propertyNotifier,
159 DiscardQueue& discardQueue,
160 RenderController& renderController,
161 RenderManager& renderManager,
162 RenderQueue& renderQueue,
163 SceneGraphBuffers& sceneGraphBuffers,
164 RenderTaskProcessor& renderTaskProcessor )
165 : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
166 notificationManager( notificationManager ),
168 animationPlaylist( animationPlaylist ),
169 propertyNotifier( propertyNotifier ),
170 shaderSaver( nullptr ),
171 discardQueue( discardQueue ),
172 renderController( renderController ),
173 sceneController( nullptr ),
174 renderManager( renderManager ),
175 renderQueue( renderQueue ),
176 renderTaskProcessor( renderTaskProcessor ),
177 backgroundColor( Dali::DEFAULT_BACKGROUND_COLOR ),
181 panGestureProcessor( nullptr ),
182 messageQueue( renderController, sceneGraphBuffers ),
183 frameCallbackProcessor( nullptr ),
184 keepRenderingSeconds( 0.0f ),
185 nodeDirtyFlags( NodePropertyFlags::TRANSFORM ), // set to TransformFlag to ensure full update the first time through Update()
187 renderingBehavior( DevelStage::Rendering::IF_REQUIRED ),
188 animationFinishedDuringUpdate( false ),
189 previousUpdateScene( false ),
190 renderTaskWaiting( false ),
191 renderersAdded( false ),
192 surfaceRectChanged( false ),
193 renderingRequired( false )
195 sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
197 // create first 'dummy' node
198 nodes.PushBack(nullptr);
203 // Disconnect render tasks from nodes, before destroying the nodes
204 for( auto&& scene : scenes )
206 if ( scene && scene->taskList )
208 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
209 for ( auto&& task : tasks )
211 task->SetSourceNode( nullptr );
216 // UpdateManager owns the Nodes. Although Nodes are pool allocated they contain heap allocated parts
217 // like custom properties, which get released here
218 Vector<Node*>::Iterator iter = nodes.Begin()+1;
219 Vector<Node*>::Iterator endIter = nodes.End();
220 for(;iter!=endIter;++iter)
222 (*iter)->OnDestroy();
226 for( auto&& scene : scenes )
228 if ( scene && scene->root )
230 scene->root->OnDestroy();
231 Node::Delete( scene->root );
236 delete sceneController;
240 * Lazy init for FrameCallbackProcessor.
241 * @param[in] updateManager A reference to the update-manager
243 FrameCallbackProcessor& GetFrameCallbackProcessor( UpdateManager& updateManager )
245 if( ! frameCallbackProcessor )
247 frameCallbackProcessor = new FrameCallbackProcessor( updateManager, transformManager );
249 return *frameCallbackProcessor;
252 SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
253 RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
254 NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
255 TransformManager transformManager; ///< Used to update the transformation matrices of the nodes
256 CompleteNotificationInterface& animationPlaylist; ///< Holds handles to all the animations
257 PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified.
258 ShaderSaver* shaderSaver; ///< Saves shader binaries.
259 DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph.
260 RenderController& renderController; ///< render controller
261 SceneControllerImpl* sceneController; ///< scene controller
262 RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
263 RenderQueue& renderQueue; ///< Used to queue messages for the next render
264 RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
266 Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
268 using SceneInfoPtr = std::unique_ptr< SceneInfo >;
269 std::vector< SceneInfoPtr > scenes; ///< A container of SceneInfo.
271 Vector<Node*> nodes; ///< A container of all instantiated nodes
273 OwnerContainer< Camera* > cameras; ///< A container of cameras
274 OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
276 OwnerContainer< PropertyResetterBase* > propertyResetters; ///< A container of property resetters
277 OwnerContainer< Animation* > animations; ///< A container of owned animations
278 PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
279 OwnerContainer< Renderer* > renderers; ///< A container of owned renderers
280 OwnerContainer< TextureSet* > textureSets; ///< A container of owned texture sets
281 OwnerContainer< Shader* > shaders; ///< A container of owned shaders
282 OwnerPointer< PanGesture > panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager
284 MessageQueue messageQueue; ///< The messages queued from the event-thread
285 std::vector<Internal::ShaderDataPtr> renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
286 std::vector<Internal::ShaderDataPtr> updateCompiledShaders; ///< Shaders to be sent from Update to Event
287 Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
289 OwnerPointer<FrameCallbackProcessor> frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required.
291 float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
292 NodePropertyFlags nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
293 uint32_t frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
295 DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior
297 bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
298 bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
299 bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
300 bool renderersAdded; ///< Flag to keep track when renderers have been added to avoid unnecessary processing
301 bool surfaceRectChanged; ///< True if the default surface rect is changed
302 bool renderingRequired; ///< True if required to render the current frame
306 Impl( const Impl& ); ///< Undefined
307 Impl& operator=( const Impl& ); ///< Undefined
310 UpdateManager::UpdateManager( NotificationManager& notificationManager,
311 CompleteNotificationInterface& animationFinishedNotifier,
312 PropertyNotifier& propertyNotifier,
313 DiscardQueue& discardQueue,
314 RenderController& controller,
315 RenderManager& renderManager,
316 RenderQueue& renderQueue,
317 RenderTaskProcessor& renderTaskProcessor )
320 mImpl = new Impl( notificationManager,
321 animationFinishedNotifier,
328 renderTaskProcessor );
332 UpdateManager::~UpdateManager()
337 void UpdateManager::InstallRoot( OwnerPointer<Layer>& layer )
339 DALI_ASSERT_DEBUG( layer->IsLayer() );
340 DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
342 Layer* rootLayer = layer.Release();
344 DALI_ASSERT_DEBUG( std::find_if( mImpl->scenes.begin(), mImpl->scenes.end(),
345 [rootLayer]( Impl::SceneInfoPtr& scene )
347 return scene && scene->root == rootLayer;
349 ) == mImpl->scenes.end() && "Root Node already installed" );
351 rootLayer->CreateTransform( &mImpl->transformManager );
352 rootLayer->SetRoot(true);
354 mImpl->scenes.emplace_back( new Impl::SceneInfo( rootLayer ) );
357 void UpdateManager::UninstallRoot( Layer* layer )
359 DALI_ASSERT_DEBUG( layer->IsLayer() );
360 DALI_ASSERT_DEBUG( layer->GetParent() == NULL );
362 for (auto iter = mImpl->scenes.begin(); iter != mImpl->scenes.end(); ++iter)
364 if( (*iter) && (*iter)->root == layer )
366 mImpl->scenes.erase( iter );
371 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), layer );
373 // Notify the layer about impending destruction
377 void UpdateManager::AddNode( OwnerPointer<Node>& node )
379 DALI_ASSERT_ALWAYS( nullptr == node->GetParent() ); // Should not have a parent yet
381 Node* rawNode = node.Release();
382 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddNode\n", rawNode );
384 mImpl->nodes.PushBack(rawNode);
385 rawNode->CreateTransform(&mImpl->transformManager);
388 void UpdateManager::ConnectNode( Node* parent, Node* node )
390 DALI_ASSERT_ALWAYS( nullptr != parent );
391 DALI_ASSERT_ALWAYS( nullptr != node );
392 DALI_ASSERT_ALWAYS( nullptr == node->GetParent() ); // Should not have a parent yet
394 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] ConnectNode\n", node );
396 parent->ConnectChild( node );
398 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
399 if( mImpl->frameCallbackProcessor )
401 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
405 void UpdateManager::DisconnectNode( Node* node )
407 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DisconnectNode\n", node );
409 Node* parent = node->GetParent();
410 DALI_ASSERT_ALWAYS( nullptr != parent );
411 parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused
413 parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
415 // Inform the frame-callback-processor, if set, about the node-hierarchy changing
416 if( mImpl->frameCallbackProcessor )
418 mImpl->frameCallbackProcessor->NodeHierarchyChanged();
422 void UpdateManager::DestroyNode( Node* node )
424 DALI_ASSERT_ALWAYS( nullptr != node );
425 DALI_ASSERT_ALWAYS( nullptr == node->GetParent() ); // Should have been disconnected
427 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DestroyNode\n", node );
429 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
430 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
431 for(;iter!=endIter;++iter)
435 mImpl->nodes.Erase(iter);
440 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
442 // Notify the Node about impending destruction
446 void UpdateManager::AddCamera( OwnerPointer< Camera >& camera )
448 mImpl->cameras.PushBack( camera.Release() ); // takes ownership
451 void UpdateManager::RemoveCamera( Camera* camera )
453 // Find the camera and destroy it
454 EraseUsingDiscardQueue( mImpl->cameras, camera, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
457 void UpdateManager::AddObject( OwnerPointer<PropertyOwner>& object )
459 mImpl->customObjects.PushBack( object.Release() );
462 void UpdateManager::RemoveObject( PropertyOwner* object )
464 mImpl->customObjects.EraseObject( object );
467 void UpdateManager::AddRenderTaskList( OwnerPointer<RenderTaskList>& taskList )
469 RenderTaskList* taskListPointer = taskList.Release();
470 taskListPointer->SetRenderMessageDispatcher( &mImpl->renderMessageDispatcher );
472 mImpl->scenes.back()->taskList = taskListPointer;
475 void UpdateManager::RemoveRenderTaskList( RenderTaskList* taskList )
477 for ( auto&& scene : mImpl->scenes )
479 if ( scene && scene->taskList == taskList )
481 scene->taskList.Reset();
487 void UpdateManager::AddScene( OwnerPointer< Scene >& scene )
489 mImpl->scenes.back()->scene = scene.Release();
491 // Initialize the context from render manager
492 typedef MessageValue1< RenderManager, SceneGraph::Scene* > DerivedType;
494 // Reserve some memory inside the render queue
495 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
497 // Construct message in the render queue memory; note that delete should not be called on the return value
498 SceneGraph::Scene& sceneObject = *mImpl->scenes.back()->scene;
499 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::InitializeScene, &sceneObject );
502 void UpdateManager::RemoveScene( Scene* scene )
504 // Initialize the context from render manager
505 using DerivedType = MessageValue1<RenderManager, SceneGraph::Scene*>;
507 // Reserve some memory inside the render queue
508 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
510 // Construct message in the render queue memory; note that delete should not be called on the return value
511 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UninitializeScene, scene );
513 for ( auto&& sceneInfo : mImpl->scenes )
515 if ( sceneInfo && sceneInfo->scene && sceneInfo->scene.Get() == scene )
517 mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), sceneInfo->scene.Release() ); // take the address of the reference to a pointer
523 void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation )
525 mImpl->animations.PushBack( animation.Release() );
528 void UpdateManager::StopAnimation( Animation* animation )
530 DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
532 bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
534 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
537 void UpdateManager::RemoveAnimation( Animation* animation )
539 DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
541 animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
543 DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
546 bool UpdateManager::IsAnimationRunning() const
548 // Find any animation that isn't stopped or paused
549 for ( auto&& iter : mImpl->animations )
551 const Animation::State state = iter->GetState();
553 if (state != Animation::Stopped &&
554 state != Animation::Paused)
556 return true; // stop iteration as soon as first one is found
563 void UpdateManager::AddPropertyResetter( OwnerPointer<PropertyResetterBase>& propertyResetter )
565 propertyResetter->Initialize();
566 mImpl->propertyResetters.PushBack( propertyResetter.Release() );
569 void UpdateManager::AddPropertyNotification( OwnerPointer< PropertyNotification >& propertyNotification )
571 mImpl->propertyNotifications.PushBack( propertyNotification.Release() );
574 void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
576 mImpl->propertyNotifications.EraseObject( propertyNotification );
579 void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
581 DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
582 propertyNotification->SetNotifyMode( notifyMode );
585 void UpdateManager::AddShader( OwnerPointer< Shader >& shader )
587 mImpl->shaders.PushBack( shader.Release() );
590 void UpdateManager::RemoveShader( Shader* shader )
592 // Find the shader and destroy it
593 EraseUsingDiscardQueue( mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
596 void UpdateManager::SetShaderProgram( Shader* shader,
597 Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
601 using DerivedType = MessageValue3<Shader, Internal::ShaderDataPtr, ProgramCache*, bool>;
603 // Reserve some memory inside the render queue
604 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
606 // Construct message in the render queue memory; note that delete should not be called on the return value
607 new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry );
611 void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
613 DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
614 DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
616 // lock as update might be sending previously compiled shaders to event thread
617 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
618 mImpl->renderCompiledShaders.push_back( shaderData );
622 void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
624 mImpl->shaderSaver = &upstream;
627 void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer )
629 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer.Get() );
631 renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
632 mImpl->renderers.PushBack( renderer.Release() );
633 mImpl->renderersAdded = true;
636 void UpdateManager::RemoveRenderer( Renderer* renderer )
638 DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] RemoveRenderer\n", renderer );
640 // Find the renderer and destroy it
641 EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
642 // Need to remove the render object as well
643 renderer->DisconnectFromSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
646 void UpdateManager::SetPanGestureProcessor( PanGesture* panGestureProcessor )
648 DALI_ASSERT_DEBUG( NULL != panGestureProcessor );
650 mImpl->panGestureProcessor = panGestureProcessor;
653 void UpdateManager::AddTextureSet( OwnerPointer< TextureSet >& textureSet )
655 mImpl->textureSets.PushBack( textureSet.Release() );
658 void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
660 mImpl->textureSets.EraseObject( textureSet );
663 uint32_t* UpdateManager::ReserveMessageSlot( uint32_t size, bool updateScene )
665 return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
668 void UpdateManager::EventProcessingStarted()
670 mImpl->messageQueue.EventProcessingStarted();
673 bool UpdateManager::FlushQueue()
675 return mImpl->messageQueue.FlushQueue();
678 void UpdateManager::ResetProperties( BufferIndex bufferIndex )
680 // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
681 mImpl->animationFinishedDuringUpdate = false;
683 // Reset all animating / constrained properties
684 std::vector<PropertyResetterBase*>toDelete;
685 for( auto&& element : mImpl->propertyResetters )
687 element->ResetToBaseValue( bufferIndex );
688 if( element->IsFinished() )
690 toDelete.push_back( element );
694 // If a resetter is no longer required (the animator or constraint has been removed), delete it.
695 for( auto&& elementPtr : toDelete )
697 mImpl->propertyResetters.EraseObject( elementPtr );
700 // Clear all root nodes dirty flags
701 for( auto& scene : mImpl->scenes )
703 auto root = scene->root;
704 root->ResetDirtyFlags( bufferIndex );
707 // Clear node dirty flags
708 Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
709 Vector<Node*>::Iterator endIter = mImpl->nodes.End();
710 for( ;iter != endIter; ++iter )
712 (*iter)->ResetDirtyFlags( bufferIndex );
716 bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds )
718 bool gestureUpdated( false );
720 if( mImpl->panGestureProcessor )
722 // gesture processor only supports default properties
723 mImpl->panGestureProcessor->ResetDefaultProperties( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message
724 gestureUpdated |= mImpl->panGestureProcessor->UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
727 return gestureUpdated;
730 bool UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
732 bool animationActive = false;
734 auto&& iter = mImpl->animations.Begin();
735 bool animationLooped = false;
737 while ( iter != mImpl->animations.End() )
739 Animation* animation = *iter;
740 bool finished = false;
742 bool progressMarkerReached = false;
743 animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
745 animationActive = animationActive || animation->IsActive();
747 if ( progressMarkerReached )
749 mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
752 mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
753 animationLooped = animationLooped || looped;
755 // Remove animations that had been destroyed but were still waiting for an update
756 if (animation->GetState() == Animation::Destroyed)
758 iter = mImpl->animations.Erase(iter);
766 // queue the notification on finished or looped (to update loop count)
767 if ( mImpl->animationFinishedDuringUpdate || animationLooped )
769 // The application should be notified by NotificationManager, in another thread
770 mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
773 return animationActive;
776 void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
778 //Constrain custom objects (in construction order)
779 for ( auto&& object : mImpl->customObjects )
781 ConstrainPropertyOwner( *object, bufferIndex );
785 void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
787 // Constrain render-tasks
788 for ( auto&& scene : mImpl->scenes )
790 if ( scene && scene->taskList )
792 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
793 for ( auto&& task : tasks )
795 ConstrainPropertyOwner( *task, bufferIndex );
801 void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
803 // constrain shaders... (in construction order)
804 for ( auto&& shader : mImpl->shaders )
806 ConstrainPropertyOwner( *shader, bufferIndex );
810 void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
812 for( auto&& notification : mImpl->propertyNotifications )
814 bool valid = notification->Check( bufferIndex );
817 mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
822 void UpdateManager::ForwardCompiledShadersToEventThread()
824 DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
825 if( mImpl->shaderSaver )
827 // lock and swap the queues
829 // render might be attempting to send us more binaries at the same time
830 Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
831 mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
834 if( mImpl->updateCompiledShaders.size() > 0 )
836 ShaderSaver& factory = *mImpl->shaderSaver;
837 for( auto&& shader : mImpl->updateCompiledShaders )
839 mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, shader ) );
841 // we don't need them in update anymore
842 mImpl->updateCompiledShaders.clear();
847 void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
849 for( auto&& renderer : mImpl->renderers )
852 ConstrainPropertyOwner( *renderer, bufferIndex );
854 mImpl->renderingRequired = renderer->PrepareRender( bufferIndex ) || mImpl->renderingRequired;
858 void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
860 mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
862 for ( auto&& scene : mImpl->scenes )
864 if ( scene && scene->root )
866 // Prepare resources, update shaders, for each node
867 // And add the renderers to the sorted layers. Start from root, which is also a layer
868 mImpl->nodeDirtyFlags |= UpdateNodeTree( *scene->root,
870 mImpl->renderQueue );
875 uint32_t UpdateManager::Update( float elapsedSeconds,
876 uint32_t lastVSyncTimeMilliseconds,
877 uint32_t nextVSyncTimeMilliseconds,
878 bool renderToFboEnabled,
879 bool isRenderingToFbo )
881 const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
883 //Clear nodes/resources which were previously discarded
884 mImpl->discardQueue.Clear( bufferIndex );
886 bool isAnimationRunning = IsAnimationRunning();
888 //Process Touches & Gestures
889 const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
891 bool updateScene = // The scene-graph requires an update if..
892 (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR
893 isAnimationRunning || // ..at least one animation is running OR
894 mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR
895 mImpl->frameCallbackProcessor || // ..a frame callback processor is existed OR
896 gestureUpdated; // ..a gesture property was updated
898 bool keepRendererRendering = false;
899 mImpl->renderingRequired = false;
901 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
902 // values if the scene was updated in the previous frame.
903 if( updateScene || mImpl->previousUpdateScene )
905 //Reset properties from the previous update
906 ResetProperties( bufferIndex );
907 mImpl->transformManager.ResetToBaseValue();
910 // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called
911 // between calling IsSceneUpdateRequired() above and here, so updateScene should
913 updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex );
915 //Forward compiled shader programs to event thread for saving
916 ForwardCompiledShadersToEventThread();
918 // Although the scene-graph may not require an update, we still need to synchronize double-buffered
919 // renderer lists if the scene was updated in the previous frame.
920 // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
921 if( updateScene || mImpl->previousUpdateScene )
924 bool animationActive = Animate( bufferIndex, elapsedSeconds );
926 //Constraint custom objects
927 ConstrainCustomObjects( bufferIndex );
929 //Clear the lists of renderers from the previous update
930 for( auto&& scene : mImpl->scenes )
934 for( auto&& layer : scene->sortedLayerList )
938 layer->ClearRenderables();
944 // Call the frame-callback-processor if set
945 if( mImpl->frameCallbackProcessor )
947 mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
950 //Update node hierarchy, apply constraints and perform sorting / culling.
951 //This will populate each Layer with a list of renderers which are ready.
952 UpdateNodes( bufferIndex );
954 //Apply constraints to RenderTasks, shaders
955 ConstrainRenderTasks( bufferIndex );
956 ConstrainShaders( bufferIndex );
958 //Update renderers and apply constraints
959 UpdateRenderers( bufferIndex );
961 //Update the transformations of all the nodes
962 if ( mImpl->transformManager.Update() )
964 mImpl->nodeDirtyFlags |= NodePropertyFlags::TRANSFORM;
967 //Process Property Notifications
968 ProcessPropertyNotifications( bufferIndex );
971 for( auto&& cameraIterator : mImpl->cameras )
973 cameraIterator->Update( bufferIndex );
976 //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame.
977 //reset the update buffer index and make sure there is enough room in the instruction container
978 if( mImpl->renderersAdded )
980 // Calculate how many render tasks we have in total
981 std::size_t numberOfRenderTasks = 0;
982 for (auto&& scene : mImpl->scenes )
984 if ( scene && scene->taskList )
986 numberOfRenderTasks += scene->taskList->GetTasks().Count();
990 std::size_t numberOfRenderInstructions = 0;
991 for ( auto&& scene : mImpl->scenes )
993 if ( scene && scene->root && scene->taskList && scene->scene )
995 scene->scene->GetRenderInstructions().ResetAndReserve( bufferIndex,
996 static_cast<uint32_t>( scene->taskList->GetTasks().Count() ) );
998 // If there are animations running, only add render instruction if at least one animation is currently active (i.e. not delayed)
999 // or the nodes are dirty
1000 if ( !isAnimationRunning || animationActive || mImpl->renderingRequired || (mImpl->nodeDirtyFlags & RenderableUpdateFlags) )
1002 keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
1005 scene->sortedLayerList,
1006 scene->scene->GetRenderInstructions(),
1010 scene->scene->SetSkipRendering( false );
1014 scene->scene->SetSkipRendering( true );
1017 numberOfRenderInstructions += scene->scene->GetRenderInstructions().Count( bufferIndex );
1021 DALI_LOG_INFO( gLogFilter, Debug::General,
1022 "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n",
1023 numberOfRenderTasks, numberOfRenderInstructions );
1027 for ( auto&& scene : mImpl->scenes )
1029 if ( scene && scene->root && scene->taskList )
1031 RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
1033 // check the countdown and notify
1034 bool doRenderOnceNotify = false;
1035 mImpl->renderTaskWaiting = false;
1036 for ( auto&& renderTask : tasks )
1038 renderTask->UpdateState();
1040 if( renderTask->IsWaitingToRender() &&
1041 renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
1043 mImpl->renderTaskWaiting = true; // keep update/render threads alive
1046 if( renderTask->HasRendered() )
1048 doRenderOnceNotify = true;
1052 if( doRenderOnceNotify )
1054 DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
1055 mImpl->notificationManager.QueueCompleteNotification( scene->taskList->GetCompleteNotificationInterface() );
1060 // Macro is undefined in release build.
1061 SNAPSHOT_NODE_LOGGING;
1063 // A ResetProperties() may be required in the next frame
1064 mImpl->previousUpdateScene = updateScene;
1066 // Check whether further updates are required
1067 uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds );
1069 if( keepRendererRendering )
1071 keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
1073 // Set dirty flags for next frame to continue rendering
1074 mImpl->nodeDirtyFlags |= RenderableUpdateFlags;
1077 // tell the update manager that we're done so the queue can be given to event thread
1078 mImpl->notificationManager.UpdateCompleted();
1080 // The update has finished; swap the double-buffering indices
1081 mSceneGraphBuffers.Swap();
1083 return keepUpdating;
1086 uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
1088 // Update the duration set via Stage::KeepRendering()
1089 if ( mImpl->keepRenderingSeconds > 0.0f )
1091 mImpl->keepRenderingSeconds -= elapsedSeconds;
1094 uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
1096 // If the rendering behavior is set to continuously render, then continue to render.
1097 // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
1098 // Keep updating until no messages are received and no animations are running.
1099 // If an animation has just finished, update at least once more for Discard end-actions.
1100 // No need to check for renderQueue as there is always a render after update and if that
1101 // render needs another update it will tell the adaptor to call update again
1103 if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
1104 ( mImpl->keepRenderingSeconds > 0.0f ) )
1106 keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
1109 if ( IsAnimationRunning() ||
1110 mImpl->animationFinishedDuringUpdate )
1112 keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
1115 if ( mImpl->renderTaskWaiting )
1117 keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
1120 return keepUpdatingRequest;
1123 void UpdateManager::SetDefaultSurfaceRect( const Rect<int32_t>& rect )
1125 mImpl->surfaceRectChanged = true;
1127 using DerivedType = MessageValue1<RenderManager, Rect<int32_t> >;
1129 // Reserve some memory inside the render queue
1130 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1132 // Construct message in the render queue memory; note that delete should not be called on the return value
1133 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect );
1136 void UpdateManager::SurfaceReplaced( Scene* scene )
1138 using DerivedType = MessageValue1<RenderManager, Scene*>;
1140 // Reserve some memory inside the render queue
1141 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1143 // Construct message in the render queue memory; note that delete should not be called on the return value
1144 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SurfaceReplaced, scene );
1147 void UpdateManager::SetDefaultSurfaceOrientation(int orientation)
1149 using DerivedType = MessageValue1<RenderManager, int>;
1151 // Reserve some memory inside the render queue
1152 unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
1154 // Construct message in the render queue memory; note that delete should not be called on the return value
1155 new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetDefaultSurfaceOrientation, orientation);
1158 void UpdateManager::KeepRendering( float durationSeconds )
1160 mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
1163 void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
1165 mImpl->renderingBehavior = renderingBehavior;
1168 void UpdateManager::RequestRendering()
1170 mImpl->renderingRequired = true;
1173 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
1175 for ( auto&& scene : mImpl->scenes )
1177 if ( scene && scene->root == rootLayer )
1179 scene->sortedLayerList = layers;
1185 void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
1187 // note,this vector is already in depth order. It could be used as-is to
1188 // remove sorting in update algorithm. However, it lacks layer boundary markers.
1189 for( auto&& iter : nodeDepths->nodeDepths )
1191 iter.node->SetDepthIndex( iter.sortedDepth );
1194 for ( auto&& scene : mImpl->scenes )
1198 // Go through node hierarchy and rearrange siblings according to depth-index
1199 SortSiblingNodesRecursively( *scene->root );
1204 bool UpdateManager::IsDefaultSurfaceRectChanged()
1206 bool surfaceRectChanged = mImpl->surfaceRectChanged;
1209 mImpl->surfaceRectChanged = false;
1211 return surfaceRectChanged;
1214 void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode )
1216 mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode );
1219 void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
1221 mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback );
1224 void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
1226 // Message has ownership of Sampler while in transit from update to render
1227 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Sampler> >;
1229 // Reserve some memory inside the render queue
1230 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1232 // Construct message in the render queue memory; note that delete should not be called on the return value
1233 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler );
1236 void UpdateManager::RemoveSampler( Render::Sampler* sampler )
1238 using DerivedType = MessageValue1<RenderManager, Render::Sampler*>;
1240 // Reserve some memory inside the render queue
1241 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1243 // Construct message in the render queue memory; note that delete should not be called on the return value
1244 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler );
1247 void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode )
1249 using DerivedType = MessageValue3<RenderManager, Render::Sampler*, uint32_t, uint32_t>;
1251 // Reserve some memory inside the render queue
1252 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1254 // Construct message in the render queue memory; note that delete should not be called on the return value
1255 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode );
1258 void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
1260 using DerivedType = MessageValue4<RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t>;
1262 // Reserve some memory inside the render queue
1263 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1265 // Construct message in the render queue memory; note that delete should not be called on the return value
1266 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
1269 void UpdateManager::AddVertexBuffer( OwnerPointer< Render::VertexBuffer >& vertexBuffer )
1271 // Message has ownership of format while in transit from update -> render
1272 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::VertexBuffer> >;
1274 // Reserve some memory inside the render queue
1275 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1277 // Construct message in the render queue memory; note that delete should not be called on the return value
1278 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, vertexBuffer );
1281 void UpdateManager::RemoveVertexBuffer( Render::VertexBuffer* vertexBuffer )
1283 using DerivedType = MessageValue1<RenderManager, Render::VertexBuffer*>;
1285 // Reserve some memory inside the render queue
1286 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1288 // Construct message in the render queue memory; note that delete should not be called on the return value
1289 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, vertexBuffer );
1292 void UpdateManager::SetVertexBufferFormat( Render::VertexBuffer* vertexBuffer, OwnerPointer< Render::VertexBuffer::Format>& format )
1294 // Message has ownership of format while in transit from update -> render
1295 using DerivedType = MessageValue2<RenderManager, Render::VertexBuffer*, OwnerPointer<Render::VertexBuffer::Format> >;
1297 // Reserve some memory inside the render queue
1298 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1300 // Construct message in the render queue memory; note that delete should not be called on the return value
1301 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetVertexBufferFormat, vertexBuffer, format );
1304 void UpdateManager::SetVertexBufferData( Render::VertexBuffer* vertexBuffer, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
1306 // Message has ownership of format while in transit from update -> render
1307 using DerivedType = MessageValue3<RenderManager, Render::VertexBuffer*, OwnerPointer<Dali::Vector<uint8_t> >, uint32_t>;
1309 // Reserve some memory inside the render queue
1310 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1312 // Construct message in the render queue memory; note that delete should not be called on the return value
1313 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetVertexBufferData, vertexBuffer, data, size );
1316 void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
1318 // Message has ownership of format while in transit from update -> render
1319 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Geometry> >;
1321 // Reserve some memory inside the render queue
1322 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1324 // Construct message in the render queue memory; note that delete should not be called on the return value
1325 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
1328 void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
1330 using DerivedType = MessageValue1<RenderManager, Render::Geometry*>;
1332 // Reserve some memory inside the render queue
1333 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1335 // Construct message in the render queue memory; note that delete should not be called on the return value
1336 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
1339 void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
1341 using DerivedType = MessageValue2<RenderManager, Render::Geometry*, uint32_t>;
1343 // Reserve some memory inside the render queue
1344 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1346 // Construct message in the render queue memory; note that delete should not be called on the return value
1347 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
1350 void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
1352 using DerivedType = IndexBufferMessage<RenderManager>;
1354 // Reserve some memory inside the render queue
1355 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1357 // Construct message in the render queue memory; note that delete should not be called on the return value
1358 new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
1361 void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
1363 using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1365 // Reserve some memory inside the render queue
1366 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1368 // Construct message in the render queue memory; note that delete should not be called on the return value
1369 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, vertexBuffer );
1372 void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer )
1374 using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
1376 // Reserve some memory inside the render queue
1377 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1379 // Construct message in the render queue memory; note that delete should not be called on the return value
1380 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, vertexBuffer );
1383 void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
1385 // Message has ownership of Texture while in transit from update -> render
1386 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Texture> >;
1388 // Reserve some memory inside the render queue
1389 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1391 // Construct message in the render queue memory; note that delete should not be called on the return value
1392 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
1395 void UpdateManager::RemoveTexture( Render::Texture* texture)
1397 using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
1399 // Reserve some memory inside the render queue
1400 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1402 // Construct message in the render queue memory; note that delete should not be called on the return value
1403 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
1406 void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
1408 using DerivedType = MessageValue3<RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams>;
1410 // Reserve some memory inside the message queue
1411 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1413 // Construct message in the message queue memory; note that delete should not be called on the return value
1414 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
1417 void UpdateManager::GenerateMipmaps( Render::Texture* texture )
1419 using DerivedType = MessageValue1<RenderManager, Render::Texture*>;
1421 // Reserve some memory inside the render queue
1422 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1424 // Construct message in the render queue memory; note that delete should not be called on the return value
1425 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
1428 void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
1430 using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::FrameBuffer> >;
1432 // Reserve some memory inside the render queue
1433 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1435 // Construct message in the render queue memory; note that delete should not be called on the return value
1436 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
1439 void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
1441 using DerivedType = MessageValue1<RenderManager, Render::FrameBuffer*>;
1443 // Reserve some memory inside the render queue
1444 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1446 // Construct message in the render queue memory; note that delete should not be called on the return value
1447 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
1450 void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
1452 using DerivedType = MessageValue4<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t>;
1454 // Reserve some memory inside the render queue
1455 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1457 // Construct message in the render queue memory; note that delete should not be called on the return value
1458 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
1461 void UpdateManager::AttachDepthTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1463 using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1465 // Reserve some memory inside the render queue
1466 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1468 // Construct message in the render queue memory; note that delete should not be called on the return value
1469 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachDepthTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1472 void UpdateManager::AttachDepthStencilTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel )
1474 using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
1476 // Reserve some memory inside the render queue
1477 uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
1479 // Construct message in the render queue memory; note that delete should not be called on the return value
1480 new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachDepthStencilTextureToFrameBuffer, frameBuffer, texture, mipmapLevel );
1483 } // namespace SceneGraph
1485 } // namespace Internal