X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Fmanager%2Fprepare-render-instructions.cpp;h=350d66e910df204b2a6a2e93a4536be2088069ca;hb=449cde6cfe99f1e9297bec8cdb5cedff37502afb;hp=bae7711ac6afd32ffc909c78637fb44755e17a24;hpb=f7ab8a90317658a2306d43d94ff3409f23c9fec3;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/update/manager/prepare-render-instructions.cpp b/dali/internal/update/manager/prepare-render-instructions.cpp index bae7711..350d66e 100644 --- a/dali/internal/update/manager/prepare-render-instructions.cpp +++ b/dali/internal/update/manager/prepare-render-instructions.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. @@ -19,17 +19,30 @@ #include // INTERNAL INCLUDES +#include +#include +#include #include // for the default sorting function -#include +#include #include #include -#include -#include +#include +#include #include #include #include #include -#include +#include +#include +#include +#include + +namespace +{ +#if defined(DEBUG_ENABLED) +Debug::Filter* gRenderListLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RENDER_LISTS"); +#endif +} namespace Dali { @@ -41,139 +54,103 @@ namespace SceneGraph { /** - * Set flags for opaque renderlist - * @param renderList to set the flags to - * @param transparentRenderersExist is true if there is transparent renderers in this layer - * @param stencilRenderablesExist is true if there are stencil renderers on this layer - * @param depthTestDisabled whether depth test is disabled. + * Add a renderer to the list + * @param updateBufferIndex to read the model matrix from + * @param renderList to add the item to + * @param renderable Node-Renderer pair + * @param viewMatrix used to calculate modelview matrix for the item + * @param camera The camera used to render + * @param geometryBatcher The instance of the geometry batcher + * @param isLayer3d Whether we are processing a 3D layer or not + * @param cull Whether frustum culling is enabled or not */ -inline void SetOpaqueRenderFlags( RenderList& renderList, bool transparentRenderersExist, bool stencilRenderablesExist, bool depthTestDisabled ) +inline void AddRendererToRenderList( BufferIndex updateBufferIndex, + RenderList& renderList, + Renderable& renderable, + const Matrix& viewMatrix, + SceneGraph::Camera& camera, + GeometryBatcher& geometryBatcher, + bool isLayer3d, + bool cull ) { - // Special optimization if depth test is disabled or if only one opaque rendered in the layer (for example background image) - // and this renderer does not need depth test against itself (for example a mesh actor) - // if this layer has got exactly one opaque renderer - // and this renderer is not interested in depth testing - // (i.e. is an image or text and not a model) - if ( ( ( renderList.Count() == 1 ) && - ( !transparentRenderersExist ) && - ( !renderList.GetRenderer( 0 )->RequiresDepthTest() ) ) || - depthTestDisabled ) + // discard renderable early if it belongs to the batch which has been consumed in during frame + Node* renderableNode = renderable.mNode; + const bool batchingValid( renderable.mRenderer->IsBatchingEnabled() && renderableNode->mBatchIndex != BATCH_NULL_HANDLE ); + if( batchingValid && geometryBatcher.HasRendered( renderableNode->mBatchIndex ) ) { - // no need to enable depth test or clear depth buffer - // if there's something transparent already rendered by previous layers, - // this opaque renderer will correctly draw on top of them since no depth test - renderList.ClearFlags(); + return; } - else - { - // Prepare for rendering multiple opaque objects - unsigned int flags = RenderList::DEPTH_TEST | RenderList::DEPTH_WRITE | RenderList::DEPTH_CLEAR; // clear depth buffer, draw over the previously rendered layers; - renderList.ClearFlags(); - renderList.SetFlags(flags); - } + bool inside( true ); + const Node* batchParentNode = renderable.mNode->GetBatchParent(); + const Node* node = ( renderable.mRenderer->IsBatchingEnabled() && batchParentNode ) ? + batchParentNode : renderableNode; - if( stencilRenderablesExist ) + if ( cull && !renderable.mRenderer->GetShader().HintEnabled( Dali::Shader::Hint::MODIFIES_GEOMETRY ) ) { - renderList.SetFlags( RenderList::STENCIL_TEST ); + const Vector4& boundingSphere = node->GetBoundingSphere(); + inside = (boundingSphere.w > Math::MACHINE_EPSILON_1000) && + (camera.CheckSphereInFrustum( updateBufferIndex, Vector3(boundingSphere), boundingSphere.w ) ); } -} -/** - * Set the transparent flags on the renderlist - * @param renderList to set the flags on - * @param opaqueRenderersExist is true if there are opaque renderers on this layer - * @param stencilRenderablesExist is true if there are stencil renderers on this layer - * @param depthTestDisabled whether depth test is disabled. - */ -inline void SetTransparentRenderFlags( RenderList& renderList, bool opaqueRenderersExist, bool stencilRenderablesExist, bool depthTestDisabled ) -{ - renderList.ClearFlags(); - // We don't need to write to the depth buffer, as transparent objects - // don't obscure each other. - - if ( opaqueRenderersExist && !depthTestDisabled ) + if( inside ) { - // If there are a mix of opaque and transparent objects, the transparent - // objects should be rendered with depth test on to avoid background objects - // appearing in front of opaque foreground objects. - - renderList.SetFlags( RenderList::DEPTH_TEST ); - } - - if( stencilRenderablesExist ) - { - renderList.SetFlags( RenderList::STENCIL_TEST ); - } -} - + if( batchingValid ) + { + geometryBatcher.SetRendered( renderableNode->mBatchIndex ); + } -/** - * Set flags for overlay renderlist - * @param renderList to set the flags for - * @param stencilRenderablesExist is true if there are stencil renderers on this layer - */ -inline void SetOverlayRenderFlags( RenderList& renderList, bool stencilRenderablesExist ) -{ - if(stencilRenderablesExist) - { - renderList.SetFlags(RenderList::STENCIL_TEST); + Renderer::Opacity opacity = renderable.mRenderer->GetOpacity( updateBufferIndex, *renderable.mNode ); + if( opacity != Renderer::TRANSPARENT ) + { + // Get the next free RenderItem + RenderItem& item = renderList.GetNextFreeItem(); + item.mRenderer = &renderable.mRenderer->GetRenderer(); + item.mNode = renderable.mNode; + item.mIsOpaque = (opacity == Renderer::OPAQUE); + + if( isLayer3d ) + { + item.mDepthIndex = renderable.mRenderer->GetDepthIndex(); + } + else + { + item.mDepthIndex = renderable.mRenderer->GetDepthIndex() + static_cast( renderable.mNode->GetDepth() ) * Dali::Layer::TREE_DEPTH_MULTIPLIER; + } + // save MV matrix onto the item + node->GetWorldMatrixAndSize( item.mModelMatrix, item.mSize ); + Matrix::Multiply( item.mModelViewMatrix, item.mModelMatrix, viewMatrix ); + } } } /** - * Set flags for stencil renderlist - * @param renderList to set the flags for - */ -inline void SetStencilRenderFlags( RenderList& renderList ) -{ - renderList.ClearFlags(); - renderList.SetFlags(RenderList::STENCIL_CLEAR | RenderList::STENCIL_WRITE | RenderList::STENCIL_TEST); -} - -/** - * Add a renderer to the list - * @param updateBufferIndex to read the model matrix from - * @param renderList to add the item to - * @param renderable attachment - * @param viewMatrix used to calculate modelview matrix for the item - */ -inline void AddRendererToRenderList( BufferIndex updateBufferIndex, - RenderList& renderList, - RenderableAttachment& renderable, - const Matrix& viewMatrix ) -{ - const Renderer& renderer = renderable.GetRenderer(); - - // Get the next free RenderItem - RenderItem& item = renderList.GetNextFreeItem(); - item.SetRenderer( const_cast< Renderer* >( &renderer ) ); - - // calculate MV matrix onto the item - Matrix& modelViewMatrix = item.GetModelViewMatrix(); - const Matrix& worldMatrix = renderable.GetParent().GetWorldMatrix( updateBufferIndex ); - - Matrix::Multiply( modelViewMatrix, worldMatrix, viewMatrix ); -} - -/** * Add all renderers to the list * @param updateBufferIndex to read the model matrix from * @param renderList to add the items to - * @param renderable attachments + * @param renderers to render + * NodeRendererContainer Node-Renderer pairs * @param viewMatrix used to calculate modelview matrix for the items + * @param camera The camera used to render + * @param geometryBatcher The instance of the geometry batcher + * @param isLayer3d Whether we are processing a 3D layer or not + * @param cull Whether frustum culling is enabled or not */ inline void AddRenderersToRenderList( BufferIndex updateBufferIndex, RenderList& renderList, - RenderableAttachmentContainer& attachments, - const Matrix& viewMatrix ) + RenderableContainer& renderers, + const Matrix& viewMatrix, + SceneGraph::Camera& camera, + GeometryBatcher* geometryBatcher, + bool isLayer3d, + bool cull) { - // Add renderer for each attachment - const RenderableAttachmentIter endIter = attachments.end(); - for ( RenderableAttachmentIter iter = attachments.begin(); iter != endIter; ++iter ) + DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "AddRenderersToRenderList()\n"); + + unsigned int rendererCount( renderers.Size() ); + for( unsigned int i(0); iGetRenderer(); + const Render::Renderer& renderer = renderables[index].mRenderer->GetRenderer(); checkSumNew += size_t( &renderer ); - checkSumOld += size_t( renderList.GetRenderer( index ) ); + checkSumOld += size_t( &renderList.GetRenderer( index ) ); } if( checkSumNew == checkSumOld ) { @@ -218,63 +194,87 @@ inline bool TryReuseCachedRenderers( Layer& layer, } /** - * Add opaque renderers from the layer onto the next free render list - * @param updateBufferIndex to use - * @param layer to get the renderers from - * @param viewmatrix for the camera from rendertask - * @param transparentRenderersExist is true if there is transparent renderers in this layer - * @param stencilRenderablesExist is true if there are stencil renderers on this layer - * @param instruction to fill in - * @param tryReuseRenderList whether to try to reuse the cached items from the instruction + * Function which sorts render items by depth index then by instance + * ptrs of shader/texture/geometry. + * @param lhs item + * @param rhs item + * @return true if left item is greater than right */ -inline void AddOpaqueRenderers( BufferIndex updateBufferIndex, - Layer& layer, - const Matrix& viewMatrix, - bool transparentRenderablesExist, - bool stencilRenderablesExist, - RenderInstruction& instruction, - bool tryReuseRenderList ) +bool CompareItems( const RendererWithSortAttributes& lhs, const RendererWithSortAttributes& rhs ) { - RenderList& opaqueRenderList = instruction.GetNextFreeRenderList( layer.opaqueRenderables.size() ); - opaqueRenderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() ); - - // try to reuse cached renderitems from last time around - if( tryReuseRenderList ) + if( lhs.renderItem->mDepthIndex == rhs.renderItem->mDepthIndex ) { - if( TryReuseCachedRenderers( layer, opaqueRenderList, layer.opaqueRenderables ) ) + if( lhs.shader == rhs.shader ) { - // reset the flags as other layers might have changed - // opaque flags can only be set after renderers are added - SetOpaqueRenderFlags(opaqueRenderList, transparentRenderablesExist, stencilRenderablesExist, layer.IsDepthTestDisabled() ); - return; + if( lhs.textureResourceId == rhs.textureResourceId ) + { + return lhs.geometry < rhs.geometry; + } + return lhs.textureResourceId < rhs.textureResourceId; } + return lhs.shader < rhs.shader; } - AddRenderersToRenderList( updateBufferIndex, opaqueRenderList, layer.opaqueRenderables, viewMatrix ); - - // opaque flags can only be set after renderers are added - SetOpaqueRenderFlags(opaqueRenderList, transparentRenderablesExist, stencilRenderablesExist, layer.IsDepthTestDisabled() ); + return lhs.renderItem->mDepthIndex < rhs.renderItem->mDepthIndex; } - /** - * Function which sorts based on the calculated depth values ordering them back to front + * Function which sorts the render items by Z function, then + * by instance ptrs of shader/texture/geometry. * @param lhs item * @param rhs item * @return true if left item is greater than right */ -bool SortByDepthSortValue( const RendererWithSortValue& lhs, const RendererWithSortValue& rhs ) +bool CompareItems3D( const RendererWithSortAttributes& lhs, const RendererWithSortAttributes& rhs ) { - return lhs.first > rhs.first; + bool lhsIsOpaque = lhs.renderItem->mIsOpaque; + if( lhsIsOpaque == rhs.renderItem->mIsOpaque ) + { + if( lhsIsOpaque ) + { + //If both RenderItems are opaque, sort using shader, then texture 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; + } + else + { + //If both RenderItems are transparent, sort using z,then shader, then texture, 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 lhs.zValue > rhs.zValue; + } + } + else + { + return lhsIsOpaque; + } } /** - * Sort transparent render items - * @param transparentRenderList to sort + * Sort render items + * @param bufferIndex The buffer to read from + * @param renderList to sort * @param layer where the renderers are from * @param sortingHelper to use for sorting the renderitems (to avoid reallocating) */ -inline void SortTransparentRenderItems( RenderList& transparentRenderList, Layer& layer, RendererSortingHelper& sortingHelper ) +inline void SortRenderItems( BufferIndex bufferIndex, RenderList& renderList, Layer& layer, RendererSortingHelper& sortingHelper ) { - const size_t renderableCount = transparentRenderList.Count(); + const size_t renderableCount = renderList.Count(); // reserve space if needed const unsigned int oldcapacity = sortingHelper.size(); if( oldcapacity < renderableCount ) @@ -283,26 +283,29 @@ inline void SortTransparentRenderItems( RenderList& transparentRenderList, Layer // add real objects (reserve does not construct objects) sortingHelper.insert( sortingHelper.begin() + oldcapacity, (renderableCount - oldcapacity), - RendererWithSortValue( 0.0f, NULL ) ); + RendererWithSortAttributes() ); } else { // clear extra elements from helper, does not decrease capability sortingHelper.resize( renderableCount ); } + // calculate the sorting value, once per item by calling the layers sort function // 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 ) { - RenderItem& item = transparentRenderList.GetItem( index ); + RenderItem& item = renderList.GetItem( index ); + + item.mRenderer->SetSortAttributes( bufferIndex, sortingHelper[ index ] ); + // the default sorting function should get inlined here - sortingHelper[ index ].first = Internal::Layer::ZValue( - item.GetModelViewMatrix().GetTranslation3(), - layer.transparentRenderables[ index ]->GetSortModifier() ); + sortingHelper[ index ].zValue = Internal::Layer::ZValue( item.mModelViewMatrix.GetTranslation3() ) - item.mDepthIndex; + // keep the renderitem pointer in the helper so we can quickly reorder items after sort - sortingHelper[ index ].second = &item; + sortingHelper[ index ].renderItem = &item; } } else @@ -310,68 +313,84 @@ inline void SortTransparentRenderItems( RenderList& transparentRenderList, Layer const Dali::Layer::SortFunctionType sortFunction = layer.GetSortFunction(); for( size_t index = 0; index < renderableCount; ++index ) { - RenderItem& item = transparentRenderList.GetItem( index ); - sortingHelper[ index ].first = (*sortFunction)( - item.GetModelViewMatrix().GetTranslation3(), - layer.transparentRenderables[ index ]->GetSortModifier() ); + RenderItem& item = renderList.GetItem( index ); + + item.mRenderer->SetSortAttributes( bufferIndex, sortingHelper[ index ] ); + sortingHelper[ index ].zValue = (*sortFunction)( item.mModelViewMatrix.GetTranslation3() ) - item.mDepthIndex; + // keep the renderitem pointer in the helper so we can quickly reorder items after sort - sortingHelper[ index ].second = &item; + sortingHelper[ index ].renderItem = &item; } } - // sort the renderers back to front, Z Axis point from near plane to far plane - std::sort( sortingHelper.begin(), sortingHelper.end(), SortByDepthSortValue ); + if( layer.GetBehavior() == Dali::Layer::LAYER_3D) + { + // sort the renderers back to front, Z Axis point from near plane to far plane + std::stable_sort( sortingHelper.begin(), sortingHelper.end(), CompareItems3D ); + } + else + { + // sort the renderers based on DepthIndex + std::stable_sort( sortingHelper.begin(), sortingHelper.end(), CompareItems ); + } // reorder/repopulate the renderitems in renderlist to correct order based on sortinghelper - RenderItemContainer::Iterator renderListIter = transparentRenderList.GetContainer().Begin(); + 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 ) { - *renderListIter = sortingHelper[ index ].second; + *renderListIter = sortingHelper[ index ].renderItem; + DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, " sortedList[%d] = %p\n", index, sortingHelper[ index ].renderItem->mRenderer); } } /** - * Add transparent renderers from the layer onto the next free render list + * Add color renderers from the layer onto the next free render list * @param updateBufferIndex to use * @param layer to get the renderers from * @param viewmatrix for the camera from rendertask - * @param opaqueRenderablesExist is true if there are opaque renderers on this layer + * @param camera to use the view frustum * @param stencilRenderablesExist is true if there are stencil renderers on this layer * @param instruction to fill in * @param sortingHelper to use for sorting the renderitems (to avoid reallocating) + * @param geometryBatcher the instance of the geometry batcher * @param tryReuseRenderList whether to try to reuse the cached items from the instruction + * @param cull Whether frustum culling is enabled or not */ -inline void AddTransparentRenderers( BufferIndex updateBufferIndex, - Layer& layer, - const Matrix& viewMatrix, - bool opaqueRenderablesExist, - bool stencilRenderablesExist, - RenderInstruction& instruction, - RendererSortingHelper& sortingHelper, - bool tryReuseRenderList ) +inline void AddColorRenderers( BufferIndex updateBufferIndex, + Layer& layer, + const Matrix& viewMatrix, + SceneGraph::Camera& camera, + bool stencilRenderablesExist, + RenderInstruction& instruction, + RendererSortingHelper& sortingHelper, + GeometryBatcher& geometryBatcher, + bool tryReuseRenderList, + bool cull) { - const size_t renderableCount = layer.transparentRenderables.size(); - RenderList& transparentRenderList = instruction.GetNextFreeRenderList( renderableCount ); - transparentRenderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() ); - // transparent flags are independent of the amount of transparent renderers - SetTransparentRenderFlags( transparentRenderList, opaqueRenderablesExist, stencilRenderablesExist, layer.IsDepthTestDisabled() ); + RenderList& renderList = instruction.GetNextFreeRenderList( layer.colorRenderables.Size() ); + renderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() ); + renderList.SetSourceLayer( &layer ); + renderList.SetHasColorRenderItems( true ); // try to reuse cached renderitems from last time around if( tryReuseRenderList ) { - if( TryReuseCachedRenderers( layer, transparentRenderList, layer.transparentRenderables ) ) + if( TryReuseCachedRenderers( layer, renderList, layer.colorRenderables ) ) { return; } } - transparentRenderList.SetSourceLayer( &layer ); - AddRenderersToRenderList( updateBufferIndex, transparentRenderList, layer.transparentRenderables, viewMatrix ); + AddRenderersToRenderList( updateBufferIndex, renderList, layer.colorRenderables, viewMatrix, camera, &geometryBatcher, layer.GetBehavior() == Dali::Layer::LAYER_3D, cull ); + SortRenderItems( updateBufferIndex, renderList, layer, sortingHelper ); - // sorting is only needed if more than 1 item - if( renderableCount > 1 ) + // Setup the render flags for stencil. + renderList.ClearFlags(); + if( stencilRenderablesExist ) { - SortTransparentRenderItems( transparentRenderList, layer, sortingHelper ); + // Note: SetFlags does not overwrite, it ORs, so ClearFlags() is also required. + renderList.SetFlags( RenderList::STENCIL_BUFFER_ENABLED ); } } @@ -380,20 +399,33 @@ inline void AddTransparentRenderers( BufferIndex updateBufferIndex, * @param updateBufferIndex to use * @param layer to get the renderers from * @param viewmatrix for the camera from rendertask + * @param camera to use * @param stencilRenderablesExist is true if there are stencil renderers on this layer * @param instruction to fill in * @param tryReuseRenderList whether to try to reuse the cached items from the instruction + * @param cull Whether frustum culling is enabled or not */ inline void AddOverlayRenderers( BufferIndex updateBufferIndex, Layer& layer, const Matrix& viewMatrix, + SceneGraph::Camera& camera, bool stencilRenderablesExist, RenderInstruction& instruction, - bool tryReuseRenderList ) + RendererSortingHelper& sortingHelper, + bool tryReuseRenderList, + bool cull ) { - RenderList& overlayRenderList = instruction.GetNextFreeRenderList( layer.overlayRenderables.size() ); + RenderList& overlayRenderList = instruction.GetNextFreeRenderList( layer.overlayRenderables.Size() ); overlayRenderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() ); - SetOverlayRenderFlags( overlayRenderList, stencilRenderablesExist ); + overlayRenderList.SetSourceLayer( &layer ); + overlayRenderList.SetHasColorRenderItems( false ); + + //Set render flags + overlayRenderList.ClearFlags(); + if(stencilRenderablesExist) + { + overlayRenderList.SetFlags(RenderList::STENCIL_BUFFER_ENABLED); + } // try to reuse cached renderitems from last time around if( tryReuseRenderList ) @@ -403,7 +435,8 @@ inline void AddOverlayRenderers( BufferIndex updateBufferIndex, return; } } - AddRenderersToRenderList( updateBufferIndex, overlayRenderList, layer.overlayRenderables, viewMatrix ); + AddRenderersToRenderList( updateBufferIndex, overlayRenderList, layer.overlayRenderables, viewMatrix, camera, NULL, layer.GetBehavior() == Dali::Layer::LAYER_3D, cull ); + SortRenderItems( updateBufferIndex, overlayRenderList, layer, sortingHelper ); } /** @@ -411,18 +444,27 @@ inline void AddOverlayRenderers( BufferIndex updateBufferIndex, * @param updateBufferIndex to use * @param layer to get the renderers from * @param viewmatrix for the camera from rendertask + * @param camera to use * @param instruction to fill in * @param tryReuseRenderList whether to try to reuse the cached items from the instruction + * @param cull Whether frustum culling is enabled or not */ inline void AddStencilRenderers( BufferIndex updateBufferIndex, Layer& layer, const Matrix& viewMatrix, + SceneGraph::Camera& camera, RenderInstruction& instruction, - bool tryReuseRenderList ) + bool tryReuseRenderList, + bool cull ) { - RenderList& stencilRenderList = instruction.GetNextFreeRenderList( layer.stencilRenderables.size() ); + RenderList& stencilRenderList = instruction.GetNextFreeRenderList( layer.stencilRenderables.Size() ); stencilRenderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() ); - SetStencilRenderFlags( stencilRenderList ); + stencilRenderList.SetSourceLayer( &layer ); + stencilRenderList.SetHasColorRenderItems( false ); + + //Set render flags + stencilRenderList.ClearFlags(); + stencilRenderList.SetFlags(RenderList::STENCIL_CLEAR | RenderList::STENCIL_WRITE | RenderList::STENCIL_BUFFER_ENABLED ); // try to reuse cached renderitems from last time around if( tryReuseRenderList ) @@ -432,24 +474,16 @@ inline void AddStencilRenderers( BufferIndex updateBufferIndex, return; } } - AddRenderersToRenderList( updateBufferIndex, stencilRenderList, layer.stencilRenderables, viewMatrix ); + AddRenderersToRenderList( updateBufferIndex, stencilRenderList, layer.stencilRenderables, viewMatrix, camera, NULL, layer.GetBehavior() == Dali::Layer::LAYER_3D, cull ); } -/** - * Prepare a single render instruction - * @param updateBufferIndex to use - * @param sortedLayers to prepare the instruction from - * @param renderTask to get the view matrix - * @param sortingHelper to use for sorting the renderitems (to avoid reallocating) - * @param renderTracker An optional render tracker object - * @param instructions container - */ void PrepareRenderInstruction( BufferIndex updateBufferIndex, SortedLayerPointers& sortedLayers, RenderTask& renderTask, RendererSortingHelper& sortingHelper, - RenderTracker* renderTracker, - RenderInstructionContainer& instructions ) + bool cull, + RenderInstructionContainer& instructions, + GeometryBatcher& geometryBatcher ) { // Retrieve the RenderInstruction buffer from the RenderInstructionContainer // then populate with instructions. @@ -458,58 +492,46 @@ void PrepareRenderInstruction( BufferIndex updateBufferIndex, bool viewMatrixHasNotChanged = !renderTask.ViewMatrixUpdated(); const Matrix& viewMatrix = renderTask.GetViewMatrix( updateBufferIndex ); + SceneGraph::Camera& camera = renderTask.GetCamera(); const SortedLayersIter endIter = sortedLayers.end(); for ( SortedLayersIter iter = sortedLayers.begin(); iter != endIter; ++iter ) { Layer& layer = **iter; - const bool stencilRenderablesExist( !layer.stencilRenderables.empty() ); - const bool opaqueRenderablesExist( !layer.opaqueRenderables.empty() ); - const bool transparentRenderablesExist( !layer.transparentRenderables.empty() ); - const bool overlayRenderablesExist( !layer.overlayRenderables.empty() ); - const bool tryReuseRenderList( viewMatrixHasNotChanged && layer.CanReuseRenderers(renderTask.GetCamera()) ); + const bool stencilRenderablesExist( !layer.stencilRenderables.Empty() ); + const bool colorRenderablesExist( !layer.colorRenderables.Empty() ); + const bool overlayRenderablesExist( !layer.overlayRenderables.Empty() ); + const bool tryReuseRenderList( viewMatrixHasNotChanged && layer.CanReuseRenderers( &renderTask.GetCamera() ) ); // Ignore stencils if there's nothing to test if( stencilRenderablesExist && - ( opaqueRenderablesExist || transparentRenderablesExist || overlayRenderablesExist ) ) + ( colorRenderablesExist || overlayRenderablesExist ) ) { - AddStencilRenderers( updateBufferIndex, layer, viewMatrix, instruction, tryReuseRenderList ); + AddStencilRenderers( updateBufferIndex, layer, viewMatrix, camera, instruction, tryReuseRenderList, cull ); } - if ( opaqueRenderablesExist ) + if ( colorRenderablesExist ) { - AddOpaqueRenderers( updateBufferIndex, - layer, - viewMatrix, - transparentRenderablesExist, - stencilRenderablesExist, - instruction, - tryReuseRenderList ); - } - - if ( transparentRenderablesExist ) - { - AddTransparentRenderers( updateBufferIndex, - layer, - viewMatrix, - opaqueRenderablesExist, - stencilRenderablesExist, - instruction, - sortingHelper, - tryReuseRenderList ); + AddColorRenderers( updateBufferIndex, + layer, + viewMatrix, + camera, + stencilRenderablesExist, + instruction, + sortingHelper, + geometryBatcher, + tryReuseRenderList, + cull ); } if ( overlayRenderablesExist ) { - AddOverlayRenderers( updateBufferIndex, layer, viewMatrix, stencilRenderablesExist, - instruction, tryReuseRenderList ); + AddOverlayRenderers( updateBufferIndex, layer, viewMatrix, camera, stencilRenderablesExist, + instruction, sortingHelper, tryReuseRenderList, cull ); } } - instruction.mRenderTracker = renderTracker; - instruction.mCullMode = renderTask.GetCullMode(); - // inform the render instruction that all renderers have been added and this frame is complete instruction.UpdateCompleted(); }