X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Fmanager%2Frender-instruction-processor.cpp;h=a76632e1a25160d6bddc3607cadc3802f6de3233;hb=b43741a90b40ca9dfbd33d6a9d390d3c09230e89;hp=bbb216a599cc46d0a26b10a19e0a2e5e0b050a03;hpb=ff364987bf3c2ef5bb2b57348747eeb784d8ba90;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/update/manager/render-instruction-processor.cpp b/dali/internal/update/manager/render-instruction-processor.cpp old mode 100644 new mode 100755 index bbb216a..a76632e --- a/dali/internal/update/manager/render-instruction-processor.cpp +++ b/dali/internal/update/manager/render-instruction-processor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,14 +19,12 @@ #include // INTERNAL INCLUDES -#include #include #include #include // for the default sorting function #include #include #include -#include #include #include #include @@ -35,6 +33,7 @@ #include #include #include +#include namespace { @@ -56,47 +55,41 @@ namespace { /** - * Function which sorts render items by depth index then by instance - * ptrs of shader/geometry/material. + * Function which compares render items by shader/textureSet/geometry * @param[in] lhs Left hand side item * @param[in] rhs Right hand side item * @return True if left item is greater than right */ -bool CompareItems( const RenderInstructionProcessor::SortAttributes& lhs, const RenderInstructionProcessor::SortAttributes& rhs ) +inline bool PartialCompareItems( const RenderInstructionProcessor::SortAttributes& lhs, + const RenderInstructionProcessor::SortAttributes& rhs ) { - // @todo Consider replacing all these sortAttributes with a single long int that - // encapsulates the same data (e.g. the middle-order bits of the ptrs). - if( lhs.renderItem->mDepthIndex == rhs.renderItem->mDepthIndex ) + if( lhs.shader == rhs.shader ) { - if( lhs.shader == rhs.shader ) + if( lhs.textureSet == rhs.textureSet ) { - if( lhs.textureResourceId == rhs.textureResourceId ) - { - return lhs.geometry < rhs.geometry; - } - return lhs.textureResourceId < rhs.textureResourceId; + return lhs.geometry < rhs.geometry; } - return lhs.shader < rhs.shader; + return lhs.textureSet < rhs.textureSet; } - return lhs.renderItem->mDepthIndex < rhs.renderItem->mDepthIndex; + return lhs.shader < rhs.shader; } /** - * Function which sorts render items by clipping hierarchy, then depth index and instance - * ptrs of shader/geometry/material. + * Function which sorts render items by depth index then by instance + * ptrs of shader/textureSet/geometry. * @param[in] lhs Left hand side item * @param[in] rhs Right hand side item * @return True if left item is greater than right */ -bool CompareItemsWithClipping( const RenderInstructionProcessor::SortAttributes& lhs, const RenderInstructionProcessor::SortAttributes& rhs ) +bool CompareItems( const RenderInstructionProcessor::SortAttributes& lhs, const RenderInstructionProcessor::SortAttributes& rhs ) { - // Items must be sorted in order of clipping first, otherwise incorrect clipping regions could be used. - if( lhs.renderItem->mNode->mClippingSortModifier == rhs.renderItem->mNode->mClippingSortModifier ) + // @todo Consider replacing all these sortAttributes with a single long int that + // encapsulates the same data (e.g. the middle-order bits of the ptrs). + if( lhs.renderItem->mDepthIndex == rhs.renderItem->mDepthIndex ) { - return CompareItems( lhs, rhs ); + return PartialCompareItems( lhs, rhs ); } - - return lhs.renderItem->mNode->mClippingSortModifier < rhs.renderItem->mNode->mClippingSortModifier; + return lhs.renderItem->mDepthIndex < rhs.renderItem->mDepthIndex; } /** @@ -108,36 +101,20 @@ bool CompareItemsWithClipping( const RenderInstructionProcessor::SortAttributes& */ bool CompareItems3D( const RenderInstructionProcessor::SortAttributes& lhs, const RenderInstructionProcessor::SortAttributes& rhs ) { - bool lhsIsOpaque = lhs.renderItem->mIsOpaque; + const bool lhsIsOpaque = lhs.renderItem->mIsOpaque; if( lhsIsOpaque == rhs.renderItem->mIsOpaque ) { if( lhsIsOpaque ) { // If both RenderItems are opaque, sort using shader, then material then geometry. - if( lhs.shader == rhs.shader ) - { - if( lhs.textureResourceId == rhs.textureResourceId ) - { - return lhs.geometry < rhs.geometry; - } - return lhs.textureResourceId < rhs.textureResourceId; - } - return lhs.shader < rhs.shader; + return PartialCompareItems( lhs, rhs ); } else { // If both RenderItems are transparent, sort using Z, then shader, then material, then geometry. if( Equals( lhs.zValue, rhs.zValue ) ) { - if( lhs.shader == rhs.shader ) - { - if( lhs.textureResourceId == rhs.textureResourceId ) - { - return lhs.geometry < rhs.geometry; - } - return lhs.textureResourceId < rhs.textureResourceId; - } - return lhs.shader < rhs.shader; + return PartialCompareItems( lhs, rhs ); } return lhs.zValue > rhs.zValue; } @@ -184,34 +161,78 @@ inline void AddRendererToRenderList( BufferIndex updateBufferIndex, bool cull ) { bool inside( true ); - if ( cull && !renderable.mRenderer->GetShader().HintEnabled( Dali::Shader::Hint::MODIFIES_GEOMETRY ) ) + Node* node = renderable.mNode; + bool isModifiesGeometryHint = false; + if( cull && renderable.mRenderer && !( isModifiesGeometryHint = renderable.mRenderer->GetShader().HintEnabled( Dali::Shader::Hint::MODIFIES_GEOMETRY ) ) ) { - const Vector4& boundingSphere = renderable.mNode->GetBoundingSphere(); - inside = (boundingSphere.w > Math::MACHINE_EPSILON_1000) && - (camera.CheckSphereInFrustum( updateBufferIndex, Vector3(boundingSphere), boundingSphere.w ) ); + const Vector4& boundingSphere = node->GetBoundingSphere(); + inside = ( boundingSphere.w > Math::MACHINE_EPSILON_1000 ) && + ( camera.CheckSphereInFrustum( updateBufferIndex, Vector3( boundingSphere ), boundingSphere.w ) ); } - if ( inside ) + if( inside ) { - Renderer::Opacity opacity = renderable.mRenderer->GetOpacity( updateBufferIndex, *renderable.mNode ); - if( opacity != Renderer::TRANSPARENT ) + Renderer::OpacityType opacityType = renderable.mRenderer ? renderable.mRenderer->GetOpacityType( updateBufferIndex, *renderable.mNode ) : Renderer::OPAQUE; + if( opacityType != Renderer::TRANSPARENT || node->GetClippingMode() == ClippingMode::CLIP_CHILDREN ) { // Get the next free RenderItem. RenderItem& item = renderList.GetNextFreeItem(); - item.mRenderer = &renderable.mRenderer->GetRenderer(); + item.mNode = renderable.mNode; - item.mIsOpaque = ( opacity == Renderer::OPAQUE ); - item.mDepthIndex = renderable.mRenderer->GetDepthIndex(); + item.mIsOpaque = ( opacityType == Renderer::OPAQUE ); + item.mDepthIndex = 0; + item.mPartialUpdateEnabled = false; if( !isLayer3d ) { - item.mDepthIndex += static_cast( renderable.mNode->GetDepth() ) * Dali::Layer::TREE_DEPTH_MULTIPLIER; + item.mDepthIndex = renderable.mNode->GetDepthIndex(); + } + if( isLayer3d || isModifiesGeometryHint ) + { + renderList.SetPartialUpdateEnabled( false ); + } + + if( DALI_LIKELY( renderable.mRenderer ) ) + { + item.mRenderer = &renderable.mRenderer->GetRenderer(); + item.mTextureSet = renderable.mRenderer->GetTextures(); + item.mDepthIndex += renderable.mRenderer->GetDepthIndex(); + + if( FaceCullingMode::NONE != renderable.mRenderer->GetFaceCullingMode() ) + { + renderList.SetPartialUpdateEnabled( false ); + } + } + else + { + item.mRenderer = nullptr; } // Save ModelView matrix onto the item. - renderable.mNode->GetWorldMatrixAndSize( item.mModelMatrix, item.mSize ); + node->GetWorldMatrixAndSize( item.mModelMatrix, item.mSize ); + Matrix::Multiply( item.mModelViewMatrix, item.mModelMatrix, viewMatrix ); + + if( DALI_LIKELY( item.mRenderer ) && renderList.IsPartialUpdateEnabled() ) + { + if( node->IsPropertyDirty() || node->IsComponentChanged() ) + { + item.mPartialUpdateEnabled = true; + + item.mUpdateSizeHint = item.mSize; + Vector3 updateSizeHint = node->GetUpdateSizeHint( updateBufferIndex ); + if( updateSizeHint != Vector3::ZERO ) + { + item.mUpdateSizeHint = updateSizeHint; + } + } + } } + node->SetCulled( updateBufferIndex, false ); + } + else + { + node->SetCulled( updateBufferIndex, true ); } } @@ -236,10 +257,15 @@ inline void AddRenderersToRenderList( BufferIndex updateBufferIndex, { DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "AddRenderersToRenderList()\n"); - unsigned int rendererCount( renderers.Size() ); - for( unsigned int i(0); i < rendererCount; ++i ) + for( auto&& renderer : renderers ) { - AddRendererToRenderList( updateBufferIndex, renderList, renderers[i], viewMatrix, camera, isLayer3d, cull ); + AddRendererToRenderList( updateBufferIndex, + renderList, + renderer, + viewMatrix, + camera, + isLayer3d, + cull ); } } @@ -256,7 +282,7 @@ inline bool TryReuseCachedRenderers( Layer& layer, RenderableContainer& renderables ) { bool retValue = false; - size_t renderableCount = renderables.Size(); + uint32_t renderableCount = static_cast( renderables.Size() ); // Check that the cached list originates from this layer and that the counts match if( ( renderList.GetSourceLayer() == &layer )&& ( renderList.GetCachedItemCount() == renderableCount ) ) @@ -266,11 +292,11 @@ inline bool TryReuseCachedRenderers( Layer& layer, // Therefore we check a combined sum of all renderer addresses. size_t checkSumNew = 0; size_t checkSumOld = 0; - for( size_t index = 0; index < renderableCount; ++index ) + for( uint32_t index = 0; index < renderableCount; ++index ) { const Render::Renderer& renderer = renderables[index].mRenderer->GetRenderer(); - checkSumNew += size_t( &renderer ); - checkSumOld += size_t( &renderList.GetRenderer( index ) ); + checkSumNew += reinterpret_cast( &renderer ); + checkSumOld += reinterpret_cast( &renderList.GetRenderer( index ) ); } if( checkSumNew == checkSumOld ) { @@ -303,10 +329,9 @@ RenderInstructionProcessor::RenderInstructionProcessor() : mSortingHelper() { // Set up a container of comparators for fast run-time selection. - mSortComparitors.Reserve( 4u ); + mSortComparitors.Reserve( 3u ); mSortComparitors.PushBack( CompareItems ); - mSortComparitors.PushBack( CompareItemsWithClipping ); mSortComparitors.PushBack( CompareItems3D ); mSortComparitors.PushBack( CompareItems3DWithClipping ); } @@ -317,9 +342,9 @@ RenderInstructionProcessor::~RenderInstructionProcessor() inline void RenderInstructionProcessor::SortRenderItems( BufferIndex bufferIndex, RenderList& renderList, Layer& layer, bool respectClippingOrder ) { - const size_t renderableCount = renderList.Count(); + const uint32_t renderableCount = static_cast( renderList.Count() ); // Reserve space if needed. - const unsigned int oldcapacity = mSortingHelper.size(); + const uint32_t oldcapacity = static_cast( mSortingHelper.size() ); if( oldcapacity < renderableCount ) { mSortingHelper.reserve( renderableCount ); @@ -338,14 +363,20 @@ inline void RenderInstructionProcessor::SortRenderItems( BufferIndex bufferIndex // Using an if and two for-loops rather than if inside for as its better for branch prediction. if( layer.UsesDefaultSortFunction() ) { - for( size_t index = 0; index < renderableCount; ++index ) + for( uint32_t index = 0; index < renderableCount; ++index ) { RenderItem& item = renderList.GetItem( index ); - item.mRenderer->SetSortAttributes( bufferIndex, mSortingHelper[ index ] ); + if( item.mRenderer ) + { + item.mRenderer->SetSortAttributes( bufferIndex, mSortingHelper[ index ] ); + } + + // texture set + mSortingHelper[ index ].textureSet = item.mTextureSet; // The default sorting function should get inlined here. - mSortingHelper[ index ].zValue = Internal::Layer::ZValue( item.mModelViewMatrix.GetTranslation3() ) - item.mDepthIndex; + mSortingHelper[ index ].zValue = Internal::Layer::ZValue( item.mModelViewMatrix.GetTranslation3() ) - static_cast( item.mDepthIndex ); // Keep the renderitem pointer in the helper so we can quickly reorder items after sort. mSortingHelper[ index ].renderItem = &item; @@ -354,31 +385,35 @@ inline void RenderInstructionProcessor::SortRenderItems( BufferIndex bufferIndex else { const Dali::Layer::SortFunctionType sortFunction = layer.GetSortFunction(); - for( size_t index = 0; index < renderableCount; ++index ) + for( uint32_t index = 0; index < renderableCount; ++index ) { RenderItem& item = renderList.GetItem( index ); item.mRenderer->SetSortAttributes( bufferIndex, mSortingHelper[ index ] ); - mSortingHelper[ index ].zValue = (*sortFunction)( item.mModelViewMatrix.GetTranslation3() ) - item.mDepthIndex; + + // texture set + mSortingHelper[ index ].textureSet = item.mTextureSet; + + + mSortingHelper[ index ].zValue = (*sortFunction)( item.mModelViewMatrix.GetTranslation3() ) - static_cast( item.mDepthIndex ); // Keep the RenderItem pointer in the helper so we can quickly reorder items after sort. mSortingHelper[ index ].renderItem = &item; } } - // Here we detemine which comparitor (of the 4) to use. - // The comparitors work like a bitmask. - // 1 << 0 is added to select a clipping comparitor. - // 1 << 1 is added for 3D comparitors. - const unsigned int comparitorIndex = ( respectClippingOrder ? ( 1u << 0u ) : 0u ) | - ( layer.GetBehavior() == Dali::Layer::LAYER_3D ? ( 1u << 1u ) : 0u ); + // Here we determine which comparitor (of the 3) to use. + // 0 is LAYER_UI + // 1 is LAYER_3D + // 2 is LAYER_3D + Clipping + const unsigned int comparitorIndex = layer.GetBehavior() == Dali::Layer::LAYER_3D ? respectClippingOrder ? 2u : 1u : 0u; std::stable_sort( mSortingHelper.begin(), mSortingHelper.end(), mSortComparitors[ comparitorIndex ] ); // Reorder / re-populate the RenderItems in the RenderList to correct order based on the sortinghelper. DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "Sorted Transparent List:\n"); RenderItemContainer::Iterator renderListIter = renderList.GetContainer().Begin(); - for( unsigned int index = 0; index < renderableCount; ++index, ++renderListIter ) + for( uint32_t index = 0; index < renderableCount; ++index, ++renderListIter ) { *renderListIter = mSortingHelper[ index ].renderItem; DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, " sortedList[%d] = %p\n", index, mSortingHelper[ index ].renderItem->mRenderer); @@ -397,6 +432,8 @@ void RenderInstructionProcessor::Prepare( BufferIndex updateBufferIndex, RenderInstruction& instruction = instructions.GetNextInstruction( updateBufferIndex ); renderTask.PrepareRenderInstruction( instruction, updateBufferIndex ); bool viewMatrixHasNotChanged = !renderTask.ViewMatrixUpdated(); + bool isRenderListAdded = false; + bool isRootLayerDirty = false; const Matrix& viewMatrix = renderTask.GetViewMatrix( updateBufferIndex ); SceneGraph::Camera& camera = renderTask.GetCamera(); @@ -409,6 +446,12 @@ void RenderInstructionProcessor::Prepare( BufferIndex updateBufferIndex, const bool isLayer3D = layer.GetBehavior() == Dali::Layer::LAYER_3D; RenderList* renderList = NULL; + if( layer.IsRoot() && ( layer.GetDirtyFlags() != NodePropertyFlags::NOTHING ) ) + { + // If root-layer & dirty, i.e. a property has changed or a child has been deleted, then we need to ensure we render once more + isRootLayerDirty = true; + } + if( !layer.colorRenderables.Empty() ) { RenderableContainer& renderables = layer.colorRenderables; @@ -416,11 +459,23 @@ void RenderInstructionProcessor::Prepare( BufferIndex updateBufferIndex, if( !SetupRenderList( renderables, layer, instruction, tryReuseRenderList, &renderList ) ) { renderList->SetHasColorRenderItems( true ); - AddRenderersToRenderList( updateBufferIndex, *renderList, renderables, viewMatrix, camera, isLayer3D, cull ); + if( !isLayer3D ) + { + renderList->SetPartialUpdateEnabled( true ); + } + AddRenderersToRenderList( updateBufferIndex, + *renderList, + renderables, + viewMatrix, + camera, + isLayer3D, + cull ); // We only use the clipping version of the sort comparitor if any clipping nodes exist within the RenderList. SortRenderItems( updateBufferIndex, *renderList, layer, hasClippingNodes ); } + + isRenderListAdded = true; } if( !layer.overlayRenderables.Empty() ) @@ -430,18 +485,34 @@ void RenderInstructionProcessor::Prepare( BufferIndex updateBufferIndex, if( !SetupRenderList( renderables, layer, instruction, tryReuseRenderList, &renderList ) ) { renderList->SetHasColorRenderItems( false ); - AddRenderersToRenderList( updateBufferIndex, *renderList, renderables, viewMatrix, camera, isLayer3D, cull ); + if( !isLayer3D ) + { + renderList->SetPartialUpdateEnabled( true ); + } + AddRenderersToRenderList( updateBufferIndex, + *renderList, + renderables, + viewMatrix, + camera, + isLayer3D, + cull ); // Clipping hierarchy is irrelevant when sorting overlay items, so we specify using the non-clipping version of the sort comparitor. SortRenderItems( updateBufferIndex, *renderList, layer, false ); } + + isRenderListAdded = true; } } // Inform the render instruction that all renderers have been added and this frame is complete. instruction.UpdateCompleted(); -} + if( !isRenderListAdded && !instruction.mIsClearColorSet && !isRootLayerDirty ) + { + instructions.DiscardCurrentInstruction( updateBufferIndex ); + } +} } // SceneGraph