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/render-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 item.GetRenderer().Render( context, textureCache, bufferIndex, item.GetNode(), defaultShader, item.GetModelViewMatrix(), viewMatrix, projectionMatrix, frameTime, cullMode, !item.IsOpaque() );
150 size_t count = renderList.Count();
151 for ( size_t index = 0; index < count; ++index )
153 const RenderItem& item = renderList.GetItem( index );
154 DALI_PRINT_RENDER_ITEM( item );
156 item.GetRenderer().Render( context, textureCache, bufferIndex, item.GetNode(), defaultShader, item.GetModelViewMatrix(), viewMatrix, projectionMatrix, frameTime, cullMode, !item.IsOpaque() );
163 * Render items from the currentIndex until the depth index changes.
164 * Leaves currentIndex pointing at the
166 * @param[in] renderList The render-list to process.
167 * @param[in] context The GL context.
168 * @param[in] defaultShader The default shader to use.
169 * @param[in] buffer The current render buffer index (previous update buffer)
170 * @param[in] frameTime The elapsed time between the last two updates.
171 * @param[in] viewMatrix The view matrix from the appropriate camera.
172 * @param[in] projectionMatrix The projection matrix from the appropriate camera.
173 * @param[in] cullMode True if the renderers should be subjected to clipspace culling
174 * @param[in] depthIndex The current depth index
175 * @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.
177 inline void RenderItemsAtDepthIndex(
178 const RenderList& renderList,
180 SceneGraph::TextureCache& textureCache,
181 SceneGraph::Shader& defaultShader,
182 BufferIndex bufferIndex,
184 const Matrix& viewMatrix,
185 const Matrix& projectionMatrix,
188 size_t& currentIndex ) // Out parameter
190 const size_t count = renderList.Count();
192 // Don't initialise currentIndex. Ever.
193 for( ; currentIndex < count ; currentIndex++ )
195 const RenderItem& renderItem = renderList.GetItem( currentIndex );
196 DALI_PRINT_RENDER_ITEM( renderItem );
198 if( renderItem.GetDepthIndex() == depthIndex )
200 const Matrix& modelViewMatrix = renderItem.GetModelViewMatrix();
201 renderItem.GetRenderer().Render( context, textureCache, bufferIndex, renderItem.GetNode(), defaultShader, modelViewMatrix, viewMatrix, projectionMatrix, frameTime, cullMode, !renderItem.IsOpaque() );
206 break; // Stop iterating when we reach a new depth index
213 void ProcessRenderInstruction( const RenderInstruction& instruction,
215 SceneGraph::TextureCache& textureCache,
216 SceneGraph::Shader& defaultShader,
217 BufferIndex bufferIndex,
220 DALI_PRINT_RENDER_INSTRUCTION( instruction, bufferIndex );
222 const Matrix* viewMatrix = instruction.GetViewMatrix( bufferIndex );
223 const Matrix* projectionMatrix = instruction.GetProjectionMatrix( bufferIndex );
225 DALI_ASSERT_DEBUG( NULL != viewMatrix );
226 DALI_ASSERT_DEBUG( NULL != projectionMatrix );
228 if( NULL != viewMatrix &&
229 NULL != projectionMatrix )
231 const RenderListContainer::SizeType count = instruction.RenderListCount();
233 // Iterate through each render list in order. If a pair of render lists
234 // are marked as interleaved, then process them together.
235 for( RenderListContainer::SizeType index = 0; index < count; ++index )
237 const RenderList* renderList = instruction.GetRenderList( index );
240 !renderList->IsEmpty() )
242 ProcessRenderList( *renderList, context, textureCache, defaultShader, bufferIndex, frameTime, *viewMatrix, *projectionMatrix, instruction.mCullMode );
248 } // namespace Render
250 } // namespace Internal