From: Tom Robinson Date: Fri, 15 Jul 2016 16:57:15 +0000 (+0100) Subject: Rendering API Stencil Implementation X-Git-Tag: dali_1.1.45~9 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-core.git;a=commitdiff_plain;h=ad06250b0131a81ad28ae63c7e063f3d291d3060 Rendering API Stencil Implementation Change-Id: I802f2d0fb3a569e5f5d7159cd73d56f47874410e --- diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h b/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h index e445084..1f55977 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h @@ -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 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 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 <> diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.h b/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.h index 32375a6..137bfaf 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.h @@ -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 #include #include +#include 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 diff --git a/automated-tests/src/dali/utc-Dali-Renderer.cpp b/automated-tests/src/dali/utc-Dali-Renderer.cpp index ce5dd3f..8bf5035 100644 --- a/automated-tests/src/dali/utc-Dali-Renderer.cpp +++ b/automated-tests/src/dali/utc-Dali-Renderer.cpp @@ -19,9 +19,11 @@ #include #include #include +#include // INTERNAL INCLUDES #include +#include #include 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( static_cast( renderer.GetProperty( Renderer::Property::STENCIL_FUNCTION ).Get() ), static_cast( StencilFunction::ALWAYS ), TEST_LOCATION ); + DALI_TEST_EQUALS( static_cast( renderer.GetProperty( Renderer::Property::STENCIL_FUNCTION_MASK ).Get() ), 0xFF, TEST_LOCATION ); + DALI_TEST_EQUALS( static_cast( renderer.GetProperty( Renderer::Property::STENCIL_FUNCTION_REFERENCE ).Get() ), 0x00, TEST_LOCATION ); + DALI_TEST_EQUALS( static_cast( renderer.GetProperty( Renderer::Property::STENCIL_MASK ).Get() ), 0xFF, TEST_LOCATION ); + DALI_TEST_EQUALS( static_cast( renderer.GetProperty( Renderer::Property::STENCIL_OPERATION_ON_FAIL ).Get() ), static_cast( StencilOperation::KEEP ), TEST_LOCATION ); + DALI_TEST_EQUALS( static_cast( renderer.GetProperty( Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL ).Get() ), static_cast( StencilOperation::KEEP ), TEST_LOCATION ); + DALI_TEST_EQUALS( static_cast( renderer.GetProperty( Renderer::Property::STENCIL_OPERATION_ON_Z_PASS ).Get() ), static_cast( 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( static_cast( renderer.GetProperty( Renderer::Property::STENCIL_FUNCTION ).Get() ), static_cast( 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( i ) ); + + // Check GetProperty returns the same value. + DALI_TEST_EQUALS( static_cast( renderer.GetProperty( Renderer::Property::STENCIL_FUNCTION ).Get() ), 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( static_cast( renderer.GetProperty( Renderer::Property::STENCIL_FUNCTION_REFERENCE ).Get() ), 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( static_cast( renderer.GetProperty( Renderer::Property::STENCIL_FUNCTION_MASK ).Get() ), 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( i ) ); + + // Check GetProperty returns the same value. + DALI_TEST_EQUALS( static_cast( renderer.GetProperty( stencilOperationPropertyKeys[ parameterIndex ] ).Get() ), 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( static_cast( renderer.GetProperty( Renderer::Property::STENCIL_MASK ).Get() ), 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( static_cast( renderer.GetProperty( Renderer::Property::STENCIL_MASK ).Get() ), 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() ); + + 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( colorMaskParams.red, false, TEST_LOCATION ); + DALI_TEST_EQUALS( colorMaskParams.green, false, TEST_LOCATION ); + DALI_TEST_EQUALS( colorMaskParams.blue, false, TEST_LOCATION ); + DALI_TEST_EQUALS( 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() ); + + 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( colorMaskParamsChanged.red, true, TEST_LOCATION ); + DALI_TEST_EQUALS( colorMaskParamsChanged.green, true, TEST_LOCATION ); + DALI_TEST_EQUALS( colorMaskParamsChanged.blue, true, TEST_LOCATION ); + DALI_TEST_EQUALS( colorMaskParamsChanged.alpha, true, TEST_LOCATION ); + + END_TEST; +} diff --git a/dali/internal/common/type-abstraction-enums.h b/dali/internal/common/type-abstraction-enums.h index 3545df4..b1d44ad 100644 --- a/dali/internal/common/type-abstraction-enums.h +++ b/dali/internal/common/type-abstraction-enums.h @@ -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 diff --git a/dali/internal/event/rendering/renderer-impl.cpp b/dali/internal/event/rendering/renderer-impl.cpp index 2b80191..0bd59c7 100644 --- a/dali/internal/event/rendering/renderer-impl.cpp +++ b/dali/internal/event/rendering/renderer-impl.cpp @@ -21,11 +21,11 @@ // INTERNAL INCLUDES #include #include // Dali::Internal::ObjectHelper -#include // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END +#include // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END #include -#include -#include #include +#include +#include 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( 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( 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( 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( 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( 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 ) { } diff --git a/dali/internal/event/rendering/renderer-impl.h b/dali/internal/event/rendering/renderer-impl.h index 5019784..64d99ba 100644 --- a/dali/internal/event/rendering/renderer-impl.h +++ b/dali/internal/event/rendering/renderer-impl.h @@ -28,6 +28,7 @@ #include // Dali::Internal::Object #include // Dali::Internal::TextureSet #include // Dali::Internal::Geometry +#include // Dali::Render::Renderer::StencilParameters namespace Dali { @@ -38,7 +39,6 @@ namespace SceneGraph class Renderer; } - class Renderer; typedef IntrusivePtr 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 mTextureSetConnector; ///< Connector that holds the texture set used by this renderer - IntrusivePtr 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 mTextureSetConnector; ///< Connector that holds the texture set used by this renderer + IntrusivePtr 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 diff --git a/dali/internal/render/common/render-algorithms.cpp b/dali/internal/render/common/render-algorithms.cpp index 695a574..95c0cae 100644 --- a/dali/internal/render/common/render-algorithms.cpp +++ b/dali/internal/render/common/render-algorithms.cpp @@ -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 ); diff --git a/dali/internal/render/common/render-algorithms.h b/dali/internal/render/common/render-algorithms.h index b84d68d..a2e4c57 100644 --- a/dali/internal/render/common/render-algorithms.h +++ b/dali/internal/render/common/render-algorithms.h @@ -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 diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index 5400c12..01c03e3 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -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 - // INTERNAL INCLUDES #include #include @@ -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, diff --git a/dali/internal/render/renderers/render-renderer.h b/dali/internal/render/renderers/render-renderer.h index f766024..d7e6575 100644 --- a/dali/internal/render/renderers/render-renderer.h +++ b/dali/internal/render/renderers/render-renderer.h @@ -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 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 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 diff --git a/dali/internal/update/rendering/scene-graph-renderer.cpp b/dali/internal/update/rendering/scene-graph-renderer.cpp index 636e645..2fd1cfb 100644 --- a/dali/internal/update/rendering/scene-graph-renderer.cpp +++ b/dali/internal/update/rendering/scene-graph-renderer.cpp @@ -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. @@ -17,13 +17,12 @@ // CLASS HEADER #include "scene-graph-renderer.h" -// INTERNAL HEADERS +// INTERNAL INCLUDES #include #include #include #include #include -#include #include #include #include @@ -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 ); } diff --git a/dali/internal/update/rendering/scene-graph-renderer.h b/dali/internal/update/rendering/scene-graph-renderer.h index 030d25f..4249b0f 100644 --- a/dali/internal/update/rendering/scene-graph-renderer.h +++ b/dali/internal/update/rendering/scene-graph-renderer.h @@ -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 #include // Dali::Renderer #include @@ -27,6 +26,7 @@ #include #include #include +#include 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 diff --git a/dali/public-api/rendering/renderer.h b/dali/public-api/rendering/renderer.h index 3b5d7d0..9c06ea3 100644 --- a/dali/public-api/rendering/renderer.h +++ b/dali/public-api/rendering/renderer.h @@ -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 };