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.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 = false;
192
193   CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
194
195   std::size_t numTrackedResources = mTrackedResources.Count();
196   if( mHasUntrackedResources || numTrackedResources == 0 )
197   {
198     ready = mResourcesReady;
199     complete = mFinishedResourceAcquisition;
200   }
201   else
202   {
203     // If there are tracked resources and no untracked resources, test the trackers
204     ready = true;
205     for( size_t i=0; i < numTrackedResources; ++i )
206     {
207       ResourceTracker* tracker = completeStatusManager.FindResourceTracker(mTrackedResources[i]);
208       if( tracker && ! tracker->IsComplete() )
209       {
210         ready = false;
211         break;
212       }
213     }
214
215     complete = mFinishedResourceAcquisition;
216     if( ! complete )
217     {
218       complete = ready;
219     }
220   }
221 }
222
223 bool RenderableAttachment::IsBlendingOn( BufferIndex updateBufferIndex )
224 {
225   // Check whether blending needs to be disabled / enabled
226   bool blend = false;
227   switch( mBlendingMode )
228   {
229     case BlendingMode::OFF:
230     {
231       // No blending.
232       blend = false;
233       break;
234     }
235     case BlendingMode::AUTO:
236     {
237       // Blending if the node is not fully opaque only.
238       blend = !IsFullyOpaque( updateBufferIndex );
239       break;
240     }
241     case BlendingMode::ON:
242     {
243       // Blending always.
244       blend = true;
245       break;
246     }
247     default:
248     {
249       DALI_ASSERT_ALWAYS( !"RenderableAttachment::PrepareRender. Wrong blending mode" );
250     }
251   }
252   return blend;
253 }
254
255 void RenderableAttachment::PrepareRender( BufferIndex updateBufferIndex )
256 {
257   // call the derived class first as it might change its state regarding blending
258   DoPrepareRender( updateBufferIndex );
259
260   bool blend = IsBlendingOn( updateBufferIndex );
261   ChangeBlending( updateBufferIndex, blend );
262 }
263
264 RenderableAttachment::RenderableAttachment( bool usesGeometryScaling )
265 : mSceneController(NULL),
266   mBlendingMode( Dali::RenderableActor::DEFAULT_BLENDING_MODE ),
267   mUsesGeometryScaling( usesGeometryScaling ),
268   mScaleForSizeDirty( true ),
269   mUseBlend( false ),
270   mHasSizeAndColorFlag( false ),
271   mResourcesReady( false ),
272   mFinishedResourceAcquisition( false ),
273   mHasUntrackedResources( false ),
274   mCullFaceMode( CullNone ),
275   mSortModifier( 0.0f )
276 {
277 }
278
279 RenderableAttachment::~RenderableAttachment()
280 {
281 }
282
283 void RenderableAttachment::ConnectToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex )
284 {
285   mSceneController = &sceneController;
286
287   // Chain to derived attachments
288   ConnectToSceneGraph2( updateBufferIndex );
289
290   // After derived classes have (potentially) created their renderer
291   GetRenderer().SetCullFace( mCullFaceMode );
292 }
293
294 void RenderableAttachment::OnDestroy()
295 {
296   // Chain to derived attachments
297   OnDestroy2();
298
299   // SceneController is no longer valid
300   mSceneController = NULL;
301 }
302
303 RenderableAttachment* RenderableAttachment::GetRenderable()
304 {
305   return this;
306 }
307
308
309 } // namespace SceneGraph
310
311 } // namespace Internal
312
313 } // namespace Dali