Changed drawing order for 2D and 3D layers 12/46012/1
authorFerran Sole <ferran.sole@samsung.com>
Thu, 13 Aug 2015 08:38:24 +0000 (09:38 +0100)
committerFerran Sole <ferran.sole@samsung.com>
Thu, 13 Aug 2015 08:38:24 +0000 (09:38 +0100)
 -In 2D Layers, all renderers (opaque and transparent) are sorted based on its SortModifier/DepthIndex.
 -In 3D Layers, opaque renderers are sorted by mesh and material to reduce GL state changes
  and transparent renderers are sorted back to front. SortModifier/DepthIndex is used as an offset to
  the Z position of the transparent renderers when sorting.

Change-Id: I5ca4cd4786bd106d62edf6428c58ad538a0dd2f3

dali/internal/render/common/render-algorithms.cpp
dali/internal/render/common/render-item.cpp
dali/internal/render/common/render-item.h
dali/internal/render/common/render-list.h
dali/internal/update/manager/prepare-render-algorithms.cpp
dali/internal/update/manager/prepare-render-instructions.cpp
dali/internal/update/manager/prepare-render-instructions.h
dali/internal/update/manager/process-render-tasks.cpp
dali/internal/update/manager/update-algorithms.cpp
dali/internal/update/nodes/scene-graph-layer.h

index 95785de..faa4b4e 100644 (file)
@@ -71,12 +71,10 @@ inline void SetRenderFlags( const RenderList& renderList, Context& context )
   const unsigned int renderFlags = renderList.GetFlags();
 
   bool enableDepthBuffer = ( ( renderFlags & RenderList::DEPTH_BUFFER_ENABLED ) != 0u );
-  bool depthMask         = ( ( renderFlags & RenderList::DEPTH_WRITE ) != 0u );
 
   GLbitfield clearMask   = ( renderFlags & RenderList::DEPTH_CLEAR ) ? GL_DEPTH_BUFFER_BIT : 0u;
 
   context.EnableDepthBuffer( enableDepthBuffer );
-  context.DepthMask( depthMask );
 
   // Stencil enabled, writing, and clearing...
   const bool enableStencilBuffer( renderFlags & RenderList::STENCIL_BUFFER_ENABLED );
@@ -132,17 +130,34 @@ inline void ProcessRenderList(
   SetScissorTest( renderList, context );
   SetRenderFlags( renderList, context );
 
-  size_t count = renderList.Count();
-  for ( size_t index = 0; index < count; ++index )
+  if( renderList.HasColorRenderItems() )
   {
-    const RenderItem& item = renderList.GetItem( index );
+    bool depthBufferEnabled = ( ( renderList.GetFlags() & RenderList::DEPTH_BUFFER_ENABLED ) != 0u );
+    size_t count = renderList.Count();
+    for ( size_t index = 0; index < count; ++index )
+    {
+      const RenderItem& item = renderList.GetItem( index );
+      DALI_PRINT_RENDER_ITEM( item );
+
+      //Enable depth writes if depth buffer is enabled and item is opaque
+      context.DepthMask( depthBufferEnabled && item.IsOpaque() );
 
-    DALI_PRINT_RENDER_ITEM( item );
+      SceneGraph::Renderer* renderer = const_cast< SceneGraph::Renderer* >( item.GetRenderer() );
+      renderer->Render( context, textureCache, bufferIndex, defaultShader, item.GetModelViewMatrix(), viewMatrix, projectionMatrix, frameTime, cullMode );
+    }
+  }
+  else
+  {
+    size_t count = renderList.Count();
+    for ( size_t index = 0; index < count; ++index )
+    {
+      const RenderItem& item = renderList.GetItem( index );
+      DALI_PRINT_RENDER_ITEM( item );
 
-    SceneGraph::Renderer* renderer = const_cast< SceneGraph::Renderer* >( item.GetRenderer() );
-    const Matrix& modelViewMatrix = item.GetModelViewMatrix();
+      SceneGraph::Renderer* renderer = const_cast< SceneGraph::Renderer* >( item.GetRenderer() );
+      renderer->Render( context, textureCache, bufferIndex, defaultShader, item.GetModelViewMatrix(), viewMatrix, projectionMatrix, frameTime, cullMode );
+    }
 
-    renderer->Render( context, textureCache, bufferIndex, defaultShader, modelViewMatrix, viewMatrix, projectionMatrix, frameTime, cullMode );
   }
 }
 
