*/
// CLASS HEADER
-#include <dali/internal/update/manager/process-render-tasks.h>
+#include <dali/internal/update/manager/render-task-processor.h>
// INTERNAL INCLUDES
-#include <dali/internal/update/manager/prepare-render-instructions.h>
#include <dali/internal/update/manager/sorted-layers.h>
#include <dali/internal/update/render-tasks/scene-graph-render-task.h>
#include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
namespace //Unnamed namespace
{
-// Return false if the node or it's parents are exclusive to another render-task
+// Return false if the node or it's parents are exclusive to another render-task.
bool CheckExclusivity( const Node& node, const RenderTask& task )
{
const RenderTask* exclusiveTo = node.GetExclusiveRenderTask();
- if ( exclusiveTo )
+ if( exclusiveTo )
{
- if ( exclusiveTo == &task )
- {
- // Exclusive to the same render-task
- return true;
- }
- else
- {
- // Exclusive to another render-task
- return false;
- }
+ return ( exclusiveTo == &task );
}
const Node* parent = node.GetParent();
return CheckExclusivity( *parent, task );
}
- // No exclusive flags set
+ // No exclusive flags set.
return true;
}
Layer* FindLayer( Node& node )
{
Node* currentNode( &node );
- Layer* layer(NULL);
+ Layer* layer( NULL );
while( currentNode )
{
- if( (layer = currentNode->GetLayer()) != NULL )
+ if( ( layer = currentNode->GetLayer() ) != NULL )
{
return layer;
}
}
/**
- * Rebuild the Layer::colorRenderables, stencilRenderables and overlayRenderables members,
+ * Rebuild the Layer::colorRenderables and overlayRenderables members,
* including only renderers which are included in the current render-task.
* Returns true if all renderers have finished acquiring resources.
+ *
+ * @param[in] updateBufferIndex The current update buffer index.
+ * @param[in] node The current node of the scene-graph.
+ * @param[in] currentLayer The current layer containing lists of opaque/transparent renderables.
+ * @param[in] renderTask The current render-task.
+ * @param[in] inheritedDrawMode The draw mode of the parent
+ * @param[in] currentClippingId The current Clipping Id
+ * Note: ClippingId is passed by reference, so it is permanently modified when traversing back up the tree for uniqueness.
+ * @param[in] clippingDepth The current clipping depth
*/
bool AddRenderablesForTask( BufferIndex updateBufferIndex,
Node& node,
Layer& currentLayer,
RenderTask& renderTask,
- int inheritedDrawMode )
+ int inheritedDrawMode,
+ uint32_t& currentClippingId,
+ uint32_t clippingDepth )
{
bool resourcesFinished = true;
// Short-circuit for invisible nodes
- if ( !node.IsVisible( updateBufferIndex ) )
+ if( !node.IsVisible( updateBufferIndex ) )
{
return resourcesFinished;
}
// Check whether node is exclusive to a different render-task
const RenderTask* exclusiveTo = node.GetExclusiveRenderTask();
- if ( exclusiveTo &&
- exclusiveTo != &renderTask )
+ if( exclusiveTo && ( exclusiveTo != &renderTask ) )
{
return resourcesFinished;
}
- Layer* layer = ¤tLayer;
- Layer* nodeIsLayer( node.GetLayer() );
- if ( nodeIsLayer )
+ // Assume all children go to this layer (if this node is a layer).
+ Layer* layer = node.GetLayer();
+ if( layer )
{
- // All children go to this layer
- layer = nodeIsLayer;
-
// Layers do not inherit the DrawMode from their parents
- inheritedDrawMode = DrawMode::NORMAL;
+ inheritedDrawMode = node.GetDrawMode();
}
+ else
+ {
+ // This node is not a layer.
+ layer = ¤tLayer;
+ inheritedDrawMode |= node.GetDrawMode();
+ }
+
DALI_ASSERT_DEBUG( NULL != layer );
- inheritedDrawMode |= node.GetDrawMode();
+ // Update the clipping Id and depth for this node (if clipping is enabled).
+ if( DALI_UNLIKELY( node.GetClippingMode() != ClippingMode::DISABLED ) )
+ {
+ ++currentClippingId; // This modifies the reference passed in as well as the local value, causing the value to be global to the recursion.
+ ++clippingDepth; // This only modifies the local value (which is passed in when the method recurses).
+ }
+ // Set the information in the node.
+ node.SetClippingInformation( currentClippingId, clippingDepth );
const unsigned int count = node.GetRendererCount();
for( unsigned int i = 0; i < count; ++i )
bool complete = false;
renderer->GetReadyAndComplete( ready, complete );
- DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "Testing renderable:%p ready:%s complete:%s\n", renderer, ready?"T":"F", complete?"T":"F");
+ DALI_LOG_INFO( gRenderTaskLogFilter, Debug::General, "Testing renderable:%p ready:%s complete:%s\n", renderer, ready ? "T" : "F", complete ? "T" : "F" );
resourcesFinished &= complete;
- if( ready ) // i.e. should be rendered (all resources are available)
+ if( ready ) // IE. should be rendered (all resources are available)
{
- if( DrawMode::STENCIL == inheritedDrawMode )
+ // Normal is the more-likely draw mode to occur.
+ if( DALI_LIKELY( inheritedDrawMode == DrawMode::NORMAL ) )
{
- layer->stencilRenderables.PushBack( Renderable(&node, renderer ) );
- }
- else if( DrawMode::OVERLAY_2D == inheritedDrawMode )
- {
- layer->overlayRenderables.PushBack( Renderable(&node, renderer ) );
+ layer->colorRenderables.PushBack( Renderable( &node, renderer ) );
}
else
{
- layer->colorRenderables.PushBack( Renderable(&node, renderer ) );
+ layer->overlayRenderables.PushBack( Renderable( &node, renderer ) );
}
}
}
-
-
- // Recurse children
+ // Recurse children.
NodeContainer& children = node.GetChildren();
const NodeIter endIter = children.End();
- for ( NodeIter iter = children.Begin(); iter != endIter; ++iter )
+ for( NodeIter iter = children.Begin(); iter != endIter; ++iter )
{
Node& child = **iter;
- bool childResourcesComplete = AddRenderablesForTask( updateBufferIndex, child, *layer, renderTask, inheritedDrawMode );
+ bool childResourcesComplete = AddRenderablesForTask( updateBufferIndex, child, *layer, renderTask, inheritedDrawMode, currentClippingId, clippingDepth );
resourcesFinished &= childResourcesComplete;
}
return resourcesFinished;
}
-} //Unnamed namespace
-
-void ProcessRenderTasks( BufferIndex updateBufferIndex,
- RenderTaskList& renderTasks,
- Layer& rootNode,
- SortedLayerPointers& sortedLayers,
- RendererSortingHelper& sortingHelper,
- RenderInstructionContainer& instructions )
+
+} // Anonymous namespace.
+
+
+RenderTaskProcessor::RenderTaskProcessor()
+{
+}
+
+RenderTaskProcessor::~RenderTaskProcessor()
+{
+}
+
+void RenderTaskProcessor::Process( BufferIndex updateBufferIndex,
+ RenderTaskList& renderTasks,
+ Layer& rootNode,
+ SortedLayerPointers& sortedLayers,
+ RenderInstructionContainer& instructions )
{
RenderTaskList::RenderTaskContainer& taskContainer = renderTasks.GetTasks();
- if ( taskContainer.IsEmpty() )
+ if( taskContainer.IsEmpty() )
{
// Early-exit if there are no tasks to process
return;
// 3) Traverse the scene-graph, filling the lists for the current render-task
// 4) Prepare render-instructions
- DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "ProcessRenderTasks() Offscreens first\n");
+ DALI_LOG_INFO( gRenderTaskLogFilter, Debug::General, "RenderTaskProcessor::Process() Offscreens first\n" );
// First process off screen render tasks - we may need the results of these for the on screen renders
+ uint32_t clippingId = 0u;
+ bool hasClippingNodes = false;
+
RenderTaskList::RenderTaskContainer::ConstIterator endIter = taskContainer.End();
- for ( RenderTaskList::RenderTaskContainer::Iterator iter = taskContainer.Begin(); endIter != iter; ++iter )
+ for( RenderTaskList::RenderTaskContainer::Iterator iter = taskContainer.Begin(); endIter != iter; ++iter )
{
RenderTask& renderTask = **iter;
- // off screen only
- if(0 == renderTask.GetFrameBufferId() && renderTask.GetFrameBuffer() == 0 )
- {
- // Skip to next task
- continue;
- }
-
- if ( !renderTask.ReadyToRender( updateBufferIndex ) )
+ // Off screen only.
+ if( ( ( 0 == renderTask.GetFrameBufferId() ) && ( renderTask.GetFrameBuffer() == 0 ) ) ||
+ ( !renderTask.ReadyToRender( updateBufferIndex ) ) )
{
- // Skip to next task
+ // Skip to next task.
continue;
}
Node* sourceNode = renderTask.GetSourceNode();
- DALI_ASSERT_DEBUG( NULL != sourceNode ); // otherwise Prepare() should return false
+ DALI_ASSERT_DEBUG( NULL != sourceNode ); // Otherwise Prepare() should return false
- // Check that the source node is not exclusive to another task
- if ( ! CheckExclusivity( *sourceNode, renderTask ) )
+ // Check that the source node is not exclusive to another task.
+ if( ! CheckExclusivity( *sourceNode, renderTask ) )
{
continue;
}
Layer* layer = FindLayer( *sourceNode );
if( !layer )
{
- // Skip to next task as no layer
+ // Skip to next task as no layer.
continue;
}
*sourceNode,
*layer,
renderTask,
- sourceNode->GetDrawMode() );
+ sourceNode->GetDrawMode(),
+ clippingId,
+ 0u );
renderTask.SetResourcesFinished( resourcesFinished );
- PrepareRenderInstruction( updateBufferIndex,
- sortedLayers,
- renderTask,
- sortingHelper,
- renderTask.GetCullMode(),
- instructions );
+
+ // If the clipping Id is still 0 after adding all Renderables, there is no clipping required for this RenderTaskList.
+ hasClippingNodes = clippingId != 0u;
+
+ mRenderInstructionProcessor.Prepare( updateBufferIndex,
+ sortedLayers,
+ renderTask,
+ renderTask.GetCullMode(),
+ hasClippingNodes,
+ instructions );
}
else
{
}
}
- DALI_LOG_INFO(gRenderTaskLogFilter, Debug::General, "ProcessRenderTasks() Onscreen\n");
+ DALI_LOG_INFO( gRenderTaskLogFilter, Debug::General, "RenderTaskProcessor::Process() Onscreen\n" );
- // Now that the off screen renders are done we can process on screen render tasks
+ // Now that the off screen renders are done we can process on screen render tasks.
+ // Reset the clipping Id for the OnScreen render tasks.
+ clippingId = 0u;
for ( RenderTaskList::RenderTaskContainer::Iterator iter = taskContainer.Begin(); endIter != iter; ++iter )
{
RenderTask& renderTask = **iter;
- // on screen only
- if(0 != renderTask.GetFrameBufferId() || renderTask.GetFrameBuffer() != 0 )
+ // On screen only.
+ if( ( 0 != renderTask.GetFrameBufferId() ) ||
+ ( renderTask.GetFrameBuffer() != 0 ) ||
+ ( !renderTask.ReadyToRender( updateBufferIndex ) ) )
{
- // Skip to next task
- continue;
- }
- if ( !renderTask.ReadyToRender( updateBufferIndex ) )
- {
- // Skip to next task
+ // Skip to next task.
continue;
}
Node* sourceNode = renderTask.GetSourceNode();
- DALI_ASSERT_DEBUG( NULL != sourceNode ); // otherwise Prepare() should return false
+ DALI_ASSERT_DEBUG( NULL != sourceNode ); // Otherwise Prepare() should return false.
- // Check that the source node is not exclusive to another task
- if ( ! CheckExclusivity( *sourceNode, renderTask ) )
+ // Check that the source node is not exclusive to another task.
+ if( ! CheckExclusivity( *sourceNode, renderTask ) )
{
continue;
}
Layer* layer = FindLayer( *sourceNode );
if( !layer )
{
- // Skip to next task as no layer
+ // Skip to next task as no layer.
continue;
}
if( renderTask.IsRenderRequired() )
{
size_t layerCount( sortedLayers.size() );
- for( size_t i(0); i<layerCount; ++i )
+ for( size_t i(0); i < layerCount; ++i )
{
sortedLayers[i]->ClearRenderables();
}
*sourceNode,
*layer,
renderTask,
- sourceNode->GetDrawMode() );
-
- PrepareRenderInstruction( updateBufferIndex,
- sortedLayers,
- renderTask,
- sortingHelper,
- renderTask.GetCullMode(),
- instructions );
+ sourceNode->GetDrawMode(),
+ clippingId,
+ 0u );
+
+ // If the clipping Id is still 0 after adding all Renderables, there is no clipping required for this RenderTaskList.
+ hasClippingNodes = clippingId != 0;
+
+ mRenderInstructionProcessor.Prepare( updateBufferIndex,
+ sortedLayers,
+ renderTask,
+ renderTask.GetCullMode(),
+ hasClippingNodes,
+ instructions );
}
renderTask.SetResourcesFinished( resourcesFinished );