Set BlendFunc for the non-premultiplied format as well
[platform/core/uifw/dali-core.git] / dali / internal / event / rendering / renderer-impl.cpp
index a044737..3e77d16 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 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/event/rendering/renderer-impl.h> // Dali::Internal::Renderer
 
 // 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/devel-api/rendering/renderer.h> // Dali::Renderer
 #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-helper.h>    // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
 #include <dali/internal/event/common/property-input-impl.h>
-#include <dali/internal/update/rendering/scene-graph-renderer.h>
-#include <dali/internal/update/manager/update-manager.h>
 #include <dali/internal/render/renderers/render-geometry.h>
+#include <dali/internal/update/manager/update-manager.h>
+#include <dali/internal/update/rendering/scene-graph-renderer.h>
 
 namespace Dali
 {
@@ -37,26 +38,129 @@ namespace
 {
 
 /**
- *            |name                              |type     |writable|animatable|constraint-input|enum for index-checking|
+ * Properties: |name                              |type     |writable|animatable|constraint-input|enum for index-checking|
  */
 DALI_PROPERTY_TABLE_BEGIN
 DALI_PROPERTY( "depthIndex",                      INTEGER,   true, false,  false, Dali::Renderer::Property::DEPTH_INDEX )
 DALI_PROPERTY( "faceCullingMode",                 INTEGER,   true, false,  false, Dali::Renderer::Property::FACE_CULLING_MODE )
-DALI_PROPERTY( "blendingMode",                    INTEGER,   true, false,  false, Dali::Renderer::Property::BLENDING_MODE )
+DALI_PROPERTY( "blendMode",                       INTEGER,   true, false,  false, Dali::Renderer::Property::BLEND_MODE )
 DALI_PROPERTY( "blendEquationRgb",                INTEGER,   true, false,  false, Dali::Renderer::Property::BLEND_EQUATION_RGB )
 DALI_PROPERTY( "blendEquationAlpha",              INTEGER,   true, false,  false, Dali::Renderer::Property::BLEND_EQUATION_ALPHA )
-DALI_PROPERTY( "sourceBlendFactorRgb",            INTEGER,   true, false,  false, Dali::Renderer::Property::BLENDING_SRC_FACTOR_RGB )
-DALI_PROPERTY( "destinationBlendFactorRgb",       INTEGER,   true, false,  false, Dali::Renderer::Property::BLENDING_DEST_FACTOR_RGB )
-DALI_PROPERTY( "sourceBlendFactorAlpha",          INTEGER,   true, false,  false, Dali::Renderer::Property::BLENDING_SRC_FACTOR_ALPHA )
-DALI_PROPERTY( "destinationBlendFactorAlpha",     INTEGER,   true, false,  false, Dali::Renderer::Property::BLENDING_DEST_FACTOR_ALPHA )
-DALI_PROPERTY( "blendingColor",                   VECTOR4,   true, false,  false, Dali::Renderer::Property::BLENDING_COLOR )
+DALI_PROPERTY( "blendFactorSrcRgb",               INTEGER,   true, false,  false, Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB )
+DALI_PROPERTY( "blendFactorDestRgb",              INTEGER,   true, false,  false, Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB )
+DALI_PROPERTY( "blendFactorSrcAlpha",             INTEGER,   true, false,  false, Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA )
+DALI_PROPERTY( "blendFactorDestAlpha",            INTEGER,   true, false,  false, Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA )
+DALI_PROPERTY( "blendColor",                      VECTOR4,   true, false,  false, Dali::Renderer::Property::BLEND_COLOR )
 DALI_PROPERTY( "blendPreMultipliedAlpha",         BOOLEAN,   true, false,  false, Dali::Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA )
 DALI_PROPERTY( "indexRangeFirst",                 INTEGER,   true, false,  false, Dali::Renderer::Property::INDEX_RANGE_FIRST )
 DALI_PROPERTY( "indexRangeCount",                 INTEGER,   true, false,  false, Dali::Renderer::Property::INDEX_RANGE_COUNT )
 DALI_PROPERTY( "depthWriteMode",                  INTEGER,   true, false,  false, Dali::Renderer::Property::DEPTH_WRITE_MODE )
-DALI_PROPERTY_TABLE_END( DEFAULT_OBJECT_PROPERTY_START_INDEX )
-
-const ObjectImplHelper<DEFAULT_PROPERTY_COUNT> RENDERER_IMPL = { DEFAULT_PROPERTY_DETAILS };
+DALI_PROPERTY( "depthFunction",                   INTEGER,   true, false,  false, Dali::Renderer::Property::DEPTH_FUNCTION )
+DALI_PROPERTY( "depthTestMode",                   INTEGER,   true, false,  false, Dali::Renderer::Property::DEPTH_TEST_MODE )
+DALI_PROPERTY( "renderMode",                      INTEGER,   true, false,  false, Dali::Renderer::Property::RENDER_MODE )
+DALI_PROPERTY( "stencilFunction",                 INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_FUNCTION )
+DALI_PROPERTY( "stencilFunctionMask",             INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_FUNCTION_MASK )
+DALI_PROPERTY( "stencilFunctionReference",        INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE )
+DALI_PROPERTY( "stencilMask",                     INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_MASK )
+DALI_PROPERTY( "stencilOperationOnFail",          INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL )
+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_TABLE_END( DEFAULT_RENDERER_PROPERTY_START_INDEX )
+
+// Property string to enumeration tables:
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( FACE_CULLING_MODE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( FaceCullingMode, NONE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( FaceCullingMode, FRONT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( FaceCullingMode, BACK )
+DALI_ENUM_TO_STRING_WITH_SCOPE( FaceCullingMode, FRONT_AND_BACK )
+DALI_ENUM_TO_STRING_TABLE_END( FACE_CULLING_MODE )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( BLEND_MODE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendMode, OFF )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendMode, AUTO )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendMode, ON )
+DALI_ENUM_TO_STRING_TABLE_END( BLEND_MODE )
+
+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_TABLE_END( BLEND_EQUATION )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( BLEND_FACTOR )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ZERO )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, SRC_COLOR )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_SRC_COLOR )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, SRC_ALPHA )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_SRC_ALPHA )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, DST_ALPHA )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_DST_ALPHA )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, DST_COLOR )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_DST_COLOR )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, SRC_ALPHA_SATURATE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, CONSTANT_COLOR )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_CONSTANT_COLOR )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, CONSTANT_ALPHA )
+DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_CONSTANT_ALPHA )
+DALI_ENUM_TO_STRING_TABLE_END( BLEND_FACTOR )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( DEPTH_WRITE_MODE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DepthWriteMode, OFF )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DepthWriteMode, AUTO )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DepthWriteMode, ON )
+DALI_ENUM_TO_STRING_TABLE_END( DEPTH_WRITE_MODE )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( DEPTH_TEST_MODE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DepthTestMode, OFF )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DepthTestMode, AUTO )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DepthTestMode, ON )
+DALI_ENUM_TO_STRING_TABLE_END( DEPTH_TEST_MODE )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( DEPTH_FUNCTION )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, NEVER )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, ALWAYS )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, LESS )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, GREATER )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, EQUAL )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, NOT_EQUAL )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, LESS_EQUAL )
+DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, GREATER_EQUAL )
+DALI_ENUM_TO_STRING_TABLE_END( DEPTH_FUNCTION )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( STENCIL_FUNCTION )
+DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, NEVER )
+DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, LESS )
+DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, EQUAL )
+DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, LESS_EQUAL )
+DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, GREATER )
+DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, NOT_EQUAL )
+DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, GREATER_EQUAL )
+DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, ALWAYS )
+DALI_ENUM_TO_STRING_TABLE_END( STENCIL_FUNCTION )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( RENDER_MODE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( RenderMode, NONE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( RenderMode, AUTO )
+DALI_ENUM_TO_STRING_WITH_SCOPE( RenderMode, COLOR )
+DALI_ENUM_TO_STRING_WITH_SCOPE( RenderMode, STENCIL )
+DALI_ENUM_TO_STRING_WITH_SCOPE( RenderMode, COLOR_STENCIL )
+DALI_ENUM_TO_STRING_TABLE_END( RENDER_MODE )
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( STENCIL_OPERATION )
+DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, ZERO )
+DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, KEEP )
+DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, REPLACE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, INCREMENT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, DECREMENT )
+DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, INVERT )
+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 )
+
+const ObjectImplHelper<DEFAULT_PROPERTY_COUNT> RENDERER_IMPL = { DEFAULT_PROPERTY_DETAILS, DEFAULT_RENDERER_PROPERTY_START_INDEX };
 
 BaseHandle Create()
 {
@@ -89,14 +193,14 @@ Geometry* Renderer::GetGeometry() const
 
 void Renderer::SetTextures( TextureSet& textureSet )
 {
-  mTextureSetConnector.Set( textureSet, OnStage() );
+  mTextureSet = &textureSet;
   const SceneGraph::TextureSet* textureSetSceneObject = textureSet.GetTextureSetSceneObject();
   SetTexturesMessage( GetEventThreadServices(), *mSceneObject, *textureSetSceneObject );
 }
 
 TextureSet* Renderer::GetTextures() const
 {
-  return mTextureSetConnector.Get().Get();
+  return mTextureSet.Get();
 }
 
 void Renderer::SetShader( Shader& shader )
@@ -125,55 +229,40 @@ int Renderer::GetDepthIndex() const
   return mDepthIndex;
 }
 
