X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Fmanager%2Frender-task-processor.cpp;h=c5b7e3183823f4ce6a563ecd6206cfffc9ab4b5c;hb=refs%2Fchanges%2F42%2F160542%2F1;hp=e6200051471ab9c788acf43cf5eb589086b60e2d;hpb=0134ea4e146744fa0946c5f266bdf2408b0a269d;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/update/manager/render-task-processor.cpp b/dali/internal/update/manager/render-task-processor.cpp index e620005..c5b7e31 100644 --- a/dali/internal/update/manager/render-task-processor.cpp +++ b/dali/internal/update/manager/render-task-processor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 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. @@ -40,7 +40,6 @@ namespace Dali namespace Internal { - namespace SceneGraph { @@ -86,38 +85,40 @@ Layer* FindLayer( Node& node ) /** * 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 + * @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] parentDepthIndex The inherited parent node depth index + * @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 stencil clipping depth + * @param[in] clippingDepth The current scissor clipping depth + * @param[out] clippingUsed Gets set to true if any clipping nodes have been found */ -bool AddRenderablesForTask( BufferIndex updateBufferIndex, +void AddRenderablesForTask( BufferIndex updateBufferIndex, Node& node, Layer& currentLayer, RenderTask& renderTask, int inheritedDrawMode, uint32_t& currentClippingId, - uint32_t clippingDepth ) + uint32_t clippingDepth, + uint32_t scissorDepth, + bool& clippingUsed ) { - bool resourcesFinished = true; - // Short-circuit for invisible nodes if( !node.IsVisible( updateBufferIndex ) ) { - return resourcesFinished; + return; } // Check whether node is exclusive to a different render-task const RenderTask* exclusiveTo = node.GetExclusiveRenderTask(); if( exclusiveTo && ( exclusiveTo != &renderTask ) ) { - return resourcesFinished; + return; } // Assume all children go to this layer (if this node is a layer). @@ -136,38 +137,45 @@ bool AddRenderablesForTask( BufferIndex updateBufferIndex, DALI_ASSERT_DEBUG( NULL != layer ); + const unsigned int count = node.GetRendererCount(); + // Update the clipping Id and depth for this node (if clipping is enabled). - if( DALI_UNLIKELY( node.GetClippingMode() != ClippingMode::DISABLED ) ) + const Dali::ClippingMode::Type clippingMode = node.GetClippingMode(); + if( DALI_UNLIKELY( clippingMode != 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). + if( DALI_LIKELY( clippingMode == ClippingMode::CLIP_TO_BOUNDING_BOX ) ) + { + ++scissorDepth; // This only modifies the local value (which is passed in when the method recurses). + // If we do not have any renderers, create one to house the scissor operation. + if( count == 0u ) + { + layer->colorRenderables.PushBack( Renderable( &node, nullptr ) ); + } + } + else + { + // We only need clipping Id for stencil clips. This means we can deliberately avoid modifying it for bounding box clips, + // thus allowing bounding box clipping to still detect clip depth changes without turning on the stencil buffer for non-clipped nodes. + ++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). + } + clippingUsed = true; } // Set the information in the node. - node.SetClippingInformation( currentClippingId, clippingDepth ); + node.SetClippingInformation( currentClippingId, clippingDepth, scissorDepth ); - const unsigned int count = node.GetRendererCount(); for( unsigned int i = 0; i < count; ++i ) { SceneGraph::Renderer* renderer = node.GetRendererAt( i ); - bool ready = false; - 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" ); - - resourcesFinished &= complete; - if( ready ) // IE. should be rendered (all resources are available) + // Normal is the more-likely draw mode to occur. + if( DALI_LIKELY( inheritedDrawMode == DrawMode::NORMAL ) ) { - // Normal is the more-likely draw mode to occur. - if( DALI_LIKELY( inheritedDrawMode == DrawMode::NORMAL ) ) - { - layer->colorRenderables.PushBack( Renderable( &node, renderer ) ); - } - else - { - layer->overlayRenderables.PushBack( Renderable( &node, renderer ) ); - } + layer->colorRenderables.PushBack( Renderable( &node, renderer ) ); + } + else + { + layer->overlayRenderables.PushBack( Renderable( &node, renderer ) ); } } @@ -177,59 +185,43 @@ bool AddRenderablesForTask( BufferIndex updateBufferIndex, for( NodeIter iter = children.Begin(); iter != endIter; ++iter ) { Node& child = **iter; - bool childResourcesComplete = AddRenderablesForTask( updateBufferIndex, child, *layer, renderTask, inheritedDrawMode, currentClippingId, clippingDepth ); - resourcesFinished &= childResourcesComplete; + AddRenderablesForTask( updateBufferIndex, child, *layer, renderTask, inheritedDrawMode, currentClippingId, clippingDepth, scissorDepth, clippingUsed ); } - - return resourcesFinished; } -} // Anonymous namespace. - -RenderTaskProcessor::RenderTaskProcessor() -{ -} - -RenderTaskProcessor::~RenderTaskProcessor() -{ -} - -void RenderTaskProcessor::Process( BufferIndex updateBufferIndex, - RenderTaskList& renderTasks, - Layer& rootNode, - SortedLayerPointers& sortedLayers, - GeometryBatcher& geometryBatcher, - RenderInstructionContainer& instructions ) +/** + * Process the list of render-tasks; the output is a series of render instructions. + * @note When ProcessRenderTasks is called, the layers should already the transparent/opaque renderers which are ready to render. + * If there is only one default render-task, then no further processing is required. + * @param[in] updateBufferIndex The current update buffer index. + * @param[in] taskContainer The container of render-tasks. + * @param[in] rootNode The root node of the scene-graph. + * @param[in] sortedLayers The layers containing lists of opaque / transparent renderables. + * @param[out] instructions The instructions for rendering the next frame. + * @param[in] renderInstructionProcessor An instance of the RenderInstructionProcessor used to sort and handle the renderers for each layer. + * @param[in] processOffscreen Whether the offscreen render tasks are the ones processed. Otherwise it processes the onscreen tasks. + */ +void ProcessTasks( BufferIndex updateBufferIndex, + RenderTaskList::RenderTaskContainer& taskContainer, + Layer& rootNode, + SortedLayerPointers& sortedLayers, + RenderInstructionContainer& instructions, + RenderInstructionProcessor& renderInstructionProcessor, + bool processOffscreen ) { - RenderTaskList::RenderTaskContainer& taskContainer = renderTasks.GetTasks(); - - if( taskContainer.IsEmpty() ) - { - // Early-exit if there are no tasks to process - return; - } - - // For each render-task: - // 1) Prepare the render-task - // 2) Clear the layer-stored lists of renderers (TODO check if the layer is not changed and don't clear in this case) - // 3) Traverse the scene-graph, filling the lists for the current render-task - // 4) Prepare render-instructions - - 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 = taskContainer.End(); endIter != iter; ++iter ) { RenderTask& renderTask = **iter; - // Off screen only. - if( ( ( 0 == renderTask.GetFrameBufferId() ) && ( renderTask.GetFrameBuffer() == 0 ) ) || - ( !renderTask.ReadyToRender( updateBufferIndex ) ) ) + const bool hasFrameBuffer = renderTask.GetFrameBuffer() != 0; + + if( ( !processOffscreen && hasFrameBuffer ) || + ( processOffscreen && !hasFrameBuffer ) || + !renderTask.ReadyToRender( updateBufferIndex ) ) { // Skip to next task. continue; @@ -239,7 +231,7 @@ void RenderTaskProcessor::Process( BufferIndex updateBufferIndex, 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 ) ) + if( !CheckExclusivity( *sourceNode, renderTask ) ) { continue; } @@ -251,109 +243,87 @@ void RenderTaskProcessor::Process( BufferIndex updateBufferIndex, continue; } - bool resourcesFinished = false; if( renderTask.IsRenderRequired() ) { - size_t layerCount( sortedLayers.size() ); - for( size_t i(0); iClearRenderables(); } - resourcesFinished = AddRenderablesForTask( updateBufferIndex, - *sourceNode, - *layer, - renderTask, - sourceNode->GetDrawMode(), - clippingId, - 0u ); - - renderTask.SetResourcesFinished( resourcesFinished ); - - // 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(), - geometryBatcher, - hasClippingNodes, - instructions ); - } - else - { - renderTask.SetResourcesFinished( resourcesFinished ); + AddRenderablesForTask( updateBufferIndex, + *sourceNode, + *layer, + renderTask, + sourceNode->GetDrawMode(), + clippingId, + 0u, + 0u, + hasClippingNodes ); + + renderInstructionProcessor.Prepare( updateBufferIndex, + sortedLayers, + renderTask, + renderTask.GetCullMode(), + hasClippingNodes, + instructions ); } } +} - DALI_LOG_INFO( gRenderTaskLogFilter, Debug::General, "RenderTaskProcessor::Process() Onscreen\n" ); +} // Anonymous namespace. - // 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; +RenderTaskProcessor::RenderTaskProcessor() +{ +} - // On screen only. - if( ( 0 != renderTask.GetFrameBufferId() ) || - ( renderTask.GetFrameBuffer() != 0 ) || - ( !renderTask.ReadyToRender( updateBufferIndex ) ) ) - { - // Skip to next task. - continue; - } +RenderTaskProcessor::~RenderTaskProcessor() +{ +} - Node* sourceNode = renderTask.GetSourceNode(); - DALI_ASSERT_DEBUG( NULL != sourceNode ); // Otherwise Prepare() should return false. +void RenderTaskProcessor::Process( BufferIndex updateBufferIndex, + RenderTaskList& renderTasks, + Layer& rootNode, + SortedLayerPointers& sortedLayers, + RenderInstructionContainer& instructions ) +{ + RenderTaskList::RenderTaskContainer& taskContainer = renderTasks.GetTasks(); - // Check that the source node is not exclusive to another task. - if( ! CheckExclusivity( *sourceNode, renderTask ) ) - { - continue; - } + if( taskContainer.IsEmpty() ) + { + // Early-exit if there are no tasks to process + return; + } - Layer* layer = FindLayer( *sourceNode ); - if( !layer ) - { - // Skip to next task as no layer. - continue; - } + // For each render-task: + // 1) Prepare the render-task + // 2) Clear the layer-stored lists of renderers (TODO check if the layer is not changed and don't clear in this case) + // 3) Traverse the scene-graph, filling the lists for the current render-task + // 4) Prepare render-instructions - bool resourcesFinished = false; - if( renderTask.IsRenderRequired() ) - { - size_t layerCount( sortedLayers.size() ); - for( size_t i(0); i < layerCount; ++i ) - { - sortedLayers[i]->ClearRenderables(); - } + DALI_LOG_INFO( gRenderTaskLogFilter, Debug::General, "RenderTaskProcessor::Process() Offscreens first\n" ); - resourcesFinished = AddRenderablesForTask( updateBufferIndex, - *sourceNode, - *layer, - renderTask, - 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(), - geometryBatcher, - hasClippingNodes, - instructions ); - } + // First process off screen render tasks - we may need the results of these for the on screen renders - renderTask.SetResourcesFinished( resourcesFinished ); - } -} + ProcessTasks( updateBufferIndex, + taskContainer, + rootNode, + sortedLayers, + instructions, + mRenderInstructionProcessor, + true ); + 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. + // Reset the clipping Id for the OnScreen render tasks. + + ProcessTasks( updateBufferIndex, + taskContainer, + rootNode, + sortedLayers, + instructions, + mRenderInstructionProcessor, + false ); +} } // SceneGraph