X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Fmanager%2Fupdate-manager.cpp;h=0dfe3091b1abbf81305a8a72400c01073e623ec8;hb=4c8af0dfb14efdf61ab9eaf507dca05d13b36d0c;hp=2846281994f220c6ccb5bf8ee8f57bd229d96d9b;hpb=d46e06b577afa0f99a293d257a834add7c2f3755;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index 2846281..0c6f697 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,56 +20,53 @@ // INTERNAL INCLUDES #include -#include +#include +#include +#include #include #include -#include +#include #include #include -#include #include #include #include #include +#include #include #include #include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include +#include #include #include #include -#include -#include +#include +#include +#include +#include +#include +#include #include #include -#include +#include +#include +#include +#include +#include #include #include #include -#include #include -#include -#include - -#ifdef DYNAMICS_SUPPORT -#include -#include -#endif +#include +#include +#include +#include // Un-comment to enable node tree debug logging //#define NODE_TREE_LOGGING 1 @@ -107,39 +104,19 @@ namespace Internal namespace SceneGraph { -namespace -{ - -const int DEFAULT_CAMERA_INDEX = -1; - -void DestroyNodeSet( std::set& nodeSet ) -{ - for( std::set::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter ) - { - Node* node( *iter ); - - // Call Node::OnDestroy as each node is destroyed - node->OnDestroy(); - - delete node; - } - nodeSet.clear(); -} - -} //namespace - typedef OwnerContainer< Shader* > ShaderContainer; typedef ShaderContainer::Iterator ShaderIter; typedef ShaderContainer::ConstIterator ShaderConstIter; -typedef AnimatableMeshContainer::Iterator AnimatableMeshIter; -typedef AnimatableMeshContainer::ConstIterator AnimatableMeshConstIter; -typedef MaterialContainer::Iterator MaterialIter; +typedef std::vector ShaderDataBinaryQueue; typedef OwnerContainer GestureContainer; typedef GestureContainer::Iterator GestureIter; typedef GestureContainer::ConstIterator GestureConstIter; +typedef OwnerContainer< TextureSet* > TextureSetContainer; +typedef TextureSetContainer::Iterator TextureSetIter; +typedef TextureSetContainer::ConstIterator TextureSetConstIter; /** * Structure to contain UpdateManager internal data @@ -147,7 +124,6 @@ typedef GestureContainer::ConstIterator GestureConstIter; struct UpdateManager::Impl { Impl( NotificationManager& notificationManager, - GlSyncAbstraction& glSyncAbstraction, CompleteNotificationInterface& animationFinishedNotifier, PropertyNotifier& propertyNotifier, ResourceManager& resourceManager, @@ -155,14 +131,14 @@ struct UpdateManager::Impl RenderController& renderController, RenderManager& renderManager, RenderQueue& renderQueue, - TextureCache& textureCache, - TouchResampler& touchResampler, - SceneGraphBuffers& sceneGraphBuffers ) - : - renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ), + SceneGraphBuffers& sceneGraphBuffers, + RenderTaskProcessor& renderTaskProcessor ) + : renderMessageDispatcher( renderManager, renderQueue, sceneGraphBuffers ), notificationManager( notificationManager ), + transformManager(), animationFinishedNotifier( animationFinishedNotifier ), propertyNotifier( propertyNotifier ), + shaderSaver( NULL ), resourceManager( resourceManager ), discardQueue( discardQueue ), renderController( renderController ), @@ -170,25 +146,28 @@ struct UpdateManager::Impl renderManager( renderManager ), renderQueue( renderQueue ), renderInstructions( renderManager.GetRenderInstructionContainer() ), - completeStatusManager( glSyncAbstraction, renderMessageDispatcher, resourceManager ), - touchResampler( touchResampler ), + renderTaskProcessor( renderTaskProcessor ), backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ), - taskList ( completeStatusManager ), - systemLevelTaskList ( completeStatusManager ), + taskList( renderMessageDispatcher, resourceManager ), + systemLevelTaskList( renderMessageDispatcher, resourceManager ), root( NULL ), systemLevelRoot( NULL ), + renderers( sceneGraphBuffers, discardQueue ), + textureSets(), messageQueue( renderController, sceneGraphBuffers ), - dynamicsChanged( false ), keepRenderingSeconds( 0.0f ), animationFinishedDuringUpdate( false ), - activeConstraints( 0 ), nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update() previousUpdateScene( false ), frameCounter( 0 ), - renderSortingHelper(), renderTaskWaiting( false ) { - sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager ); + sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue ); + + renderers.SetSceneController( *sceneController ); + + // create first 'dummy' node + nodes.PushBack(0u); } ~Impl() @@ -207,16 +186,20 @@ struct UpdateManager::Impl } // UpdateManager owns the Nodes - DestroyNodeSet( activeDisconnectedNodes ); - DestroyNodeSet( connectedNodes ); - DestroyNodeSet( disconnectedNodes ); + Vector::Iterator iter = nodes.Begin()+1; + Vector::Iterator endIter = nodes.End(); + 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 ) { root->OnDestroy(); - delete root; + Node::Delete( root ); root = NULL; } @@ -224,19 +207,20 @@ struct UpdateManager::Impl { systemLevelRoot->OnDestroy(); - delete systemLevelRoot; + Node::Delete( systemLevelRoot ); systemLevelRoot = NULL; } - sceneController->GetTextureCache().SetBufferIndices(NULL); // TODO - Remove delete sceneController; } SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread NotificationManager& notificationManager; ///< Queues notification messages for the event-thread. + TransformManager transformManager; ///< Used to update the transformation matrices of the nodes CompleteNotificationInterface& animationFinishedNotifier; ///< Provides notification to applications when animations are finished. PropertyNotifier& propertyNotifier; ///< Provides notification to applications when properties are modified. + ShaderSaver* shaderSaver; ///< Saves shader binaries. ResourceManager& resourceManager; ///< resource manager DiscardQueue& discardQueue; ///< Nodes are added here when disconnected from the scene-graph. RenderController& renderController; ///< render controller @@ -244,8 +228,7 @@ struct UpdateManager::Impl RenderManager& renderManager; ///< This is responsible for rendering the results of each "update" RenderQueue& renderQueue; ///< Used to queue messages for the next render RenderInstructionContainer& renderInstructions; ///< Used to prepare the render instructions - CompleteStatusManager completeStatusManager; ///< Complete Status Manager - TouchResampler& touchResampler; ///< Used to resample touch events on every update. + RenderTaskProcessor& renderTaskProcessor; ///< Handles RenderTasks and RenderInstrucitons Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame. @@ -254,45 +237,41 @@ struct UpdateManager::Impl Layer* root; ///< The root node (root is a layer) Layer* systemLevelRoot; ///< A separate root-node for system-level content - std::set< Node* > activeDisconnectedNodes; ///< A container of new or modified nodes (without parent) owned by UpdateManager - std::set< Node* > connectedNodes; ///< A container of connected (with parent) nodes owned by UpdateManager - std::set< Node* > disconnectedNodes; ///< A container of inactive disconnected nodes (without parent) owned by UpdateManager + + Vector nodes; ///< A container of all instantiated nodes SortedLayerPointers sortedLayers; ///< A container of Layer pointers sorted by depth SortedLayerPointers systemLevelSortedLayers; ///< A separate container of system-level Layers + OwnerContainer< Camera* > cameras; ///< A container of cameras OwnerContainer< PropertyOwner* > customObjects; ///< A container of owned objects (with custom properties) AnimationContainer animations; ///< A container of owned animations PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications. + ObjectOwnerContainer renderers; + TextureSetContainer textureSets; ///< A container of texture sets + ShaderContainer shaders; ///< A container of owned shaders - AnimatableMeshContainer animatableMeshes; ///< A container of owned animatable meshes - MaterialContainer materials; ///< A container of owned materials MessageQueue messageQueue; ///< The messages queued from the event-thread - -#ifdef DYNAMICS_SUPPORT - OwnerPointer dynamicsWorld; ///< Wrapper for dynamics simulation -#endif - bool dynamicsChanged; ///< This is set to true if an object is changed in the dynamics simulation tick + ShaderDataBinaryQueue renderCompiledShaders; ///< Shaders compiled on Render thread are inserted here for update thread to pass on to event thread. + ShaderDataBinaryQueue updateCompiledShaders; ///< Shaders to be sent from Update to Event + Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update() - unsigned int activeConstraints; ///< number of active constraints from previous frame int nodeDirtyFlags; ///< cumulative node dirty flags from previous frame bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out) int frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore. - RendererSortingHelper renderSortingHelper; ///< helper used to sort transparent renderers GestureContainer gestures; ///< A container of owned gesture detectors bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered }; UpdateManager::UpdateManager( NotificationManager& notificationManager, - GlSyncAbstraction& glSyncAbstraction, CompleteNotificationInterface& animationFinishedNotifier, PropertyNotifier& propertyNotifier, ResourceManager& resourceManager, @@ -300,12 +279,11 @@ UpdateManager::UpdateManager( NotificationManager& notificationManager, RenderController& controller, RenderManager& renderManager, RenderQueue& renderQueue, - TextureCache& textureCache, - TouchResampler& touchResampler ) + TextureCacheDispatcher& textureCacheDispatcher, + RenderTaskProcessor& renderTaskProcessor ) : mImpl(NULL) { mImpl = new Impl( notificationManager, - glSyncAbstraction, animationFinishedNotifier, propertyNotifier, resourceManager, @@ -313,11 +291,10 @@ UpdateManager::UpdateManager( NotificationManager& notificationManager, controller, renderManager, renderQueue, - textureCache, - touchResampler, - mSceneGraphBuffers ); + mSceneGraphBuffers, + renderTaskProcessor ); - textureCache.SetBufferIndices( &mSceneGraphBuffers ); + textureCacheDispatcher.SetBufferIndices( &mSceneGraphBuffers ); } UpdateManager::~UpdateManager() @@ -325,11 +302,6 @@ UpdateManager::~UpdateManager() delete mImpl; } -EventToUpdate& UpdateManager::GetEventToUpdate() -{ - return mImpl->messageQueue; -} - void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel ) { DALI_ASSERT_DEBUG( layer->IsLayer() ); @@ -339,11 +311,13 @@ void UpdateManager::InstallRoot( SceneGraph::Layer* layer, bool systemLevel ) { DALI_ASSERT_DEBUG( mImpl->root == NULL && "Root Node already installed" ); mImpl->root = layer; + mImpl->root->CreateTransform( &mImpl->transformManager); } else { DALI_ASSERT_DEBUG( mImpl->systemLevelRoot == NULL && "System-level Root Node already installed" ); mImpl->systemLevelRoot = layer; + mImpl->systemLevelRoot->CreateTransform( &mImpl->transformManager); } layer->SetRoot(true); @@ -354,27 +328,26 @@ void UpdateManager::AddNode( Node* node ) DALI_ASSERT_ALWAYS( NULL != node ); DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet - mImpl->activeDisconnectedNodes.insert( node ); // Takes ownership of node + // Nodes must be sorted by pointer + Vector::Iterator begin = mImpl->nodes.Begin(); + for(Vector::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter) + { + if(node > (*iter)) + { + mImpl->nodes.Insert((iter+1), node); + node->CreateTransform( &mImpl->transformManager); + break; + } + } } -void UpdateManager::ConnectNode( Node* parent, Node* node, int index ) +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 - // Move from active/disconnectedNodes to connectedNodes - std::set::size_type removed = mImpl->activeDisconnectedNodes.erase( node ); - if( !removed ) - { - removed = mImpl->disconnectedNodes.erase( node ); - DALI_ASSERT_ALWAYS( removed ); - } - mImpl->connectedNodes.insert( node ); - - node->SetActive( true ); - - parent->ConnectChild( node, index ); + parent->ConnectChild( node ); } void UpdateManager::DisconnectNode( Node* node ) @@ -383,21 +356,7 @@ void UpdateManager::DisconnectNode( Node* node ) DALI_ASSERT_ALWAYS( NULL != parent ); parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused - // Move from connectedNodes to activeDisconnectedNodes (reset properties next frame) - parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node, mImpl->connectedNodes, mImpl->activeDisconnectedNodes ); -} - -void UpdateManager::SetNodeActive( Node* node ) -{ - DALI_ASSERT_ALWAYS( NULL != node ); - DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet - - // Move from disconnectedNodes to activeDisconnectedNodes (reset properties next frame) - std::set::size_type removed = mImpl->disconnectedNodes.erase( node ); - DALI_ASSERT_ALWAYS( removed ); - mImpl->activeDisconnectedNodes.insert( node ); - - node->SetActive( true ); + parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node ); } void UpdateManager::DestroyNode( Node* node ) @@ -405,28 +364,47 @@ void UpdateManager::DestroyNode( Node* node ) DALI_ASSERT_ALWAYS( NULL != node ); DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected - // Transfer ownership from new/disconnectedNodes to the discard queue - // This keeps the nodes alive, until the render-thread has finished with them - std::set::size_type removed = mImpl->activeDisconnectedNodes.erase( node ); - if( !removed ) + Vector::Iterator iter = mImpl->nodes.Begin()+1; + Vector::Iterator endIter = mImpl->nodes.End(); + for(;iter!=endIter;++iter) { - removed = mImpl->disconnectedNodes.erase( node ); - DALI_ASSERT_ALWAYS( removed ); + if((*iter) == node) + { + mImpl->nodes.Erase(iter); + break; + } } + mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), node ); // Notify the Node about impending destruction node->OnDestroy(); } -void UpdateManager::AttachToNode( Node* node, NodeAttachment* attachment ) +void UpdateManager::AddCamera( Camera* camera ) { - DALI_ASSERT_DEBUG( node != NULL ); - DALI_ASSERT_DEBUG( attachment != NULL ); + DALI_ASSERT_DEBUG( camera != NULL ); + + mImpl->cameras.PushBack( camera ); // takes ownership +} + +void UpdateManager::RemoveCamera( const Camera* camera ) +{ + // Find the camera + OwnerContainer::Iterator iter = mImpl->cameras.Begin(); + OwnerContainer::ConstIterator end = mImpl->cameras.End(); + for ( ; iter != end; ++iter ) + { + Camera* value = *iter; + if ( camera == value ) + { + // Transfer ownership to the discard queue + mImpl->discardQueue.Add( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->cameras.Release( iter ) ); + + return; + } + } - // attach node to attachment first so that parent is known by the time attachment is connected - node->Attach( *attachment ); // node takes ownership - attachment->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() ); } void UpdateManager::AddObject( PropertyOwner* object ) @@ -529,6 +507,11 @@ void UpdateManager::PropertyNotificationSetNotify( PropertyNotification* propert propertyNotification->SetNotifyMode( notifyMode ); } +ObjectOwnerContainer& UpdateManager::GetRendererOwner() +{ + return mImpl->renderers; +} + void UpdateManager::AddShader( Shader* shader ) { DALI_ASSERT_DEBUG( NULL != shader ); @@ -547,12 +530,9 @@ void UpdateManager::AddShader( Shader* shader ) } mImpl->shaders.PushBack( shader ); - - // Allows the shader to dispatch texture requests to the cache - shader->Initialize( mImpl->renderQueue, mImpl->sceneController->GetTextureCache() ); } -void UpdateManager::RemoveShader(Shader* shader) +void UpdateManager::RemoveShader( Shader* shader ) { DALI_ASSERT_DEBUG(shader != NULL); @@ -575,91 +555,30 @@ void UpdateManager::RemoveShader(Shader* shader) DALI_ASSERT_DEBUG(false); } -void UpdateManager::SetShaderProgram( Shader* shader, GeometryType geometryType, ShaderSubTypes subType, ResourceId resourceId, size_t shaderHash, bool modifiesGeometry ) +void UpdateManager::SetShaderProgram( Shader* shader, + Internal::ShaderDataPtr shaderData, bool modifiesGeometry ) { - DALI_LOG_TRACE_METHOD_FMT(Debug::Filter::gShader, " - (geometryType:%d subType:%d id:%d hash:%d)\n", geometryType, subType, resourceId, shaderHash); - - DALI_ASSERT_ALWAYS( NULL != shader && "shader is uninitialized" ); - - Integration::ShaderDataPtr shaderData( mImpl->resourceManager.GetShaderData(resourceId) ); if( shaderData ) { - shaderData->SetHashValue( shaderHash ); - shaderData->SetResourceId( resourceId ); - typedef MessageValue6< Shader, GeometryType, Internal::ShaderSubTypes, Integration::ResourceId, Integration::ShaderDataPtr, ProgramCache*, bool> DerivedType; + 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 ) ); // Construct message in the render queue memory; note that delete should not be called on the return value - new (slot) DerivedType( shader, &Shader::SetProgram, geometryType, subType, resourceId, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry ); + new (slot) DerivedType( shader, &Shader::SetProgram, shaderData, mImpl->renderManager.GetProgramCache(), modifiesGeometry ); } } -void UpdateManager::AddAnimatableMesh( AnimatableMesh* animatableMesh ) -{ - mImpl->animatableMeshes.PushBack(animatableMesh); -} - -void UpdateManager::RemoveAnimatableMesh( AnimatableMesh* animatableMesh ) -{ - DALI_ASSERT_DEBUG(animatableMesh != NULL); - - AnimatableMeshContainer& animatableMeshes = mImpl->animatableMeshes; - - // Find the animatableMesh and destroy it - for ( AnimatableMeshIter iter = animatableMeshes.Begin(); iter != animatableMeshes.End(); ++iter ) - { - AnimatableMesh& current = **iter; - if ( ¤t == animatableMesh ) - { - animatableMeshes.Erase( iter ); - break; - } - } -} - -void UpdateManager::AddMaterial( Material* material ) -{ - DALI_ASSERT_DEBUG( NULL != material ); - - mImpl->materials.PushBack( material ); - RenderMaterial* renderMaterial = new RenderMaterial(); - - typedef MessageValue1< RenderManager, RenderMaterial* > 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::AddRenderMaterial, renderMaterial ); - - material->SetRenderMaterial( renderMaterial ); - material->OnStageConnection( *mImpl->sceneController ); -} - -void UpdateManager::RemoveMaterial( Material* theMaterial ) +void UpdateManager::SaveBinary( Internal::ShaderDataPtr shaderData ) { - // Caused by last reference to material being released (e.g. app or internal mesh-actor) - - for ( MaterialIter iter=mImpl->materials.Begin(), end=mImpl->materials.End() ; iter != end ; ++iter ) + DALI_ASSERT_DEBUG( shaderData && "No NULL shader data pointers please." ); + DALI_ASSERT_DEBUG( shaderData->GetBufferSize() > 0 && "Shader binary empty so nothing to save." ); { - const Material* aMaterial = *iter; - - if( aMaterial == theMaterial ) - { - typedef MessageValue1< RenderManager, RenderMaterial* > 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::RemoveRenderMaterial, theMaterial->GetRenderMaterial() ); - - mImpl->materials.Erase( iter ); - break; - } + // lock as update might be sending previously compiled shaders to event thread + Mutex::ScopedLock lock( mImpl->compiledShaderMutex ); + mImpl->renderCompiledShaders.push_back( shaderData ); } } @@ -704,48 +623,67 @@ void UpdateManager::RemoveGesture( PanGesture* gesture ) DALI_ASSERT_DEBUG(false); } -void UpdateManager::ResetNodeProperty( Node& node ) +void UpdateManager::AddTextureSet( TextureSet* textureSet ) +{ + DALI_ASSERT_DEBUG( NULL != textureSet ); + mImpl->textureSets.PushBack( textureSet ); +} + +void UpdateManager::RemoveTextureSet( TextureSet* textureSet ) { - node.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() ); + DALI_ASSERT_DEBUG(textureSet != NULL); + size_t textureSetCount( mImpl->textureSets.Size() ); + for( size_t i(0); itextureSets[i] ) + { + mImpl->textureSets.Remove( mImpl->textureSets.Begin() + i ); + + // Update manager has ownership of the TextureSet + delete textureSet; + return; + } + } } -void UpdateManager::ResetProperties() +unsigned int* UpdateManager::ReserveMessageSlot( std::size_t size, bool updateScene ) { - PERF_MONITOR_START(PerformanceMonitor::RESET_PROPERTIES); + return mImpl->messageQueue.ReserveMessageSlot( size, updateScene ); +} +void UpdateManager::EventProcessingStarted() +{ + mImpl->messageQueue.EventProcessingStarted(); +} + +bool UpdateManager::FlushQueue() +{ + return mImpl->messageQueue.FlushQueue(); +} + +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 node properties + // Reset root properties if ( mImpl->root ) { - ResetNodeProperty( *mImpl->root ); + mImpl->root->ResetToBaseValues( bufferIndex ); } - if ( mImpl->systemLevelRoot ) { - ResetNodeProperty( *mImpl->systemLevelRoot ); - } - - // Reset the Connected Nodes - const std::set::iterator endIter = mImpl->connectedNodes.end(); - for( std::set::iterator iter = mImpl->connectedNodes.begin(); endIter != iter; ++iter ) - { - ResetNodeProperty( **iter ); + mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex ); } - // If a Node is disconnected, it may still be "active" (requires a reset in next frame) - for( std::set::iterator iter = mImpl->activeDisconnectedNodes.begin(); mImpl->activeDisconnectedNodes.end() != iter; iter = mImpl->activeDisconnectedNodes.begin() ) + // Reset all the nodes + Vector::Iterator iter = mImpl->nodes.Begin()+1; + Vector::Iterator endIter = mImpl->nodes.End(); + for(;iter != endIter; ++iter) { - Node* node = *iter; - node->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() ); - node->SetActive( false ); - - // Move everything from activeDisconnectedNodes to disconnectedNodes (no need to reset again) - mImpl->activeDisconnectedNodes.erase( iter ); - mImpl->disconnectedNodes.insert( node ); + (*iter)->ResetToBaseValues( bufferIndex ); } // Reset system-level render-task list properties to base values @@ -753,7 +691,7 @@ void UpdateManager::ResetProperties() for (RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter) { - (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() ); + (*iter)->ResetToBaseValues( bufferIndex ); } // Reset render-task list properties to base values. @@ -761,31 +699,25 @@ void UpdateManager::ResetProperties() for (RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter) { - (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() ); + (*iter)->ResetToBaseValues( bufferIndex ); } // Reset custom object properties to base values for (OwnerContainer::Iterator iter = mImpl->customObjects.Begin(); iter != mImpl->customObjects.End(); ++iter) { - (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() ); + (*iter)->ResetToBaseValues( bufferIndex ); } + mImpl->renderers.ResetToBaseValues( bufferIndex ); + // Reset animatable shader properties to base values for (ShaderIter iter = mImpl->shaders.Begin(); iter != mImpl->shaders.End(); ++iter) { - (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() ); - } - - // Reset animatable mesh properties to base values - for ( AnimatableMeshIter iter = mImpl->animatableMeshes.Begin(); iter != mImpl->animatableMeshes.End(); ++iter ) - { - (*iter)->ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() ); + (*iter)->ResetToBaseValues( bufferIndex ); } - - PERF_MONITOR_END(PerformanceMonitor::RESET_PROPERTIES); } -bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds ) +bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds ) { bool gestureUpdated( false ); @@ -795,25 +727,27 @@ bool UpdateManager::ProcessGestures( unsigned int lastVSyncTimeMilliseconds, uns for ( GestureIter iter = gestures.Begin(), endIter = gestures.End(); iter != endIter; ++iter ) { PanGesture& gesture = **iter; - gesture.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message + gesture.ResetToBaseValues( bufferIndex ); // Needs to be done every time as gesture data is written directly to an update-buffer rather than via a message gestureUpdated |= gesture.UpdateProperties( lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds ); } return gestureUpdated; } -void UpdateManager::Animate( float elapsedSeconds ) +void UpdateManager::Animate( BufferIndex bufferIndex, float elapsedSeconds ) { - PERF_MONITOR_START(PerformanceMonitor::ANIMATE_NODES); - AnimationContainer &animations = mImpl->animations; AnimationIter iter = animations.Begin(); + bool animationLooped = false; while ( iter != animations.End() ) { Animation* animation = *iter; - bool finished = animation->Update(mSceneGraphBuffers.GetUpdateBufferIndex(), elapsedSeconds); + bool finished = false; + bool looped = false; + animation->Update( bufferIndex, elapsedSeconds, looped, finished ); mImpl->animationFinishedDuringUpdate = mImpl->animationFinishedDuringUpdate || finished; + animationLooped = animationLooped || looped; // Remove animations that had been destroyed but were still waiting for an update if (animation->GetState() == Animation::Destroyed) @@ -826,90 +760,57 @@ void UpdateManager::Animate( float elapsedSeconds ) } } - if ( mImpl->animationFinishedDuringUpdate ) + // queue the notification on finished or looped (to update loop count) + if ( mImpl->animationFinishedDuringUpdate || animationLooped ) { // The application should be notified by NotificationManager, in another thread mImpl->notificationManager.QueueCompleteNotification( &mImpl->animationFinishedNotifier ); } - - PERF_MONITOR_END(PerformanceMonitor::ANIMATE_NODES); } -void UpdateManager::ApplyConstraints() +void UpdateManager::ConstrainCustomObjects( BufferIndex bufferIndex ) { - PERF_MONITOR_START(PerformanceMonitor::APPLY_CONSTRAINTS); - - mImpl->activeConstraints = 0; - - // constrain custom objects... (in construction order) + //Constrain custom objects (in construction order) OwnerContainer< PropertyOwner* >& customObjects = mImpl->customObjects; - const OwnerContainer< PropertyOwner* >::Iterator endIter = customObjects.End(); for ( OwnerContainer< PropertyOwner* >::Iterator iter = customObjects.Begin(); endIter != iter; ++iter ) { PropertyOwner& object = **iter; - mImpl->activeConstraints += ConstrainPropertyOwner( object, mSceneGraphBuffers.GetUpdateBufferIndex() ); + ConstrainPropertyOwner( object, bufferIndex ); } +} - // constrain nodes... (in Depth First traversal order) - if ( mImpl->root ) - { - mImpl->activeConstraints += ConstrainNodes( *(mImpl->root), mSceneGraphBuffers.GetUpdateBufferIndex() ); - } - - if ( mImpl->systemLevelRoot ) - { - mImpl->activeConstraints += ConstrainNodes( *(mImpl->systemLevelRoot), mSceneGraphBuffers.GetUpdateBufferIndex() ); - } - - // constrain other property-owners after nodes as they are more likely to depend on a node's - // current frame property than vice versa. They tend to be final constraints (no further - // constraints depend on their properties) - // e.g. ShaderEffect uniform a function of Actor's position. - // Mesh vertex a function of Actor's position or world position. - - // TODO: refactor this code (and reset nodes) as these are all just lists of property-owners - // they can be all processed in a super-list of property-owners. - +void UpdateManager::ConstrainRenderTasks( BufferIndex bufferIndex ) +{ // Constrain system-level render-tasks const RenderTaskList::RenderTaskContainer& systemLevelTasks = mImpl->systemLevelTaskList.GetTasks(); - for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = systemLevelTasks.Begin(); iter != systemLevelTasks.End(); ++iter ) { RenderTask& task = **iter; - mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() ); + ConstrainPropertyOwner( task, bufferIndex ); } // Constrain render-tasks const RenderTaskList::RenderTaskContainer& tasks = mImpl->taskList.GetTasks(); - for ( RenderTaskList::RenderTaskContainer::ConstIterator iter = tasks.Begin(); iter != tasks.End(); ++iter ) { RenderTask& task = **iter; - mImpl->activeConstraints += ConstrainPropertyOwner( task, mSceneGraphBuffers.GetUpdateBufferIndex() ); - } - - // constrain meshes (in construction order) - AnimatableMeshContainer& meshes = mImpl->animatableMeshes; - for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter ) - { - AnimatableMesh& mesh = **iter; - mImpl->activeConstraints += ConstrainPropertyOwner( mesh, mSceneGraphBuffers.GetUpdateBufferIndex() ); + ConstrainPropertyOwner( task, bufferIndex ); } +} +void UpdateManager::ConstrainShaders( BufferIndex bufferIndex ) +{ // constrain shaders... (in construction order) ShaderContainer& shaders = mImpl->shaders; - for ( ShaderIter iter = shaders.Begin(); iter != shaders.End(); ++iter ) { Shader& shader = **iter; - mImpl->activeConstraints += ConstrainPropertyOwner( shader, mSceneGraphBuffers.GetUpdateBufferIndex() ); + ConstrainPropertyOwner( shader, bufferIndex ); } - - PERF_MONITOR_END(PerformanceMonitor::APPLY_CONSTRAINTS); } -void UpdateManager::ProcessPropertyNotifications() +void UpdateManager::ProcessPropertyNotifications( BufferIndex bufferIndex ) { PropertyNotificationContainer ¬ifications = mImpl->propertyNotifications; PropertyNotificationIter iter = notifications.Begin(); @@ -917,9 +818,7 @@ void UpdateManager::ProcessPropertyNotifications() while ( iter != notifications.End() ) { PropertyNotification* notification = *iter; - - bool valid = notification->Check( mSceneGraphBuffers.GetUpdateBufferIndex() ); - + bool valid = notification->Check( bufferIndex ); if(valid) { mImpl->notificationManager.QueueMessage( PropertyChangedMessage( mImpl->propertyNotifier, notification, notification->GetValidity() ) ); @@ -928,59 +827,78 @@ void UpdateManager::ProcessPropertyNotifications() } } -void UpdateManager::UpdateNodes() +void UpdateManager::PrepareTextureSets( BufferIndex bufferIndex ) { - mImpl->nodeDirtyFlags = NothingFlag; - - if ( !mImpl->root ) + size_t textureSetCount( mImpl->textureSets.Size() ); + for( size_t i(0); itextureSets[i]->Prepare( mImpl->resourceManager ); } +} - PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES ); - - // Prepare resources, update shaders, update attachments, for each node - // And add the renderers to the sorted layers. Start from root, which is also a layer - mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ), - mSceneGraphBuffers.GetUpdateBufferIndex(), - mImpl->resourceManager, - mImpl->renderQueue ); - - if ( mImpl->systemLevelRoot ) +void UpdateManager::ForwardCompiledShadersToEventThread() +{ + DALI_ASSERT_DEBUG( (mImpl->shaderSaver != 0) && "shaderSaver should be wired-up during startup." ); + if( mImpl->shaderSaver ) { - mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ), - mSceneGraphBuffers.GetUpdateBufferIndex(), - mImpl->resourceManager, - mImpl->renderQueue ); - } + // 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 ); + } - PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES ); + if( mImpl->updateCompiledShaders.size() > 0 ) + { + ShaderSaver& factory = *mImpl->shaderSaver; + ShaderDataBinaryQueue::iterator i = mImpl->updateCompiledShaders.begin(); + ShaderDataBinaryQueue::iterator end = mImpl->updateCompiledShaders.end(); + for( ; i != end; ++i ) + { + mImpl->notificationManager.QueueMessage( ShaderCompiledMessage( factory, *i ) ); + } + // we don't need them in update anymore + mImpl->updateCompiledShaders.clear(); + } + } } -void UpdateManager::UpdateMeshes( BufferIndex updateBufferIndex, AnimatableMeshContainer& meshes ) +void UpdateManager::UpdateRenderers( BufferIndex bufferIndex ) { - for ( AnimatableMeshIter iter = meshes.Begin(); iter != meshes.End(); ++iter ) + const OwnerContainer& rendererContainer( mImpl->renderers.GetObjectContainer() ); + unsigned int rendererCount( rendererContainer.Size() ); + for( unsigned int i(0); iPrepareRender( bufferIndex ); } } -void UpdateManager::UpdateMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials ) +void UpdateManager::UpdateNodes( BufferIndex bufferIndex ) { - for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ ) + mImpl->nodeDirtyFlags = NothingFlag; + + if ( !mImpl->root ) { - Material* material = *iter; - material->PrepareResources( updateBufferIndex, mImpl->resourceManager ); + return; } -} -void UpdateManager::PrepareMaterials( BufferIndex updateBufferIndex, MaterialContainer& materials ) -{ - for( MaterialIter iter = materials.Begin(), end = materials.End(); iter != end; iter++ ) + // Prepare resources, update shaders, for each node + // And add the renderers to the sorted layers. Start from root, which is also a layer + mImpl->nodeDirtyFlags = UpdateNodeTree( *( mImpl->root ), + bufferIndex, + mImpl->resourceManager, + mImpl->renderQueue ); + + if ( mImpl->systemLevelRoot ) { - Material* material = *iter; - material->PrepareRender( updateBufferIndex ); + mImpl->nodeDirtyFlags |= UpdateNodeTree( *( mImpl->systemLevelRoot ), + bufferIndex, + mImpl->resourceManager, + mImpl->renderQueue ); } } @@ -988,120 +906,108 @@ unsigned int UpdateManager::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds ) { - PERF_MONITOR_END(PerformanceMonitor::FRAME_RATE); // Mark the End of the last frame - PERF_MONITOR_NEXT_FRAME(); // Prints out performance info for the last frame (if enabled) - PERF_MONITOR_START(PerformanceMonitor::FRAME_RATE); // Mark the start of this current frame - - // Measure the time spent in UpdateManager::Update - PERF_MONITOR_START(PerformanceMonitor::UPDATE); + const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex(); - // Update the frame time delta on the render thread. - mImpl->renderManager.SetFrameDeltaTime(elapsedSeconds); + //Clear nodes/resources which were previously discarded + mImpl->discardQueue.Clear( bufferIndex ); - // 1) Clear nodes/resources which were previously discarded - mImpl->discardQueue.Clear( mSceneGraphBuffers.GetUpdateBufferIndex() ); + //Grab any loaded resources + bool resourceChanged = mImpl->resourceManager.UpdateCache( bufferIndex ); - // 2) Grab any loaded resources - bool resourceChanged = mImpl->resourceManager.UpdateCache( mSceneGraphBuffers.GetUpdateBufferIndex() ); + //Process Touches & Gestures + const bool gestureUpdated = ProcessGestures( bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds ); - // 3) Process Touches & Gestures - mImpl->touchResampler.Update(); - const bool gestureUpdated = ProcessGestures( 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 + resourceChanged || // ..one or more resources were updated/changed OR + gestureUpdated; // ..a gesture property was updated - const bool updateScene = // The scene-graph requires an update if.. - mImpl->activeConstraints != 0 || // ..constraints were active in previous frame OR - (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR - IsAnimationRunning() || // ..at least one animation is running OR - mImpl->dynamicsChanged || // ..there was a change in the dynamics simulation OR - mImpl->messageQueue.IsSceneUpdateRequired() || // ..a message that modifies the scene graph node tree is queued OR - resourceChanged || // ..one or more resources were updated/changed OR - gestureUpdated; // ..a gesture property was updated // Although the scene-graph may not require an update, we still need to synchronize double-buffered // values if the scene was updated in the previous frame. if( updateScene || mImpl->previousUpdateScene ) { - // 4) Reset properties from the previous update - ResetProperties(); + //Reset properties from the previous update + ResetProperties( bufferIndex ); + mImpl->transformManager.ResetToBaseValue(); } - // 5) Process the queued scene messages - mImpl->messageQueue.ProcessMessages(); + // 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 ); + + //Post Process Ids of resources updated by renderer + mImpl->resourceManager.PostProcessResources( bufferIndex ); - // 6) Post Process Ids of resources updated by renderer - mImpl->resourceManager.PostProcessResources( mSceneGraphBuffers.GetUpdateBufferIndex() ); + //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 ) { - // 7) Animate - Animate( elapsedSeconds ); + //Animate + Animate( bufferIndex, elapsedSeconds ); - // 8) Apply Constraints - ApplyConstraints(); + //Constraint custom objects + ConstrainCustomObjects( bufferIndex ); -#ifdef DYNAMICS_SUPPORT - // 9) Update dynamics simulation - mImpl->dynamicsChanged = false; - if( mImpl->dynamicsWorld ) + //Prepare texture sets and apply constraints to them + PrepareTextureSets( bufferIndex ); + + //Clear the lists of renderers from the previous update + for( size_t i(0); isortedLayers.size(); ++i ) { - mImpl->dynamicsChanged = mImpl->dynamicsWorld->Update( elapsedSeconds ); + mImpl->sortedLayers[i]->ClearRenderables(); } -#endif - - // 10) Check Property Notifications - ProcessPropertyNotifications(); - // 11) Clear the lists of renderable-attachments from the previous update - ClearRenderables( mImpl->sortedLayers ); - ClearRenderables( mImpl->systemLevelSortedLayers ); + for( size_t i(0); isystemLevelSortedLayers.size(); ++i ) + { + mImpl->systemLevelSortedLayers[i]->ClearRenderables(); + } - // 12) Update animated meshes - UpdateMeshes( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->animatableMeshes ); + //Update node hierarchy, apply constraints and perform sorting / culling. + //This will populate each Layer with a list of renderers which are ready. + UpdateNodes( bufferIndex ); - // 13) Update materials. Prepares image resources - UpdateMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials ); + //Apply constraints to RenderTasks, shaders + ConstrainRenderTasks( bufferIndex ); + ConstrainShaders( bufferIndex ); - // 14) Update node hierarchy and perform sorting / culling. - // This will populate each Layer with a list of renderers which are ready. - UpdateNodes(); + //Update renderers and apply constraints + UpdateRenderers( bufferIndex ); - // 15) Prepare for the next render - PERF_MONITOR_START(PerformanceMonitor::PREPARE_RENDERABLES); - PrepareMaterials( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->materials ); - PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->sortedLayers ); - PrepareRenderables( mSceneGraphBuffers.GetUpdateBufferIndex(), mImpl->systemLevelSortedLayers ); - PERF_MONITOR_END(PerformanceMonitor::PREPARE_RENDERABLES); + //Update the trnasformations of all the nodes + mImpl->transformManager.Update(); - PERF_MONITOR_START(PerformanceMonitor::PROCESS_RENDER_TASKS); + //Process Property Notifications + ProcessPropertyNotifications( bufferIndex ); - // 16) Process the RenderTasks; this creates the instructions for rendering the next frame. - // reset the update buffer index and make sure there is enough room in the instruction container - mImpl->renderInstructions.ResetAndReserve( mSceneGraphBuffers.GetUpdateBufferIndex(), + //Process the RenderTasks; this creates the instructions for rendering the next frame. + //reset the update buffer index and make sure there is enough room in the instruction container + mImpl->renderInstructions.ResetAndReserve( bufferIndex, mImpl->taskList.GetTasks().Count() + mImpl->systemLevelTaskList.GetTasks().Count() ); if ( NULL != mImpl->root ) { - ProcessRenderTasks( mSceneGraphBuffers.GetUpdateBufferIndex(), - mImpl->completeStatusManager, - mImpl->taskList, - *mImpl->root, - mImpl->sortedLayers, - mImpl->renderSortingHelper, - mImpl->renderInstructions ); + mImpl->renderTaskProcessor.Process( bufferIndex, + mImpl->taskList, + *mImpl->root, + mImpl->sortedLayers, + mImpl->renderInstructions ); // Process the system-level RenderTasks last if ( NULL != mImpl->systemLevelRoot ) { - ProcessRenderTasks( mSceneGraphBuffers.GetUpdateBufferIndex(), - mImpl->completeStatusManager, - mImpl->systemLevelTaskList, - *mImpl->systemLevelRoot, - mImpl->systemLevelSortedLayers, - mImpl->renderSortingHelper, - mImpl->renderInstructions ); + mImpl->renderTaskProcessor.Process( bufferIndex, + mImpl->systemLevelTaskList, + *mImpl->systemLevelRoot, + mImpl->systemLevelSortedLayers, + mImpl->renderInstructions ); } } } @@ -1118,7 +1024,7 @@ unsigned int UpdateManager::Update( float elapsedSeconds, renderTask.UpdateState(); if( renderTask.IsWaitingToRender() && - renderTask.ReadyToRender(mSceneGraphBuffers.GetUpdateBufferIndex()) /*avoid updating forever when source actor is off-stage*/ ) + renderTask.ReadyToRender( bufferIndex ) /*avoid updating forever when source actor is off-stage*/ ) { mImpl->renderTaskWaiting = true; // keep update/render threads alive } @@ -1135,8 +1041,6 @@ unsigned int UpdateManager::Update( float elapsedSeconds, mImpl->notificationManager.QueueCompleteNotification( mImpl->taskList.GetCompleteNotificationInterface() ); } - PERF_MONITOR_END(PerformanceMonitor::PROCESS_RENDER_TASKS); - // Macro is undefined in release build. SNAPSHOT_NODE_LOGGING; @@ -1146,18 +1050,11 @@ unsigned int UpdateManager::Update( float elapsedSeconds, // Check whether further updates are required unsigned int keepUpdating = KeepUpdatingCheck( elapsedSeconds ); -#ifdef PERFORMANCE_MONITOR_ENABLED - // Always keep rendering when measuring FPS - keepUpdating |= KeepUpdating::MONITORING_PERFORMANCE; -#endif - - // The update has finished; swap the double-buffering indices - mSceneGraphBuffers.Swap(); - // tell the update manager that we're done so the queue can be given to event thread mImpl->notificationManager.UpdateCompleted(); - PERF_MONITOR_END(PerformanceMonitor::UPDATE); + // The update has finished; swap the double-buffering indices + mSceneGraphBuffers.Swap(); return keepUpdating; } @@ -1183,22 +1080,12 @@ unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING; } - if ( !mImpl->messageQueue.WasEmpty() ) - { - keepUpdatingRequest |= KeepUpdating::INCOMING_MESSAGES; - } - if ( IsAnimationRunning() || mImpl->animationFinishedDuringUpdate ) { keepUpdatingRequest |= KeepUpdating::ANIMATIONS_RUNNING; } - if ( mImpl->dynamicsChanged ) - { - keepUpdatingRequest |= KeepUpdating::DYNAMICS_CHANGED; - } - if ( mImpl->renderTaskWaiting ) { keepUpdatingRequest |= KeepUpdating::RENDER_TASK_SYNC; @@ -1247,20 +1134,241 @@ void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool syst } } -#ifdef DYNAMICS_SUPPORT +void UpdateManager::SetShaderSaver( ShaderSaver& upstream ) +{ + mImpl->shaderSaver = &upstream; +} + +void UpdateManager::AddSampler( Render::Sampler* sampler ) +{ + typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // 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 ); +} + +void UpdateManager::RemoveSampler( Render::Sampler* sampler ) +{ + typedef MessageValue1< RenderManager, Render::Sampler* > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // 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 ) +{ + typedef MessageValue3< RenderManager, Render::Sampler*, unsigned int, unsigned int > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetFilterMode, sampler, minFilterMode, magFilterMode ); +} + +void UpdateManager::SetWrapMode( Render::Sampler* sampler, unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode ) +{ + typedef MessageValue4< RenderManager, Render::Sampler*, unsigned int, unsigned int, unsigned int > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetWrapMode, sampler, rWrapMode, sWrapMode, tWrapMode ); +} + +void UpdateManager::AddPropertyBuffer( Render::PropertyBuffer* propertyBuffer ) +{ + typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddPropertyBuffer, propertyBuffer ); +} + +void UpdateManager::RemovePropertyBuffer( Render::PropertyBuffer* propertyBuffer ) +{ + typedef MessageValue1< RenderManager, Render::PropertyBuffer* > DerivedType; + + // Reserve some memory inside the render queue + 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::RemovePropertyBuffer, propertyBuffer ); +} + +void UpdateManager::SetPropertyBufferFormat(Render::PropertyBuffer* propertyBuffer, Render::PropertyBuffer::Format* format ) +{ + typedef MessageValue2< RenderManager, Render::PropertyBuffer*, Render::PropertyBuffer::Format* > 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::SetPropertyBufferFormat, propertyBuffer, format ); +} + +void UpdateManager::SetPropertyBufferData( Render::PropertyBuffer* propertyBuffer, Dali::Vector* data, size_t size ) +{ + typedef MessageValue3< RenderManager, Render::PropertyBuffer*, Dali::Vector*, size_t > 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::SetPropertyBufferData, propertyBuffer, data, size ); +} + +void UpdateManager::AddGeometry( Render::Geometry* geometry ) +{ + typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddGeometry, geometry ); +} + +void UpdateManager::RemoveGeometry( Render::Geometry* geometry ) +{ + typedef MessageValue1< RenderManager, Render::Geometry* > DerivedType; + + // Reserve some memory inside the render queue + 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::RemoveGeometry, geometry ); +} -void UpdateManager::InitializeDynamicsWorld( SceneGraph::DynamicsWorld* dynamicsWorld, Integration::DynamicsWorldSettings* worldSettings ) +void UpdateManager::SetGeometryType( Render::Geometry* geometry, unsigned int geometryType ) { - dynamicsWorld->Initialize( mImpl->sceneController, worldSettings, &mSceneGraphBuffers ); - mImpl->dynamicsWorld = dynamicsWorld; + typedef MessageValue2< RenderManager, Render::Geometry*, unsigned int > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetGeometryType, geometry, geometryType ); } -void UpdateManager::TerminateDynamicsWorld() +void UpdateManager::SetIndexBuffer( Render::Geometry* geometry, Dali::Vector& indices ) { - mImpl->dynamicsWorld.Reset(); + typedef IndexBufferMessage< RenderManager > 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, geometry, indices ); } -#endif // DYNAMICS_SUPPORT +void UpdateManager::RemoveVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer ) +{ + typedef MessageValue2< RenderManager, Render::Geometry*, Render::PropertyBuffer* > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveVertexBuffer, geometry, propertyBuffer ); +} + +void UpdateManager::AddVertexBuffer( Render::Geometry* geometry, Render::PropertyBuffer* propertyBuffer ) +{ + 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 ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddVertexBuffer, geometry, propertyBuffer ); +} + +void UpdateManager::AddTexture( Render::NewTexture* texture ) +{ + typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddTexture, texture ); +} + +void UpdateManager::RemoveTexture( Render::NewTexture* texture) +{ + typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveTexture, texture ); +} + +void UpdateManager::UploadTexture( Render::NewTexture* texture, PixelDataPtr pixelData, const NewTexture::UploadParams& params ) +{ + typedef MessageValue3< RenderManager, Render::NewTexture*, PixelDataPtr, NewTexture::UploadParams > DerivedType; + + // Reserve some memory inside the message queue + unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the message queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::UploadTexture, texture, pixelData, params ); +} + +void UpdateManager::GenerateMipmaps( Render::NewTexture* texture ) +{ + typedef MessageValue1< RenderManager, Render::NewTexture* > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::GenerateMipmaps, texture ); +} + +void UpdateManager::AddFrameBuffer( Render::FrameBuffer* frameBuffer ) +{ + typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AddFrameBuffer, frameBuffer ); +} + +void UpdateManager::RemoveFrameBuffer( Render::FrameBuffer* frameBuffer) +{ + typedef MessageValue1< RenderManager, Render::FrameBuffer* > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::RemoveFrameBuffer, frameBuffer ); +} + +void UpdateManager::AttachColorTextureToFrameBuffer( Render::FrameBuffer* frameBuffer, Render::NewTexture* texture, unsigned int mipmapLevel, unsigned int layer ) +{ + typedef MessageValue4< RenderManager, Render::FrameBuffer*, Render::NewTexture*, unsigned int, unsigned int > DerivedType; + + // Reserve some memory inside the render queue + unsigned int* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) ); + + // Construct message in the render queue memory; note that delete should not be called on the return value + new (slot) DerivedType( &mImpl->renderManager, &RenderManager::AttachColorTextureToFrameBuffer, frameBuffer, texture, mipmapLevel, layer ); +} } // namespace SceneGraph