Fix the renderable visibility checking and its relationship with render once
[platform/core/uifw/dali-core.git] / dali / internal / update / node-attachments / scene-graph-renderable-attachment.h
1 #ifndef __DALI_INTERNAL_SCENE_GRAPH_RENDERABLE_ATTACHMENT_H__
2 #define __DALI_INTERNAL_SCENE_GRAPH_RENDERABLE_ATTACHMENT_H__
3
4 //
5 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
6 //
7 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 // INTERNAL INCLUDES
21 #include <dali/public-api/actors/layer.h>
22 #include <dali/internal/common/blending-options.h>
23 #include <dali/internal/common/event-to-update.h>
24 #include <dali/internal/common/internal-constants.h>
25 #include <dali/internal/common/type-abstraction-enums.h>
26 #include <dali/internal/update/controllers/scene-controller.h>
27 #include <dali/internal/update/nodes/node.h>
28 #include <dali/internal/update/node-attachments/node-attachment.h>
29 #include <dali/internal/update/common/double-buffered.h>
30 #include <dali/internal/update/resources/resource-manager-declarations.h>
31 #include <dali/internal/render/renderers/scene-graph-renderer-declarations.h>
32
33 namespace Dali
34 {
35
36 namespace Internal
37 {
38 class ResourceManager;
39 class ResourceTracker;
40
41 namespace SceneGraph
42 {
43 class Renderer;
44
45 /**
46  * RenderableAttachments are responsible for preparing textures, meshes, matrices etc. during the Update.
47  * These resources are then passed to a renderer, for use in the next Render.
48  */
49 class RenderableAttachment : public NodeAttachment
50 {
51 public: // API
52
53   /**
54    * Set the sort-modifier for the attachment.
55    * @param[in] modifier The depth-sort modifier.
56    */
57   void SetSortModifier(float modifier);
58
59   /**
60    * Retrieve the sort-modifier for the attachment.
61    * @return The sort-modifier.
62    */
63   float GetSortModifier() const;
64
65   /**
66    * @See Dali::RenderableActor::SetBlendMode().
67    */
68   void SetBlendingMode( BlendingMode::Type mode );
69
70   /**
71    * @copydoc Dali::RenderableActor::GetBlendMode().
72    */
73   BlendingMode::Type GetBlendingMode() const;
74
75   /**
76    * Check if the blending mode has changed - if it has, send message to renderer
77    * @param[in] updateBufferIndex The current update buffer index.
78    * @param[in] useBlending True if the renderer should use blending option
79    */
80   void ChangeBlending( BufferIndex updateBufferIndex, bool useBlending );
81
82   /**
83    * Set the blending options. This should only be called from the update-thread.
84    * @param[in] updateBufferIndex The current update buffer index.
85    * @param[in] options A bitmask of blending options.
86    */
87   void SetBlendingOptions( BufferIndex updateBufferIndex, unsigned int options );
88
89   /**
90    * Set the blend-color. This should only be called from the update-thread.
91    * @param[in] updateBufferIndex The current update buffer index.
92    * @param[in] color The new blend-color.
93    */
94   void SetBlendColor( BufferIndex updateBufferIndex, const Vector4& color );
95
96   /**
97    * Set the face-culling mode.
98    * @param[in] updateBufferIndex The current update buffer index.
99    * @param[in] mode The face-culling mode.
100    */
101   void SetCullFace( BufferIndex updateBufferIndex, CullFaceMode mode );
102
103   /**
104    * Flag to check if any geometry scaling is needed, inlined as called from update algorithm often
105    * @return true if the derived renderable uses geometry scaling
106    */
107   bool UsesGeometryScaling() const
108   {
109     return mUsesGeometryScaling;
110   }
111
112   /**
113    * Triggers scale for size update. GetScaleForSize will be called in this frame
114    */
115   void SetRecalculateScaleForSize();
116
117   /**
118    * Returns the scaling dirty flag, inlined as called from update algorithm often
119    * @return if scale for size is dirty, i.e. scaling has changed
120    */
121   bool IsScaleForSizeDirty() const
122   {
123     return mScaleForSizeDirty;
124   }
125
126   /**
127    * Retrieve scale-for-size for given node size
128    * Clears the scale for size flag
129    * @param[in] nodeSize to scale to
130    * @param[out] scaling factors
131    */
132   void GetScaleForSize( const Vector3& nodeSize, Vector3& scaling );
133
134 public: // For use during in the update algorithm only
135
136   /**
137    * TODO this method should not be virtual but because mesh attachment is a mess, it needs to be
138    * considered visible regardless of its size... need to remove geometry scaling to fix this!!!
139    * @param[in] updateBufferIndex The current update buffer index.
140    * @return visible tells if this renderer can be potentially seen
141    */
142   virtual bool ResolveVisibility( BufferIndex updateBufferIndex )
143   {
144     mHasSizeAndColorFlag = false;
145     const Vector4& color = mParent->GetWorldColor( updateBufferIndex );
146     if( color.a > FULLY_TRANSPARENT )               // not fully transparent
147     {
148       const Vector3& size = mParent->GetSize( updateBufferIndex );
149       if( ( size.width > Math::MACHINE_EPSILON_1000 )&&   // width is greater than a very small number
150           ( size.height > Math::MACHINE_EPSILON_1000 ) )  // height is greater than a very small number
151       {
152         mHasSizeAndColorFlag = true;
153       }
154     }
155     return mHasSizeAndColorFlag;
156   }
157
158   /**
159    * if this renderable actor has visible size and color
160    * @return true if you can potentially see this actor
161    */
162   bool HasVisibleSizeAndColor() const
163   {
164     return mHasSizeAndColorFlag;
165   }
166
167   /**
168    * Check whether the attachment has been marked as ready to render
169    * @param[out] ready TRUE if the attachment has resources to render
170    * @param[out] complete TRUE if the attachment's resources are complete
171    * (e.g. image has finished loading, framebuffer is ready to render, native image
172    * framebuffer has been rendered)
173    */
174   void GetReadyAndComplete(bool& ready, bool& complete) const;
175
176   /**
177    * Query whether the attachment has blending enabled.
178    * @param[in] updateBufferIndex The current update buffer index.
179    * @return true if blending is enabled, false otherwise.
180    */
181   bool IsBlendingOn( BufferIndex updateBufferIndex );
182
183   /**
184    * Prepare the object for rendering.
185    * This is called by the UpdateManager when an object is due to be rendered in the current frame.
186    * @param[in] updateBufferIndex The current update buffer index.
187    */
188   void PrepareRender( BufferIndex updateBufferIndex );
189
190 public: // API for derived classes
191
192   /**
193    * Retrieve a Renderer used by this attachment; implemented in derived classes.
194    * @note The first Renderer is the main renderer for the attachment, and
195    * should always exist during the lifetime of the RenderableAttachment.
196    * @return A Renderer.
197    */
198   virtual Renderer& GetRenderer() = 0;
199
200   /**
201    * Retrieve a Renderer used by this attachment.
202    * @note The first Renderer is the main renderer for the attachment, and
203    * should always exist during the lifetime of the RenderableAttachment.
204    * Other renderers are for effects such as shadows and reflections.
205    * @return A Renderer.
206    */
207   virtual const Renderer& GetRenderer() const = 0;
208
209   /**
210    * Prepare the object resources.
211    * This must be called by the UpdateManager before calling PrepareRender, for each frame.
212    * @param[in] updateBufferIndex The current update buffer index.
213    * @param[in] resourceManager The resource manager.
214    */
215   void PrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager );
216
217   /**
218    * If the resource is being tracked, then follow it. ( Further ready tests will use this
219    * list ) Otherwise, if it's not complete, set mHasUntrackedResources.
220    * @param[in] The resource id
221    */
222   void FollowTracker( Integration::ResourceId id );
223
224   /**
225    * @copydoc RenderableAttachment::PrepareRender()
226    */
227   virtual void DoPrepareRender( BufferIndex updateBufferIndex ) = 0;
228
229   /**
230    * Query whether the attachment is fully opaque.
231    * @param[in] updateBufferIndex The current update buffer index.
232    * @return True if fully opaque.
233    */
234   virtual bool IsFullyOpaque( BufferIndex updateBufferIndex ) = 0;
235
236   /**
237    * Called to notify that the shader might have been changed
238    * The implementation should recalculate geometry and scale based on the
239    * hints from the new shader
240    * @param[in] updateBufferIndex The current update buffer index.
241    * @return Return true if the geometry changed.
242    */
243   virtual void ShaderChanged( BufferIndex updateBufferIndex ) = 0;
244
245   /**
246    * Called to notify that the size has been changed
247    * The implementation may tell the renderer to recalculate geometry and scale based on the new size
248    * @param[in] updateBufferIndex The current update buffer index.
249    */
250   virtual void SizeChanged( BufferIndex updateBufferIndex ) = 0;
251
252   /**
253    * Chained from NodeAttachment::ConnectToSceneGraph()
254    */
255   virtual void ConnectToSceneGraph2( BufferIndex updateBufferIndex ) = 0;
256
257   /**
258    * Chained from NodeAttachment::OnDestroy()
259    */
260   virtual void OnDestroy2() = 0;
261
262   /**
263    * Retrieve the scale-for-size for given node size. Default implementation returns Vector3::ZERO
264    * @param[in] nodeSize to scale to
265    * @param[out] scaling factors
266    */
267   virtual void DoGetScaleForSize( const Vector3& nodeSize, Vector3& scaling );
268
269 protected:
270
271   /**
272    * Protected constructor; only base classes can be instantiated.
273    * @param usesGeometryScaling should be false if the derived class does not need geometry scaling
274    */
275   RenderableAttachment( bool usesGeometryScaling );
276
277   /**
278    * Virtual destructor, no deletion through this interface
279    */
280   virtual ~RenderableAttachment();
281
282 private: // From NodeAttachment
283
284   /**
285    * @copydoc NodeAttachment::ConnectToSceneGraph().
286    */
287   virtual void ConnectToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex );
288
289   /**
290    * @copydoc NodeAttachment::DisconnectFromSceneGraph().
291    */
292   virtual void OnDestroy();
293
294   /**
295    * @copydoc NodeAttachment::GetRenderable()
296    */
297   virtual RenderableAttachment* GetRenderable();
298
299 private:
300
301   /**
302    * Prepare the object resources.
303    * This must be called by the UpdateManager before calling PrepareRender, for each frame.
304    * @param[in] updateBufferIndex The current buffer index.
305    * @param[in] resourceManager The resource manager.
306    * @return True if resources are ready, false will prevent PrepareRender being called for this attachment.
307    */
308   virtual bool DoPrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager ) = 0;
309
310   // Undefined
311   RenderableAttachment( const RenderableAttachment& );
312
313   // Undefined
314   RenderableAttachment& operator=( const RenderableAttachment& rhs );
315
316 protected:
317
318   SceneController* mSceneController;   ///< Used for initializing renderers whilst attached
319
320   BlendingMode::Type mBlendingMode:2;    ///< Whether blending is used to render the renderable attachment. 2 bits is enough for 3 values
321
322   bool mUsesGeometryScaling:1;         ///< True if the derived renderer uses scaling.
323   bool mScaleForSizeDirty:1;           ///< True if mScaleForSize has changed in the current frame.
324   bool mUseBlend:1;                    ///< True if the attachment & renderer should be considered opaque for sorting and blending.
325   bool mHasSizeAndColorFlag:1;         ///< Set during the update algorithm to tell whether this renderer can potentially be seen
326   bool mResourcesReady:1;              ///< Set during the Update algorithm; true if the attachment has resources ready for the current frame.
327   bool mFinishedResourceAcquisition:1; ///< Set during DoPrepareResources; true if ready & all resource acquisition has finished (successfully or otherwise)
328   bool mHasUntrackedResources:1;       ///< Set during PrepareResources, true if have tried to follow untracked resources
329   CullFaceMode mCullFaceMode:3;        ///< Cullface mode, 3 bits is enough for 4 values
330
331   float mSortModifier;
332
333   Dali::Vector< Integration::ResourceId > mTrackedResources; ///< Filled during PrepareResources if there are uncomplete, tracked resources.
334 };
335
336 // Messages for RenderableAttachment
337
338 inline void SetSortModifierMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment, float modifier )
339 {
340   typedef MessageValue1< RenderableAttachment, float > LocalType;
341
342   // Reserve some memory inside the message queue
343   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
344
345   // Construct message in the message queue memory; note that delete should not be called on the return value
346   new (slot) LocalType( &attachment, &RenderableAttachment::SetSortModifier, modifier );
347 }
348
349 inline void SetCullFaceMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment, CullFaceMode mode )
350 {
351   typedef MessageDoubleBuffered1< RenderableAttachment, CullFaceMode > LocalType;
352
353   // Reserve some memory inside the message queue
354   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
355
356   // Construct message in the message queue memory; note that delete should not be called on the return value
357   new (slot) LocalType( &attachment, &RenderableAttachment::SetCullFace, mode );
358 }
359
360 inline void SetBlendingModeMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment, BlendingMode::Type mode )
361 {
362   typedef MessageValue1< RenderableAttachment, BlendingMode::Type > LocalType;
363
364   // Reserve some memory inside the message queue
365   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
366
367   new (slot) LocalType( &attachment, &RenderableAttachment::SetBlendingMode, mode );
368 }
369
370 inline void SetBlendingOptionsMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment, unsigned int options )
371 {
372   typedef MessageDoubleBuffered1< RenderableAttachment, unsigned int > LocalType;
373
374   // Reserve some memory inside the message queue
375   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
376
377   new (slot) LocalType( &attachment, &RenderableAttachment::SetBlendingOptions, options );
378 }
379
380 inline void SetBlendColorMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment, const Vector4& color )
381 {
382   typedef MessageDoubleBuffered1< RenderableAttachment, Vector4 > LocalType;
383
384   // Reserve some memory inside the message queue
385   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
386
387   new (slot) LocalType( &attachment, &RenderableAttachment::SetBlendColor, color );
388 }
389
390 } // namespace SceneGraph
391
392 } // namespace Internal
393
394 } // namespace Dali
395
396 #endif // __DALI_INTERNAL_SCENE_GRAPH_RENDERABLE_ATTACHMENT_H__