1 #ifndef __DALI_INTERNAL_SCENE_GRAPH_RENDERABLE_ATTACHMENT_H__
2 #define __DALI_INTERNAL_SCENE_GRAPH_RENDERABLE_ATTACHMENT_H__
5 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
39 class ResourceManager;
40 class ResourceTracker;
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.
51 class RenderableAttachment : public NodeAttachment
56 * Set the sort-modifier for the attachment.
57 * @param[in] modifier The depth-sort modifier.
59 void SetSortModifier(float modifier);
62 * Retrieve the sort-modifier for the attachment.
63 * @return The sort-modifier.
65 float GetSortModifier() const
67 // inlined as its called a lot when sorting transparent renderers
72 * @See Dali::RenderableActor::SetBlendMode().
74 void SetBlendingMode( BlendingMode::Type mode );
77 * @copydoc Dali::RenderableActor::GetBlendMode().
79 BlendingMode::Type GetBlendingMode() const;
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
86 void ChangeBlending( BufferIndex updateBufferIndex, bool useBlending );
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.
93 void SetBlendingOptions( BufferIndex updateBufferIndex, unsigned int options );
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.
100 void SetBlendColor( BufferIndex updateBufferIndex, const Vector4& color );
103 * Set the face-culling mode.
104 * @param[in] updateBufferIndex The current update buffer index.
105 * @param[in] mode The face-culling mode.
107 void SetCullFace( BufferIndex updateBufferIndex, CullFaceMode mode );
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.
114 void SetSampler( BufferIndex updateBufferIndex, unsigned int samplerBitfield );
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
120 bool UsesGeometryScaling() const
122 return mUsesGeometryScaling;
126 * Triggers scale for size update. GetScaleForSize will be called in this frame
128 void SetRecalculateScaleForSize();
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
134 bool IsScaleForSizeDirty() const
136 return mScaleForSizeDirty;
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
145 void GetScaleForSize( const Vector3& nodeSize, Vector3& scaling );
148 * Apply a shader on the renderable
149 * @param[in] updateBufferIndex The current update buffer index.
150 * @param[in] shader to apply.
152 void ApplyShader( BufferIndex updateBufferIndex, Shader* shader );
155 * Remove the shader from the renderable
156 * @param[in] updateBufferIndex The current update buffer index.
158 void RemoveShader( BufferIndex updateBufferIndex );
160 public: // For use during in the update algorithm only
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
168 virtual bool ResolveVisibility( BufferIndex updateBufferIndex )
170 mHasSizeAndColorFlag = false;
171 const Vector4& color = mParent->GetWorldColor( updateBufferIndex );
172 if( color.a > FULLY_TRANSPARENT ) // not fully transparent
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
178 mHasSizeAndColorFlag = true;
181 return mHasSizeAndColorFlag;
185 * if this renderable actor has visible size and color
186 * @return true if you can potentially see this actor
188 bool HasVisibleSizeAndColor() const
190 return mHasSizeAndColorFlag;
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)
200 void GetReadyAndComplete(bool& ready, bool& complete) const;
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.
207 bool IsBlendingOn( BufferIndex updateBufferIndex );
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.
214 void PrepareRender( BufferIndex updateBufferIndex );
216 public: // API for derived classes
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.
224 virtual Renderer& GetRenderer() = 0;
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.
233 virtual const Renderer& GetRenderer() const = 0;
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.
241 void PrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager );
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
248 void FollowTracker( Integration::ResourceId id );
251 * @copydoc RenderableAttachment::PrepareRender()
253 virtual void DoPrepareRender( BufferIndex updateBufferIndex ) = 0;
256 * Query whether the attachment is fully opaque.
257 * @param[in] updateBufferIndex The current update buffer index.
258 * @return True if fully opaque.
260 virtual bool IsFullyOpaque( BufferIndex updateBufferIndex ) = 0;
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.
269 virtual void ShaderChanged( BufferIndex updateBufferIndex ) = 0;
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.
276 virtual void SizeChanged( BufferIndex updateBufferIndex ) = 0;
279 * Chained from NodeAttachment::ConnectToSceneGraph()
281 virtual void ConnectToSceneGraph2( BufferIndex updateBufferIndex ) = 0;
284 * Chained from NodeAttachment::OnDestroy()
286 virtual void OnDestroy2() = 0;
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
293 virtual void DoGetScaleForSize( const Vector3& nodeSize, Vector3& scaling );
298 * Protected constructor; only base classes can be instantiated.
299 * @param usesGeometryScaling should be false if the derived class does not need geometry scaling
301 RenderableAttachment( bool usesGeometryScaling );
304 * Virtual destructor, no deletion through this interface
306 virtual ~RenderableAttachment();
308 private: // From NodeAttachment
311 * @copydoc NodeAttachment::ConnectToSceneGraph().
313 virtual void ConnectToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex );
316 * @copydoc NodeAttachment::DisconnectFromSceneGraph().
318 virtual void OnDestroy();
321 * @copydoc NodeAttachment::GetRenderable()
323 virtual RenderableAttachment* GetRenderable();
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.
334 virtual bool DoPrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager ) = 0;
337 * Sends the shader to the renderer
338 * @param updateBufferIndex for the message buffer
340 void SendShaderChangeMessage( BufferIndex updateBufferIndex );
343 RenderableAttachment( const RenderableAttachment& );
346 RenderableAttachment& operator=( const RenderableAttachment& rhs );
350 SceneController* mSceneController; ///< Used for initializing renderers whilst attached
351 Shader* mShader; ///< A pointer to the shader
353 Dali::Vector< Integration::ResourceId > mTrackedResources; ///< Filled during PrepareResources if there are uncomplete, tracked resources.
357 BlendingMode::Type mBlendingMode:2; ///< Whether blending is used to render the renderable attachment. 2 bits is enough for 3 values
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
370 // Messages for RenderableAttachment
372 inline void SetSortModifierMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment, float modifier )
374 typedef MessageValue1< RenderableAttachment, float > LocalType;
376 // Reserve some memory inside the message queue
377 unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
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 );
383 inline void SetCullFaceMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment, CullFaceMode mode )
385 typedef MessageDoubleBuffered1< RenderableAttachment, CullFaceMode > LocalType;
387 // Reserve some memory inside the message queue
388 unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
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 );
394 inline void SetBlendingModeMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment, BlendingMode::Type mode )
396 typedef MessageValue1< RenderableAttachment, BlendingMode::Type > LocalType;
398 // Reserve some memory inside the message queue
399 unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
401 new (slot) LocalType( &attachment, &RenderableAttachment::SetBlendingMode, mode );
404 inline void SetBlendingOptionsMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment, unsigned int options )
406 typedef MessageDoubleBuffered1< RenderableAttachment, unsigned int > LocalType;
408 // Reserve some memory inside the message queue
409 unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
411 new (slot) LocalType( &attachment, &RenderableAttachment::SetBlendingOptions, options );
414 inline void SetBlendColorMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment, const Vector4& color )
416 typedef MessageDoubleBuffered1< RenderableAttachment, Vector4 > LocalType;
418 // Reserve some memory inside the message queue
419 unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
421 new (slot) LocalType( &attachment, &RenderableAttachment::SetBlendColor, color );
424 inline void SetSamplerMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment, unsigned int samplerBitfield )
426 typedef MessageDoubleBuffered1< RenderableAttachment, unsigned int > LocalType;
428 // Reserve some memory inside the message queue
429 unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
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 );
435 inline void ApplyShaderMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment, const Shader& constShader )
437 // Update thread can edit the object
438 Shader& shader = const_cast< Shader& >( constShader );
440 typedef MessageDoubleBuffered1< RenderableAttachment, Shader* > LocalType;
442 // Reserve some memory inside the message queue
443 unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
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 );
449 inline void RemoveShaderMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment )
451 typedef MessageDoubleBuffered0< RenderableAttachment > LocalType;
453 // Reserve some memory inside the message queue
454 unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
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 );
460 } // namespace SceneGraph
462 } // namespace Internal
466 #endif // __DALI_INTERNAL_SCENE_GRAPH_RENDERABLE_ATTACHMENT_H__