[3.0] Clipping API feature in Actor
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-Renderer.cpp
index ce5dd3f..6591dd9 100644 (file)
 #include <dali/public-api/dali-core.h>
 #include <dali/devel-api/images/texture-set-image.h>
 #include <cstdio>
+#include <string>
 
 // INTERNAL INCLUDES
 #include <dali-test-suite-utils.h>
+#include <test-trace-call-stack.h>
 #include <mesh-builder.h>
 
 using namespace Dali;
@@ -34,8 +36,38 @@ const BlendFactor::Type   DEFAULT_BLEND_FACTOR_DEST_RGB(   BlendFactor::ONE_MINU
 const BlendFactor::Type   DEFAULT_BLEND_FACTOR_SRC_ALPHA(  BlendFactor::ONE );
 const BlendFactor::Type   DEFAULT_BLEND_FACTOR_DEST_ALPHA( BlendFactor::ONE_MINUS_SRC_ALPHA );
 
-const BlendEquation::Type DEFAULT_BLEND_EQUATION_RGB(   BlendEquation::ADD );
-const BlendEquation::Type DEFAULT_BLEND_EQUATION_ALPHA( BlendEquation::ADD );
+const BlendEquation::Type DEFAULT_BLEND_EQUATION_RGB(      BlendEquation::ADD );
+const BlendEquation::Type DEFAULT_BLEND_EQUATION_ALPHA(    BlendEquation::ADD );
+
+/**
+ * @brief Get GL stencil test enumeration value as a string.
+ * @return The string representation of the value of GL_STENCIL_TEST
+ */
+std::string GetStencilTestString(void)
+{
+  std::stringstream stream;
+  stream << GL_STENCIL_TEST;
+  return stream.str();
+}
+
+/**
+ * @brief Get GL depth test enumeration value as a string.
+ * @return The string representation of the value of GL_DEPTH_TEST
+ */
+std::string GetDepthTestString(void)
+{
+  std::stringstream stream;
+  stream << GL_DEPTH_TEST;
+  return stream.str();
+}
+
+void ResetDebugAndFlush( TestApplication& application, TraceCallStack& glEnableDisableStack, TraceCallStack& glStencilFunctionStack )
+{
+  glEnableDisableStack.Reset();
+  glStencilFunctionStack.Reset();
+  application.SendNotification();
+  application.Render();
+}
 
 void TestConstraintNoBlue( Vector4& current, const PropertyInputContainer& inputs )
 {
@@ -716,7 +748,7 @@ int UtcDaliRendererSetBlendMode06(void)
   tet_infoline("Test setting the blend mode to auto with an opaque color and an image without an alpha channel and a shader with the hint OUTPUT_IS_TRANSPARENT renders with blending enabled");
 
   Geometry geometry = CreateQuadGeometry();
-  Shader shader = Shader::New( "vertexSrc", "fragmentSrc", Shader::HINT_OUTPUT_IS_TRANSPARENT );
+  Shader shader = Shader::New( "vertexSrc", "fragmentSrc", Shader::Hint::OUTPUT_IS_TRANSPARENT );
 
   Renderer renderer = Renderer::New( geometry, shader );
 
@@ -1026,8 +1058,6 @@ int UtcDaliRendererConstraint02(void)
   END_TEST;
 }
 
-
-
 int UtcDaliRendererAnimatedProperty01(void)
 {
   TestApplication application;
@@ -1370,7 +1400,6 @@ int UtcDaliRendererUniformMapMultipleUniforms02(void)
   END_TEST;
 }
 
-
 int UtcDaliRendererRenderOrder2DLayer(void)
 {
   TestApplication application;
@@ -1781,7 +1810,7 @@ int UtcDaliRendererSetIndexRange(void)
 
   // create geometry
   Geometry geometry = Geometry::New();
-  geometry.SetGeometryType( Geometry::LINE_LOOP );
+  geometry.SetType( Geometry::LINE_LOOP );
 
   // --------------------------------------------------------------------------
   // index buffer
@@ -1846,7 +1875,7 @@ int UtcDaliRendererSetIndexRange(void)
   // LINE_STRIP, first 15, count 6
   {
     renderer.SetIndexRange( 15, 6 );
-    geometry.SetGeometryType( Geometry::LINE_STRIP );
+    geometry.SetType( Geometry::LINE_STRIP );
     sprintf( buffer, "%u, 6, %u, indices", GL_LINE_STRIP, GL_UNSIGNED_SHORT );
     application.SendNotification();
     application.Render();
@@ -1857,7 +1886,7 @@ int UtcDaliRendererSetIndexRange(void)
   // Index out of bounds
   {
     renderer.SetIndexRange( 15, 30 );
-    geometry.SetGeometryType( Geometry::LINE_STRIP );
+    geometry.SetType( Geometry::LINE_STRIP );
     sprintf( buffer, "%u, 6, %u, indices", GL_LINE_STRIP, GL_UNSIGNED_SHORT );
     application.SendNotification();
     application.Render();
@@ -1868,7 +1897,7 @@ int UtcDaliRendererSetIndexRange(void)
   // drawing whole buffer starting from 15 ( last valid primitive )
   {
     renderer.SetIndexRange( 15, 0 );
-    geometry.SetGeometryType( Geometry::LINE_STRIP );
+    geometry.SetType( Geometry::LINE_STRIP );
     sprintf( buffer, "%u, 6, %u, indices", GL_LINE_STRIP, GL_UNSIGNED_SHORT );
     application.SendNotification();
     application.Render();
@@ -2015,3 +2044,520 @@ int UtcDaliRendererSetDepthFunction(void)
 
   END_TEST;
 }
+
+/**
+ * @brief This templatized function checks an enumeration property is setting and getting correctly.
+ * The checks performed are as follows:
+ *  - Check the initial/default value.
+ *  - Set a different value via enum.
+ *  - Check it was set.
+ *  - Set a different value via string.
+ *  - Check it was set.
+ */
+template< typename T >
+void CheckEnumerationProperty( Renderer& renderer, Property::Index propertyIndex, T initialValue, T firstCheckEnumeration, T secondCheckEnumeration, std::string secondCheckString )
+{
+  DALI_TEST_CHECK( renderer.GetProperty<int>( propertyIndex ) == static_cast<int>( initialValue ) );
+  renderer.SetProperty( propertyIndex, firstCheckEnumeration );
+  DALI_TEST_CHECK( renderer.GetProperty<int>( propertyIndex ) == static_cast<int>( firstCheckEnumeration ) );
+  renderer.SetProperty( propertyIndex, secondCheckString );
+  DALI_TEST_CHECK( renderer.GetProperty<int>( propertyIndex ) == static_cast<int>( secondCheckEnumeration ) );
+}
+
+int UtcDaliRendererEnumProperties(void)
+{
+  TestApplication application;
+  tet_infoline( "Test Renderer enumeration properties can be set with both integer and string values" );
+
+  Geometry geometry = CreateQuadGeometry();
+  Shader shader = CreateShader();
+  Renderer renderer = Renderer::New( geometry, shader );
+
+  /*
+   * Here we use a templatized function to perform several checks on each enumeration property.
+   * @see CheckEnumerationProperty for details of the checks performed.
+   */
+
+  CheckEnumerationProperty< FaceCullingMode::Type >( renderer, Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::NONE, FaceCullingMode::FRONT, FaceCullingMode::BACK, "BACK" );
+  CheckEnumerationProperty< BlendMode::Type >( renderer, Renderer::Property::BLEND_MODE, BlendMode::AUTO, BlendMode::OFF, BlendMode::ON, "ON" );
+  CheckEnumerationProperty< BlendEquation::Type >( renderer, Renderer::Property::BLEND_EQUATION_RGB, BlendEquation::ADD, BlendEquation::SUBTRACT, BlendEquation::REVERSE_SUBTRACT, "REVERSE_SUBTRACT" );
+  CheckEnumerationProperty< BlendEquation::Type >( renderer, Renderer::Property::BLEND_EQUATION_ALPHA, BlendEquation::ADD, BlendEquation::SUBTRACT, BlendEquation::REVERSE_SUBTRACT, "REVERSE_SUBTRACT" );
+  CheckEnumerationProperty< BlendFactor::Type >( renderer, Renderer::Property::BLEND_FACTOR_SRC_RGB, BlendFactor::SRC_ALPHA, BlendFactor::ONE, BlendFactor::SRC_COLOR, "SRC_COLOR" );
+  CheckEnumerationProperty< BlendFactor::Type >( renderer, Renderer::Property::BLEND_FACTOR_DEST_RGB, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::ONE, BlendFactor::SRC_COLOR, "SRC_COLOR" );
+  CheckEnumerationProperty< BlendFactor::Type >( renderer, Renderer::Property::BLEND_FACTOR_SRC_ALPHA, BlendFactor::ONE, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::SRC_COLOR, "SRC_COLOR" );
+  CheckEnumerationProperty< BlendFactor::Type >( renderer, Renderer::Property::BLEND_FACTOR_DEST_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::ONE, BlendFactor::SRC_COLOR, "SRC_COLOR" );
+  CheckEnumerationProperty< DepthWriteMode::Type >( renderer, Renderer::Property::DEPTH_WRITE_MODE, DepthWriteMode::AUTO, DepthWriteMode::OFF, DepthWriteMode::ON, "ON" );
+  CheckEnumerationProperty< DepthFunction::Type >( renderer, Renderer::Property::DEPTH_FUNCTION, DepthFunction::LESS, DepthFunction::ALWAYS, DepthFunction::GREATER, "GREATER" );
+  CheckEnumerationProperty< DepthTestMode::Type >( renderer, Renderer::Property::DEPTH_TEST_MODE, DepthTestMode::AUTO, DepthTestMode::OFF, DepthTestMode::ON, "ON" );
+  CheckEnumerationProperty< StencilFunction::Type >( renderer, Renderer::Property::STENCIL_FUNCTION, StencilFunction::ALWAYS, StencilFunction::LESS, StencilFunction::EQUAL, "EQUAL" );
+  CheckEnumerationProperty< RenderMode::Type >( renderer, Renderer::Property::RENDER_MODE, RenderMode::AUTO, RenderMode::NONE, RenderMode::STENCIL, "STENCIL" );
+  CheckEnumerationProperty< StencilOperation::Type >( renderer, Renderer::Property::STENCIL_OPERATION_ON_FAIL, StencilOperation::KEEP, StencilOperation::REPLACE, StencilOperation::INCREMENT, "INCREMENT" );
+  CheckEnumerationProperty< StencilOperation::Type >( renderer, Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL, StencilOperation::KEEP, StencilOperation::REPLACE, StencilOperation::INCREMENT, "INCREMENT" );
+  CheckEnumerationProperty< StencilOperation::Type >( renderer, Renderer::Property::STENCIL_OPERATION_ON_Z_PASS, StencilOperation::KEEP, StencilOperation::REPLACE, StencilOperation::INCREMENT, "INCREMENT" );
+
+  END_TEST;
+}
+
+Renderer RendererTestFixture( TestApplication& application )
+{
+  Geometry geometry = CreateQuadGeometry();
+  Shader shader = CreateShader();
+  Renderer renderer = Renderer::New( geometry, shader );
+
+  Actor actor = Actor::New();
+  actor.AddRenderer( renderer );
+  actor.SetSize( 400.0f, 400.0f );
+  Stage stage = Stage::GetCurrent();
+  stage.GetRootLayer().SetBehavior( Layer::LAYER_3D );
+  stage.Add( actor );
+
+  return renderer;
+}
+
+int UtcDaliRendererSetDepthTestMode(void)
+{
+  TestApplication application;
+  tet_infoline("Test setting the DepthTestMode");
+
+  Renderer renderer = RendererTestFixture( application );
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+  glAbstraction.EnableEnableDisableCallTrace( true );
+  TraceCallStack& glEnableDisableStack = glAbstraction.GetEnableDisableTrace();
+
+  glEnableDisableStack.Reset();
+  application.SendNotification();
+  application.Render();
+
+  // Check depth-test is enabled by default.
+  DALI_TEST_CHECK( glEnableDisableStack.FindMethodAndParams( "Enable", GetDepthTestString() ) );
+  DALI_TEST_CHECK( !glEnableDisableStack.FindMethodAndParams( "Disable", GetDepthTestString() ) );
+
+  // Turn off depth-testing. We want to check if the depth buffer has been disabled, so we need to turn off depth-write as well for this case.
+  renderer.SetProperty( Renderer::Property::DEPTH_TEST_MODE, DepthTestMode::OFF );
+  renderer.SetProperty( Renderer::Property::DEPTH_WRITE_MODE, DepthWriteMode::OFF );
+
+  glEnableDisableStack.Reset();
+  application.SendNotification();
+  application.Render();
+
+  // Check the depth buffer was disabled.
+  DALI_TEST_CHECK( glEnableDisableStack.FindMethodAndParams( "Disable", GetDepthTestString() ) );
+
+  // Turn on automatic mode depth-testing.
+  // Layer behavior is currently set to LAYER_3D so AUTO should enable depth-testing.
+  renderer.SetProperty( Renderer::Property::DEPTH_TEST_MODE, DepthTestMode::AUTO );
+
+  glEnableDisableStack.Reset();
+  application.SendNotification();
+  application.Render();
+
+  // Check depth-test is now enabled.
+  DALI_TEST_CHECK( glEnableDisableStack.FindMethodAndParams( "Enable", GetDepthTestString() ) );
+  DALI_TEST_CHECK( !glEnableDisableStack.FindMethodAndParams( "Disable", GetDepthTestString() ) );
+
+  // Change the layer behavior to LAYER_2D.
+  // Note this will also disable depth testing for the layer by default, we test this first.
+  Stage::GetCurrent().GetRootLayer().SetBehavior( Layer::LAYER_2D );
+
+  glEnableDisableStack.Reset();
+  application.SendNotification();
+  application.Render();
+
+  // Check depth-test is disabled.
+  DALI_TEST_CHECK( glEnableDisableStack.FindMethodAndParams( "Disable", GetDepthTestString() ) );
+
+  // Turn the layer depth-test flag back on, and confirm that depth testing is now on.
+  Stage::GetCurrent().GetRootLayer().SetDepthTestDisabled( false );
+
+  glEnableDisableStack.Reset();
+  application.SendNotification();
+  application.Render();
+
+  // Check depth-test is *still* disabled.
+  DALI_TEST_CHECK( glEnableDisableStack.FindMethodAndParams( "Enable", GetDepthTestString() ) );
+
+  END_TEST;
+}
+
+int UtcDaliRendererSetDepthWriteMode(void)
+{
+  TestApplication application;
+  tet_infoline("Test setting the DepthWriteMode");
+
+  Renderer renderer = RendererTestFixture( application );
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+
+  application.SendNotification();
+  application.Render();
+
+  // Check the default depth-write status first.
+  DALI_TEST_CHECK( glAbstraction.GetLastDepthMask() );
+
+  // Turn off depth-writing.
+  renderer.SetProperty( Renderer::Property::DEPTH_WRITE_MODE, DepthWriteMode::OFF );
+
+  application.SendNotification();
+  application.Render();
+
+  // Check depth-write is now disabled.
+  DALI_TEST_CHECK( !glAbstraction.GetLastDepthMask() );
+
+  // Test the AUTO mode for depth-writing.
+  // As our renderer is opaque, depth-testing should be enabled.
+  renderer.SetProperty( Renderer::Property::DEPTH_WRITE_MODE, DepthWriteMode::AUTO );
+
+  application.SendNotification();
+  application.Render();
+
+  // Check depth-write is now enabled.
+  DALI_TEST_CHECK( glAbstraction.GetLastDepthMask() );
+
+  // Now make the renderer be treated as translucent by enabling blending.
+  // The AUTO depth-write mode should turn depth-write off in this scenario.
+  renderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
+
+  application.SendNotification();
+  application.Render();
+
+  // Check depth-write is now disabled.
+  DALI_TEST_CHECK( !glAbstraction.GetLastDepthMask() );
+
+  END_TEST;
+}
+
+int UtcDaliRendererCheckStencilDefaults(void)
+{
+  TestApplication application;
+  tet_infoline("Test the stencil defaults");
+
+  Renderer renderer = RendererTestFixture( application );
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+  glAbstraction.EnableEnableDisableCallTrace( true );
+  glAbstraction.EnableStencilFunctionCallTrace( true );
+  TraceCallStack& glEnableDisableStack = glAbstraction.GetEnableDisableTrace();
+  TraceCallStack& glStencilFunctionStack = glAbstraction.GetStencilFunctionTrace();
+
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+
+  // Check the defaults:
+  DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_FUNCTION ).Get<int>() ), static_cast<int>( StencilFunction::ALWAYS ), TEST_LOCATION );
+  DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_FUNCTION_MASK ).Get<int>() ), 0xFF, TEST_LOCATION );
+  DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_FUNCTION_REFERENCE ).Get<int>() ), 0x00, TEST_LOCATION );
+  DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_MASK ).Get<int>() ), 0xFF, TEST_LOCATION );
+  DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_OPERATION_ON_FAIL ).Get<int>() ), static_cast<int>( StencilOperation::KEEP ), TEST_LOCATION );
+  DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL ).Get<int>() ), static_cast<int>( StencilOperation::KEEP ), TEST_LOCATION );
+  DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_OPERATION_ON_Z_PASS ).Get<int>() ), static_cast<int>( StencilOperation::KEEP ), TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliRendererSetRenderModeToUseStencilBuffer(void)
+{
+  TestApplication application;
+  tet_infoline("Test setting the RenderMode to use the stencil buffer");
+
+  Renderer renderer = RendererTestFixture( application );
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+  glAbstraction.EnableEnableDisableCallTrace( true );
+  glAbstraction.EnableStencilFunctionCallTrace( true );
+  TraceCallStack& glEnableDisableStack = glAbstraction.GetEnableDisableTrace();
+  TraceCallStack& glStencilFunctionStack = glAbstraction.GetStencilFunctionTrace();
+
+  // Set the StencilFunction to something other than the default, to confirm it is set as a property,
+  // but NO GL call has been made while the RenderMode is set to not use the stencil buffer.
+  renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::NONE );
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+
+  renderer.SetProperty( Renderer::Property::STENCIL_FUNCTION, StencilFunction::NEVER );
+  DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_FUNCTION ).Get<int>() ), static_cast<int>( StencilFunction::NEVER ), TEST_LOCATION );
+
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+  std::string methodString( "StencilFunc" );
+  DALI_TEST_CHECK( !glStencilFunctionStack.FindMethod( methodString ) );
+
+  // Test the other RenderModes that will not enable the stencil buffer.
+  renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::AUTO );
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+  DALI_TEST_CHECK( !glStencilFunctionStack.FindMethod( methodString ) );
+
+  renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::COLOR );
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+  DALI_TEST_CHECK( !glStencilFunctionStack.FindMethod( methodString ) );
+
+  // Now set the RenderMode to modes that will use the stencil buffer, and check the StencilFunction has changed.
+  renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::STENCIL );
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+
+  DALI_TEST_CHECK( glEnableDisableStack.FindMethodAndParams( "Enable", GetStencilTestString() ) );
+  DALI_TEST_CHECK( glStencilFunctionStack.FindMethod( methodString ) );
+
+  // Test the COLOR_STENCIL RenderMode as it also enables the stencil buffer.
+  // First set a mode to turn off the stencil buffer, so the enable is required.
+  renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::COLOR );
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+  renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::COLOR_STENCIL );
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+
+  DALI_TEST_CHECK( glEnableDisableStack.FindMethodAndParams( "Enable", GetStencilTestString() ) );
+  DALI_TEST_CHECK( glStencilFunctionStack.FindMethod( methodString ) );
+
+  END_TEST;
+}
+
+// Helper function for the SetRenderModeToUseColorBuffer test.
+void CheckRenderModeColorMask( TestApplication& application, Renderer& renderer, RenderMode::Type renderMode, bool expectedValue )
+{
+  // Set the RenderMode property to a value that should not allow color buffer writes.
+  renderer.SetProperty( Renderer::Property::RENDER_MODE, renderMode );
+  application.SendNotification();
+  application.Render();
+
+  // Check if ColorMask has been called, and that the values are correct.
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+  const TestGlAbstraction::ColorMaskParams& colorMaskParams( glAbstraction.GetColorMaskParams() );
+
+  DALI_TEST_EQUALS<bool>( colorMaskParams.red,   expectedValue, TEST_LOCATION );
+  DALI_TEST_EQUALS<bool>( colorMaskParams.green, expectedValue, TEST_LOCATION );
+  DALI_TEST_EQUALS<bool>( colorMaskParams.blue,  expectedValue, TEST_LOCATION );
+  DALI_TEST_EQUALS<bool>( colorMaskParams.alpha, expectedValue, TEST_LOCATION );
+}
+
+int UtcDaliRendererSetRenderModeToUseColorBuffer(void)
+{
+  TestApplication application;
+  tet_infoline("Test setting the RenderMode to use the color buffer");
+
+  Renderer renderer = RendererTestFixture( application );
+
+  // Set the RenderMode property to a value that should not allow color buffer writes.
+  // Then check if ColorMask has been called, and that the values are correct.
+  CheckRenderModeColorMask( application, renderer, RenderMode::AUTO, true );
+  CheckRenderModeColorMask( application, renderer, RenderMode::NONE, false );
+  CheckRenderModeColorMask( application, renderer, RenderMode::COLOR, true );
+  CheckRenderModeColorMask( application, renderer, RenderMode::STENCIL, false );
+  CheckRenderModeColorMask( application, renderer, RenderMode::COLOR_STENCIL, true );
+
+  END_TEST;
+}
+
+int UtcDaliRendererSetStencilFunction(void)
+{
+  TestApplication application;
+  tet_infoline("Test setting the StencilFunction");
+
+  Renderer renderer = RendererTestFixture( application );
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+  glAbstraction.EnableEnableDisableCallTrace( true );
+  glAbstraction.EnableStencilFunctionCallTrace( true );
+  TraceCallStack& glEnableDisableStack = glAbstraction.GetEnableDisableTrace();
+  TraceCallStack& glStencilFunctionStack = glAbstraction.GetStencilFunctionTrace();
+
+  // RenderMode must use the stencil for StencilFunction to operate.
+  renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::STENCIL );
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+
+  /*
+   * Lookup table for testing StencilFunction.
+   * Note: This MUST be in the same order as the Dali::StencilFunction enum.
+   */
+  const int StencilFunctionLookupTable[] = {
+      GL_NEVER,
+      GL_LESS,
+      GL_EQUAL,
+      GL_LEQUAL,
+      GL_GREATER,
+      GL_NOTEQUAL,
+      GL_GEQUAL,
+      GL_ALWAYS
+  }; const int StencilFunctionLookupTableCount = sizeof( StencilFunctionLookupTable ) / sizeof( StencilFunctionLookupTable[0] );
+
+  /*
+   * Loop through all types of StencilFunction, checking:
+   *  - The value is cached (set in event thread side)
+   *  - Causes "glStencilFunc" to be called
+   *  - Checks the correct parameters to "glStencilFunc" were used
+   */
+  std::string nonChangingParameters = "0, 255";
+  std::string methodString( "StencilFunc" );
+  for( int i = 0; i < StencilFunctionLookupTableCount; ++i )
+  {
+    // Set the property.
+    renderer.SetProperty( Renderer::Property::STENCIL_FUNCTION, static_cast<Dali::StencilFunction::Type>( i ) );
+
+    // Check GetProperty returns the same value.
+    DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_FUNCTION ).Get<int>() ), i, TEST_LOCATION );
+
+    // Reset the trace debug.
+    ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+
+    // Check the function is called and the parameters are correct.
+    std::stringstream parameterStream;
+    parameterStream << StencilFunctionLookupTable[ i ] << ", " << nonChangingParameters;
+
+    DALI_TEST_CHECK( glStencilFunctionStack.FindMethodAndParams( methodString, parameterStream.str() ) );
+  }
+
+  // Change the Function Reference only and check the behavior is correct:
+  // 170 is 0xaa in hex / 10101010 in binary (every other bit set).
+  int testValueReference = 170;
+  renderer.SetProperty( Renderer::Property::STENCIL_FUNCTION_REFERENCE, testValueReference );
+
+  DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_FUNCTION_REFERENCE ).Get<int>() ), testValueReference, TEST_LOCATION );
+
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+
+  std::stringstream parameterStream;
+  parameterStream << StencilFunctionLookupTable[ StencilOperation::DECREMENT_WRAP ] << ", " << testValueReference << ", 255";
+
+  DALI_TEST_CHECK( glStencilFunctionStack.FindMethodAndParams( methodString, parameterStream.str() ) );
+
+
+  // Change the Function Mask only and check the behavior is correct:
+  // 85 is 0x55 in hex / 01010101 in binary (every other bit set).
+  int testValueMask = 85;
+  renderer.SetProperty( Renderer::Property::STENCIL_FUNCTION_MASK, testValueMask );
+
+  DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_FUNCTION_MASK ).Get<int>() ), testValueMask, TEST_LOCATION );
+
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+
+  // Clear the stringstream.
+  parameterStream.str( std::string() );
+  parameterStream << StencilFunctionLookupTable[ StencilOperation::DECREMENT_WRAP ] << ", " << testValueReference << ", " << testValueMask;
+
+  DALI_TEST_CHECK( glStencilFunctionStack.FindMethodAndParams( methodString, parameterStream.str() ) );
+
+  END_TEST;
+}
+
+int UtcDaliRendererSetStencilOperation(void)
+{
+  TestApplication application;
+  tet_infoline("Test setting the StencilOperation");
+
+  Renderer renderer = RendererTestFixture( application );
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+  glAbstraction.EnableEnableDisableCallTrace( true );
+  glAbstraction.EnableStencilFunctionCallTrace( true );
+  TraceCallStack& glEnableDisableStack = glAbstraction.GetEnableDisableTrace();
+  TraceCallStack& glStencilFunctionStack = glAbstraction.GetStencilFunctionTrace();
+
+  // RenderMode must use the stencil for StencilOperation to operate.
+  renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::STENCIL );
+
+  /*
+   * Lookup table for testing StencilOperation.
+   * Note: This MUST be in the same order as the Dali::StencilOperation enum.
+   */
+  const int StencilOperationLookupTable[] = {
+    GL_ZERO,
+    GL_KEEP,
+    GL_REPLACE,
+    GL_INCR,
+    GL_DECR,
+    GL_INVERT,
+    GL_INCR_WRAP,
+    GL_DECR_WRAP
+  }; const int StencilOperationLookupTableCount = sizeof( StencilOperationLookupTable ) / sizeof( StencilOperationLookupTable[0] );
+
+  // Set all 3 StencilOperation properties to a default.
+  renderer.SetProperty( Renderer::Property::STENCIL_OPERATION_ON_FAIL, StencilOperation::ZERO );
+  renderer.SetProperty( Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL, StencilOperation::ZERO );
+  renderer.SetProperty( Renderer::Property::STENCIL_OPERATION_ON_Z_PASS, StencilOperation::ZERO );
+
+  // Set our expected parameter list to the equivalent result.
+  int parameters[] = { StencilOperationLookupTable[ StencilOperation::ZERO ], StencilOperationLookupTable[ StencilOperation::ZERO ], StencilOperationLookupTable[ StencilOperation::ZERO ] };
+
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+
+  /*
+   * Loop through all types of StencilOperation, checking:
+   *  - The value is cached (set in event thread side)
+   *  - Causes "glStencilFunc" to be called
+   *  - Checks the correct parameters to "glStencilFunc" were used
+   *  - Checks the above for all 3 parameter placements of StencilOperation ( OnFail, OnZFail, OnPass )
+   */
+  int stencilOperationPropertyKeys[] = { Renderer::Property::STENCIL_OPERATION_ON_FAIL, Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL, Renderer::Property::STENCIL_OPERATION_ON_Z_PASS };
+  std::string methodString( "StencilOp" );
+
+  for( int parameterIndex = 0; parameterIndex < 3; ++parameterIndex )
+  {
+    for( int i = 0; i < StencilOperationLookupTableCount; ++i )
+    {
+      // Set the property (outer loop causes all 3 different properties to be set separately).
+      renderer.SetProperty( stencilOperationPropertyKeys[ parameterIndex ], static_cast<Dali::StencilFunction::Type>( i ) );
+
+      // Check GetProperty returns the same value.
+      DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( stencilOperationPropertyKeys[ parameterIndex ] ).Get<int>() ), i, TEST_LOCATION );
+
+      // Reset the trace debug.
+      ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+
+      // Check the function is called and the parameters are correct.
+      // Set the expected parameter value at its correct index (only)
+      parameters[ parameterIndex ] = StencilOperationLookupTable[ i ];
+
+      // Build the parameter list.
+      std::stringstream parameterStream;
+      for( int parameterBuild = 0; parameterBuild < 3; ++parameterBuild )
+      {
+        parameterStream << parameters[ parameterBuild ];
+        // Comma-separate the parameters.
+        if( parameterBuild < 2 )
+        {
+          parameterStream << ", ";
+        }
+      }
+
+      // Check the function was called and the parameters were correct.
+      DALI_TEST_CHECK( glStencilFunctionStack.FindMethodAndParams( methodString, parameterStream.str() ) );
+    }
+  }
+
+  END_TEST;
+}
+
+int UtcDaliRendererSetStencilMask(void)
+{
+  TestApplication application;
+  tet_infoline("Test setting the StencilMask");
+
+  Renderer renderer = RendererTestFixture( application );
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+  glAbstraction.EnableEnableDisableCallTrace( true );
+  glAbstraction.EnableStencilFunctionCallTrace( true );
+  TraceCallStack& glEnableDisableStack = glAbstraction.GetEnableDisableTrace();
+  TraceCallStack& glStencilFunctionStack = glAbstraction.GetStencilFunctionTrace();
+
+  // RenderMode must use the stencil for StencilMask to operate.
+  renderer.SetProperty( Renderer::Property::RENDER_MODE, RenderMode::STENCIL );
+
+  // Set the StencilMask property to a value.
+  renderer.SetProperty( Renderer::Property::STENCIL_MASK, 0x00 );
+
+  // Check GetProperty returns the same value.
+  DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_MASK ).Get<int>() ), 0x00, TEST_LOCATION );
+
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+
+  std::string methodString( "StencilMask" );
+  std::string parameterString = "0";
+
+  // Check the function was called and the parameters were correct.
+  DALI_TEST_CHECK( glStencilFunctionStack.FindMethodAndParams( methodString, parameterString ) );
+
+  // Set the StencilMask property to another value to ensure it has changed.
+  renderer.SetProperty( Renderer::Property::STENCIL_MASK, 0xFF );
+
+  // Check GetProperty returns the same value.
+  DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_MASK ).Get<int>() ), 0xFF, TEST_LOCATION );
+
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+
+  parameterString = "255";
+
+  // Check the function was called and the parameters were correct.
+  DALI_TEST_CHECK( glStencilFunctionStack.FindMethodAndParams( methodString, parameterString ) );
+
+  END_TEST;
+}