-void Renderer::SetFaceCullingMode( Dali::Renderer::FaceCullingMode cullingMode )
-{
-  if( mFaceCullingMode != cullingMode )
-  {
-    mFaceCullingMode = cullingMode;
-
-    SetFaceCullingModeMessage( GetEventThreadServices(), *mSceneObject, mFaceCullingMode );
-  }
-}
-
-Dali::Renderer::FaceCullingMode Renderer::GetFaceCullingMode()
-{
-  return mFaceCullingMode;
-}
-
-void Renderer::SetBlendMode( BlendingMode::Type mode )
+void Renderer::SetBlendMode( BlendMode::Type mode )
 {
-  if( mBlendingMode != mode )
+  if( mBlendMode != mode )
   {
-    mBlendingMode = mode;
+    mBlendMode = mode;
 
-    SetBlendingModeMessage( GetEventThreadServices(), *mSceneObject, mBlendingMode );
+    SetBlendModeMessage( GetEventThreadServices(), *mSceneObject, mBlendMode );
   }
 }
 
-BlendingMode::Type Renderer::GetBlendMode() const
+BlendMode::Type Renderer::GetBlendMode() const
 {
-  return mBlendingMode;
+  return mBlendMode;
 }
 
-void Renderer::SetBlendFunc( BlendingFactor::Type srcFactorRgba, BlendingFactor::Type destFactorRgba )
+void Renderer::SetBlendFunc( BlendFactor::Type srcFactorRgba, BlendFactor::Type destFactorRgba )
 {
   mBlendingOptions.SetBlendFunc( srcFactorRgba, destFactorRgba, srcFactorRgba, destFactorRgba );
   SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
 }
 
-void Renderer::SetBlendFunc( BlendingFactor::Type srcFactorRgb,
-                             BlendingFactor::Type destFactorRgb,
-                             BlendingFactor::Type srcFactorAlpha,
-                             BlendingFactor::Type destFactorAlpha )
+void Renderer::SetBlendFunc( BlendFactor::Type srcFactorRgb,
+                             BlendFactor::Type destFactorRgb,
+                             BlendFactor::Type srcFactorAlpha,
+                             BlendFactor::Type destFactorAlpha )
 {
   mBlendingOptions.SetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
   SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
 }
 
-void Renderer::GetBlendFunc( BlendingFactor::Type& srcFactorRgb,
-                             BlendingFactor::Type& destFactorRgb,
-                             BlendingFactor::Type& srcFactorAlpha,
-                             BlendingFactor::Type& destFactorAlpha ) const
+void Renderer::GetBlendFunc( BlendFactor::Type& srcFactorRgb,
+                             BlendFactor::Type& destFactorRgb,
+                             BlendFactor::Type& srcFactorAlpha,
+                             BlendFactor::Type& destFactorAlpha ) const
 {
   srcFactorRgb    = mBlendingOptions.GetBlendSrcFactorRgb();
   destFactorRgb   = mBlendingOptions.GetBlendDestFactorRgb();
@@ -181,49 +270,27 @@ void Renderer::GetBlendFunc( BlendingFactor::Type& srcFactorRgb,
   destFactorAlpha = mBlendingOptions.GetBlendDestFactorAlpha();
 }
 
-void Renderer::SetBlendEquation( BlendingEquation::Type equationRgba )
+void Renderer::SetBlendEquation( BlendEquation::Type equationRgba )
 {
   mBlendingOptions.SetBlendEquation( equationRgba, equationRgba );
   SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
 }
 
-void Renderer::SetBlendEquation( BlendingEquation::Type equationRgb,
-                                 BlendingEquation::Type equationAlpha )
+void Renderer::SetBlendEquation( BlendEquation::Type equationRgb,
+                                 BlendEquation::Type equationAlpha )
 {
   mBlendingOptions.SetBlendEquation( equationRgb, equationAlpha );
   SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
 }
 
-void Renderer::GetBlendEquation( BlendingEquation::Type& equationRgb,
-                                 BlendingEquation::Type& equationAlpha ) const
+void Renderer::GetBlendEquation( BlendEquation::Type& equationRgb,
+                                 BlendEquation::Type& equationAlpha ) const
 {
   // These are not animatable, the cached values are up-to-date.
   equationRgb   = mBlendingOptions.GetBlendEquationRgb();
   equationAlpha = mBlendingOptions.GetBlendEquationAlpha();
 }
 
-void Renderer::SetBlendColor( const Vector4& color )
-{
-  if( !mBlendColor )
-  {
-    mBlendColor = new Vector4();
-  }
-  if( *mBlendColor != color )
-  {
-    *mBlendColor = color;
-    SetBlendColorMessage( GetEventThreadServices(), *mSceneObject, *mBlendColor );
-  }
-}
-
-Vector4 Renderer::GetBlendColor() const
-{
-  if( mBlendColor )
-  {
-    return *mBlendColor;
-  }
-  return Color::TRANSPARENT; // GL default
-}
-
 void Renderer::SetIndexedDrawFirstElement( size_t firstElement )
 {
   if( firstElement != mIndexedDrawFirstElement )
@@ -249,7 +316,11 @@ void Renderer::EnablePreMultipliedAlpha( bool preMultipled )
   {
     if( preMultipled )
     {
-      SetBlendFunc( BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA, BlendingFactor::ONE, BlendingFactor::ONE );
+      SetBlendFunc( BlendFactor::ONE, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::ONE, BlendFactor::ONE_MINUS_SRC_ALPHA );
+    }
+    else
+    {
+      SetBlendFunc( BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::ONE, BlendFactor::ONE_MINUS_SRC_ALPHA );
     }
     mPremultipledAlphaEnabled = preMultipled;
     SetEnablePreMultipliedAlphaMessage( GetEventThreadServices(), *mSceneObject, mPremultipledAlphaEnabled );
@@ -318,113 +389,92 @@ void Renderer::SetDefaultProperty( Property::Index index,
     }
     case Dali::Renderer::Property::FACE_CULLING_MODE:
     {
-      int faceCullingMode;
-      if( propertyValue.Get( faceCullingMode ) )
+      FaceCullingMode::Type convertedValue = mFaceCullingMode;
+      if( Scripting::GetEnumerationProperty< FaceCullingMode::Type >( propertyValue, FACE_CULLING_MODE_TABLE, FACE_CULLING_MODE_TABLE_COUNT, convertedValue ) )
       {
-        SetFaceCullingMode( Dali::Renderer::FaceCullingMode( faceCullingMode ) );
+        mFaceCullingMode = convertedValue;
+        SetFaceCullingModeMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
       }
       break;
     }
-    case Dali::Renderer::Property::BLENDING_MODE:
+    case Dali::Renderer::Property::BLEND_MODE:
     {
-      int blendingMode;
-      if( propertyValue.Get( blendingMode ) )
+      BlendMode::Type convertedValue = mBlendMode;
+      if( Scripting::GetEnumerationProperty< BlendMode::Type >( propertyValue, BLEND_MODE_TABLE, BLEND_MODE_TABLE_COUNT, convertedValue ) )
       {
-        SetBlendMode( BlendingMode::Type( blendingMode ) );
+        SetBlendMode( convertedValue );
       }
       break;
     }
     case Dali::Renderer::Property::BLEND_EQUATION_RGB:
     {
-      int blendingEquation;
-      if( propertyValue.Get( blendingEquation ) )
+      BlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationRgb();
+
+      if( Scripting::GetEnumerationProperty< BlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
       {
-        BlendingEquation::Type alphaEquation = mBlendingOptions.GetBlendEquationAlpha();
-        mBlendingOptions.SetBlendEquation( static_cast<BlendingEquation::Type>( blendingEquation ), alphaEquation );
+        BlendEquation::Type alphaEquation = mBlendingOptions.GetBlendEquationAlpha();
+        mBlendingOptions.SetBlendEquation( convertedValue, alphaEquation );
         SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
       }
       break;
     }
     case Dali::Renderer::Property::BLEND_EQUATION_ALPHA:
     {
-      int blendingEquation;
-      if( propertyValue.Get( blendingEquation ) )
+      BlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationAlpha();
+
+      if( Scripting::GetEnumerationProperty< BlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
       {
-        BlendingEquation::Type rgbEquation = mBlendingOptions.GetBlendEquationRgb();
-        mBlendingOptions.SetBlendEquation( rgbEquation, static_cast<BlendingEquation::Type>( blendingEquation ) );
+        BlendEquation::Type rgbEquation = mBlendingOptions.GetBlendEquationRgb();
+        mBlendingOptions.SetBlendEquation( rgbEquation, convertedValue );
         SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
       }
       break;
     }
-    case Dali::Renderer::Property::BLENDING_SRC_FACTOR_RGB:
+    case Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB:
     {
-      int blendingFactor;
-      if( propertyValue.Get( blendingFactor ) )
+      BlendFactor::Type sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha;
+      GetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
+
+      if( Scripting::GetEnumerationProperty< BlendFactor::Type >( propertyValue, BLEND_FACTOR_TABLE, BLEND_FACTOR_TABLE_COUNT, sourceFactorRgb ) )
       {
-        BlendingFactor::Type srcFactorRgb;
-        BlendingFactor::Type destFactorRgb;
-        BlendingFactor::Type srcFactorAlpha;
-        BlendingFactor::Type destFactorAlpha;
-        GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
-        SetBlendFunc( static_cast<BlendingFactor::Type>( blendingFactor ),
-            destFactorRgb,
-            srcFactorAlpha,
-            destFactorAlpha );
+        SetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
       }
       break;
     }
-    case Dali::Renderer::Property::BLENDING_DEST_FACTOR_RGB:
+    case Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB:
     {
-      int blendingFactor;
-      if( propertyValue.Get( blendingFactor ) )
+      BlendFactor::Type sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha;
+      GetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
+
+      if( Scripting::GetEnumerationProperty< BlendFactor::Type >( propertyValue, BLEND_FACTOR_TABLE, BLEND_FACTOR_TABLE_COUNT, destinationFactorRgb ) )
       {
-        BlendingFactor::Type srcFactorRgb;
-        BlendingFactor::Type destFactorRgb;
-        BlendingFactor::Type srcFactorAlpha;
-        BlendingFactor::Type destFactorAlpha;
-        GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
-        SetBlendFunc( srcFactorRgb,
-            static_cast<BlendingFactor::Type>( blendingFactor ),
-            srcFactorAlpha,
-            destFactorAlpha );
+        SetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
       }
       break;
     }
-    case Dali::Renderer::Property::BLENDING_SRC_FACTOR_ALPHA:
+    case Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA:
     {
-      int blendingFactor;
-      if( propertyValue.Get( blendingFactor ) )
+      BlendFactor::Type sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha;
+      GetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
+
+      if( Scripting::GetEnumerationProperty< BlendFactor::Type >( propertyValue, BLEND_FACTOR_TABLE, BLEND_FACTOR_TABLE_COUNT, sourceFactorAlpha ) )
       {
-        BlendingFactor::Type srcFactorRgb;
-        BlendingFactor::Type destFactorRgb;
-        BlendingFactor::Type srcFactorAlpha;
-        BlendingFactor::Type destFactorAlpha;
-        GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
-        SetBlendFunc( srcFactorRgb,
-            destFactorRgb,
-            static_cast<BlendingFactor::Type>( blendingFactor ),
-            destFactorAlpha );
+        SetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
       }
       break;
     }
-    case Dali::Renderer::Property::BLENDING_DEST_FACTOR_ALPHA:
+    case Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA:
     {
-      int blendingFactor;
-      if( propertyValue.Get( blendingFactor ) )
+      BlendFactor::Type sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha;
+      GetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
+
+      if( Scripting::GetEnumerationProperty< BlendFactor::Type >( propertyValue, BLEND_FACTOR_TABLE, BLEND_FACTOR_TABLE_COUNT, destinationFactorAlpha ) )
       {
-        BlendingFactor::Type srcFactorRgb;
-        BlendingFactor::Type destFactorRgb;
-        BlendingFactor::Type srcFactorAlpha;
-        BlendingFactor::Type destFactorAlpha;
-        GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
-        SetBlendFunc( srcFactorRgb,
-            destFactorRgb,
-            srcFactorAlpha,
-            static_cast<BlendingFactor::Type>( blendingFactor ) );
+        SetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
       }
       break;
     }
-    case Dali::Renderer::Property::BLENDING_COLOR:
+    case Dali::Renderer::Property::BLEND_COLOR:
     {
       Vector4 blendColor;
       if( propertyValue.Get( blendColor ) )
@@ -462,132 +512,204 @@ void Renderer::SetDefaultProperty( Property::Index index,
     }
     case Dali::Renderer::Property::DEPTH_WRITE_MODE:
     {
-      int value;
-      propertyValue.Get( value );
-      Dali::Renderer::DepthWriteMode mode = static_cast<Dali::Renderer::DepthWriteMode>(value);
-      if( mode != mDepthWriteMode )
+      DepthWriteMode::Type convertedValue = mDepthWriteMode;
+      if( Scripting::GetEnumerationProperty< DepthWriteMode::Type >( propertyValue, DEPTH_WRITE_MODE_TABLE, DEPTH_WRITE_MODE_TABLE_COUNT, convertedValue ) )
       {
-        mDepthWriteMode = mode;
-        SetDepthWriteModeMessage( GetEventThreadServices(), *mSceneObject, mode );
+        mDepthWriteMode = convertedValue;
+        SetDepthWriteModeMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
       }
-
       break;
     }
-  }
-}
-
-void Renderer::SetSceneGraphProperty( Property::Index index,
-                                      const PropertyMetadata& entry,
-                                      const Property::Value& value )
-{
-  RENDERER_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
-  OnPropertySet(index, value);
-}
-
-Property::Value Renderer::GetDefaultProperty( Property::Index index ) const
-{
-  Property::Value value;
-  switch( index )
-  {
-    case Dali::Renderer::Property::DEPTH_INDEX:
+    case Dali::Renderer::Property::DEPTH_FUNCTION:
     {
-      value = GetDepthIndex();
+      DepthFunction::Type convertedValue = mDepthFunction;
+      if( Scripting::GetEnumerationProperty< DepthFunction::Type >( propertyValue, DEPTH_FUNCTION_TABLE, DEPTH_FUNCTION_TABLE_COUNT, convertedValue ) )
+      {
+        mDepthFunction = convertedValue;
+        SetDepthFunctionMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
+      }
       break;
     }
-    case Dali::Renderer::Property::FACE_CULLING_MODE:
+    case Dali::Renderer::Property::DEPTH_TEST_MODE:
     {
-      value = mFaceCullingMode;
+      DepthTestMode::Type convertedValue = mDepthTestMode;
+      if( Scripting::GetEnumerationProperty< DepthTestMode::Type >( propertyValue, DEPTH_TEST_MODE_TABLE, DEPTH_TEST_MODE_TABLE_COUNT, convertedValue ) )
+      {
+        mDepthTestMode = convertedValue;
+        SetDepthTestModeMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
+      }
       break;
     }
-    case Dali::Renderer::Property::BLENDING_MODE:
+    case Dali::Renderer::Property::RENDER_MODE:
     {
-      value = mBlendingMode;
+      RenderMode::Type convertedValue = mStencilParameters.renderMode;
+      if( Scripting::GetEnumerationProperty< RenderMode::Type >( propertyValue, RENDER_MODE_TABLE, RENDER_MODE_TABLE_COUNT, convertedValue ) )
+      {
+        mStencilParameters.renderMode = convertedValue;
+        SetRenderModeMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
+      }
       break;
     }
-    case Dali::Renderer::Property::BLEND_EQUATION_RGB:
+    case Dali::Renderer::Property::STENCIL_FUNCTION:
     {
-      value = static_cast<int>( mBlendingOptions.GetBlendEquationRgb() );
+      StencilFunction::Type convertedValue = mStencilParameters.stencilFunction;
+      if( Scripting::GetEnumerationProperty< StencilFunction::Type >( propertyValue, STENCIL_FUNCTION_TABLE, STENCIL_FUNCTION_TABLE_COUNT, convertedValue ) )
+      {
+        mStencilParameters.stencilFunction = convertedValue;
+        SetStencilFunctionMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
+      }
       break;
     }
-    case Dali::Renderer::Property::BLEND_EQUATION_ALPHA:
+    case Dali::Renderer::Property::STENCIL_FUNCTION_MASK:
     {
-      value = static_cast<int>( mBlendingOptions.GetBlendEquationAlpha() );
+      int stencilFunctionMask;
+      if( propertyValue.Get( stencilFunctionMask ) )
+      {
+        if( stencilFunctionMask != mStencilParameters.stencilFunctionMask )
+        {
+          mStencilParameters.stencilFunctionMask = stencilFunctionMask;
+          SetStencilFunctionMaskMessage( GetEventThreadServices(), *mSceneObject, stencilFunctionMask );
+        }
+      }
       break;
     }
-    case Dali::Renderer::Property::BLENDING_SRC_FACTOR_RGB:
+    case Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE:
     {
-      BlendingFactor::Type srcFactorRgb;
-      BlendingFactor::Type destFactorRgb;
-      BlendingFactor::Type srcFactorAlpha;
-      BlendingFactor::Type destFactorAlpha;
-      GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
-      value = static_cast<int>( srcFactorRgb );
+      int stencilFunctionReference;
+      if( propertyValue.Get( stencilFunctionReference ) )
+      {
+        if( stencilFunctionReference != mStencilParameters.stencilFunctionReference )
+        {
+          mStencilParameters.stencilFunctionReference = stencilFunctionReference;
+          SetStencilFunctionReferenceMessage( GetEventThreadServices(), *mSceneObject, stencilFunctionReference );
+        }
+      }
       break;
     }
-    case Dali::Renderer::Property::BLENDING_DEST_FACTOR_RGB:
+    case Dali::Renderer::Property::STENCIL_MASK:
     {
-      BlendingFactor::Type srcFactorRgb;
-      BlendingFactor::Type destFactorRgb;
-      BlendingFactor::Type srcFactorAlpha;
-      BlendingFactor::Type destFactorAlpha;
-      GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
-      value = static_cast<int>( destFactorRgb );
+      int stencilMask;
+      if( propertyValue.Get( stencilMask ) )
+      {
+        if( stencilMask != mStencilParameters.stencilMask )
+        {
+          mStencilParameters.stencilMask = stencilMask;
+          SetStencilMaskMessage( GetEventThreadServices(), *mSceneObject, stencilMask );
+        }
+      }
       break;
     }
-    case Dali::Renderer::Property::BLENDING_SRC_FACTOR_ALPHA:
+    case Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL:
     {
-      BlendingFactor::Type srcFactorRgb;
-      BlendingFactor::Type destFactorRgb;
-      BlendingFactor::Type srcFactorAlpha;
-      BlendingFactor::Type destFactorAlpha;
-      GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
-      value = static_cast<int>( srcFactorAlpha );
+      StencilOperation::Type convertedValue = mStencilParameters.stencilOperationOnFail;
+      if( Scripting::GetEnumerationProperty< StencilOperation::Type >( propertyValue, STENCIL_OPERATION_TABLE, STENCIL_OPERATION_TABLE_COUNT, convertedValue ) )
+      {
+        mStencilParameters.stencilOperationOnFail = convertedValue;
+        SetStencilOperationOnFailMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
+      }
       break;
     }
-    case Dali::Renderer::Property::BLENDING_DEST_FACTOR_ALPHA:
+    case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL:
     {
-      BlendingFactor::Type srcFactorRgb;
-      BlendingFactor::Type destFactorRgb;
-      BlendingFactor::Type srcFactorAlpha;
-      BlendingFactor::Type destFactorAlpha;
-      GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
-      value = static_cast<int>( destFactorAlpha );
+      StencilOperation::Type convertedValue = mStencilParameters.stencilOperationOnZFail;
+      if( Scripting::GetEnumerationProperty< StencilOperation::Type >( propertyValue, STENCIL_OPERATION_TABLE, STENCIL_OPERATION_TABLE_COUNT, convertedValue ) )
+      {
+        mStencilParameters.stencilOperationOnZFail = convertedValue;
+        SetStencilOperationOnZFailMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
+      }
       break;
     }
-    case Dali::Renderer::Property::BLENDING_COLOR:
+    case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS:
     {
-      if( mBlendColor )
-      {
-        value = *mBlendColor;
-      }
-      else
+      StencilOperation::Type convertedValue = mStencilParameters.stencilOperationOnZPass;
+      if( Scripting::GetEnumerationProperty< StencilOperation::Type >( propertyValue, STENCIL_OPERATION_TABLE, STENCIL_OPERATION_TABLE_COUNT, convertedValue ) )
       {
-        value = Color::TRANSPARENT;
+        mStencilParameters.stencilOperationOnZPass = convertedValue;
+        SetStencilOperationOnZPassMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
       }
       break;
     }
-    case Dali::Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA:
+    case Dali::DevelRenderer::Property::OPACITY:
     {
-      value = IsPreMultipliedAlphaEnabled();
-      break;
-    }
-    case Dali::Renderer::Property::INDEX_RANGE_FIRST:
-    {
-      value = static_cast<int>( mIndexedDrawFirstElement );
+      float opacity;
+      if( propertyValue.Get( opacity ) )
+      {
+        if( !Equals( mOpacity, opacity ) )
+        {
+          mOpacity = opacity;
+          BakeOpacityMessage( GetEventThreadServices(), *mSceneObject, mOpacity );
+        }
+      }
       break;
     }
-    case Dali::Renderer::Property::INDEX_RANGE_COUNT:
+  }
+}
+
+void Renderer::SetSceneGraphProperty( Property::Index index,
+                                      const PropertyMetadata& entry,
+                                      const Property::Value& value )
+{
+  RENDERER_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
+  OnPropertySet(index, value);
+}
+
+Property::Value Renderer::GetDefaultProperty( Property::Index index ) const
+{
+  Property::Value value;
+
+  if( ! GetCachedPropertyValue( index, value ) )
+  {
+    // If property value is not stored in the event-side, then it must be a scene-graph only property
+    GetCurrentPropertyValue( index, value );
+  }
+
+  return value;
+}
+
+Property::Value Renderer::GetDefaultPropertyCurrentValue( Property::Index index ) const
+{
+  Property::Value value;
+
+  if( ! GetCurrentPropertyValue( index, value ) )
+  {
+    // If unable to retrieve scene-graph property value, then it must be an event-side only property
+    GetCachedPropertyValue( index, value );
+  }
+
+  return value;
+}
+
+void Renderer::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
+{
+  switch( animationType )
+  {
+    case Animation::TO:
+    case Animation::BETWEEN:
     {
-      value = static_cast<int>( mIndexedDrawElementCount );
+      switch( index )
+      {
+        case Dali::DevelRenderer::Property::OPACITY:
+        {
+          value.Get( mOpacity );
+          break;
+        }
+      }
       break;
     }
-    case Dali::Renderer::Property::DEPTH_WRITE_MODE:
+
+    case Animation::BY:
     {
-      value = mDepthWriteMode;
+      switch( index )
+      {
+        case Dali::DevelRenderer::Property::OPACITY:
+        {
+          AdjustValue< float >( mOpacity, value );
+          break;
+        }
+      }
       break;
     }
   }
-  return value;
 }
 
 const SceneGraph::PropertyOwner* Renderer::GetPropertyOwner() const
@@ -605,13 +727,18 @@ const SceneGraph::PropertyBase* Renderer::GetSceneObjectAnimatableProperty( Prop
   DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
   const SceneGraph::PropertyBase* property = NULL;
 
-  if( OnStage() )
+  property = RENDERER_IMPL.GetRegisteredSceneGraphProperty(
+    this,
+    &Renderer::FindAnimatableProperty,
+    &Renderer::FindCustomProperty,
+    index );
+
+  if( !property )
   {
-    property = RENDERER_IMPL.GetRegisteredSceneGraphProperty(
-      this,
-      &Renderer::FindAnimatableProperty,
-      &Renderer::FindCustomProperty,
-      index );
+    if( index == DevelRenderer::Property::OPACITY )
+    {
+      property = &mSceneObject->mOpacity;
+    }
   }
 
   return property;
@@ -621,15 +748,12 @@ const PropertyInputImpl* Renderer::GetSceneObjectInputProperty( Property::Index
 {
   const PropertyInputImpl* property = NULL;
 
-  if( OnStage() )
-  {
-    const SceneGraph::PropertyBase* baseProperty =
-      RENDERER_IMPL.GetRegisteredSceneGraphProperty( this,
-                                                     &Renderer::FindAnimatableProperty,
-                                                     &Renderer::FindCustomProperty,
-                                                     index );
-    property = static_cast<const PropertyInputImpl*>( baseProperty );
-  }
+  const SceneGraph::PropertyBase* baseProperty =
+    RENDERER_IMPL.GetRegisteredSceneGraphProperty( this,
+                                                   &Renderer::FindAnimatableProperty,
+                                                   &Renderer::FindCustomProperty,
+                                                   index );
+  property = static_cast<const PropertyInputImpl*>( baseProperty );
 
   return property;
 }
@@ -639,42 +763,19 @@ int Renderer::GetPropertyComponentIndex( Property::Index index ) const
   return Property::INVALID_COMPONENT_INDEX;
 }
 
-bool Renderer::OnStage() const
-{
-  return mOnStageCount > 0;
-}
-
-void Renderer::Connect()
-{
-  if( mOnStageCount == 0 )
-  {
-    OnStageConnectMessage( GetEventThreadServices(), *mSceneObject );
-    mTextureSetConnector.OnStageConnect();
-  }
-  ++mOnStageCount;
-}
-
-void Renderer::Disconnect()
-{
-  --mOnStageCount;
-  if( mOnStageCount == 0 )
-  {
-    OnStageDisconnectMessage( GetEventThreadServices(), *mSceneObject);
-    mTextureSetConnector.OnStageDisconnect();
-  }
-}
-
 Renderer::Renderer()
-: mSceneObject (NULL ),
-  mBlendColor( NULL ),
+: mSceneObject(NULL ),
   mDepthIndex( 0 ),
-  mOnStageCount( 0 ),
   mIndexedDrawFirstElement( 0 ),
   mIndexedDrawElementCount( 0 ),
-  mFaceCullingMode( Dali::Renderer::CULL_NONE ),
-  mBlendingMode( Dali::BlendingMode::AUTO ),
+  mStencilParameters( RenderMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP ),
   mBlendingOptions(),
-  mDepthWriteMode( Dali::Renderer::DEPTH_WRITE_AUTO ),
+  mOpacity( 1.0f ),
+  mDepthFunction( DepthFunction::LESS ),
+  mFaceCullingMode( FaceCullingMode::NONE ),
+  mBlendMode( BlendMode::AUTO ),
+  mDepthWriteMode( DepthWriteMode::AUTO ),
+  mDepthTestMode( DepthTestMode::AUTO ),
   mPremultipledAlphaEnabled( false )
 {
 }
@@ -685,22 +786,369 @@ void Renderer::Initialize()
   SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
 
   mSceneObject = SceneGraph::Renderer::New();
-  AddMessage( updateManager, updateManager.GetRendererOwner(), *mSceneObject );
+  OwnerPointer< SceneGraph::Renderer > transferOwnership( mSceneObject );
+  AddRendererMessage( updateManager, transferOwnership );
 
   eventThreadServices.RegisterObject( this );
 }
 
+void Renderer::SetBlendColor( const Vector4& blendColor )
+{
+  mBlendingOptions.SetBlendColor( blendColor );
+  SetBlendColorMessage( GetEventThreadServices(), *mSceneObject, GetBlendColor() );
+}
+
+const Vector4& Renderer::GetBlendColor() const
+{
+  const Vector4* blendColor = mBlendingOptions.GetBlendColor();
+  if( blendColor )
+  {
+    return *blendColor;
+  }
+  return Color::TRANSPARENT; // GL default
+}
+
 Renderer::~Renderer()
 {
   if( EventThreadServices::IsCoreRunning() )
   {
     EventThreadServices& eventThreadServices = GetEventThreadServices();
     SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
-    RemoveMessage( updateManager, updateManager.GetRendererOwner(), *mSceneObject );
+    RemoveRendererMessage( updateManager, *mSceneObject );
 
     eventThreadServices.UnregisterObject( this );
   }
 }
 
+bool Renderer::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
+{
+  bool valueSet = true;
+
+  switch( index )
+  {
+    case Dali::Renderer::Property::DEPTH_INDEX:
+    {
+      value = GetDepthIndex();
+      break;
+    }
+    case Dali::Renderer::Property::FACE_CULLING_MODE:
+    {
+      value = mFaceCullingMode;
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_MODE:
+    {
+      value = mBlendMode;
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_EQUATION_RGB:
+    {
+      value = static_cast<int>( mBlendingOptions.GetBlendEquationRgb() );
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_EQUATION_ALPHA:
+    {
+      value = static_cast<int>( mBlendingOptions.GetBlendEquationAlpha() );
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB:
+    {
+      BlendFactor::Type srcFactorRgb;
+      BlendFactor::Type destFactorRgb;
+      BlendFactor::Type srcFactorAlpha;
+      BlendFactor::Type destFactorAlpha;
+      GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
+      value = static_cast<int>( srcFactorRgb );
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB:
+    {
+      BlendFactor::Type srcFactorRgb;
+      BlendFactor::Type destFactorRgb;
+      BlendFactor::Type srcFactorAlpha;
+      BlendFactor::Type destFactorAlpha;
+      GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
+      value = static_cast<int>( destFactorRgb );
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA:
+    {
+      BlendFactor::Type srcFactorRgb;
+      BlendFactor::Type destFactorRgb;
+      BlendFactor::Type srcFactorAlpha;
+      BlendFactor::Type destFactorAlpha;
+      GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
+      value = static_cast<int>( srcFactorAlpha );
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA:
+    {
+      BlendFactor::Type srcFactorRgb;
+      BlendFactor::Type destFactorRgb;
+      BlendFactor::Type srcFactorAlpha;
+      BlendFactor::Type destFactorAlpha;
+      GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
+      value = static_cast<int>( destFactorAlpha );
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_COLOR:
+    {
+      value = GetBlendColor();
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA:
+    {
+      value = IsPreMultipliedAlphaEnabled();
+      break;
+    }
+    case Dali::Renderer::Property::INDEX_RANGE_FIRST:
+    {
+      value = static_cast<int>( mIndexedDrawFirstElement );
+      break;
+    }
+    case Dali::Renderer::Property::INDEX_RANGE_COUNT:
+    {
+      value = static_cast<int>( mIndexedDrawElementCount );
+      break;
+    }
+    case Dali::Renderer::Property::DEPTH_WRITE_MODE:
+    {
+      value = mDepthWriteMode;
+      break;
+    }
+    case Dali::Renderer::Property::DEPTH_FUNCTION:
+    {
+      value = mDepthFunction;
+      break;
+    }
+    case Dali::Renderer::Property::DEPTH_TEST_MODE:
+    {
+      value = mDepthTestMode;
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_FUNCTION:
+    {
+      value = mStencilParameters.stencilFunction;
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_FUNCTION_MASK:
+    {
+      value = mStencilParameters.stencilFunctionMask;
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE:
+    {
+      value = mStencilParameters.stencilFunctionReference;
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_MASK:
+    {
+      value = mStencilParameters.stencilMask;
+      break;
+    }
+    case Dali::Renderer::Property::RENDER_MODE:
+    {
+      value = mStencilParameters.renderMode;
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL:
+    {
+      value = mStencilParameters.stencilOperationOnFail;
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL:
+    {
+      value = mStencilParameters.stencilOperationOnZFail;
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS:
+    {
+      value = mStencilParameters.stencilOperationOnZPass;
+      break;
+    }
+    case Dali::DevelRenderer::Property::OPACITY:
+    {
+      value = mOpacity;
+      break;
+    }
+    default:
+    {
+      // Must be a scene-graph only property
+      valueSet = false;
+      break;
+    }
+  }
+
+  return valueSet;
+}
+
+bool Renderer::GetCurrentPropertyValue( Property::Index index, Property::Value& value  ) const
+{
+  bool valueSet = true;
+
+  switch( index )
+  {
+    case Dali::Renderer::Property::DEPTH_INDEX:
+    {
+      value = mSceneObject->GetDepthIndex();
+      break;
+    }
+    case Dali::Renderer::Property::FACE_CULLING_MODE:
+    {
+      value = mSceneObject->GetFaceCullingMode();
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_MODE:
+    {
+      value = mSceneObject->GetBlendMode();
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_EQUATION_RGB:
+    {
+      unsigned int bitMask = mSceneObject->GetBlendingOptions();
+      BlendingOptions blendingOptions;
+      blendingOptions.SetBitmask( bitMask );
+      value = static_cast<int>( blendingOptions.GetBlendEquationRgb() );
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_EQUATION_ALPHA:
+    {
+      unsigned int bitMask = mSceneObject->GetBlendingOptions();
+      BlendingOptions blendingOptions;
+      blendingOptions.SetBitmask( bitMask );
+      value = static_cast<int>( blendingOptions.GetBlendEquationAlpha() );
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB:
+    {
+      unsigned int bitMask = mSceneObject->GetBlendingOptions();
+      BlendingOptions blendingOptions;
+      blendingOptions.SetBitmask( bitMask );
+      value = static_cast<int>( blendingOptions.GetBlendSrcFactorRgb() );
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB:
+    {
+      unsigned int bitMask = mSceneObject->GetBlendingOptions();
+      BlendingOptions blendingOptions;
+      blendingOptions.SetBitmask( bitMask );
+      value = static_cast<int>( blendingOptions.GetBlendDestFactorRgb() );
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA:
+    {
+      unsigned int bitMask = mSceneObject->GetBlendingOptions();
+      BlendingOptions blendingOptions;
+      blendingOptions.SetBitmask( bitMask );
+      value = static_cast<int>( blendingOptions.GetBlendSrcFactorAlpha() );
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA:
+    {
+      unsigned int bitMask = mSceneObject->GetBlendingOptions();
+      BlendingOptions blendingOptions;
+      blendingOptions.SetBitmask( bitMask );
+      value = static_cast<int>( blendingOptions.GetBlendDestFactorAlpha() );
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_COLOR:
+    {
+      value = mSceneObject->GetBlendColor();
+      break;
+    }
+    case Dali::Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA:
+    {
+      value = mSceneObject->IsPreMultipliedAlphaEnabled();
+      break;
+    }
+    case Dali::Renderer::Property::INDEX_RANGE_FIRST:
+    {
+      value = static_cast<int>( mSceneObject->GetIndexedDrawFirstElement() );
+      break;
+    }
+    case Dali::Renderer::Property::INDEX_RANGE_COUNT:
+    {
+      value = static_cast<int>( mSceneObject->GetIndexedDrawElementsCount() );
+      break;
+    }
+    case Dali::Renderer::Property::DEPTH_WRITE_MODE:
+    {
+      value = mSceneObject->GetDepthWriteMode();
+      break;
+    }
+    case Dali::Renderer::Property::DEPTH_FUNCTION:
+    {
+      value = mSceneObject->GetDepthFunction();
+      break;
+    }
+    case Dali::Renderer::Property::DEPTH_TEST_MODE:
+    {
+      value = mSceneObject->GetDepthTestMode();
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_FUNCTION:
+    {
+      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      value = stencilParameters.stencilFunction;
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_FUNCTION_MASK:
+    {
+      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      value = stencilParameters.stencilFunctionMask;
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE:
+    {
+      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      value = stencilParameters.stencilFunctionReference;
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_MASK:
+    {
+      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      value = stencilParameters.stencilMask;
+      break;
+    }
+    case Dali::Renderer::Property::RENDER_MODE:
+    {
+      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      value = stencilParameters.renderMode;
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL:
+    {
+      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      value = stencilParameters.stencilOperationOnFail;
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL:
+    {
+      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      value = stencilParameters.stencilOperationOnZFail;
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS:
+    {
+      Render::Renderer::StencilParameters stencilParameters = mSceneObject->GetStencilParameters();
+      value = stencilParameters.stencilOperationOnZPass;
+      break;
+    }
+    case Dali::DevelRenderer::Property::OPACITY:
+    {
+      value = mSceneObject->GetOpacity( GetEventThreadServices().GetEventBufferIndex() );
+      break;
+    }
+    default:
+    {
+      // Must be an event-side only property
+      valueSet = false;
+      break;
+    }
+  }
+
+  return valueSet;
+}
+
 } // namespace Internal
 } // namespace Dali