Unused variables.
[platform/core/uifw/dali-core.git] / dali / internal / update / render-tasks / scene-graph-render-task.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
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
18 // CLASS HEADER
19 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/math/matrix.h>
23 #include <dali/internal/update/resources/resource-manager.h>
24 #include <dali/internal/update/resources/complete-status-manager.h>
25 #include <dali/internal/update/nodes/node.h>
26 #include <dali/internal/update/node-attachments/scene-graph-camera-attachment.h>
27 #include <dali/internal/render/common/render-instruction.h>
28
29 #include <dali/internal/update/render-tasks/scene-graph-render-task-debug.h>
30
31 namespace Dali
32 {
33 namespace Internal
34 {
35
36 namespace SceneGraph
37 {
38
39 RenderTask* RenderTask::New()
40 {
41   return new RenderTask();
42 }
43
44 RenderTask::~RenderTask()
45 {
46   // Remove exclusive flag from source node
47   if( mExclusive )
48   {
49     if( mSourceNode && (this == mSourceNode->GetExclusiveRenderTask() ) )
50     {
51       mSourceNode->SetExclusiveRenderTask( NULL );
52     }
53   }
54   if( mFrameBufferResourceId )
55   {
56     mCompleteStatusManager->StopTrackingResource( mFrameBufferResourceId );
57   }
58 }
59
60 void RenderTask::SetSourceNode( Node* node )
61 {
62   // Remove exclusive flag from the old node, if necessary
63   if ( mSourceNode &&
64        this == mSourceNode->GetExclusiveRenderTask() )
65   {
66     mSourceNode->SetExclusiveRenderTask( NULL );
67   }
68
69   mSourceNode = node;
70
71   if ( mSourceNode && mExclusive )
72   {
73     mSourceNode->SetExclusiveRenderTask( this );
74   }
75 }
76
77 Node* RenderTask::GetSourceNode() const
78 {
79   return mSourceNode;
80 }
81
82 void RenderTask::SetExclusive( bool exclusive )
83 {
84   mExclusive = exclusive;
85
86   if ( mSourceNode )
87   {
88     if ( mExclusive )
89     {
90       mSourceNode->SetExclusiveRenderTask( this );
91     }
92     else if ( this == mSourceNode->GetExclusiveRenderTask() )
93     {
94       mSourceNode->SetExclusiveRenderTask( NULL );
95     }
96   }
97 }
98
99 bool RenderTask::IsExclusive() const
100 {
101   return mExclusive;
102 }
103
104 void RenderTask::SetCameraNode( Node* cameraNode )
105 {
106   // if camera changed
107   if( cameraNode != mCameraNode )
108   {
109     if( cameraNode )
110     {
111       // get attachment. when camera node is changed we will get a message from event thread object
112       // so no need to observe the node here
113       mCameraAttachment = dynamic_cast< CameraAttachment* >( &cameraNode->GetAttachment() );
114       DALI_ASSERT_DEBUG( mCameraAttachment && "Camera without attachment" );
115     }
116     mCameraNode = cameraNode;
117   }
118 }
119
120 void RenderTask::SetFrameBufferId( unsigned int resourceId )
121 {
122   if ( mFrameBufferResourceId != resourceId )
123   {
124     DALI_ASSERT_DEBUG(mCompleteStatusManager && "Complete status tracker is null");
125     if( mCompleteStatusManager )
126     {
127       if( resourceId && mState == RENDER_ONCE_WAITING_FOR_RESOURCES )
128       {
129         mCompleteStatusManager->TrackResource( resourceId );
130       }
131
132       if( mFrameBufferResourceId )
133       {
134         mCompleteStatusManager->StopTrackingResource( mFrameBufferResourceId );
135       }
136     }
137
138     mFrameBufferResourceId = resourceId;
139   }
140 }
141
142 unsigned int RenderTask::GetFrameBufferId() const
143 {
144   return mFrameBufferResourceId;
145 }
146
147 bool RenderTask::QueryViewport( BufferIndex bufferIndex, Viewport& viewport ) const
148 {
149   if( ! GetViewportEnabled( bufferIndex ) )
150   {
151     return false;
152   }
153
154   viewport.x = mViewportPosition[bufferIndex].x;
155   viewport.y = mViewportPosition[bufferIndex].y;
156   viewport.width = mViewportSize[bufferIndex].width;
157   viewport.height = mViewportSize[bufferIndex].height;
158
159   return true;
160 }
161
162 void RenderTask::SetClearColor( BufferIndex updateBufferIndex, const Vector4& value )
163 {
164   mClearColor.Set( updateBufferIndex, value );
165 }
166
167 const Vector4& RenderTask::GetClearColor( BufferIndex bufferIndex ) const
168 {
169   return mClearColor[bufferIndex];
170 }
171
172 void RenderTask::BakeClearColor( BufferIndex updateBufferIndex, const Vector4& value )
173 {
174   mClearColor.Bake( updateBufferIndex, value );
175 }
176
177 void RenderTask::SetClearEnabled( bool enabled )
178 {
179   mClearEnabled = enabled;
180 }
181
182 bool RenderTask::GetClearEnabled() const
183 {
184   return mClearEnabled;
185 }
186
187 void RenderTask::SetCullMode( bool mode )
188 {
189   mCullMode = mode;
190 }
191
192 bool RenderTask::GetCullMode() const
193 {
194   return mCullMode;
195 }
196
197 void RenderTask::SetRefreshRate( unsigned int refreshRate )
198 {
199   DALI_LOG_TRACE_METHOD_FMT(gRenderTaskLogFilter, "this:%p RefreshRate:%d\n", this, refreshRate);
200
201   mRefreshRate = refreshRate;
202
203   if( mRefreshRate > 0 )
204   {
205     mState = RENDER_CONTINUOUSLY;
206
207     if( mFrameBufferResourceId )
208     {
209       // Don't need tracking
210       DALI_ASSERT_DEBUG(mCompleteStatusManager && "Ready state tracker is null");
211       if( mCompleteStatusManager != NULL )
212       {
213         mCompleteStatusManager->StopTrackingResource( mFrameBufferResourceId );
214       }
215     }
216   }
217   else
218   {
219     mState = RENDER_ONCE_WAITING_FOR_RESOURCES;
220     mWaitingToRender = true;
221     mNotifyTrigger = false;
222
223     if( mFrameBufferResourceId )
224     {
225       DALI_ASSERT_DEBUG(mCompleteStatusManager && "Ready state tracker is null");
226       if( mCompleteStatusManager != NULL )
227       {
228         mCompleteStatusManager->TrackResource( mFrameBufferResourceId );
229       }
230     }
231   }
232
233   mFrameCounter = 0u;
234 }
235
236 unsigned int RenderTask::GetRefreshRate() const
237 {
238   return mRefreshRate;
239 }
240
241 bool RenderTask::ReadyToRender( BufferIndex updateBufferIndex )
242 {
243   if ( NULL == mSourceNode ||
244        ( !mSourceNode->IsRoot() && NULL == mSourceNode->GetParent() ) )
245   {
246     TASK_LOG_FMT(Debug::General, " =F  No source actor  FC:%d\n", mFrameCounter );
247
248     // Source node is missing or disconnected
249     return false;
250   }
251
252   // Check if the source node (root actor) and all its ancestors are visible.
253   if( !mSourceNode->IsFullyVisible( updateBufferIndex ) )
254   {
255     TASK_LOG_FMT(Debug::General, " =F  No visible source  FC:%d\n", mFrameCounter );
256     return false;
257   }
258
259   if ( NULL == mCameraNode ||
260        NULL == mCameraNode->GetParent() ||
261        !mCameraNode->HasAttachment() )
262   {
263     // Camera node is missing or disconnected
264     TASK_LOG_FMT(Debug::General, " =F  No Camera  FC:%d\n", mFrameCounter );
265
266     return false;
267   }
268
269   TASK_LOG_FMT(Debug::General, " =T (FBO ID:%d) FC:%d\n", mFrameBufferResourceId , mFrameCounter );
270   return true;
271 }
272
273 bool RenderTask::IsRenderRequired()
274 {
275   bool required = false;
276
277   switch( mState )
278   {
279     case RENDER_CONTINUOUSLY:
280       required = (mFrameCounter == 0);
281       break;
282
283     case RENDER_ONCE_WAITING_FOR_RESOURCES:
284       required = true;
285       break;
286
287     default:
288       required = false;
289       break;
290   }
291
292   TASK_LOG_FMT( Debug::General, " State:%s = %s\n", STATE_STRING(mState), required?"T":"F" );
293
294   return required;
295 }
296
297 void RenderTask::SetResourcesFinished( bool resourcesFinished )
298 {
299   mResourcesFinished = resourcesFinished;
300 }
301
302 // Called every frame regardless of whether render was required.
303 // If render was not required, ignore resourcesFinished.
304 void RenderTask::UpdateState()
305 {
306   TASK_LOG_FMT( Debug::General, "(mResourcesFinished:%s)  FC:%d State:%s RR:%d\n", mResourcesFinished?"T":"F", mFrameCounter, STATE_STRING(mState), mRefreshRate );
307
308   switch( mState )
309   {
310     case RENDER_CONTINUOUSLY:
311     {
312       if( mRefreshRate != Dali::RenderTask::REFRESH_ALWAYS )
313       {
314         if( mFrameCounter == 0 )
315         {
316           if( mResourcesFinished )
317           {
318             ++mFrameCounter; // Only start skipping frames when resources are loaded
319           }
320         }
321         else // Continue counting to skip frames
322         {
323           ++mFrameCounter;
324           if( mFrameCounter >= mRefreshRate )
325           {
326             mFrameCounter = 0;
327           }
328         }
329       }
330       // else do nothing
331     }
332     break;
333
334     case RENDER_ONCE_WAITING_FOR_RESOURCES:
335     {
336       if( mResourcesFinished )
337       {
338         mState = RENDERED_ONCE;
339       }
340     }
341     break;
342
343     case RENDERED_ONCE:
344     {
345       if( mFrameBufferResourceId > 0 )
346       {
347         // Query if the framebuffer is complete:
348         DALI_ASSERT_DEBUG(mCompleteStatusManager && "Complete status tracker is null");
349         if( mCompleteStatusManager != NULL &&
350             CompleteStatusManager::COMPLETE == mCompleteStatusManager->GetStatus( mFrameBufferResourceId ) )
351         {
352           mWaitingToRender = false;
353           mNotifyTrigger = true;
354         }
355         else
356         {
357           mWaitingToRender = true;
358         }
359       }
360       else
361       {
362         mWaitingToRender = false;
363         mNotifyTrigger = true;
364       }
365     }
366     break;
367
368     default:
369       break;
370   }
371
372   TASK_LOG_FMT( Debug::General, " EXIT FC:%d State:%s Notify:%s\n", mFrameCounter, STATE_STRING(mState), mNotifyTrigger?"T":"F");
373 }
374
375 bool RenderTask::IsWaitingToRender()
376 {
377   TASK_LOG_FMT(Debug::Verbose, " State:%s waiting:%s \n", STATE_STRING(mState), mWaitingToRender?"T":"F");
378   return mWaitingToRender;
379 }
380
381 bool RenderTask::HasRendered()
382 {
383   bool notify = false;
384   if( mNotifyTrigger == true )
385   {
386     ++mRenderedOnceCounter;
387     mState = RENDERED_ONCE_AND_NOTIFIED;
388     mNotifyTrigger = false;
389     notify = true;
390   }
391
392   TASK_LOG_FMT(Debug::Verbose, " State:%s hasRendered:%s \n", STATE_STRING(mState), notify?"T":"F");
393   return notify;
394 }
395
396 unsigned int RenderTask::GetRenderedOnceCounter() const
397 {
398   return mRenderedOnceCounter;
399 }
400
401
402 const Matrix& RenderTask::GetViewMatrix( BufferIndex bufferIndex ) const
403 {
404   DALI_ASSERT_DEBUG( NULL != mCameraAttachment );
405
406   return mCameraAttachment->GetViewMatrix( bufferIndex );
407 }
408
409 const Matrix& RenderTask::GetProjectionMatrix( BufferIndex bufferIndex ) const
410 {
411   DALI_ASSERT_DEBUG( NULL != mCameraAttachment );
412
413   return mCameraAttachment->GetProjectionMatrix( bufferIndex );
414 }
415
416 void RenderTask::PrepareRenderInstruction( RenderInstruction& instruction, BufferIndex updateBufferIndex )
417 {
418   DALI_ASSERT_DEBUG( NULL != mCameraAttachment );
419
420   TASK_LOG(Debug::General);
421
422   Viewport viewport;
423   bool viewportSet = QueryViewport( updateBufferIndex, viewport );
424
425   instruction.Reset( mCameraAttachment,
426                      GetFrameBufferId(),
427                      viewportSet ? &viewport : NULL,
428                      mClearEnabled ? &GetClearColor( updateBufferIndex ) : NULL );
429 }
430
431 bool RenderTask::ViewMatrixUpdated()
432 {
433   bool retval = false;
434   if( mCameraAttachment )
435   {
436     retval = mCameraAttachment->ViewMatrixUpdated();
437   }
438   return retval;
439 }
440
441 void RenderTask::SetCompleteStatusManager(CompleteStatusManager* completeStatusManager)
442 {
443   mCompleteStatusManager = completeStatusManager;
444 }
445
446 void RenderTask::SetViewportPosition( BufferIndex updateBufferIndex, const Vector2& value )
447 {
448   mViewportPosition.Set( updateBufferIndex, value );
449 }
450
451 const Vector2& RenderTask::GetViewportPosition( BufferIndex bufferIndex ) const
452 {
453   return mViewportPosition[bufferIndex];
454 }
455
456 void RenderTask::BakeViewportPosition( BufferIndex updateBufferIndex, const Vector2& value )
457 {
458   mViewportPosition.Bake( updateBufferIndex, value );
459 }
460
461 void RenderTask::SetViewportSize( BufferIndex updateBufferIndex, const Vector2& value )
462 {
463   mViewportSize.Set( updateBufferIndex, value );
464 }
465
466 const Vector2& RenderTask::GetViewportSize( BufferIndex bufferIndex ) const
467 {
468   return mViewportSize[bufferIndex];
469 }
470
471 void RenderTask::BakeViewportSize( BufferIndex updateBufferIndex, const Vector2& value )
472 {
473   mViewportSize.Bake( updateBufferIndex, value );
474 }
475
476 bool RenderTask::GetViewportEnabled( BufferIndex bufferIndex ) const
477 {
478   if(fabsf(mViewportPosition[bufferIndex].x) > Math::MACHINE_EPSILON_1 ||
479      fabsf(mViewportPosition[bufferIndex].y) > Math::MACHINE_EPSILON_1 ||
480      fabsf(mViewportSize[bufferIndex].width) > Math::MACHINE_EPSILON_1 ||
481      fabsf(mViewportSize[bufferIndex].height) > Math::MACHINE_EPSILON_1)
482   {
483     return true;
484   }
485
486   return false;
487 }
488
489 Node* RenderTask::GetCamera() const
490 {
491   return mCameraNode;
492 }
493
494 void RenderTask::ResetDefaultProperties( BufferIndex updateBufferIndex )
495 {
496   // Reset default properties
497   mViewportPosition.ResetToBaseValue( updateBufferIndex );
498   mViewportSize.ResetToBaseValue( updateBufferIndex );
499   mClearColor.ResetToBaseValue( updateBufferIndex );
500 }
501
502 RenderTask::RenderTask()
503 : mViewportPosition( Vector2::ZERO),
504   mViewportSize( Vector2::ZERO),
505   mClearColor( Dali::RenderTask::DEFAULT_CLEAR_COLOR ),
506   mCompleteStatusManager( NULL ),
507   mSourceNode( NULL ),
508   mCameraNode( NULL ),
509   mCameraAttachment( NULL ),
510   mFrameBufferResourceId( 0 ),
511   mResourcesFinished( false ),
512   mWaitingToRender( false ),
513   mNotifyTrigger( false ),
514   mExclusive( Dali::RenderTask::DEFAULT_EXCLUSIVE ),
515   mClearEnabled( Dali::RenderTask::DEFAULT_CLEAR_ENABLED ),
516   mCullMode( Dali::RenderTask::DEFAULT_CULL_MODE ),
517   mRenderTarget( NULL ),
518   mState( (Dali::RenderTask::DEFAULT_REFRESH_RATE == Dali::RenderTask::REFRESH_ALWAYS)
519           ? RENDER_CONTINUOUSLY
520           : RENDER_ONCE_WAITING_FOR_RESOURCES ),
521   mRefreshRate( Dali::RenderTask::DEFAULT_REFRESH_RATE ),
522   mFrameCounter( 0u ),
523   mRenderedOnceCounter( 0u )
524 {
525 }
526
527 } // namespace SceneGraph
528
529 } // namespace Internal
530
531 } // namespace Dali