[dali_1.9.23] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-renderer.cpp
index e3f1684..80449e8 100644 (file)
@@ -25,6 +25,8 @@
 #include <dali/internal/render/shaders/scene-graph-shader.h>
 #include <dali/internal/render/shaders/program.h>
 #include <dali/internal/render/data-providers/node-data-provider.h>
+#include <dali/internal/render/data-providers/uniform-map-data-provider.h>
+#include <dali/internal/render/common/render-instruction.h>
 
 namespace Dali
 {
@@ -136,6 +138,7 @@ Renderer::Renderer( SceneGraph::RenderDataProvider* dataProvider,
   mGeometry( geometry ),
   mUniformIndexMap(),
   mAttributesLocation(),
+  mUniformsHash(),
   mStencilParameters( stencilParameters ),
   mBlendingOptions(),
   mIndexedDrawFirstElement( 0 ),
@@ -146,7 +149,8 @@ Renderer::Renderer( SceneGraph::RenderDataProvider* dataProvider,
   mDepthTestMode( depthTestMode ),
   mUpdateAttributesLocation( true ),
   mPremultipledAlphaEnabled( preMultipliedAlphaEnabled ),
-  mShaderChanged( false )
+  mShaderChanged( false ),
+  mUpdated( true )
 {
   if( blendingBitmask != 0u )
   {
@@ -170,6 +174,11 @@ void Renderer::SetGeometry( Render::Geometry* geometry )
   mGeometry = geometry;
   mUpdateAttributesLocation = true;
 }
+void Renderer::SetDrawCommands( Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size )
+{
+  mDrawCommands.clear();
+  mDrawCommands.insert( mDrawCommands.end(), pDrawCommands, pDrawCommands+size );
+}
 
 void Renderer::SetBlending( Context& context, bool blend )
 {
@@ -197,6 +206,8 @@ void Renderer::SetBlending( Context& context, bool blend )
     context.BlendEquationSeparate( mBlendingOptions.GetBlendEquationRgb(),
                                    mBlendingOptions.GetBlendEquationAlpha() );
   }
+
+  mUpdated = true;
 }
 
 void Renderer::GlContextDestroyed()
@@ -375,41 +386,49 @@ bool Renderer::BindTextures( Context& context, Program& program, Vector<GLuint>&
 void Renderer::SetFaceCullingMode( FaceCullingMode::Type mode )
 {
   mFaceCullingMode =  mode;
+  mUpdated = true;
 }
 
 void Renderer::SetBlendingBitMask( uint32_t bitmask )
 {
   mBlendingOptions.SetBitmask( bitmask );
+  mUpdated = true;
 }
 
 void Renderer::SetBlendColor( const Vector4& color )
 {
   mBlendingOptions.SetBlendColor( color );
+  mUpdated = true;
 }
 
 void Renderer::SetIndexedDrawFirstElement( uint32_t firstElement )
 {
   mIndexedDrawFirstElement = firstElement;
+  mUpdated = true;
 }
 
 void Renderer::SetIndexedDrawElementsCount( uint32_t elementsCount )
 {
   mIndexedDrawElementsCount = elementsCount;
+  mUpdated = true;
 }
 
 void Renderer::EnablePreMultipliedAlpha( bool enable )
 {
   mPremultipledAlphaEnabled = enable;
+  mUpdated = true;
 }
 
 void Renderer::SetDepthWriteMode( DepthWriteMode::Type depthWriteMode )
 {
   mDepthWriteMode = depthWriteMode;
+  mUpdated = true;
 }
 
 void Renderer::SetDepthTestMode( DepthTestMode::Type depthTestMode )
 {
   mDepthTestMode = depthTestMode;
+  mUpdated = true;
 }
 
 DepthWriteMode::Type Renderer::GetDepthWriteMode() const
@@ -425,6 +444,7 @@ DepthTestMode::Type Renderer::GetDepthTestMode() const
 void Renderer::SetDepthFunction( DepthFunction::Type depthFunction )
 {
   mDepthFunction = depthFunction;
+  mUpdated = true;
 }
 
 DepthFunction::Type Renderer::GetDepthFunction() const
@@ -435,6 +455,7 @@ DepthFunction::Type Renderer::GetDepthFunction() const
 void Renderer::SetRenderMode( RenderMode::Type renderMode )
 {
   mStencilParameters.renderMode = renderMode;
+  mUpdated = true;
 }
 
 RenderMode::Type Renderer::GetRenderMode() const
@@ -445,6 +466,7 @@ RenderMode::Type Renderer::GetRenderMode() const
 void Renderer::SetStencilFunction( StencilFunction::Type stencilFunction )
 {
   mStencilParameters.stencilFunction = stencilFunction;
+  mUpdated = true;
 }
 
 StencilFunction::Type Renderer::GetStencilFunction() const
@@ -455,6 +477,7 @@ StencilFunction::Type Renderer::GetStencilFunction() const
 void Renderer::SetStencilFunctionMask( int stencilFunctionMask )
 {
   mStencilParameters.stencilFunctionMask = stencilFunctionMask;
+  mUpdated = true;
 }
 
 int Renderer::GetStencilFunctionMask() const
@@ -465,6 +488,7 @@ int Renderer::GetStencilFunctionMask() const
 void Renderer::SetStencilFunctionReference( int stencilFunctionReference )
 {
   mStencilParameters.stencilFunctionReference = stencilFunctionReference;
+  mUpdated = true;
 }
 
 int Renderer::GetStencilFunctionReference() const
@@ -475,6 +499,7 @@ int Renderer::GetStencilFunctionReference() const
 void Renderer::SetStencilMask( int stencilMask )
 {
   mStencilParameters.stencilMask = stencilMask;
+  mUpdated = true;
 }
 
 int Renderer::GetStencilMask() const
@@ -485,6 +510,7 @@ int Renderer::GetStencilMask() const
 void Renderer::SetStencilOperationOnFail( StencilOperation::Type stencilOperationOnFail )
 {
   mStencilParameters.stencilOperationOnFail = stencilOperationOnFail;
+  mUpdated = true;
 }
 
 StencilOperation::Type Renderer::GetStencilOperationOnFail() const
@@ -495,6 +521,7 @@ StencilOperation::Type Renderer::GetStencilOperationOnFail() const
 void Renderer::SetStencilOperationOnZFail( StencilOperation::Type stencilOperationOnZFail )
 {
   mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail;
+  mUpdated = true;
 }
 
 StencilOperation::Type Renderer::GetStencilOperationOnZFail() const
@@ -505,6 +532,7 @@ StencilOperation::Type Renderer::GetStencilOperationOnZFail() const
 void Renderer::SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass )
 {
   mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass;
+  mUpdated = true;
 }
 
 StencilOperation::Type Renderer::GetStencilOperationOnZPass() const
@@ -526,8 +554,32 @@ void Renderer::Render( Context& context,
                        const Matrix& projectionMatrix,
                        const Vector3& size,
                        bool blend,
-                       Vector<GLuint>& boundTextures )
+                       Vector<GLuint>& boundTextures,
+                       const Dali::Internal::SceneGraph::RenderInstruction& instruction,
+                       uint32_t queueIndex )
 {
+  // Before doing anything test if the call happens in the right queue
+  if( mDrawCommands.empty() && queueIndex > 0 )
+  {
+    return;
+  }
+
+  // Prepare commands
+  std::vector<DevelRenderer::DrawCommand*> commands;
+  for( auto& cmd : mDrawCommands )
+  {
+    if(cmd.queue == queueIndex)
+    {
+      commands.emplace_back( &cmd );
+    }
+  }
+
+  // Have commands but nothing to be drawn - abort
+  if(!mDrawCommands.empty() && commands.empty())
+  {
+    return;
+  }
+
   // Get the program to use:
   Program* program = mRenderDataProvider->GetShader().GetProgram();
   if( !program )
@@ -537,10 +589,33 @@ void Renderer::Render( Context& context,
   }
 
   //Set cull face  mode
-  context.CullFace( mFaceCullingMode );
-
-  //Set blending mode
-  SetBlending( context, blend );
+  const Dali::Internal::SceneGraph::Camera* cam = instruction.GetCamera();
+  if (cam->GetReflectionUsed())
+  {
+    auto adjFaceCullingMode = mFaceCullingMode;
+    switch( mFaceCullingMode )
+    {
+      case FaceCullingMode::Type::FRONT:
+      {
+        adjFaceCullingMode = FaceCullingMode::Type::BACK;
+        break;
+      }
+      case FaceCullingMode::Type::BACK:
+      {
+        adjFaceCullingMode = FaceCullingMode::Type::FRONT;
+        break;
+      }
+      default:
+      {
+        // nothing to do, leave culling as it is
+      }
+    }
+    context.CullFace( adjFaceCullingMode );
+  }
+  else
+  {
+    context.CullFace( mFaceCullingMode );
+  }
 
   // Take the program into use so we can send uniforms to it
   program->Use();
@@ -576,11 +651,30 @@ void Renderer::Render( Context& context,
       mUpdateAttributesLocation = false;
     }
 
-    mGeometry->Draw( context,
-                     bufferIndex,
-                     mAttributesLocation,
-                     mIndexedDrawFirstElement,
-                     mIndexedDrawElementsCount );
+    if(mDrawCommands.empty())
+    {
+      SetBlending( context, blend );
+
+      mGeometry->Draw( context,
+                       bufferIndex,
+                       mAttributesLocation,
+                       mIndexedDrawFirstElement,
+                       mIndexedDrawElementsCount );
+    }
+    else
+    {
+      for(auto& cmd : commands )
+      {
+        if(cmd->queue == queueIndex )
+        {
+          //Set blending mode
+          SetBlending(context, cmd->queue == DevelRenderer::RENDER_QUEUE_OPAQUE ? false : blend);
+          mGeometry->Draw(context, bufferIndex, mAttributesLocation,
+                          cmd->firstIndex, cmd->elementCount);
+        }
+      }
+    }
+    mUpdated = false;
   }
 }
 
@@ -596,6 +690,51 @@ void Renderer::SetShaderChanged( bool value )
   mShaderChanged = value;
 }
 
+bool Renderer::Updated(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider* node)
+{
+  if (mUpdated)
+  {
+    mUpdated = false;
+    return true;
+  }
+
+  if (mShaderChanged || mUpdateAttributesLocation || mGeometry->AttributesChanged())
+  {
+    return true;
+  }
+
+  std::vector<Render::Texture*> textures = mRenderDataProvider->GetTextures();
+  for (Render::Texture* texture : textures)
+  {
+    if (texture && texture->IsNativeImage())
+    {
+      return true;
+    }
+  }
+
+  uint64_t hash = 0xc70f6907UL;
+  const SceneGraph::CollectedUniformMap& uniformMapNode = node->GetUniformMap( bufferIndex );
+  for (const auto* uniformProperty : uniformMapNode)
+  {
+    hash = uniformProperty->propertyPtr->Hash(bufferIndex, hash);
+  }
+
+  const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMap();
+  const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap( bufferIndex );
+  for (const auto* uniformProperty : uniformMap)
+  {
+    hash = uniformProperty->propertyPtr->Hash(bufferIndex, hash);
+  }
+
+  if (mUniformsHash != hash)
+  {
+    mUniformsHash = hash;
+    return true;
+  }
+
+  return false;
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal