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