/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
// INTERNAL INCLUDES
#include <dali/public-api/common/stage.h>
-#include <dali/devel-api/common/set-wrapper.h>
-#include <dali/devel-api/common/mutex.h>
#include <dali/devel-api/common/owner-container.h>
+#include <dali/devel-api/threading/mutex.h>
#include <dali/integration-api/core.h>
#include <dali/integration-api/render-controller.h>
#include <dali/internal/event/common/property-notification-impl.h>
#include <dali/internal/event/common/property-notifier.h>
#include <dali/internal/event/effects/shader-factory.h>
+#include <dali/internal/event/animation/animation-playlist.h>
#include <dali/internal/update/animation/scene-graph-animator.h>
#include <dali/internal/update/animation/scene-graph-animation.h>
#include <dali/internal/update/common/discard-queue.h>
#include <dali/internal/update/common/scene-graph-buffers.h>
-#include <dali/internal/update/common/scene-graph-property-buffer.h>
#include <dali/internal/update/controllers/render-message-dispatcher.h>
#include <dali/internal/update/controllers/scene-controller-impl.h>
#include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
-#include <dali/internal/update/manager/object-owner-container.h>
-#include <dali/internal/update/manager/prepare-render-algorithms.h>
-#include <dali/internal/update/manager/process-render-tasks.h>
+#include <dali/internal/update/manager/frame-callback-processor.h>
+#include <dali/internal/update/manager/render-task-processor.h>
#include <dali/internal/update/manager/sorted-layers.h>
+#include <dali/internal/update/manager/scene-graph-frame-callback.h>
#include <dali/internal/update/manager/update-algorithms.h>
#include <dali/internal/update/manager/update-manager-debug.h>
-#include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
-#include <dali/internal/update/node-attachments/scene-graph-image-attachment.h>
+#include <dali/internal/update/manager/transform-manager.h>
#include <dali/internal/update/nodes/node.h>
#include <dali/internal/update/nodes/scene-graph-layer.h>
#include <dali/internal/update/queue/update-message-queue.h>
#include <dali/internal/update/render-tasks/scene-graph-render-task.h>
#include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
-#include <dali/internal/update/rendering/scene-graph-material.h>
-#include <dali/internal/update/rendering/scene-graph-geometry.h>
-#include <dali/internal/update/resources/resource-manager.h>
-#include <dali/internal/update/resources/complete-status-manager.h>
-#include <dali/internal/update/touch/touch-resampler.h>
+#include <dali/internal/update/render-tasks/scene-graph-camera.h>
#include <dali/internal/render/common/render-instruction-container.h>
#include <dali/internal/render/common/render-manager.h>
#include <dali/internal/render/queue/render-queue.h>
-#include <dali/internal/render/common/performance-monitor.h>
-#include <dali/internal/render/gl-resources/texture-cache.h>
#include <dali/internal/render/shaders/scene-graph-shader.h>
-#include <dali/internal/render/renderers/render-sampler.h>
// Un-comment to enable node tree debug logging
//#define NODE_TREE_LOGGING 1
#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++;
#if defined(DEBUG_ENABLED)
extern Debug::Filter* gRenderTaskLogFilter;
+namespace
+{
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_UPDATE_MANAGER" );
+} // unnamed namespace
#endif
namespace
{
-
-void DestroyNodeSet( std::set<Node*>& nodeSet )
+/**
+ * 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<T*>& container, T* object, DiscardQueue& discardQueue, BufferIndex updateBufferIndex )
{
- for( std::set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter )
- {
- Node* node( *iter );
-
- // Call Node::OnDestroy as each node is destroyed
- node->OnDestroy();
+ DALI_ASSERT_DEBUG( object && "NULL object not allowed" );
- delete node;
+ // 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
+ }
}
- nodeSet.clear();
}
-} //namespace
-
-typedef OwnerContainer< Shader* > ShaderContainer;
-typedef ShaderContainer::Iterator ShaderIter;
-typedef ShaderContainer::ConstIterator ShaderConstIter;
-
-typedef std::vector<Internal::ShaderDataPtr> 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<PanGesture*> GestureContainer;
-typedef GestureContainer::Iterator GestureIter;
-typedef GestureContainer::ConstIterator GestureConstIter;
+ // Descend tree and sort as well
+ for( auto&& iter : container )
+ {
+ SortSiblingNodesRecursively( *iter );
+ }
+}
+} // 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)
+ };
+
Impl( NotificationManager& notificationManager,
- GlSyncAbstraction& glSyncAbstraction,
- CompleteNotificationInterface& animationFinishedNotifier,
+ CompleteNotificationInterface& animationPlaylist,
PropertyNotifier& propertyNotifier,
- ResourceManager& resourceManager,
DiscardQueue& discardQueue,
RenderController& renderController,
RenderManager& renderManager,
RenderQueue& renderQueue,
- TextureCache& textureCache,
- TouchResampler& touchResampler,
- SceneGraphBuffers& sceneGraphBuffers )
- :
- renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
+ SceneGraphBuffers& sceneGraphBuffers,
+ RenderTaskProcessor& renderTaskProcessor,
+ bool partialUpdateAvailable )
+ : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
notificationManager( notificationManager ),
- animationFinishedNotifier( animationFinishedNotifier ),
+ transformManager(),
+ animationPlaylist( animationPlaylist ),
propertyNotifier( propertyNotifier ),
shaderSaver( NULL ),
- resourceManager( resourceManager ),
discardQueue( discardQueue ),
renderController( renderController ),
sceneController( NULL ),
renderManager( renderManager ),
renderQueue( renderQueue ),
renderInstructions( renderManager.GetRenderInstructionContainer() ),
- completeStatusManager( glSyncAbstraction, renderMessageDispatcher, resourceManager ),
- touchResampler( touchResampler ),
+ renderTaskProcessor( renderTaskProcessor ),
backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
- taskList ( completeStatusManager ),
- systemLevelTaskList ( completeStatusManager ),
- root( NULL ),
- systemLevelRoot( NULL ),
- renderers( sceneGraphBuffers, discardQueue ),
- geometries( sceneGraphBuffers, discardQueue ),
- materials( sceneGraphBuffers, discardQueue ),
- propertyBuffers( 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 ),
- renderSortingHelper(),
- renderTaskWaiting( false )
+ renderTaskWaiting( false ),
+ renderersAdded( false ),
+ surfaceRectChanged( false ),
+ partialUpdateAvailable( partialUpdateAvailable )
{
- sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager );
+ sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
- renderers.SetSceneController( *sceneController );
- geometries.SetSceneController( *sceneController );
- materials.SetSceneController( *sceneController );
- propertyBuffers.SetSceneController( *sceneController );
+ // create first 'dummy' node
+ nodes.PushBack(0u);
}
~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
- DestroyNodeSet( activeDisconnectedNodes );
- DestroyNodeSet( connectedNodes );
- DestroyNodeSet( disconnectedNodes );
-
- // If there is root, reset it, otherwise do nothing as rendering was never started
- if( root )
+ // UpdateManager owns the Nodes. Although Nodes are pool allocated they contain heap allocated parts
+ // like custom properties, which get released here
+ Vector<Node*>::Iterator iter = nodes.Begin()+1;
+ Vector<Node*>::Iterator endIter = nodes.End();
+ for(;iter!=endIter;++iter)
{
- root->OnDestroy();
-
- delete root;
- root = NULL;
+ (*iter)->OnDestroy();
+ 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();
- sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove
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.
- 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
- CompleteStatusManager completeStatusManager; ///< Complete Status Manager
- TouchResampler& touchResampler; ///< Used to resample touch events on every update.
-
- 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
- std::set< Node* > activeDisconnectedNodes; ///< A container of new or modified nodes (without parent) owned by UpdateManager
- std::set< Node* > connectedNodes; ///< A container of connected (with parent) nodes owned by UpdateManager
- std::set< Node* > disconnectedNodes; ///< A container of inactive disconnected nodes (without parent) owned by UpdateManager
-
- SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
- SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
-
- 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<Renderer> renderers;
- ObjectOwnerContainer<Geometry> geometries; ///< A container of geometries
- ObjectOwnerContainer<Material> materials; ///< A container of materials
- ObjectOwnerContainer<PropertyBuffer> propertyBuffers; ///< A container of property buffers
-
- 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.
- RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers
+ /**
+ * 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
+ 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.
+
+ using SceneInfoPtr = std::unique_ptr< SceneInfo >;
+ std::vector< SceneInfoPtr > scenes; ///< A container of SceneInfo.
+
+ Vector<Node*> 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<Internal::ShaderDataPtr> renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread.
+ std::vector<Internal::ShaderDataPtr> updateCompiledShaders; ///< Shaders to be sent from Update to Event
+ Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
+
+ OwnerPointer<FrameCallbackProcessor> 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
+ bool partialUpdateAvailable; ///< Whether the partial update is available
+
+private:
+
+ Impl( const Impl& ); ///< Undefined
+ Impl& operator=( const Impl& ); ///< Undefined
};
UpdateManager::UpdateManager( NotificationManager& notificationManager,
- GlSyncAbstraction& glSyncAbstraction,
CompleteNotificationInterface& animationFinishedNotifier,
PropertyNotifier& propertyNotifier,
- ResourceManager& resourceManager,
DiscardQueue& discardQueue,
RenderController& controller,
RenderManager& renderManager,
RenderQueue& renderQueue,
- TextureCache& textureCache,
- TouchResampler& touchResampler )
+ RenderTaskProcessor& renderTaskProcessor,
+ bool partialUpdateAvailable )
: mImpl(NULL)
{
mImpl = new Impl( notificationManager,
- glSyncAbstraction,
animationFinishedNotifier,
propertyNotifier,
- resourceManager,
discardQueue,
controller,
renderManager,
renderQueue,
- textureCache,
- touchResampler,
- mSceneGraphBuffers );
+ mSceneGraphBuffers,
+ renderTaskProcessor,
+ partialUpdateAvailable );
- textureCache.SetBufferIndices( &mSceneGraphBuffers );
}
UpdateManager::~UpdateManager()
delete mImpl;
}
-void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel )
+void UpdateManager::InstallRoot( OwnerPointer<Layer>& 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;
- }
- 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;
+ 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>& node )
{
- DALI_ASSERT_ALWAYS( NULL != node );
DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
- mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node
+ // Nodes must be sorted by pointer
+ Node* rawNode = node.Release();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddNode\n", rawNode );
+
+ Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
+ for( Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter )
+ {
+ if( rawNode > (*iter) )
+ {
+ mImpl->nodes.Insert((iter+1), rawNode );
+ rawNode->CreateTransform( &mImpl->transformManager );
+ rawNode->SetPartialUpdateAvailable( mImpl->partialUpdateAvailable );
+ return;
+ }
+ }
}
void UpdateManager::ConnectNode( Node* parent, Node* node )
DALI_ASSERT_ALWAYS( NULL != node );
DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
- // Move from active/disconnectedNodes to connectedNodes
- std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
- if( !removed )
- {
- removed = mImpl->disconnectedNodes.erase( node );
- DALI_ASSERT_ALWAYS( removed );
- }
- mImpl->connectedNodes.insert( node );
-
- node->SetActive( true );
+ DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] ConnectNode\n", node );
parent->ConnectChild( node );
+
+ parent->SetPropertyDirty( true );
+
+ // 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
-
- // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame)
- parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes );
-}
+ parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused
-void UpdateManager::SetNodeActive( Node* node )
-{
- DALI_ASSERT_ALWAYS( NULL != node );
- DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
+ parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
- // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame)
- std::set<Node*>::size_type removed = mImpl->disconnectedNodes.erase( node );
- DALI_ASSERT_ALWAYS( removed );
- mImpl->activeDisconnectedNodes.insert( node );
-
- node->SetActive( true );
+ // Inform the frame-callback-processor, if set, about the node-hierarchy changing
+ if( mImpl->frameCallbackProcessor )
+ {
+ mImpl->frameCallbackProcessor->NodeHierarchyChanged();
+ }
}
void UpdateManager::DestroyNode( Node* node )
DALI_ASSERT_ALWAYS( NULL != node );
DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
- // Transfer ownership from new/disconnectedNodes to the discard queue
- // This keeps the nodes alive, until the render-thread has finished with them
- std::set<Node*>::size_type removed = mImpl->activeDisconnectedNodes.erase( node );
- if( !removed )
+ DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DestroyNode\n", node );
+
+ Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
+ Vector<Node*>::Iterator endIter = mImpl->nodes.End();
+ for(;iter!=endIter;++iter)
{
- removed = mImpl->disconnectedNodes.erase( node );
- DALI_ASSERT_ALWAYS( removed );
+ if((*iter) == node)
+ {
+ mImpl->nodes.Erase(iter);
+ break;
+ }
}
+
mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
// Notify the Node about impending destruction
node->OnDestroy();
}
-//@todo MESH_REWORK Extend to allow arbitrary scene objects to connect to each other
-void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment )
+void UpdateManager::AddCamera( OwnerPointer< Camera >& camera )
{
- DALI_ASSERT_DEBUG( node != NULL );
- DALI_ASSERT_DEBUG( attachment != NULL );
-
- // attach node to attachment first so that parent is known by the time attachment is connected
- node->Attach( *attachment ); // node takes ownership
-
- // @todo MESH_REWORK Remove after merge of SceneGraph::RenderableAttachment and SceneGraph::RendererAttachment
- if( dynamic_cast<SceneGraph::ImageAttachment*>( attachment ) != NULL )
- {
- attachment->Initialize( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
- }
+ mImpl->cameras.PushBack( camera.Release() ); // takes ownership
}
-void UpdateManager::AddObject( PropertyOwner* object )
+void UpdateManager::RemoveCamera( Camera* camera )
{
- DALI_ASSERT_DEBUG( NULL != object );
+ // Find the camera and destroy it
+ EraseUsingDiscardQueue( mImpl->cameras, camera, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
+}
- mImpl->customObjects.PushBack( object );
+void UpdateManager::AddObject( OwnerPointer<PropertyOwner>& object )
+{
+ mImpl->customObjects.PushBack( object.Release() );
}
void UpdateManager::RemoveObject( PropertyOwner* object )
{
- DALI_ASSERT_DEBUG( NULL != object );
+ mImpl->customObjects.EraseObject( object );
+}
- OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects;
+void UpdateManager::AddRenderTaskList( OwnerPointer<RenderTaskList>& taskList )
+{
+ RenderTaskList* taskListPointer = taskList.Release();
+ taskListPointer->SetRenderMessageDispatcher( &mImpl->renderMessageDispatcher );
- // Find the object and destroy it
- for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); iter != customObjects.End(); ++iter )
+ mImpl->scenes.back()->taskList = taskListPointer;
+}
+
+void UpdateManager::RemoveRenderTaskList( RenderTaskList* taskList )
+{
+ for ( auto&& scene : mImpl->scenes )
{
- PropertyOwner* current = *iter;
- if ( current == object )
+ if ( scene && scene->taskList == taskList )
{
- customObjects.Erase( iter );
- return;
+ scene->taskList.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 )
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<PropertyResetterBase>& 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 )
propertyNotification->SetNotifyMode( notifyMode );
}
-ObjectOwnerContainer<Geometry>& UpdateManager::GetGeometryOwner()
+void UpdateManager::AddShader( OwnerPointer< Shader >& shader )
{
- return mImpl->geometries;
-}
-
-ObjectOwnerContainer<Renderer>& UpdateManager::GetRendererOwner()
-{
- return mImpl->renderers;
-}
-
-
-ObjectOwnerContainer<Material>& UpdateManager::GetMaterialOwner()
-{
- return mImpl->materials;
-}
-
-ObjectOwnerContainer<PropertyBuffer>& UpdateManager::GetPropertyBufferOwner()
-{
- return mImpl->propertyBuffers;
-}
-
-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 );
-
- // Allows the shader to dispatch texture requests to the cache
- shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() );
+ 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,
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 );
}
}
-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( OwnerPointer< TextureSet >& textureSet )
+{
+ mImpl->textureSets.PushBack( textureSet.Release() );
+}
+
+void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
+{
+ 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 );
}
void UpdateManager::ResetProperties( BufferIndex bufferIndex )
{
- PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES);
-
// 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 the Connected Nodes
- const std::set<Node*>::iterator endIter = mImpl->connectedNodes.end();
- for( std::set<Node*>::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter )
+ // Reset all animating / constrained properties
+ std::vector<PropertyResetterBase*>toDelete;
+ for( auto&& element : mImpl->propertyResetters )
{
- (*iter)->ResetToBaseValues( bufferIndex );
- }
-
- // If a Node is disconnected, it may still be "active" (requires a reset in next frame)
- for( std::set<Node*>::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() )
- {
- Node* node = *iter;
- node->ResetToBaseValues( bufferIndex );
- node->SetActive( false );
-
- // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again)
- mImpl->activeDisconnectedNodes.erase( iter );
- mImpl->disconnectedNodes.insert( node );
- }
-
- // 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<PropertyOwner*>::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->materials.ResetToBaseValues( bufferIndex );
- mImpl->geometries.ResetToBaseValues( bufferIndex );
- mImpl->propertyBuffers.ResetToBaseValues( 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<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
+ Vector<Node*>::Iterator endIter = mImpl->nodes.End();
+ for( ;iter != endIter; ++iter )
{
- (*iter)->ResetToBaseValues( bufferIndex );
+ (*iter)->ResetDirtyFlags( bufferIndex );
}
-
- PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES);
}
-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;
void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
{
- PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES);
+ auto&& iter = mImpl->animations.Begin();
+ bool animationLooped = false;
- AnimationContainer &animations = mImpl->animations;
- AnimationIter iter = animations.Begin();
- while ( iter != animations.End() )
+ while ( iter != mImpl->animations.End() )
{
Animation* animation = *iter;
- bool finished = animation->Update( bufferIndex, elapsedSeconds );
+ bool finished = false;
+ bool looped = false;
+ 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;
// 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
{
}
}
- if ( mImpl->animationFinishedDuringUpdate )
+ // queue the notification on finished or looped (to update loop count)
+ if ( mImpl->animationFinishedDuringUpdate || animationLooped )
{
// The application should be notified by NotificationManager, in another thread
- mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier );
+ mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
}
-
- PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES);
}
-void UpdateManager::ApplyConstraints( BufferIndex bufferIndex )
+void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
{
- PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS);
-
- // 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 )
- {
- PropertyOwner& object = **iter;
- ConstrainPropertyOwner( object, bufferIndex );
- }
-
- // constrain nodes... (in Depth First traversal order)
- if ( mImpl->root )
- {
- ConstrainNodes( *(mImpl->root), bufferIndex );
- }
-
- if ( mImpl->systemLevelRoot )
- {
- ConstrainNodes( *(mImpl->systemLevelRoot), bufferIndex );
- }
-
- // constrain other property-owners after nodes as they are more likely to depend on a node's
- // current frame property than vice versa. They tend to be final constraints (no further
- // constraints depend on their properties)
- // e.g. ShaderEffect uniform a function of Actor's position.
- // Mesh vertex a function of Actor's position or world position.
-
- // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners
- // they can be all processed in a super-list of property-owners.
-
- // Constrain system-level render-tasks
- const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
-
- for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter )
+ //Constrain custom objects (in construction order)
+ for ( auto&& object : mImpl->customObjects )
{
- RenderTask& task = **iter;
- ConstrainPropertyOwner( task, bufferIndex );
+ ConstrainPropertyOwner( *object, bufferIndex );
}
+}
+void UpdateManager::ConstrainRenderTasks( BufferIndex 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 );
+ }
+ }
}
+}
- // Constrain Materials and geometries
- mImpl->materials.ConstrainObjects( bufferIndex );
- mImpl->geometries.ConstrainObjects( bufferIndex );
- mImpl->propertyBuffers.ConstrainObjects( bufferIndex );
- mImpl->renderers.ConstrainObjects( 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 );
}
-
- PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS);
}
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;
}
}
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();
void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
{
- const OwnerContainer<Renderer*>& rendererContainer( mImpl->renderers.GetObjectContainer() );
- unsigned int rendererCount( rendererContainer.Size() );
- for( unsigned int i(0); i<rendererCount; ++i )
+ for( auto&& renderer : mImpl->renderers )
{
- if( rendererContainer[i]->IsReferenced() )
- {
- rendererContainer[i]->PrepareResources(bufferIndex, mImpl->resourceManager);
- rendererContainer[i]->PrepareRender( bufferIndex );
- }
+ //Apply constraints
+ ConstrainPropertyOwner( *renderer, bufferIndex );
+
+ renderer->PrepareRender( bufferIndex );
}
}
void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
{
- mImpl->nodeDirtyFlags = NothingFlag;
+ mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
- if ( !mImpl->root )
+ for ( auto&& scene : mImpl->scenes )
{
- return;
- }
-
- PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
-
- // Prepare resources, update shaders, update attachments, for each node
- // And add the renderers to the sorted layers. Start from root, which is also a layer
- mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
- bufferIndex,
- mImpl->resourceManager,
- mImpl->renderQueue );
-
- if ( mImpl->systemLevelRoot )
- {
- mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( 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 );
+ }
}
-
- PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
}
-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 )
{
- PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE); // Mark the End of the last frame
- PERF_MONITOR_NEXT_FRAME(); // Prints out performance info for the last frame (if enabled)
- PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame
-
- // Measure the time spent in UpdateManager::Update
- PERF_MONITOR_START(PerformanceMonitor::UPDATE);
-
const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
- // Update the frame time delta on the render thread.
- mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds);
-
- // 1) Clear nodes/resources which were previously discarded
+ //Clear nodes/resources which were previously discarded
mImpl->discardQueue.Clear( bufferIndex );
- // 2) Grab any loaded resources
- bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex );
-
- // 3) Process Touches & Gestures
- mImpl->touchResampler.Update();
+ //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.
if( updateScene || mImpl->previousUpdateScene )
{
- // 4) Reset properties from the previous update
+ //Reset properties from the previous update
ResetProperties( bufferIndex );
+ mImpl->transformManager.ResetToBaseValue();
}
- // 5) Process the queued scene messages
- mImpl->messageQueue.ProcessMessages( bufferIndex );
-
- // 6) 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 );
- // 6.1) Forward compiled shader programs to event thread for saving
+ //Forward compiled shader programs to event thread for saving
ForwardCompiledShadersToEventThread();
// Although the scene-graph may not require an update, we still need to synchronize double-buffered
// We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
if( updateScene || mImpl->previousUpdateScene )
{
- // 7) Animate
+ //Animate
Animate( bufferIndex, elapsedSeconds );
- // 8) Apply Constraints
- ApplyConstraints( bufferIndex );
+ //Constraint custom objects
+ ConstrainCustomObjects( bufferIndex );
- // 9) Check Property Notifications
- ProcessPropertyNotifications( bufferIndex );
+ //Clear the lists of renderers from the previous update
+ for( auto&& scene : mImpl->scenes )
+ {
+ if ( scene )
+ {
+ for( auto&& layer : scene->sortedLayerList )
+ {
+ if ( layer )
+ {
+ layer->ClearRenderables();
+ }
+ }
+ }
+ }
- // 10) Clear the lists of renderable-attachments from the previous update
- ClearRenderables( mImpl->sortedLayers );
- ClearRenderables( mImpl->systemLevelSortedLayers );
+ // Call the frame-callback-processor if set
+ if( mImpl->frameCallbackProcessor )
+ {
+ mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
+ }
- // 11) Update node hierarchy and perform sorting / culling.
- // This will populate each Layer with a list of renderers which are ready.
+ //Update node hierarchy, apply constraints and perform sorting / culling.
+ //This will populate each Layer with a list of renderers which are ready.
UpdateNodes( bufferIndex );
- UpdateRenderers( bufferIndex );
+ //Apply constraints to RenderTasks, shaders
+ ConstrainRenderTasks( bufferIndex );
+ ConstrainShaders( bufferIndex );
- // 12) Prepare for the next render
- PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES);
+ //Update renderers and apply constraints
+ UpdateRenderers( bufferIndex );
- PrepareRenderables( bufferIndex, mImpl->sortedLayers );
- PrepareRenderables( bufferIndex, mImpl->systemLevelSortedLayers );
- PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES);
+ //Update the transformations of all the nodes
+ mImpl->transformManager.Update();
- PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS);
+ //Process Property Notifications
+ ProcessPropertyNotifications( bufferIndex );
- // 14) 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->completeStatusManager,
- mImpl->taskList,
- *mImpl->root,
- mImpl->sortedLayers,
- mImpl->renderSortingHelper,
- 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 )
{
- ProcessRenderTasks( bufferIndex,
- mImpl->completeStatusManager,
- mImpl->systemLevelTaskList,
- *mImpl->systemLevelRoot,
- mImpl->systemLevelSortedLayers,
- mImpl->renderSortingHelper,
- 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));
+ mImpl->renderInstructions.ResetAndReserve( bufferIndex,
+ static_cast<uint32_t>( numberOfRenderTasks ) );
- 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
- }
+ for ( auto&& scene : mImpl->scenes )
+ {
+ if ( scene && scene->root && scene->taskList )
+ {
+ keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
+ *scene->taskList,
+ *scene->root,
+ scene->sortedLayerList,
+ mImpl->renderInstructions,
+ renderToFboEnabled,
+ isRenderingToFbo );
+ }
+ }
- if( renderTask.HasRendered() )
- {
- doRenderOnceNotify = true;
+ DALI_LOG_INFO( gLogFilter, Debug::General,
+ "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n",
+ numberOfRenderTasks, mImpl->renderInstructions.Count( bufferIndex ) );
}
}
- 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();
- PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS);
+ // 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.
SNAPSHOT_NODE_LOGGING;
mImpl->previousUpdateScene = updateScene;
// Check whether further updates are required
- unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
+ uint32_t keepUpdating = KeepUpdatingCheck( elapsedSeconds );
-#ifdef PERFORMANCE_MONITOR_ENABLED
- // Always keep rendering when measuring FPS
- keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE;
-#endif
+ if( keepRendererRendering )
+ {
+ keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
+ }
// tell the update manager that we're done so the queue can be given to event thread
mImpl->notificationManager.UpdateCompleted();
// The update has finished; swap the double-buffering indices
mSceneGraphBuffers.Swap();
- PERF_MONITOR_END(PerformanceMonitor::UPDATE);
-
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 )
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;
}
typedef MessageValue1< RenderManager, Vector4 > 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 );
}
-void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
+void UpdateManager::SetDefaultSurfaceRect( const Rect<int32_t>& rect )
{
- typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
+ mImpl->surfaceRectChanged = true;
+
+ typedef MessageValue1< RenderManager, Rect<int32_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::SetDefaultSurfaceRect, rect );
}
+void UpdateManager::SetDefaultSurfaceOrientation( int orientation )
+{
+ typedef MessageValue1< RenderManager, 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::SetDefaultSurfaceOrientation, orientation );
+}
+
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 )
{
- if ( !systemLevel )
+ for ( auto&& scene : mImpl->scenes )
{
- // just copy the vector of pointers
- mImpl->sortedLayers = layers;
+ if ( scene && scene->root == rootLayer )
+ {
+ scene->sortedLayerList = layers;
+ break;
+ }
}
- else
+}
+
+void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
+{
+ // 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 );
+ }
+
+ 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 );
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 uWrapMode, unsigned int vWrapMode )
+void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
{
- typedef MessageValue3< RenderManager, Render::Sampler*, 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( OwnerPointer< Render::PropertyBuffer >& propertyBuffer )
+{
+ // 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
+ 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 );
+}
+
+void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
+{
+ typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
+
+ // 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::RemovePropertyBuffer, propertyBuffer );
+}
+
+void UpdateManager::SetPropertyBufferFormat( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Render::PropertyBuffer::Format>& format )
+{
+ // 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
+ 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, OwnerPointer< Vector<uint8_t> >& data, uint32_t size )
+{
+ // Message has ownership of format while in transit from update -> render
+ typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<uint8_t> >, uint32_t > DerivedType;
+
+ // 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::SetPropertyBufferData, propertyBuffer, data, size );
+}
+
+void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
+{
+ // 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
+ 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 );
+}
+
+void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
+{
+ typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
+
+ // 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::RemoveGeometry, geometry );
+}
+
+void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
+{
+ typedef MessageValue2< RenderManager, Render::Geometry*, uint32_t > DerivedType;
+
+ // 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::SetGeometryType, geometry, geometryType );
+}
+
+void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
+{
+ typedef IndexBufferMessage< RenderManager > DerivedType;
+
+ // 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, geometry, indices );
+}
+
+void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
+{
+ typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
+
+ // 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::RemoveVertexBuffer, geometry, 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
+ 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::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
+ 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 );
+}
+
+void UpdateManager::RemoveTexture( Render::Texture* texture)
+{
+ typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
+
+ // 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::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
+ 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::Texture* texture )
+{
+ typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
+
+ // 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::GenerateMipmaps, texture );
+}
+
+void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
+{
+ typedef MessageValue1< RenderManager, OwnerPointer< Render::FrameBuffer > > DerivedType;
+
+ // 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::AddFrameBuffer, frameBuffer );
+}
+
+void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
+{
+ typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
+
+ // 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::RemoveFrameBuffer, frameBuffer );
+}
+
+void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
+{
+ typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t > DerivedType;
+
+ // 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::SetWrapMode, sampler, uWrapMode, vWrapMode );
+ new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
}
} // namespace SceneGraph