/*
- * 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.
#include <dali/internal/update/manager/prepare-render-instructions.h>
// INTERNAL INCLUDES
+#include <dali/public-api/shader-effects/shader-effect.h>
+#include <dali/public-api/actors/layer.h>
+#include <dali/integration-api/debug.h>
#include <dali/internal/event/actors/layer-impl.h> // for the default sorting function
-#include <dali/internal/update/resources/resource-manager-declarations.h>
+#include <dali/internal/update/nodes/scene-graph-layer.h>
#include <dali/internal/update/manager/sorted-layers.h>
#include <dali/internal/update/render-tasks/scene-graph-render-task.h>
-#include <dali/internal/update/node-attachments/scene-graph-renderable-attachment.h>
-#include <dali/internal/update/nodes/scene-graph-layer.h>
+#include <dali/internal/update/rendering/scene-graph-texture-set.h>
+#include <dali/internal/update/resources/resource-manager-declarations.h>
#include <dali/internal/render/common/render-item.h>
#include <dali/internal/render/common/render-tracker.h>
#include <dali/internal/render/common/render-instruction.h>
#include <dali/internal/render/common/render-instruction-container.h>
-#include <dali/internal/render/renderers/scene-graph-renderer.h>
+#include <dali/internal/render/shaders/scene-graph-shader.h>
+#include <dali/internal/render/renderers/render-renderer.h>
+#include <dali/internal/render/renderers/render-property-buffer.h>
+#include <dali/internal/update/manager/geometry-batcher.h>
+
+namespace
+{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gRenderListLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RENDER_LISTS");
+#endif
+}
namespace Dali
{
{
/**
- * 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<int>( 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); i<rendererCount; ++i )
{
- RenderableAttachment& attachment = **iter;
- AddRendererToRenderList( updateBufferIndex, renderList, attachment, viewMatrix );
+ AddRendererToRenderList( updateBufferIndex, renderList, renderers[i], viewMatrix, camera, *geometryBatcher, isLayer3d, cull );
}
}
* An example case is a toolbar layer that rarely changes or a popup on top of the rest of the stage
* @param layer that is being processed
* @param renderList that is cached from frame N-1
- * @param attachmentList that is being used
+ * @param renderables list of renderables
*/
inline bool TryReuseCachedRenderers( Layer& layer,
RenderList& renderList,
- RenderableAttachmentContainer& attachmentList )
+ RenderableContainer& renderables )
{
bool retValue = false;
- size_t renderableCount = attachmentList.size();
+ size_t renderableCount = renderables.Size();
// check that the cached list originates from this layer and that the counts match
if( ( renderList.GetSourceLayer() == &layer )&&
( renderList.GetCachedItemCount() == renderableCount ) )
{
- // check that all the same renderers are there. This gives us additional security in avoiding rendering the wrong attachments
- // Attachments are not sorted, but render list is so at this stage renderers may be in different order
+ // check that all the same renderers are there. This gives us additional security in avoiding rendering the wrong things
+ // Render list is sorted so at this stage renderers may be in different order
// 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 )
{
- RenderableAttachment* attachment = attachmentList[ index ];
- const Renderer& renderer = attachment->GetRenderer();
+ 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 )
{
}
/**
- * 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 )
// 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
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 );
}
}
* @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 )
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 );
}
/**
* @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 )
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.
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();
}