2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/render/common/render-algorithms.h>
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>
28 using Dali::Internal::SceneGraph::RenderItem;
29 using Dali::Internal::SceneGraph::RenderList;
30 using Dali::Internal::SceneGraph::RenderListContainer;
31 using Dali::Internal::SceneGraph::RenderInstruction;
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
47 inline void SetScissorTest( const RenderList& renderList, Context& context )
50 if( renderList.IsClipping() )
52 context.SetScissorTest( true );
54 const Dali::ClippingBox& clip = renderList.GetClippingBox();
55 context.Scissor(clip.x, clip.y, clip.width, clip.height);
59 context.SetScissorTest( false );
64 * Sets the render flags for depth testing and stencil buffer
66 * @param[in] renderList The render list from which to get the render flags
67 * @param[in] context The context
69 inline void SetRenderFlags( const RenderList& renderList, Context& context )
71 const unsigned int renderFlags = renderList.GetFlags();
73 bool enableDepthBuffer = ( ( renderFlags & RenderList::DEPTH_BUFFER_ENABLED ) != 0u );
75 GLbitfield clearMask = ( renderFlags & RenderList::DEPTH_CLEAR ) ? GL_DEPTH_BUFFER_BIT : 0u;
77 context.EnableDepthBuffer( enableDepthBuffer );
79 // Stencil enabled, writing, and clearing...
80 const bool enableStencilBuffer( renderFlags & RenderList::STENCIL_BUFFER_ENABLED );
81 const bool enableStencilWrite( renderFlags & RenderList::STENCIL_WRITE );
83 context.EnableStencilBuffer( enableStencilBuffer );
85 if( enableStencilBuffer )
87 context.StencilFunc( (enableStencilWrite ? GL_ALWAYS : GL_EQUAL), 1, 0xFF );
88 context.StencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
90 clearMask |= (renderFlags & RenderList::STENCIL_CLEAR) ? GL_STENCIL_BUFFER_BIT : 0u;
93 // Write to stencil buffer or color buffer, but not both
94 context.StencilMask( enableStencilWrite ? 0xFF : 0x00 );
95 context.ColorMask( !enableStencilWrite );
97 // Clear depth and/or stencil buffer.
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 );
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] frameTime The elapsed time between the last two updates.
113 * @param[in] viewMatrix The view matrix from the appropriate camera.
114 * @param[in] projectionMatrix The projection matrix from the appropriate camera.
115 * @param[in] cullMode True if the renderers should be subjected to clipspace culling
117 inline void ProcessRenderList(
118 const RenderList& renderList,
120 SceneGraph::TextureCache& textureCache,
121 SceneGraph::Shader& defaultShader,
122 BufferIndex bufferIndex,
124 const Matrix& viewMatrix,
125 const Matrix& projectionMatrix,
128 DALI_PRINT_RENDER_LIST( renderList );
130 SetScissorTest( renderList, context );
131 SetRenderFlags( renderList, context );
133 if( renderList.HasColorRenderItems() )
135 bool depthBufferEnabled = ( ( renderList.GetFlags() & RenderList::DEPTH_BUFFER_ENABLED ) != 0u );
136 size_t count = renderList.Count();
137 for ( size_t index = 0; index < count; ++index )
139 const RenderItem& item = renderList.GetItem( index );
140 DALI_PRINT_RENDER_ITEM( item );
142 //Enable depth writes if depth buffer is enabled and item is opaque
143 context.DepthMask( depthBufferEnabled && item.IsOpaque() );
145 SceneGraph::Renderer* renderer = const_cast< SceneGraph::Renderer* >( item.GetRenderer() );
146 renderer->Render( context, textureCache, bufferIndex, defaultShader, item.GetModelViewMatrix(), viewMatrix, projectionMatrix, frameTime, cullMode );
151 size_t count = renderList.Count();
152 for ( size_t index = 0; index < count; ++index )
154 const RenderItem& item = renderList.GetItem( index );
155 DALI_PRINT_RENDER_ITEM( item );
157 SceneGraph::Renderer* renderer = const_cast< SceneGraph::Renderer* >( item.GetRenderer() );
158 renderer->Render( context, textureCache, bufferIndex, defaultShader, item.GetModelViewMatrix(), viewMatrix, projectionMatrix, frameTime, cullMode );
165 * Render items from the currentIndex until the depth index changes.
166 * Leaves currentIndex pointing at the
168 * @param[in] renderList The render-list to process.
169 * @param[in] context The GL context.
170 * @param[in] defaultShader The default shader to use.
171 * @param[in] buffer The current render buffer index (previous update buffer)
172 * @param[in] frameTime The elapsed time between the last two updates.
173 * @param[in] viewMatrix The view matrix from the appropriate camera.
174 * @param[in] projectionMatrix The projection matrix from the appropriate camera.
175 * @param[in] cullMode True if the renderers should be subjected to clipspace culling
176 * @param[in] depthIndex The current depth index
177 * @param[inout] currentIndex On entry, the index in the render list of the first item at the given depth index. On exit, the index of the first item at the next depth index.
179 inline void RenderItemsAtDepthIndex(
180 const RenderList& renderList,
182 SceneGraph::TextureCache& textureCache,
183 SceneGraph::Shader& defaultShader,
184 BufferIndex bufferIndex,
186 const Matrix& viewMatrix,
187 const Matrix& projectionMatrix,
190 size_t& currentIndex ) // Out parameter
192 const size_t count = renderList.Count();
194 // Don't initialise currentIndex. Ever.
195 for( ; currentIndex < count ; currentIndex++ )
197 const RenderItem& renderItem = renderList.GetItem( currentIndex );
198 DALI_PRINT_RENDER_ITEM( renderItem );
200 if( renderItem.GetDepthIndex() == depthIndex )
202 SceneGraph::Renderer* renderer = const_cast< SceneGraph::Renderer* >( renderItem.GetRenderer() );
203 const Matrix& modelViewMatrix = renderItem.GetModelViewMatrix();
204 renderer->Render( context, textureCache, bufferIndex, defaultShader, modelViewMatrix, viewMatrix, projectionMatrix, frameTime, cullMode );
209 break; // Stop iterating when we reach a new depth index
216 void ProcessRenderInstruction( const RenderInstruction& instruction,
218 SceneGraph::TextureCache& textureCache,
219 SceneGraph::Shader& defaultShader,
220 BufferIndex bufferIndex,
223 DALI_PRINT_RENDER_INSTRUCTION( instruction, bufferIndex );
225 const Matrix* viewMatrix = instruction.GetViewMatrix( bufferIndex );
226 const Matrix* projectionMatrix = instruction.GetProjectionMatrix( bufferIndex );
228 DALI_ASSERT_DEBUG( NULL != viewMatrix );
229 DALI_ASSERT_DEBUG( NULL != projectionMatrix );
231 if( NULL != viewMatrix &&
232 NULL != projectionMatrix )
234 const RenderListContainer::SizeType count = instruction.RenderListCount();
236 // Iterate through each render list in order. If a pair of render lists
237 // are marked as interleaved, then process them together.
238 for( RenderListContainer::SizeType index = 0; index < count; ++index )
240 const RenderList* renderList = instruction.GetRenderList( index );
243 !renderList->IsEmpty() )
245 ProcessRenderList( *renderList, context, textureCache, defaultShader, bufferIndex, frameTime, *viewMatrix, *projectionMatrix, instruction.mCullMode );
251 } // namespace Render
253 } // namespace Internal