X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Frender%2Fcommon%2Frender-algorithms.cpp;h=610496d8294d09e142d520125fb6920ce72bceea;hb=55827866fcb8c7ee47581ac4335a3390472090e8;hp=9a28418e1494ebf64b4bd30212c825a816cb11ac;hpb=afa7ce29cc34aa631272ce5569b4298aa00490bf;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/render/common/render-algorithms.cpp b/dali/internal/render/common/render-algorithms.cpp old mode 100644 new mode 100755 index 9a28418..610496d --- a/dali/internal/render/common/render-algorithms.cpp +++ b/dali/internal/render/common/render-algorithms.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -194,9 +194,6 @@ inline void SetupDepthBuffer( const RenderItem& item, Context& context, bool dep // 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() ] ); @@ -210,8 +207,12 @@ inline void SetupDepthBuffer( const RenderItem& item, Context& context, bool dep 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 { @@ -230,7 +231,7 @@ inline void SetupDepthBuffer( const RenderItem& item, Context& context, bool dep * @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; @@ -255,6 +256,11 @@ inline void RenderAlgorithms::SetupScissorClipping( const RenderItem& item, Cont // 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 ) @@ -286,12 +292,41 @@ inline void RenderAlgorithms::SetupScissorClipping( const RenderItem& item, Cont 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; @@ -309,12 +344,16 @@ inline void RenderAlgorithms::SetupClipping( const RenderItem& item, Context& co // 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; } @@ -323,8 +362,11 @@ inline void RenderAlgorithms::SetupClipping( const RenderItem& item, Context& co { // 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 ); @@ -334,46 +376,55 @@ inline void RenderAlgorithms::SetupClipping( const RenderItem& item, Context& co 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& boundTextures, + int orientation, + Dali::ClippingBox& scissorBox ) { 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 ); @@ -382,16 +433,54 @@ inline void RenderAlgorithms::ProcessRenderList( 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; } + else if ( !scissorBox.IsEmpty() ) + { + context.SetScissorTest( true ); + context.Scissor( scissorBox.x, scissorBox.y, scissorBox.width, scissorBox.height ); + mScissorStack.push_back( scissorBox ); + } else { // We are not performing a layer clip. Add the viewport as the root scissor rectangle. @@ -400,27 +489,30 @@ inline void RenderAlgorithms::ProcessRenderList( } // 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 ); } } } @@ -431,7 +523,14 @@ RenderAlgorithms::RenderAlgorithms() { } -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& boundTextures, + int orientation, + Dali::ClippingBox& scissorBox ) { DALI_PRINT_RENDER_INSTRUCTION( instruction, bufferIndex ); @@ -453,7 +552,16 @@ void RenderAlgorithms::ProcessRenderInstruction( const RenderInstruction& instru if( renderList && !renderList->IsEmpty() ) { - ProcessRenderList( *renderList, context, bufferIndex, *viewMatrix, *projectionMatrix ); + ProcessRenderList( *renderList, + context, + bufferIndex, + *viewMatrix, + *projectionMatrix, + depthBufferAvailable, + stencilBufferAvailable, + boundTextures, + orientation, + scissorBox ); } } }