@@ -197,87 +212,6 @@ inline void RenderItemsAtDepthIndex(
 }
 
 
-/**
- * Process two interleaved render-lists.
- *
- * For each depth index, it will set the flags for the first list,
- * render items in the first list, set flags for the second list and
- * render items from the second list.
- *
- * @param[in] renderList1 The first render-list to process.
- * @param[in] renderList2 The second render-list to process.
- * @param[in] context The GL context.
- * @param[in] defaultShader The default shader to use.
- * @param[in] buffer The current render buffer index (previous update buffer)
- * @param[in] frameTime The elapsed time between the last two updates.
- * @param[in] viewMatrix The view matrix from the appropriate camera.
- * @param[in] projectionMatrix The projection matrix from the appropriate camera.
- * @param[in] cullMode True if the renderers should be subjected to clipspace culling
- */
-
-inline void ProcessInterleavedRenderLists(
-  const RenderList&         renderList1,
-  const RenderList&         renderList2,
-  Context&                  context,
-  SceneGraph::TextureCache& textureCache,
-  SceneGraph::Shader&       defaultShader,
-  BufferIndex               bufferIndex,
-  float                     frameTime,
-  const Matrix&             viewMatrix,
-  const Matrix&             projectionMatrix,
-  bool                      cullMode )
-{
-
-  SetScissorTest( renderList1, context ); // Scissor settings are identical for both lists
-  size_t count1 = renderList1.Count();
-  size_t count2 = renderList2.Count();
-  size_t index1 = 0;
-  size_t index2 = 0;
-
-  int depthIndex=renderList1.GetItem( 0 ).GetDepthIndex();
-
-  while( index1 < count1 || index2 < count2 )
-  {
-    if( index1 < count1 && index2 < count2 )
-    {
-      // Take the lowest depth index in both lists
-      depthIndex = std::min( renderList1.GetItem( index1 ).GetDepthIndex(),
-                             renderList2.GetItem( index2 ).GetDepthIndex() );
-    }
-    else if( index1 < count1 )
-    {
-      // Items left only in list 1
-      depthIndex = renderList1.GetItem( index1 ).GetDepthIndex();
-    }
-    else // index2 < count2
-    {
-      // Items left only in list 2
-      depthIndex = renderList2.GetItem( index2 ).GetDepthIndex();
-    }
-
-    // Between each successive depth index, reset the flags.
-    SetRenderFlags( renderList1, context );
-
-    // Find and render items in the first list that correspond to the current depth index
-    if( index1 < count1 )
-    {
-      RenderItemsAtDepthIndex( renderList1, context, textureCache, defaultShader,
-                               bufferIndex, frameTime, viewMatrix, projectionMatrix,
-                               cullMode, depthIndex,
-                               index1 ); // Out parameter
-    }
-
-    SetRenderFlags( renderList2, context );
-    if( index2 < count2 )
-    {
-      RenderItemsAtDepthIndex( renderList2, context, textureCache, defaultShader,
-                               bufferIndex, frameTime, viewMatrix, projectionMatrix,
-                               cullMode, depthIndex,
-                               index2 ); // Out parameter
-    }
-  }
-}
-
 
 void ProcessRenderInstruction( const RenderInstruction& instruction,
                                Context& context,
@@ -308,26 +242,7 @@ void ProcessRenderInstruction( const RenderInstruction& instruction,
       if(  renderList &&
           !renderList->IsEmpty() )
       {
-        if( renderList->GetInterleave() &&
-            index < count-1 &&
-            instruction.GetRenderList(index+1)->GetInterleave() )
-        {
-          ProcessInterleavedRenderLists( *renderList,
-                                         *(instruction.GetRenderList(index+1)),
-                                         context,
-                                         textureCache,
-                                         defaultShader,
-                                         bufferIndex,
-                                         frameTime,
-                                         *viewMatrix,
-                                         *projectionMatrix,
-                                         instruction.mCullMode );
-          index++; // Skip over next render list
-        }
-        else
-        {
           ProcessRenderList( *renderList, context, textureCache, defaultShader, bufferIndex, frameTime, *viewMatrix, *projectionMatrix, instruction.mCullMode );
-        }
       }
     }
   }
