/*
- * Copyright (c) 2018 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.
#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/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/manager/transform-manager.h>
#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
{
/**
- * 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
*/
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,
CompleteNotificationInterface& animationPlaylist,
PropertyNotifier& propertyNotifier,
renderInstructions( renderManager.GetRenderInstructionContainer() ),
renderTaskProcessor( renderTaskProcessor ),
backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
- taskList( renderMessageDispatcher ),
- systemLevelTaskList( renderMessageDispatcher ),
- root( NULL ),
- systemLevelRoot( NULL ),
renderers(),
textureSets(),
shaders(),
panGestureProcessor( NULL ),
messageQueue( renderController, sceneGraphBuffers ),
+ frameCallbackProcessor( NULL ),
keepRenderingSeconds( 0.0f ),
- nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
+ 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 )
+ renderersAdded( false ),
+ surfaceRectChanged( false )
{
sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
~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( NULL );
+ }
+ }
}
// UpdateManager owns the Nodes. Although Nodes are pool allocated they contain heap allocated parts
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;
+ /**
+ * Lazy init for FrameCallbackProcessor.
+ * @param[in] updateManager A reference to the update-manager
+ */
+ FrameCallbackProcessor& GetFrameCallbackProcessor( UpdateManager& updateManager )
+ {
+ if( ! frameCallbackProcessor )
+ {
+ frameCallbackProcessor = new FrameCallbackProcessor( updateManager, transformManager );
}
-
- delete sceneController;
+ return *frameCallbackProcessor;
}
SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
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
+ using SceneInfoPtr = std::unique_ptr< SceneInfo >;
+ std::vector< SceneInfoPtr > scenes; ///< A container of SceneInfo.
Vector<Node*> nodes; ///< A container of all instantiated nodes
- SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth
- SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers
-
OwnerContainer< Camera* > cameras; ///< A container of cameras
OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties)
OwnerContainer< PropertyResetterBase* > propertyResetters; ///< A container of property resetters
- AnimationContainer animations; ///< A container of owned animations
+ 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
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
- 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.
+ NodePropertyFlags nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
+ uint32_t frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
+
+ DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior
bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
bool renderersAdded; ///< Flag to keep track when renderers have been added to avoid unnecessary processing
+ bool surfaceRectChanged; ///< True if the default surface rect is changed
private:
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);
- 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);
+
+ 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->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), layer );
+
+ // Notify the layer about impending destruction
+ layer->OnDestroy();
}
void UpdateManager::AddNode( OwnerPointer<Node>& 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 )
{
DALI_ASSERT_ALWAYS( NULL != node );
DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
+ DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] ConnectNode\n", node );
+
parent->ConnectChild( node );
+
+ 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
+ parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused
parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
+
+ // Inform the frame-callback-processor, if set, about the node-hierarchy changing
+ if( mImpl->frameCallbackProcessor )
+ {
+ mImpl->frameCallbackProcessor->NodeHierarchyChanged();
+ }
}
void UpdateManager::DestroyNode( Node* node )
DALI_ASSERT_ALWAYS( NULL != node );
DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
+ DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DestroyNode\n", node );
+
Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
Vector<Node*>::Iterator endIter = mImpl->nodes.End();
for(;iter!=endIter;++iter)
mImpl->cameras.PushBack( camera.Release() ); // takes ownership
}
-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() );
+ EraseUsingDiscardQueue( mImpl->cameras, camera, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
}
void UpdateManager::AddObject( OwnerPointer<PropertyOwner>& object )
mImpl->customObjects.EraseObject( object );
}
+void UpdateManager::AddRenderTaskList( OwnerPointer<RenderTaskList>& taskList )
+{
+ RenderTaskList* taskListPointer = taskList.Release();
+ taskListPointer->SetRenderMessageDispatcher( &mImpl->renderMessageDispatcher );
+
+ mImpl->scenes.back()->taskList = taskListPointer;
+}
+
+void UpdateManager::RemoveRenderTaskList( RenderTaskList* taskList )
+{
+ for ( auto&& scene : mImpl->scenes )
+ {
+ if ( scene && scene->taskList == taskList )
+ {
+ scene->taskList.Reset();
+ break;
+ }
+ }
+}
+
void UpdateManager::AddAnimation( OwnerPointer< SceneGraph::Animation >& animation )
{
mImpl->animations.PushBack( animation.Release() );
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 );
void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer )
{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer.Get() );
+
renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
mImpl->renderers.PushBack( renderer.Release() );
mImpl->renderersAdded = true;
void UpdateManager::RemoveRenderer( Renderer* renderer )
{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] RemoveRenderer\n", renderer );
+
// Find the renderer and destroy it
EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
// Need to remove the render object as well
mImpl->textureSets.EraseObject( textureSet );
}
-RenderTaskList* UpdateManager::GetRenderTaskList( bool systemLevel )
-{
- 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);
- }
-}
-
-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 );
}
}
}
-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 );
void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds )
{
- AnimationContainer &animations = mImpl->animations;
- AnimationIter iter = animations.Begin();
+ auto&& iter = mImpl->animations.Begin();
bool animationLooped = false;
- while ( iter != animations.End() )
+ while ( iter != mImpl->animations.End() )
{
Animation* animation = *iter;
bool finished = false;
// 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
{
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::UpdateRenderers( BufferIndex bufferIndex )
{
- const unsigned int rendererCount = mImpl->renderers.Count();
- for( unsigned int i = 0; i < rendererCount; ++i )
+ for( auto&& renderer : mImpl->renderers )
{
//Apply constraints
- ConstrainPropertyOwner( *mImpl->renderers[i], bufferIndex );
+ ConstrainPropertyOwner( *renderer, bufferIndex );
- mImpl->renderers[i]->PrepareRender( bufferIndex );
+ renderer->PrepareRender( bufferIndex );
}
}
void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
{
- mImpl->nodeDirtyFlags = NothingFlag;
-
- if ( !mImpl->root )
- {
- return;
- }
-
- // 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 );
+ mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
- if ( mImpl->systemLevelRoot )
+ for ( auto&& scene : mImpl->scenes )
{
- mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ),
- bufferIndex,
- mImpl->renderQueue );
+ if ( scene && scene->root )
+ {
+ // Prepare resources, update shaders, for each node
+ // And add the renderers to the sorted layers. Start from root, which is also a layer
+ mImpl->nodeDirtyFlags |= UpdateNodeTree( *scene->root,
+ bufferIndex,
+ mImpl->renderQueue );
+ }
}
}
-unsigned int UpdateManager::Update( float elapsedSeconds,
- unsigned int lastVSyncTimeMilliseconds,
- unsigned int nextVSyncTimeMilliseconds,
- bool renderToFboEnabled,
- bool isRenderingToFbo )
+uint32_t UpdateManager::Update( float elapsedSeconds,
+ uint32_t lastVSyncTimeMilliseconds,
+ uint32_t nextVSyncTimeMilliseconds,
+ bool renderToFboEnabled,
+ bool isRenderingToFbo )
{
const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued 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.
ConstrainCustomObjects( bufferIndex );
//Clear the lists of renderers from the previous update
- for( size_t i(0); i<mImpl->sortedLayers.size(); ++i )
+ for( auto&& scene : mImpl->scenes )
{
- mImpl->sortedLayers[i]->ClearRenderables();
+ if ( scene )
+ {
+ for( auto&& layer : scene->sortedLayerList )
+ {
+ if ( layer )
+ {
+ layer->ClearRenderables();
+ }
+ }
+ }
}
- for( size_t i(0); 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.
//reset the update buffer index and make sure there is enough room in the instruction container
if( mImpl->renderersAdded )
{
+ // 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();
+ }
+ }
+
mImpl->renderInstructions.ResetAndReserve( bufferIndex,
- mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() );
+ static_cast<uint32_t>( numberOfRenderTasks ) );
- if ( NULL != mImpl->root )
+ 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 )
{
- mImpl->renderTaskProcessor.Process( bufferIndex,
- mImpl->systemLevelTaskList,
- *mImpl->systemLevelRoot,
- mImpl->systemLevelSortedLayers,
+ keepRendererRendering |= mImpl->renderTaskProcessor.Process( bufferIndex,
+ *scene->taskList,
+ *scene->root,
+ scene->sortedLayerList,
mImpl->renderInstructions,
renderToFboEnabled,
isRenderingToFbo );
}
}
+
+ DALI_LOG_INFO( gLogFilter, Debug::General,
+ "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n",
+ numberOfRenderTasks, mImpl->renderInstructions.Count( bufferIndex ) );
}
}
- // 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() )
+ for ( auto&& scene : mImpl->scenes )
{
- renderTask->UpdateState();
-
- if( renderTask->IsWaitingToRender() &&
- renderTask->ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ )
+ if ( scene && scene->root && scene->taskList )
{
- mImpl->renderTaskWaiting = true; // keep update/render threads alive
- }
+ 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( doRenderOnceNotify )
- {
- DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Notify a render task has finished\n");
- mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() );
+ 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.
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;
+ }
// 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
+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 )
{
- if ( !systemLevel )
- {
- // just copy the vector of pointers
- mImpl->sortedLayers = layers;
- }
- else
+ mImpl->renderingBehavior = renderingBehavior;
+}
+
+void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, const Layer* rootLayer )
+{
+ for ( auto&& scene : mImpl->scenes )
{
- mImpl->systemLevelSortedLayers = layers;
+ if ( scene && scene->root == rootLayer )
+ {
+ scene->sortedLayerList = layers;
+ break;
+ }
}
}
iter.node->SetDepthIndex( iter.sortedDepth );
}
- // Go through node hierarchy and rearrange siblings according to depth-index
- SortSiblingNodesRecursively( *( mImpl->root ) );
+ for ( auto&& scene : mImpl->scenes )
+ {
+ if ( scene )
+ {
+ // Go through node hierarchy and rearrange siblings according to depth-index
+ SortSiblingNodesRecursively( *scene->root );
+ }
+ }
+}
+
+bool UpdateManager::IsDefaultSurfaceRectChanged()
+{
+ bool surfaceRectChanged = mImpl->surfaceRectChanged;
+
+ // Reset the flag
+ mImpl->surfaceRectChanged = false;
+
+ return surfaceRectChanged;
+}
+
+void UpdateManager::AddFrameCallback( OwnerPointer< FrameCallback >& frameCallback, const Node* rootNode )
+{
+ mImpl->GetFrameCallbackProcessor( *this ).AddFrameCallback( frameCallback, rootNode );
+}
+
+void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
+{
+ mImpl->GetFrameCallbackProcessor( *this ).RemoveFrameCallback( frameCallback );
}
void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
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 rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode )
+void UpdateManager::SetWrapMode( Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode )
{
- typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > DerivedType;
+ typedef MessageValue4< RenderManager, Render::Sampler*, uint32_t, uint32_t, uint32_t > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode );
typedef MessageValue1< RenderManager, OwnerPointer< Render::PropertyBuffer > > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer );
typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemovePropertyBuffer, propertyBuffer );
typedef MessageValue2< RenderManager, Render::PropertyBuffer*, OwnerPointer< Render::PropertyBuffer::Format > > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetPropertyBufferFormat, propertyBuffer, format );
}
-void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, OwnerPointer< Vector<char> >& data, size_t size )
+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<char> >, size_t > DerivedType;
+ typedef MessageValue3< RenderManager, Render::PropertyBuffer*, OwnerPointer< Dali::Vector<uint8_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::SetPropertyBufferData, propertyBuffer, data, size );
typedef MessageValue1< RenderManager, OwnerPointer< Render::Geometry > > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry );
typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveGeometry, geometry );
}
-void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType )
+void UpdateManager::SetGeometryType( Render::Geometry* geometry, uint32_t geometryType )
{
- typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType;
+ typedef MessageValue2< RenderManager, Render::Geometry*, uint32_t > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType );
}
-void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<unsigned short>& indices )
+void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector<uint16_t>& indices )
{
typedef IndexBufferMessage< RenderManager > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, geometry, indices );
typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer );
typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachVertexBuffer, geometry, propertyBuffer );
typedef MessageValue1< RenderManager, OwnerPointer< Render::Texture > > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture );
typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture );
typedef MessageValue3< RenderManager, Render::Texture*, PixelDataPtr, Texture::UploadParams > DerivedType;
// Reserve some memory inside the message queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the message queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params );
typedef MessageValue1< RenderManager, Render::Texture* > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture );
}
-void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer )
+void UpdateManager::AddFrameBuffer( OwnerPointer< Render::FrameBuffer >& frameBuffer )
{
- typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
+ typedef MessageValue1< RenderManager, OwnerPointer< Render::FrameBuffer > > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer );
typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer );
}
-void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, unsigned int mipmapLevel, unsigned int layer )
+void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer )
{
- typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, unsigned int, unsigned int > DerivedType;
+ typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::Texture*, uint32_t, uint32_t > DerivedType;
// Reserve some memory inside the render queue
- unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
+ uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
// Construct message in the render queue memory; note that delete should not be called on the return value
new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer );