mEnableDisableTrace.Reset();
mShaderTrace.Reset();
mStencilFunctionTrace.Reset();
- mScissorTrace.Reset();
mTextureTrace.Reset();
mTexParamaterTrace.Reset();
mDrawTrace.Reset();
mScissorParams.y = y;
mScissorParams.width = width;
mScissorParams.height = height;
-
- std::stringstream out;
- out << x << ", " << y << ", " << width << ", " << height;
- TraceCallStack::NamedParams namedParams;
- namedParams["x"] = ToString( x );
- namedParams["y"] = ToString( y );
- namedParams["width"] = ToString( width );
- namedParams["height"] = ToString( height );
- mScissorTrace.PushCall( "Scissor", out.str(), namedParams );
}
inline void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
inline void ResetStencilFunctionCallStack() { mStencilFunctionTrace.Reset(); }
inline TraceCallStack& GetStencilFunctionTrace() { return mStencilFunctionTrace; }
- //Methods for Scissor verification
- inline void EnableScissorCallTrace(bool enable) { mScissorTrace.Enable(enable); }
- inline void ResetScissorCallStack() { mScissorTrace.Reset(); }
- inline TraceCallStack& GetScissorTrace() { return mScissorTrace; }
-
//Methods for Uniform function verification
inline void EnableSetUniformCallTrace(bool enable) { mSetUniformTrace.Enable(enable); }
inline void ResetSetUniformCallStack() { mSetUniformTrace.Reset(); }
TraceCallStack mDrawTrace;
TraceCallStack mDepthFunctionTrace;
TraceCallStack mStencilFunctionTrace;
- TraceCallStack mScissorTrace;
TraceCallStack mSetUniformTrace;
// Shaders & Uniforms
int UtcDaliActorPropertyClippingP(void)
{
// This test checks the clippingMode property.
- tet_infoline( "Testing Actor::Property::ClippingMode: P" );
+ tet_infoline( "Testing Actor::Property::CLIPPING_MODE P" );
TestApplication application;
Actor actor = Actor::New();
DALI_TEST_EQUALS<int>( value, ClippingMode::DISABLED, TEST_LOCATION );
}
- // Check setting the property to the stencil mode.
+ // Check setting the property.
actor.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
// Check the new value was set.
DALI_TEST_EQUALS<int>( value, ClippingMode::CLIP_CHILDREN, TEST_LOCATION );
}
- // Check setting the property to the scissor mode.
- actor.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX );
-
- // Check the new value was set.
- getValue = actor.GetProperty( Actor::Property::CLIPPING_MODE );
- getValueResult = getValue.Get( value );
- DALI_TEST_CHECK( getValueResult );
-
- if( getValueResult )
- {
- DALI_TEST_EQUALS<int>( value, ClippingMode::CLIP_TO_BOUNDING_BOX, TEST_LOCATION );
- }
END_TEST;
}
int UtcDaliActorPropertyClippingN(void)
{
// Negative test case for Clipping.
- tet_infoline( "Testing Actor::Property::ClippingMode: N" );
+ tet_infoline( "Testing Actor::Property::CLIPPING_MODE N" );
TestApplication application;
Actor actor = Actor::New();
int UtcDaliActorPropertyClippingActor(void)
{
// This test checks that an actor is correctly setup for clipping.
- tet_infoline( "Testing Actor::Property::ClippingMode: CLIP_CHILDREN actor" );
+ tet_infoline( "Testing Actor::Property::CLIPPING_MODE actor" );
TestApplication application;
TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
int UtcDaliActorPropertyClippingActorEnableThenDisable(void)
{
// This test checks that an actor is correctly setup for clipping and then correctly setup when clipping is disabled
- tet_infoline( "Testing Actor::Property::ClippingMode: CLIP_CHILDREN actor enable and then disable" );
+ tet_infoline( "Testing Actor::Property::CLIPPING_MODE actor enable and then disable" );
TestApplication application;
TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
END_TEST;
}
+
int UtcDaliActorPropertyClippingNestedChildren(void)
{
// This test checks that a hierarchy of actors are clipped correctly by
// writing to and reading from the correct bit-planes of the stencil buffer.
- tet_infoline( "Testing Actor::Property::ClippingMode: CLIP_CHILDREN nested children" );
+ tet_infoline( "Testing Actor::Property::CLIPPING_MODE nested children" );
TestApplication application;
TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
TraceCallStack& stencilTrace = glAbstraction.GetStencilFunctionTrace();
int UtcDaliActorPropertyClippingActorDrawOrder(void)
{
// This test checks that a hierarchy of actors are drawn in the correct order when clipping is enabled.
- tet_infoline( "Testing Actor::Property::ClippingMode: CLIP_CHILDREN draw order" );
+ tet_infoline( "Testing Actor::Property::CLIPPING_MODE draw order" );
TestApplication application;
TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace();
END_TEST;
}
-int UtcDaliActorPropertyScissorClippingActor(void)
-{
- // This test checks that an actor is correctly setup for clipping.
- tet_infoline( "Testing Actor::Property::ClippingMode: CLIP_TO_BOUNDING_BOX actor" );
- TestApplication application;
-
- TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
- TraceCallStack& scissorTrace = glAbstraction.GetScissorTrace();
- TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace();
-
- const Vector2 stageSize( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT );
- const Vector2 imageSize( 16.0f, 16.0f );
-
- // Create a clipping actor.
- Actor clippingActorA = CreateActorWithContent();
- // Note: Scissor coords are have flipped Y values compared with DALi's coordinate system.
- // We choose BOTTOM_LEFT to give us x=0, y=0 starting coordinates for the first test.
- clippingActorA.SetParentOrigin( ParentOrigin::BOTTOM_LEFT );
- clippingActorA.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
- clippingActorA.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX );
- Stage::GetCurrent().Add( clippingActorA );
-
- // Gather the call trace.
- GenerateTrace( application, enabledDisableTrace, scissorTrace );
-
- // Check we are writing to the color buffer.
- CheckColorMask( glAbstraction, true );
-
- // Check scissor test was enabled.
- DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParams( "Enable", "3089" ) ); // 3089 = 0xC11 (GL_SCISSOR_TEST)
-
- // Check the scissor was set, and the coordinates are correct.
- std::stringstream compareParametersString;
- compareParametersString << "0, 0, " << imageSize.x << ", " << imageSize.y;
- DALI_TEST_CHECK( scissorTrace.FindMethodAndParams( "Scissor", compareParametersString.str() ) ); // Compare with 0, 0, 16, 16
-
- clippingActorA.SetParentOrigin( ParentOrigin::TOP_RIGHT );
- clippingActorA.SetAnchorPoint( AnchorPoint::TOP_RIGHT );
-
- // Gather the call trace.
- GenerateTrace( application, enabledDisableTrace, scissorTrace );
-
- // Check the scissor was set, and the coordinates are correct.
- compareParametersString.str( std::string() );
- compareParametersString.clear();
- compareParametersString << ( stageSize.x - imageSize.x ) << ", " << ( stageSize.y - imageSize.y ) << ", " << imageSize.x << ", " << imageSize.y;
- DALI_TEST_CHECK( scissorTrace.FindMethodAndParams( "Scissor", compareParametersString.str() ) ); // Compare with 464, 784, 16, 16
-
- END_TEST;
-}
-
-int UtcDaliActorPropertyScissorClippingActorNested(void)
-{
- // This test checks that an actor is correctly setup for clipping.
- tet_infoline( "Testing Actor::Property::ClippingMode: CLIP_TO_BOUNDING_BOX actor nested" );
- TestApplication application;
-
- TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
- TraceCallStack& scissorTrace = glAbstraction.GetScissorTrace();
- TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace();
-
- const Vector2 stageSize( TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT );
- const Vector2 imageSize( 16.0f, 16.0f );
-
- /* Create a nest of 2 scissors to test nesting (intersecting clips).
-
- A is drawn first - with scissor clipping on
- B is drawn second - also with scissor clipping on
- C is the generated clipping region, the intersection ( A ∩ B )
-
- ┏━━━━━━━┓ ┌───────┐
- ┃ B ┃ │ B │
- ┌───╂┄┄┄┐ ┃ ┌┄┄┄╆━━━┓ │
- │ ┃ ┊ ┃ ━━━━━> ┊ ┃ C ┃ │
- │ ┗━━━┿━━━┛ ┊ ┗━━━╃───┘
- │ A │ ┊ A ┊
- └───────┘ └┄┄┄┄┄┄┄┘
-
- We then reposition B around each corner of A to test the 4 overlap combinations (thus testing intersecting works correctly).
- */
-
- // Create a clipping actor.
- Actor clippingActorA = CreateActorWithContent();
- // Note: Scissor coords are have flipped Y values compared with DALi's coordinate system.
- // We choose BOTTOM_LEFT to give us x=0, y=0 starting coordinates for the first test.
- clippingActorA.SetParentOrigin( ParentOrigin::CENTER );
- clippingActorA.SetAnchorPoint( AnchorPoint::CENTER );
- clippingActorA.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX );
- Stage::GetCurrent().Add( clippingActorA );
-
- // Create a child clipping actor.
- Actor clippingActorB = CreateActorWithContent();
- clippingActorB.SetParentOrigin( ParentOrigin::CENTER );
- clippingActorB.SetAnchorPoint( AnchorPoint::CENTER );
- clippingActorB.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX );
- clippingActorA.Add( clippingActorB );
-
- // positionModifiers is an array of positions to position B around.
- // expect is an array of expected scissor clip coordinate results.
- const Vector2 positionModifiers[4] = { Vector2( 1.0f, 1.0f ), Vector2( -1.0f, 1.0f ), Vector2( -1.0f, -1.0f ), Vector2( 1.0f, -1.0f ) };
- const Vector4 expect[4] = { Vector4( 240, 392, 8, 8 ), Vector4( 232, 392, 8, 8 ), Vector4( 232, 400, 8, 8 ), Vector4( 240, 400, 8, 8 ) };
-
- // Loop through each overlap combination.
- for( unsigned int test = 0u; test < 4u; ++test )
- {
- // Position the child clipping actor so it intersects with the 1st clipping actor. This changes each loop.
- const Vector2 position = ( imageSize / 2.0f ) * positionModifiers[test];
- clippingActorB.SetPosition( position.x, position.y );
-
- // Gather the call trace.
- GenerateTrace( application, enabledDisableTrace, scissorTrace );
-
- // Check we are writing to the color buffer.
- CheckColorMask( glAbstraction, true );
-
- // Check scissor test was enabled.
- DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParams( "Enable", "3089" ) ); // 3089 = 0xC11 (GL_SCISSOR_TEST)
-
- // Check the scissor was set, and the coordinates are correct.
- const Vector4& expectResults( expect[test] );
- std::stringstream compareParametersString;
- compareParametersString << expectResults.x << ", " << expectResults.y << ", " << expectResults.z << ", " << expectResults.w;
- DALI_TEST_CHECK( scissorTrace.FindMethodAndParams( "Scissor", compareParametersString.str() ) ); // Compare with the expected result
- }
-
- END_TEST;
-}
-
int UtcDaliActorPropertyClippingActorWithRendererOverride(void)
{
// This test checks that an actor with clipping will be ignored if overridden by the Renderer properties.
DALI_TEST_CHECK( !stencilTrace.FindMethod( "StencilMask" ) );
DALI_TEST_CHECK( !stencilTrace.FindMethod( "StencilOp" ) );
- // Check that scissor clipping is overriden by the renderer properties.
- TraceCallStack& scissorTrace = glAbstraction.GetScissorTrace();
-
- actorDepth1Clip.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX );
-
- // Gather the call trace.
- GenerateTrace( application, enabledDisableTrace, scissorTrace );
-
- // Check the stencil buffer was not enabled.
- DALI_TEST_CHECK( !enabledDisableTrace.FindMethodAndParams( "Enable", "3089" ) ); // 3089 = 0xC11 (GL_SCISSOR_TEST)
-
- DALI_TEST_CHECK( !scissorTrace.FindMethod( "StencilFunc" ) );
-
END_TEST;
}
// 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
+
/**
- * @brief Find the intersection of two AABB rectangles.
- * This is a logical AND operation. IE. The intersection is the area overlapped by both rectangles.
- * @param[in] aabbA Rectangle A
- * @param[in] aabbB Rectangle B
- * @return The intersection of rectangle A & B (result is a rectangle)
+ * Sets up the scissor test if required.
+ * @param[in] renderList The render list from which to get the clipping flag
+ * @param[in] context The context
*/
-inline ClippingBox IntersectAABB( const ClippingBox& aabbA, const ClippingBox& aabbB )
+inline void SetScissorTest( const RenderList& renderList, Context& context )
{
- ClippingBox intersectionBox;
-
- // First calculate the largest starting positions in X and Y.
- intersectionBox.x = std::max( aabbA.x, aabbB.x );
- intersectionBox.y = std::max( aabbA.y, aabbB.y );
-
- // Now calculate the smallest ending positions, and take the largest starting
- // positions from the result, to get the width and height respectively.
- // If the two boxes do not intersect at all, then we need a 0 width and height clipping area.
- // We use max here to clamp both width and height to >= 0 for this use-case.
- intersectionBox.width = std::max( std::min( aabbA.x + aabbA.width, aabbB.x + aabbB.width ) - intersectionBox.x, 0 );
- intersectionBox.height = std::max( std::min( aabbA.y + aabbA.height, aabbB.y + aabbB.height ) - intersectionBox.y, 0 );
+ // Scissor testing
+ if( renderList.IsClipping() )
+ {
+ context.SetScissorTest( true );
- return intersectionBox;
+ const Dali::ClippingBox& clip = renderList.GetClippingBox();
+ context.Scissor( clip.x, clip.y, clip.width, clip.height );
+ }
+ else
+ {
+ context.SetScissorTest( false );
+ }
}
/**
* @brief Set up the stencil and color buffer for automatic clipping (StencilMode::AUTO).
* @param[in] item The current RenderItem about to be rendered
* @param[in] context The context
- * @param[in/out] lastClippingDepth The stencil depth of the last renderer drawn.
+ * @param[in/out] lastStencilDepth The stencil depth of the last renderer drawn.
* @param[in/out] lastClippingId The clipping ID of the last renderer drawn.
*/
-inline void SetupStencilClipping( const RenderItem& item, Context& context, uint32_t& lastClippingDepth, uint32_t& lastClippingId )
+inline void SetupClipping( const RenderItem& item, Context& context, uint32_t& lastStencilDepth, uint32_t& lastClippingId )
{
const Dali::Internal::SceneGraph::Node* node = item.mNode;
const uint32_t clippingId = node->GetClippingId();
+
+ // Turn the color buffer on as we always want to render this renderer, regardless of clipping hierarchy.
+ context.ColorMask( true );
+
// If there is no clipping Id, then either we haven't reached a clipping Node yet, or there aren't any.
// Either way we can skip clipping setup for this renderer.
if( clippingId == 0u )
return;
}
- context.EnableStencilBuffer( true );
+ const ClippingMode::Type clippingMode( node->GetClippingMode() );
+ const uint32_t currentStencilDepth( node->GetClippingDepth() );
- const uint32_t clippingDepth = node->GetClippingDepth();
+ context.EnableStencilBuffer( true );
// Pre-calculate a mask which has all bits set up to and including the current clipping depth.
// EG. If depth is 3, the mask would be "111" in binary.
- const uint32_t currentDepthMask = ( 1u << clippingDepth ) - 1u;
+ const uint32_t currentDepthMask = ( 1u << currentStencilDepth ) - 1u;
- // Are we are writing to the stencil buffer?
- if( item.mNode->GetClippingMode() == Dali::ClippingMode::CLIP_CHILDREN )
+ // If we have a clipping mode specified, we are writing to the stencil buffer.
+ if( clippingMode != ClippingMode::DISABLED )
{
// We are writing to the stencil buffer.
// If clipping Id is 1, this is the first clipping renderer within this render-list.
context.StencilMask( 0xff );
context.Clear( GL_STENCIL_BUFFER_BIT, Context::CHECK_CACHED_VALUES );
}
- else if( ( clippingDepth < lastClippingDepth ) ||
- ( ( clippingDepth == lastClippingDepth ) && ( clippingId > lastClippingId ) ) )
+ else if( ( currentStencilDepth < lastStencilDepth ) ||
+ ( ( currentStencilDepth == lastStencilDepth ) && ( clippingId > lastClippingId ) ) )
{
// The above if() statement tests if we need to clear some (not all) stencil bit-planes.
// We need to do this if either of the following are true:
// We keep track of the last clipping Id and depth so we can determine when we are
// moving back up the scene graph and require some of the stencil bit-planes to be deleted.
- lastClippingDepth = clippingDepth;
+ lastStencilDepth = currentStencilDepth;
lastClippingId = clippingId;
// We only ever write to bit-planes up to the current depth as we may need
}
/**
- * @brief 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.
- * - If AUTO is selected for writing, the decision will be based on the items opacity.
- * @param[in] item The RenderItem to set up the depth buffer for.
- * @param[in] context The context used to execute GL commands.
- * @param[in] depthTestEnabled True if depth testing has been enabled.
- * @param[in/out] firstDepthBufferUse Initialize to true on the first call, this method will set it to false afterwards.
+ * @brief Set up the stencil and color buffer based on the current Renderers properties.
+ * @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. Used by StencilMode::ON.
+ * @param[in/out] lastStencilDepth The stencil depth of the last renderer drawn. Used by the clipping feature.
+ * @param[in/out] lastClippingId The clipping ID of the last renderer drawn. Used by the clipping feature.
*/
-inline void SetupDepthBuffer( const RenderItem& item, Context& context, bool depthTestEnabled, bool& firstDepthBufferUse )
-{
- // Set up whether or not to write to the depth buffer.
- const DepthWriteMode::Type depthWriteMode = item.mRenderer->GetDepthWriteMode();
- // Most common mode (AUTO) is tested first.
- const bool enableDepthWrite = ( ( depthWriteMode == DepthWriteMode::AUTO ) && depthTestEnabled && item.mIsOpaque ) ||
- ( depthWriteMode == DepthWriteMode::ON );
-
- // Set up whether or not to read from (test) the depth buffer.
- const DepthTestMode::Type depthTestMode = item.mRenderer->GetDepthTestMode();
- // Most common mode (AUTO) is tested first.
- const bool enableDepthTest = ( ( depthTestMode == DepthTestMode::AUTO ) && depthTestEnabled ) ||
- ( depthTestMode == DepthTestMode::ON );
-
- // Is the depth buffer in use?
- if( enableDepthWrite || enableDepthTest )
- {
- // The depth buffer must be enabled if either reading or writing.
- context.EnableDepthBuffer( true );
-
- // Set up the depth mask based on our depth write setting.
- context.DepthMask( enableDepthWrite );
-
- // Look-up the GL depth function from the Dali::DepthFunction enum, and set it.
- context.DepthFunc( DaliDepthToGLDepthTable[ item.mRenderer->GetDepthFunction() ] );
-
- // If this is the first use of the depth buffer this RenderTask, perform a clear.
- // Note: We could do this at the beginning of the RenderTask and rely on the
- // context cache to ignore the clear if not required, but, we would have to enable
- // the depth buffer to do so, which could be a redundant enable.
- if( DALI_UNLIKELY( firstDepthBufferUse ) )
- {
- // This is the first time the depth buffer is being written to or read.
- firstDepthBufferUse = false;
-
- // Note: The buffer will only be cleared if written to since a previous clear.
- context.Clear( GL_DEPTH_BUFFER_BIT, Context::CHECK_CACHED_VALUES );
- }
- }
- else
- {
- // The depth buffer is not being used by this renderer, so we must disable it to stop it being tested.
- context.EnableDepthBuffer( false );
- }
-}
-
-} // Unnamed namespace
-
-
-inline ClippingBox RenderAlgorithms::CalculateScreenSpaceAABB( const SceneGraph::RenderItem& item )
-{
- // Calculate extent vector of the AABB:
- const Vector3& actorSize = item.mSize;
- const float halfActorX = actorSize.x * 0.5f;
- const float halfActorY = actorSize.y * 0.5f;
-
- // Transform to absolute oriented bounding box.
- const Matrix& worldMatrix = item.mModelViewMatrix;
-
- // To transform the actor bounds to screen-space, We do a fast, 2D version of a matrix multiply optimized for 2D quads.
- // This reduces float multiplications from 64 (16 * 4) to 12 (4 * 3).
- // We create an array of 4 corners and directly initialize the first 3 with the matrix multiplication result of the respective corner.
- // This causes the construction of the vector arrays contents in-place for optimization.
- // We skip the 4th corner here as we can calculate that from the other 3, bypassing matrix multiplication.
- // Note: The below * operators trigger a fast (2D) matrix multiply (only 4 multiplications are done).
- Vector2 corners[4]{ worldMatrix * Vector2( -halfActorX, -halfActorY ),
- worldMatrix * Vector2( halfActorX, -halfActorY ),
- worldMatrix * Vector2( halfActorX, halfActorY ) };
-
- // As we are dealing with a rectangle, we can do a fast calculation to get the 4th corner from knowing the other 3 (even if rotated).
- corners[3] = Vector2( corners[0] + ( corners[2] - corners[1] ) );
-
- // Calculate the AABB:
- // We use knowledge that opposite corners will be the max/min of each other. Doing this reduces the normal 12 branching comparisons to 3.
- // The standard equivalent min/max code of the below would be:
- // Vector2 AABBmax( std::max( corners[0].x, std::max( corners[1].x, std::max( corners[3].x, corners[2].x ) ) ),
- // std::max( corners[0].y, std::max( corners[1].y, std::max( corners[3].y, corners[2].y ) ) ) );
- // Vector2 AABBmin( std::min( corners[0].x, std::min( corners[1].x, std::min( corners[3].x, corners[2].x ) ) ),
- // std::min( corners[0].y, std::min( corners[1].y, std::min( corners[3].y, corners[2].y ) ) ) );
- unsigned int smallestX = 0u;
- // Loop 3 times to find the index of the smallest X value.
- // Note: We deliberately do NOT unroll the code here as this hampers the compilers output.
- for( unsigned int i = 1u; i < 4u; ++i )
- {
- if( corners[i].x < corners[smallestX].x )
- {
- smallestX = i;
- }
- }
-
- // As we are dealing with a rectangle, we can assume opposite corners are the largest.
- // So without doing min/max branching, we can fetch the min/max values of all the remaining X/Y coords from this one index.
- Vector4 aabb( corners[smallestX].x, corners[( smallestX + 3u ) % 4].y, corners[( smallestX + 2u ) % 4].x, corners[( smallestX + 1u ) % 4].y );
-
- // Convert maximums to extents.
- aabb.z -= aabb.x;
- aabb.w -= aabb.y;
-
- // Return the AABB in screen-space pixels (x, y, width, height).
- // Note: This is a algebraic simplification of: ( viewport.x - aabb.width ) / 2 - ( ( aabb.width / 2 ) + aabb.x ) per axis.
- return ClippingBox( ( mViewportRectangle.width / 2 ) - aabb.z - aabb.x, ( mViewportRectangle.height / 2 ) - aabb.w - aabb.y, aabb.z, aabb.w );
-}
-
-inline void RenderAlgorithms::SetupScissorClipping( const RenderItem& item, Context& context )
-{
- // Get the number of child scissors in the stack (do not include layer or root box).
- size_t childStackDepth = mScissorStack.size() - 1u;
- const uint32_t scissorDepth = item.mNode->GetScissorDepth();
- const bool clippingNode = item.mNode->GetClippingMode() == Dali::ClippingMode::CLIP_TO_BOUNDING_BOX;
- bool traversedUpTree = false;
-
- // If we are using scissor clipping and we are at the same depth (or less), we need to undo previous clips.
- // We do this by traversing up the scissor clip stack and then apply the appropriate clip for the current render item.
- // To know this, we use clippingDepth. This value is set on *every* node, but only increased as clipping nodes are hit depth-wise.
- // So we know if we are at depth 4 and the stackDepth is 5, that we have gone up.
- // If the depth is the same then we are effectively part of a different sub-tree from the parent, we must also remove the current clip.
- // Note: Stack depth must always be at least 1, as we will have the layer or stage size as the root value.
- if( ( childStackDepth > 0u ) && ( scissorDepth < childStackDepth ) )
- {
- while( scissorDepth < childStackDepth )
- {
- mScissorStack.pop_back();
- --childStackDepth;
- }
-
- // We traversed up the tree, we need to apply a new scissor rectangle (unless we are at the root).
- traversedUpTree = true;
- }
-
- // If we are on a clipping node, or we have traveled up the tree and gone back past a clipping node, may need to apply a new scissor clip.
- if( clippingNode || traversedUpTree )
- {
- // First, check if we are a clipping node.
- if( clippingNode )
- {
- // This is a clipping node. We generate the AABB for this node and intersect it with the previous intersection further up the tree.
-
- // Get the AABB bounding box for the current render item.
- const ClippingBox scissorBox( CalculateScreenSpaceAABB( item ) );
- // Get the AABB for the parent item that we must intersect with.
- const ClippingBox& parentBox( mScissorStack.back() );
-
- // We must reduce the clipping area based on the parents area to allow nested clips. This is a set intersection function.
- // We add the new scissor box to the stack so we can return to it if needed.
- mScissorStack.emplace_back( IntersectAABB( parentBox, scissorBox ) );
- }
-
- // The scissor test is enabled if we have any children on the stack, OR, if there are none but it is a user specified layer scissor box.
- // IE. It is not enabled if we are at the top of the stack and the layer does not have a specified clipping box.
- const bool scissorEnabled = ( mScissorStack.size() > 0u ) || mHasLayerScissor;
-
- // Enable the scissor test based on the above calculation
- context.SetScissorTest( scissorEnabled );
-
- // If scissor is enabled, we use the calculated screen-space coordinates (now in the stack).
- if( scissorEnabled )
- {
- ClippingBox useScissorBox( mScissorStack.back() );
- context.Scissor( useScissorBox.x, useScissorBox.y, useScissorBox.width, useScissorBox.height );
- }
- }
-}
-
-inline void RenderAlgorithms::SetupClipping( const RenderItem& item, Context& context, bool& usedStencilBuffer, uint32_t& lastClippingDepth, uint32_t& lastClippingId )
+inline void SetupStencilBuffer( const RenderItem& item, Context& context, bool& usedStencilBuffer, uint32_t& lastStencilDepth, uint32_t& lastClippingId )
{
const Renderer *renderer = item.mRenderer;
{
case RenderMode::AUTO:
{
- // Turn the color buffer on as we always want to render this renderer, regardless of clipping hierarchy.
- context.ColorMask( true );
-
- // The automatic clipping feature will manage the scissor and stencil functions.
- // As both scissor and stencil clips can be nested, we may be simultaneously traversing up the scissor tree, requiring a scissor to be un-done. Whilst simultaneously adding a new stencil clip.
- // We process both based on our current and old clipping depths for each mode.
- // Both methods with return rapidly if there is nothing to be done for that type of clipping.
- SetupScissorClipping( item, context );
- SetupStencilClipping( item, context, lastClippingDepth, lastClippingId );
+ // The automatic clipping feature will manage the stencil functions and color buffer mask.
+ SetupClipping( item, context, lastStencilDepth, lastClippingId );
break;
}
case RenderMode::NONE:
case RenderMode::COLOR:
{
- // No clipping is performed for these modes.
- // Note: We do not turn off scissor clipping as it may be used for the whole layer.
// The stencil buffer will not be used at all.
context.EnableStencilBuffer( false );
}
}
-inline void RenderAlgorithms::ProcessRenderList(
+/**
+ * @brief 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.
+ * - If AUTO is selected for writing, the decision will be based on the items opacity.
+ * @param[in] item The RenderItem to set up the depth buffer for.
+ * @param[in] context The context used to execute GL commands.
+ * @param[in] depthTestEnabled True if depth testing has been enabled.
+ * @param[in/out] firstDepthBufferUse Initialise to true on the first call, this method will set it to false afterwards.
+ */
+inline void SetupDepthBuffer( const RenderItem& item, Context& context, bool depthTestEnabled, bool& firstDepthBufferUse )
+{
+ // Set up whether or not to write to the depth buffer.
+ const DepthWriteMode::Type depthWriteMode = item.mRenderer->GetDepthWriteMode();
+ // Most common mode (AUTO) is tested first.
+ const bool enableDepthWrite = ( ( depthWriteMode == DepthWriteMode::AUTO ) && depthTestEnabled && item.mIsOpaque ) ||
+ ( depthWriteMode == DepthWriteMode::ON );
+
+ // Set up whether or not to read from (test) the depth buffer.
+ const DepthTestMode::Type depthTestMode = item.mRenderer->GetDepthTestMode();
+ // Most common mode (AUTO) is tested first.
+ const bool enableDepthTest = ( ( depthTestMode == DepthTestMode::AUTO ) && depthTestEnabled ) ||
+ ( depthTestMode == DepthTestMode::ON );
+
+ // Is the depth buffer in use?
+ if( enableDepthWrite || enableDepthTest )
+ {
+ // The depth buffer must be enabled if either reading or writing.
+ context.EnableDepthBuffer( true );
+
+ // Set up the depth mask based on our depth write setting.
+ context.DepthMask( enableDepthWrite );
+
+ // Look-up the GL depth function from the Dali::DepthFunction enum, and set it.
+ context.DepthFunc( DaliDepthToGLDepthTable[ item.mRenderer->GetDepthFunction() ] );
+
+ // If this is the first use of the depth buffer this RenderTask, perform a clear.
+ // Note: We could do this at the beginning of the RenderTask and rely on the
+ // context cache to ignore the clear if not required, but, we would have to enable
+ // the depth buffer to do so, which could be a redundant enable.
+ if( DALI_UNLIKELY( firstDepthBufferUse ) )
+ {
+ // This is the first time the depth buffer is being written to or read.
+ firstDepthBufferUse = false;
+
+ // Note: The buffer will only be cleared if written to since a previous clear.
+ context.Clear( GL_DEPTH_BUFFER_BIT, Context::CHECK_CACHED_VALUES );
+ }
+ }
+ else
+ {
+ // The depth buffer is not being used by this renderer, so we must disable it to stop it being tested.
+ context.EnableDepthBuffer( false );
+ }
+}
+
+/**
+ * @brief Process a render-list.
+ * @param[in] renderList The render-list to process.
+ * @param[in] context The GL context.
+ * @param[in] buffer The current render buffer index (previous update buffer)
+ * @param[in] viewMatrix The view matrix from the appropriate camera.
+ * @param[in] projectionMatrix The projection matrix from the appropriate camera.
+ */
+inline void ProcessRenderList(
const RenderList& renderList,
Context& context,
BufferIndex bufferIndex,
{
DALI_PRINT_RENDER_LIST( renderList );
+ SetScissorTest( renderList, context );
+
// Note: The depth buffer is enabled or disabled on a per-renderer basis.
// Here we pre-calculate the value to use if these modes are set to AUTO.
const bool autoDepthTestMode( !( renderList.GetSourceLayer()->IsDepthTestDisabled() ) && renderList.HasColorRenderItems() );
const std::size_t count = renderList.Count();
- uint32_t lastClippingDepth( 0u );
+ uint32_t lastStencilDepth( 0u );
uint32_t lastClippingId( 0u );
bool usedStencilBuffer( false );
bool firstDepthBufferUse( true );
- mViewportRectangle = context.GetViewport();
- mHasLayerScissor = false;
-
- // Setup Scissor testing (for both viewport and per-node scissor)
- mScissorStack.clear();
- if( renderList.IsClipping() )
- {
- context.SetScissorTest( true );
- const ClippingBox& layerScissorBox = renderList.GetClippingBox();
- context.Scissor( layerScissorBox.x, layerScissorBox.y, layerScissorBox.width, layerScissorBox.height );
- mScissorStack.push_back( layerScissorBox );
- mHasLayerScissor = true;
- }
- else
- {
- // We are not performing a layer clip. Add the viewport as the root scissor rectangle.
- context.SetScissorTest( false );
- mScissorStack.push_back( mViewportRectangle );
- }
for( size_t index( 0u ); index < count; ++index )
{
// Set up the depth buffer based on per-renderer flags.
// If the per renderer flags are set to "ON" or "OFF", they will always override any Layer depth mode or
// draw-mode state, such as Overlays.
- // If the flags are set to "AUTO", the behavior then depends on the type of renderer. Overlay Renderers will always
+ // If the flags are set to "AUTO", the behaviour then depends on the type of renderer. Overlay Renderers will always
// disable depth testing and writing. Color Renderers will enable them if the Layer does.
SetupDepthBuffer( item, context, autoDepthTestMode, firstDepthBufferUse );
- // Set up clipping based on both the Renderer and Actor APIs.
+ // Set up the stencil buffer based on both the Renderer and Actor APIs.
// The Renderer API will be used if specified. If AUTO, the Actors automatic clipping feature will be used.
- SetupClipping( item, context, usedStencilBuffer, lastClippingDepth, lastClippingId );
-
- // Render the item (we skip rendering for bounding box clips).
- if( item.mNode->GetClippingMode() != ClippingMode::CLIP_TO_BOUNDING_BOX )
- {
- item.mRenderer->Render( context, bufferIndex, *item.mNode, item.mModelMatrix, item.mModelViewMatrix,
- viewMatrix, projectionMatrix, item.mSize, !item.mIsOpaque );
- }
+ SetupStencilBuffer( item, context, usedStencilBuffer, lastStencilDepth, lastClippingId );
+
+ // Render the item
+ item.mRenderer->Render( context,
+ bufferIndex,
+ *item.mNode,
+ item.mModelMatrix,
+ item.mModelViewMatrix,
+ viewMatrix,
+ projectionMatrix,
+ item.mSize,
+ !item.mIsOpaque );
}
}
-RenderAlgorithms::RenderAlgorithms()
- : mViewportRectangle(),
- mHasLayerScissor( false )
-{
-}
-
-void RenderAlgorithms::ProcessRenderInstruction( const RenderInstruction& instruction, Context& context, BufferIndex bufferIndex )
+void ProcessRenderInstruction( const RenderInstruction& instruction,
+ Context& context,
+ BufferIndex bufferIndex )
{
DALI_PRINT_RENDER_INSTRUCTION( instruction, bufferIndex );
if( renderList && !renderList->IsEmpty() )
{
- ProcessRenderList( *renderList, context, bufferIndex, *viewMatrix, *projectionMatrix );
+ ProcessRenderList( *renderList,
+ context,
+ bufferIndex,
+ *viewMatrix,
+ *projectionMatrix );
}
}
}
}
-
} // namespace Render
} // namespace Internal
#define DALI_INTERNAL_RENDER_ALGORITHMS_H
/*
- * Copyright (c) 2017 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.
// INTERNAL INCLUDES
#include <dali/internal/common/buffer-index.h>
-#include <dali/internal/render/common/render-list.h>
namespace Dali
{
-
namespace Internal
{
class Context;
namespace SceneGraph
{
class RenderInstruction;
-struct RenderItem;
+class TextureCache;
}
namespace Render
{
/**
- * @brief The responsibility of the RenderAlgorithms object is to action renders required by a RenderInstruction.
+ * Process a render-instruction.
+ * @param[in] instruction The render-instruction to process.
+ * @param[in] context The GL context.
+ * @param[in] bufferIndex The current render buffer index (previous update buffer)
*/
-class RenderAlgorithms
-{
- public:
-
- /**
- * Constructor.
- */
- RenderAlgorithms();
-
- /**
- * Process a render-instruction.
- * @param[in] instruction The render-instruction to process.
- * @param[in] context The GL context.
- * @param[in] bufferIndex The current render buffer index (previous update buffer)
- */
- void ProcessRenderInstruction( const SceneGraph::RenderInstruction& instruction, Context& context, BufferIndex bufferIndex );
-
- private:
-
- /**
- * @brief Calculate a 2D AABB (axis aligned bounding box) in screen space.
- * The RenderItems dimensions are translated and a Z value of 0 is assumed for this purpose.
- * No projection is performed, but rotation on Z is supported.
- * @param[in] item The RenderItem to generate an AABB for
- * @return The generated AABB in screen space
- */
- inline Dali::ClippingBox CalculateScreenSpaceAABB( const Dali::Internal::SceneGraph::RenderItem& item );
-
- /**
- * @brief Perform any scissor clipping related operations based on the current RenderItem.
- * This includes:
- * - Determining if any action is to be taken (so the method can be exited early if not).
- * - If the node is a clipping node, apply the nodes clip intersected with the current/parent scissor clip.
- * - If we have gone up the scissor hierarchy, and need to un-apply a scissor clip.
- * - Disable scissor clipping completely if it is not needed
- * @param[in] item The current RenderItem (about to be rendered)
- * @param[in] context The current Context
- */
- inline void SetupScissorClipping( const Dali::Internal::SceneGraph::RenderItem& item, Context& context );
-
- /**
- * @brief Set up the clipping based on the specified clipping settings.
- * @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. Used by StencilMode::ON.
- * @param[in/out] lastClippingDepth The stencil depth of the last renderer drawn. Used by the clipping feature.
- * @param[in/out] lastClippingId The clipping ID of the last renderer drawn. Used by the clipping feature.
- */
- inline void SetupClipping( const Dali::Internal::SceneGraph::RenderItem& item, Context& context, bool& usedStencilBuffer, uint32_t& lastClippingDepth, uint32_t& lastClippingId );
-
- /**
- * @brief Process a render-list.
- * @param[in] renderList The render-list to process.
- * @param[in] context The GL context.
- * @param[in] buffer The current render buffer index (previous update buffer)
- * @param[in] viewMatrix The view matrix from the appropriate camera.
- * @param[in] projectionMatrix The projection matrix from the appropriate camera.
- */
- inline void ProcessRenderList( const Dali::Internal::SceneGraph::RenderList& renderList, Context& context, BufferIndex bufferIndex, const Matrix& viewMatrix, const Matrix& projectionMatrix );
-
- // Prevent copying:
- RenderAlgorithms( RenderAlgorithms& rhs );
- RenderAlgorithms& operator=( const RenderAlgorithms& rhs );
-
-
- // Member variables:
-
- typedef std::vector<Dali::ClippingBox> ScissorStackType; ///< The container type used to maintain the applied scissor hierarchy
- ScissorStackType mScissorStack; ///< Contains the currently applied scissor hierarchy (so we can undo clips)
- Dali::ClippingBox mViewportRectangle; ///< The viewport dimensions, used to translate AABBs to scissor coordinates
- bool mHasLayerScissor:1; ///< Marks if the currently process render instruction has a layer-based clipping region
-};
+void ProcessRenderInstruction( const SceneGraph::RenderInstruction& instruction,
+ Context& context,
+ BufferIndex bufferIndex );
} // namespace Render
glSyncAbstraction( glSyncAbstraction ),
renderQueue(),
instructions(),
- renderAlgorithms(),
backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
frameCount( 0 ),
renderBufferIndex( SceneGraphBuffers::INITIAL_UPDATE_BUFFER_INDEX ),
// Render instructions describe what should be rendered during RenderManager::Render()
// Owned by RenderManager. Update manager updates instructions for the next frame while we render the current one
RenderInstructionContainer instructions;
- Render::RenderAlgorithms renderAlgorithms; ///< The RenderAlgorithms object is used to action the renders required by a RenderInstruction
Vector4 backgroundColor; ///< The glClear color used at the beginning of each frame.
mImpl->context.SetScissorTest( false );
}
- mImpl->renderAlgorithms.ProcessRenderInstruction( instruction, mImpl->context, mImpl->renderBufferIndex );
+ Render::ProcessRenderInstruction( instruction,
+ mImpl->context,
+ mImpl->renderBufferIndex );
if( instruction.mRenderTracker && ( instruction.mFrameBuffer != NULL ) )
{
* Rebuild the Layer::colorRenderables and overlayRenderables members,
* including only renderers which are included in the current render-task.
*
- * @param[in] updateBufferIndex The current update buffer index.
- * @param[in] node The current node of the scene-graph.
- * @param[in] currentLayer The current layer containing lists of opaque/transparent renderables.
- * @param[in] renderTask The current render-task.
- * @param[in] inheritedDrawMode The draw mode of the parent
- * @param[in] parentDepthIndex The inherited parent node depth index
- * @param[in] currentClippingId The current Clipping Id
- * Note: ClippingId is passed by reference, so it is permanently modified when traversing back up the tree for uniqueness.
- * @param[in] clippingDepth The current stencil clipping depth
- * @param[in] clippingDepth The current scissor clipping depth
- * @param[out] clippingUsed Gets set to true if any clipping nodes have been found
+ * @param[in] updateBufferIndex The current update buffer index.
+ * @param[in] node The current node of the scene-graph.
+ * @param[in] currentLayer The current layer containing lists of opaque/transparent renderables.
+ * @param[in] renderTask The current render-task.
+ * @param[in] inheritedDrawMode The draw mode of the parent
+ * @param[in] parentDepthIndex The inherited parent node depth index
+ * @param[in] currentClippingId The current Clipping Id
+ * Note: ClippingId is passed by reference, so it is permanently modified when traversing back up the tree for uniqueness.
+ * @param[in] clippingDepth The current clipping depth
*/
void AddRenderablesForTask( BufferIndex updateBufferIndex,
Node& node,
RenderTask& renderTask,
int inheritedDrawMode,
uint32_t& currentClippingId,
- uint32_t clippingDepth,
- uint32_t scissorDepth,
- bool& clippingUsed )
+ uint32_t clippingDepth )
{
// Short-circuit for invisible nodes
if( !node.IsVisible( updateBufferIndex ) )
DALI_ASSERT_DEBUG( NULL != layer );
// Update the clipping Id and depth for this node (if clipping is enabled).
- const Dali::ClippingMode::Type clippingMode = node.GetClippingMode();
- if( DALI_UNLIKELY( clippingMode != ClippingMode::DISABLED ) )
+ if( DALI_UNLIKELY( node.GetClippingMode() != ClippingMode::DISABLED ) )
{
- if( DALI_LIKELY( clippingMode == ClippingMode::CLIP_TO_BOUNDING_BOX ) )
- {
- ++scissorDepth; // This only modifies the local value (which is passed in when the method recurses).
- }
- else
- {
- // We only need clipping Id for stencil clips. This means we can deliberately avoid modifying it for bounding box clips,
- // thus allowing bounding box clipping to still detect clip depth changes without turning on the stencil buffer for non-clipped nodes.
- ++currentClippingId; // This modifies the reference passed in as well as the local value, causing the value to be global to the recursion.
- ++clippingDepth; // This only modifies the local value (which is passed in when the method recurses).
- }
- clippingUsed = true;
+ ++currentClippingId; // This modifies the reference passed in as well as the local value, causing the value to be global to the recursion.
+ ++clippingDepth; // This only modifies the local value (which is passed in when the method recurses).
}
// Set the information in the node.
- node.SetClippingInformation( currentClippingId, clippingDepth, scissorDepth );
+ node.SetClippingInformation( currentClippingId, clippingDepth );
const unsigned int count = node.GetRendererCount();
for( unsigned int i = 0; i < count; ++i )
for( NodeIter iter = children.Begin(); iter != endIter; ++iter )
{
Node& child = **iter;
- AddRenderablesForTask( updateBufferIndex, child, *layer, renderTask, inheritedDrawMode, currentClippingId, clippingDepth, scissorDepth, clippingUsed );
+ AddRenderablesForTask( updateBufferIndex, child, *layer, renderTask, inheritedDrawMode, currentClippingId, clippingDepth );
}
}
renderTask,
sourceNode->GetDrawMode(),
clippingId,
- 0u,
- 0u,
- hasClippingNodes );
+ 0u );
+
+ // If the clipping Id is still 0 after adding all Renderables, there is no clipping required for this RenderTaskList.
+ hasClippingNodes = clippingId != 0u;
mRenderInstructionProcessor.Prepare( updateBufferIndex,
sortedLayers,
// Now that the off screen renders are done we can process on screen render tasks.
// Reset the clipping Id for the OnScreen render tasks.
clippingId = 0u;
- hasClippingNodes = false;
for ( RenderTaskList::RenderTaskContainer::Iterator iter = taskContainer.Begin(); endIter != iter; ++iter )
{
RenderTask& renderTask = **iter;
renderTask,
sourceNode->GetDrawMode(),
clippingId,
- 0u,
- 0u,
- hasClippingNodes );
+ 0u );
+
+ // If the clipping Id is still 0 after adding all Renderables, there is no clipping required for this RenderTaskList.
+ hasClippingNodes = clippingId != 0;
mRenderInstructionProcessor.Prepare( updateBufferIndex,
sortedLayers,
mExclusiveRenderTask( NULL ),
mChildren(),
mClippingDepth( 0u ),
- mScissorDepth( 0u ),
mDepthIndex( 0u ),
mRegenerateUniformMap( 0 ),
mDirtyFlags( AllFlags ),
* A value is calculated that can be used during sorting to increase sort speed.
* @param[in] clippingId The Clipping ID of the node to set
* @param[in] clippingDepth The Clipping Depth of the node to set
- * @param[in] scissorDepth The Scissor Clipping Depth of the node to set
*/
- void SetClippingInformation( const uint32_t clippingId, const uint32_t clippingDepth, const uint32_t scissorDepth )
+ void SetClippingInformation( const uint32_t clippingId, const uint32_t clippingDepth )
{
- // We only set up the sort value if we have a stencil clipping depth, IE. At least 1 clipping node has been hit.
+ // We only set up the sort value if we have a clipping depth, IE. At least 1 clipping node has been hit.
// If not, if we traverse down a clipping tree and back up, and there is another
// node on the parent, this will have a non-zero clipping ID that must be ignored
- if( clippingDepth > 0u )
+ if( DALI_LIKELY( clippingDepth > 0u ) )
{
mClippingDepth = clippingDepth;
// If we do not have a clipping depth, then set this to 0 so we do not have a Clipping ID either.
mClippingSortModifier = 0u;
}
-
- // The scissor depth does not modify the clipping sort modifier (as scissor clips are 2D only).
- // For this reason we can always update the member variable.
- mScissorDepth = scissorDepth;
}
/**
}
/**
- * Gets the Scissor Clipping Depth for this node.
- * @return The Scissor Clipping Depth for this node.
- */
- uint32_t GetScissorDepth() const
- {
- return mScissorDepth;
- }
-
- /**
* Sets the clipping mode for this node.
* @param[in] clippingMode The ClippingMode to set
*/
CollectedUniformMap mCollectedUniformMap[2]; ///< Uniform maps of the node
unsigned int mUniformMapChanged[2]; ///< Records if the uniform map has been altered this frame
- uint32_t mClippingDepth; ///< The number of stencil clipping nodes deep this node is
- uint32_t mScissorDepth; ///< The number of scissor clipping nodes deep this node is
+ uint32_t mClippingDepth; ///< The number of clipping nodes deep this node is
uint32_t mDepthIndex; ///< Depth index of the node
enum Type
{
DISABLED, ///< This Actor will not clip its children. @SINCE_1_2_5
- CLIP_CHILDREN, ///< This Actor will clip all children to within the visible pixels of this actors renderer (the actor will also be visible itself). @SINCE_1_2_5
- CLIP_TO_BOUNDING_BOX ///< This Actor will clip all children within a screen-aligned rectangle encompassing its boundaries (the actor will NOT be visible itself). @SINCE_1_2.59
+ CLIP_CHILDREN, ///< This Actor will clip all children to within its boundaries (the actor will also be visible itself). @SINCE_1_2_5
};
}
// INTERNAL INCLUDES
#include <dali/public-api/common/dali-common.h>
-#include <dali/public-api/math/vector2.h>
#include <dali/public-api/math/vector3.h>
#include <dali/public-api/math/vector4.h>
#include <dali/public-api/math/quaternion.h>
return temp;
}
-Vector2 Matrix::operator*( const Vector2& rhs ) const
-{
- MATH_INCREASE_BY( PerformanceMonitor::FLOAT_POINT_MULTIPLY, 4 );
-
- #ifndef __ARM_NEON__
- // The following optimizations are applied:
- // pMatrix[8 -> 11] are optimized out.
- // pMatrix[12 -> 15] are always multiplied by 1.
- // z & w results are unneeded and so not calculated.
- return Vector2( rhs.x * mMatrix[0] + rhs.y * mMatrix[4] + mMatrix[12], rhs.x * mMatrix[1] + rhs.y * mMatrix[5] + mMatrix[13] );
- #else
- // Call the operator*( Vector4 ) version for NEON.
- // It is suggested the NEON version is removed for this simple case, as the CPU optimization surpasses the NEON overhead.
- const Vector4 result( operator*( Vector4( rhs.x, rhs.y, 0.0f, 1.0f ) ) );
- return Vector2( result.x, result.y );
- #endif
-}
-
bool Matrix::operator==(const Matrix& rhs) const
{
return (
* @{
*/
-class Vector2;
class Quaternion;
/**
static void Multiply( Matrix& result, const Matrix& lhs, const Quaternion& rhs );
/**
- * @brief The multiplication by Vector4 operator.
+ * @brief The multiplication operator.
*
* @SINCE_1_0.0
- * @param[in] rhs The Vector4 coordinates to multiply this matrix by
- * @return A Vector4 containing the result coordinates
+ * @param[in] rhs The Matrix to multiply this by
+ * @return A matrix containing the result
*/
Vector4 operator*(const Vector4& rhs) const;
/**
- * @brief The multiplication by Vector2 operator.
- * Note: This performs an optimized 2D transformation.
- *
- * @SINCE_1_2.59
- * @param[in] rhs The Vector2 coordinates to multiply this matrix by
- * @return A Vector2 containing the result coordinates
- */
- Vector2 operator*( const Vector2& rhs ) const;
-
- /**
* @brief The equality operator.
*
* Utilizes appropriate machine epsilon values.