Merge "Clean up the code to build successfully on macOS" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / event / rendering / renderer-impl.cpp
index 2f66002..838e047 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
@@ -20,9 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/devel-api/scripting/scripting.h>
-#include <dali/devel-api/rendering/renderer-devel.h>
 #include <dali/public-api/object/type-registry.h>
-#include <dali/internal/event/common/object-impl-helper.h> // Dali::Internal::ObjectHelper
 #include <dali/internal/event/common/property-helper.h>    // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
 #include <dali/internal/event/common/property-input-impl.h>
 #include <dali/internal/render/renderers/render-geometry.h>
@@ -66,6 +64,8 @@ DALI_PROPERTY( "stencilOperationOnFail",          INTEGER,   true, false,  false
 DALI_PROPERTY( "stencilOperationOnZFail",         INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL )
 DALI_PROPERTY( "stencilOperationOnZPass",         INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS )
 DALI_PROPERTY( "opacity",                         FLOAT,     true, true,   true,  Dali::DevelRenderer::Property::OPACITY )
+DALI_PROPERTY( "renderingBehavior",               INTEGER,   true, false,  false, Dali::DevelRenderer::Property::RENDERING_BEHAVIOR )
+DALI_PROPERTY( "blendEquation",                   INTEGER,   true, false,  false, Dali::DevelRenderer::Property::BLEND_EQUATION )
 DALI_PROPERTY_TABLE_END( DEFAULT_RENDERER_PROPERTY_START_INDEX, RendererDefaultProperties )
 
 // Property string to enumeration tables:
@@ -87,6 +87,23 @@ DALI_ENUM_TO_STRING_TABLE_BEGIN( BLEND_EQUATION )
 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendEquation, ADD )
 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendEquation, SUBTRACT )
 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendEquation, REVERSE_SUBTRACT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, MIN )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, MAX )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, MULTIPLY )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, SCREEN )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, OVERLAY )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, DARKEN )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, LIGHTEN )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, COLOR_DODGE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, COLOR_BURN )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, HARD_LIGHT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, SOFT_LIGHT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, DIFFERENCE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, EXCLUSION )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, HUE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, SATURATION )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, COLOR )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, LUMINOSITY )
 DALI_ENUM_TO_STRING_TABLE_END( BLEND_EQUATION )
 
 DALI_ENUM_TO_STRING_TABLE_BEGIN( BLEND_FACTOR )
@@ -160,6 +177,11 @@ DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, INCREMENT_WRAP )
 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, DECREMENT_WRAP )
 DALI_ENUM_TO_STRING_TABLE_END( STENCIL_OPERATION )
 