index 63e868f..a082149 100644 (file)
@@ -33,7 +33,8 @@ namespace SceneGraph
 RenderItem::RenderItem()
 : mModelViewMatrix( false ),
   mRenderer( NULL ),
-  mDepthIndex(0)
+  mDepthIndex(0),
+  mIsOpaque(true)
 {
 }
 
@@ -71,6 +72,11 @@ void RenderItem::SetDepthIndex( int depthIndex )
   mDepthIndex = depthIndex;
 }
 
+void RenderItem::SetIsOpaque( bool isOpaque )
+{
+  mIsOpaque = isOpaque;
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index 35c1107..839a1bd 100644 (file)
@@ -96,6 +96,21 @@ public:
    */
   void SetDepthIndex( int depthIndex );
 
+  /**
+   * Set if the RenderItem is opaque
+   * @param[in] isOpaque true if the RenderItem is opaque, false otherwise
+   */
+  void SetIsOpaque( bool isOpaque );
+
+  /**
+   * Check if the RenderItem is opaque
+   * @return True if it is opaque, false otherwise
+   */
+  bool IsOpaque() const
+  {
+    return mIsOpaque;
+  }
+
 private:
 
   // RenderItems should not be copied as they are heavy
@@ -105,6 +120,7 @@ private:
   Matrix    mModelViewMatrix;
   Renderer* mRenderer;
   int       mDepthIndex;
+  bool      mIsOpaque:1;
 };
 
 } // namespace SceneGraph
index 192f5f3..dfe58f1 100644 (file)
@@ -78,7 +78,7 @@ public:
     mRenderFlags( 0u ),
     mClippingBox( NULL ),
     mSourceLayer( NULL ),
-    mInterleave(false)
+    mHasColorRenderItems( false )
   {
   }
 
@@ -285,22 +285,21 @@ public:
   }
 
   /**
-   * Determine if this render list should be interleaved with it's adjacent
-   * neighbour.
-   * @return true if the render list should be interleaved
+   * Set if the RenderList contains color RenderItems
+   * @param[in] hasColorRenderItems True if it contains color RenderItems, false otherwise
    */
-  bool GetInterleave() const
+  void SetHasColorRenderItems( bool hasColorRenderItems )
   {
-    return mInterleave;
+    mHasColorRenderItems = hasColorRenderItems;
   }
 
   /**
-   * Set the interleave flag for this render list
-   * @param[in] interleave The interleave flag.
+   * Check if the RenderList contains color RenderItems
+   * @return true if the RenderList contains color RenderItems, false otherwise
    */
-  void SetInterleave(bool interleave)
+  bool HasColorRenderItems() const
   {
-    mInterleave = interleave;
+    return mHasColorRenderItems;
   }
 
 private:
@@ -316,9 +315,9 @@ private:
 
   unsigned int mRenderFlags;    ///< The render flags
 
-  ClippingBox* mClippingBox;    ///< The clipping box, in window coordinates, when clipping is enabled
-  Layer*       mSourceLayer;    ///< The originating layer where the renderers are from
-  bool         mInterleave;     ///< True if render list should be interleaved
+  ClippingBox* mClippingBox;               ///< The clipping box, in window coordinates, when clipping is enabled
+  Layer*       mSourceLayer;              ///< The originating layer where the renderers are from
+  bool         mHasColorRenderItems : 1;  ///< True if list contains color render items
 };
 
 } // namespace SceneGraph
index 51e1699..c213f95 100644 (file)
@@ -48,8 +48,7 @@ void ClearRenderables( SortedLayerPointers& sortedLayers )
   for ( SortedLayersIter iter = sortedLayers.begin(); iter != endIter; ++iter )
   {
     (*iter)->stencilRenderables.clear();
-    (*iter)->opaqueRenderables.clear();
-    (*iter)->transparentRenderables.clear();
+    (*iter)->colorRenderables.clear();
     (*iter)->overlayRenderables.clear();
   }
 }
