/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
#include <dali/internal/update/manager/update-manager.h>
// INTERNAL INCLUDES
-#include <dali/public-api/common/stage.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/common/shader-data.h>
-#include <dali/integration-api/debug.h>
-#include <dali/internal/common/core-impl.h>
-#include <dali/internal/common/message.h>
+#include <dali/internal/common/owner-key-container.h>
+#include <dali/internal/event/animation/animation-playlist.h>
#include <dali/internal/event/common/notification-manager.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/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/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/transform-manager.h>
#include <dali/internal/update/manager/update-algorithms.h>
#include <dali/internal/update/manager/update-manager-debug.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/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/shaders/scene-graph-shader.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;\
-if( mImpl->frameCounter >= FRAME_COUNT_TRIGGER )\
- {\
- if ( NULL != mImpl->root )\
- {\
- mImpl->frameCounter = 0;\
- PrintNodeTree( *mImpl->root, mSceneGraphBuffers.GetUpdateBufferIndex(), "" );\
- }\
- }\
-mImpl->frameCounter++;
+#if(defined(DEBUG_ENABLED) && defined(NODE_TREE_LOGGING))
+#define SNAPSHOT_NODE_LOGGING \
+ const uint32_t FRAME_COUNT_TRIGGER = 16; \
+ if(mImpl->frameCounter >= FRAME_COUNT_TRIGGER) \
+ { \
+ for(auto&& scene : mImpl->scenes) \
+ { \
+ if(scene && scene->root) \
+ { \
+ mImpl->frameCounter = 0; \
+ PrintNodes(*scene->root, mSceneGraphBuffers.GetUpdateBufferIndex(), 0); \
+ } \
+ } \
+ } \
+ mImpl->frameCounter++;
#else
#define SNAPSHOT_NODE_LOGGING
#endif
#if defined(DEBUG_ENABLED)
extern Debug::Filter* gRenderTaskLogFilter;
+namespace
+{
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_UPDATE_MANAGER");
+} // unnamed namespace
#endif
-
using namespace Dali::Integration;
using Dali::Internal::Update::MessageQueue;
namespace Dali
{
-
namespace Internal
{
-
namespace SceneGraph
{
-
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<T*>& 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<T*>& container, T* object, DiscardQueue& discardQueue, BufferIndex updateBufferIndex )
+template<class Type>
+inline void EraseUsingDiscardQueue(OwnerContainer<Type*>& container, Type* object, DiscardQueue<Type*, OwnerContainer<Type*>>& discardQueue, BufferIndex updateBufferIndex)
{
- DALI_ASSERT_DEBUG( object && "NULL object not allowed" );
+ 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 )
+ for(auto&& iter : container)
{
- if ( iter == object )
+ 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
+ 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
}
}
}
/**
- * 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
+ * Helper to Erase an object from std::vector using discard queue
+ * @param container to remove from
+ * @param object to remove
+ * @param discardQueue to put the object to
+ * @param updateBufferIndex to use
*/
-void SortSiblingNodesRecursively( Node& node )
+template<class Type>
+inline void EraseUsingDiscardQueue(OwnerKeyContainer<Type>& container, const MemoryPoolKey<Type>& key, DiscardQueue<MemoryPoolKey<Type>, OwnerKeyContainer<Type>>& discardQueue, BufferIndex updateBufferIndex)
{
- NodeContainer& container = node.GetChildren();
- std::sort( container.Begin(), container.End(),
- []( Node* a, Node* b ) { return a->GetDepthIndex() < b->GetDepthIndex(); } );
+ DALI_ASSERT_DEBUG(key && "INVALID Key not allowed");
- // Descend tree and sort as well
- for( auto&& iter : container )
+ for(auto iter = container.begin(), end = container.end(); iter != end; ++iter)
{
- SortSiblingNodesRecursively( *iter );
+ if(*iter == key)
+ {
+ // 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));
+ return; // return as we only ever remove one object. Iterators to container are now invalidated as well so cannot continue
+ }
}
}
*/
struct UpdateManager::Impl
{
- Impl( NotificationManager& notificationManager,
- CompleteNotificationInterface& animationPlaylist,
- PropertyNotifier& propertyNotifier,
- DiscardQueue& discardQueue,
- RenderController& renderController,
- RenderManager& renderManager,
- RenderQueue& renderQueue,
- SceneGraphBuffers& sceneGraphBuffers,
- RenderTaskProcessor& renderTaskProcessor )
- : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ),
- notificationManager( notificationManager ),
+ // SceneInfo keeps the root node of the Scene, its scene graph render task list, and the list of Layer pointers sorted by depth
+ struct SceneInfo
+ {
+ SceneInfo(Layer* root) ///< Constructor
+ : root(root)
+ {
+ }
+
+ ~SceneInfo() = default; ///< Default non-virtual destructor
+ SceneInfo(SceneInfo&& rhs) = default; ///< Move constructor
+ SceneInfo& operator=(SceneInfo&& rhs) = default; ///< Move assignment operator
+ SceneInfo& operator=(const SceneInfo& rhs) = delete; ///< Assignment operator
+ SceneInfo(const SceneInfo& rhs) = delete; ///< Copy constructor
+
+ Layer* root{nullptr}; ///< Root node (root is a layer). The layer is not stored in the node memory pool.
+ OwnerPointer<RenderTaskList> taskList; ///< Scene graph render task list
+ SortedLayerPointers sortedLayerList; ///< List of Layer pointers sorted by depth (one list of sorted layers per root)
+ OwnerPointer<Scene> scene; ///< Scene graph object of the scene
+ };
+
+ Impl(NotificationManager& notificationManager,
+ CompleteNotificationInterface& animationPlaylist,
+ PropertyNotifier& propertyNotifier,
+ RenderController& renderController,
+ RenderManager& renderManager,
+ RenderQueue& renderQueue,
+ SceneGraphBuffers& sceneGraphBuffers,
+ RenderTaskProcessor& renderTaskProcessor)
+ : renderMessageDispatcher(renderManager, renderQueue, sceneGraphBuffers),
+ notificationManager(notificationManager),
transformManager(),
- animationPlaylist( animationPlaylist ),
- propertyNotifier( propertyNotifier ),
- shaderSaver( NULL ),
- discardQueue( discardQueue ),
- renderController( renderController ),
- sceneController( NULL ),
- renderManager( renderManager ),
- renderQueue( renderQueue ),
- renderInstructions( renderManager.GetRenderInstructionContainer() ),
- renderTaskProcessor( renderTaskProcessor ),
- backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
- taskList( renderMessageDispatcher ),
- systemLevelTaskList( renderMessageDispatcher ),
- root( NULL ),
- systemLevelRoot( NULL ),
+ animationPlaylist(animationPlaylist),
+ propertyNotifier(propertyNotifier),
+ shaderSaver(nullptr),
+ renderController(renderController),
+ sceneController(nullptr),
+ renderManager(renderManager),
+ renderQueue(renderQueue),
+ renderTaskProcessor(renderTaskProcessor),
+ backgroundColor(Dali::DEFAULT_BACKGROUND_COLOR),
renderers(),
textureSets(),
shaders(),
- panGestureProcessor( NULL ),
- messageQueue( renderController, sceneGraphBuffers ),
- keepRenderingSeconds( 0.0f ),
- nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
- frameCounter( 0 ),
- animationFinishedDuringUpdate( false ),
- previousUpdateScene( false ),
- renderTaskWaiting( false ),
- renderersAdded( false )
+ panGestureProcessor(nullptr),
+ messageQueue(renderController, sceneGraphBuffers),
+ frameCallbackProcessor(nullptr),
+ 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),
+ previousUpdateScene(false),
+ renderTaskWaiting(false),
+ renderersAdded(false),
+ renderingRequired(false)
{
- sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
+ sceneController = new SceneControllerImpl(renderMessageDispatcher, renderQueue);
// create first 'dummy' node
- nodes.PushBack(0u);
+ nodes.PushBack(nullptr);
}
~Impl()
{
// Disconnect render tasks from nodes, before destroying the nodes
- RenderTaskList::RenderTaskContainer& tasks = taskList.GetTasks();
- for ( auto&& iter : tasks )
+ for(auto&& scene : scenes)
{
- iter->SetSourceNode( NULL );
- }
- // ..repeat for system level RenderTasks
- RenderTaskList::RenderTaskContainer& systemLevelTasks = systemLevelTaskList.GetTasks();
- for ( auto&& iter : systemLevelTasks )
- {
- iter->SetSourceNode( NULL );
+ if(scene && scene->taskList)
+ {
+ RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
+ for(auto&& task : tasks)
+ {
+ task->SetSourceNode(nullptr);
+ }
+ }
}
// 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 iter = nodes.Begin() + 1;
Vector<Node*>::Iterator endIter = nodes.End();
- for(;iter!=endIter;++iter)
+ for(; iter != endIter; ++iter)
{
(*iter)->OnDestroy();
Node::Delete(*iter);
}
- // If there is root, reset it, otherwise do nothing as rendering was never started
- if( root )
+ for(auto&& scene : scenes)
{
- root->OnDestroy();
-
- Node::Delete( root );
- root = NULL;
+ if(scene && scene->root)
+ {
+ scene->root->OnDestroy();
+ Node::Delete(scene->root);
+ }
}
+ scenes.clear();
- if( systemLevelRoot )
- {
- systemLevelRoot->OnDestroy();
+ delete sceneController;
- Node::Delete( systemLevelRoot );
- systemLevelRoot = NULL;
- }
+ // Ensure to clear renderers
+ renderers.Clear();
+ shaders.Clear();
+ }
- delete sceneController;
+ /**
+ * 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;
}
- 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
+ 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.
+ RenderController& renderController; ///< render controller
+ SceneControllerImpl* sceneController; ///< scene controller
+ RenderManager& renderManager; ///< This is responsible for rendering the results of each "update"
+ RenderQueue& renderQueue; ///< Used to queue messages for the next render
+ RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons
- Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
+ 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
+ using SceneInfoPtr = std::unique_ptr<SceneInfo>;
+ std::vector<SceneInfoPtr> scenes; ///< A container of SceneInfo.
- Layer* root; ///< The root node (root is a layer)
- Layer* systemLevelRoot; ///< A separate root-node for system-level content
+ Vector<Node*> nodes; ///< A container of all instantiated nodes
- Vector<Node*> nodes; ///< A container of all instantiated nodes
+ Vector<Camera*> cameras; ///< A container of cameras. Note : these cameras are owned by Impl::nodes.
- 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)
- 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<NodeResetter*> nodeResetters; ///< A container of node resetters
+ OwnerContainer<Animation*> animations; ///< A container of owned animations
+ PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
+ OwnerKeyContainer<Renderer> renderers; ///< A container of owned renderers
+ OwnerContainer<TextureSet*> textureSets; ///< A container of owned texture sets
+ OwnerContainer<Shader*> shaders; ///< A container of owned shaders
- AnimationContainer animations; ///< A container of owned animations
- PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
+ DiscardQueue<Node*, OwnerContainer<Node*>> nodeDiscardQueue; ///< Nodes are added here when disconnected from the scene-graph.
+ DiscardQueue<Shader*, OwnerContainer<Shader*>> shaderDiscardQueue;
+ DiscardQueue<MemoryPoolKey<Renderer>, OwnerKeyContainer<Renderer>> rendererDiscardQueue;
+ DiscardQueue<Scene*, OwnerContainer<Scene*>> sceneDiscardQueue;
- 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
+ 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
+ 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
- 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.
+ OwnerPointer<FrameCallbackProcessor> frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required.
- 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
+ std::atomic<std::size_t> renderInstructionCapacity{0u};
+ 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
-private:
+ 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 renderingRequired; ///< True if required to render the current frame
- Impl( const Impl& ); ///< Undefined
- Impl& operator=( const Impl& ); ///< Undefined
+private:
+ Impl(const Impl&); ///< Undefined
+ Impl& operator=(const Impl&); ///< Undefined
};
-UpdateManager::UpdateManager( NotificationManager& notificationManager,
- CompleteNotificationInterface& animationFinishedNotifier,
- PropertyNotifier& propertyNotifier,
- DiscardQueue& discardQueue,
- RenderController& controller,
- RenderManager& renderManager,
- RenderQueue& renderQueue,
- RenderTaskProcessor& renderTaskProcessor )
- : mImpl(NULL)
-{
- mImpl = new Impl( notificationManager,
- animationFinishedNotifier,
- propertyNotifier,
- discardQueue,
- controller,
- renderManager,
- renderQueue,
- mSceneGraphBuffers,
- renderTaskProcessor );
-
+UpdateManager::UpdateManager(NotificationManager& notificationManager,
+ CompleteNotificationInterface& animationFinishedNotifier,
+ PropertyNotifier& propertyNotifier,
+ RenderController& controller,
+ RenderManager& renderManager,
+ RenderQueue& renderQueue,
+ RenderTaskProcessor& renderTaskProcessor)
+: mImpl(nullptr)
+{
+ mImpl = new Impl(notificationManager,
+ animationFinishedNotifier,
+ propertyNotifier,
+ controller,
+ renderManager,
+ renderQueue,
+ mSceneGraphBuffers,
+ renderTaskProcessor);
}
UpdateManager::~UpdateManager()
delete mImpl;
}
-void UpdateManager::InstallRoot( OwnerPointer<Layer>& layer, bool systemLevel )
+void UpdateManager::InstallRoot(OwnerPointer<Layer>& layer)
{
- DALI_ASSERT_DEBUG( layer->IsLayer() );
- DALI_ASSERT_DEBUG( layer->GetParent() == NULL);
+ 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.Release();
- mImpl->root->CreateTransform( &mImpl->transformManager );
- mImpl->root->SetRoot(true);
- }
- 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);
+
+ AddNodeResetter(*rootLayer);
+
+ 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.Release();
- mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager );
- mImpl->systemLevelRoot->SetRoot(true);
+ if((*iter) && (*iter)->root == layer)
+ {
+ mImpl->scenes.erase(iter);
+ break;
+ }
}
+ mImpl->nodeDiscardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), layer);
+
+ // Notify the layer about impending destruction
+ layer->OnDestroy();
}
-void UpdateManager::AddNode( OwnerPointer<Node>& node )
+void UpdateManager::AddNode(OwnerPointer<Node>& node)
{
- DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
+ DALI_ASSERT_ALWAYS(nullptr == node->GetParent()); // Should not have a parent yet
- // Nodes must be sorted by pointer
Node* rawNode = node.Release();
- Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
- for( Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter )
+ DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] AddNode\n", rawNode);
+
+ // Add camera nodes occured rarely.
+ if(DALI_UNLIKELY(rawNode->IsCamera()))
{
- if( rawNode > (*iter) )
- {
- mImpl->nodes.Insert((iter+1), rawNode );
- rawNode->CreateTransform( &mImpl->transformManager );
- return;
- }
+ AddCamera(static_cast<Camera*>(rawNode));
}
+
+ mImpl->nodes.PushBack(rawNode);
+ rawNode->CreateTransform(&mImpl->transformManager);
}
-void UpdateManager::ConnectNode( Node* parent, Node* node )
+void UpdateManager::ConnectNode(Node* parent, Node* node)
{
- DALI_ASSERT_ALWAYS( NULL != parent );
- DALI_ASSERT_ALWAYS( NULL != node );
- DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
+ DALI_ASSERT_ALWAYS(nullptr != parent);
+ DALI_ASSERT_ALWAYS(nullptr != node);
+ DALI_ASSERT_ALWAYS(nullptr == node->GetParent()); // Should not have a parent yet
+
+ DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] ConnectNode\n", node);
+
+ parent->ConnectChild(node);
+
+ AddNodeResetter(*node);
- parent->ConnectChild( node );
+ // Inform the frame-callback-processor, if set, about the node-hierarchy changing
+ if(mImpl->frameCallbackProcessor)
+ {
+ mImpl->frameCallbackProcessor->NodeHierarchyChanged();
+ }
}
-void UpdateManager::DisconnectNode( Node* node )
+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
+ DALI_ASSERT_ALWAYS(nullptr != parent);
+ parent->SetDirtyFlag(NodePropertyFlags::CHILD_DELETED); // make parent dirty so that render items dont get reused
+
+ parent->DisconnectChild(mSceneGraphBuffers.GetUpdateBufferIndex(), *node);
- 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 )
+void UpdateManager::DestroyNode(Node* node)
{
- DALI_ASSERT_ALWAYS( NULL != node );
- DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
+ DALI_ASSERT_ALWAYS(nullptr != node);
+ DALI_ASSERT_ALWAYS(nullptr == node->GetParent()); // Should have been disconnected
- Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
+ 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)
+ for(; iter != endIter; ++iter)
{
if((*iter) == node)
{
}
}
- mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node );
+ // Remove camera nodes occured rarely.
+ if(DALI_UNLIKELY(node->IsCamera()))
+ {
+ RemoveCamera(static_cast<Camera*>(node));
+ }
+
+ mImpl->nodeDiscardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), node);
// Notify the Node about impending destruction
node->OnDestroy();
}
-void UpdateManager::AddCamera( OwnerPointer< Camera >& camera )
+void UpdateManager::AddCamera(Camera* camera)
{
- mImpl->cameras.PushBack( camera.Release() ); // takes ownership
+ DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] AddCamera\n", camera);
+
+ mImpl->cameras.PushBack(camera);
}
-void UpdateManager::RemoveCamera( const Camera* camera )
+void UpdateManager::RemoveCamera(Camera* camera)
{
- // Find the camera and destroy it
- EraseUsingDiscardQueue( mImpl->cameras, const_cast<Camera*>( camera ), mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
+ DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] RemoveCamera\n", camera);
+
+ // Find the camera and remove it from list of cameras
+ Vector<Camera*>::Iterator iter = mImpl->cameras.Begin();
+ Vector<Camera*>::Iterator endIter = mImpl->cameras.End();
+ for(; iter != endIter; ++iter)
+ {
+ if((*iter) == camera)
+ {
+ mImpl->cameras.Erase(iter);
+ break;
+ }
+ }
}
-void UpdateManager::AddObject( OwnerPointer<PropertyOwner>& object )
+void UpdateManager::AddObject(OwnerPointer<PropertyOwner>& object)
{
- mImpl->customObjects.PushBack( object.Release() );
+ mImpl->customObjects.PushBack(object.Release());
}
-void UpdateManager::RemoveObject( PropertyOwner* object )
+void UpdateManager::RemoveObject(PropertyOwner* object)
{
- mImpl->customObjects.EraseObject( object );
+ mImpl->customObjects.EraseObject(object);
}
-void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation )
+void UpdateManager::AddRenderTaskList(OwnerPointer<RenderTaskList>& taskList)
{
- mImpl->animations.PushBack( animation.Release() );
+ RenderTaskList* taskListPointer = taskList.Release();
+ taskListPointer->SetRenderMessageDispatcher(&mImpl->renderMessageDispatcher);
+
+ mImpl->scenes.back()->taskList = taskListPointer;
}
-void UpdateManager::StopAnimation( Animation* animation )
+void UpdateManager::RemoveRenderTaskList(RenderTaskList* taskList)
{
- DALI_ASSERT_DEBUG( animation && "NULL animation called to stop" );
+ for(auto&& scene : mImpl->scenes)
+ {
+ if(scene && scene->taskList == taskList)
+ {
+ scene->taskList.Reset();
+ break;
+ }
+ }
+}
- bool animationFinished = animation->Stop( mSceneGraphBuffers.GetUpdateBufferIndex() );
+void UpdateManager::AddScene(OwnerPointer<Scene>& scene)
+{
+ auto& sceneInfo = mImpl->scenes.back();
+ sceneInfo->scene = scene.Release();
+
+ // Set root to the Scene
+ sceneInfo->scene->SetRoot(sceneInfo->root);
+
+ // Initialize the context from render manager
+ typedef MessageValue1<RenderManager, SceneGraph::Scene*> 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
+ SceneGraph::Scene& sceneObject = *sceneInfo->scene;
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::InitializeScene, &sceneObject);
+}
+
+void UpdateManager::RemoveScene(Scene* scene)
+{
+ // Initialize the context from render manager
+ using DerivedType = MessageValue1<RenderManager, SceneGraph::Scene*>;
+
+ // Reserve some memory inside the render queue
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
+
+ // Construct message in the render queue memory; note that delete should not be called on the return value
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::UninitializeScene, scene);
+
+ for(auto&& sceneInfo : mImpl->scenes)
+ {
+ if(sceneInfo && sceneInfo->scene && sceneInfo->scene.Get() == scene)
+ {
+ mImpl->sceneDiscardQueue.Add(mSceneGraphBuffers.GetUpdateBufferIndex(), sceneInfo->scene.Release()); // take the address of the reference to a pointer
+ break;
+ }
+ }
+}
+
+void UpdateManager::AddAnimation(OwnerPointer<SceneGraph::Animation>& animation)
+{
+ mImpl->animations.PushBack(animation.Release());
+}
+
+void UpdateManager::StopAnimation(Animation* animation)
+{
+ DALI_ASSERT_DEBUG(animation && "NULL animation called to stop");
+
+ bool animationFinished = animation->Stop(mSceneGraphBuffers.GetUpdateBufferIndex());
mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || animationFinished;
}
-void UpdateManager::RemoveAnimation( Animation* animation )
+void UpdateManager::RemoveAnimation(Animation* animation)
{
- DALI_ASSERT_DEBUG( animation && "NULL animation called to remove" );
+ DALI_ASSERT_DEBUG(animation && "NULL animation called to remove");
- animation->OnDestroy( mSceneGraphBuffers.GetUpdateBufferIndex() );
+ animation->OnDestroy(mSceneGraphBuffers.GetUpdateBufferIndex());
- DALI_ASSERT_DEBUG( animation->GetState() == Animation::Destroyed );
+ DALI_ASSERT_DEBUG(animation->GetState() == Animation::Destroyed);
}
bool UpdateManager::IsAnimationRunning() const
{
// Find any animation that isn't stopped or paused
- for ( auto&& iter : mImpl->animations )
+ for(auto&& iter : mImpl->animations)
{
const Animation::State state = iter->GetState();
- if (state != Animation::Stopped &&
- state != Animation::Paused)
+ if(state != Animation::Stopped &&
+ state != Animation::Paused)
{
return true; // stop iteration as soon as first one is found
}
return false;
}
-void UpdateManager::AddPropertyNotification( OwnerPointer< PropertyNotification >& propertyNotification )
+void UpdateManager::AddPropertyResetter(OwnerPointer<PropertyResetterBase>& propertyResetter)
{
- mImpl->propertyNotifications.PushBack( propertyNotification.Release() );
+ propertyResetter->Initialize();
+ mImpl->propertyResetters.PushBack(propertyResetter.Release());
}
-void UpdateManager::RemovePropertyNotification( PropertyNotification* propertyNotification )
+void UpdateManager::AddNodeResetter(const Node& node)
{
- mImpl->propertyNotifications.EraseObject( propertyNotification );
+ OwnerPointer<SceneGraph::NodeResetter> nodeResetter = SceneGraph::NodeResetter::New(node);
+ nodeResetter->Initialize();
+ mImpl->nodeResetters.PushBack(nodeResetter.Release());
}
-void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode )
+void UpdateManager::AddPropertyNotification(OwnerPointer<PropertyNotification>& propertyNotification)
{
- DALI_ASSERT_DEBUG( propertyNotification && "propertyNotification scene graph object missing" );
- propertyNotification->SetNotifyMode( notifyMode );
+ mImpl->propertyNotifications.PushBack(propertyNotification.Release());
}
-void UpdateManager::AddShader( OwnerPointer< Shader >& shader )
+void UpdateManager::RemovePropertyNotification(PropertyNotification* propertyNotification)
{
- mImpl->shaders.PushBack( shader.Release() );
+ mImpl->propertyNotifications.EraseObject(propertyNotification);
}
-void UpdateManager::RemoveShader( Shader* shader )
+void UpdateManager::PropertyNotificationSetNotify(PropertyNotification* propertyNotification, PropertyNotification::NotifyMode notifyMode)
{
- // Find the shader and destroy it
- EraseUsingDiscardQueue( mImpl->shaders, shader, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
+ DALI_ASSERT_DEBUG(propertyNotification && "propertyNotification scene graph object missing");
+ propertyNotification->SetNotifyMode(notifyMode);
}
-void UpdateManager::SetShaderProgram( Shader* shader,
- Internal::ShaderDataPtr shaderData, bool modifiesGeometry )
+void UpdateManager::AddShader(OwnerPointer<Shader>& shader)
{
- if( shaderData )
- {
-
- 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 ) );
+ mImpl->shaders.PushBack(shader.Release());
+}
- // 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 );
- }
+void UpdateManager::RemoveShader(Shader* shader)
+{
+ // Find the shader and destroy it
+ EraseUsingDiscardQueue(mImpl->shaders, shader, mImpl->shaderDiscardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
}
-void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData )
+void UpdateManager::SaveBinary(Internal::ShaderDataPtr shaderData)
{
- DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." );
- DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." );
+ DALI_ASSERT_DEBUG(shaderData && "No NULL shader data pointers please.");
+ DALI_ASSERT_DEBUG(shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save.");
{
// lock as update might be sending previously compiled shaders to event thread
- Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
- mImpl->renderCompiledShaders.push_back( shaderData );
+ Mutex::ScopedLock lock(mImpl->compiledShaderMutex);
+ mImpl->renderCompiledShaders.push_back(shaderData);
}
}
-void UpdateManager::SetShaderSaver( ShaderSaver& upstream )
+void UpdateManager::SetShaderSaver(ShaderSaver& upstream)
{
mImpl->shaderSaver = &upstream;
}
-void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer )
+void UpdateManager::AddRenderer(const RendererKey& rendererKey)
{
- renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
- mImpl->renderers.PushBack( renderer.Release() );
- mImpl->renderersAdded = true;
+ SceneGraph::Renderer* renderer = rendererKey.Get();
+
+ DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer);
+
+ renderer->ConnectToSceneGraph(*mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex());
+ mImpl->renderers.PushBack(rendererKey);
}
-void UpdateManager::RemoveRenderer( Renderer* renderer )
+void UpdateManager::RemoveRenderer(const RendererKey& rendererKey)
{
+ DALI_LOG_INFO(gLogFilter, Debug::General, "[%x] RemoveRenderer\n", rendererKey.Get());
+
// Find the renderer and destroy it
- EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
+ EraseUsingDiscardQueue(mImpl->renderers, rendererKey, mImpl->rendererDiscardQueue, mSceneGraphBuffers.GetUpdateBufferIndex());
// Need to remove the render object as well
- renderer->DisconnectFromSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
+ rendererKey->DisconnectFromSceneGraph(*mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex());
}
-void UpdateManager::SetPanGestureProcessor( PanGesture* panGestureProcessor )
+void UpdateManager::AttachRenderer(Node* node, Renderer* renderer)
{
- DALI_ASSERT_DEBUG( NULL != panGestureProcessor );
+ node->AddRenderer(Renderer::GetKey(renderer));
+ mImpl->renderersAdded = true;
+}
+
+void UpdateManager::SetPanGestureProcessor(PanGesture* panGestureProcessor)
+{
+ DALI_ASSERT_DEBUG(NULL != panGestureProcessor);
mImpl->panGestureProcessor = panGestureProcessor;
}
-void UpdateManager::AddTextureSet( OwnerPointer< TextureSet >& textureSet )
+void UpdateManager::AddTextureSet(OwnerPointer<TextureSet>& textureSet)
{
- mImpl->textureSets.PushBack( textureSet.Release() );
+ mImpl->textureSets.PushBack(textureSet.Release());
}
-void UpdateManager::RemoveTextureSet( TextureSet* textureSet )
+void UpdateManager::RemoveTextureSet(TextureSet* textureSet)
{
- mImpl->textureSets.EraseObject( textureSet );
+ mImpl->textureSets.EraseObject(textureSet);
}
-RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
+uint32_t* UpdateManager::ReserveMessageSlot(uint32_t size, bool updateScene)
{
- 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);
- }
+ return mImpl->messageQueue.ReserveMessageSlot(size, updateScene);
}
-unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene )
+std::size_t UpdateManager::GetUpdateMessageQueueCapacity() const
{
- return mImpl->messageQueue.ReserveMessageSlot( size, updateScene );
+ return mImpl->messageQueue.GetCapacity();
+}
+
+std::size_t UpdateManager::GetRenderMessageQueueCapacity() const
+{
+ return mImpl->renderQueue.GetCapacity();
+}
+
+std::size_t UpdateManager::GetRenderInstructionCapacity() const
+{
+ return mImpl->renderInstructionCapacity;
}
void UpdateManager::EventProcessingStarted()
return mImpl->messageQueue.FlushQueue();
}
-void UpdateManager::ResetProperties( BufferIndex bufferIndex )
+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 node properties
+ std::vector<NodeResetter*> nodeResetterToDelete;
+ for(auto&& element : mImpl->nodeResetters)
{
- mImpl->root->ResetToBaseValues( bufferIndex );
+ element->ResetToBaseValue(bufferIndex);
+ if(element->IsFinished())
+ {
+ nodeResetterToDelete.push_back(element);
+ }
}
- if ( mImpl->systemLevelRoot )
+
+ // If a node resetter is no longer required, delete it.
+ for(auto&& elementPtr : nodeResetterToDelete)
{
- mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
+ mImpl->nodeResetters.EraseObject(elementPtr);
}
- // Reset all the nodes
- Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
- Vector<Node*>::Iterator endIter = mImpl->nodes.End();
- for( ;iter != endIter; ++iter )
+ // Reset all animating / constrained properties
+ std::vector<PropertyResetterBase*> propertyResettertoDelete;
+ for(auto&& element : mImpl->propertyResetters)
{
- (*iter)->ResetToBaseValues( bufferIndex );
+ element->ResetToBaseValue(bufferIndex);
+ if(element->IsFinished())
+ {
+ propertyResettertoDelete.push_back(element);
+ }
}
- // Reset system-level render-task list properties to base values
- ResetToBaseValues( mImpl->systemLevelTaskList.GetTasks(), bufferIndex );
-
- // Reset render-task list properties to base values.
- ResetToBaseValues( mImpl->taskList.GetTasks(), bufferIndex );
-
- // Reset custom object properties to base values
- ResetToBaseValues( mImpl->customObjects, bufferIndex );
+ // If a property resetter is no longer required (the animator or constraint has been removed), delete it.
+ for(auto&& elementPtr : propertyResettertoDelete)
+ {
+ mImpl->propertyResetters.EraseObject(elementPtr);
+ }
- // Reset animatable renderer properties to base values
- ResetToBaseValues( mImpl->renderers, bufferIndex );
+ // Clear all root nodes dirty flags
+ for(auto& scene : mImpl->scenes)
+ {
+ auto root = scene->root;
+ root->ResetDirtyFlags(bufferIndex);
+ }
- // Reset animatable shader properties to base values
- ResetToBaseValues( mImpl->shaders, bufferIndex );
+ // Clear node dirty flags
+ Vector<Node*>::Iterator iter = mImpl->nodes.Begin() + 1;
+ Vector<Node*>::Iterator endIter = mImpl->nodes.End();
+ for(; iter != endIter; ++iter)
+ {
+ (*iter)->ResetDirtyFlags(bufferIndex);
+ }
}
-bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
+bool UpdateManager::ProcessGestures(BufferIndex bufferIndex, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds)
{
- bool gestureUpdated( false );
+ bool gestureUpdated(false);
- if( mImpl->panGestureProcessor )
+ if(mImpl->panGestureProcessor)
{
// 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 );
+ 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 )
+bool UpdateManager::Animate(BufferIndex bufferIndex, float elapsedSeconds)
{
- AnimationContainer &animations = mImpl->animations;
- AnimationIter iter = animations.Begin();
- bool animationLooped = false;
+ bool animationActive = false;
- while ( iter != animations.End() )
+ auto&& iter = mImpl->animations.Begin();
+ bool animationLooped = false;
+
+ while(iter != mImpl->animations.End())
{
- Animation* animation = *iter;
- bool finished = false;
- bool looped = false;
- bool progressMarkerReached = false;
- animation->Update( bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached );
+ Animation* animation = *iter;
+ bool finished = false;
+ bool looped = false;
+ bool progressMarkerReached = false;
+ animation->Update(bufferIndex, elapsedSeconds, looped, finished, progressMarkerReached);
+
+ animationActive = animationActive || animation->IsActive();
- if ( progressMarkerReached )
+ if(progressMarkerReached)
{
- mImpl->notificationManager.QueueMessage( Internal::NotifyProgressReachedMessage( mImpl->animationPlaylist, animation ) );
+ mImpl->notificationManager.QueueMessage(Internal::NotifyProgressReachedMessage(mImpl->animationPlaylist, animation));
}
mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished;
- animationLooped = animationLooped || looped;
+ animationLooped = animationLooped || looped;
// Remove animations that had been destroyed but were still waiting for an update
- if (animation->GetState() == Animation::Destroyed)
+ if(animation->GetState() == Animation::Destroyed)
{
- iter = animations.Erase(iter);
+ iter = mImpl->animations.Erase(iter);
}
else
{
}
// queue the notification on finished or looped (to update loop count)
- if ( mImpl->animationFinishedDuringUpdate || animationLooped )
+ if(mImpl->animationFinishedDuringUpdate || animationLooped)
{
// The application should be notified by NotificationManager, in another thread
- mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationPlaylist );
+ mImpl->notificationManager.QueueCompleteNotification(&mImpl->animationPlaylist);
}
+
+ return animationActive;
}
-void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex )
+void UpdateManager::ConstrainCustomObjects(BufferIndex bufferIndex)
{
- //Constrain custom objects (in construction order)
- for ( auto&& object : mImpl->customObjects )
+ // Constrain custom objects (in construction order)
+ for(auto&& object : mImpl->customObjects)
{
- ConstrainPropertyOwner( *object, bufferIndex );
+ ConstrainPropertyOwner(*object, bufferIndex);
}
}
-void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex )
+void UpdateManager::ConstrainRenderTasks(BufferIndex bufferIndex)
{
- // Constrain system-level render-tasks
- const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks();
- for ( auto&& task : systemLevelTasks )
- {
- ConstrainPropertyOwner( *task, bufferIndex );
- }
-
// Constrain render-tasks
- const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks();
- for ( auto&& task : tasks )
+ for(auto&& scene : mImpl->scenes)
{
- ConstrainPropertyOwner( *task, bufferIndex );
+ if(scene && scene->taskList)
+ {
+ RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
+ for(auto&& task : tasks)
+ {
+ ConstrainPropertyOwner(*task, bufferIndex);
+ }
+ }
}
}
-void UpdateManager::ConstrainShaders( BufferIndex bufferIndex )
+void UpdateManager::ConstrainShaders(BufferIndex bufferIndex)
{
// constrain shaders... (in construction order)
- for ( auto&& shader : mImpl->shaders )
+ for(auto&& shader : mImpl->shaders)
{
- ConstrainPropertyOwner( *shader, bufferIndex );
+ ConstrainPropertyOwner(*shader, bufferIndex);
}
}
-void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex )
+void UpdateManager::ProcessPropertyNotifications(BufferIndex bufferIndex)
{
- for( auto&& notification : mImpl->propertyNotifications )
+ for(auto&& notification : mImpl->propertyNotifications)
{
- bool valid = notification->Check( bufferIndex );
+ bool valid = notification->Check(bufferIndex);
if(valid)
{
- mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) );
+ mImpl->notificationManager.QueueMessage(PropertyChangedMessage(mImpl->propertyNotifier, notification, notification->GetValidity()));
}
}
}
void UpdateManager::ForwardCompiledShadersToEventThread()
{
- DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." );
- if( mImpl->shaderSaver )
+ DALI_ASSERT_DEBUG((mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup.");
+ if(mImpl->shaderSaver)
{
// lock and swap the queues
{
// render might be attempting to send us more binaries at the same time
- Mutex::ScopedLock lock( mImpl->compiledShaderMutex );
- mImpl->renderCompiledShaders.swap( mImpl->updateCompiledShaders );
+ Mutex::ScopedLock lock(mImpl->compiledShaderMutex);
+ mImpl->renderCompiledShaders.swap(mImpl->updateCompiledShaders);
}
- if( mImpl->updateCompiledShaders.size() > 0 )
+ if(mImpl->updateCompiledShaders.size() > 0)
{
ShaderSaver& factory = *mImpl->shaderSaver;
- for( auto&& shader : mImpl->updateCompiledShaders )
+ for(auto&& shader : mImpl->updateCompiledShaders)
{
- mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, shader ) );
+ mImpl->notificationManager.QueueMessage(ShaderCompiledMessage(factory, shader));
}
// we don't need them in update anymore
mImpl->updateCompiledShaders.clear();
}
}
-void UpdateManager::UpdateRenderers( BufferIndex bufferIndex )
+void UpdateManager::UpdateRenderers(BufferIndex bufferIndex)
{
- const unsigned int rendererCount = mImpl->renderers.Count();
- for( unsigned int i = 0; i < rendererCount; ++i )
+ for(const auto& rendererKey : mImpl->renderers)
{
- //Apply constraints
- ConstrainPropertyOwner( *mImpl->renderers[i], bufferIndex );
+ // Apply constraints
+ auto renderer = rendererKey.Get();
+ ConstrainPropertyOwner(*renderer, bufferIndex);
- mImpl->renderers[i]->PrepareRender( bufferIndex );
+ mImpl->renderingRequired = renderer->PrepareRender(bufferIndex) || mImpl->renderingRequired;
}
}
-void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
+void UpdateManager::UpdateNodes(BufferIndex bufferIndex)
{
- mImpl->nodeDirtyFlags = NothingFlag;
+ mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
- if ( !mImpl->root )
+ for(auto&& scene : mImpl->scenes)
{
- return;
+ 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);
+ }
}
+}
- // Prepare resources, update shaders, for each node
- // And add the renderers to the sorted layers. Start from root, which is also a layer
- mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ),
- bufferIndex,
- mImpl->renderQueue );
-
- if ( mImpl->systemLevelRoot )
+void UpdateManager::UpdateLayers(BufferIndex bufferIndex)
+{
+ for(auto&& scene : mImpl->scenes)
{
- mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
- bufferIndex,
- mImpl->renderQueue );
+ if(scene && scene->root)
+ {
+ SceneGraph::UpdateLayerTree(*scene->root, bufferIndex);
+ }
}
}
-unsigned int UpdateManager::Update( float elapsedSeconds,
- unsigned int lastVSyncTimeMilliseconds,
- unsigned int nextVSyncTimeMilliseconds,
- bool renderToFboEnabled,
- bool isRenderingToFbo )
+uint32_t UpdateManager::Update(float elapsedSeconds,
+ uint32_t lastVSyncTimeMilliseconds,
+ uint32_t nextVSyncTimeMilliseconds,
+ bool renderToFboEnabled,
+ bool isRenderingToFbo,
+ bool uploadOnly)
{
const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
- //Clear nodes/resources which were previously discarded
- mImpl->discardQueue.Clear( bufferIndex );
+ // Clear nodes/resources which were previously discarded
+ mImpl->nodeDiscardQueue.Clear(bufferIndex);
+ mImpl->shaderDiscardQueue.Clear(bufferIndex);
+ mImpl->rendererDiscardQueue.Clear(bufferIndex);
+ mImpl->sceneDiscardQueue.Clear(bufferIndex);
+
+ bool isAnimationRunning = IsAnimationRunning();
- //Process Touches & Gestures
- const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
+ // Process Touches & Gestures
+ const bool gestureUpdated = ProcessGestures(bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds);
- 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
- gestureUpdated; // ..a gesture property was updated
+ 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
+ mImpl->frameCallbackProcessor || // ..a frame callback processor is existed OR
+ gestureUpdated; // ..a gesture property was updated
+ bool keepRendererRendering = false;
+ mImpl->renderingRequired = 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 )
+ if(updateScene || mImpl->previousUpdateScene)
{
- //Reset properties from the previous update
- ResetProperties( bufferIndex );
+ // Reset properties from the previous update
+ ResetProperties(bufferIndex);
mImpl->transformManager.ResetToBaseValue();
}
// 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 );
+ updateScene |= mImpl->messageQueue.ProcessMessages(bufferIndex);
- //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
// renderer lists if the scene was updated in the previous frame.
// We should not start skipping update steps or reusing lists until there has been two frames where nothing changes
- if( updateScene || mImpl->previousUpdateScene )
+ if(updateScene || mImpl->previousUpdateScene)
{
- //Animate
- Animate( bufferIndex, elapsedSeconds );
+ // Animate
+ bool animationActive = Animate(bufferIndex, elapsedSeconds);
- //Constraint custom objects
- ConstrainCustomObjects( bufferIndex );
+ // Constraint custom objects
+ ConstrainCustomObjects(bufferIndex);
- //Clear the lists of renderers from the previous update
- for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
+ // Clear the lists of renderers from the previous update
+ for(auto&& scene : mImpl->scenes)
{
- mImpl->sortedLayers[i]->ClearRenderables();
+ if(scene)
+ {
+ for(auto&& layer : scene->sortedLayerList)
+ {
+ if(layer)
+ {
+ layer->ClearRenderables();
+ }
+ }
+ }
}
- for( size_t i(0); i<mImpl->systemLevelSortedLayers.size(); ++i )
+ // Call the frame-callback-processor if set
+ if(mImpl->frameCallbackProcessor)
{
- mImpl->systemLevelSortedLayers[i]->ClearRenderables();
+ mImpl->frameCallbackProcessor->Update(bufferIndex, elapsedSeconds);
}
- //Update node hierarchy, apply constraints and perform sorting / culling.
- //This will populate each Layer with a list of renderers which are ready.
- UpdateNodes( bufferIndex );
+ // Update node hierarchy, apply constraints,
+ UpdateNodes(bufferIndex);
- //Apply constraints to RenderTasks, shaders
- ConstrainRenderTasks( bufferIndex );
- ConstrainShaders( bufferIndex );
+ // Apply constraints to RenderTasks, shaders
+ ConstrainRenderTasks(bufferIndex);
+ ConstrainShaders(bufferIndex);
- //Update renderers and apply constraints
- UpdateRenderers( bufferIndex );
+ // Update renderers and apply constraints
+ UpdateRenderers(bufferIndex);
+
+ // Update the transformations of all the nodes
+ if(mImpl->transformManager.Update())
+ {
+ mImpl->nodeDirtyFlags |= NodePropertyFlags::TRANSFORM;
+ }
- //Update the trnasformations of all the nodes
- mImpl->transformManager.Update();
+ // Initialise layer renderable reuse
+ UpdateLayers(bufferIndex);
- //Process Property Notifications
- ProcessPropertyNotifications( bufferIndex );
+ // Process Property Notifications
+ ProcessPropertyNotifications(bufferIndex);
- //Update cameras
- for( auto&& cameraIterator : mImpl->cameras )
+ // Update cameras
+ for(auto&& cameraIterator : mImpl->cameras)
{
- cameraIterator->Update( bufferIndex );
+ cameraIterator->Update(bufferIndex);
}
- //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 )
+ // 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)
{
- mImpl->renderInstructions.ResetAndReserve( bufferIndex,
- mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
+ // Calculate how many render tasks we have in total
+ std::size_t numberOfRenderTasks = 0;
+ for(auto&& scene : mImpl->scenes)
+ {
+ if(scene && scene->taskList)
+ {
+ numberOfRenderTasks += scene->taskList->GetTasks().Count();
+ }
+ }
- if ( NULL != mImpl->root )
+ std::size_t numberOfRenderInstructions = 0;
+ mImpl->renderInstructionCapacity = 0u;
+ for(auto&& scene : mImpl->scenes)
{
- mImpl->renderTaskProcessor.Process( bufferIndex,
- mImpl->taskList,
- *mImpl->root,
- mImpl->sortedLayers,
- mImpl->renderInstructions,
- renderToFboEnabled,
- isRenderingToFbo );
-
- // Process the system-level RenderTasks last
- if ( NULL != mImpl->systemLevelRoot )
+ if(scene && scene->root && scene->taskList && scene->scene)
{
- mImpl->renderTaskProcessor.Process( bufferIndex,
- mImpl->systemLevelTaskList,
- *mImpl->systemLevelRoot,
- mImpl->systemLevelSortedLayers,
- mImpl->renderInstructions,
- renderToFboEnabled,
- isRenderingToFbo );
+ scene->scene->GetRenderInstructions().ResetAndReserve(bufferIndex,
+ static_cast<uint32_t>(scene->taskList->GetTasks().Count()));
+
+ // If there are animations running, only add render instruction if at least one animation is currently active (i.e. not delayed)
+ // or the nodes are dirty
+ if(!isAnimationRunning || animationActive || mImpl->renderingRequired || (mImpl->nodeDirtyFlags & RenderableUpdateFlags))
+ {
+ keepRendererRendering |= mImpl->renderTaskProcessor.Process(bufferIndex,
+ *scene->taskList,
+ *scene->root,
+ scene->sortedLayerList,
+ scene->scene->GetRenderInstructions(),
+ renderToFboEnabled,
+ isRenderingToFbo);
+
+ mImpl->renderInstructionCapacity += scene->scene->GetRenderInstructions().GetCapacity();
+ scene->scene->SetSkipRendering(false);
+ }
+ else
+ {
+ scene->scene->SetSkipRendering(true);
+ }
+
+ numberOfRenderInstructions += scene->scene->GetRenderInstructions().Count(bufferIndex);
}
}
+
+ DALI_LOG_INFO(gLogFilter, Debug::General, "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n", numberOfRenderTasks, numberOfRenderInstructions);
}
}
- // 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;
- for ( auto&& renderTask : mImpl->taskList.GetTasks() )
+ if(!uploadOnly)
{
- renderTask->UpdateState();
-
- if( renderTask->IsWaitingToRender() &&
- renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
+ for(auto&& scene : mImpl->scenes)
{
- mImpl->renderTaskWaiting = true; // keep update/render threads alive
- }
+ if(scene && scene->root && scene->taskList)
+ {
+ RenderTaskList::RenderTaskContainer& tasks = scene->taskList->GetTasks();
- if( renderTask->HasRendered() )
- {
- doRenderOnceNotify = true;
- }
- }
+ // 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( mImpl->taskList.GetCompleteNotificationInterface() );
+ 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.
mImpl->previousUpdateScene = updateScene;
// Check whether further updates are required
- unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds );
+ uint32_t keepUpdating = KeepUpdatingCheck(elapsedSeconds);
+
+ if(keepRendererRendering)
+ {
+ keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
+
+ // Set dirty flags for next frame to continue rendering
+ mImpl->nodeDirtyFlags |= RenderableUpdateFlags;
+ }
// tell the update manager that we're done so the queue can be given to event thread
mImpl->notificationManager.UpdateCompleted();
return keepUpdating;
}
-unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
+void UpdateManager::PostRender()
+{
+ // Reset dirty flag
+ for(auto&& renderer : mImpl->renderers)
+ {
+ renderer->ResetDirtyFlag();
+ }
+
+ for(auto&& scene : mImpl->scenes)
+ {
+ scene->root->SetUpdatedTree(false);
+ }
+}
+
+uint32_t UpdateManager::KeepUpdatingCheck(float elapsedSeconds) const
{
// Update the duration set via Stage::KeepRendering()
- if ( mImpl->keepRenderingSeconds > 0.0f )
+ 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;
}
- if ( IsAnimationRunning() ||
- mImpl->animationFinishedDuringUpdate )
+ if(IsAnimationRunning() ||
+ mImpl->animationFinishedDuringUpdate)
{
keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING;
}
- if ( mImpl->renderTaskWaiting )
+ if(mImpl->renderTaskWaiting)
{
keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC;
}
return keepUpdatingRequest;
}
-void UpdateManager::SetBackgroundColor( const Vector4& color )
+void UpdateManager::SurfaceReplaced(Scene* scene)
{
- typedef MessageValue1< RenderManager, Vector4 > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, Scene*>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SurfaceReplaced, scene);
}
-void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
+void UpdateManager::KeepRendering(float durationSeconds)
{
- typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
-
- // Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ mImpl->keepRenderingSeconds = std::max(mImpl->keepRenderingSeconds, durationSeconds);
+}
- // 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::SetRenderingBehavior(DevelStage::Rendering renderingBehavior)
+{
+ mImpl->renderingBehavior = renderingBehavior;
}
-void UpdateManager::KeepRendering( float durationSeconds )
+void UpdateManager::RequestRendering()
{
- mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
+ mImpl->renderingRequired = true;
}
-void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
+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;
- }
- else
- {
- mImpl->systemLevelSortedLayers = layers;
+ if(scene && scene->root == rootLayer)
+ {
+ scene->sortedLayerList = layers;
+ break;
+ }
}
}
-void UpdateManager::SetDepthIndices( OwnerPointer< NodeDepths >& nodeDepths )
+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 )
+ // note, this vector is already in depth order.
+ // So if we reverse iterate, we can assume that
+ // my descendant node's depth index are updated.
+ for(auto rIter = nodeDepths->nodeDepths.rbegin(), rEndIter = nodeDepths->nodeDepths.rend(); rIter != rEndIter; rIter++)
{
- iter.node->SetDepthIndex( iter.sortedDepth );
+ auto* node = rIter->node;
+ node->SetDepthIndex(rIter->sortedDepth);
+ if(node->IsChildrenReorderRequired())
+ {
+ // Reorder children container only if sibiling order changed.
+ NodeContainer& container = node->GetChildren();
+ std::sort(container.Begin(), container.End(), [](Node* a, Node* b) { return a->GetDepthIndex() < b->GetDepthIndex(); });
+ }
}
+}
+
+void UpdateManager::AddFrameCallback(OwnerPointer<FrameCallback>& frameCallback, const Node* rootNode)
+{
+ mImpl->GetFrameCallbackProcessor(*this).AddFrameCallback(frameCallback, rootNode);
+}
- // Go through node hierarchy and rearrange siblings according to depth-index
- SortSiblingNodesRecursively( *( mImpl->root ) );
+void UpdateManager::RemoveFrameCallback(FrameCallbackInterface* frameCallback)
+{
+ mImpl->GetFrameCallbackProcessor(*this).RemoveFrameCallback(frameCallback);
}
-void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
+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;
+ using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Sampler>>;
// 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 );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AddSampler, sampler);
}
-void UpdateManager::RemoveSampler( Render::Sampler* sampler )
+void UpdateManager::RemoveSampler(Render::Sampler* sampler)
{
- typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, Render::Sampler*>;
// 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 );
+ 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;
+ using DerivedType = MessageValue3<RenderManager, Render::Sampler*, uint32_t, uint32_t>;
// 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 );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode);
}
-void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
+void UpdateManager::SetWrapMode(Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode)
{
- typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > DerivedType;
+ using DerivedType = MessageValue4<RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t>;
// 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 );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode);
}
-void UpdateManager::AddPropertyBuffer( OwnerPointer< Render::PropertyBuffer >& propertyBuffer )
+void UpdateManager::AddVertexBuffer(OwnerPointer<Render::VertexBuffer>& vertexBuffer)
{
// Message has ownership of format while in transit from update -> render
- typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::VertexBuffer>>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AddVertexBuffer, vertexBuffer);
}
-void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer )
+void UpdateManager::RemoveVertexBuffer(Render::VertexBuffer* vertexBuffer)
{
- typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, Render::VertexBuffer*>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::RemoveVertexBuffer, vertexBuffer);
}
-void UpdateManager::SetPropertyBufferFormat( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Render::PropertyBuffer::Format>& format )
+void UpdateManager::SetVertexBufferFormat(Render::VertexBuffer* vertexBuffer, OwnerPointer<Render::VertexBuffer::Format>& format)
{
// Message has ownership of format while in transit from update -> render
- typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType;
+ using DerivedType = MessageValue2<RenderManager, Render::VertexBuffer*, OwnerPointer<Render::VertexBuffer::Format>>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetVertexBufferFormat, vertexBuffer, format);
}
-void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Vector<char> >& data, size_t size )
+void UpdateManager::SetVertexBufferData(Render::VertexBuffer* vertexBuffer, 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<char> >, size_t > DerivedType;
+ using DerivedType = MessageValue3<RenderManager, Render::VertexBuffer*, OwnerPointer<Dali::Vector<uint8_t>>, uint32_t>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferData, propertyBuffer, data, size );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetVertexBufferData, vertexBuffer, data, size);
}
-void UpdateManager::AddGeometry( OwnerPointer< Render::Geometry >& geometry )
+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;
+ using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::Geometry>>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AddGeometry, geometry);
}
-void UpdateManager::RemoveGeometry( Render::Geometry* geometry )
+void UpdateManager::RemoveGeometry(Render::Geometry* geometry)
{
- typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, Render::Geometry*>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::RemoveGeometry, geometry);
}
-void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
+void UpdateManager::SetGeometryType(Render::Geometry* geometry, uint32_t geometryType)
{
- typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType;
+ using DerivedType = MessageValue2<RenderManager, Render::Geometry*, uint32_t>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType);
}
-void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
+void UpdateManager::SetIndexBuffer(Render::Geometry* geometry, Dali::Vector<uint16_t>& indices)
{
- typedef IndexBufferMessage< RenderManager > DerivedType;
+ using DerivedType = IndexBufferMessage<RenderManager>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
+ new(slot) DerivedType(&mImpl->renderManager, geometry, indices);
}
-void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
+void UpdateManager::RemoveVertexBuffer(Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer)
{
- typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
+ using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, vertexBuffer);
}
-void UpdateManager::AttachVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer )
+void UpdateManager::AttachVertexBuffer(Render::Geometry* geometry, Render::VertexBuffer* vertexBuffer)
{
- typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
+ using DerivedType = MessageValue2<RenderManager, Render::Geometry*, Render::VertexBuffer*>;
// 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::AttachVertexBuffer, geometry, propertyBuffer );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, vertexBuffer);
}
-void UpdateManager::AddTexture( OwnerPointer< Render::Texture >& texture )
+void UpdateManager::AddTexture(const Render::TextureKey& texture)
{
- // Message has ownership of Texture while in transit from update -> render
- typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AddTexture, texture);
}
-void UpdateManager::RemoveTexture( Render::Texture* texture)
+void UpdateManager::RemoveTexture(const Render::TextureKey& texture)
{
- typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
+ using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::RemoveTexture, texture);
}
-void UpdateManager::UploadTexture( Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params )
+void UpdateManager::UploadTexture(const Render::TextureKey& texture, PixelDataPtr pixelData, const Texture::UploadParams& params)
{
- typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
+ using DerivedType = MessageValue3<RenderManager, Render::TextureKey, PixelDataPtr, Texture::UploadParams>;
// Reserve some memory inside the message queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the message queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params);
+}
+
+void UpdateManager::GenerateMipmaps(const Render::TextureKey& texture)
+{
+ using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
+
+ // 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)
+{
+ using DerivedType = MessageValue1<RenderManager, OwnerPointer<Render::FrameBuffer>>;
+
+ // 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)
+{
+ using DerivedType = MessageValue1<RenderManager, Render::FrameBuffer*>;
+
+ // 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::GenerateMipmaps( Render::Texture* texture )
+void UpdateManager::AttachColorTextureToFrameBuffer(Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer)
{
- typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
+ using DerivedType = MessageValue4<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer);
}
-void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
+void UpdateManager::AttachDepthTextureToFrameBuffer(Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel)
{
- typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
+ using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AttachDepthTextureToFrameBuffer, frameBuffer, texture, mipmapLevel);
}
-void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer)
+void UpdateManager::AttachDepthStencilTextureToFrameBuffer(Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel)
{
- typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
+ using DerivedType = MessageValue3<RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::AttachDepthStencilTextureToFrameBuffer, frameBuffer, texture, mipmapLevel);
}
-void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, unsigned int mipmapLevel, unsigned int layer )
+void UpdateManager::SetMultiSamplingLevelToFrameBuffer(Render::FrameBuffer* frameBuffer, uint8_t multiSamplingLevel)
{
- typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, unsigned int, unsigned int > DerivedType;
+ using DerivedType = MessageValue2<RenderManager, Render::FrameBuffer*, uint8_t>;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot(mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof(DerivedType));
// Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );
+ new(slot) DerivedType(&mImpl->renderManager, &RenderManager::SetMultiSamplingLevelToFrameBuffer, frameBuffer, multiSamplingLevel);
}
} // namespace SceneGraph