Merge "RenderItem clean-up" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / render / common / render-list.h
1 #ifndef __DALI_INTERNAL_SCENE_GRAPH_RENDER_LIST_H__
2 #define __DALI_INTERNAL_SCENE_GRAPH_RENDER_LIST_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/math/rect.h>
23 #include <dali/devel-api/common/owner-container.h>
24 #include <dali/internal/render/common/render-item.h>
25
26 namespace Dali
27 {
28
29 typedef Rect<int> ClippingBox;
30
31 namespace Internal
32 {
33
34 namespace Render
35 {
36 class Renderer;
37 }
38
39 namespace SceneGraph
40 {
41
42 class Layer;
43
44 typedef OwnerContainer< RenderItem* > RenderItemContainer;
45
46 struct RenderList;
47 typedef OwnerContainer< RenderList* > RenderListContainer;
48
49 /**
50  * The RenderList structure provides the renderer with a list of renderers and
51  * a set of flags to tell it what depth buffering is required.
52  */
53 struct RenderList
54 {
55 public:
56
57   /**
58    * The RenderFlags describe how the objects are rendered using the depth and stencil buffer.
59    *
60    * The flags which relate to GL_DEPTH_TEST and GL_STENCIL_TEST are called
61    * DEPTH_BUFFER_ENABLED and STENCIL_BUFFER_ENABLED to avoid any confusion.
62    * E.g. if GL_DEPTH_TEST is not enabled you can't write to the depth buffer, which can cause confusion.
63    *
64    */
65   enum RenderFlags
66   {
67     DEPTH_BUFFER_ENABLED   = 1 << 0, ///< If depth buffer should be used for writing / test operations
68     DEPTH_WRITE            = 1 << 1, ///< If the depth buffer is writable
69     DEPTH_CLEAR            = 1 << 2, ///< If the depth buffer should first be cleared
70     STENCIL_BUFFER_ENABLED = 1 << 3, ///< If stencil buffer should be used for writing / test operation
71     STENCIL_WRITE          = 1 << 4, ///< If the stencil buffer is writable
72     STENCIL_CLEAR          = 1 << 5, ///< If the stencil buffer should first be cleared
73
74   };
75
76   /**
77    * Constructor
78    */
79   RenderList()
80   : mNextFree( 0 ),
81     mRenderFlags( 0u ),
82     mClippingBox( NULL ),
83     mSourceLayer( NULL ),
84     mHasColorRenderItems( false )
85   {
86   }
87
88   /**
89    * Destructor
90    */
91   ~RenderList()
92   {
93     // pointer container deletes the render items
94     delete mClippingBox;
95   }
96
97   /**
98    * Clear the render flags
99    */
100   void ClearFlags()
101   {
102     mRenderFlags = 0u;
103   }
104
105   /**
106    * Set particular render flags
107    * @param[in] flags The set of flags to bitwise or with existing flags
108    */
109   void SetFlags( unsigned int flags )
110   {
111     mRenderFlags |= flags;
112   }
113
114   /**
115    * Retrieve the render flags.
116    * @return the render flags.
117    */
118   unsigned int GetFlags() const
119   {
120     return mRenderFlags;
121   }
122
123   /**
124    * Reset the render list for next frame
125    */
126   void Reset()
127   {
128     // we dont want to delete and re-create the render items every frame
129     mNextFree = 0;
130     mRenderFlags = 0u;
131
132     delete mClippingBox;
133     mClippingBox = NULL;
134   }
135
136   /**
137    * Reserve space in the render list
138    * @param size to reserve
139    */
140   void Reserve( RenderItemContainer::SizeType size )
141   {
142     mNextFree = 0;
143     mItems.Reserve( size );
144   }
145
146   /**
147    * @return the capacity of the render list
148    */
149   RenderItemContainer::SizeType Capacity()
150   {
151     return mItems.Capacity();
152   }
153
154   /**
155    * Get next free render item
156    * @return reference to the next available RenderItem
157    */
158   RenderItem& GetNextFreeItem()
159   {
160     // check if we have enough items, we can only be one behind at worst
161     if( mItems.Count() <= mNextFree )
162     {
163       mItems.PushBack( RenderItem::New() ); // Push a new empty render item
164     }
165     // get the item mNextFree points to and increase by one
166     RenderItem& item = *mItems[ mNextFree++ ];
167     return item;
168   }
169
170   /**
171    * Get item at a given position in the list
172    */
173   RenderItem& GetItem( RenderItemContainer::SizeType index ) const
174   {
175     DALI_ASSERT_DEBUG( index < GetCachedItemCount() );
176     return *mItems[ index ];
177   }
178
179   /**
180    * Get renderer from an item in the list
181    */
182   const Render::Renderer& GetRenderer( RenderItemContainer::SizeType index ) const
183   {
184     DALI_ASSERT_DEBUG( index < GetCachedItemCount() );
185     return *mItems[ index ]->mRenderer;
186   }
187
188   /**
189    * Get the number of real items
190    * Because of caching, the actual size may be bit more
191    * @return The number of items
192    */
193   RenderItemContainer::SizeType Count() const
194   {
195     return mNextFree;
196   }
197
198   /**
199    * @return the number of items cached by the list
200    */
201   RenderItemContainer::SizeType GetCachedItemCount() const
202   {
203     return mItems.Count();
204   }
205
206   /**
207    * Tells the render list to reuse the items from the cache
208    */
209   void ReuseCachedItems()
210   {
211     mNextFree = mItems.Count();
212   }
213
214   /**
215    * Predicate to inform if the list is empty
216    */
217   bool IsEmpty() const
218   {
219     return (mNextFree == 0);
220   }
221
222   /**
223    * Set clipping
224    * @param clipping on/off
225    * @param box for clipping
226    */
227   void SetClipping( bool clipping, const ClippingBox& box )
228   {
229     if( clipping )
230     {
231       ClippingBox* newBox = new ClippingBox( box );
232       delete mClippingBox;
233       mClippingBox = newBox;
234     }
235   }
236
237   /**
238    * @return true if clipping is on
239    */
240   bool IsClipping() const
241   {
242     return (NULL != mClippingBox);
243   }
244
245   /**
246    * @return the clipping box
247    */
248   const ClippingBox& GetClippingBox() const
249   {
250     return *mClippingBox;
251   }
252
253   /**
254    * @return the container (for sorting)
255    */
256   RenderItemContainer& GetContainer()
257   {
258     return mItems;
259   }
260
261   /**
262    * Do some housekeeping to keep memory consumption low
263    */
264   void ReleaseUnusedItems()
265   {
266     // release any non-used RenderItems
267     if( mItems.Count() > mNextFree )
268     {
269       mItems.Resize( mNextFree );
270     }
271   }
272
273   /**
274    * @return the source layer these renderitems originate from
275    */
276   Layer* GetSourceLayer()
277   {
278     return mSourceLayer;
279   }
280
281   /**
282    * @param layer these renderitems originate from
283    */
284   void SetSourceLayer( Layer* layer )
285   {
286     mSourceLayer = layer;
287   }
288
289   /**
290    * Set if the RenderList contains color RenderItems
291    * @param[in] hasColorRenderItems True if it contains color RenderItems, false otherwise
292    */
293   void SetHasColorRenderItems( bool hasColorRenderItems )
294   {
295     mHasColorRenderItems = hasColorRenderItems;
296   }
297
298   /**
299    * Check if the RenderList contains color RenderItems
300    * @return true if the RenderList contains color RenderItems, false otherwise
301    */
302   bool HasColorRenderItems() const
303   {
304     return mHasColorRenderItems;
305   }
306
307 private:
308
309   /*
310    * Copy constructor and assignment operator not defined
311    */
312   RenderList( const RenderList& rhs );
313   const RenderList& operator=( const RenderList& rhs );
314
315   RenderItemContainer mItems; ///< Each item is a renderer and matrix pair
316   RenderItemContainer::SizeType mNextFree;              ///< index for the next free item to use
317
318   unsigned int mRenderFlags;    ///< The render flags
319
320   ClippingBox* mClippingBox;               ///< The clipping box, in window coordinates, when clipping is enabled
321   Layer*       mSourceLayer;              ///< The originating layer where the renderers are from
322   bool         mHasColorRenderItems : 1;  ///< True if list contains color render items
323 };
324
325 } // namespace SceneGraph
326
327 } // namespace Internal
328
329 } // namespace Dali
330
331 #endif // __DALI_INTERNAL_SCENE_GRAPH_RENDER_LIST_H__