+
+/**
+ * @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( TestApplication& application, Renderer& renderer, Property::Index propertyIndex, T initialValue, T firstCheckEnumeration, T secondCheckEnumeration, std::string secondCheckString )
+{
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK( renderer.GetProperty<int>( propertyIndex ) == static_cast<int>( initialValue ) );
+ DALI_TEST_CHECK( renderer.GetCurrentProperty< int >( propertyIndex ) == static_cast<int>( initialValue ) );
+ renderer.SetProperty( propertyIndex, firstCheckEnumeration );
+ DALI_TEST_CHECK( renderer.GetProperty<int>( propertyIndex ) == static_cast<int>( firstCheckEnumeration ) );
+ DALI_TEST_CHECK( renderer.GetCurrentProperty< int >( propertyIndex ) != static_cast<int>( firstCheckEnumeration ) );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK( renderer.GetProperty<int>( propertyIndex ) == static_cast<int>( firstCheckEnumeration ) );
+ DALI_TEST_CHECK( renderer.GetCurrentProperty< int >( propertyIndex ) == static_cast<int>( firstCheckEnumeration ) );
+
+ renderer.SetProperty( propertyIndex, secondCheckString );
+ DALI_TEST_CHECK( renderer.GetProperty<int>( propertyIndex ) == static_cast<int>( secondCheckEnumeration ) );
+ DALI_TEST_CHECK( renderer.GetCurrentProperty< int >( propertyIndex ) != static_cast<int>( secondCheckEnumeration ) );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK( renderer.GetProperty<int>( propertyIndex ) == static_cast<int>( secondCheckEnumeration ) );
+ DALI_TEST_CHECK( renderer.GetCurrentProperty< 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 );
+
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+ actor.SetSize(400, 400);
+ Stage::GetCurrent().Add(actor);
+
+ /*
+ * 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 >( application, renderer, Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::NONE, FaceCullingMode::FRONT, FaceCullingMode::BACK, "BACK" );
+ CheckEnumerationProperty< BlendMode::Type >( application, renderer, Renderer::Property::BLEND_MODE, BlendMode::AUTO, BlendMode::OFF, BlendMode::ON, "ON" );
+ CheckEnumerationProperty< BlendEquation::Type >( application, renderer, Renderer::Property::BLEND_EQUATION_RGB, BlendEquation::ADD, BlendEquation::SUBTRACT, BlendEquation::REVERSE_SUBTRACT, "REVERSE_SUBTRACT" );
+ CheckEnumerationProperty< BlendEquation::Type >( application, renderer, Renderer::Property::BLEND_EQUATION_ALPHA, BlendEquation::ADD, BlendEquation::SUBTRACT, BlendEquation::REVERSE_SUBTRACT, "REVERSE_SUBTRACT" );
+ CheckEnumerationProperty< BlendFactor::Type >( application, renderer, Renderer::Property::BLEND_FACTOR_SRC_RGB, BlendFactor::SRC_ALPHA, BlendFactor::ONE, BlendFactor::SRC_COLOR, "SRC_COLOR" );
+ CheckEnumerationProperty< BlendFactor::Type >( application, renderer, Renderer::Property::BLEND_FACTOR_DEST_RGB, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::ONE, BlendFactor::SRC_COLOR, "SRC_COLOR" );
+ CheckEnumerationProperty< BlendFactor::Type >( application, renderer, Renderer::Property::BLEND_FACTOR_SRC_ALPHA, BlendFactor::ONE, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::SRC_COLOR, "SRC_COLOR" );
+ CheckEnumerationProperty< BlendFactor::Type >( application, renderer, Renderer::Property::BLEND_FACTOR_DEST_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::ONE, BlendFactor::SRC_COLOR, "SRC_COLOR" );
+ CheckEnumerationProperty< DepthWriteMode::Type >( application, renderer, Renderer::Property::DEPTH_WRITE_MODE, DepthWriteMode::AUTO, DepthWriteMode::OFF, DepthWriteMode::ON, "ON" );
+ CheckEnumerationProperty< DepthFunction::Type >( application, renderer, Renderer::Property::DEPTH_FUNCTION, DepthFunction::LESS, DepthFunction::ALWAYS, DepthFunction::GREATER, "GREATER" );
+ CheckEnumerationProperty< DepthTestMode::Type >( application, renderer, Renderer::Property::DEPTH_TEST_MODE, DepthTestMode::AUTO, DepthTestMode::OFF, DepthTestMode::ON, "ON" );
+ CheckEnumerationProperty< StencilFunction::Type >( application, renderer, Renderer::Property::STENCIL_FUNCTION, StencilFunction::ALWAYS, StencilFunction::LESS, StencilFunction::EQUAL, "EQUAL" );
+ CheckEnumerationProperty< RenderMode::Type >( application, renderer, Renderer::Property::RENDER_MODE, RenderMode::AUTO, RenderMode::NONE, RenderMode::STENCIL, "STENCIL" );
+ CheckEnumerationProperty< StencilOperation::Type >( application, renderer, Renderer::Property::STENCIL_OPERATION_ON_FAIL, StencilOperation::KEEP, StencilOperation::REPLACE, StencilOperation::INCREMENT, "INCREMENT" );
+ CheckEnumerationProperty< StencilOperation::Type >( application, renderer, Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL, StencilOperation::KEEP, StencilOperation::REPLACE, StencilOperation::INCREMENT, "INCREMENT" );
+ CheckEnumerationProperty< StencilOperation::Type >( application, 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_UI.
+ // Note this will also disable depth testing for the layer by default, we test this first.
+ Stage::GetCurrent().GetRootLayer().SetBehavior( Layer::LAYER_UI );
+
+ 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 );
+ // Set a different stencil function as the last one is cached.
+ renderer.SetProperty( Renderer::Property::STENCIL_FUNCTION, StencilFunction::ALWAYS );
+ 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 );
+
+ DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetCurrentProperty( Renderer::Property::STENCIL_FUNCTION_REFERENCE ).Get<int>() ), testValueReference, TEST_LOCATION );
+
+ 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 );
+
+ DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetCurrentProperty( Renderer::Property::STENCIL_FUNCTION_MASK ).Get<int>() ), testValueMask, TEST_LOCATION );
+
+ // 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::KEEP );
+ 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 )
+ */
+ std::string methodString( "StencilOp" );
+
+ for( int i = 0; i < StencilOperationLookupTableCount; ++i )
+ {
+ for( int j = 0; j < StencilOperationLookupTableCount; ++j )
+ {
+ for( int k = 0; k < StencilOperationLookupTableCount; ++k )
+ {
+ // Set the property (outer loop causes all 3 different properties to be set separately).
+ renderer.SetProperty( Renderer::Property::STENCIL_OPERATION_ON_FAIL, static_cast<Dali::StencilFunction::Type>( i ) );
+ renderer.SetProperty( Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL, static_cast<Dali::StencilFunction::Type>( j ) );
+ renderer.SetProperty( Renderer::Property::STENCIL_OPERATION_ON_Z_PASS, static_cast<Dali::StencilFunction::Type>( k ) );
+
+ // Check GetProperty returns the same value.
+ DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_OPERATION_ON_FAIL ).Get<int>() ), i, TEST_LOCATION );
+ DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL ).Get<int>() ), j, TEST_LOCATION );
+ DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetProperty( Renderer::Property::STENCIL_OPERATION_ON_Z_PASS ).Get<int>() ), k, 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[ 0u ] = StencilOperationLookupTable[ i ];
+ parameters[ 1u ] = StencilOperationLookupTable[ j ];
+ parameters[ 2u ] = StencilOperationLookupTable[ k ];
+
+ // 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 );
+
+ DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetCurrentProperty( Renderer::Property::STENCIL_MASK ).Get<int>() ), 0x00, TEST_LOCATION );
+
+ 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 );
+
+ DALI_TEST_EQUALS<int>( static_cast<int>( renderer.GetCurrentProperty( Renderer::Property::STENCIL_MASK ).Get<int>() ), 0xFF, TEST_LOCATION );
+
+ parameterString = "255";
+
+ // Check the function was called and the parameters were correct.
+ DALI_TEST_CHECK( glStencilFunctionStack.FindMethodAndParams( methodString, parameterString ) );
+
+ END_TEST;
+}
+
+int UtcDaliRendererWrongNumberOfTextures(void)
+{
+ TestApplication application;
+ tet_infoline("Test renderer does render even if number of textures is different than active samplers in the shader");
+
+ //Create a TextureSet with 4 textures (One more texture in the texture set than active samplers)
+ //@note Shaders in the test suit have 3 active samplers. See TestGlAbstraction::GetActiveUniform()
+ Texture texture = Texture::New( TextureType::TEXTURE_2D, Pixel::RGBA8888, 64u, 64u );
+ TextureSet textureSet = CreateTextureSet();
+ textureSet.SetTexture(0, texture );
+ textureSet.SetTexture(1, texture );
+ textureSet.SetTexture(2, texture );
+ textureSet.SetTexture(3, texture );
+ Shader shader = Shader::New("VertexSource", "FragmentSource");
+ Geometry geometry = CreateQuadGeometry();
+ Renderer renderer = Renderer::New( geometry, shader );
+ renderer.SetTextures( textureSet );
+
+ Actor actor= Actor::New();
+ actor.AddRenderer(renderer);
+ actor.SetPosition(0.0f,0.0f);
+ actor.SetSize(100, 100);
+ Stage::GetCurrent().Add(actor);
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& drawTrace = gl.GetDrawTrace();
+ drawTrace.Reset();
+ drawTrace.Enable(true);
+
+ application.SendNotification();
+ application.Render(0);
+
+ //Test we do the drawcall when TextureSet has more textures than there are active samplers in the shader
+ DALI_TEST_EQUALS( drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION );
+
+ //Create a TextureSet with 1 texture (two more active samplers than texture in the texture set)
+ //@note Shaders in the test suit have 3 active samplers. See TestGlAbstraction::GetActiveUniform()
+ textureSet = CreateTextureSet();
+ renderer.SetTextures( textureSet );
+ textureSet.SetTexture(0, texture );
+ drawTrace.Reset();
+ application.SendNotification();
+ application.Render(0);
+
+ //Test we do the drawcall when TextureSet has less textures than there are active samplers in the shader.
+ DALI_TEST_EQUALS( drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliRendererOpacity(void)
+{
+ TestApplication application;
+
+ tet_infoline( "Test OPACITY property" );
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = Shader::New( "vertexSrc", "fragmentSrc" );
+ Renderer renderer = Renderer::New( geometry, shader );
+
+ Actor actor = Actor::New();
+ actor.AddRenderer( renderer );
+ actor.SetSize( 400, 400 );
+ actor.SetProperty( Actor::Property::COLOR, Vector4( 1.0f, 0.0f, 1.0f, 1.0f ) );
+ Stage::GetCurrent().Add( actor );
+
+ Property::Value value = renderer.GetProperty( DevelRenderer::Property::OPACITY );
+ float opacity;
+ DALI_TEST_CHECK( value.Get( opacity ) );
+ DALI_TEST_EQUALS( opacity, 1.0f, Dali::Math::MACHINE_EPSILON_1, TEST_LOCATION );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector4 actualValue;
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ DALI_TEST_CHECK( gl.GetUniformValue< Vector4 >( "uColor", actualValue ) );
+ DALI_TEST_EQUALS( actualValue.a, 1.0f, Dali::Math::MACHINE_EPSILON_1, TEST_LOCATION );
+
+ renderer.SetProperty( DevelRenderer::Property::OPACITY, 0.5f );
+
+ application.SendNotification();
+ application.Render();
+
+ value = renderer.GetProperty( DevelRenderer::Property::OPACITY );
+ DALI_TEST_CHECK( value.Get( opacity ) );
+ DALI_TEST_EQUALS( opacity, 0.5f, Dali::Math::MACHINE_EPSILON_1, TEST_LOCATION );
+
+ value = renderer.GetCurrentProperty( DevelRenderer::Property::OPACITY );
+ DALI_TEST_CHECK( value.Get( opacity ) );
+ DALI_TEST_EQUALS( opacity, 0.5f, Dali::Math::MACHINE_EPSILON_1, TEST_LOCATION );
+
+ DALI_TEST_CHECK( gl.GetUniformValue< Vector4 >( "uColor", actualValue ) );
+ DALI_TEST_EQUALS( actualValue.a, 0.5f, Dali::Math::MACHINE_EPSILON_1, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliRendererOpacityAnimation(void)
+{
+ TestApplication application;
+
+ tet_infoline( "Test OPACITY property animation" );
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = Shader::New( "vertexSrc", "fragmentSrc" );
+ Renderer renderer = Renderer::New( geometry, shader );
+
+ Actor actor = Actor::New();
+ actor.AddRenderer( renderer );
+ actor.SetSize( 400, 400 );
+ actor.SetProperty( Actor::Property::COLOR, Vector4( 1.0f, 0.0f, 1.0f, 1.0f ) );
+ Stage::GetCurrent().Add( actor );
+
+ application.SendNotification();
+ application.Render(0);
+
+ Property::Value value = renderer.GetProperty( DevelRenderer::Property::OPACITY );
+ float opacity;
+ DALI_TEST_CHECK( value.Get( opacity ) );
+ DALI_TEST_EQUALS( opacity, 1.0f, Dali::Math::MACHINE_EPSILON_1, TEST_LOCATION );
+
+ Animation animation = Animation::New( 1.0f );
+ animation.AnimateTo( Property( renderer, DevelRenderer::Property::OPACITY ), 0.0f );
+ animation.Play();
+
+ application.SendNotification();
+ application.Render( 1000 );
+
+ value = renderer.GetProperty( DevelRenderer::Property::OPACITY );
+ DALI_TEST_CHECK( value.Get( opacity ) );
+ DALI_TEST_EQUALS( opacity, 0.0f, Dali::Math::MACHINE_EPSILON_1, TEST_LOCATION );
+
+ // Need to clear the animation before setting the property as the animation value is baked and will override any previous setters
+ animation.Clear();
+ renderer.SetProperty( DevelRenderer::Property::OPACITY, 0.1f );
+
+ animation.AnimateBy( Property( renderer, DevelRenderer::Property::OPACITY ), 0.5f );
+ animation.Play();
+
+ application.SendNotification();
+ application.Render( 1000 );
+
+ value = renderer.GetProperty( DevelRenderer::Property::OPACITY );
+ DALI_TEST_CHECK( value.Get( opacity ) );
+ DALI_TEST_EQUALS( opacity, 0.6f, Dali::Math::MACHINE_EPSILON_1, TEST_LOCATION );
+ DALI_TEST_EQUALS( opacity, renderer.GetCurrentProperty( DevelRenderer::Property::OPACITY ).Get< float >(), Dali::Math::MACHINE_EPSILON_1, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliRendererInvalidProperty(void)
+{
+ TestApplication application;
+
+ tet_infoline( "Test invalid property" );
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = Shader::New( "vertexSrc", "fragmentSrc" );
+ Renderer renderer = Renderer::New( geometry, shader );
+
+ Actor actor = Actor::New();
+ actor.AddRenderer( renderer );
+ actor.SetSize( 400, 400 );
+ Stage::GetCurrent().Add( actor );
+
+ application.SendNotification();
+ application.Render(0);
+
+ Property::Value value = renderer.GetProperty( Renderer::Property::DEPTH_INDEX + 100 );
+ DALI_TEST_CHECK( value.GetType() == Property::Type::NONE );
+
+ value = renderer.GetCurrentProperty( Renderer::Property::DEPTH_INDEX + 100 );
+ DALI_TEST_CHECK( value.GetType() == Property::Type::NONE );
+
+ END_TEST;
+}
+
+int UtcDaliRendererRenderingBehavior(void)
+{
+ TestApplication application;
+
+ tet_infoline( "Test RENDERING_BEHAVIOR property" );
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = Shader::New( "vertexSrc", "fragmentSrc" );
+ Renderer renderer = Renderer::New( geometry, shader );
+
+ Actor actor = Actor::New();
+ actor.AddRenderer( renderer );
+ actor.SetSize( 400, 400 );
+ actor.SetProperty( Actor::Property::COLOR, Vector4( 1.0f, 0.0f, 1.0f, 1.0f ) );
+ Stage::GetCurrent().Add( actor );
+
+ Property::Value value = renderer.GetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR );
+ int renderingBehavior;
+ DALI_TEST_CHECK( value.Get( renderingBehavior ) );
+ DALI_TEST_EQUALS( static_cast< DevelRenderer::Rendering::Type >( renderingBehavior ), DevelRenderer::Rendering::IF_REQUIRED, TEST_LOCATION );
+
+ application.SendNotification();
+ application.Render();
+
+ uint32_t updateStatus = application.GetUpdateStatus();
+
+ DALI_TEST_CHECK( !( updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING ) );
+
+ renderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY );
+
+ value = renderer.GetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR );
+ DALI_TEST_CHECK( value.Get( renderingBehavior ) );
+ DALI_TEST_EQUALS( static_cast< DevelRenderer::Rendering::Type >( renderingBehavior ), DevelRenderer::Rendering::CONTINUOUSLY, TEST_LOCATION );
+
+ // Render and check the update status
+ application.SendNotification();
+ application.Render();
+
+ updateStatus = application.GetUpdateStatus();
+
+ DALI_TEST_CHECK( updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING );
+
+ value = renderer.GetCurrentProperty( DevelRenderer::Property::RENDERING_BEHAVIOR );
+ DALI_TEST_CHECK( value.Get( renderingBehavior ) );
+ DALI_TEST_EQUALS( static_cast< DevelRenderer::Rendering::Type >( renderingBehavior ), DevelRenderer::Rendering::CONTINUOUSLY, TEST_LOCATION );
+
+ // Render again and check the update status
+ application.SendNotification();
+ application.Render();
+
+ updateStatus = application.GetUpdateStatus();
+
+ DALI_TEST_CHECK( updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING );
+
+ // Change rendering behavior
+ renderer.SetProperty( DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED );
+
+ // Render and check the update status
+ application.SendNotification();
+ application.Render();
+
+ updateStatus = application.GetUpdateStatus();
+
+ DALI_TEST_CHECK( !( updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING ) );
+
+ END_TEST;
+}
+
+int UtcDaliRendererRegenerateUniformMap(void)
+{
+ TestApplication application;
+
+ tet_infoline( "Test regenerating uniform map when attaching renderer to the node" );
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = Shader::New( "vertexSrc", "fragmentSrc" );
+ Renderer renderer = Renderer::New( geometry, shader );
+
+ Actor actor = Actor::New();
+ actor.AddRenderer( renderer );
+ actor.SetSize( 400, 400 );
+ actor.SetProperty( Actor::Property::COLOR, Vector4( 1.0f, 0.0f, 1.0f, 1.0f ) );
+ Stage::GetCurrent().Add( actor );
+
+ application.SendNotification();
+ application.Render();
+
+ actor.RemoveRenderer( renderer );
+ shader = Shader::New( "vertexSrc", "fragmentSrc" );
+ shader.RegisterProperty( "opacity", 0.5f );
+ renderer.SetShader( shader );
+
+ Stage::GetCurrent().KeepRendering( 1.0f );
+
+ // Update for several frames
+ application.SendNotification();
+ application.Render();
+ application.SendNotification();
+ application.Render();
+ application.SendNotification();
+ application.Render();
+ application.SendNotification();
+ application.Render();
+
+ // Add Renderer
+ actor.AddRenderer( renderer );
+ application.SendNotification();
+ application.Render();
+
+ // Nothing to test here, the test must not crash
+ auto updateStatus = application.GetUpdateStatus();
+ DALI_TEST_CHECK( updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING );
+
+ END_TEST;
+}