@@ -77,8 +76,7 @@ void PrepareRenderables( BufferIndex updateBufferIndex, SortedLayerPointers& sor
     Layer& layer = **iter;
 
     PrepareRenderables( updateBufferIndex, layer.stencilRenderables );
-    PrepareRenderables( updateBufferIndex, layer.opaqueRenderables );
-    PrepareRenderables( updateBufferIndex, layer.transparentRenderables );
+    PrepareRenderables( updateBufferIndex, layer.colorRenderables );
     PrepareRenderables( updateBufferIndex, layer.overlayRenderables );
   }
 }
index 999d3c9..db7e383 100644 (file)
@@ -55,105 +55,6 @@ 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.
- */
-inline void SetOpaqueRenderFlags( RenderList& renderList, bool transparentRenderersExist, bool stencilRenderablesExist, bool depthTestDisabled )
-{
-  //@todo MESH_REWORK Move RequiresDepthTest from render thread object to update thread object
-
-  renderList.SetInterleave(transparentRenderersExist);
-
-  // 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 (e.g. mesh)
-  // and if this layer has got exactly one opaque renderer
-  // and this renderer is not interested in depth testing
-  // (i.e. is an image and not a mesh)
-  if ( (  renderList.Count() == 1 ) &&
-       (  !transparentRenderersExist ) &&
-       (  !renderList.GetRenderer( 0 )->RequiresDepthTest() ) )
-  {
-    // 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();
-    renderList.SetInterleave(false);
-  }
-  else if( depthTestDisabled )
-  {
-    renderList.ClearFlags();
-  }
-  else
-  {
-    // Prepare for rendering multiple opaque objects
-    unsigned int flags = RenderList::DEPTH_BUFFER_ENABLED | RenderList::DEPTH_WRITE | RenderList::DEPTH_CLEAR; // clear depth buffer, draw over the previously rendered layers;
-
-    renderList.ClearFlags();
-    renderList.SetFlags(flags);
-  }
-
-  if( stencilRenderablesExist )
-  {
-    renderList.SetFlags( RenderList::STENCIL_BUFFER_ENABLED );
-  }
-}
-
-/**
- * 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.
-
-  renderList.SetInterleave(opaqueRenderersExist);
-  if ( opaqueRenderersExist && !depthTestDisabled )
-  {
-    // 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_BUFFER_ENABLED );
-  }
-
-  if( stencilRenderablesExist )
-  {
-    renderList.SetFlags( RenderList::STENCIL_BUFFER_ENABLED );
-  }
-}
-
-
-/**
- * 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_BUFFER_ENABLED);
-  }
-}
-
-/**
- * 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_BUFFER_ENABLED );
-}
-
-/**
  * Add a renderer to the list
  * @param updateBufferIndex to read the model matrix from
  * @param renderList to add the item to
@@ -200,10 +101,11 @@ inline void AddRendererToRenderList( BufferIndex updateBufferIndex,
 
   if ( inside )
   {
-    // Get the next free RenderItem
+    // Get the next free RenderItem and initialization
     RenderItem& item = renderList.GetNextFreeItem();
     const Renderer& renderer = renderable.GetRenderer();
     item.SetRenderer( const_cast< Renderer* >( &renderer ) );
+    item.SetIsOpaque( renderable.IsFullyOpaque(updateBufferIndex) );
     if( isLayer3d )
     {
       item.SetDepthIndex( renderable.GetDepthIndex() );
@@ -214,8 +116,7 @@ inline void AddRendererToRenderList( BufferIndex updateBufferIndex,
     }
 
     // save MV matrix onto the item
-    Matrix& modelViewMatrix = item.GetModelViewMatrix();
-    Matrix::Multiply( modelViewMatrix, worldMatrix, viewMatrix );
+    Matrix::Multiply( item.GetModelViewMatrix(), worldMatrix, viewMatrix );
   }
 }
 
@@ -321,133 +222,57 @@ bool CompareItems( const RendererWithSortAttributes& lhs, const RendererWithSort
  * @param rhs item
  * @return true if left item is greater than right
  */
