Merge "Add macros to provide branch prediction information" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / render / common / render-algorithms.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/render/common/render-algorithms.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/render/common/render-debug.h>
23 #include <dali/internal/render/common/render-list.h>
24 #include <dali/internal/render/common/render-instruction.h>
25 #include <dali/internal/render/gl-resources/context.h>
26 #include <dali/internal/render/renderers/render-renderer.h>
27
28 using Dali::Internal::SceneGraph::RenderItem;
29 using Dali::Internal::SceneGraph::RenderList;
30 using Dali::Internal::SceneGraph::RenderListContainer;
31 using Dali::Internal::SceneGraph::RenderInstruction;
32
33 namespace Dali
34 {
35
36 namespace Internal
37 {
38
39 namespace Render
40 {
41
42 /**
43  * Sets up the scissor test if required.
44  * @param[in] renderList The render list from which to get the clipping flag
45  * @param[in] context The context
46  */
47 inline void SetScissorTest( const RenderList& renderList, Context& context )
48 {
49   // Scissor testing
50   if( renderList.IsClipping() )
51   {
52     context.SetScissorTest( true );
53
54     const Dali::ClippingBox& clip = renderList.GetClippingBox();
55     context.Scissor(clip.x, clip.y, clip.width, clip.height);
56   }
57   else
58   {
59     context.SetScissorTest( false );
60   }
61 }
62
63 /**
64  * Sets the render flags for depth testing and stencil buffer
65  *
66  * @param[in] renderList The render list from which to get the render flags
67  * @param[in] context The context
68  */
69 inline void SetRenderFlags( const RenderList& renderList, Context& context )
70 {
71   const unsigned int renderFlags = renderList.GetFlags();
72
73   bool enableDepthBuffer = ( ( renderFlags & RenderList::DEPTH_BUFFER_ENABLED ) != 0u );
74
75   GLbitfield clearMask   = ( renderFlags & RenderList::DEPTH_CLEAR ) ? GL_DEPTH_BUFFER_BIT : 0u;
76
77   context.EnableDepthBuffer( enableDepthBuffer );
78
79   // Stencil enabled, writing, and clearing...
80   const bool enableStencilBuffer( renderFlags & RenderList::STENCIL_BUFFER_ENABLED );
81   const bool enableStencilWrite( renderFlags & RenderList::STENCIL_WRITE );
82
83   context.EnableStencilBuffer( enableStencilBuffer );
84
85   if( enableStencilBuffer )
86   {
87     context.StencilFunc( (enableStencilWrite ? GL_ALWAYS : GL_EQUAL), 1, 0xFF );
88     context.StencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
89
90     clearMask |= (renderFlags & RenderList::STENCIL_CLEAR) ? GL_STENCIL_BUFFER_BIT : 0u;
91   }
92
93   // Write to stencil buffer or color buffer, but not both
94   context.StencilMask( enableStencilWrite ? 0xFF : 0x00 );
95   context.ColorMask( !enableStencilWrite );
96
97   // Clear depth and/or stencil buffer.
98   if( clearMask )
99   {
100     // only clear if the depth and/or stencil buffer have been written to after a previous clear
101     context.Clear( clearMask, Context::CHECK_CACHED_VALUES );
102   }
103 }
104
105
106 /**
107  * Process a render-list.
108  * @param[in] renderList The render-list to process.
109  * @param[in] context The GL context.
110  * @param[in] defaultShader The default shader to use.
111  * @param[in] buffer The current render buffer index (previous update buffer)
112  * @param[in] viewMatrix The view matrix from the appropriate camera.
113  * @param[in] projectionMatrix The projection matrix from the appropriate camera.
114  */
115 inline void ProcessRenderList(
116   const RenderList& renderList,
117   Context& context,
118   SceneGraph::TextureCache& textureCache,
119   SceneGraph::Shader& defaultShader,
120   BufferIndex bufferIndex,
121   const Matrix& viewMatrix,
122   const Matrix& projectionMatrix )
123 {
124   DALI_PRINT_RENDER_LIST( renderList );
125
126   SetScissorTest( renderList, context );
127   SetRenderFlags( renderList, context );
128
129   if( renderList.HasColorRenderItems() )
130   {
131     bool depthBufferEnabled = ( ( renderList.GetFlags() & RenderList::DEPTH_BUFFER_ENABLED ) != 0u );
132     size_t count = renderList.Count();
133     for ( size_t index = 0; index < count; ++index )
134     {
135       const RenderItem& item = renderList.GetItem( index );
136       DALI_PRINT_RENDER_ITEM( item );
137
138       //Enable depth writes if depth buffer is enabled and item is opaque
139       context.DepthMask( depthBufferEnabled && ( item.IsOpaque() || item.GetRenderer().RequiresDepthTest() ) );
140
141       item.GetRenderer().Render( context, textureCache, bufferIndex, item.GetNode(), defaultShader, item.GetModelViewMatrix(), viewMatrix, projectionMatrix, !item.IsOpaque() );
142     }
143   }
144   else
145   {
146     size_t count = renderList.Count();
147     for ( size_t index = 0; index < count; ++index )
148     {
149       const RenderItem& item = renderList.GetItem( index );
150       DALI_PRINT_RENDER_ITEM( item );
151
152       item.GetRenderer().Render( context, textureCache, bufferIndex, item.GetNode(), defaultShader, item.GetModelViewMatrix(), viewMatrix, projectionMatrix, !item.IsOpaque() );
153     }
154
155   }
156 }
157
158 void ProcessRenderInstruction( const RenderInstruction& instruction,
159                                Context& context,
160                                SceneGraph::TextureCache& textureCache,
161                                SceneGraph::Shader& defaultShader,
162                                BufferIndex bufferIndex )
163 {
164   DALI_PRINT_RENDER_INSTRUCTION( instruction, bufferIndex );
165
166   const Matrix* viewMatrix       = instruction.GetViewMatrix( bufferIndex );
167   const Matrix* projectionMatrix = instruction.GetProjectionMatrix( bufferIndex );
168
169   DALI_ASSERT_DEBUG( NULL != viewMatrix );
170   DALI_ASSERT_DEBUG( NULL != projectionMatrix );
171
172   if( NULL != viewMatrix &&
173       NULL != projectionMatrix )
174   {
175     const RenderListContainer::SizeType count = instruction.RenderListCount();
176
177     // Iterate through each render list in order. If a pair of render lists
178     // are marked as interleaved, then process them together.
179     for( RenderListContainer::SizeType index = 0; index < count; ++index )
180     {
181       const RenderList* renderList = instruction.GetRenderList( index );
182
183       if(  renderList &&
184           !renderList->IsEmpty() )
185       {
186         ProcessRenderList( *renderList, context, textureCache, defaultShader, bufferIndex, *viewMatrix, *projectionMatrix );
187       }
188     }
189   }
190 }
191
192 } // namespace Render
193
194 } // namespace Internal
195
196 } // namespace Dali