[SRUK] Initial copy from Tizen 2.2 version
[platform/core/uifw/dali-core.git] / dali / internal / update / node-attachments / scene-graph-renderable-attachment.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.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
7 //
8 //     http://floralicense.org/license/
9 //
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.
15 //
16
17 // CLASS HEADER
18 #include <dali/internal/update/node-attachments/scene-graph-renderable-attachment.h>
19
20 // INTERNAL INCLUDES
21 #include <dali/integration-api/resource-declarations.h>
22 #include <dali/public-api/actors/renderable-actor.h>
23 #include <dali/internal/update/nodes/node.h>
24 #include <dali/internal/update/resources/resource-manager.h>
25 #include <dali/internal/update/resources/complete-status-manager.h>
26 #include <dali/internal/update/resources/resource-tracker.h>
27 #include <dali/internal/render/queue/render-queue.h>
28 #include <dali/internal/render/renderers/scene-graph-renderer.h>
29 #include <dali/internal/render/shaders/shader.h>
30
31 using namespace std;
32
33 namespace Dali
34 {
35
36 namespace Internal
37 {
38
39 namespace SceneGraph
40 {
41
42 void RenderableAttachment::SetSortModifier(float modifier)
43 {
44   // Setting sort modifier makes the node dirty, i.e. we cannot reuse previous frames render items
45   if( mParent )
46   {
47     // only do this if we are on-stage
48     mParent->SetDirtyFlag( SortModifierFlag );
49   }
50   mSortModifier = modifier;
51 }
52
53 float RenderableAttachment::GetSortModifier() const
54 {
55   return mSortModifier;
56 }
57
58 void RenderableAttachment::SetBlendingMode( BlendingMode::Type mode )
59 {
60   mBlendingMode = mode;
61 }
62
63 BlendingMode::Type RenderableAttachment::GetBlendingMode() const
64 {
65   return mBlendingMode;
66 }
67
68 void RenderableAttachment::ChangeBlending( BufferIndex updateBufferIndex, bool useBlend )
69 {
70   if ( mUseBlend != useBlend )
71   {
72     mUseBlend = useBlend;
73
74     // Enable/disable blending in the next render
75     typedef MessageValue1< Renderer, bool > DerivedType;
76
77     // Reserve some memory inside the render queue
78     unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
79
80     // Construct message in the render queue memory; note that delete should not be called on the return value
81     new (slot) DerivedType( &GetRenderer(), &Renderer::SetUseBlend, useBlend );
82   }
83 }
84
85 void RenderableAttachment::SetBlendingOptions( BufferIndex updateBufferIndex, unsigned int options )
86 {
87   // Blending options are forwarded to renderer in render-thread
88   typedef MessageValue1< Renderer, unsigned int > DerivedType;
89
90   // Reserve some memory inside the render queue
91   unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
92
93   // Construct message in the render queue memory; note that delete should not be called on the return value
94   new (slot) DerivedType( &GetRenderer(), &Renderer::SetBlendingOptions, options );
95 }
96
97 void RenderableAttachment::SetBlendColor( BufferIndex updateBufferIndex, const Vector4& color )
98 {
99   // Blend color is forwarded to renderer in render-thread
100   typedef MessageValue1< Renderer, Vector4 > DerivedType;
101
102   // Reserve some memory inside the render queue
103   unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
104
105   // Construct message in the render queue memory; note that delete should not be called on the return value
106   new (slot) DerivedType( &GetRenderer(), &Renderer::SetBlendColor, color );
107 }
108
109 void RenderableAttachment::PrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager )
110 {
111   mHasUntrackedResources = false; // Only need to know this if the resources are not yet complete
112   mTrackedResources.Clear(); // Resource trackers are only needed if not yet completea
113
114   if( Shader* shader = mParent->GetAppliedShader() )
115   {
116     Integration::ResourceId id = shader->GetEffectTextureResourceId();
117
118     if( id != 0 )
119     {
120       CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
121
122       if(CompleteStatusManager::COMPLETE != completeStatusManager.GetStatus( id ))
123       {
124         FollowTracker(id);
125         mFinishedResourceAcquisition = false;
126         mResourcesReady = false;
127
128         // If shader has effect texture and it's not complete and tracked, ensure
129         // we call DoPrepareResources, as the effect texture may become ready in
130         // the ProcessRenderTasks step.  Otherwise, may early out.
131         if( mHasUntrackedResources )
132         {
133           return;
134         }
135       }
136     }
137   }
138
139   mResourcesReady = DoPrepareResources( updateBufferIndex, resourceManager );
140 }
141
142 void RenderableAttachment::FollowTracker( Integration::ResourceId id )
143 {
144   CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
145
146   if( completeStatusManager.FindResourceTracker(id) != NULL )
147   {
148     mTrackedResources.PushBack( id );
149   }
150   else
151   {
152     mHasUntrackedResources = true;
153   }
154 }
155
156 void RenderableAttachment::SetCullFace( BufferIndex updateBufferIndex, CullFaceMode mode )
157 {
158   DALI_ASSERT_DEBUG(mSceneController);
159   DALI_ASSERT_DEBUG(mode >= CullNone && mode <= CullFrontAndBack);
160
161   mCullFaceMode = mode;
162
163   typedef MessageValue1< Renderer, CullFaceMode > DerivedType;
164
165   // Reserve some memory inside the render queue
166   unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
167
168   // Construct message in the render queue memory; note that delete should not be called on the return value
169   new (slot) DerivedType( &GetRenderer(), &Renderer::SetCullFace, mode );
170 }
171
172 void RenderableAttachment::SetRecalculateScaleForSize()
173 {
174   mScaleForSizeDirty = true;
175 }
176
177 void RenderableAttachment::GetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
178 {
179   DoGetScaleForSize( nodeSize, scaling );
180   mScaleForSizeDirty = false;
181 }
182
183 void RenderableAttachment::DoGetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
184 {
185   scaling = Vector3::ONE;
186 }
187
188 void RenderableAttachment::GetReadyAndComplete(bool& ready, bool& complete) const
189 {
190   ready = false;
191   complete = true; // If attachment doesn't have size or color, this should be marked as complete.
192
193   CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
194
195   if( mHasSizeAndColorFlag )
196   {
197     std::size_t numTrackedResources = mTrackedResources.Count();
198     if( mHasUntrackedResources || numTrackedResources == 0 )
199     {
200       ready = mResourcesReady;
201       complete = mFinishedResourceAcquisition;
202     }
203     else
204     {
205       // If there are tracked resources and no untracked resources, test the trackers
206       ready = true;
207       for( size_t i=0; i < numTrackedResources; ++i )
208       {
209         ResourceTracker* tracker = completeStatusManager.FindResourceTracker(mTrackedResources[i]);
210         if( tracker && ! tracker->IsComplete() )
211         {
212           ready = false;
213           break;
214         }
215       }
216
217       complete = mFinishedResourceAcquisition;
218       if( ! complete )
219       {
220         complete = ready;
221       }
222     }
223   }
224 }
225
226 bool RenderableAttachment::IsBlendingOn( BufferIndex updateBufferIndex )
227 {
228   // Check whether blending needs to be disabled / enabled
229   bool blend = false;
230   switch( mBlendingMode )
231   {
232     case BlendingMode::OFF:
233     {
234       // No blending.
235       blend = false;
236       break;
237     }
238     case BlendingMode::AUTO:
239     {
240       // Blending if the node is not fully opaque only.
241       blend = !IsFullyOpaque( updateBufferIndex );
242       break;
243     }
244     case BlendingMode::ON:
245     {
246       // Blending always.
247       blend = true;
248       break;
249     }
250     default:
251     {
252       DALI_ASSERT_ALWAYS( !"RenderableAttachment::PrepareRender. Wrong blending mode" );
253     }
254   }
255   return blend;
256 }
257
258 void RenderableAttachment::PrepareRender( BufferIndex updateBufferIndex )
259 {
260   // call the derived class first as it might change its state regarding blending
261   DoPrepareRender( updateBufferIndex );
262
263   bool blend = IsBlendingOn( updateBufferIndex );
264   ChangeBlending( updateBufferIndex, blend );
265 }
266
267 RenderableAttachment::RenderableAttachment( bool usesGeometryScaling )
268 : mSceneController(NULL),
269   mBlendingMode( Dali::RenderableActor::DEFAULT_BLENDING_MODE ),
270   mUsesGeometryScaling( usesGeometryScaling ),
271   mScaleForSizeDirty( true ),
272   mUseBlend( false ),
273   mHasSizeAndColorFlag( false ),
274   mResourcesReady( false ),
275   mFinishedResourceAcquisition( false ),
276   mHasUntrackedResources( false ),
277   mCullFaceMode( CullNone ),
278   mSortModifier( 0.0f )
279 {
280 }
281
282 RenderableAttachment::~RenderableAttachment()
283 {
284 }
285
286 void RenderableAttachment::ConnectToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex )
287 {
288   mSceneController = &sceneController;
289
290   // Chain to derived attachments
291   ConnectToSceneGraph2( updateBufferIndex );
292
293   // After derived classes have (potentially) created their renderer
294   GetRenderer().SetCullFace( mCullFaceMode );
295 }
296
297 void RenderableAttachment::OnDestroy()
298 {
299   // Chain to derived attachments
300   OnDestroy2();
301
302   // SceneController is no longer valid
303   mSceneController = NULL;
304 }
305
306 RenderableAttachment* RenderableAttachment::GetRenderable()
307 {
308   return this;
309 }
310
311
312 } // namespace SceneGraph
313
314 } // namespace Internal
315
316 } // namespace Dali