+DALI_ENUM_TO_STRING_TABLE_BEGIN( RENDERING_BEHAVIOR )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelRenderer::Rendering, IF_REQUIRED )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DevelRenderer::Rendering, CONTINUOUSLY )
+DALI_ENUM_TO_STRING_TABLE_END( RENDERING_BEHAVIOR )
+
 BaseHandle Create()
 {
   return Dali::BaseHandle();
@@ -171,8 +193,17 @@ TypeRegistration mType( typeid( Dali::Renderer ), typeid( Dali::Handle ), Create
 
 RendererPtr Renderer::New()
 {
-  RendererPtr rendererPtr( new Renderer() );
-  rendererPtr->Initialize();
+  // create scene object first so it's guaranteed to exist for the event side
+  auto sceneObject = SceneGraph::Renderer::New();
+  OwnerPointer< SceneGraph::Renderer > transferOwnership( sceneObject );
+  // pass the pointer to base for message passing
+  RendererPtr rendererPtr( new Renderer( sceneObject ) );
+  // transfer scene object ownership to update manager
+  EventThreadServices& eventThreadServices = rendererPtr->GetEventThreadServices();
+  SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
+  AddRendererMessage( updateManager, transferOwnership );
+
+  eventThreadServices.RegisterObject( rendererPtr.Get() );
   return rendererPtr;
 }
 
@@ -181,48 +212,48 @@ void Renderer::SetGeometry( Geometry& geometry )
   mGeometry = &geometry;
 
   const Render::Geometry* geometrySceneObject = geometry.GetRenderObject();
-  SetGeometryMessage( GetEventThreadServices(), *mSceneObject, *geometrySceneObject );
+  SetGeometryMessage( GetEventThreadServices(), GetRendererSceneObject(), *geometrySceneObject );
 }
 
-Geometry* Renderer::GetGeometry() const
+GeometryPtr Renderer::GetGeometry() const
 {
-  return mGeometry.Get();
+  return mGeometry;
 }
 
 void Renderer::SetTextures( TextureSet& textureSet )
 {
   mTextureSet = &textureSet;
   const SceneGraph::TextureSet* textureSetSceneObject = textureSet.GetTextureSetSceneObject();
-  SetTexturesMessage( GetEventThreadServices(), *mSceneObject, *textureSetSceneObject );
+  SetTexturesMessage( GetEventThreadServices(), GetRendererSceneObject(), *textureSetSceneObject );
 }
 
-TextureSet* Renderer::GetTextures() const
+TextureSetPtr Renderer::GetTextures() const
 {
-  return mTextureSet.Get();
+  return mTextureSet;
 }
 
 void Renderer::SetShader( Shader& shader )
 {
   mShader = &shader;
-  SceneGraph::Shader& sceneGraphShader = *shader.GetShaderSceneObject();
-  SceneGraph::SetShaderMessage( GetEventThreadServices(), *mSceneObject, sceneGraphShader );
+  const SceneGraph::Shader& sceneGraphShader = shader.GetShaderSceneObject();
+  SceneGraph::SetShaderMessage( GetEventThreadServices(), GetRendererSceneObject(), sceneGraphShader );
 }
 
-Shader* Renderer::GetShader() const
+ShaderPtr Renderer::GetShader() const
 {
-  return mShader.Get();
+  return mShader;
 }
 
-void Renderer::SetDepthIndex( int depthIndex )
+void Renderer::SetDepthIndex( int32_t depthIndex )
 {
   if ( mDepthIndex != depthIndex )
   {
     mDepthIndex = depthIndex;
-    SetDepthIndexMessage( GetEventThreadServices(), *mSceneObject, depthIndex );
+    SetDepthIndexMessage( GetEventThreadServices(), GetRendererSceneObject(), depthIndex );
   }
 }
 
-int Renderer::GetDepthIndex() const
+int32_t Renderer::GetDepthIndex() const
 {
   return mDepthIndex;
 }
@@ -233,7 +264,7 @@ void Renderer::SetBlendMode( BlendMode::Type mode )
   {
     mBlendMode = mode;
 
-    SetBlendModeMessage( GetEventThreadServices(), *mSceneObject, mBlendMode );
+    SetBlendModeMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendMode );
   }
 }
 
@@ -245,7 +276,7 @@ BlendMode::Type Renderer::GetBlendMode() const
 void Renderer::SetBlendFunc( BlendFactor::Type srcFactorRgba, BlendFactor::Type destFactorRgba )
 {
   mBlendingOptions.SetBlendFunc( srcFactorRgba, destFactorRgba, srcFactorRgba, destFactorRgba );
-  SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
+  SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
 }
 
 void Renderer::SetBlendFunc( BlendFactor::Type srcFactorRgb,
@@ -254,7 +285,7 @@ void Renderer::SetBlendFunc( BlendFactor::Type srcFactorRgb,
                              BlendFactor::Type destFactorAlpha )
 {
   mBlendingOptions.SetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
-  SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
+  SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
 }
 
 void Renderer::GetBlendFunc( BlendFactor::Type& srcFactorRgb,
@@ -268,21 +299,26 @@ void Renderer::GetBlendFunc( BlendFactor::Type& srcFactorRgb,
   destFactorAlpha = mBlendingOptions.GetBlendDestFactorAlpha();
 }
 
-void Renderer::SetBlendEquation( BlendEquation::Type equationRgba )
+void Renderer::SetBlendEquation( DevelBlendEquation::Type equationRgba )
 {
   mBlendingOptions.SetBlendEquation( equationRgba, equationRgba );
-  SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
+  SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
 }
 
-void Renderer::SetBlendEquation( BlendEquation::Type equationRgb,
-                                 BlendEquation::Type equationAlpha )
+void Renderer::SetBlendEquation( DevelBlendEquation::Type equationRgb,
+                                 DevelBlendEquation::Type equationAlpha )
 {
+  if( mBlendingOptions.IsAdvancedBlendEquation( equationRgb ) || mBlendingOptions.IsAdvancedBlendEquation( equationAlpha ) )
+  {
+    DALI_LOG_ERROR("Advanced blend equation requires to be set by using SetBlendEquation( DevelBlendEquation::Type equationRgba ).");
+    return;
+  }
   mBlendingOptions.SetBlendEquation( equationRgb, equationAlpha );
-  SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
+  SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
 }
 
-void Renderer::GetBlendEquation( BlendEquation::Type& equationRgb,
-                                 BlendEquation::Type& equationAlpha ) const
+void Renderer::GetBlendEquation( DevelBlendEquation::Type& equationRgb,
+                                 DevelBlendEquation::Type& equationAlpha ) const
 {
   // These are not animatable, the cached values are up-to-date.
   equationRgb   = mBlendingOptions.GetBlendEquationRgb();
@@ -294,7 +330,7 @@ void Renderer::SetIndexedDrawFirstElement( uint32_t firstElement )
   if( firstElement != mIndexedDrawFirstElement )
   {
     mIndexedDrawFirstElement = firstElement;
-    SetIndexedDrawFirstElementMessage( GetEventThreadServices(), *mSceneObject, mIndexedDrawFirstElement );
+    SetIndexedDrawFirstElementMessage( GetEventThreadServices(), GetRendererSceneObject(), mIndexedDrawFirstElement );
   }
 }
 
@@ -303,7 +339,7 @@ void Renderer::SetIndexedDrawElementsCount( uint32_t elementsCount )
   if( elementsCount != mIndexedDrawElementCount )
   {
     mIndexedDrawElementCount = elementsCount;
-    SetIndexedDrawElementsCountMessage( GetEventThreadServices(), *mSceneObject, mIndexedDrawElementCount );
+    SetIndexedDrawElementsCountMessage( GetEventThreadServices(), GetRendererSceneObject(), mIndexedDrawElementCount );
   }
 }
 
@@ -321,7 +357,7 @@ void Renderer::EnablePreMultipliedAlpha( bool preMultipled )
       SetBlendFunc( BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::ONE, BlendFactor::ONE_MINUS_SRC_ALPHA );
     }
     mPremultipledAlphaEnabled = preMultipled;
