Rendering API Stencil Implementation 06/80306/20
authorTom Robinson <tom.robinson@samsung.com>
Fri, 15 Jul 2016 16:57:15 +0000 (17:57 +0100)
committerTom Robinson <tom.robinson@samsung.com>
Tue, 26 Jul 2016 14:13:17 +0000 (07:13 -0700)
Change-Id: I802f2d0fb3a569e5f5d7159cd73d56f47874410e

13 files changed:
automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h
automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.h
automated-tests/src/dali/utc-Dali-Renderer.cpp
dali/internal/common/type-abstraction-enums.h
dali/internal/event/rendering/renderer-impl.cpp
dali/internal/event/rendering/renderer-impl.h
dali/internal/render/common/render-algorithms.cpp
dali/internal/render/common/render-algorithms.h
dali/internal/render/renderers/render-renderer.cpp
dali/internal/render/renderers/render-renderer.h
dali/internal/update/rendering/scene-graph-renderer.cpp
dali/internal/update/rendering/scene-graph-renderer.h
dali/public-api/rendering/renderer.h

index e445084..1f55977 100644 (file)
@@ -277,10 +277,21 @@ public:
 
   inline void ClearStencil(GLint s)
   {
+    std::stringstream out;
+    out << s;
+
+    TraceCallStack::NamedParams namedParams;
+    namedParams["s"] = ToString( s );
+
+    mStencilFunctionTrace.PushCall( "ClearStencil", out.str(), namedParams );
   }
 
   inline void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
   {
+    mColorMaskParams.red = red;
+    mColorMaskParams.green = green;
+    mColorMaskParams.blue = blue;
+    mColorMaskParams.alpha = alpha;
   }
 
   inline void CompileShader(GLuint shader)
@@ -662,6 +673,11 @@ public:
         *type = GL_SAMPLER_2D;
         *size = 1;
         break;
+      case 2:
+        *length = snprintf(name, bufsize, "sGloss");
+        *type = GL_SAMPLER_2D;
+        *size = 1;
+        break;
       default:
         break;
     }
@@ -878,9 +894,10 @@ public:
     namedParams["program"] = ToString(program);
     mShaderTrace.PushCall("LinkProgram", out.str(), namedParams);
 
-    mNumberOfActiveUniforms=2;
+    mNumberOfActiveUniforms=3;
     GetUniformLocation(program, "sTexture");
     GetUniformLocation(program, "sEffect");
+    GetUniformLocation(program, "sGloss");
   }
 
   inline void PixelStorei(GLenum pname, GLint param)
@@ -953,26 +970,79 @@ public:
 
   inline void StencilFunc(GLenum func, GLint ref, GLuint mask)
   {
+    std::stringstream out;
+    out << func << ", " << ref << ", " << mask;
+
+    TraceCallStack::NamedParams namedParams;
+    namedParams["func"] = ToString( func );
+    namedParams["ref"] = ToString( ref );
+    namedParams["mask"] = ToString( mask );
+
+    mStencilFunctionTrace.PushCall( "StencilFunc", out.str(), namedParams );
   }
 
   inline void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
   {
+    std::stringstream out;
+    out << face << ", " << func << ", " << ref << ", " << mask;
+
+    TraceCallStack::NamedParams namedParams;
+    namedParams["face"] = ToString( face );
+    namedParams["func"] = ToString( func );
+    namedParams["ref"] = ToString( ref );
+    namedParams["mask"] = ToString( mask );
+
+    mStencilFunctionTrace.PushCall( "StencilFuncSeparate", out.str(), namedParams );
   }
 
   inline void StencilMask(GLuint mask)
   {
+    std::stringstream out;
+    out << mask;
+
+    TraceCallStack::NamedParams namedParams;
+    namedParams["mask"] = ToString( mask );
+
+    mStencilFunctionTrace.PushCall( "StencilMask", out.str(), namedParams );
   }
 
   inline void StencilMaskSeparate(GLenum face, GLuint mask)
   {
+    std::stringstream out;
+    out << face << ", " << mask;
+
+    TraceCallStack::NamedParams namedParams;
+    namedParams["face"] = ToString( face );
+    namedParams["mask"] = ToString( mask );
+
+    mStencilFunctionTrace.PushCall( "StencilMaskSeparate", out.str(), namedParams );
   }
 
   inline void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
   {
+    std::stringstream out;
+    out << fail << ", " << zfail << ", " << zpass;
+
+    TraceCallStack::NamedParams namedParams;
+    namedParams["fail"] = ToString( fail );
+    namedParams["zfail"] = ToString( zfail );
+    namedParams["zpass"] = ToString( zpass );
+
+    mStencilFunctionTrace.PushCall( "StencilOp", out.str(), namedParams );
   }
 
   inline void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
   {
+    std::stringstream out;
+    out << face << ", " << fail << ", " << zfail << "," << zpass;
+
+    TraceCallStack::NamedParams namedParams;
+    namedParams["face"] = ToString( face );
+    namedParams["fail"] = ToString( fail );
+    namedParams["zfail"] = ToString( zfail );
+    namedParams["zpass"] = ToString( zpass );
+
+    mStencilFunctionTrace.PushCall( "StencilOpSeparate", out.str(), namedParams );
   }
 
   inline void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels)
@@ -1775,6 +1845,11 @@ public: // TEST FUNCTIONS
   inline void ResetDepthFunctionCallStack() { mDepthFunctionTrace.Reset(); }
   inline TraceCallStack& GetDepthFunctionTrace() { return mDepthFunctionTrace; }
 
+  //Methods for Stencil function verification
+  inline void EnableStencilFunctionCallTrace(bool enable) { mStencilFunctionTrace.Enable(enable); }
+  inline void ResetStencilFunctionCallStack() { mStencilFunctionTrace.Reset(); }
+  inline TraceCallStack& GetStencilFunctionTrace() { return mStencilFunctionTrace; }
+
   template <typename T>
   inline bool GetUniformValue( const char* name, T& value ) const
   {
@@ -1917,10 +1992,22 @@ public: // TEST FUNCTIONS
   // Methods to check scissor tests
   inline const ScissorParams& GetScissorParams() const { return mScissorParams; }
 
+  struct ColorMaskParams
+  {
+    GLboolean red;
+    GLboolean green;
+    GLboolean blue;
+    GLboolean alpha;
+
+    ColorMaskParams() : red( true ), green( true ), blue( true ), alpha( true ) { }
+  };
+
   inline bool GetProgramBinaryCalled() const { return mGetProgramBinaryCalled; }
 
   inline unsigned int GetClearCountCalled() const { return mClearCount; }
 
+  inline const ColorMaskParams& GetColorMaskParams() const { return mColorMaskParams; }
+
   typedef std::vector<size_t> BufferDataCalls;
   inline const BufferDataCalls& GetBufferDataCalls() const { return mBufferDataCalls; }
   inline void ResetBufferDataCalls() { mBufferDataCalls.clear(); }
@@ -1992,6 +2079,7 @@ private:
   TraceCallStack mTexParamaterTrace;
   TraceCallStack mDrawTrace;
   TraceCallStack mDepthFunctionTrace;
+  TraceCallStack mStencilFunctionTrace;
 
   // Shaders & Uniforms
   GLuint mLastShaderIdUsed;
@@ -2119,6 +2207,7 @@ private:
   }
 
   ScissorParams mScissorParams;
+  ColorMaskParams mColorMaskParams;
 };
 
 template <>
index 32375a6..137bfaf 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __TEST_TRACE_CALL_STACK_H__
-#define __TEST_TRACE_CALL_STACK_H__
+#ifndef TEST_TRACE_CALL_STACK_H
+#define TEST_TRACE_CALL_STACK_H
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
@@ -21,6 +21,7 @@
 #include <string>
 #include <vector>
 #include <map>
