X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Fmanager%2Fupdate-manager.cpp;h=8a3bfb997f209c82f377a5557ce176675a8141d4;hb=b0874a94f3eedf812a2dcc2d23089c639c1719a4;hp=2ddbc18200751d11dfb5f9adc3a35d4f57921369;hpb=5dfc23c442205d994856292a010a8acf55bf5ac6;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 2ddbc18..8a3bfb9 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) 2018 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,17 +35,17 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include -#include -#include +#include +#include #include #include #include @@ -56,16 +55,12 @@ #include #include #include -#include -#include +#include #include #include #include -#include #include -#include -#include // Un-comment to enable node tree debug logging //#define NODE_TREE_LOGGING 1 @@ -103,19 +98,66 @@ namespace Internal namespace SceneGraph { -typedef OwnerContainer< Shader* > ShaderContainer; -typedef ShaderContainer::Iterator ShaderIter; -typedef ShaderContainer::ConstIterator ShaderConstIter; +namespace +{ +/** + * Helper to reset animate-able objects to base values + * @param container to iterate over + * @param updateBufferIndex to use + */ +template< class T > +inline void ResetToBaseValues( OwnerContainer& container, BufferIndex updateBufferIndex ) +{ + // Reset animatable properties to base values + // use reference to avoid extra copies of the iterator + for( auto&& iter : container ) + { + iter->ResetToBaseValues( updateBufferIndex ); + } +} + +/** + * 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 @@ -123,47 +165,50 @@ typedef TextureSetContainer::ConstIterator TextureSetConstIter; struct UpdateManager::Impl { Impl( NotificationManager& notificationManager, - CompleteNotificationInterface& animationFinishedNotifier, + CompleteNotificationInterface& animationPlaylist, PropertyNotifier& propertyNotifier, - ResourceManager& resourceManager, DiscardQueue& discardQueue, RenderController& renderController, RenderManager& renderManager, RenderQueue& renderQueue, - SceneGraphBuffers& sceneGraphBuffers ) + SceneGraphBuffers& sceneGraphBuffers, + 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() ), + renderTaskProcessor( renderTaskProcessor ), backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ), - taskList( renderMessageDispatcher, resourceManager ), - systemLevelTaskList( renderMessageDispatcher, resourceManager ), + taskList( renderMessageDispatcher ), + systemLevelTaskList( renderMessageDispatcher ), root( NULL ), systemLevelRoot( NULL ), - renderers( sceneGraphBuffers, discardQueue ), + renderers(), textureSets(), + shaders(), + panGestureProcessor( NULL ), messageQueue( renderController, sceneGraphBuffers ), + frameCallbackProcessor( NULL ), keepRenderingSeconds( 0.0f ), - animationFinishedDuringUpdate( false ), nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update() - previousUpdateScene( false ), frameCounter( 0 ), - renderSortingHelper(), - renderTaskWaiting( false ) + renderingBehavior( DevelStage::Rendering::IF_REQUIRED ), + animationFinishedDuringUpdate( false ), + previousUpdateScene( false ), + renderTaskWaiting( false ), + renderersAdded( false ), + surfaceRectChanged( false ) { sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue ); - renderers.SetSceneController( *sceneController ); - // create first 'dummy' node nodes.PushBack(0u); } @@ -172,24 +217,25 @@ struct UpdateManager::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) + for ( auto&& iter : tasks ) { - (*iter)->SetSourceNode( NULL ); + 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&& iter : systemLevelTasks ) { - (*iter)->SetSourceNode( NULL ); + iter->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); + Node::Delete(*iter); } // If there is root, reset it, otherwise do nothing as rendering was never started @@ -197,7 +243,7 @@ struct UpdateManager::Impl { root->OnDestroy(); - delete root; + Node::Delete( root ); root = NULL; } @@ -205,92 +251,109 @@ struct UpdateManager::Impl { systemLevelRoot->OnDestroy(); - delete systemLevelRoot; + Node::Delete( systemLevelRoot ); systemLevelRoot = NULL; } 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 + /** + * Lazy init for FrameCallbackProcessor. + */ + FrameCallbackProcessor& GetFrameCallbackProcessor() + { + if( ! frameCallbackProcessor ) + { + frameCallbackProcessor = new FrameCallbackProcessor( transformManager, *root ); + } + return *frameCallbackProcessor; + } + + 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 + RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions + RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons - Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame. + 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 + 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 + 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 + 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 + 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) + 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. + OwnerContainer< PropertyResetterBase* > propertyResetters; ///< A container of property resetters + AnimationContainer 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 - ObjectOwnerContainer renderers; - TextureSetContainer textureSets; ///< A container of texture sets + 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 - ShaderContainer shaders; ///< A container of owned shaders + OwnerPointer frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required. - 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 + int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame + int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore. - float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering - bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update() + DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior - 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) + 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 - int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore. - RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers +private: - GestureContainer gestures; ///< A container of owned gesture detectors - bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered + Impl( const Impl& ); ///< Undefined + Impl& operator=( const Impl& ); ///< Undefined }; UpdateManager::UpdateManager( NotificationManager& notificationManager, CompleteNotificationInterface& animationFinishedNotifier, PropertyNotifier& propertyNotifier, - ResourceManager& resourceManager, DiscardQueue& discardQueue, RenderController& controller, RenderManager& renderManager, RenderQueue& renderQueue, - TextureCacheDispatcher& textureCacheDispatcher ) + RenderTaskProcessor& renderTaskProcessor ) : mImpl(NULL) { mImpl = new Impl( notificationManager, animationFinishedNotifier, propertyNotifier, - resourceManager, discardQueue, controller, renderManager, renderQueue, - mSceneGraphBuffers ); + mSceneGraphBuffers, + renderTaskProcessor ); - textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers ); } UpdateManager::~UpdateManager() @@ -298,7 +361,7 @@ UpdateManager::~UpdateManager() delete mImpl; } -void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel ) +void UpdateManager::InstallRoot( OwnerPointer& layer, bool systemLevel ) { DALI_ASSERT_DEBUG( layer->IsLayer() ); DALI_ASSERT_DEBUG( layer->GetParent() == NULL); @@ -306,33 +369,34 @@ void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel ) if ( !systemLevel ) { DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" ); - mImpl->root = layer; - mImpl->root->CreateTransform( &mImpl->transformManager); + mImpl->root = layer.Release(); + mImpl->root->CreateTransform( &mImpl->transformManager ); + mImpl->root->SetRoot(true); } else { DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" ); - mImpl->systemLevelRoot = layer; - mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager); + mImpl->systemLevelRoot = layer.Release(); + mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager ); + mImpl->systemLevelRoot->SetRoot(true); } - layer->SetRoot(true); } -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(); 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); - break; + mImpl->nodes.Insert((iter+1), rawNode ); + rawNode->CreateTransform( &mImpl->transformManager ); + return; } } } @@ -344,6 +408,12 @@ void UpdateManager::ConnectNode( Node* parent, Node* node ) DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet 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 ) @@ -353,6 +423,12 @@ void UpdateManager::DisconnectNode( Node* node ) parent->SetDirtyFlag( ChildDeletedFlag ); // 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,63 +453,30 @@ void UpdateManager::DestroyNode( Node* node ) node->OnDestroy(); } -void UpdateManager::AddCamera( Camera* camera ) +void UpdateManager::AddCamera( OwnerPointer< Camera >& camera ) { - DALI_ASSERT_DEBUG( camera != NULL ); - - mImpl->cameras.PushBack( camera ); // takes ownership + mImpl->cameras.PushBack( camera.Release() ); // takes ownership } void UpdateManager::RemoveCamera( const Camera* camera ) { - // Find the camera - OwnerContainer::Iterator iter = mImpl->cameras.Begin(); - OwnerContainer::ConstIterator end = mImpl->cameras.End(); - for ( ; iter != end; ++iter ) - { - Camera* value = *iter; - if ( camera == value ) - { - // Transfer ownership to the discard queue - mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->cameras.Release( iter ) ); - - return; - } - } - + // Find the camera and destroy it + EraseUsingDiscardQueue( mImpl->cameras, const_cast( camera ), mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() ); } -void UpdateManager::AddObject( PropertyOwner* object ) +void UpdateManager::AddObject( OwnerPointer& object ) { - DALI_ASSERT_DEBUG( NULL != object ); - - mImpl->customObjects.PushBack( object ); + mImpl->customObjects.PushBack( object.Release() ); } void UpdateManager::RemoveObject( PropertyOwner* object ) { - DALI_ASSERT_DEBUG( NULL != object ); - - OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects; - - // Find the object and destroy it - for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter ) - { - PropertyOwner* current = *iter; - if ( current == object ) - { - customObjects.Erase( iter ); - return; - } - } - - // Should not reach here - DALI_ASSERT_DEBUG(false); + mImpl->customObjects.EraseObject( object ); } -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 ) @@ -456,45 +499,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 ) @@ -503,52 +536,15 @@ void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propert propertyNotification->SetNotifyMode( notifyMode ); } -ObjectOwnerContainer& UpdateManager::GetRendererOwner() +void UpdateManager::AddShader( OwnerPointer< Shader >& shader ) { - return mImpl->renderers; -} - -void UpdateManager::AddShader( 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, @@ -578,64 +574,54 @@ 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 ); - - 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 ); + // 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() ); +} - GestureContainer& gestures = mImpl->gestures; +void UpdateManager::SetPanGestureProcessor( PanGesture* panGestureProcessor ) +{ + DALI_ASSERT_DEBUG( NULL != panGestureProcessor ); - // 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); + 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.EraseObject( textureSet ); +} + +RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel ) +{ + if ( !systemLevel ) { - if( textureSet == mImpl->textureSets[i] ) - { - mImpl->textureSets.Remove( mImpl->textureSets.Begin() + i ); - return; - } + // 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); } } @@ -659,54 +645,29 @@ 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 ) + // Reset all animating / constrained properties + std::vectortoDelete; + for( auto&& element : mImpl->propertyResetters ) { - mImpl->root->ResetToBaseValues( bufferIndex ); + element->ResetToBaseValue( bufferIndex ); + if( element->IsFinished() ) + { + toDelete.push_back( element ); + } } - if ( mImpl->systemLevelRoot ) + + // If a resetter is no longer required (the animator or constraint has been removed), delete it. + for( auto&& elementPtr : toDelete ) { - mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex ); + mImpl->propertyResetters.EraseObject( elementPtr ); } - // Reset all the nodes + // Clear node dirty flags Vector::Iterator iter = mImpl->nodes.Begin()+1; Vector::Iterator endIter = mImpl->nodes.End(); - for(;iter != endIter; ++iter) - { - (*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 ); - } - - // 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) + for( ;iter != endIter; ++iter ) { - (*iter)->ResetToBaseValues( bufferIndex ); - } - - // Reset custom object properties to base values - for (OwnerContainer::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter) - { - (*iter)->ResetToBaseValues( bufferIndex ); - } - - mImpl->renderers.ResetToBaseValues( bufferIndex ); - - // Reset animatable shader properties to base values - for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter) - { - (*iter)->ResetToBaseValues( bufferIndex ); + (*iter)->ResetDirtyFlags( bufferIndex ); } } @@ -714,14 +675,11 @@ bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastV { 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; @@ -732,12 +690,19 @@ void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds ) AnimationContainer &animations = mImpl->animations; AnimationIter iter = animations.Begin(); bool animationLooped = false; + while ( iter != 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; @@ -757,19 +722,16 @@ 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 ); } } @@ -777,56 +739,37 @@ 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 ) + for ( auto&& task : systemLevelTasks ) { - RenderTask& task = **iter; - ConstrainPropertyOwner( task, bufferIndex ); + 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&& task : tasks ) { - RenderTask& task = **iter; - ConstrainPropertyOwner( task, bufferIndex ); + 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; - } -} - -void UpdateManager::PrepareTextureSets( BufferIndex bufferIndex ) -{ - size_t textureSetCount( mImpl->textureSets.Size() ); - for( size_t i(0); itextureSets[i]->Prepare( mImpl->resourceManager ); } } @@ -845,11 +788,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(); @@ -859,17 +800,13 @@ 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.Count(); + for( unsigned int i = 0; i < rendererCount; ++i ) { //Apply constraints - ConstrainPropertyOwner( *rendererContainer[i], bufferIndex ); + ConstrainPropertyOwner( *mImpl->renderers[i], bufferIndex ); - if( rendererContainer[i]->IsReferenced() ) - { - rendererContainer[i]->PrepareRender( bufferIndex ); - } + mImpl->renderers[i]->PrepareRender( bufferIndex ); } } @@ -886,38 +823,34 @@ void UpdateManager::UpdateNodes( BufferIndex bufferIndex ) // 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 ) { mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ), bufferIndex, - mImpl->resourceManager, mImpl->renderQueue ); } } unsigned int UpdateManager::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, - unsigned int nextVSyncTimeMilliseconds ) + unsigned int 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 @@ -930,11 +863,10 @@ unsigned int UpdateManager::Update( float elapsedSeconds, mImpl->transformManager.ResetToBaseValue(); } - //Process the queued scene messages - mImpl->messageQueue.ProcessMessages( bufferIndex ); - - //Post Process Ids of resources updated by renderer - mImpl->resourceManager.PostProcessResources( 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(); @@ -950,9 +882,6 @@ unsigned int UpdateManager::Update( float elapsedSeconds, //Constraint custom objects ConstrainCustomObjects( bufferIndex ); - //Prepare texture sets and apply constraints to them - PrepareTextureSets( bufferIndex ); - //Clear the lists of renderers from the previous update for( size_t i(0); isortedLayers.size(); ++i ) { @@ -975,35 +904,52 @@ unsigned int UpdateManager::Update( float elapsedSeconds, //Update renderers and apply constraints UpdateRenderers( bufferIndex ); - //Update the trnasformations of all the nodes + // Call the frame-callback-processor if set + if( mImpl->frameCallbackProcessor ) + { + mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds ); + } + + //Update the transformations of all the nodes mImpl->transformManager.Update(); //Process Property Notifications ProcessPropertyNotifications( bufferIndex ); - //Process the RenderTasks; 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() ); + //Update cameras + for( auto&& cameraIterator : mImpl->cameras ) + { + cameraIterator->Update( bufferIndex ); + } - if ( NULL != mImpl->root ) + //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 + if( mImpl->renderersAdded ) { - ProcessRenderTasks( bufferIndex, - mImpl->taskList, - *mImpl->root, - mImpl->sortedLayers, - mImpl->renderSortingHelper, - mImpl->renderInstructions ); - - // Process the system-level RenderTasks last - if ( NULL != mImpl->systemLevelRoot ) + mImpl->renderInstructions.ResetAndReserve( bufferIndex, + mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() ); + + if ( NULL != mImpl->root ) { - ProcessRenderTasks( bufferIndex, - mImpl->systemLevelTaskList, - *mImpl->systemLevelRoot, - mImpl->systemLevelSortedLayers, - mImpl->renderSortingHelper, - mImpl->renderInstructions ); + mImpl->renderTaskProcessor.Process( bufferIndex, + mImpl->taskList, + *mImpl->root, + mImpl->sortedLayers, + mImpl->renderInstructions, + renderToFboEnabled, + isRenderingToFbo ); + + // Process the system-level RenderTasks last + if ( NULL != mImpl->systemLevelRoot ) + { + mImpl->renderTaskProcessor.Process( bufferIndex, + mImpl->systemLevelTaskList, + *mImpl->systemLevelRoot, + mImpl->systemLevelSortedLayers, + mImpl->renderInstructions, + renderToFboEnabled, + isRenderingToFbo ); + } } } } @@ -1011,21 +957,17 @@ unsigned int UpdateManager::Update( float elapsedSeconds, // 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 ) + for ( auto&& renderTask : mImpl->taskList.GetTasks() ) { - RenderTask& renderTask(*(*iter)); + renderTask->UpdateState(); - renderTask.UpdateState(); - - if( renderTask.IsWaitingToRender() && - renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ ) + 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() ) + if( renderTask->HasRendered() ) { doRenderOnceNotify = true; } @@ -1065,13 +1007,15 @@ unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const unsigned int 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; } @@ -1103,6 +1047,8 @@ void UpdateManager::SetBackgroundColor( const Vector4& color ) void UpdateManager::SetDefaultSurfaceRect( const Rect& rect ) { + mImpl->surfaceRectChanged = true; + typedef MessageValue1< RenderManager, Rect > DerivedType; // Reserve some memory inside the render queue @@ -1117,6 +1063,11 @@ void UpdateManager::KeepRendering( float durationSeconds ) mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds ); } +void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior ) +{ + mImpl->renderingBehavior = renderingBehavior; +} + void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel ) { if ( !systemLevel ) @@ -1130,14 +1081,43 @@ void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool syst } } -void UpdateManager::SetShaderSaver( ShaderSaver& upstream ) +void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths ) { - mImpl->shaderSaver = &upstream; + // 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 ) + { + iter.node->SetDepthIndex( iter.sortedDepth ); + } + + // Go through node hierarchy and rearrange siblings according to depth-index + SortSiblingNodesRecursively( *( mImpl->root ) ); } -void UpdateManager::AddSampler( Render::Sampler* sampler ) +bool UpdateManager::IsDefaultSurfaceRectChanged() { - typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType; + bool surfaceRectChanged = mImpl->surfaceRectChanged; + + // Reset the flag + mImpl->surfaceRectChanged = false; + + return surfaceRectChanged; +} + +void UpdateManager::AddFrameCallback( FrameCallbackInterface* frameCallback, const Node* rootNode ) +{ + mImpl->GetFrameCallbackProcessor().AddFrameCallback( frameCallback, rootNode ); +} + +void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback ) +{ + mImpl->GetFrameCallbackProcessor().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 ) ); @@ -1168,20 +1148,21 @@ void UpdateManager::SetFilterMode( Render::Sampler* sampler, unsigned int minFil new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode ); } -void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int uWrapMode, unsigned int vWrapMode ) +void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode ) { - typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType; + typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > 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::SetWrapMode, sampler, uWrapMode, vWrapMode ); + 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 ) ); @@ -1201,9 +1182,10 @@ void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer 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 ) ); @@ -1212,9 +1194,10 @@ void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuff 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, size_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 >, size_t > DerivedType; // Reserve some memory inside the render queue unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); @@ -1223,9 +1206,10 @@ void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffe 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 ) ); @@ -1278,7 +1262,7 @@ void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::Prop 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; @@ -1286,9 +1270,86 @@ void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::Propert 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::AddVertexBuffer, geometry, propertyBuffer ); + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, propertyBuffer ); +} + +void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture ) +{ + // 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 ) ); + + // 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 ); +} + +void UpdateManager::RemoveTexture( Render::Texture* texture) +{ + typedef MessageValue1< RenderManager, Render::Texture* > 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::RemoveTexture, texture ); +} + +void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params ) +{ + 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 ) ); + + // 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::Texture* texture ) +{ + typedef MessageValue1< RenderManager, Render::Texture* > 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::GenerateMipmaps, texture ); +} + +void UpdateManager::AddFrameBuffer( 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 ) ); + + // 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 ); +} + +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 ) ); + + // 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::Texture* texture, unsigned int mipmapLevel, unsigned int layer ) +{ + typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, unsigned int, unsigned int > 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::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer ); +} } // namespace SceneGraph