-    SetEnablePreMultipliedAlphaMessage( GetEventThreadServices(), *mSceneObject, mPremultipledAlphaEnabled );
+    SetEnablePreMultipliedAlphaMessage( GetEventThreadServices(), GetRendererSceneObject(), mPremultipledAlphaEnabled );
   }
 }
 
@@ -330,9 +366,22 @@ bool Renderer::IsPreMultipliedAlphaEnabled() const
   return mPremultipledAlphaEnabled;
 }
 
-SceneGraph::Renderer* Renderer::GetRendererSceneObject()
+bool Renderer::IsAdvancedBlendEquationApplied() const
 {
-  return mSceneObject;
+  DevelBlendEquation::Type equationRgb, equationAlpha;
+  GetBlendEquation( equationRgb, equationAlpha );
+
+  if( equationRgb != equationAlpha )
+  {
+    return false;
+  }
+
+  return mBlendingOptions.IsAdvancedBlendEquation( equationRgb );
+}
+
+const SceneGraph::Renderer& Renderer::GetRendererSceneObject() const
+{
+  return static_cast<const SceneGraph::Renderer&>( GetSceneObject() );
 }
 
 void Renderer::SetDefaultProperty( Property::Index index,
@@ -342,7 +391,7 @@ void Renderer::SetDefaultProperty( Property::Index index,
   {
     case Dali::Renderer::Property::DEPTH_INDEX:
     {
-      SetDepthIndex( propertyValue.Get<int>() );
+      SetDepthIndex( propertyValue.Get<int32_t>() );
       break;
     }
     case Dali::Renderer::Property::FACE_CULLING_MODE:
@@ -351,7 +400,7 @@ void Renderer::SetDefaultProperty( Property::Index index,
       if( Scripting::GetEnumerationProperty< FaceCullingMode::Type >( propertyValue, FACE_CULLING_MODE_TABLE, FACE_CULLING_MODE_TABLE_COUNT, convertedValue ) )
       {
         mFaceCullingMode = convertedValue;
-        SetFaceCullingModeMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
+        SetFaceCullingModeMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
       }
       break;
     }
@@ -364,27 +413,48 @@ void Renderer::SetDefaultProperty( Property::Index index,
       }
       break;
     }
+    case Dali::DevelRenderer::Property::BLEND_EQUATION:
+    {
+      DevelBlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationRgb();
+
+      if( Scripting::GetEnumerationProperty< DevelBlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
+      {
+        mBlendingOptions.SetBlendEquation( convertedValue, convertedValue );
+        SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
+      }
+      break;
+    }
     case Dali::Renderer::Property::BLEND_EQUATION_RGB:
     {
-      BlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationRgb();
+      DevelBlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationRgb();
 
-      if( Scripting::GetEnumerationProperty< BlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
+      if( Scripting::GetEnumerationProperty< DevelBlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
       {
-        BlendEquation::Type alphaEquation = mBlendingOptions.GetBlendEquationAlpha();
+        if( mBlendingOptions.IsAdvancedBlendEquation( convertedValue ) )
+        {
+          DALI_LOG_ERROR("Advanced blend equation requires to be set by using DevelBlendEquation::BLEND_EQUATION.");
+          break;
+        }
+        DevelBlendEquation::Type alphaEquation = mBlendingOptions.GetBlendEquationAlpha();
         mBlendingOptions.SetBlendEquation( convertedValue, alphaEquation );
-        SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
+        SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
       }
       break;
     }
     case Dali::Renderer::Property::BLEND_EQUATION_ALPHA:
     {
-      BlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationAlpha();
+      DevelBlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationAlpha();
 
-      if( Scripting::GetEnumerationProperty< BlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
+      if( Scripting::GetEnumerationProperty< DevelBlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
       {
-        BlendEquation::Type rgbEquation = mBlendingOptions.GetBlendEquationRgb();
+        if( mBlendingOptions.IsAdvancedBlendEquation( convertedValue ) )
+        {
+          DALI_LOG_ERROR("Advanced blend equation requires to be set by using DevelBlendEquation::BLEND_EQUATION.");
+          break;
+        }
+        DevelBlendEquation::Type rgbEquation = mBlendingOptions.GetBlendEquationRgb();
         mBlendingOptions.SetBlendEquation( rgbEquation, convertedValue );
-        SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
+        SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
       }
       break;
     }
@@ -452,7 +522,7 @@ void Renderer::SetDefaultProperty( Property::Index index,
     }
     case Dali::Renderer::Property::INDEX_RANGE_FIRST:
     {
-      int firstElement;
+      int32_t firstElement;
       if( propertyValue.Get( firstElement ) )
       {
         SetIndexedDrawFirstElement( firstElement );
@@ -461,7 +531,7 @@ void Renderer::SetDefaultProperty( Property::Index index,
     }
     case Dali::Renderer::Property::INDEX_RANGE_COUNT:
     {
-      int elementsCount;
+      int32_t elementsCount;
       if( propertyValue.Get( elementsCount ) )
       {
         SetIndexedDrawElementsCount( elementsCount );
@@ -474,7 +544,7 @@ void Renderer::SetDefaultProperty( Property::Index index,
       if( Scripting::GetEnumerationProperty< DepthWriteMode::Type >( propertyValue, DEPTH_WRITE_MODE_TABLE, DEPTH_WRITE_MODE_TABLE_COUNT, convertedValue ) )
       {
         mDepthWriteMode = convertedValue;
-        SetDepthWriteModeMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
+        SetDepthWriteModeMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
       }
       break;
     }
@@ -484,7 +554,7 @@ void Renderer::SetDefaultProperty( Property::Index index,
       if( Scripting::GetEnumerationProperty< DepthFunction::Type >( propertyValue, DEPTH_FUNCTION_TABLE, DEPTH_FUNCTION_TABLE_COUNT, convertedValue ) )
       {
         mDepthFunction = convertedValue;
-        SetDepthFunctionMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
+        SetDepthFunctionMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
       }
       break;
     }
@@ -494,7 +564,7 @@ void Renderer::SetDefaultProperty( Property::Index index,
       if( Scripting::GetEnumerationProperty< DepthTestMode::Type >( propertyValue, DEPTH_TEST_MODE_TABLE, DEPTH_TEST_MODE_TABLE_COUNT, convertedValue ) )
       {
         mDepthTestMode = convertedValue;
-        SetDepthTestModeMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
+        SetDepthTestModeMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
       }
       break;
     }
@@ -504,7 +574,7 @@ void Renderer::SetDefaultProperty( Property::Index index,
       if( Scripting::GetEnumerationProperty< RenderMode::Type >( propertyValue, RENDER_MODE_TABLE, RENDER_MODE_TABLE_COUNT, convertedValue ) )
       {
         mStencilParameters.renderMode = convertedValue;
-        SetRenderModeMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
+        SetRenderModeMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
       }
       break;
     }
@@ -514,45 +584,45 @@ void Renderer::SetDefaultProperty( Property::Index index,
       if( Scripting::GetEnumerationProperty< StencilFunction::Type >( propertyValue, STENCIL_FUNCTION_TABLE, STENCIL_FUNCTION_TABLE_COUNT, convertedValue ) )
       {
         mStencilParameters.stencilFunction = convertedValue;
-        SetStencilFunctionMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
+        SetStencilFunctionMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
       }
       break;
     }
     case Dali::Renderer::Property::STENCIL_FUNCTION_MASK:
     {
-      int stencilFunctionMask;
+      int32_t stencilFunctionMask;
       if( propertyValue.Get( stencilFunctionMask ) )
       {
         if( stencilFunctionMask != mStencilParameters.stencilFunctionMask )
         {
           mStencilParameters.stencilFunctionMask = stencilFunctionMask;
-          SetStencilFunctionMaskMessage( GetEventThreadServices(), *mSceneObject, stencilFunctionMask );
+          SetStencilFunctionMaskMessage( GetEventThreadServices(), GetRendererSceneObject(), stencilFunctionMask );
         }
       }
       break;
     }
     case Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE:
     {
-      int stencilFunctionReference;
+      int32_t stencilFunctionReference;
       if( propertyValue.Get( stencilFunctionReference ) )
       {
         if( stencilFunctionReference != mStencilParameters.stencilFunctionReference )
         {
           mStencilParameters.stencilFunctionReference = stencilFunctionReference;
-          SetStencilFunctionReferenceMessage( GetEventThreadServices(), *mSceneObject, stencilFunctionReference );
+          SetStencilFunctionReferenceMessage( GetEventThreadServices(), GetRendererSceneObject(), stencilFunctionReference );
         }
       }
       break;
     }
     case Dali::Renderer::Property::STENCIL_MASK:
     {
-      int stencilMask;
+      int32_t stencilMask;
       if( propertyValue.Get( stencilMask ) )
       {
         if( stencilMask != mStencilParameters.stencilMask )
         {
           mStencilParameters.stencilMask = stencilMask;
-          SetStencilMaskMessage( GetEventThreadServices(), *mSceneObject, stencilMask );
+          SetStencilMaskMessage( GetEventThreadServices(), GetRendererSceneObject(), stencilMask );
         }
       }
       break;
@@ -563,7 +633,7 @@ void Renderer::SetDefaultProperty( Property::Index index,
       if( Scripting::GetEnumerationProperty< StencilOperation::Type >( propertyValue, STENCIL_OPERATION_TABLE, STENCIL_OPERATION_TABLE_COUNT, convertedValue ) )
       {
         mStencilParameters.stencilOperationOnFail = convertedValue;
-        SetStencilOperationOnFailMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
+        SetStencilOperationOnFailMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
       }
       break;
     }
@@ -573,7 +643,7 @@ void Renderer::SetDefaultProperty( Property::Index index,
       if( Scripting::GetEnumerationProperty< StencilOperation::Type >( propertyValue, STENCIL_OPERATION_TABLE, STENCIL_OPERATION_TABLE_COUNT, convertedValue ) )
       {
         mStencilParameters.stencilOperationOnZFail = convertedValue;
-        SetStencilOperationOnZFailMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
+        SetStencilOperationOnZFailMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
       }
       break;
     }
@@ -583,7 +653,7 @@ void Renderer::SetDefaultProperty( Property::Index index,
       if( Scripting::GetEnumerationProperty< StencilOperation::Type >( propertyValue, STENCIL_OPERATION_TABLE, STENCIL_OPERATION_TABLE_COUNT, convertedValue ) )
       {
         mStencilParameters.stencilOperationOnZPass = convertedValue;
-        SetStencilOperationOnZPassMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
+        SetStencilOperationOnZPassMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
       }
       break;
     }
@@ -595,22 +665,24 @@ void Renderer::SetDefaultProperty( Property::Index index,
         if( !Equals( mOpacity, opacity ) )
         {
           mOpacity = opacity;
-          BakeOpacityMessage( GetEventThreadServices(), *mSceneObject, mOpacity );
+          BakeOpacityMessage( GetEventThreadServices(), GetRendererSceneObject(), mOpacity );
         }
       }
       break;
     }
+    case DevelRenderer::Property::RENDERING_BEHAVIOR:
+    {
+      DevelRenderer::Rendering::Type convertedValue = mRenderingBehavior;
+      if( Scripting::GetEnumerationProperty< DevelRenderer::Rendering::Type >( propertyValue, RENDERING_BEHAVIOR_TABLE, RENDERING_BEHAVIOR_TABLE_COUNT, convertedValue ) )
+      {
+        mRenderingBehavior = convertedValue;
+        SetRenderingBehaviorMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
+      }
+      break;
+    }
   }
 }
 
-void Renderer::SetSceneGraphProperty( Property::Index index,
-                                      const PropertyMetadata& entry,
-                                      const Property::Value& value )
-{
-  ObjectImplHelper::SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
-  OnPropertySet(index, value);
-}
-
 Property::Value Renderer::GetDefaultProperty( Property::Index index ) const
 {
   Property::Value value;
@@ -670,32 +742,18 @@ void Renderer::OnNotifyDefaultPropertyAnimation( Animation& animation, Property:
   }
 }
 
-const SceneGraph::PropertyOwner* Renderer::GetPropertyOwner() const
-{
-  return mSceneObject;
-}
-
-const SceneGraph::PropertyOwner* Renderer::GetSceneObject() const
-{
-  return mSceneObject;
-}
-
 const SceneGraph::PropertyBase* Renderer::GetSceneObjectAnimatableProperty( Property::Index index ) const
 {
-  DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
-  const SceneGraph::PropertyBase* property = NULL;
-
-  property = ObjectImplHelper::GetRegisteredSceneGraphProperty( this,
-                                                                &Renderer::FindAnimatableProperty,
-                                                                &Renderer::FindCustomProperty,
-                                                                index );
+  const SceneGraph::PropertyBase* property = nullptr;
 
+  if( index == DevelRenderer::Property::OPACITY )
+  {
+    property = &GetRendererSceneObject().mOpacity;
+  }
   if( !property )
   {
-    if( index == DevelRenderer::Property::OPACITY )
-    {
-      property = &mSceneObject->mOpacity;
-    }
+    // not our property, ask base
+    property = Object::GetSceneObjectAnimatableProperty( index );
   }
 
   return property;
@@ -703,24 +761,12 @@ const SceneGraph::PropertyBase* Renderer::GetSceneObjectAnimatableProperty( Prop
 
 const PropertyInputImpl* Renderer::GetSceneObjectInputProperty( Property::Index index ) const
 {
-  const PropertyInputImpl* property = NULL;
-
-  const SceneGraph::PropertyBase* baseProperty = ObjectImplHelper::GetRegisteredSceneGraphProperty( this,
-                                                                                                    &Renderer::FindAnimatableProperty,
-                                                                                                    &Renderer::FindCustomProperty,
-                                                                                                    index );
-  property = static_cast<const PropertyInputImpl*>( baseProperty );
-
-  return property;
+  // reuse animatable property getter, Object::GetSceneObjectInputProperty does the same so no need to call that0
+  return GetSceneObjectAnimatableProperty( index );
 }
 
-int Renderer::GetPropertyComponentIndex( Property::Index index ) const
-{
-  return Property::INVALID_COMPONENT_INDEX;
-}
-
-Renderer::Renderer()
-: mSceneObject(NULL ),
+Renderer::Renderer( const SceneGraph::Renderer* sceneObject )
+: Object( sceneObject ),
   mDepthIndex( 0 ),
   mIndexedDrawFirstElement( 0 ),
   mIndexedDrawElementCount( 0 ),
@@ -732,26 +778,15 @@ Renderer::Renderer()
   mBlendMode( BlendMode::AUTO ),
   mDepthWriteMode( DepthWriteMode::AUTO ),
   mDepthTestMode( DepthTestMode::AUTO ),
+  mRenderingBehavior( DevelRenderer::Rendering::IF_REQUIRED ),
   mPremultipledAlphaEnabled( false )
 {
 }
 
-void Renderer::Initialize()
-{
-  EventThreadServices& eventThreadServices = GetEventThreadServices();
-  SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
-
-  mSceneObject = SceneGraph::Renderer::New();
-  OwnerPointer< SceneGraph::Renderer > transferOwnership( mSceneObject );
-  AddRendererMessage( updateManager, transferOwnership );
-
-  eventThreadServices.RegisterObject( this );
-}
-
 void Renderer::SetBlendColor( const Vector4& blendColor )
 {
   mBlendingOptions.SetBlendColor( blendColor );
-  SetBlendColorMessage( GetEventThreadServices(), *mSceneObject, GetBlendColor() );
+  SetBlendColorMessage( GetEventThreadServices(), GetRendererSceneObject(), GetBlendColor() );
 }
 
 const Vector4& Renderer::GetBlendColor() const
@@ -770,7 +805,7 @@ Renderer::~Renderer()
   {
     EventThreadServices& eventThreadServices = GetEventThreadServices();
     SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
-    RemoveRendererMessage( updateManager, *mSceneObject );
+    RemoveRendererMessage( updateManager, GetRendererSceneObject() );
 
     eventThreadServices.UnregisterObject( this );
   }
@@ -797,6 +832,11 @@ bool Renderer::GetCachedPropertyValue( Property::Index index, Property::Value& v
       value = mBlendMode;
       break;
     }
+    case Dali::DevelRenderer::Property::BLEND_EQUATION:
+    {
+      value = static_cast<int32_t>( mBlendingOptions.GetBlendEquationRgb() );
+      break;
+    }
     case Dali::Renderer::Property::BLEND_EQUATION_RGB:
     {
       value = static_cast<int32_t>( mBlendingOptions.GetBlendEquationRgb() );
@@ -927,6 +967,11 @@ bool Renderer::GetCachedPropertyValue( Property::Index index, Property::Value& v
       value = mOpacity;
       break;
     }
+    case Dali::DevelRenderer::Property::RENDERING_BEHAVIOR:
+    {
+      value = mRenderingBehavior;
+      break;
+    }
     default:
     {
       // Must be a scene-graph only property
@@ -941,27 +986,36 @@ bool Renderer::GetCachedPropertyValue( Property::Index index, Property::Value& v
 bool Renderer::GetCurrentPropertyValue( Property::Index index, Property::Value& value  ) const
 {
   bool valueSet = true;
+  const SceneGraph::Renderer& sceneObject = GetRendererSceneObject();
 
   switch( index )
   {
     case Dali::Renderer::Property::DEPTH_INDEX:
     {
-      value = mSceneObject->GetDepthIndex();
+      value = sceneObject.GetDepthIndex();
       break;
     }
     case Dali::Renderer::Property::FACE_CULLING_MODE:
     {
-      value = mSceneObject->GetFaceCullingMode();
+      value = sceneObject.GetFaceCullingMode();
       break;
     }
     case Dali::Renderer::Property::BLEND_MODE:
     {
-      value = mSceneObject->GetBlendMode();
+      value = sceneObject.GetBlendMode();
+      break;
+    }
+    case Dali::DevelRenderer::Property::BLEND_EQUATION:
+    {
+      uint32_t bitMask = sceneObject.GetBlendingOptions();
+      BlendingOptions blendingOptions;
+      blendingOptions.SetBitmask( bitMask );
+      value = static_cast<int32_t>( blendingOptions.GetBlendEquationRgb() );
       break;
     }
     case Dali::Renderer::Property::BLEND_EQUATION_RGB:
     {
-      uint32_t bitMask = mSceneObject->GetBlendingOptions();
+      uint32_t bitMask = sceneObject.GetBlendingOptions();
       BlendingOptions blendingOptions;
       blendingOptions.SetBitmask( bitMask );
       value = static_cast<int32_t>( blendingOptions.GetBlendEquationRgb() );
@@ -969,7 +1023,7 @@ bool Renderer::GetCurrentPropertyValue( Property::Index index, Property::Value&
     }
     case Dali::Renderer::Property::BLEND_EQUATION_ALPHA:
     {
-      uint32_t bitMask = mSceneObject->GetBlendingOptions();
+      uint32_t bitMask = sceneObject.GetBlendingOptions();
       BlendingOptions blendingOptions;
       blendingOptions.SetBitmask( bitMask );
       value = static_cast<int32_t>( blendingOptions.GetBlendEquationAlpha() );
@@ -977,7 +1031,7 @@ bool Renderer::GetCurrentPropertyValue( Property::Index index, Property::Value&
     }
     case Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB:
     {
-      uint32_t bitMask = mSceneObject->GetBlendingOptions();
+      uint32_t bitMask = sceneObject.GetBlendingOptions();
       BlendingOptions blendingOptions;
       blendingOptions.SetBitmask( bitMask );
       value = static_cast<int32_t>( blendingOptions.GetBlendSrcFactorRgb() );
@@ -985,7 +1039,7 @@ bool Renderer::GetCurrentPropertyValue( Property::Index index, Property::Value&
     }
     case Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB:
     {
-      uint32_t bitMask = mSceneObject->GetBlendingOptions();
+      uint32_t bitMask = sceneObject.GetBlendingOptions();
       BlendingOptions blendingOptions;
       blendingOptions.SetBitmask( bitMask );
       value = static_cast<int32_t>( blendingOptions.GetBlendDestFactorRgb() );
@@ -993,7 +1047,7 @@ bool Renderer::GetCurrentPropertyValue( Property::Index index, Property::Value&
     }
     case Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA:
     {
-      uint32_t bitMask = mSceneObject->GetBlendingOptions();
+      uint32_t bitMask = sceneObject.GetBlendingOptions();
       BlendingOptions blendingOptions;
       blendingOptions.SetBitmask( bitMask );
       value = static_cast<int32_t>( blendingOptions.GetBlendSrcFactorAlpha() );
@@ -1001,7 +1055,7 @@ bool Renderer::GetCurrentPropertyValue( Property::Index index, Property::Value&
     }
     case Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA:
     {
-      uint32_t bitMask = mSceneObject->GetBlendingOptions();
+      uint32_t bitMask = sceneObject.GetBlendingOptions();
       BlendingOptions blendingOptions;
       blendingOptions.SetBitmask( bitMask );
       value = static_cast<int32_t>( blendingOptions.GetBlendDestFactorAlpha() );
@@ -1009,90 +1063,95 @@ bool Renderer::GetCurrentPropertyValue( Property::Index index, Property::Value&
     }
     case Dali::Renderer::Property::BLEND_COLOR:
     {
-      value = mSceneObject->GetBlendColor();
+      value = sceneObject.GetBlendColor();
       break;
     }
     case Dali::Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA:
     {
-      value = mSceneObject->IsPreMultipliedAlphaEnabled();
+      value = sceneObject.IsPreMultipliedAlphaEnabled();
       break;
     }
     case Dali::Renderer::Property::INDEX_RANGE_FIRST:
     {
-      value = static_cast<int>( mSceneObject->GetIndexedDrawFirstElement() );
+      value = static_cast<int32_t>( sceneObject.GetIndexedDrawFirstElement() );
       break;
     }
     case Dali::Renderer::Property::INDEX_RANGE_COUNT:
     {
-      value = static_cast<int>( mSceneObject->GetIndexedDrawElementsCount() );
+      value = static_cast<int32_t>( sceneObject.GetIndexedDrawElementsCount() );
       break;
     }
     case Dali::Renderer::Property::DEPTH_WRITE_MODE:
     {
-      value = mSceneObject->GetDepthWriteMode();
+      value = sceneObject.GetDepthWriteMode();
       break;
     }
     case Dali::Renderer::Property::DEPTH_FUNCTION:
     {
-      value = mSceneObject->GetDepthFunction();
+      value = sceneObject.GetDepthFunction();
       break;
     }
     case Dali::Renderer::Property::DEPTH_TEST_MODE:
     {
-      value = mSceneObject->GetDepthTestMode();
+      value = sceneObject.GetDepthTestMode();
       break;
     }
     case Dali::Renderer::Property::STENCIL_FUNCTION:
     {
-      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
       value = stencilParameters.stencilFunction;
       break;
     }
     case Dali::Renderer::Property::STENCIL_FUNCTION_MASK:
     {
-      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
       value = stencilParameters.stencilFunctionMask;
       break;
     }
     case Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE:
     {
-      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
       value = stencilParameters.stencilFunctionReference;
       break;
     }
     case Dali::Renderer::Property::STENCIL_MASK:
     {
-      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
       value = stencilParameters.stencilMask;
       break;
     }
     case Dali::Renderer::Property::RENDER_MODE:
     {
-      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
       value = stencilParameters.renderMode;
       break;
     }
     case Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL:
     {
-      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
       value = stencilParameters.stencilOperationOnFail;
       break;
     }
     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL:
     {
-      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
       value = stencilParameters.stencilOperationOnZFail;
       break;
     }
     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS:
     {
-      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
       value = stencilParameters.stencilOperationOnZPass;
       break;
     }
     case Dali::DevelRenderer::Property::OPACITY:
     {
-      value = mSceneObject->GetOpacity( GetEventThreadServices().GetEventBufferIndex() );
+      value = sceneObject.GetOpacity( GetEventThreadServices().GetEventBufferIndex() );
+      break;
+    }
+    case Dali::DevelRenderer::Property::RENDERING_BEHAVIOR:
+    {
+      value = sceneObject.GetRenderingBehavior();
       break;
     }
     default:
@@ -1106,5 +1165,24 @@ bool Renderer::GetCurrentPropertyValue( Property::Index index, Property::Value&
   return valueSet;
 }
 
+void Renderer::AddDrawCommand( const Dali::DevelRenderer::DrawCommand& command )
+{
+  if(!mDrawCommands.capacity())
+  {
+    mDrawCommands.reserve(8);
+  }
+
+  mDrawCommands.emplace_back( command );
+
+  Dali::Internal::SceneGraph::SetDrawCommandsMessage( GetEventThreadServices(),
+                                                      GetRendererSceneObject(),
+                                                      mDrawCommands.data(),
+                                                      uint32_t(mDrawCommands.size())
+
+  );
+}
+
+
 } // namespace Internal
+
 } // namespace Dali