+#include <sstream>
 
 namespace Dali
 {
@@ -34,6 +35,7 @@ std::string ToString(float x);
 class TraceCallStack
 {
 public:
+
   /// Typedef for passing and storing named parameters
   typedef std::map< std::string, std::string > NamedParams;
 
@@ -128,6 +130,23 @@ public:
    */
   void Reset();
 
+  /**
+   * Method to display contents of the TraceCallStack.
+   * @return A string containing a list of function calls and parameters (may contain newline characters)
+   */
+  std::string GetTraceString()
+  {
+    std::stringstream traceStream;
+    int functionCount = mCallStack.size();
+    for( int i = 0; i < functionCount; ++i )
+    {
+      Dali::TraceCallStack::FunctionCall functionCall = mCallStack[ i ];
+      traceStream << "StackTrace: Index:" << i << ",  Function:" << functionCall.method << ",  ParamList:" << functionCall.paramList << std::endl;
+    }
+
+    return traceStream.str();
+  }
+
 private:
   bool mTraceActive; ///< True if the trace is active
 
@@ -151,4 +170,4 @@ private:
 
 } // namespace dali
 
-#endif //__TEST_TRACE_CALL_STACK_H__
+#endif // TEST_TRACE_CALL_STACK_H
index ce5dd3f..8bf5035 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;
@@ -37,6 +39,25 @@ const BlendFactor::Type   DEFAULT_BLEND_FACTOR_DEST_ALPHA( BlendFactor::ONE_MINU
 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();
+}
+
+void ResetDebugAndFlush( TestApplication& application, TraceCallStack& glEnableDisableStack, TraceCallStack& glStencilFunctionStack )
+{
+  glEnableDisableStack.Reset();
+  glStencilFunctionStack.Reset();
+  application.SendNotification();
+  application.Render();
+}
+
 void TestConstraintNoBlue( Vector4& current, const PropertyInputContainer& inputs )
 {
   current.b = 0.0f;
@@ -2015,3 +2036,345 @@ int UtcDaliRendererSetDepthFunction(void)
 
   END_TEST;
 }
+
+Renderer StencilTestFixture( 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 UtcDaliRendererCheckStencilDefaults(void)
+{
+  TestApplication application;
+  tet_infoline("Test the stencil defaults");
+
+  Renderer renderer = StencilTestFixture( 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 UtcDaliRendererSetStencilMode(void)
+{
+  TestApplication application;
+  tet_infoline("Test setting the StencilMode");
+
+  Renderer renderer = StencilTestFixture( application );
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+  glAbstraction.EnableEnableDisableCallTrace( true );
+  glAbstraction.EnableStencilFunctionCallTrace( true );
+  TraceCallStack& glEnableDisableStack = glAbstraction.GetEnableDisableTrace();
+  TraceCallStack& glStencilFunctionStack = glAbstraction.GetStencilFunctionTrace();
+
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+
+  // 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 StencilMode is set to OFF.
+  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 ) );
+
+  // Now set the StencilMode to ON and check the StencilFunction has changed.
+  renderer.SetProperty( Renderer::Property::STENCIL_MODE, StencilMode::ON );
+  ResetDebugAndFlush( application, glEnableDisableStack, glStencilFunctionStack );
+
+  DALI_TEST_CHECK( glEnableDisableStack.FindMethodAndParams( "Enable", GetStencilTestString() ) );
+  DALI_TEST_CHECK( glStencilFunctionStack.FindMethod( methodString ) );
+
+  END_TEST;
+}
+
+int UtcDaliRendererSetStencilFunction(void)
+{
+  TestApplication application;
+  tet_infoline("Test setting the StencilFunction");
+
+  Renderer renderer = StencilTestFixture( application );
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+  glAbstraction.EnableEnableDisableCallTrace( true );
+  glAbstraction.EnableStencilFunctionCallTrace( true );
+  TraceCallStack& glEnableDisableStack = glAbstraction.GetEnableDisableTrace();
+  TraceCallStack& glStencilFunctionStack = glAbstraction.GetStencilFunctionTrace();
+
+  // StencilMode must be ON for StencilFunction to operate.
+  renderer.SetProperty( Renderer::Property::STENCIL_MODE, StencilMode::ON );
+  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 = StencilTestFixture( application );
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+  glAbstraction.EnableEnableDisableCallTrace( true );
+  glAbstraction.EnableStencilFunctionCallTrace( true );
+  TraceCallStack& glEnableDisableStack = glAbstraction.GetEnableDisableTrace();
+  TraceCallStack& glStencilFunctionStack = glAbstraction.GetStencilFunctionTrace();
+
+  // StencilMode must be ON for StencilOperation to operate.
+  renderer.SetProperty( Renderer::Property::STENCIL_MODE, StencilMode::ON );
+
+  /*
+   * 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 = StencilTestFixture( application );
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+  glAbstraction.EnableEnableDisableCallTrace( true );
+  glAbstraction.EnableStencilFunctionCallTrace( true );
+  TraceCallStack& glEnableDisableStack = glAbstraction.GetEnableDisableTrace();
+  TraceCallStack& glStencilFunctionStack = glAbstraction.GetStencilFunctionTrace();
+
+  // StencilMode must be ON for StencilMask to operate.
+  renderer.SetProperty( Renderer::Property::STENCIL_MODE, StencilMode::ON );
+
+  // 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;
+}
+
+int UtcDaliRendererSetWriteToColorBuffer(void)
+{
+  TestApplication application;
+  tet_infoline("Test setting the WriteToColorBuffer flag");
+
+  Renderer renderer = StencilTestFixture( application );
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+
+  // Set the StencilMask property to a value.
+  renderer.SetProperty( Renderer::Property::WRITE_TO_COLOR_BUFFER, false );
+
+  // Check GetProperty returns the same value.
+  DALI_TEST_CHECK( !renderer.GetProperty( Renderer::Property::WRITE_TO_COLOR_BUFFER ).Get<bool>() );
+
+  application.SendNotification();
+  application.Render();
+
+  // Check if ColorMask has been called, and that the values are correct.
+  const TestGlAbstraction::ColorMaskParams& colorMaskParams( glAbstraction.GetColorMaskParams() );
+
+  DALI_TEST_EQUALS<bool>( colorMaskParams.red,   false, TEST_LOCATION );
+  DALI_TEST_EQUALS<bool>( colorMaskParams.green, false, TEST_LOCATION );
+  DALI_TEST_EQUALS<bool>( colorMaskParams.blue,  false, TEST_LOCATION );
+  DALI_TEST_EQUALS<bool>( colorMaskParams.alpha, false, TEST_LOCATION );
+
+  // Set the StencilMask property to true.
+  renderer.SetProperty( Renderer::Property::WRITE_TO_COLOR_BUFFER, true );
+
+  // Check GetProperty returns the same value.
+  DALI_TEST_CHECK( renderer.GetProperty( Renderer::Property::WRITE_TO_COLOR_BUFFER ).Get<bool>() );
+
+  application.SendNotification();
+  application.Render();
+
+  // Check if ColorMask has been called, and that the values are correct.
+  const TestGlAbstraction::ColorMaskParams& colorMaskParamsChanged( glAbstraction.GetColorMaskParams() );
+
+  DALI_TEST_EQUALS<bool>( colorMaskParamsChanged.red,   true, TEST_LOCATION );
+  DALI_TEST_EQUALS<bool>( colorMaskParamsChanged.green, true, TEST_LOCATION );
+  DALI_TEST_EQUALS<bool>( colorMaskParamsChanged.blue,  true, TEST_LOCATION );
+  DALI_TEST_EQUALS<bool>( colorMaskParamsChanged.alpha, true, TEST_LOCATION );
+
+  END_TEST;
+}
index 3545df4..b1d44ad 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __DALI_INTERNAL_TYPE_ABSTRACTION_ENUMS_H__
-#define __DALI_INTERNAL_TYPE_ABSTRACTION_ENUMS_H__
+#ifndef DALI_INTERNAL_TYPE_ABSTRACTION_ENUMS_H
+#define DALI_INTERNAL_TYPE_ABSTRACTION_ENUMS_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
@@ -28,14 +28,17 @@ namespace Dali
 namespace Internal
 {
 
-template <> struct ParameterType< Dali::FaceCullingMode::Type > : public BasicType< Dali::FaceCullingMode::Type > {};
-template <> struct ParameterType< Dali::BlendMode::Type > : public BasicType< Dali::BlendMode::Type > {};
-template <> struct ParameterType< Dali::DepthWriteMode::Type > : public BasicType< Dali::DepthWriteMode::Type > {};
-template <> struct ParameterType< Dali::DepthTestMode::Type > : public BasicType< Dali::DepthTestMode::Type > {};
-template <> struct ParameterType< Dali::DepthFunction::Type > : public BasicType< Dali::DepthFunction::Type > {};
+template <> struct ParameterType< Dali::FaceCullingMode::Type >  : public BasicType< Dali::FaceCullingMode::Type > {};
+template <> struct ParameterType< Dali::BlendMode::Type >        : public BasicType< Dali::BlendMode::Type > {};
+template <> struct ParameterType< Dali::DepthWriteMode::Type >   : public BasicType< Dali::DepthWriteMode::Type > {};
+template <> struct ParameterType< Dali::DepthTestMode::Type >    : public BasicType< Dali::DepthTestMode::Type > {};
+template <> struct ParameterType< Dali::DepthFunction::Type >    : public BasicType< Dali::DepthFunction::Type > {};
+template <> struct ParameterType< Dali::StencilMode::Type >      : public BasicType< Dali::StencilMode::Type > {};
+template <> struct ParameterType< Dali::StencilFunction::Type >  : public BasicType< Dali::StencilFunction::Type > {};
+template <> struct ParameterType< Dali::StencilOperation::Type > : public BasicType< Dali::StencilOperation::Type > {};
 
 } //namespace Internal
 
 } //namespace Dali
 
-#endif // __DALI_INTERNAL_TYPE_ABSTRACTION_ENUMS_H__
+#endif // DALI_INTERNAL_TYPE_ABSTRACTION_ENUMS_H
index 2b80191..0bd59c7 100644 (file)
 // INTERNAL INCLUDES
 #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-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
 {
@@ -506,8 +506,116 @@ void Renderer::SetDefaultProperty( Property::Index index,
       }
       break;
     }
-    default:
+    case Dali::Renderer::Property::STENCIL_MODE:
+    {
+      int value;
+      propertyValue.Get( value );
+      StencilMode::Type stencilMode = static_cast<StencilMode::Type>( value );
+      if( stencilMode != mStencilParameters.stencilMode )
+      {
+        mStencilParameters.stencilMode = stencilMode;
+        SetStencilModeMessage( GetEventThreadServices(), *mSceneObject, stencilMode );
+      }
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_FUNCTION:
+    {
+      int value;
+      propertyValue.Get( value );
+      StencilFunction::Type stencilFunction = static_cast<StencilFunction::Type>( value );
+      if( stencilFunction != mStencilParameters.stencilFunction )
+      {
+        mStencilParameters.stencilFunction = stencilFunction;
+        SetStencilFunctionMessage( GetEventThreadServices(), *mSceneObject, stencilFunction );
+      }
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_FUNCTION_MASK:
+    {
+      int stencilFunctionMask;
+      if( propertyValue.Get( stencilFunctionMask ) )
+      {
+        if( stencilFunctionMask != mStencilParameters.stencilFunctionMask )
+        {
+          mStencilParameters.stencilFunctionMask = stencilFunctionMask;
+          SetStencilFunctionMaskMessage( GetEventThreadServices(), *mSceneObject, stencilFunctionMask );
+        }
+      }
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE:
+    {
+      int stencilFunctionReference;
+      if( propertyValue.Get( stencilFunctionReference ) )
+      {
+        if( stencilFunctionReference != mStencilParameters.stencilFunctionReference )
+        {
+          mStencilParameters.stencilFunctionReference = stencilFunctionReference;
+          SetStencilFunctionReferenceMessage( GetEventThreadServices(), *mSceneObject, stencilFunctionReference );
+        }
+      }
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_MASK:
+    {
+      int stencilMask;
+      if( propertyValue.Get( stencilMask ) )
+      {
+        if( stencilMask != mStencilParameters.stencilMask )
+        {
+          mStencilParameters.stencilMask = stencilMask;
+          SetStencilMaskMessage( GetEventThreadServices(), *mSceneObject, stencilMask );
+        }
+      }
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL:
     {
+      int value;
+      propertyValue.Get( value );
+      StencilOperation::Type stencilOperation = static_cast<StencilOperation::Type>( value );
+      if( stencilOperation != mStencilParameters.stencilOperationOnFail )
+      {
+        mStencilParameters.stencilOperationOnFail = stencilOperation;
+        SetStencilOperationOnFailMessage( GetEventThreadServices(), *mSceneObject, stencilOperation );
+      }
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL:
+    {
+      int value;
+      propertyValue.Get( value );
+      StencilOperation::Type stencilOperation = static_cast<StencilOperation::Type>( value );
+      if( stencilOperation != mStencilParameters.stencilOperationOnZFail )
+      {
+        mStencilParameters.stencilOperationOnZFail = stencilOperation;
+        SetStencilOperationOnZFailMessage( GetEventThreadServices(), *mSceneObject, stencilOperation );
+      }
+      break;
+    }
+    case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS:
+    {
+      int value;
+      propertyValue.Get( value );
+      StencilOperation::Type stencilOperation = static_cast<StencilOperation::Type>( value );
+      if( stencilOperation != mStencilParameters.stencilOperationOnZPass )
+      {
+        mStencilParameters.stencilOperationOnZPass = stencilOperation;
+        SetStencilOperationOnZPassMessage( GetEventThreadServices(), *mSceneObject, stencilOperation );
+      }
+      break;
+    }
+    case Dali::Renderer::Property::WRITE_TO_COLOR_BUFFER:
+    {
+      bool writeToColorBuffer;
+      if( propertyValue.Get( writeToColorBuffer ) )
+      {
+        if( mWriteToColorBuffer != writeToColorBuffer )
+        {
+          mWriteToColorBuffer = writeToColorBuffer;
+          SetWriteToColorBufferMessage( GetEventThreadServices(), *mSceneObject, writeToColorBuffer );
+        }
+      }
       break;
     }
   }
@@ -633,6 +741,51 @@ Property::Value Renderer::GetDefaultProperty( Property::Index index ) const
       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::STENCIL_MODE:
+    {
+      value = mStencilParameters.stencilMode;
+      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::Renderer::Property::WRITE_TO_COLOR_BUFFER:
+    {
+      value = mWriteToColorBuffer;
+      break;
+    }
   }
   return value;
 }
@@ -716,12 +869,14 @@ Renderer::Renderer()
   mOnStageCount( 0 ),
   mIndexedDrawFirstElement( 0 ),
   mIndexedDrawElementCount( 0 ),
+  mStencilParameters( StencilMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP ),
+  mBlendingOptions(),
+  mDepthFunction( DepthFunction::LESS ),
   mFaceCullingMode( FaceCullingMode::NONE ),
   mBlendMode( BlendMode::AUTO ),
-  mBlendingOptions(),
   mDepthWriteMode( DepthWriteMode::AUTO ),
-  mDepthFunction( DepthFunction::LESS ),
   mDepthTestMode( DepthTestMode::AUTO ),
+  mWriteToColorBuffer( true ),
   mPremultipledAlphaEnabled( false )
 {
 }
index 5019784..64d99ba 100644 (file)
@@ -28,6 +28,7 @@
 #include <dali/internal/event/common/object-impl.h> // Dali::Internal::Object
 #include <dali/internal/event/rendering/texture-set-impl.h> // Dali::Internal::TextureSet
 #include <dali/internal/event/rendering/geometry-impl.h> // Dali::Internal::Geometry
+#include <dali/internal/render/renderers/render-renderer.h> // Dali::Render::Renderer::StencilParameters
 
 namespace Dali
 {
@@ -38,7 +39,6 @@ namespace SceneGraph
 class Renderer;
 }
 
-
 class Renderer;
 typedef IntrusivePtr<Renderer> RendererPtr;
 
@@ -303,25 +303,27 @@ private: // unimplemented methods
 
 private: // data
   SceneGraph::Renderer* mSceneObject;
-  Vector4* mBlendColor;                             ///< Local copy of blend color, pointer only as its rarely used
-  GeometryPtr mGeometry;                            ///< Connector that holds the geometry used by this renderer
-  ObjectConnector<TextureSet> mTextureSetConnector; ///< Connector that holds the texture set used by this renderer
-  IntrusivePtr<Shader> mShader;                     ///< Connector that holds the shader used by this renderer
+  Vector4* mBlendColor;                                       ///< Local copy of blend color, pointer only as its rarely used
+  GeometryPtr mGeometry;                                      ///< Connector that holds the geometry used by this renderer
+  ObjectConnector<TextureSet> mTextureSetConnector;           ///< Connector that holds the texture set used by this renderer
+  IntrusivePtr<Shader> mShader;                               ///< Connector that holds the shader used by this renderer
 
   int mDepthIndex;
   int mOnStageCount;
 
-  size_t mIndexedDrawFirstElement;                  ///< Offset of first element to draw from bound index buffer
-  size_t mIndexedDrawElementCount;                  ///< Number of elements to draw
+  size_t mIndexedDrawFirstElement;                            ///< Offset of first element to draw from bound index buffer
+  size_t mIndexedDrawElementCount;                            ///< Number of elements to draw
 
-  Dali::FaceCullingMode::Type mFaceCullingMode;     ///< Local copy of face culling mode
-  BlendMode::Type mBlendMode;                       ///< Local copy of blending mode
-  BlendingOptions mBlendingOptions;                 ///< Local copy of blending options bitmask
-  Dali::DepthWriteMode::Type mDepthWriteMode;       ///< Local copy of depth write mode
-  Dali::DepthFunction::Type mDepthFunction;         ///< Local copy of depth function
-  Dali::DepthTestMode::Type mDepthTestMode;         ///< Local copy of depth test mode
+  Render::Renderer::StencilParameters mStencilParameters;     ///< Struct containing all stencil related options
+  BlendingOptions              mBlendingOptions;              ///< Local copy of blending options bitmask
 
-  bool mPremultipledAlphaEnabled : 1;               ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
+  DepthFunction::Type          mDepthFunction:3;              ///< Local copy of the depth function
+  FaceCullingMode::Type        mFaceCullingMode:2;            ///< Local copy of the mode of face culling
+  BlendMode::Type              mBlendMode:2;                  ///< Local copy of the mode of blending
+  DepthWriteMode::Type         mDepthWriteMode:2;             ///< Local copy of the depth write mode
+  DepthTestMode::Type          mDepthTestMode:2;              ///< Local copy of the depth test mode
+  bool                         mWriteToColorBuffer:1;         ///< Local copy of the write to color buffer flag
+  bool                         mPremultipledAlphaEnabled:1;   ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
 };
 
 } // namespace Internal
index 695a574..95c0cae 100644 (file)
@@ -42,9 +42,19 @@ namespace Render
 
 namespace
 {
+
 // Table for fast look-up of Dali::DepthFunction enum to a GL depth function.
 // Note: These MUST be in the same order as Dali::DepthFunction enum.
-const short DaliDepthToGLDepthTable[] = { GL_NEVER, GL_ALWAYS, GL_LESS, GL_GREATER, GL_EQUAL, GL_NOTEQUAL, GL_LEQUAL, GL_GEQUAL };
+const int DaliDepthToGLDepthTable[]  = { GL_NEVER, GL_ALWAYS, GL_LESS, GL_GREATER, GL_EQUAL, GL_NOTEQUAL, GL_LEQUAL, GL_GEQUAL };
+
+// Table for fast look-up of Dali::StencilFunction enum to a GL stencil function.
+// Note: These MUST be in the same order as Dali::StencilFunction enum.
+const int DaliStencilFunctionToGL[]  = { GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS };
+
+// Table for fast look-up of Dali::StencilOperation enum to a GL stencil operation.
+// Note: These MUST be in the same order as Dali::StencilOperation enum.
+const int DaliStencilOperationToGL[] = { GL_ZERO, GL_KEEP, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT, GL_INCR_WRAP, GL_DECR_WRAP };
+
 } // Unnamed namespace
 
 /**
@@ -89,13 +99,14 @@ inline void SetRenderFlags( const RenderList& renderList, Context& context, bool
     context.StencilFunc( ( enableStencilWrite ? GL_ALWAYS : GL_EQUAL ), 1, 0xFF );
     context.StencilOp( GL_KEEP, GL_REPLACE, GL_REPLACE );
 
+    // Write to stencil buffer or color buffer, but not both.
+    // These should only be set if the Actor::DrawMode is managing the stencil (and color) buffer.
+    context.StencilMask( enableStencilWrite ? 0xFF : 0x00 );
+    context.ColorMask( !enableStencilWrite );
+
     clearMask |= ( renderFlags & RenderList::STENCIL_CLEAR ) ? GL_STENCIL_BUFFER_BIT : 0u;
   }
 
-  // Write to stencil buffer or color buffer, but not both
-  context.StencilMask( enableStencilWrite ? 0xFF : 0x00 );
-  context.ColorMask( !enableStencilWrite );
-
   // Enable and Clear the depth buffer if required.
   // DepthTest must be enabled for the layer, else testing is turned off.
   if( !depthTestEnabled )
@@ -118,6 +129,55 @@ inline void SetRenderFlags( const RenderList& renderList, Context& context, bool
 }
 
 /**
+ * @brief This method sets up the stencil and color buffer based on the current Renderers flags.
+ * @param[in]     item                     The current RenderItem about to be rendered
+ * @param[in]     context                  The context
+ * @param[in/out] usedStencilBuffer        True if the stencil buffer has been used so far within this RenderList
+ * @param[in]     stencilManagedByDrawMode True if the stencil and color buffer is being managed by DrawMode::STENCIL
+ */
+inline void SetupPerRendererFlags( const RenderItem& item, Context& context, bool& usedStencilBuffer, bool stencilManagedByDrawMode )
+{
+  // DrawMode::STENCIL is deprecated, however to support it we must not set
+  // flags based on the renderer properties if it is in use.
+  if( stencilManagedByDrawMode )
+  {
+    return;
+  }
+
+  // Setup the color buffer based on the renderers properties.
+  Renderer *renderer = item.mRenderer;
+  context.ColorMask( renderer->GetWriteToColorBuffer() );
+
+  // If the stencil buffer is disabled for this renderer, exit now to save unnecessary value setting.
+  if( renderer->GetStencilMode() != StencilMode::ON )
+  {
+    // No per-renderer stencil setup, exit.
+    context.EnableStencilBuffer( false );
+    return;
+  }
+
+  // At this point, the stencil buffer is enabled.
+  context.EnableStencilBuffer( true );
+
+  // If this is the first use of the stencil buffer within this RenderList, clear it now.
+  // This avoids unnecessary clears.
+  if( !usedStencilBuffer )
+  {
+    context.Clear( GL_STENCIL_BUFFER_BIT, Context::CHECK_CACHED_VALUES );
+    usedStencilBuffer = true;
+  }
+
+  // Setup the stencil buffer based on the renderers properties.
+  context.StencilFunc( DaliStencilFunctionToGL[ renderer->GetStencilFunction() ],
+      renderer->GetStencilFunctionReference(),
+      renderer->GetStencilFunctionMask() );
+  context.StencilOp( DaliStencilOperationToGL[ renderer->GetStencilOperationOnFail() ],
+      DaliStencilOperationToGL[ renderer->GetStencilOperationOnZFail() ],
+      DaliStencilOperationToGL[ renderer->GetStencilOperationOnZPass() ] );
+  context.StencilMask( renderer->GetStencilMask() );
+}
+
+/**
  * Sets up the depth buffer for reading and writing based on the current render item.
  * The items read and write mode are used if specified.
  * If AUTO is selected for reading, the decision will be based on the Layer Behavior.
@@ -169,6 +229,8 @@ inline void ProcessRenderList(
 
   bool depthTestEnabled = !( renderList.GetSourceLayer()->IsDepthTestDisabled() );
   bool isLayer3D = renderList.GetSourceLayer()->GetBehavior() == Dali::Layer::LAYER_3D;
+  bool usedStencilBuffer = false;
+  bool stencilManagedByDrawMode = renderList.GetFlags() & RenderList::STENCIL_BUFFER_ENABLED;
 
   SetScissorTest( renderList, context );
   SetRenderFlags( renderList, context, depthTestEnabled, isLayer3D );
@@ -184,6 +246,7 @@ inline void ProcessRenderList(
       const RenderItem& item = renderList.GetItem( index );
       DALI_PRINT_RENDER_ITEM( item );
 
+      SetupPerRendererFlags( item, context, usedStencilBuffer, stencilManagedByDrawMode );
       item.mRenderer->Render( context, textureCache, bufferIndex, *item.mNode, defaultShader,
                               item.mModelMatrix, item.mModelViewMatrix, viewMatrix, projectionMatrix, item.mSize, !item.mIsOpaque );
     }
@@ -198,6 +261,7 @@ inline void ProcessRenderList(
 
       // Set up the depth buffer based on per-renderer flags.
       SetupDepthBuffer( item, context, isLayer3D );
+      SetupPerRendererFlags( item, context, usedStencilBuffer, stencilManagedByDrawMode );
 
       item.mRenderer->Render( context, textureCache, bufferIndex, *item.mNode, defaultShader,
                               item.mModelMatrix, item.mModelViewMatrix, viewMatrix, projectionMatrix, item.mSize, !item.mIsOpaque );
index b84d68d..a2e4c57 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_INTERNAL_RENDER_ALGORITHMS_H__
-#define __DALI_INTERNAL_RENDER_ALGORITHMS_H__
+#ifndef DALI_INTERNAL_RENDER_ALGORITHMS_H
+#define DALI_INTERNAL_RENDER_ALGORITHMS_H
 
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
@@ -43,7 +43,7 @@ namespace Render
  * @param[in] context The GL context.
  * @param[in] textureCache The texture cache used to get textures.
  * @param[in] defaultShader The default shader.
- * @param[in] buffer The current render buffer index (previous update buffer)
+ * @param[in] bufferIndex The current render buffer index (previous update buffer)
  */
 void ProcessRenderInstruction( const SceneGraph::RenderInstruction& instruction,
                                Context& context,
@@ -57,4 +57,4 @@ void ProcessRenderInstruction( const SceneGraph::RenderInstruction& instruction,
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_RENDER_ALGORITHMS_H__
+#endif // DALI_INTERNAL_RENDER_ALGORITHMS_H
index 5400c12..01c03e3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
@@ -18,7 +18,6 @@
 // CLASS HEADER
 #include <dali/internal/render/renderers/render-renderer.h>
 
-
 // INTERNAL INCLUDES
 #include <dali/internal/common/image-sampler.h>
 #include <dali/internal/render/gl-resources/context.h>
@@ -118,9 +117,13 @@ Renderer* Renderer::New( SceneGraph::RenderDataProvider* dataProvider,
                          bool preMultipliedAlphaEnabled,
                          DepthWriteMode::Type depthWriteMode,
                          DepthTestMode::Type depthTestMode,
-                         DepthFunction::Type depthFunction )
+                         DepthFunction::Type depthFunction,
+                         StencilParameters& stencilParameters,
+                         bool writeToColorBuffer )
 {
-  return new Renderer( dataProvider, geometry, blendingBitmask, blendColor, faceCullingMode, preMultipliedAlphaEnabled, depthWriteMode, depthTestMode, depthFunction );
+  return new Renderer( dataProvider, geometry, blendingBitmask, blendColor,
+                       faceCullingMode, preMultipliedAlphaEnabled, depthWriteMode, depthTestMode,
+                       depthFunction, stencilParameters, writeToColorBuffer );
 }
 
 Renderer::Renderer( SceneGraph::RenderDataProvider* dataProvider,
@@ -131,21 +134,25 @@ Renderer::Renderer( SceneGraph::RenderDataProvider* dataProvider,
                     bool preMultipliedAlphaEnabled,
                     DepthWriteMode::Type depthWriteMode,
                     DepthTestMode::Type depthTestMode,
-                    DepthFunction::Type depthFunction )
+                    DepthFunction::Type depthFunction,
+                    StencilParameters& stencilParameters,
+                    bool writeToColorBuffer )
 : mRenderDataProvider( dataProvider ),
-  mContext(NULL),
+  mContext( NULL),
   mTextureCache( NULL ),
   mUniformNameCache( NULL ),
   mGeometry( geometry ),
   mUniformIndexMap(),
   mAttributesLocation(),
+  mStencilParameters( stencilParameters ),
   mBlendingOptions(),
-  mFaceCullingMode( faceCullingMode ),
-  mDepthFunction( depthFunction ),
   mIndexedDrawFirstElement( 0 ),
   mIndexedDrawElementsCount( 0 ),
+  mDepthFunction( depthFunction ),
+  mFaceCullingMode( faceCullingMode ),
   mDepthWriteMode( depthWriteMode ),
   mDepthTestMode( depthTestMode ),
+  mWriteToColorBuffer( writeToColorBuffer ),
   mUpdateAttributesLocation( true ),
   mPremultipledAlphaEnabled( preMultipliedAlphaEnabled )
 {
@@ -475,6 +482,96 @@ DepthFunction::Type Renderer::GetDepthFunction() const
   return mDepthFunction;
 }
 
+void Renderer::SetStencilMode( StencilMode::Type stencilMode )
+{
+  mStencilParameters.stencilMode = stencilMode;
+}
+
+StencilMode::Type Renderer::GetStencilMode() const
+{
+  return mStencilParameters.stencilMode;
+}
+
+void Renderer::SetStencilFunction( StencilFunction::Type stencilFunction )
+{
+  mStencilParameters.stencilFunction = stencilFunction;
+}
+
+StencilFunction::Type Renderer::GetStencilFunction() const
+{
+  return mStencilParameters.stencilFunction;
+}
+
+void Renderer::SetStencilFunctionMask( int stencilFunctionMask )
+{
+  mStencilParameters.stencilFunctionMask = stencilFunctionMask;
+}
+
+int Renderer::GetStencilFunctionMask() const
+{
+  return mStencilParameters.stencilFunctionMask;
+}
+
+void Renderer::SetStencilFunctionReference( int stencilFunctionReference )
+{
+  mStencilParameters.stencilFunctionReference = stencilFunctionReference;
+}
+
+int Renderer::GetStencilFunctionReference() const
+{
+  return mStencilParameters.stencilFunctionReference;
+}
+
+void Renderer::SetStencilMask( int stencilMask )
+{
+  mStencilParameters.stencilMask = stencilMask;
+}
+
+int Renderer::GetStencilMask() const
+{
+  return mStencilParameters.stencilMask;
+}
+
+void Renderer::SetStencilOperationOnFail( StencilOperation::Type stencilOperationOnFail )
+{
+  mStencilParameters.stencilOperationOnFail = stencilOperationOnFail;
+}
+
+StencilOperation::Type Renderer::GetStencilOperationOnFail() const
+{
+  return mStencilParameters.stencilOperationOnFail;
+}
+
+void Renderer::SetStencilOperationOnZFail( StencilOperation::Type stencilOperationOnZFail )
+{
+  mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail;
+}
+
+StencilOperation::Type Renderer::GetStencilOperationOnZFail() const
+{
+  return mStencilParameters.stencilOperationOnZFail;
+}
+
+void Renderer::SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass )
+{
+  mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass;
+}
+
+StencilOperation::Type Renderer::GetStencilOperationOnZPass() const
+{
+  return mStencilParameters.stencilOperationOnZPass;
+}
+
+void Renderer::SetWriteToColorBuffer( bool writeToColorBuffer )
+{
+  mWriteToColorBuffer = writeToColorBuffer;
+}
+
+bool Renderer::GetWriteToColorBuffer() const
+{
+  return mWriteToColorBuffer;
+}
+
 void Renderer::Render( Context& context,
                        SceneGraph::TextureCache& textureCache,
                        BufferIndex bufferIndex,
index f766024..d7e6575 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __DALI_INTERNAL_RENDER_RENDERER_H__
-#define __DALI_INTERNAL_RENDER_RENDERER_H__
+#ifndef DALI_INTERNAL_RENDER_RENDERER_H
+#define DALI_INTERNAL_RENDER_RENDERER_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
@@ -65,6 +65,35 @@ class Renderer : public GlResourceOwner
 public:
 
   /**
+   * @brief Struct to encapsulate stencil parameters required for control of the stencil buffer.
+   */
+  struct StencilParameters
+  {
+    StencilParameters( StencilMode::Type stencilMode, StencilFunction::Type stencilFunction, int stencilFunctionMask,
+                       int stencilFunctionReference, int stencilMask, StencilOperation::Type stencilOperationOnFail,
+                       StencilOperation::Type stencilOperationOnZFail, StencilOperation::Type stencilOperationOnZPass )
+    : stencilFunctionMask      ( stencilFunctionMask      ),
+      stencilFunctionReference ( stencilFunctionReference ),
+      stencilMask              ( stencilMask              ),
+      stencilFunction          ( stencilFunction          ),
+      stencilOperationOnFail   ( stencilOperationOnFail   ),
+      stencilOperationOnZFail  ( stencilOperationOnZFail  ),
+      stencilOperationOnZPass  ( stencilOperationOnZPass  ),
+      stencilMode              ( stencilMode              )
+    {
+    }
+
+    int stencilFunctionMask;                          ///< The stencil function mask
+    int stencilFunctionReference;                     ///< The stencil function reference
+    int stencilMask;                                  ///< The stencil mask
+    StencilFunction::Type stencilFunction:3;          ///< The stencil function
+    StencilOperation::Type stencilOperationOnFail:3;  ///< The stencil operation for stencil test fail
+    StencilOperation::Type stencilOperationOnZFail:3; ///< The stencil operation for depth test fail
+    StencilOperation::Type stencilOperationOnZPass:3; ///< The stencil operation for depth test pass
+    StencilMode::Type stencilMode:2;                  ///< The stencil mode
+  };
+
+  /**
    * @copydoc Dali::Internal::GlResourceOwner::GlContextDestroyed()
    */
   void GlContextDestroyed();
@@ -85,6 +114,8 @@ public:
    * @param[in] depthWriteMode Depth buffer write mode
    * @param[in] depthTestMode Depth buffer test mode
    * @param[in] depthFunction Depth function
+   * @param[in] stencilParameters Struct containing all stencil related options
+   * @param[in] writeToColorBuffer Set to True to write to the color buffer
    */
   static Renderer* New( SceneGraph::RenderDataProvider* dataProviders,
                         Render::Geometry* geometry,
@@ -94,7 +125,9 @@ public:
                         bool preMultipliedAlphaEnabled,
                         DepthWriteMode::Type depthWriteMode,
                         DepthTestMode::Type depthTestMode,
-                        DepthFunction::Type depthFunction );
+                        DepthFunction::Type depthFunction,
+                        StencilParameters& stencilParameters,
+                        bool writeToColorBuffer );
 
   /**
    * Constructor.
@@ -107,6 +140,8 @@ public:
    * @param[in] depthWriteMode Depth buffer write mode
    * @param[in] depthTestMode Depth buffer test mode
    * @param[in] depthFunction Depth function
+   * @param[in] stencilParameters Struct containing all stencil related options
+   * @param[in] writeToColorBuffer Set to True to write to the color buffer
    */
   Renderer( SceneGraph::RenderDataProvider* dataProviders,
             Render::Geometry* geometry,
@@ -116,7 +151,9 @@ public:
             bool preMultipliedAlphaEnabled,
             DepthWriteMode::Type depthWriteMode,
             DepthTestMode::Type depthTestMode,
-            DepthFunction::Type depthFunction );
+            DepthFunction::Type depthFunction,
+            StencilParameters& stencilParameters,
+            bool writeToColorBuffer );
 
   /**
    * Change the data providers of the renderer
@@ -217,6 +254,114 @@ public:
   DepthFunction::Type GetDepthFunction() const;
 
   /**
+   * Sets the stencil mode
+   * @param[in] stencilMode The stencil function
+   */
+  void SetStencilMode( StencilMode::Type stencilMode );
+
+  /**
+   * Gets the stencil mode
+   * @return The stencil function
+   */
+  StencilMode::Type GetStencilMode() const;
+
+  /**
+   * Sets the stencil function
+   * @param[in] stencilFunction The stencil function
+   */
+  void SetStencilFunction( StencilFunction::Type stencilFunction );
+
+  /**
+   * Gets the stencil function
+   * @return The stencil function
+   */
+  StencilFunction::Type GetStencilFunction() const;
+
+  /**
+   * Sets the stencil function mask
+   * @param[in] stencilFunctionMask The stencil function mask
+   */
+  void SetStencilFunctionMask( int stencilFunctionMask );
+
+  /**
+   * Gets the stencil function mask
+   * @return The stencil function mask
+   */
+  int GetStencilFunctionMask() const;
+
+  /**
+   * Sets the stencil function reference
+   * @param[in] stencilFunctionReference The stencil function reference
+   */
+  void SetStencilFunctionReference( int stencilFunctionReference );
+
+  /**
+   * Gets the stencil function reference
+   * @return The stencil function reference
+   */
+  int GetStencilFunctionReference() const;
+
+  /**
+   * Sets the stencil mask
+   * @param[in] stencilMask The stencil mask
+   */
+  void SetStencilMask( int stencilMask );
+
+  /**
+   * Gets the stencil mask
+   * @return The stencil mask
+   */
+  int GetStencilMask() const;
+
+  /**
+   * Sets the stencil operation for when the stencil test fails
+   * @param[in] stencilOperationOnFail The stencil operation
+   */
+  void SetStencilOperationOnFail( StencilOperation::Type stencilOperationOnFail );
+
+  /**
+   * Gets the stencil operation for when the stencil test fails
+   * @return The stencil operation
+   */
+  StencilOperation::Type GetStencilOperationOnFail() const;
+
+  /**
+   * Sets the stencil operation for when the depth test fails
+   * @param[in] stencilOperationOnZFail The stencil operation
+   */
+  void SetStencilOperationOnZFail( StencilOperation::Type stencilOperationOnZFail );
+
+  /**
+   * Gets the stencil operation for when the depth test fails
+   * @return The stencil operation
+   */
+  StencilOperation::Type GetStencilOperationOnZFail() const;
+
+  /**
+   * Sets the stencil operation for when the depth test passes
+   * @param[in] stencilOperationOnZPass The stencil operation
+   */
+  void SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass );
+
+  /**
+   * Gets the stencil operation for when the depth test passes
+   * @return The stencil operation
+   */
+  StencilOperation::Type GetStencilOperationOnZPass() const;
+
+  /**
+   * Sets whether or not to write to the color buffer
+   * @param[in] writeToColorBuffer True to write to the color buffer
+   */
+  void SetWriteToColorBuffer( bool writeToColorBuffer );
+
+  /**
+   * Gets whether or not to write to the color buffer
+   * @return True to write to the color buffer
+   */
+  bool GetWriteToColorBuffer() const;
+
+  /**
    * Called to render during RenderManager::Render().
    * @param[in] context The context used for rendering
    * @param[in] textureCache The texture cache used to get textures
@@ -294,34 +439,35 @@ private:
 
   OwnerPointer< SceneGraph::RenderDataProvider > mRenderDataProvider;
 
-  Context* mContext;
-  SceneGraph::TextureCache* mTextureCache;
-  Render::UniformNameCache* mUniformNameCache;
-  Render::Geometry* mGeometry;
+  Context*                     mContext;
+  SceneGraph::TextureCache*    mTextureCache;
+  Render::UniformNameCache*    mUniformNameCache;
+  Render::Geometry*            mGeometry;
 
   struct UniformIndexMap
   {
-    unsigned int uniformIndex; // The index of the cached location in the Program
-    const PropertyInputImpl* propertyValue;
+    unsigned int               uniformIndex;  ///< The index of the cached location in the Program
+    const PropertyInputImpl*   propertyValue;
   };
 
   typedef Dali::Vector< UniformIndexMap > UniformIndexMappings;
-  UniformIndexMappings mUniformIndexMap;
-
-  Vector<GLint> mAttributesLocation;
-
-  BlendingOptions       mBlendingOptions; /// Blending options including blend color, blend func and blend equation
-  FaceCullingMode::Type mFaceCullingMode; /// Mode of face culling
-  DepthFunction::Type   mDepthFunction;   /// Depth function
-
-  size_t mIndexedDrawFirstElement;        /// Offset of first element to draw
-  size_t mIndexedDrawElementsCount;       /// Number of elements to draw
-
-  DepthWriteMode::Type mDepthWriteMode:2; /// Depth write mode
-  DepthTestMode::Type mDepthTestMode:2;   /// Depth test mode
-
-  bool mUpdateAttributesLocation:1;       ///< Indicates attribute locations have changed
-  bool mPremultipledAlphaEnabled:1;       ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
+  UniformIndexMappings         mUniformIndexMap;
+  Vector<GLint>                mAttributesLocation;
+
+  StencilParameters            mStencilParameters;          ///< Struct containing all stencil related options
+  BlendingOptions              mBlendingOptions;            ///< Blending options including blend color, blend func and blend equation
+
+  size_t                       mIndexedDrawFirstElement;    ///< Offset of first element to draw
+  size_t                       mIndexedDrawElementsCount;   ///< Number of elements to draw
+
+  DepthFunction::Type          mDepthFunction:3;            ///< The depth function
+  FaceCullingMode::Type        mFaceCullingMode:2;          ///< The mode of face culling
+  BlendMode::Type              mBlendMode:2;                ///< The mode of blending
+  DepthWriteMode::Type         mDepthWriteMode:2;           ///< The depth write mode
+  DepthTestMode::Type          mDepthTestMode:2;            ///< The depth test mode
+  bool                         mWriteToColorBuffer:1;       ///< True if we are writing to the color buffer
+  bool                         mUpdateAttributesLocation:1; ///< Indicates attribute locations have changed
+  bool                         mPremultipledAlphaEnabled:1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
 };
 
 } // namespace SceneGraph
@@ -330,4 +476,4 @@ private:
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_RENDER_RENDERER_H__
+#endif // DALI_INTERNAL_RENDER_RENDERER_H
index 636e645..2fd1cfb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
 // CLASS HEADER
 #include "scene-graph-renderer.h"
 
-// INTERNAL HEADERS
+// INTERNAL INCLUDES
 #include <dali/internal/update/controllers/scene-controller.h>
 #include <dali/internal/render/renderers/render-geometry.h>
 #include <dali/internal/update/controllers/render-message-dispatcher.h>
 #include <dali/internal/update/rendering/scene-graph-texture-set.h>
 #include <dali/internal/render/shaders/scene-graph-shader.h>
-#include <dali/internal/render/renderers/render-renderer.h>
 #include <dali/internal/render/data-providers/node-data-provider.h>
 #include <dali/internal/update/nodes/node.h>
 #include <dali/internal/render/queue/render-queue.h>
@@ -86,10 +85,10 @@ void AddMappings( Dali::Internal::SceneGraph::CollectedUniformMap& localMap, con
   }
 }
 
-// flags for resending data to renderer
+// Flags for re-sending data to renderer.
 enum Flags
 {
-  RESEND_DATA_PROVIDER               = 1,
+  RESEND_DATA_PROVIDER               = 1 << 0,
   RESEND_GEOMETRY                    = 1 << 1,
   RESEND_FACE_CULLING_MODE           = 1 << 2,
   RESEND_BLEND_COLOR                 = 1 << 3,
@@ -100,9 +99,18 @@ enum Flags
   RESEND_DEPTH_WRITE_MODE            = 1 << 8,
   RESEND_DEPTH_TEST_MODE             = 1 << 9,
   RESEND_DEPTH_FUNCTION              = 1 << 10,
+  RESEND_STENCIL_MODE                = 1 << 11,
+  RESEND_STENCIL_FUNCTION            = 1 << 12,
+  RESEND_STENCIL_FUNCTION_MASK       = 1 << 13,
+  RESEND_STENCIL_FUNCTION_REFERENCE  = 1 << 14,
+  RESEND_STENCIL_MASK                = 1 << 15,
+  RESEND_STENCIL_OPERATION_ON_FAIL   = 1 << 16,
+  RESEND_STENCIL_OPERATION_ON_Z_FAIL = 1 << 17,
+  RESEND_STENCIL_OPERATION_ON_Z_PASS = 1 << 18,
+  RESEND_WRITE_TO_COLOR_BUFFER       = 1 << 19
 };
 
-}
+} // Anonymous namespace
 
 namespace Dali
 {
@@ -123,6 +131,7 @@ Renderer::Renderer()
   mGeometry( NULL ),
   mShader( NULL ),
   mBlendColor( NULL ),
+  mStencilParameters( StencilMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP ),
   mIndexedDrawFirstElement( 0u ),
   mIndexedDrawElementsCount( 0u ),
   mBlendBitmask( 0u ),
@@ -133,6 +142,7 @@ Renderer::Renderer()
   mBlendMode( BlendMode::AUTO ),
   mDepthWriteMode( DepthWriteMode::AUTO ),
   mDepthTestMode( DepthTestMode::AUTO ),
+  mWriteToColorBuffer( true ),
   mResourcesReady( false ),
   mFinishedResourceAcquisition( false ),
   mPremultipledAlphaEnabled( false ),
@@ -303,6 +313,69 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex )
       new (slot) DerivedType( mRenderer, &Render::Renderer::SetDepthFunction, mDepthFunction );
     }
 
+    if( mResendFlag & RESEND_STENCIL_MODE )
+    {
+      typedef MessageValue1< Render::Renderer, StencilMode::Type > DerivedType;
+      unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
+      new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilMode, mStencilParameters.stencilMode );
+    }
+
+    if( mResendFlag & RESEND_STENCIL_FUNCTION )
+    {
+      typedef MessageValue1< Render::Renderer, StencilFunction::Type > DerivedType;
+      unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
+      new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilFunction, mStencilParameters.stencilFunction );
+    }
+
+    if( mResendFlag & RESEND_STENCIL_FUNCTION_MASK )
+    {
+      typedef MessageValue1< Render::Renderer, int > DerivedType;
+      unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
+      new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilFunctionMask, mStencilParameters.stencilFunctionMask );
+    }
+
+    if( mResendFlag & RESEND_STENCIL_FUNCTION_REFERENCE )
+    {
+      typedef MessageValue1< Render::Renderer, int > DerivedType;
+      unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
+      new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilFunctionReference, mStencilParameters.stencilFunctionReference );
+    }
+
+    if( mResendFlag & RESEND_STENCIL_MASK )
+    {
+      typedef MessageValue1< Render::Renderer, int > DerivedType;
+      unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
+      new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilMask, mStencilParameters.stencilMask );
+    }
+
+    if( mResendFlag & RESEND_STENCIL_OPERATION_ON_FAIL )
+    {
+      typedef MessageValue1< Render::Renderer, StencilOperation::Type > DerivedType;
+      unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
+      new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilOperationOnFail, mStencilParameters.stencilOperationOnFail );
+    }
+
+    if( mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_FAIL )
+    {
+      typedef MessageValue1< Render::Renderer, StencilOperation::Type > DerivedType;
+      unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
+      new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilOperationOnZFail, mStencilParameters.stencilOperationOnZFail );
+    }
+
+    if( mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_PASS )
+    {
+      typedef MessageValue1< Render::Renderer, StencilOperation::Type > DerivedType;
+      unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
+      new (slot) DerivedType( mRenderer, &Render::Renderer::SetStencilOperationOnZPass, mStencilParameters.stencilOperationOnZPass );
+    }
+
+    if( mResendFlag & RESEND_WRITE_TO_COLOR_BUFFER )
+    {
+      typedef MessageValue1< Render::Renderer, bool > DerivedType;
+      unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
+      new (slot) DerivedType( mRenderer, &Render::Renderer::SetWriteToColorBuffer, mWriteToColorBuffer );
+    }
+
     mResendFlag = 0;
   }
 }
@@ -423,6 +496,60 @@ void Renderer::SetDepthFunction( DepthFunction::Type depthFunction )
   mResendFlag |= RESEND_DEPTH_FUNCTION;
 }
 
+void Renderer::SetStencilMode( StencilMode::Type mode )
+{
+  mStencilParameters.stencilMode = mode;
+  mResendFlag |= RESEND_STENCIL_MODE;
+}
+
+void Renderer::SetStencilFunction( StencilFunction::Type stencilFunction )
+{
+  mStencilParameters.stencilFunction = stencilFunction;
+  mResendFlag |= RESEND_STENCIL_FUNCTION;
+}
+
+void Renderer::SetStencilFunctionMask( int stencilFunctionMask )
+{
+  mStencilParameters.stencilFunctionMask = stencilFunctionMask;
+  mResendFlag |= RESEND_STENCIL_FUNCTION_MASK;
+}
+
+void Renderer::SetStencilFunctionReference( int stencilFunctionReference )
+{
+  mStencilParameters.stencilFunctionReference = stencilFunctionReference;
+  mResendFlag |= RESEND_STENCIL_FUNCTION_REFERENCE;
+}
+
+void Renderer::SetStencilMask( int stencilMask )
+{
+  mStencilParameters.stencilMask = stencilMask;
+  mResendFlag |= RESEND_STENCIL_MASK;
+}
+
+void Renderer::SetStencilOperationOnFail( StencilOperation::Type stencilOperationOnFail )
+{
+  mStencilParameters.stencilOperationOnFail = stencilOperationOnFail;
+  mResendFlag |= RESEND_STENCIL_OPERATION_ON_FAIL;
+}
+
+void Renderer::SetStencilOperationOnZFail( StencilOperation::Type stencilOperationOnZFail )
+{
+  mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail;
+  mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_FAIL;
+}
+
+void Renderer::SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass )
+{
+  mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass;
+  mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_PASS;
+}
+
+void Renderer::SetWriteToColorBuffer( bool writeToColorBuffer )
+{
+  mWriteToColorBuffer = writeToColorBuffer;
+  mResendFlag |= RESEND_WRITE_TO_COLOR_BUFFER;
+}
+
 //Called when SceneGraph::Renderer is added to update manager ( that happens when an "event-thread renderer" is created )
 void Renderer::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
 {
@@ -430,13 +557,9 @@ void Renderer::ConnectToSceneGraph( SceneController& sceneController, BufferInde
   mSceneController = &sceneController;
   RenderDataProvider* dataProvider = NewRenderDataProvider();
 
-  mRenderer = Render::Renderer::New( dataProvider, mGeometry,
-                                     mBlendBitmask, mBlendColor,
-                                     static_cast< FaceCullingMode::Type >( mFaceCullingMode ),
-                                     mPremultipledAlphaEnabled,
-                                     mDepthWriteMode,
-                                     mDepthTestMode,
-                                     mDepthFunction );
+  mRenderer = Render::Renderer::New( dataProvider, mGeometry, mBlendBitmask, mBlendColor, static_cast< FaceCullingMode::Type >( mFaceCullingMode ),
+                                         mPremultipledAlphaEnabled, mDepthWriteMode, mDepthTestMode, mDepthFunction, mStencilParameters, mWriteToColorBuffer );
+
   mSceneController->GetRenderMessageDispatcher().AddRenderer( *mRenderer );
 }
 
index 030d25f..4249b0f 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef DALI_INTERNAL_SCENE_GRAPH_RENDERER2_H
-#define DALI_INTERNAL_SCENE_GRAPH_RENDERER2_H
+#ifndef DALI_INTERNAL_SCENE_GRAPH_RENDERER_H
+#define DALI_INTERNAL_SCENE_GRAPH_RENDERER_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
@@ -17,7 +17,6 @@
  * limitations under the License.
  */
 
-
 #include <dali/public-api/rendering/geometry.h>
 #include <dali/public-api/rendering/renderer.h> // Dali::Renderer
 #include <dali/internal/common/blending-options.h>
@@ -27,6 +26,7 @@
 #include <dali/internal/update/common/uniform-map.h>
 #include <dali/internal/update/common/scene-graph-connection-change-propagator.h>
 #include <dali/internal/render/data-providers/render-data-provider.h>
+#include <dali/internal/render/renderers/render-renderer.h>
 
 namespace Dali
 {
@@ -162,7 +162,6 @@ public:
 
   /**
    * @brief Set whether the Pre-multiplied Alpha Blending is required
-   *
    * @param[in] preMultipled whether alpha is pre-multiplied.
    */
   void EnablePreMultipliedAlpha( bool preMultipled );
@@ -186,6 +185,60 @@ public:
   void SetDepthFunction( DepthFunction::Type depthFunction );
 
   /**
+   * Sets the stencil mode
+   * @param[in] mode The stencil function
+   */
+  void SetStencilMode( StencilMode::Type mode );
+
+  /**
+   * Sets the stencil function
+   * @param[in] stencilFunction The stencil function
+   */
+  void SetStencilFunction( StencilFunction::Type stencilFunction );
+
+  /**
+   * Sets the stencil function mask
+   * @param[in] stencilFunctionMask The stencil function mask
+   */
+  void SetStencilFunctionMask( int stencilFunctionMask );
+
+  /**
+   * Sets the stencil function reference
+   * @param[in] stencilFunctionReference The stencil function reference
+   */
+  void SetStencilFunctionReference( int stencilFunctionReference );
+
+  /**
+   * Sets the stencil mask
+   * @param[in] stencilMask The stencil mask
+   */
+  void SetStencilMask( int stencilMask );
+
+  /**
+   * Sets the stencil operation for when the stencil test fails
+   * @param[in] stencilOperationOnFail The stencil operation
+   */
+  void SetStencilOperationOnFail( StencilOperation::Type stencilOperationOnFail );
+
+  /**
+   * Sets the stencil operation for when the depth test fails
+   * @param[in] stencilOperationOnZFail The stencil operation
+   */
+  void SetStencilOperationOnZFail( StencilOperation::Type stencilOperationOnZFail );
+
+  /**
+   * Sets the stencil operation for when the depth test passes
+   * @param[in] stencilOperationOnZPass The stencil operation
+   */
+  void SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass );
+
+  /**
+   * Sets whether or not to write to the color buffer
+   * @param[in] writeToColorBuffer True to write to the color buffer
+   */
+  void SetWriteToColorBuffer( bool writeToColorBuffer );
+
+  /**
    * Prepare the object for rendering.
    * This is called by the UpdateManager when an object is due to be rendered in the current frame.
    * @param[in] updateBufferIndex The current update buffer index.
@@ -307,34 +360,37 @@ private:
 
 private:
 
-  CollectedUniformMap   mCollectedUniformMap[2];        ///< Uniform maps collected by the renderer
-  SceneController*      mSceneController;               ///< Used for initializing renderers
-  Render::Renderer*     mRenderer;                      ///< Raw pointer to the renderer (that's owned by RenderManager)
-  TextureSet*           mTextureSet;                    ///< The texture set this renderer uses. (Not owned)
-  Render::Geometry*     mGeometry;                      ///< The geometry this renderer uses. (Not owned)
-  Shader*               mShader;                        ///< The shader this renderer uses. (Not owned)
-  Vector4*              mBlendColor;                    ///< The blend color for blending operation
-
-  size_t                mIndexedDrawFirstElement;       ///< first element index to be drawn using indexed draw
-  size_t                mIndexedDrawElementsCount;      ///< number of elements to be drawn using indexed draw
-  unsigned int          mBlendBitmask;                  ///< The bitmask of blending options
-  unsigned int          mRegenerateUniformMap;          ///< 2 if the map should be regenerated, 1 if it should be copied.
-  unsigned short        mResendFlag;                    ///< Indicate whether data should be resent to the renderer
-
-  DepthFunction::Type   mDepthFunction:3;               ///< The depth function
-  FaceCullingMode::Type mFaceCullingMode:2;             ///< The mode of face culling
-  BlendMode::Type       mBlendMode:2;                   ///< The mode of blending
-  DepthWriteMode::Type  mDepthWriteMode:2;              ///< The depth write mode
-  DepthTestMode::Type   mDepthTestMode:2;               ///< The depth test mode
-
-  bool                  mUniformMapChanged[2];          ///< Records if the uniform map has been altered this frame
-  bool                  mResourcesReady;                ///< Set during the Update algorithm; true if the renderer has resources ready for the current frame.
-  bool                  mFinishedResourceAcquisition;   ///< Set during DoPrepareResources; true if ready & all resource acquisition has finished (successfully or otherwise)
-  bool                  mPremultipledAlphaEnabled:1;    ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
+  CollectedUniformMap          mCollectedUniformMap[2];           ///< Uniform maps collected by the renderer
+  SceneController*             mSceneController;                  ///< Used for initializing renderers
+  Render::Renderer*            mRenderer;                         ///< Raw pointer to the renderer (that's owned by RenderManager)
+  TextureSet*                  mTextureSet;                       ///< The texture set this renderer uses. (Not owned)
+  Render::Geometry*            mGeometry;                         ///< The geometry this renderer uses. (Not owned)
+  Shader*                      mShader;                           ///< The shader this renderer uses. (Not owned)
+  Vector4*                     mBlendColor;                       ///< The blend color for blending operation
+
+  Render::Renderer::StencilParameters mStencilParameters;         ///< Struct containing all stencil related options
+
+  size_t                       mIndexedDrawFirstElement;          ///< first element index to be drawn using indexed draw
+  size_t                       mIndexedDrawElementsCount;         ///< number of elements to be drawn using indexed draw
+  unsigned int                 mBlendBitmask;                     ///< The bitmask of blending options
+  unsigned int                 mRegenerateUniformMap;             ///< 2 if the map should be regenerated, 1 if it should be copied.
+  unsigned int                 mResendFlag;                       ///< Indicate whether data should be resent to the renderer
+
+  DepthFunction::Type          mDepthFunction:3;                  ///< Local copy of the depth function
+  FaceCullingMode::Type        mFaceCullingMode:2;                ///< Local copy of the mode of face culling
+  BlendMode::Type              mBlendMode:2;                      ///< Local copy of the mode of blending
+  DepthWriteMode::Type         mDepthWriteMode:2;                 ///< Local copy of the depth write mode
+  DepthTestMode::Type          mDepthTestMode:2;                  ///< Local copy of the depth test mode
+  bool                         mWriteToColorBuffer:1;             ///< Local copy of the write to color buffer flag
+
+  bool                         mUniformMapChanged[2];             ///< Records if the uniform map has been altered this frame
+  bool                         mResourcesReady;                   ///< Set during the Update algorithm; true if the renderer has resources ready for the current frame.
+  bool                         mFinishedResourceAcquisition;      ///< Set during DoPrepareResources; true if ready & all resource acquisition has finished (successfully or otherwise)
+  bool                         mPremultipledAlphaEnabled:1;       ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
 
 public:
 
-  int                   mDepthIndex;                    ///< Used only in PrepareRenderInstructions
+  int                          mDepthIndex;                       ///< Used only in PrepareRenderInstructions
 };
 
 
@@ -483,6 +539,96 @@ inline void SetDepthFunctionMessage( EventThreadServices& eventThreadServices, c
   new (slot) LocalType( &renderer, &Renderer::SetDepthFunction, depthFunction );
 }
 
+inline void SetStencilModeMessage( EventThreadServices& eventThreadServices, const Renderer& renderer, StencilMode::Type mode )
+{
+  typedef MessageValue1< Renderer, StencilMode::Type > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+
+  new (slot) LocalType( &renderer, &Renderer::SetStencilMode, mode );
+}
+
+inline void SetStencilFunctionMessage( EventThreadServices& eventThreadServices, const Renderer& renderer, StencilFunction::Type stencilFunction )
+{
+  typedef MessageValue1< Renderer, StencilFunction::Type > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+
+  new (slot) LocalType( &renderer, &Renderer::SetStencilFunction, stencilFunction );
+}
+
+inline void SetStencilFunctionMaskMessage( EventThreadServices& eventThreadServices, const Renderer& renderer, int mask )
+{
+  typedef MessageValue1< Renderer, int > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+
+  new (slot) LocalType( &renderer, &Renderer::SetStencilFunctionMask, mask );
+}
+
+inline void SetStencilFunctionReferenceMessage( EventThreadServices& eventThreadServices, const Renderer& renderer, int stencilFunctionReference )
+{
+  typedef MessageValue1< Renderer, int > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+
+  new (slot) LocalType( &renderer, &Renderer::SetStencilFunctionReference, stencilFunctionReference );
+}
+
+inline void SetStencilMaskMessage( EventThreadServices& eventThreadServices, const Renderer& renderer, int stencilMask )
+{
+  typedef MessageValue1< Renderer, int > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+
+  new (slot) LocalType( &renderer, &Renderer::SetStencilMask, stencilMask );
+}
+
+inline void SetStencilOperationOnFailMessage( EventThreadServices& eventThreadServices, const Renderer& renderer, StencilOperation::Type stencilOperation )
+{
+  typedef MessageValue1< Renderer, StencilOperation::Type > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+
+  new (slot) LocalType( &renderer, &Renderer::SetStencilOperationOnFail, stencilOperation );
+}
+
+inline void SetStencilOperationOnZFailMessage( EventThreadServices& eventThreadServices, const Renderer& renderer, StencilOperation::Type stencilOperation )
+{
+  typedef MessageValue1< Renderer, StencilOperation::Type > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+
+  new (slot) LocalType( &renderer, &Renderer::SetStencilOperationOnZFail, stencilOperation );
+}
+
+inline void SetStencilOperationOnZPassMessage( EventThreadServices& eventThreadServices, const Renderer& renderer, StencilOperation::Type stencilOperation )
+{
+  typedef MessageValue1< Renderer, StencilOperation::Type > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+
+  new (slot) LocalType( &renderer, &Renderer::SetStencilOperationOnZPass, stencilOperation );
+}
+
+inline void SetWriteToColorBufferMessage( EventThreadServices& eventThreadServices, const Renderer& renderer, bool writeToColorBuffer )
+{
+  typedef MessageValue1< Renderer, bool > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+
+  new (slot) LocalType( &renderer, &Renderer::SetWriteToColorBuffer, writeToColorBuffer );
+}
+
 } // namespace SceneGraph
 } // namespace Internal
 } // namespace Dali
index 3b5d7d0..9c06ea3 100644 (file)
@@ -41,9 +41,9 @@ namespace FaceCullingMode
  */
 enum Type
 {
-  NONE,                ///< None of the faces should be culled               @SINCE_1_1.43
-  FRONT,               ///< Cull front face, back face should never be shown @SINCE_1_1.43
-  BACK,                ///< Cull back face, back face should never be shown  @SINCE_1_1.43
+  NONE,                ///< None of the faces should be culled                 @SINCE_1_1.43
+  FRONT,               ///< Cull front face, front faces should never be shown @SINCE_1_1.43
+  BACK,                ///< Cull back face, back faces should never be shown   @SINCE_1_1.43
   FRONT_AND_BACK,      ///< Cull front and back faces; if the geometry is composed of triangles none of the faces will be shown @SINCE_1_1.43
 };