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