-bool CompareItemsWithZValue( const RendererWithSortAttributes& lhs, const RendererWithSortAttributes& rhs )
+bool CompareItems3D( const RendererWithSortAttributes& lhs, const RendererWithSortAttributes& rhs )
 {
-  // @todo MESH_REWORK 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( Equals(lhs.zValue, rhs.zValue) )
+  bool lhsIsOpaque = lhs.renderItem->IsOpaque();
+  if( lhsIsOpaque ==  rhs.renderItem->IsOpaque())
   {
-    if( lhs.shader == rhs.shader )
+    if( lhsIsOpaque )
     {
-      if( lhs.material == rhs.material )
+      //If both RenderItems are opaque, sort using shader, then material then geometry
+      if( lhs.shader == rhs.shader )
       {
-        return lhs.geometry < rhs.geometry;
+        if( lhs.material == rhs.material )
+        {
+          return lhs.geometry < rhs.geometry;
+        }
+        return lhs.material < rhs.material;
       }
-      return lhs.material < rhs.material;
+      return lhs.shader < rhs.shader;
     }
-    return lhs.shader < rhs.shader;
-  }
-  return lhs.zValue > rhs.zValue;
-}
-
-inline void SortOpaqueRenderItems(
-  BufferIndex bufferIndex,
-  RenderList& opaqueRenderList,
-  Layer& layer,
-  RenderItemSortingHelper& sortingHelper )
-{
-  const size_t renderableCount = opaqueRenderList.Count();
-  // reserve space if needed
-  const unsigned int oldcapacity = sortingHelper.size();
-  if( oldcapacity < renderableCount )
-  {
-    sortingHelper.reserve( renderableCount );
-    // add real objects (reserve does not construct objects)
-    sortingHelper.insert( sortingHelper.begin() + oldcapacity,
-                          (renderableCount - oldcapacity),
-                          RendererWithSortAttributes() );
-  }
-  else
-  {
-    // clear extra elements from helper, does not decrease capability
-    sortingHelper.resize( renderableCount );
-  }
-
-  for( size_t index = 0; index < renderableCount; ++index )
-  {
-    RenderItem& item = opaqueRenderList.GetItem( index );
-
-    //@todo MESH_REWORK After merge of RenderableAttachment and RendererAttachment, should instead store the renderable ptr and get the fields directly
-    layer.opaqueRenderables[index]->SetSortAttributes( bufferIndex, sortingHelper[ index ] );
-
-    sortingHelper[ index ].zValue = 0;
-    sortingHelper[ index ].renderItem = &item;
-  }
-
-  // Sort the renderers by depth index, then by instance
-  std::stable_sort( sortingHelper.begin(), sortingHelper.end(), CompareItems );
-
-  DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "Sorted Opaque List:\n");
-
-  // Repopulate the render items in the render list based on the sorting helper
-  RenderItemContainer::Iterator renderListIter = opaqueRenderList.GetContainer().Begin();
-  for( unsigned int index = 0; index < renderableCount; ++index, ++renderListIter )
-  {
-    *renderListIter = sortingHelper[ index ].renderItem;
-    DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "  sortedList[%d] = %p\n", index, sortingHelper[ index ].renderItem->GetRenderer() );
-  }
-}
-
-/**
- * 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 cameraAttachment to use the view frustum
- * @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 disableDepthTest is true if depth test should be disabled on this layer
- * @param instruction to fill in
- * @param tryReuseRenderList whether to try to reuse the cached items from the instruction
- */
-inline void AddOpaqueRenderers( BufferIndex updateBufferIndex,
-                                Layer& layer,
-                                const Matrix& viewMatrix,
-                                SceneGraph::CameraAttachment& cameraAttachment,
-                                bool transparentRenderablesExist,
-                                bool stencilRenderablesExist,
-                                bool disableDepthTest,
-                                RenderInstruction& instruction,
-                                RendererSortingHelper& sortingHelper,
-                                bool tryReuseRenderList )
-{
-  const size_t renderableCount = layer.opaqueRenderables.size();
-  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( TryReuseCachedRenderers( layer, opaqueRenderList, layer.opaqueRenderables ) )
+    else
     {
-      // reset the flags as other layers might have changed
-      // opaque flags can only be set after renderers are added
-      SetOpaqueRenderFlags( opaqueRenderList, transparentRenderablesExist, stencilRenderablesExist, disableDepthTest );
-      return;
+      //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.material == rhs.material )
+          {
+            return lhs.geometry < rhs.geometry;
+          }
+          return lhs.material < rhs.material;
+        }
+        return lhs.shader < rhs.shader;
+      }
+      return lhs.zValue > rhs.zValue;
     }
   }
