X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Fmanager%2Fupdate-manager.cpp;h=ce42bd75741cdf4ea21e832c014c5faff08ec0a9;hb=79881246746f65474b24ea4fe14151ccef8df3f4;hp=4485b89f7b92494c37f92b91c6c08b5f92defbbc;hpb=8e11ca6446b03f89bcc59bd1d023e71944b06bf9;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index 4485b89..ce42bd7 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ // INTERNAL INCLUDES #include -#include #include #include @@ -36,18 +35,19 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include -#include +#include #include #include +#include #include #include #include @@ -56,15 +56,11 @@ #include #include #include -#include -#include -#include #include #include #include #include -#include #include // Un-comment to enable node tree debug logging @@ -72,13 +68,16 @@ #if ( defined( DEBUG_ENABLED ) && defined( NODE_TREE_LOGGING ) ) #define SNAPSHOT_NODE_LOGGING \ -const int FRAME_COUNT_TRIGGER = 16;\ +const uint32_t FRAME_COUNT_TRIGGER = 16;\ if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\ {\ - if ( NULL != mImpl->root )\ + for( auto&& scene : mImpl->scenes ) {\ - mImpl->frameCounter = 0;\ - PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\ + if ( scene && scene->root )\ + {\ + mImpl->frameCounter = 0;\ + PrintNodeTree( *scene->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\ + }\ }\ }\ mImpl->frameCounter++; @@ -88,6 +87,10 @@ mImpl->frameCounter++; #if defined(DEBUG_ENABLED) extern Debug::Filter* gRenderTaskLogFilter; +namespace +{ +Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_UPDATE_MANAGER" ); +} // unnamed namespace #endif @@ -103,72 +106,116 @@ namespace Internal namespace SceneGraph { -typedef OwnerContainer< Shader* > ShaderContainer; -typedef ShaderContainer::Iterator ShaderIter; -typedef ShaderContainer::ConstIterator ShaderConstIter; +namespace +{ +/** + * Helper to Erase an object from OwnerContainer using discard queue + * @param container to remove from + * @param object to remove + * @param discardQueue to put the object to + * @param updateBufferIndex to use + */ +template < class T > +inline void EraseUsingDiscardQueue( OwnerContainer& container, T* object, DiscardQueue& discardQueue, BufferIndex updateBufferIndex ) +{ + DALI_ASSERT_DEBUG( object && "NULL object not allowed" ); + + // need to use the reference version of auto as we need the pointer to the pointer for the Release call below + for( auto&& iter : container ) + { + if ( iter == object ) + { + // Transfer ownership to the discard queue, this keeps the object alive, until the render-thread has finished with it + discardQueue.Add( updateBufferIndex, container.Release( &iter ) ); // take the address of the reference to a pointer (iter) + return; // return as we only ever remove one object. Iterators to container are now invalidated as well so cannot continue + } + } +} -typedef std::vector ShaderDataBinaryQueue; +/** + * Descends into node's hierarchy and sorts the children of each child according to their depth-index. + * @param[in] node The node whose hierarchy to descend + */ +void SortSiblingNodesRecursively( Node& node ) +{ + NodeContainer& container = node.GetChildren(); + std::sort( container.Begin(), container.End(), + []( Node* a, Node* b ) { return a->GetDepthIndex() < b->GetDepthIndex(); } ); -typedef OwnerContainer GestureContainer; -typedef GestureContainer::Iterator GestureIter; -typedef GestureContainer::ConstIterator GestureConstIter; + // Descend tree and sort as well + for( auto&& iter : container ) + { + SortSiblingNodesRecursively( *iter ); + } +} -typedef OwnerContainer< TextureSet* > TextureSetContainer; -typedef TextureSetContainer::Iterator TextureSetIter; -typedef TextureSetContainer::ConstIterator TextureSetConstIter; +} // unnamed namespace /** * Structure to contain UpdateManager internal data */ struct UpdateManager::Impl { + // SceneInfo keeps the root node of the Scene, its scene graph render task list, and the list of Layer pointers sorted by depth + struct SceneInfo + { + SceneInfo( Layer* root ) ///< Constructor + : root( root ) + { + } + + ~SceneInfo() = default; ///< Default non-virtual destructor + SceneInfo( SceneInfo&& rhs ) = default; ///< Move constructor + SceneInfo& operator=( SceneInfo&& rhs ) = default; ///< Move assignment operator + SceneInfo& operator=( const SceneInfo& rhs ) = delete; ///< Assignment operator + SceneInfo( const SceneInfo& rhs ) = delete; ///< Copy constructor + + Layer* root{ nullptr }; ///< Root node (root is a layer). The layer is not stored in the node memory pool. + OwnerPointer< RenderTaskList > taskList; ///< Scene graph render task list + SortedLayerPointers sortedLayerList; ///< List of Layer pointers sorted by depth (one list of sorted layers per root) + OwnerPointer< Scene > scene; ///< Scene graph object of the scene + }; + Impl( NotificationManager& notificationManager, - CompleteNotificationInterface& animationFinishedNotifier, + CompleteNotificationInterface& animationPlaylist, PropertyNotifier& propertyNotifier, - ResourceManager& resourceManager, DiscardQueue& discardQueue, RenderController& renderController, RenderManager& renderManager, RenderQueue& renderQueue, SceneGraphBuffers& sceneGraphBuffers, - GeometryBatcher& geometryBatcher, RenderTaskProcessor& renderTaskProcessor ) : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ), notificationManager( notificationManager ), transformManager(), - animationFinishedNotifier( animationFinishedNotifier ), + animationPlaylist( animationPlaylist ), propertyNotifier( propertyNotifier ), shaderSaver( NULL ), - resourceManager( resourceManager ), discardQueue( discardQueue ), renderController( renderController ), sceneController( NULL ), renderManager( renderManager ), renderQueue( renderQueue ), - renderInstructions( renderManager.GetRenderInstructionContainer() ), - geometryBatcher( geometryBatcher ), renderTaskProcessor( renderTaskProcessor ), backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ), - taskList( renderMessageDispatcher, resourceManager ), - systemLevelTaskList( renderMessageDispatcher, resourceManager ), - root( NULL ), - systemLevelRoot( NULL ), - renderers( sceneGraphBuffers, discardQueue ), + renderers(), textureSets(), + shaders(), + panGestureProcessor( NULL ), messageQueue( renderController, sceneGraphBuffers ), + frameCallbackProcessor( NULL ), keepRenderingSeconds( 0.0f ), + nodeDirtyFlags( NodePropertyFlags::TRANSFORM ), // set to TransformFlag to ensure full update the first time through Update() + frameCounter( 0 ), + renderingBehavior( DevelStage::Rendering::IF_REQUIRED ), animationFinishedDuringUpdate( false ), - nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update() previousUpdateScene( false ), - frameCounter( 0 ), - renderTaskWaiting( false ) + renderTaskWaiting( false ), + renderersAdded( false ), + surfaceRectChanged( false ) { sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue ); - renderers.SetSceneController( *sceneController ); - - discardQueue.SetGeometryBatcher( &geometryBatcher ); - // create first 'dummy' node nodes.PushBack(0u); } @@ -176,103 +223,104 @@ struct UpdateManager::Impl ~Impl() { // Disconnect render tasks from nodes, before destroying the nodes - RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks(); - for (RenderTaskList::RenderTaskContainer::Iterator iter = tasks.Begin(); iter != tasks.End(); ++iter) - { - (*iter)->SetSourceNode( NULL ); - } - // ..repeat for system level RenderTasks - RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks(); - for (RenderTaskList::RenderTaskContainer::Iterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter) + for( auto&& scene : scenes ) { - (*iter)->SetSourceNode( NULL ); + if ( scene && scene->taskList ) + { + RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks(); + for ( auto&& task : tasks ) + { + task->SetSourceNode( NULL ); + } + } } - // UpdateManager owns the Nodes + // UpdateManager owns the Nodes. Although Nodes are pool allocated they contain heap allocated parts + // like custom properties, which get released here Vector::Iterator iter = nodes.Begin()+1; Vector::Iterator endIter = nodes.End(); for(;iter!=endIter;++iter) { (*iter)->OnDestroy(); - delete(*iter); - } - - // If there is root, reset it, otherwise do nothing as rendering was never started - if( root ) - { - root->OnDestroy(); - - delete root; - root = NULL; + Node::Delete(*iter); } - if( systemLevelRoot ) + for( auto&& scene : scenes ) { - systemLevelRoot->OnDestroy(); - - delete systemLevelRoot; - systemLevelRoot = NULL; + if ( scene && scene->root ) + { + scene->root->OnDestroy(); + Node::Delete( scene->root ); + } } + scenes.clear(); delete sceneController; } - SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read - RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread - NotificationManager& notificationManager; ///< Queues notification messages for the event-thread. - TransformManager transformManager; ///< Used to update the transformation matrices of the nodes - CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished. - PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified. - ShaderSaver* shaderSaver; ///< Saves shader binaries. - ResourceManager& resourceManager; ///< resource manager - DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph. - RenderController& renderController; ///< render controller - SceneControllerImpl* sceneController; ///< scene controller - RenderManager& renderManager; ///< This is responsible for rendering the results of each "update" - RenderQueue& renderQueue; ///< Used to queue messages for the next render - RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions - GeometryBatcher& geometryBatcher; ///< An instance of the GeometryBatcher - RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons - - Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame. - - RenderTaskList taskList; ///< The list of scene graph render-tasks - RenderTaskList systemLevelTaskList; ///< Separate render-tasks for system-level content - - Layer* root; ///< The root node (root is a layer) - Layer* systemLevelRoot; ///< A separate root-node for system-level content - - Vector nodes; ///< A container of all instantiated nodes - - SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth - SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers - - OwnerContainer< Camera* > cameras; ///< A container of cameras - OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties) - - AnimationContainer animations; ///< A container of owned animations - PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications. - - ObjectOwnerContainer renderers; - TextureSetContainer textureSets; ///< A container of texture sets - - ShaderContainer shaders; ///< A container of owned shaders - - MessageQueue messageQueue; ///< The messages queued from the event-thread - ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread. - ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event - Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders - - float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering - bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update() - - int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame - bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out) - - int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore. + /** + * Lazy init for FrameCallbackProcessor. + * @param[in] updateManager A reference to the update-manager + */ + FrameCallbackProcessor& GetFrameCallbackProcessor( UpdateManager& updateManager ) + { + if( ! frameCallbackProcessor ) + { + frameCallbackProcessor = new FrameCallbackProcessor( updateManager, transformManager ); + } + return *frameCallbackProcessor; + } - GestureContainer gestures; ///< A container of owned gesture detectors - bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered + SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read + RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread + NotificationManager& notificationManager; ///< Queues notification messages for the event-thread. + TransformManager transformManager; ///< Used to update the transformation matrices of the nodes + CompleteNotificationInterface& animationPlaylist; ///< Holds handles to all the animations + PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified. + ShaderSaver* shaderSaver; ///< Saves shader binaries. + DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph. + RenderController& renderController; ///< render controller + SceneControllerImpl* sceneController; ///< scene controller + RenderManager& renderManager; ///< This is responsible for rendering the results of each "update" + RenderQueue& renderQueue; ///< Used to queue messages for the next render + RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons + + Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame. + + using SceneInfoPtr = std::unique_ptr< SceneInfo >; + std::vector< SceneInfoPtr > scenes; ///< A container of SceneInfo. + + Vector nodes; ///< A container of all instantiated nodes + + OwnerContainer< Camera* > cameras; ///< A container of cameras + OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties) + + OwnerContainer< PropertyResetterBase* > propertyResetters; ///< A container of property resetters + OwnerContainer< Animation* > animations; ///< A container of owned animations + PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications. + OwnerContainer< Renderer* > renderers; ///< A container of owned renderers + OwnerContainer< TextureSet* > textureSets; ///< A container of owned texture sets + OwnerContainer< Shader* > shaders; ///< A container of owned shaders + OwnerPointer< PanGesture > panGestureProcessor; ///< Owned pan gesture processor; it lives for the lifecycle of UpdateManager + + MessageQueue messageQueue; ///< The messages queued from the event-thread + std::vector renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread. + std::vector updateCompiledShaders; ///< Shaders to be sent from Update to Event + Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders + + OwnerPointer frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required. + + float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering + NodePropertyFlags nodeDirtyFlags; ///< cumulative node dirty flags from previous frame + uint32_t frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore. + + DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior + + bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update() + bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out) + bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered + bool renderersAdded; ///< Flag to keep track when renderers have been added to avoid unnecessary processing + bool surfaceRectChanged; ///< True if the default surface rect is changed private: @@ -283,30 +331,23 @@ private: UpdateManager::UpdateManager( NotificationManager& notificationManager, CompleteNotificationInterface& animationFinishedNotifier, PropertyNotifier& propertyNotifier, - ResourceManager& resourceManager, DiscardQueue& discardQueue, RenderController& controller, RenderManager& renderManager, RenderQueue& renderQueue, - TextureCacheDispatcher& textureCacheDispatcher, - GeometryBatcher& geometryBatcher, RenderTaskProcessor& renderTaskProcessor ) : mImpl(NULL) { mImpl = new Impl( notificationManager, animationFinishedNotifier, propertyNotifier, - resourceManager, discardQueue, controller, renderManager, renderQueue, mSceneGraphBuffers, - geometryBatcher, renderTaskProcessor ); - textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers ); - mImpl->geometryBatcher.SetUpdateManager( this ); } UpdateManager::~UpdateManager() @@ -314,42 +355,62 @@ UpdateManager::~UpdateManager() delete mImpl; } -void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel ) +void UpdateManager::InstallRoot( OwnerPointer& layer ) { DALI_ASSERT_DEBUG( layer->IsLayer() ); DALI_ASSERT_DEBUG( layer->GetParent() == NULL); - if ( !systemLevel ) - { - DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" ); - mImpl->root = layer; - mImpl->root->CreateTransform( &mImpl->transformManager ); - } - else + Layer* rootLayer = layer.Release(); + + DALI_ASSERT_DEBUG( std::find_if( mImpl->scenes.begin(), mImpl->scenes.end(), + [rootLayer]( Impl::SceneInfoPtr& scene ) + { + return scene && scene->root == rootLayer; + } + ) == mImpl->scenes.end() && "Root Node already installed" ); + + rootLayer->CreateTransform( &mImpl->transformManager ); + rootLayer->SetRoot(true); + + mImpl->scenes.emplace_back( new Impl::SceneInfo( rootLayer ) ); +} + +void UpdateManager::UninstallRoot( Layer* layer ) +{ + DALI_ASSERT_DEBUG( layer->IsLayer() ); + DALI_ASSERT_DEBUG( layer->GetParent() == NULL ); + + for (auto iter = mImpl->scenes.begin(); iter != mImpl->scenes.end(); ++iter) { - DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" ); - mImpl->systemLevelRoot = layer; - mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager ); + if( (*iter) && (*iter)->root == layer ) + { + mImpl->scenes.erase( iter ); + break; + } } - layer->SetRoot(true); + mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), layer ); + + // Notify the layer about impending destruction + layer->OnDestroy(); } -void UpdateManager::AddNode( Node* node ) +void UpdateManager::AddNode( OwnerPointer& node ) { - DALI_ASSERT_ALWAYS( NULL != node ); DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet // Nodes must be sorted by pointer + Node* rawNode = node.Release(); + DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddNode\n", rawNode ); + Vector::Iterator begin = mImpl->nodes.Begin(); - for(Vector::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter) + for( Vector::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter ) { - if(node > (*iter)) + if( rawNode > (*iter) ) { - mImpl->nodes.Insert((iter+1), node); - node->CreateTransform( &mImpl->transformManager ); - node->mGeometryBatcher = &mImpl->geometryBatcher; - break; + mImpl->nodes.Insert((iter+1), rawNode ); + rawNode->CreateTransform( &mImpl->transformManager ); + return; } } } @@ -360,16 +421,32 @@ void UpdateManager::ConnectNode( Node* parent, Node* node ) DALI_ASSERT_ALWAYS( NULL != node ); DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet + DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] ConnectNode\n", node ); + parent->ConnectChild( node ); + + // Inform the frame-callback-processor, if set, about the node-hierarchy changing + if( mImpl->frameCallbackProcessor ) + { + mImpl->frameCallbackProcessor->NodeHierarchyChanged(); + } } void UpdateManager::DisconnectNode( Node* node ) { + DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DisconnectNode\n", node ); + Node* parent = node->GetParent(); DALI_ASSERT_ALWAYS( NULL != parent ); - parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused + parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node ); + + // Inform the frame-callback-processor, if set, about the node-hierarchy changing + if( mImpl->frameCallbackProcessor ) + { + mImpl->frameCallbackProcessor->NodeHierarchyChanged(); + } } void UpdateManager::DestroyNode( Node* node ) @@ -377,6 +454,8 @@ void UpdateManager::DestroyNode( Node* node ) DALI_ASSERT_ALWAYS( NULL != node ); DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected + DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DestroyNode\n", node ); + Vector::Iterator iter = mImpl->nodes.Begin()+1; Vector::Iterator endIter = mImpl->nodes.End(); for(;iter!=endIter;++iter) @@ -394,63 +473,86 @@ void UpdateManager::DestroyNode( Node* node ) node->OnDestroy(); } -void UpdateManager::AddCamera( Camera* camera ) +void UpdateManager::AddCamera( OwnerPointer< Camera >& camera ) +{ + mImpl->cameras.PushBack( camera.Release() ); // takes ownership +} + +void UpdateManager::RemoveCamera( Camera* camera ) +{ + // Find the camera and destroy it + EraseUsingDiscardQueue( mImpl->cameras, camera, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() ); +} + +void UpdateManager::AddObject( OwnerPointer& object ) { - DALI_ASSERT_DEBUG( camera != NULL ); + mImpl->customObjects.PushBack( object.Release() ); +} + +void UpdateManager::RemoveObject( PropertyOwner* object ) +{ + mImpl->customObjects.EraseObject( object ); +} + +void UpdateManager::AddRenderTaskList( OwnerPointer& taskList ) +{ + RenderTaskList* taskListPointer = taskList.Release(); + taskListPointer->SetRenderMessageDispatcher( &mImpl->renderMessageDispatcher ); - mImpl->cameras.PushBack( camera ); // takes ownership + mImpl->scenes.back()->taskList = taskListPointer; } -void UpdateManager::RemoveCamera( const Camera* camera ) +void UpdateManager::RemoveRenderTaskList( RenderTaskList* taskList ) { - // Find the camera - OwnerContainer::Iterator iter = mImpl->cameras.Begin(); - OwnerContainer::ConstIterator end = mImpl->cameras.End(); - for ( ; iter != end; ++iter ) + for ( auto&& scene : mImpl->scenes ) { - Camera* value = *iter; - if ( camera == value ) + if ( scene && scene->taskList == taskList ) { - // Transfer ownership to the discard queue - mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->cameras.Release( iter ) ); - - return; + scene->taskList.Reset(); + break; } } - } -void UpdateManager::AddObject( PropertyOwner* object ) +void UpdateManager::AddScene( OwnerPointer< Scene >& scene ) { - DALI_ASSERT_DEBUG( NULL != object ); + mImpl->scenes.back()->scene = scene.Release(); + + // Initialize the context from render manager + typedef MessageValue1< RenderManager, SceneGraph::Scene* > DerivedType; - mImpl->customObjects.PushBack( object ); + // Reserve some memory inside the render queue + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + SceneGraph::Scene& sceneObject = *mImpl->scenes.back()->scene; + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::InitializeScene, &sceneObject ); } -void UpdateManager::RemoveObject( PropertyOwner* object ) +void UpdateManager::RemoveScene( Scene* scene ) { - DALI_ASSERT_DEBUG( NULL != object ); + // Initialize the context from render manager + typedef MessageValue1< RenderManager, SceneGraph::Scene* > DerivedType; - OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects; + // Reserve some memory inside the render queue + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UninitializeScene, scene ); - // Find the object and destroy it - for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter ) + for ( auto&& sceneInfo : mImpl->scenes ) { - PropertyOwner* current = *iter; - if ( current == object ) + if ( sceneInfo && sceneInfo->scene && sceneInfo->scene.Get() == scene ) { - customObjects.Erase( iter ); - return; + sceneInfo->scene.Reset(); + break; } } - - // Should not reach here - DALI_ASSERT_DEBUG(false); } -void UpdateManager::AddAnimation( Animation* animation ) +void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation ) { - mImpl->animations.PushBack( animation ); + mImpl->animations.PushBack( animation.Release() ); } void UpdateManager::StopAnimation( Animation* animation ) @@ -473,45 +575,35 @@ void UpdateManager::RemoveAnimation( Animation* animation ) bool UpdateManager::IsAnimationRunning() const { - bool isRunning(false); - AnimationContainer& animations = mImpl->animations; - // Find any animation that isn't stopped or paused - - const AnimationIter endIter = animations.End(); - for ( AnimationIter iter = animations.Begin(); !isRunning && iter != endIter; ++iter ) + for ( auto&& iter : mImpl->animations ) { - const Animation::State state = (*iter)->GetState(); + const Animation::State state = iter->GetState(); if (state != Animation::Stopped && state != Animation::Paused) { - isRunning = true; + return true; // stop iteration as soon as first one is found } } - return isRunning; + return false; } -void UpdateManager::AddPropertyNotification( PropertyNotification* propertyNotification ) +void UpdateManager::AddPropertyResetter( OwnerPointer& propertyResetter ) { - mImpl->propertyNotifications.PushBack( propertyNotification ); + propertyResetter->Initialize(); + mImpl->propertyResetters.PushBack( propertyResetter.Release() ); } -void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification ) +void UpdateManager::AddPropertyNotification( OwnerPointer< PropertyNotification >& propertyNotification ) { - PropertyNotificationContainer &propertyNotifications = mImpl->propertyNotifications; - PropertyNotificationIter iter = propertyNotifications.Begin(); + mImpl->propertyNotifications.PushBack( propertyNotification.Release() ); +} - while ( iter != propertyNotifications.End() ) - { - if( *iter == propertyNotification ) - { - propertyNotifications.Erase(iter); - break; - } - ++iter; - } +void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification ) +{ + mImpl->propertyNotifications.EraseObject( propertyNotification ); } void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode ) @@ -520,52 +612,15 @@ void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propert propertyNotification->SetNotifyMode( notifyMode ); } -ObjectOwnerContainer& UpdateManager::GetRendererOwner() -{ - return mImpl->renderers; -} - -void UpdateManager::AddShader( Shader* shader ) +void UpdateManager::AddShader( OwnerPointer< Shader >& shader ) { - DALI_ASSERT_DEBUG( NULL != shader ); - - if( mImpl->shaders.Count() == 0 ) - { - // the first added shader becomes our default shader - // Construct message in the render queue memory; note that delete should not be called on the return value - typedef MessageValue1< RenderManager, Shader* > DerivedType; - - // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); - - // Construct message in the render queue memory; note that delete should not be called on the return value - new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultShader, shader ); - } - - mImpl->shaders.PushBack( shader ); + mImpl->shaders.PushBack( shader.Release() ); } void UpdateManager::RemoveShader( Shader* shader ) { - DALI_ASSERT_DEBUG(shader != NULL); - - ShaderContainer& shaders = mImpl->shaders; - // Find the shader and destroy it - for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter ) - { - Shader& current = **iter; - if ( ¤t == shader ) - { - // Transfer ownership to the discard queue - // This keeps the shader alive, until the render-thread has finished with it - mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), shaders.Release( iter ) ); - - return; - } - } - // Should not reach here - DALI_ASSERT_DEBUG(false); + EraseUsingDiscardQueue( mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() ); } void UpdateManager::SetShaderProgram( Shader* shader, @@ -577,7 +632,7 @@ void UpdateManager::SetShaderProgram( Shader* shader, typedef MessageValue3< Shader, Internal::ShaderDataPtr, ProgramCache*, bool> DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry ); @@ -595,68 +650,48 @@ void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData ) } } -RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel ) +void UpdateManager::SetShaderSaver( ShaderSaver& upstream ) { - if ( !systemLevel ) - { - // copy the list, this is only likely to happen once in application life cycle - return &(mImpl->taskList); - } - else - { - // copy the list, this is only likely to happen once in application life cycle - return &(mImpl->systemLevelTaskList); - } + mImpl->shaderSaver = &upstream; } -void UpdateManager::AddGesture( PanGesture* gesture ) +void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer ) { - DALI_ASSERT_DEBUG( NULL != gesture ); + DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer.Get() ); - mImpl->gestures.PushBack( gesture ); + renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() ); + mImpl->renderers.PushBack( renderer.Release() ); + mImpl->renderersAdded = true; } -void UpdateManager::RemoveGesture( PanGesture* gesture ) +void UpdateManager::RemoveRenderer( Renderer* renderer ) { - DALI_ASSERT_DEBUG( gesture != NULL ); + DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] RemoveRenderer\n", renderer ); - GestureContainer& gestures = mImpl->gestures; + // Find the renderer and destroy it + EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() ); + // Need to remove the render object as well + renderer->DisconnectFromSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() ); +} - // Find the gesture and destroy it - for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter ) - { - PanGesture& current = **iter; - if ( ¤t == gesture ) - { - mImpl->gestures.Erase( iter ); - return; - } - } - // Should not reach here - DALI_ASSERT_DEBUG(false); +void UpdateManager::SetPanGestureProcessor( PanGesture* panGestureProcessor ) +{ + DALI_ASSERT_DEBUG( NULL != panGestureProcessor ); + + mImpl->panGestureProcessor = panGestureProcessor; } -void UpdateManager::AddTextureSet( TextureSet* textureSet ) +void UpdateManager::AddTextureSet( OwnerPointer< TextureSet >& textureSet ) { - DALI_ASSERT_DEBUG( NULL != textureSet ); - mImpl->textureSets.PushBack( textureSet ); + mImpl->textureSets.PushBack( textureSet.Release() ); } void UpdateManager::RemoveTextureSet( TextureSet* textureSet ) { - DALI_ASSERT_DEBUG(textureSet != NULL); - size_t textureSetCount( mImpl->textureSets.Size() ); - for( size_t i(0); itextureSets[i] ) - { - mImpl->textureSets.Remove( mImpl->textureSets.Begin() + i ); - return; - } - } + mImpl->textureSets.EraseObject( textureSet ); } -unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene ) +uint32_t* UpdateManager::ReserveMessageSlot( uint32_t size, bool updateScene ) { return mImpl->messageQueue.ReserveMessageSlot( size, updateScene ); } @@ -676,69 +711,48 @@ void UpdateManager::ResetProperties( BufferIndex bufferIndex ) // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped mImpl->animationFinishedDuringUpdate = false; - // Animated properties have to be reset to their original value each frame - - // Reset root properties - if ( mImpl->root ) - { - mImpl->root->ResetToBaseValues( bufferIndex ); - } - if ( mImpl->systemLevelRoot ) - { - mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex ); - } - - // Reset all the nodes - Vector::Iterator iter = mImpl->nodes.Begin()+1; - Vector::Iterator endIter = mImpl->nodes.End(); - for(;iter != endIter; ++iter) + // Reset all animating / constrained properties + std::vectortoDelete; + for( auto&& element : mImpl->propertyResetters ) { - (*iter)->ResetToBaseValues( bufferIndex ); - } - - // Reset system-level render-task list properties to base values - const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks(); - - for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter) - { - (*iter)->ResetToBaseValues( bufferIndex ); + element->ResetToBaseValue( bufferIndex ); + if( element->IsFinished() ) + { + toDelete.push_back( element ); + } } - // Reset render-task list properties to base values. - const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks(); - - for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter) + // If a resetter is no longer required (the animator or constraint has been removed), delete it. + for( auto&& elementPtr : toDelete ) { - (*iter)->ResetToBaseValues( bufferIndex ); + mImpl->propertyResetters.EraseObject( elementPtr ); } - // Reset custom object properties to base values - for (OwnerContainer::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter) + // Clear all root nodes dirty flags + for( auto& scene : mImpl->scenes ) { - (*iter)->ResetToBaseValues( bufferIndex ); + auto root = scene->root; + root->ResetDirtyFlags( bufferIndex ); } - mImpl->renderers.ResetToBaseValues( bufferIndex ); - - // Reset animatable shader properties to base values - for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter) + // Clear node dirty flags + Vector::Iterator iter = mImpl->nodes.Begin()+1; + Vector::Iterator endIter = mImpl->nodes.End(); + for( ;iter != endIter; ++iter ) { - (*iter)->ResetToBaseValues( bufferIndex ); + (*iter)->ResetDirtyFlags( bufferIndex ); } } -bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds ) +bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds ) { bool gestureUpdated( false ); - // constrain gestures... (in construction order) - GestureContainer& gestures = mImpl->gestures; - - for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter ) + if( mImpl->panGestureProcessor ) { - PanGesture& gesture = **iter; - gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message - gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds ); + // gesture processor only supports default properties + 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 + gestureUpdated |= mImpl->panGestureProcessor->UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds ); } return gestureUpdated; @@ -746,15 +760,21 @@ bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastV void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds ) { - AnimationContainer &animations = mImpl->animations; - AnimationIter iter = animations.Begin(); + auto&& iter = mImpl->animations.Begin(); bool animationLooped = false; - while ( iter != animations.End() ) + + while ( iter != mImpl->animations.End() ) { Animation* animation = *iter; bool finished = false; bool looped = false; - animation->Update( bufferIndex, elapsedSeconds, looped, finished ); + bool progressMarkerReached = false; + animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached ); + + if ( progressMarkerReached ) + { + mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) ); + } mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished; animationLooped = animationLooped || looped; @@ -762,7 +782,7 @@ void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds ) // Remove animations that had been destroyed but were still waiting for an update if (animation->GetState() == Animation::Destroyed) { - iter = animations.Erase(iter); + iter = mImpl->animations.Erase(iter); } else { @@ -774,66 +794,53 @@ void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds ) if ( mImpl->animationFinishedDuringUpdate || animationLooped ) { // The application should be notified by NotificationManager, in another thread - mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier ); + mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist ); } } void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex ) { //Constrain custom objects (in construction order) - OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects; - const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End(); - for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter ) + for ( auto&& object : mImpl->customObjects ) { - PropertyOwner& object = **iter; - ConstrainPropertyOwner( object, bufferIndex ); + ConstrainPropertyOwner( *object, bufferIndex ); } } void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex ) { - // Constrain system-level render-tasks - const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks(); - for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter ) - { - RenderTask& task = **iter; - ConstrainPropertyOwner( task, bufferIndex ); - } - // Constrain render-tasks - const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks(); - for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter ) + for ( auto&& scene : mImpl->scenes ) { - RenderTask& task = **iter; - ConstrainPropertyOwner( task, bufferIndex ); + if ( scene && scene->taskList ) + { + RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks(); + for ( auto&& task : tasks ) + { + ConstrainPropertyOwner( *task, bufferIndex ); + } + } } } void UpdateManager::ConstrainShaders( BufferIndex bufferIndex ) { // constrain shaders... (in construction order) - ShaderContainer& shaders = mImpl->shaders; - for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter ) + for ( auto&& shader : mImpl->shaders ) { - Shader& shader = **iter; - ConstrainPropertyOwner( shader, bufferIndex ); + ConstrainPropertyOwner( *shader, bufferIndex ); } } void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex ) { - PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications; - PropertyNotificationIter iter = notifications.Begin(); - - while ( iter != notifications.End() ) + for( auto&& notification : mImpl->propertyNotifications ) { - PropertyNotification* notification = *iter; bool valid = notification->Check( bufferIndex ); if(valid) { mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) ); } - ++iter; } } @@ -852,11 +859,9 @@ void UpdateManager::ForwardCompiledShadersToEventThread() if( mImpl->updateCompiledShaders.size() > 0 ) { ShaderSaver& factory = *mImpl->shaderSaver; - ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin(); - ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end(); - for( ; i != end; ++i ) + for( auto&& shader : mImpl->updateCompiledShaders ) { - mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) ); + mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, shader ) ); } // we don't need them in update anymore mImpl->updateCompiledShaders.clear(); @@ -866,64 +871,53 @@ void UpdateManager::ForwardCompiledShadersToEventThread() void UpdateManager::UpdateRenderers( BufferIndex bufferIndex ) { - const OwnerContainer& rendererContainer( mImpl->renderers.GetObjectContainer() ); - unsigned int rendererCount( rendererContainer.Size() ); - for( unsigned int i(0); irenderers ) { //Apply constraints - ConstrainPropertyOwner( *rendererContainer[i], bufferIndex ); + ConstrainPropertyOwner( *renderer, bufferIndex ); - rendererContainer[i]->PrepareRender( bufferIndex ); + renderer->PrepareRender( bufferIndex ); } } void UpdateManager::UpdateNodes( BufferIndex bufferIndex ) { - mImpl->nodeDirtyFlags = NothingFlag; - - if ( !mImpl->root ) - { - return; - } + mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING; - // Prepare resources, update shaders, for each node - // And add the renderers to the sorted layers. Start from root, which is also a layer - mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ), - bufferIndex, - mImpl->resourceManager, - mImpl->renderQueue ); - - if ( mImpl->systemLevelRoot ) + for ( auto&& scene : mImpl->scenes ) { - mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ), - bufferIndex, - mImpl->resourceManager, - mImpl->renderQueue ); + if ( scene && scene->root ) + { + // Prepare resources, update shaders, for each node + // And add the renderers to the sorted layers. Start from root, which is also a layer + mImpl->nodeDirtyFlags |= UpdateNodeTree( *scene->root, + bufferIndex, + mImpl->renderQueue ); + } } } -unsigned int UpdateManager::Update( float elapsedSeconds, - unsigned int lastVSyncTimeMilliseconds, - unsigned int nextVSyncTimeMilliseconds ) +uint32_t UpdateManager::Update( float elapsedSeconds, + uint32_t lastVSyncTimeMilliseconds, + uint32_t nextVSyncTimeMilliseconds, + bool renderToFboEnabled, + bool isRenderingToFbo ) { const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex(); //Clear nodes/resources which were previously discarded mImpl->discardQueue.Clear( bufferIndex ); - //Grab any loaded resources - bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex ); - //Process Touches & Gestures const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds ); - const bool updateScene = // The scene-graph requires an update if.. + bool updateScene = // The scene-graph requires an update if.. (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR IsAnimationRunning() || // ..at least one animation is running OR mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR - resourceChanged || // ..one or more resources were updated/changed OR gestureUpdated; // ..a gesture property was updated + bool keepRendererRendering = false; // Although the scene-graph may not require an update, we still need to synchronize double-buffered // values if the scene was updated in the previous frame. @@ -934,8 +928,10 @@ unsigned int UpdateManager::Update( float elapsedSeconds, mImpl->transformManager.ResetToBaseValue(); } - //Process the queued scene messages - mImpl->messageQueue.ProcessMessages( bufferIndex ); + // Process the queued scene messages. Note, MessageQueue::FlushQueue may be called + // between calling IsSceneUpdateRequired() above and here, so updateScene should + // be set again + updateScene |= mImpl->messageQueue.ProcessMessages( bufferIndex ); //Forward compiled shader programs to event thread for saving ForwardCompiledShadersToEventThread(); @@ -952,14 +948,24 @@ unsigned int UpdateManager::Update( float elapsedSeconds, ConstrainCustomObjects( bufferIndex ); //Clear the lists of renderers from the previous update - for( size_t i(0); isortedLayers.size(); ++i ) + for( auto&& scene : mImpl->scenes ) { - mImpl->sortedLayers[i]->ClearRenderables(); + if ( scene ) + { + for( auto&& layer : scene->sortedLayerList ) + { + if ( layer ) + { + layer->ClearRenderables(); + } + } + } } - for( size_t i(0); isystemLevelSortedLayers.size(); ++i ) + // Call the frame-callback-processor if set + if( mImpl->frameCallbackProcessor ) { - mImpl->systemLevelSortedLayers[i]->ClearRenderables(); + mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds ); } //Update node hierarchy, apply constraints and perform sorting / culling. @@ -973,69 +979,91 @@ unsigned int UpdateManager::Update( float elapsedSeconds, //Update renderers and apply constraints UpdateRenderers( bufferIndex ); - //Update the trnasformations of all the nodes + //Update the transformations of all the nodes mImpl->transformManager.Update(); //Process Property Notifications ProcessPropertyNotifications( bufferIndex ); - //Update geometry batcher - mImpl->geometryBatcher.Update( bufferIndex ); + //Update cameras + for( auto&& cameraIterator : mImpl->cameras ) + { + cameraIterator->Update( bufferIndex ); + } - //Process the RenderTasks; this creates the instructions for rendering the next frame. + //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame. //reset the update buffer index and make sure there is enough room in the instruction container - mImpl->renderInstructions.ResetAndReserve( bufferIndex, - mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() ); - - if ( NULL != mImpl->root ) + if( mImpl->renderersAdded ) { - mImpl->renderTaskProcessor.Process( bufferIndex, - mImpl->taskList, - *mImpl->root, - mImpl->sortedLayers, - mImpl->geometryBatcher, - mImpl->renderInstructions ); - - // Process the system-level RenderTasks last - if ( NULL != mImpl->systemLevelRoot ) + // Calculate how many render tasks we have in total + std::size_t numberOfRenderTasks = 0; + for (auto&& scene : mImpl->scenes ) { - mImpl->renderTaskProcessor.Process( bufferIndex, - mImpl->systemLevelTaskList, - *mImpl->systemLevelRoot, - mImpl->systemLevelSortedLayers, - mImpl->geometryBatcher, - mImpl->renderInstructions ); + if ( scene && scene->taskList ) + { + numberOfRenderTasks += scene->taskList->GetTasks().Count(); + } } - } - } - - // check the countdown and notify (note, at the moment this is only done for normal tasks, not for systemlevel tasks) - bool doRenderOnceNotify = false; - mImpl->renderTaskWaiting = false; - const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks(); - for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(), endIter = tasks.End(); - endIter != iter; ++iter ) - { - RenderTask& renderTask(*(*iter)); - renderTask.UpdateState(); - if( renderTask.IsWaitingToRender() && - renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ ) - { - mImpl->renderTaskWaiting = true; // keep update/render threads alive - } + std::size_t numberOfRenderInstructions = 0; + for ( auto&& scene : mImpl->scenes ) + { + if ( scene && scene->root && scene->taskList && scene->scene ) + { + scene->scene->GetRenderInstructions().ResetAndReserve( bufferIndex, + static_cast( scene->taskList->GetTasks().Count() ) ); + + keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex, + *scene->taskList, + *scene->root, + scene->sortedLayerList, + *scene->scene->GetContext(), + scene->scene->GetRenderInstructions(), + renderToFboEnabled, + isRenderingToFbo ); + + numberOfRenderInstructions += scene->scene->GetRenderInstructions().Count( bufferIndex ); + } + } - if( renderTask.HasRendered() ) - { - doRenderOnceNotify = true; + DALI_LOG_INFO( gLogFilter, Debug::General, + "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n", + numberOfRenderTasks, numberOfRenderInstructions ); } } - if( doRenderOnceNotify ) + for ( auto&& scene : mImpl->scenes ) { - DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n"); - mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() ); + if ( scene && scene->root && scene->taskList ) + { + RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks(); + + // check the countdown and notify + bool doRenderOnceNotify = false; + mImpl->renderTaskWaiting = false; + for ( auto&& renderTask : tasks ) + { + renderTask->UpdateState(); + + if( renderTask->IsWaitingToRender() && + renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ ) + { + mImpl->renderTaskWaiting = true; // keep update/render threads alive + } + + if( renderTask->HasRendered() ) + { + doRenderOnceNotify = true; + } + } + + if( doRenderOnceNotify ) + { + DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n"); + mImpl->notificationManager.QueueCompleteNotification( scene->taskList->GetCompleteNotificationInterface() ); + } + } } // Macro is undefined in release build. @@ -1045,7 +1073,15 @@ unsigned int UpdateManager::Update( float elapsedSeconds, mImpl->previousUpdateScene = updateScene; // Check whether further updates are required - unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds ); + uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds ); + + if( keepRendererRendering ) + { + keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING; + + // Set dirty flags for next frame to continue rendering + mImpl->nodeDirtyFlags |= RenderableUpdateFlags; + } // tell the update manager that we're done so the queue can be given to event thread mImpl->notificationManager.UpdateCompleted(); @@ -1056,7 +1092,7 @@ unsigned int UpdateManager::Update( float elapsedSeconds, return keepUpdating; } -unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const +uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const { // Update the duration set via Stage::KeepRendering() if ( mImpl->keepRenderingSeconds > 0.0f ) @@ -1064,15 +1100,17 @@ unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const mImpl->keepRenderingSeconds -= elapsedSeconds; } - unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED; + uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED; + // If the rendering behavior is set to continuously render, then continue to render. // If Stage::KeepRendering() has been called, then continue until the duration has elapsed. // Keep updating until no messages are received and no animations are running. // If an animation has just finished, update at least once more for Discard end-actions. // No need to check for renderQueue as there is always a render after update and if that // render needs another update it will tell the adaptor to call update again - if ( mImpl->keepRenderingSeconds > 0.0f ) + if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) || + ( mImpl->keepRenderingSeconds > 0.0f ) ) { keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING; } @@ -1091,26 +1129,28 @@ unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const return keepUpdatingRequest; } -void UpdateManager::SetBackgroundColor( const Vector4& color ) +void UpdateManager::SetDefaultSurfaceRect( const Rect& rect ) { - typedef MessageValue1< RenderManager, Vector4 > DerivedType; + mImpl->surfaceRectChanged = true; + + typedef MessageValue1< RenderManager, Rect > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value - new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color ); + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect ); } -void UpdateManager::SetDefaultSurfaceRect( const Rect& rect ) +void UpdateManager::SurfaceReplaced( Scene* scene ) { - typedef MessageValue1< RenderManager, Rect > DerivedType; + typedef MessageValue1< RenderManager, Scene* > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value - new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetDefaultSurfaceRect, rect ); + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SurfaceReplaced, scene ); } void UpdateManager::KeepRendering( float durationSeconds ) @@ -1118,30 +1158,69 @@ void UpdateManager::KeepRendering( float durationSeconds ) mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds ); } -void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel ) +void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior ) +{ + mImpl->renderingBehavior = renderingBehavior; +} + +void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer ) +{ + for ( auto&& scene : mImpl->scenes ) + { + if ( scene && scene->root == rootLayer ) + { + scene->sortedLayerList = layers; + break; + } + } +} + +void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths ) { - if ( !systemLevel ) + // note,this vector is already in depth order. It could be used as-is to + // remove sorting in update algorithm. However, it lacks layer boundary markers. + for( auto&& iter : nodeDepths->nodeDepths ) { - // just copy the vector of pointers - mImpl->sortedLayers = layers; + iter.node->SetDepthIndex( iter.sortedDepth ); } - else + + for ( auto&& scene : mImpl->scenes ) { - mImpl->systemLevelSortedLayers = layers; + if ( scene ) + { + // Go through node hierarchy and rearrange siblings according to depth-index + SortSiblingNodesRecursively( *scene->root ); + } } } -void UpdateManager::SetShaderSaver( ShaderSaver& upstream ) +bool UpdateManager::IsDefaultSurfaceRectChanged() { - mImpl->shaderSaver = &upstream; + bool surfaceRectChanged = mImpl->surfaceRectChanged; + + // Reset the flag + mImpl->surfaceRectChanged = false; + + return surfaceRectChanged; } -void UpdateManager::AddSampler( Render::Sampler* sampler ) +void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode ) { - typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType; + mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode ); +} + +void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback ) +{ + mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback ); +} + +void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler ) +{ + // Message has ownership of Sampler while in transit from update to render + typedef MessageValue1< RenderManager, OwnerPointer< Render::Sampler > > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddSampler, sampler ); @@ -1152,40 +1231,41 @@ void UpdateManager::RemoveSampler( Render::Sampler* sampler ) typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveSampler, sampler ); } -void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFilterMode, unsigned int magFilterMode ) +void UpdateManager::SetFilterMode( Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode ) { - typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType; + typedef MessageValue3< RenderManager, Render::Sampler*, uint32_t, uint32_t > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode ); } -void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode ) +void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode ) { - typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > DerivedType; + typedef MessageValue4< RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode ); } -void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer ) +void UpdateManager::AddPropertyBuffer( OwnerPointer< Render::PropertyBuffer >& propertyBuffer ) { - typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType; + // Message has ownership of format while in transit from update -> render + typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer ); @@ -1196,40 +1276,43 @@ void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer ); } -void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format ) +void UpdateManager::SetPropertyBufferFormat( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Render::PropertyBuffer::Format>& format ) { - typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Render::PropertyBuffer::Format* > DerivedType; + // Message has ownership of format while in transit from update -> render + typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format ); } -void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector* data, size_t size ) +void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Vector >& data, uint32_t size ) { - typedef MessageValue3< RenderManager, Render::PropertyBuffer*, Dali::Vector*, size_t > DerivedType; + // Message has ownership of format while in transit from update -> render + typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector >, uint32_t > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size ); } -void UpdateManager::AddGeometry( Render::Geometry* geometry ) +void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry ) { - typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType; + // Message has ownership of format while in transit from update -> render + typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry ); @@ -1240,29 +1323,29 @@ void UpdateManager::RemoveGeometry( Render::Geometry* geometry ) typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry ); } -void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType ) +void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType ) { - typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType; + typedef MessageValue2< RenderManager, Render::Geometry*, uint32_t > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType ); } -void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector& indices ) +void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector& indices ) { typedef IndexBufferMessage< RenderManager > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, geometry, indices ); @@ -1273,73 +1356,74 @@ void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::Prop typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer ); } -void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer ) +void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer ) { typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value - new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, geometry, propertyBuffer ); + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, propertyBuffer ); } -void UpdateManager::AddTexture( Render::NewTexture* texture ) +void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture ) { - typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType; + // Message has ownership of Texture while in transit from update -> render + typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value - new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture ); + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture ); } -void UpdateManager::RemoveTexture( Render::NewTexture* texture) +void UpdateManager::RemoveTexture( Render::Texture* texture) { - typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType; + typedef MessageValue1< RenderManager, Render::Texture* > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture ); } -void UpdateManager::UploadTexture( Render::NewTexture* texture, PixelDataPtr pixelData, const NewTexture::UploadParams& params ) +void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params ) { - typedef MessageValue3< RenderManager, Render::NewTexture*, PixelDataPtr, NewTexture::UploadParams > DerivedType; + typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType; // Reserve some memory inside the message queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the message queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params ); } -void UpdateManager::GenerateMipmaps( Render::NewTexture* texture ) +void UpdateManager::GenerateMipmaps( Render::Texture* texture ) { - typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType; + typedef MessageValue1< RenderManager, Render::Texture* > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture ); } -void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer ) +void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer ) { - typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType; + typedef MessageValue1< RenderManager, OwnerPointer< Render::FrameBuffer > > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer ); @@ -1350,18 +1434,18 @@ void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer) typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer ); } -void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::NewTexture* texture, unsigned int mipmapLevel, unsigned int layer ) +void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer ) { - typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::NewTexture*, unsigned int, unsigned int > DerivedType; + typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t > DerivedType; // Reserve some memory inside the render queue - unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); // Construct message in the render queue memory; note that delete should not be called on the return value new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );