/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
// 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() ] );
firstDepthBufferUse = false;
// Note: The buffer will only be cleared if written to since a previous clear.
+ context.DepthMask( true );
context.Clear( GL_DEPTH_BUFFER_BIT, Context::CHECK_CACHED_VALUES );
}
+
+ // Set up the depth mask based on our depth write setting.
+ context.DepthMask( enableDepthWrite );
}
else
{
* @param[in] item The current RenderItem about to be rendered
* @param[in] context The context
*/
-inline void RenderAlgorithms::SetupScissorClipping( const RenderItem& item, Context& context )
+inline void RenderAlgorithms::SetupScissorClipping( const RenderItem& item, Context& context, int orientation )
{
// Get the number of child scissors in the stack (do not include layer or root box).
size_t childStackDepth = mScissorStack.size() - 1u;
// We traversed up the tree, we need to apply a new scissor rectangle (unless we are at the root).
traversedUpTree = true;
}
+ if( clippingNode && childStackDepth > 0u && childStackDepth == scissorDepth ) // case of sibling clip area
+ {
+ mScissorStack.pop_back();
+ --childStackDepth;
+ }
// 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 )
if( scissorEnabled )
{
ClippingBox useScissorBox( mScissorStack.back() );
- context.Scissor( useScissorBox.x, useScissorBox.y, useScissorBox.width, useScissorBox.height );
+ GLint x = useScissorBox.x;
+ GLint y = useScissorBox.y;
+ if( orientation == 90 )
+ {
+ x = mViewportRectangle.height - (useScissorBox.y + useScissorBox.height);
+ y = useScissorBox.x;
+ context.Scissor( x, y, useScissorBox.height, useScissorBox.width );
+ }
+ else if( orientation == 180 )
+ {
+ x = mViewportRectangle.width - (useScissorBox.x + useScissorBox.width);
+ y = mViewportRectangle.height - (useScissorBox.y + useScissorBox.height);
+ context.Scissor( x, y, useScissorBox.width, useScissorBox.height );
+ }
+ else if( orientation == 270 )
+ {
+ x = useScissorBox.y;
+ y = mViewportRectangle.width - (useScissorBox.x + useScissorBox.width);
+ context.Scissor( x, y, useScissorBox.height, useScissorBox.width );
+ }
+ else
+ {
+ context.Scissor( x, y, useScissorBox.width, useScissorBox.height );
+ }
}
}
}
-inline void RenderAlgorithms::SetupClipping( const RenderItem& item, Context& context, bool& usedStencilBuffer, uint32_t& lastClippingDepth, uint32_t& lastClippingId )
+inline void RenderAlgorithms::SetupClipping( const RenderItem& item,
+ Context& context,
+ bool& usedStencilBuffer,
+ uint32_t& lastClippingDepth,
+ uint32_t& lastClippingId,
+ Integration::StencilBufferAvailable stencilBufferAvailable,
+ int orientation )
{
RenderMode::Type renderMode = RenderMode::AUTO;
const Renderer *renderer = item.mRenderer;
// 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.
+ // The automatic clipping feature will manage the scissor and stencil functions, only if stencil buffer is available for the latter.
// 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 );
+ SetupScissorClipping( item, context, orientation );
+
+ if( stencilBufferAvailable == Integration::StencilBufferAvailable::TRUE )
+ {
+ SetupStencilClipping( item, context, lastClippingDepth, lastClippingId );
+ }
break;
}
{
// 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 );
+ // The stencil buffer will not be used at all, but we only need to disable it if it's available.
+ if( stencilBufferAvailable == Integration::StencilBufferAvailable::TRUE )
+ {
+ context.EnableStencilBuffer( false );
+ }
// Setup the color buffer based on the RenderMode.
context.ColorMask( renderMode == RenderMode::COLOR );
case RenderMode::STENCIL:
case RenderMode::COLOR_STENCIL:
{
- // We are using the low-level Renderer Stencil API.
- // The stencil buffer must be enabled for every renderer with stencil mode on, as renderers in between can disable it.
- // Note: As the command state is cached, it is only sent when needed.
- context.EnableStencilBuffer( true );
-
- // Setup the color buffer based on the RenderMode.
- context.ColorMask( renderMode == RenderMode::COLOR_STENCIL );
-
- // If this is the first use of the stencil buffer within this RenderList, clear it (this avoids unnecessary clears).
- if( !usedStencilBuffer )
+ if( stencilBufferAvailable == Integration::StencilBufferAvailable::TRUE )
{
- context.Clear( GL_STENCIL_BUFFER_BIT, Context::CHECK_CACHED_VALUES );
- usedStencilBuffer = true;
+ // We are using the low-level Renderer Stencil API.
+ // The stencil buffer must be enabled for every renderer with stencil mode on, as renderers in between can disable it.
+ // Note: As the command state is cached, it is only sent when needed.
+ context.EnableStencilBuffer( true );
+
+ // Setup the color buffer based on the RenderMode.
+ context.ColorMask( renderMode == RenderMode::COLOR_STENCIL );
+
+ // If this is the first use of the stencil buffer within this RenderList, clear it (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() );
}
-
- // 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() );
break;
}
}
}
-inline void RenderAlgorithms::ProcessRenderList(
- const RenderList& renderList,
- Context& context,
- BufferIndex bufferIndex,
- const Matrix& viewMatrix,
- const Matrix& projectionMatrix )
+inline void RenderAlgorithms::ProcessRenderList( const RenderList& renderList,
+ Context& context,
+ BufferIndex bufferIndex,
+ const Matrix& viewMatrix,
+ const Matrix& projectionMatrix,
+ Integration::DepthBufferAvailable depthBufferAvailable,
+ Integration::StencilBufferAvailable stencilBufferAvailable,
+ Vector<GLuint>& boundTextures,
+ int orientation )
{
DALI_PRINT_RENDER_LIST( renderList );
// 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 bool autoDepthTestMode( ( depthBufferAvailable == Integration::DepthBufferAvailable::TRUE ) &&
+ !( renderList.GetSourceLayer()->IsDepthTestDisabled() ) &&
+ renderList.HasColorRenderItems() );
const std::size_t count = renderList.Count();
uint32_t lastClippingDepth( 0u );
uint32_t lastClippingId( 0u );
mViewportRectangle = context.GetViewport();
mHasLayerScissor = false;
+ if( orientation == 90 || orientation == 270 )
+ {
+ int temp = mViewportRectangle.width;
+ mViewportRectangle.width = mViewportRectangle.height;
+ mViewportRectangle.height = temp;
+ }
+
// 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 );
+ GLint x = layerScissorBox.x;
+ GLint y = layerScissorBox.y;
+
+ if( orientation == 90 )
+ {
+ x = mViewportRectangle.height - (layerScissorBox.y + layerScissorBox.height);
+ y = layerScissorBox.x;
+ context.Scissor( x, y, layerScissorBox.height, layerScissorBox.width );
+ }
+ else if( orientation == 180 )
+ {
+ x = mViewportRectangle.width - (layerScissorBox.x + layerScissorBox.width);
+ y = mViewportRectangle.height - (layerScissorBox.y + layerScissorBox.height);
+ context.Scissor( x, y, layerScissorBox.width, layerScissorBox.height );
+ }
+ else if( orientation == 270 )
+ {
+ x = layerScissorBox.y;
+ y = mViewportRectangle.width - (layerScissorBox.x + layerScissorBox.width);
+ context.Scissor( x, y, layerScissorBox.height, layerScissorBox.width );
+ }
+ else
+ {
+ context.Scissor( x, y, layerScissorBox.width, layerScissorBox.height );
+ }
+
mScissorStack.push_back( layerScissorBox );
mHasLayerScissor = true;
}
}
// Loop through all RenderList in the RenderList, set up any prerequisites to render them, then perform the render.
- for( size_t index( 0u ); index < count; ++index )
+ for( uint32_t index = 0u; index < count; ++index )
{
const RenderItem& item = renderList.GetItem( index );
DALI_PRINT_RENDER_ITEM( item );
// Set up clipping 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 );
+ SetupClipping( item, context, usedStencilBuffer, lastClippingDepth, lastClippingId, stencilBufferAvailable, orientation );
if( DALI_LIKELY( item.mRenderer ) )
{
- // Set up the depth buffer based on per-renderer flags.
+ // Set up the depth buffer based on per-renderer flags if depth buffer is available
// 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
// disable depth testing and writing. Color Renderers will enable them if the Layer does.
- SetupDepthBuffer( item, context, autoDepthTestMode, firstDepthBufferUse );
+ if( depthBufferAvailable == Integration::DepthBufferAvailable::TRUE )
+ {
+ SetupDepthBuffer( item, context, autoDepthTestMode, firstDepthBufferUse );
+ }
// Render the item.
item.mRenderer->Render( context, bufferIndex, *item.mNode, item.mModelMatrix, item.mModelViewMatrix,
- viewMatrix, projectionMatrix, item.mSize, !item.mIsOpaque );
+ viewMatrix, projectionMatrix, item.mSize, !item.mIsOpaque, boundTextures );
}
}
}
{
}
-void RenderAlgorithms::ProcessRenderInstruction( const RenderInstruction& instruction, Context& context, BufferIndex bufferIndex )
+void RenderAlgorithms::ProcessRenderInstruction( const RenderInstruction& instruction,
+ Context& context,
+ BufferIndex bufferIndex,
+ Integration::DepthBufferAvailable depthBufferAvailable,
+ Integration::StencilBufferAvailable stencilBufferAvailable,
+ Vector<GLuint>& boundTextures,
+ int orientation )
{
DALI_PRINT_RENDER_INSTRUCTION( instruction, bufferIndex );
if( renderList && !renderList->IsEmpty() )
{
- ProcessRenderList( *renderList, context, bufferIndex, *viewMatrix, *projectionMatrix );
+ ProcessRenderList( *renderList,
+ context,
+ bufferIndex,
+ *viewMatrix,
+ *projectionMatrix,
+ depthBufferAvailable,
+ stencilBufferAvailable,
+ boundTextures,
+ orientation );
}
}
}