/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#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/update-algorithms.h>
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()
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 );
delete sceneController;
}
+ /**
+ * Lazy init for FrameCallbackProcessor.
+ */
+ FrameCallbackProcessor& GetFrameCallbackProcessor()
+ {
+ if( ! frameCallbackProcessor )
+ {
+ frameCallbackProcessor = new FrameCallbackProcessor( transformManager );
+ }
+ return *frameCallbackProcessor;
+ }
+
SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
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
PropertyNotificationContainer propertyNotifications; ///< A container of owner property notifications.
-
OwnerContainer< Renderer* > renderers; ///< A container of owned renderers
OwnerContainer< TextureSet* > textureSets; ///< A container of owned texture sets
OwnerContainer< Shader* > shaders; ///< A container of owned shaders
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.
+ 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:
DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
parent->ConnectChild( node );
+
+ // Inform the frame-callback-processor, if set, about the node-hierarchy changing
+ if( mImpl->frameCallbackProcessor )
+ {
+ mImpl->frameCallbackProcessor->NodeHierarchyChanged();
+ }
}
void UpdateManager::DisconnectNode( Node* node )
parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
+
+ // Inform the frame-callback-processor, if set, about the node-hierarchy changing
+ if( mImpl->frameCallbackProcessor )
+ {
+ mImpl->frameCallbackProcessor->NodeHierarchyChanged();
+ }
}
void UpdateManager::DestroyNode( Node* node )
return false;
}
+void UpdateManager::AddPropertyResetter( OwnerPointer<PropertyResetterBase>& propertyResetter )
+{
+ propertyResetter->Initialize();
+ mImpl->propertyResetters.PushBack( propertyResetter.Release() );
+}
+
void UpdateManager::AddPropertyNotification( OwnerPointer< PropertyNotification >& propertyNotification )
{
mImpl->propertyNotifications.PushBack( propertyNotification.Release() );
// Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped
mImpl->animationFinishedDuringUpdate = false;
- // Animated properties have to be reset to their original value each frame
-
- // Reset root properties
- if ( mImpl->root )
+ // Reset all animating / constrained properties
+ std::vector<PropertyResetterBase*>toDelete;
+ for( auto&& element : mImpl->propertyResetters )
{
- mImpl->root->ResetToBaseValues( bufferIndex );
+ element->ResetToBaseValue( bufferIndex );
+ if( element->IsFinished() )
+ {
+ toDelete.push_back( element );
+ }
}
- if ( mImpl->systemLevelRoot )
+
+ // If a resetter is no longer required (the animator or constraint has been removed), delete it.
+ for( auto&& elementPtr : toDelete )
{
- mImpl->systemLevelRoot->ResetToBaseValues( bufferIndex );
+ mImpl->propertyResetters.EraseObject( elementPtr );
}
- // Reset all the nodes
+ // Clear node dirty flags
Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
Vector<Node*>::Iterator endIter = mImpl->nodes.End();
for( ;iter != endIter; ++iter )
{
- (*iter)->ResetToBaseValues( bufferIndex );
+ (*iter)->ResetDirtyFlags( bufferIndex );
}
-
- // Reset system-level render-task list properties to base values
- ResetToBaseValues( mImpl->systemLevelTaskList.GetTasks(), bufferIndex );
-
- // Reset render-task list properties to base values.
- ResetToBaseValues( mImpl->taskList.GetTasks(), bufferIndex );
-
- // Reset custom object properties to base values
- ResetToBaseValues( mImpl->customObjects, bufferIndex );
-
- // Reset animatable renderer properties to base values
- ResetToBaseValues( mImpl->renderers, bufferIndex );
-
- // Reset animatable shader properties to base values
- ResetToBaseValues( mImpl->shaders, bufferIndex );
}
bool UpdateManager::ProcessGestures( BufferIndex bufferIndex, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds )
unsigned int UpdateManager::Update( float elapsedSeconds,
unsigned int lastVSyncTimeMilliseconds,
- unsigned int nextVSyncTimeMilliseconds )
+ unsigned int nextVSyncTimeMilliseconds,
+ bool renderToFboEnabled,
+ bool isRenderingToFbo )
{
const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
//Update renderers and apply constraints
UpdateRenderers( bufferIndex );
- //Update the trnasformations of all the nodes
+ // Call the frame-callback-processor if set
+ if( mImpl->frameCallbackProcessor )
+ {
+ mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
+ }
+
+ //Update the transformations of all the nodes
mImpl->transformManager.Update();
//Process Property Notifications
if ( NULL != mImpl->root )
{
mImpl->renderTaskProcessor.Process( bufferIndex,
- mImpl->taskList,
- *mImpl->root,
- mImpl->sortedLayers,
- mImpl->renderInstructions );
+ mImpl->taskList,
+ *mImpl->root,
+ mImpl->sortedLayers,
+ mImpl->renderInstructions,
+ renderToFboEnabled,
+ isRenderingToFbo );
// Process the system-level RenderTasks last
if ( NULL != mImpl->systemLevelRoot )
{
mImpl->renderTaskProcessor.Process( bufferIndex,
- mImpl->systemLevelTaskList,
- *mImpl->systemLevelRoot,
- mImpl->systemLevelSortedLayers,
- mImpl->renderInstructions );
+ mImpl->systemLevelTaskList,
+ *mImpl->systemLevelRoot,
+ mImpl->systemLevelSortedLayers,
+ mImpl->renderInstructions,
+ renderToFboEnabled,
+ isRenderingToFbo );
}
}
}
unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
+ // If the rendering behavior is set to continuously render, then continue to render.
// If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
// Keep updating until no messages are received and no animations are running.
// If an animation has just finished, update at least once more for Discard end-actions.
// No need to check for renderQueue as there is always a render after update and if that
// render needs another update it will tell the adaptor to call update again
- if ( mImpl->keepRenderingSeconds > 0.0f )
+ if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
+ ( mImpl->keepRenderingSeconds > 0.0f ) )
{
keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
}
void UpdateManager::SetDefaultSurfaceRect( const Rect<int>& rect )
{
+ mImpl->surfaceRectChanged = true;
+
typedef MessageValue1< RenderManager, Rect<int> > DerivedType;
// Reserve some memory inside the render queue
mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
}
+void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
+{
+ mImpl->renderingBehavior = renderingBehavior;
+}
+
void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
{
if ( !systemLevel )
SortSiblingNodesRecursively( *( mImpl->root ) );
}
+bool UpdateManager::IsDefaultSurfaceRectChanged()
+{
+ bool surfaceRectChanged = mImpl->surfaceRectChanged;
+
+ // Reset the flag
+ mImpl->surfaceRectChanged = false;
+
+ return surfaceRectChanged;
+}
+
+void UpdateManager::AddFrameCallback( FrameCallbackInterface* frameCallback, const Node* rootNode )
+{
+ mImpl->GetFrameCallbackProcessor().AddFrameCallback( frameCallback, rootNode );
+}
+
+void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
+{
+ mImpl->GetFrameCallbackProcessor().RemoveFrameCallback( frameCallback );
+}
+
void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
{
// Message has ownership of Sampler while in transit from update to render