-  AddRenderersToRenderList( updateBufferIndex, opaqueRenderList, layer.opaqueRenderables, viewMatrix, cameraAttachment, layer.GetBehavior() == Dali::Layer::LAYER_3D );
-
-  // opaque flags can only be set after renderers are added
-  SetOpaqueRenderFlags(opaqueRenderList, transparentRenderablesExist, stencilRenderablesExist, disableDepthTest );
-
-  // sorting is only needed if more than 1 item
-  if( renderableCount > 1 )
+  else
   {
-    SortOpaqueRenderItems( updateBufferIndex, opaqueRenderList, layer, sortingHelper.opaque );
+    return lhsIsOpaque;
   }
 }
 
 /**
- * Sort transparent render items
- * @param transparentRenderList to sort
+ * Sort color render items
+ * @param colorRenderList to sort
  * @param layer where the renderers are from
  * @param sortingHelper to use for sorting the renderitems (to avoid reallocating)
  */
-inline void SortTransparentRenderItems( BufferIndex bufferIndex, RenderList& transparentRenderList, Layer& layer, RenderItemSortingHelper& sortingHelper )
+inline void SortColorRenderItems( 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 )
@@ -470,13 +295,13 @@ inline void SortTransparentRenderItems( BufferIndex bufferIndex, RenderList& tra
   {
     for( size_t index = 0; index < renderableCount; ++index )
     {
-      RenderItem& item = transparentRenderList.GetItem( index );
+      RenderItem& item = renderList.GetItem( index );
 
       //@todo MESH_REWORK After merge of RenderableAttachment and RendererAttachment, should instead store the renderable ptr and get the fields directly
-      layer.transparentRenderables[index]->SetSortAttributes( bufferIndex, sortingHelper[ index ] );
+      layer.colorRenderables[index]->SetSortAttributes( bufferIndex, sortingHelper[ index ] );
 
       // the default sorting function should get inlined here
-      sortingHelper[ index ].zValue = Internal::Layer::ZValue( item.GetModelViewMatrix().GetTranslation3() ) + item.GetDepthIndex();
+      sortingHelper[ index ].zValue = Internal::Layer::ZValue( item.GetModelViewMatrix().GetTranslation3() ) - item.GetDepthIndex();
 
       // keep the renderitem pointer in the helper so we can quickly reorder items after sort
       sortingHelper[ index ].renderItem = &item;
@@ -487,10 +312,10 @@ inline void SortTransparentRenderItems( BufferIndex bufferIndex, RenderList& tra
     const Dali::Layer::SortFunctionType sortFunction = layer.GetSortFunction();
     for( size_t index = 0; index < renderableCount; ++index )
     {
-      RenderItem& item = transparentRenderList.GetItem( index );
+      RenderItem& item = renderList.GetItem( index );
 
-      layer.transparentRenderables[index]->SetSortAttributes( bufferIndex, sortingHelper[ index ] );
-      sortingHelper[ index ].zValue = (*sortFunction)( item.GetModelViewMatrix().GetTranslation3() );
+      layer.colorRenderables[index]->SetSortAttributes( bufferIndex, sortingHelper[ index ] );
+      sortingHelper[ index ].zValue = (*sortFunction)( item.GetModelViewMatrix().GetTranslation3() ) - item.GetDepthIndex();
 
       // keep the renderitem pointer in the helper so we can quickly reorder items after sort
       sortingHelper[ index ].renderItem = &item;
@@ -500,7 +325,7 @@ inline void SortTransparentRenderItems( BufferIndex bufferIndex, RenderList& tra
   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(), CompareItemsWithZValue );
+    std::stable_sort( sortingHelper.begin(), sortingHelper.end(), CompareItems3D );
   }
   else
   {
@@ -510,7 +335,7 @@ inline void SortTransparentRenderItems( BufferIndex bufferIndex, RenderList& tra
 
   // reorder/repopulate the renderitems in renderlist to correct order based on sortinghelper
   DALI_LOG_INFO( gRenderListLogFilter, Debug::Verbose, "Sorted Transparent List:\n");
-  RenderItemContainer::Iterator renderListIter = transparentRenderList.GetContainer().Begin();
+  RenderItemContainer::Iterator renderListIter = renderList.GetContainer().Begin();
   for( unsigned int index = 0; index < renderableCount; ++index, ++renderListIter )
   {
     *renderListIter = sortingHelper[ index ].renderItem;
@@ -519,50 +344,67 @@ inline void SortTransparentRenderItems( BufferIndex bufferIndex, RenderList& tra
 }
 
 /**
- * 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 cameraAttachment 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 tryReuseRenderList whether to try to reuse the cached items from the instruction
  */
-inline void AddTransparentRenderers( BufferIndex updateBufferIndex,
-                                     Layer& layer,
-                                     const Matrix& viewMatrix,
-                                     SceneGraph::CameraAttachment& cameraAttachment,
-                                     bool opaqueRenderablesExist,
-                                     bool stencilRenderablesExist,
-                                     RenderInstruction& instruction,
-                                     RendererSortingHelper& sortingHelper,
-                                     bool tryReuseRenderList )
+inline void AddColorRenderers( BufferIndex updateBufferIndex,
+                               Layer& layer,
+                               const Matrix& viewMatrix,
+                               SceneGraph::CameraAttachment& cameraAttachment,
+                               bool stencilRenderablesExist,
+                               RenderInstruction& instruction,
+                               RendererSortingHelper& sortingHelper,
+                               bool tryReuseRenderList )
 {
-  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.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, cameraAttachment, layer.GetBehavior() == Dali::Layer::LAYER_3D );
+  AddRenderersToRenderList( updateBufferIndex, renderList, layer.colorRenderables, viewMatrix, cameraAttachment, layer.GetBehavior() == Dali::Layer::LAYER_3D );
+  SortColorRenderItems( updateBufferIndex, renderList, layer, sortingHelper );
 
-  // sorting is only needed if more than 1 item
-  if( renderableCount > 1 )
+  //Set render flags
+  unsigned int flags = 0u;
+  if( stencilRenderablesExist )
   {
-    SortTransparentRenderItems( updateBufferIndex, transparentRenderList, layer, sortingHelper.transparent );
+    flags = RenderList::STENCIL_BUFFER_ENABLED;
   }
+
+  // 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 (e.g. mesh)
+  // and if this layer has got exactly one opaque renderer
+  // and this renderer is not interested in depth testing
+  // (i.e. is an image and not a mesh)
+  if ( ( renderList.Count() == 1 ) &&
+       ( !renderList.GetRenderer( 0 )->RequiresDepthTest() ) &&
+       ( !renderList.GetItem(0).IsOpaque() ) )
+  {
+    //Nothing to do here
+  }
+  else if( !layer.IsDepthTestDisabled())
+  {
+    flags |= RenderList::DEPTH_BUFFER_ENABLED;
+    flags |= RenderList::DEPTH_CLEAR;
+  }
+
+  renderList.ClearFlags();
+  renderList.SetFlags( flags );
 }
 
 /**
@@ -584,7 +426,14 @@ inline void AddOverlayRenderers( BufferIndex updateBufferIndex,
 {
   RenderList& overlayRenderList = instruction.GetNextFreeRenderList( layer.overlayRenderables.size() );
   overlayRenderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() );
-  SetOverlayRenderFlags( overlayRenderList, stencilRenderablesExist );
+  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 )
@@ -614,7 +463,11 @@ inline void AddStencilRenderers( BufferIndex updateBufferIndex,
 {
   RenderList& stencilRenderList = instruction.GetNextFreeRenderList( layer.stencilRenderables.size() );
   stencilRenderList.SetClipping( layer.IsClipping(), layer.GetClippingBox() );
-  SetStencilRenderFlags( stencilRenderList );
+  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 )
@@ -658,49 +511,29 @@ void PrepareRenderInstruction( BufferIndex updateBufferIndex,
     Layer& layer = **iter;
 
     const bool stencilRenderablesExist( !layer.stencilRenderables.empty() );
-    const bool opaqueRenderablesExist( !layer.opaqueRenderables.empty() );
-    const bool transparentRenderablesExist( !layer.transparentRenderables.empty() );
+    const bool colorRenderablesExist( !layer.colorRenderables.empty() );
     const bool overlayRenderablesExist( !layer.overlayRenderables.empty() );
-    const bool disableDepthTest( layer.IsDepthTestDisabled() );
     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, cameraAttachment, instruction, tryReuseRenderList );
     }
 
-    if ( opaqueRenderablesExist )
+    if ( colorRenderablesExist )
     {
-      AddOpaqueRenderers( updateBufferIndex,
-                          layer,
-                          viewMatrix,
-                          cameraAttachment,
-                          transparentRenderablesExist,
-                          stencilRenderablesExist,
-                          disableDepthTest,
-                          instruction,
-                          sortingHelper,
-                          tryReuseRenderList );
+      AddColorRenderers( updateBufferIndex,
+                         layer,
+                         viewMatrix,
+                         cameraAttachment,
+                         stencilRenderablesExist,
+                         instruction,
+                         sortingHelper,
+                         tryReuseRenderList );
     }
 
-    if ( transparentRenderablesExist )
-    {
-      AddTransparentRenderers( updateBufferIndex,
-                               layer,
-                               viewMatrix,
-                               cameraAttachment,
-                               opaqueRenderablesExist,
-                               stencilRenderablesExist,
-                               instruction,
-                               sortingHelper,
-                               tryReuseRenderList );
-    }
-
-    // @todo MESH_REWORK Mark opaque and transparent render lists as interleaveable.
-    // ( Saves having to have a pair of lists for each depth index )
-
     if ( overlayRenderablesExist )
     {
       AddOverlayRenderers( updateBufferIndex, layer, viewMatrix, cameraAttachment, stencilRenderablesExist,
index b773752..d8e794f 100644 (file)
@@ -58,13 +58,7 @@ struct RendererWithSortAttributes
   float       zValue;           // The zValue of the given renderer (either distance from camera, or a custom calculated value)
 };
 
-typedef std::vector< RendererWithSortAttributes > RenderItemSortingHelper;
-
-struct RendererSortingHelper
-{
-  RenderItemSortingHelper transparent;
-  RenderItemSortingHelper opaque;
-};
+typedef std::vector< RendererWithSortAttributes > RendererSortingHelper;
 
 class RenderTask;
 class RenderInstructionContainer;
index 366db13..478b58a 100644 (file)
@@ -164,13 +164,9 @@ static bool AddRenderablesForTask( BufferIndex updateBufferIndex,
           {
             layer->overlayRenderables.push_back( renderable );
           }
-          else if ( renderable->IsFullyOpaque( updateBufferIndex ) )
-          {
-            layer->opaqueRenderables.push_back( renderable );
-          }
           else
           {
-            layer->transparentRenderables.push_back( renderable );
+            layer->colorRenderables.push_back( renderable );
           }
         }
       }
index 232621a..2e296dc 100644 (file)
@@ -319,7 +319,7 @@ inline void AddRenderableToLayer( Layer& layer,
 {
   // The renderables are stored into the opaque list temporarily for PrepareRenderables()
   // step. The list is cleared by ProcessRenderTasks().
-  layer.opaqueRenderables.push_back( &renderable );
+  layer.colorRenderables.push_back( &renderable );
 }
 
 /**
index e414cc3..90789e4 100644 (file)
@@ -199,8 +199,7 @@ private:
 public: // For update-algorithms
 
   RenderableAttachmentContainer stencilRenderables;
-  RenderableAttachmentContainer transparentRenderables;
-  RenderableAttachmentContainer opaqueRenderables;
+  RenderableAttachmentContainer colorRenderables;
   RenderableAttachmentContainer overlayRenderables;
 
 private: