Merge remote-tracking branch 'origin/tizen' into devel/new_mesh
[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/scene-graph-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  * Process a render-list.
44  * @param[in] renderList The render-list to process.
45  * @param[in] context The GL context.
46  * @param[in] defaultShader The default shader to use.
47  * @param[in] buffer The current render buffer index (previous update buffer)
48  * @param[in] frameTime The elapsed time between the last two updates.
49  * @param[in] viewMatrix The view matrix from the appropriate camera.
50  * @param[in] projectionMatrix The projection matrix from the appropriate camera.
51  * @param[in] cullMode True if the renderers should be subjected to clipspace culling
52  */
53 inline void ProcessRenderList( const RenderList& renderList,
54                                Context& context,
55                                SceneGraph::TextureCache& textureCache,
56                                SceneGraph::Shader& defaultShader,
57                                BufferIndex bufferIndex,
58                                float frameTime,
59                                const Matrix& viewMatrix,
60                                const Matrix& projectionMatrix,
61                                bool cullMode )
62 {
63   DALI_PRINT_RENDER_LIST( renderList );
64
65   // Scissor testing
66   if( renderList.IsClipping() )
67   {
68     context.SetScissorTest( true );
69
70     const Dali::ClippingBox& clip = renderList.GetClippingBox();
71     context.Scissor(clip.x, clip.y, clip.width, clip.height);
72   }
73   else
74   {
75     context.SetScissorTest( false );
76   }
77
78   const unsigned int renderFlags = renderList.GetFlags();
79
80   bool enableDepthBuffer = ( ( renderFlags & RenderList::DEPTH_BUFFER_ENABLED ) != 0u );
81   bool depthMask         = ( ( renderFlags & RenderList::DEPTH_WRITE ) != 0u );
82
83   GLbitfield clearMask   = ( renderFlags & RenderList::DEPTH_CLEAR ) ? GL_DEPTH_BUFFER_BIT : 0u;
84
85   context.EnableDepthBuffer( enableDepthBuffer );
86   context.DepthMask( depthMask );
87
88   // Stencil enabled, writing, and clearing...
89   const bool enableStencilBuffer( renderFlags & RenderList::STENCIL_BUFFER_ENABLED );
90   const bool enableStencilWrite( renderFlags & RenderList::STENCIL_WRITE );
91
92   context.EnableStencilBuffer( enableStencilBuffer );
93
94   if( enableStencilBuffer )
95   {
96     context.StencilFunc( (enableStencilWrite ? GL_ALWAYS : GL_EQUAL), 1, 0xFF );
97     context.StencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
98
99     clearMask |= (renderFlags & RenderList::STENCIL_CLEAR) ? GL_STENCIL_BUFFER_BIT : 0u;
100   }
101
102   // Write to stencil buffer or color buffer, but not both
103   context.StencilMask( enableStencilWrite ? 0xFF : 0x00 );
104   context.ColorMask( !enableStencilWrite );
105
106   // Clear depth and/or stencil buffer.
107   if( clearMask )
108   {
109     // only clear if the depth and/or stencil buffer have been written to after a previous clear
110     context.Clear( clearMask, Context::CHECK_CACHED_VALUES );
111   }
112
113   size_t count = renderList.Count();
114   for ( size_t index = 0; index < count; ++index )
115   {
116     const RenderItem& item = renderList.GetItem( index );
117
118     DALI_PRINT_RENDER_ITEM( item );
119
120     SceneGraph::Renderer* renderer = const_cast< SceneGraph::Renderer* >( item.GetRenderer() );
121     const Matrix& modelViewMatrix = item.GetModelViewMatrix();
122
123     renderer->Render( context, textureCache, bufferIndex, defaultShader, modelViewMatrix, viewMatrix, projectionMatrix, frameTime, cullMode );
124   }
125 }
126
127 void ProcessRenderInstruction( const RenderInstruction& instruction,
128                                Context& context,
129                                SceneGraph::TextureCache& textureCache,
130                                SceneGraph::Shader& defaultShader,
131                                BufferIndex bufferIndex,
132                                float frameTime )
133 {
134   DALI_PRINT_RENDER_INSTRUCTION( instruction, bufferIndex );
135
136   const Matrix* viewMatrix       = instruction.GetViewMatrix( bufferIndex );
137   const Matrix* projectionMatrix = instruction.GetProjectionMatrix( bufferIndex );
138
139   DALI_ASSERT_DEBUG( NULL != viewMatrix );
140   DALI_ASSERT_DEBUG( NULL != projectionMatrix );
141
142   if( NULL != viewMatrix &&
143       NULL != projectionMatrix )
144   {
145     const RenderListContainer::SizeType count = instruction.RenderListCount();
146     for( RenderListContainer::SizeType index = 0; index < count; ++index )
147     {
148       const RenderList* renderList = instruction.GetRenderList( index );
149
150       if(  renderList &&
151           !renderList->IsEmpty() )
152       {
153         ProcessRenderList( *renderList, context, textureCache, defaultShader, bufferIndex, frameTime, *viewMatrix, *projectionMatrix, instruction.mCullMode );
154       }
155     }
156   }
157 }
158
159 } // namespace Render
160
161 } // namespace Internal
162
163 } // namespace Dali