Merge "Removed FrameBufferId from SceneGraph::RenderTask" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / update / render-tasks / scene-graph-render-task.cpp
1 /*
2  * Copyright (c) 2016 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/controllers/render-message-dispatcher.h>
24 #include <dali/internal/update/resources/resource-manager.h>
25 #include <dali/internal/update/nodes/node.h>
26 #include <dali/internal/render/common/render-instruction.h>
27 #include <dali/internal/render/common/render-tracker.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( mRenderSyncTracker )
55   {
56     mRenderMessageDispatcher->RemoveRenderTracker( *mRenderSyncTracker );
57   }
58 }
59
60 void RenderTask::Initialize( RenderMessageDispatcher& renderMessageDispatcher, ResourceManager& resourceManager )
61 {
62   mRenderMessageDispatcher = &renderMessageDispatcher;
63   mResourceManager = &resourceManager;
64 }
65
66 void RenderTask::SetSourceNode( Node* node )
67 {
68   // Remove exclusive flag from the old node, if necessary
69   if ( mSourceNode &&
70        this == mSourceNode->GetExclusiveRenderTask() )
71   {
72     mSourceNode->SetExclusiveRenderTask( NULL );
73   }
74
75   mSourceNode = node;
76
77   if ( mSourceNode && mExclusive )
78   {
79     mSourceNode->SetExclusiveRenderTask( this );
80   }
81 }
82
83 Node* RenderTask::GetSourceNode() const
84 {
85   return mSourceNode;
86 }
87
88 void RenderTask::SetExclusive( bool exclusive )
89 {
90   mExclusive = exclusive;
91
92   if ( mSourceNode )
93   {
94     if ( mExclusive )
95     {
96       mSourceNode->SetExclusiveRenderTask( this );
97     }
98     else if ( this == mSourceNode->GetExclusiveRenderTask() )
99     {
100       mSourceNode->SetExclusiveRenderTask( NULL );
101     }
102   }
103 }
104
105 bool RenderTask::IsExclusive() const
106 {
107   return mExclusive;
108 }
109
110 void RenderTask::SetCamera( Node* cameraNode, Camera* camera )
111 {
112   mCameraNode = cameraNode;
113   mCamera = camera;
114 }
115
116 void RenderTask::SetFrameBuffer( Render::FrameBuffer* frameBuffer )
117 {
118   mFrameBuffer = frameBuffer;
119 }
120
121 Render::FrameBuffer* RenderTask::GetFrameBuffer()
122 {
123   return mFrameBuffer;
124 }
125
126 bool RenderTask::QueryViewport( BufferIndex bufferIndex, Viewport& viewport ) const
127 {
128   if( ! GetViewportEnabled( bufferIndex ) )
129   {
130     return false;
131   }
132
133   viewport.x = mViewportPosition[bufferIndex].x;
134   viewport.y = mViewportPosition[bufferIndex].y;
135   viewport.width = mViewportSize[bufferIndex].width;
136   viewport.height = mViewportSize[bufferIndex].height;
137
138   return true;
139 }
140
141 void RenderTask::SetClearColor( BufferIndex updateBufferIndex, const Vector4& value )
142 {
143   mClearColor.Set( updateBufferIndex, value );
144 }
145
146 const Vector4& RenderTask::GetClearColor( BufferIndex bufferIndex ) const
147 {
148   return mClearColor[bufferIndex];
149 }
150
151 void RenderTask::BakeClearColor( BufferIndex updateBufferIndex, const Vector4& value )
152 {
153   mClearColor.Bake( updateBufferIndex, value );
154 }
155
156 void RenderTask::SetClearEnabled( bool enabled )
157 {
158   mClearEnabled = enabled;
159 }
160
161 bool RenderTask::GetClearEnabled() const
162 {
163   return mClearEnabled;
164 }
165
166 void RenderTask::SetCullMode( bool mode )
167 {
168   mCullMode = mode;
169 }
170
171 bool RenderTask::GetCullMode() const
172 {
173   return mCullMode;
174 }
175
176 void RenderTask::SetRefreshRate( unsigned int refreshRate )
177 {
178   DALI_LOG_TRACE_METHOD_FMT(gRenderTaskLogFilter, "this:%p RefreshRate:%d\n", this, refreshRate);
179
180   mRefreshRate = refreshRate;
181
182   if( mRefreshRate > 0 )
183   {
184     mState = RENDER_CONTINUOUSLY;
185   }
186   else
187   {
188     mState = RENDER_ONCE_WAITING_FOR_RESOURCES;
189     mWaitingToRender = true;
190     mNotifyTrigger = false;
191   }
192
193   mFrameCounter = 0u;
194 }
195
196 unsigned int RenderTask::GetRefreshRate() const
197 {
198   return mRefreshRate;
199 }
200
201 bool RenderTask::ReadyToRender( BufferIndex updateBufferIndex )
202 {
203   // If the source node of the render task is invisible we should still render
204   // We want the render task to complete and possible clear colors to happen
205
206   // Check source node
207   if ( NULL == mSourceNode ||
208        ( !mSourceNode->IsRoot() && NULL == mSourceNode->GetParent() ) )
209   {
210     TASK_LOG_FMT(Debug::General, " =F  No source actor  FC:%d\n", mFrameCounter );
211
212     // Source node is missing or disconnected
213     return false;
214   }
215
216   // Check camera node
217   if ( NULL == mCameraNode ||
218        NULL == mCameraNode->GetParent() ||
219        NULL == mCamera )
220   {
221     // Camera node is missing or disconnected
222     TASK_LOG_FMT(Debug::General, " =F  No Camera  FC:%d\n", mFrameCounter );
223
224     return false;
225   }
226
227   mCamera->Update( updateBufferIndex, *mCameraNode );
228   return true;
229 }
230
231 bool RenderTask::IsRenderRequired()
232 {
233   bool required = false;
234
235   switch( mState )
236   {
237     case RENDER_CONTINUOUSLY:
238     {
239       required = (mFrameCounter == 0);
240       break;
241     }
242     case RENDER_ONCE_WAITING_FOR_RESOURCES:
243     {
244       required = true;
245       break;
246     }
247     default:
248     {
249       required = false;
250       break;
251     }
252   }
253
254   TASK_LOG_FMT( Debug::General, " State:%s = %s\n", STATE_STRING(mState), required?"T":"F" );
255
256   return required;
257 }
258
259 void RenderTask::SetResourcesFinished( bool resourcesFinished )
260 {
261   // resourcesFinished tells us that this render task will render to its FBO
262   mResourcesFinished = resourcesFinished;
263 }
264
265 // Called every frame regardless of whether render was required.
266 // If render was not required, ignore resourcesFinished.
267 void RenderTask::UpdateState()
268 {
269   TASK_LOG_FMT( Debug::General, "(mResourcesFinished:%s)  FC:%d State:%s RR:%d\n", mResourcesFinished?"T":"F", mFrameCounter, STATE_STRING(mState), mRefreshRate );
270
271   switch( mState )
272   {
273     case RENDER_CONTINUOUSLY:
274     {
275       if( mRefreshRate != Dali::RenderTask::REFRESH_ALWAYS )
276       {
277         if( mFrameCounter == 0 )
278         {
279           if( mResourcesFinished )
280           {
281             ++mFrameCounter; // Only start skipping frames when resources are loaded
282           }
283         }
284         else // Continue counting to skip frames
285         {
286           ++mFrameCounter;
287           if( mFrameCounter >= mRefreshRate )
288           {
289             mFrameCounter = 0;
290           }
291         }
292       }
293       // else do nothing
294     }
295     break;
296
297     case RENDER_ONCE_WAITING_FOR_RESOURCES:
298     {
299       if( mResourcesFinished )
300       {
301         mState = RENDERED_ONCE;
302       }
303     }
304     break;
305
306     case RENDERED_ONCE:
307     {
308       mWaitingToRender = true;
309       mNotifyTrigger = false;
310       if( mFrameBuffer )
311       {
312         if( !mRenderSyncTracker || (mRenderSyncTracker && mRenderSyncTracker->IsSynced() ))
313         {
314           mWaitingToRender = false;
315           mNotifyTrigger = true;
316         }
317       }
318       else
319       {
320         mNotifyTrigger = true;
321       }
322     }
323
324     break;
325
326     default:
327       break;
328   }
329
330   TASK_LOG_FMT( Debug::General, " EXIT FC:%d State:%s Notify:%s\n", mFrameCounter, STATE_STRING(mState), mNotifyTrigger?"T":"F");
331 }
332
333 bool RenderTask::IsWaitingToRender()
334 {
335   TASK_LOG_FMT(Debug::Verbose, " State:%s waiting:%s \n", STATE_STRING(mState), mWaitingToRender?"T":"F");
336   return mWaitingToRender;
337 }
338
339 bool RenderTask::HasRendered()
340 {
341   bool notify = false;
342   if( mNotifyTrigger == true )
343   {
344     ++mRenderedOnceCounter;
345     mState = RENDERED_ONCE_AND_NOTIFIED;
346     mNotifyTrigger = false;
347     notify = true;
348   }
349
350   TASK_LOG_FMT(Debug::Verbose, " State:%s hasRendered:%s \n", STATE_STRING(mState), notify?"T":"F");
351   return notify;
352 }
353
354 unsigned int RenderTask::GetRenderedOnceCounter() const
355 {
356   return mRenderedOnceCounter;
357 }
358
359
360 const Matrix& RenderTask::GetViewMatrix( BufferIndex bufferIndex ) const
361 {
362   DALI_ASSERT_DEBUG( NULL != mCamera );
363
364   return mCamera->GetViewMatrix( bufferIndex );
365 }
366
367 SceneGraph::Camera& RenderTask::GetCamera() const
368 {
369   DALI_ASSERT_DEBUG( NULL != mCamera );
370   return *mCamera;
371 }
372
373 const Matrix& RenderTask::GetProjectionMatrix( BufferIndex bufferIndex ) const
374 {
375   DALI_ASSERT_DEBUG( NULL != mCamera );
376
377   return mCamera->GetProjectionMatrix( bufferIndex );
378 }
379
380 void RenderTask::PrepareRenderInstruction( RenderInstruction& instruction, BufferIndex updateBufferIndex )
381 {
382   DALI_ASSERT_DEBUG( NULL != mCamera );
383
384   TASK_LOG(Debug::General);
385
386   Viewport viewport;
387   bool viewportSet = QueryViewport( updateBufferIndex, viewport );
388
389   instruction.Reset( mCamera,
390                      GetFrameBuffer(),
391                      viewportSet ? &viewport : NULL,
392                      mClearEnabled ? &GetClearColor( updateBufferIndex ) : NULL );
393
394   if( mRequiresSync &&
395       mRefreshRate == Dali::RenderTask::REFRESH_ONCE &&
396       mResourcesFinished )
397   {
398     // create tracker if one doesn't yet exist.
399     if( !mRenderSyncTracker )
400     {
401       mRenderSyncTracker = new Render::RenderTracker();
402       mRenderMessageDispatcher->AddRenderTracker( *mRenderSyncTracker );
403     }
404     instruction.mRenderTracker = mRenderSyncTracker;
405   }
406   else
407   {
408     // no sync needed, texture FBOs are "ready" the same frame they are rendered to
409     instruction.mRenderTracker = NULL;
410   }
411 }
412
413 bool RenderTask::ViewMatrixUpdated()
414 {
415   bool retval = false;
416   if( mCamera )
417   {
418     retval = mCamera->ViewMatrixUpdated();
419   }
420   return retval;
421 }
422
423 void RenderTask::SetViewportPosition( BufferIndex updateBufferIndex, const Vector2& value )
424 {
425   mViewportPosition.Set( updateBufferIndex, value );
426 }
427
428 const Vector2& RenderTask::GetViewportPosition( BufferIndex bufferIndex ) const
429 {
430   return mViewportPosition[bufferIndex];
431 }
432
433 void RenderTask::BakeViewportPosition( BufferIndex updateBufferIndex, const Vector2& value )
434 {
435   mViewportPosition.Bake( updateBufferIndex, value );
436 }
437
438 void RenderTask::SetViewportSize( BufferIndex updateBufferIndex, const Vector2& value )
439 {
440   mViewportSize.Set( updateBufferIndex, value );
441 }
442
443 const Vector2& RenderTask::GetViewportSize( BufferIndex bufferIndex ) const
444 {
445   return mViewportSize[bufferIndex];
446 }
447
448 void RenderTask::BakeViewportSize( BufferIndex updateBufferIndex, const Vector2& value )
449 {
450   mViewportSize.Bake( updateBufferIndex, value );
451 }
452
453 bool RenderTask::GetViewportEnabled( BufferIndex bufferIndex ) const
454 {
455   if(fabsf(mViewportPosition[bufferIndex].x) > Math::MACHINE_EPSILON_1 ||
456      fabsf(mViewportPosition[bufferIndex].y) > Math::MACHINE_EPSILON_1 ||
457      fabsf(mViewportSize[bufferIndex].width) > Math::MACHINE_EPSILON_1 ||
458      fabsf(mViewportSize[bufferIndex].height) > Math::MACHINE_EPSILON_1)
459   {
460     return true;
461   }
462
463   return false;
464 }
465
466 void RenderTask::SetSyncRequired( bool requiresSync )
467 {
468   mRequiresSync = requiresSync;
469 }
470
471 void RenderTask::ResetDefaultProperties( BufferIndex updateBufferIndex )
472 {
473   // Reset default properties
474   mViewportPosition.ResetToBaseValue( updateBufferIndex );
475   mViewportSize.ResetToBaseValue( updateBufferIndex );
476   mClearColor.ResetToBaseValue( updateBufferIndex );
477 }
478
479 RenderTask::RenderTask()
480 : mViewportPosition( Vector2::ZERO),
481   mViewportSize( Vector2::ZERO),
482   mClearColor( Dali::RenderTask::DEFAULT_CLEAR_COLOR ),
483   mRenderMessageDispatcher( NULL ),
484   mResourceManager( NULL ),
485   mRenderSyncTracker( NULL ),
486   mSourceNode( NULL ),
487   mCameraNode( NULL ),
488   mCamera( NULL ),
489   mFrameBuffer(0),
490   mResourcesFinished( false ),
491   mWaitingToRender( false ),
492   mNotifyTrigger( false ),
493   mExclusive( Dali::RenderTask::DEFAULT_EXCLUSIVE ),
494   mClearEnabled( Dali::RenderTask::DEFAULT_CLEAR_ENABLED ),
495   mCullMode( Dali::RenderTask::DEFAULT_CULL_MODE ),
496   mRenderTarget( NULL ),
497   mState( (Dali::RenderTask::DEFAULT_REFRESH_RATE == Dali::RenderTask::REFRESH_ALWAYS)
498           ? RENDER_CONTINUOUSLY
499           : RENDER_ONCE_WAITING_FOR_RESOURCES ),
500   mRefreshRate( Dali::RenderTask::DEFAULT_REFRESH_RATE ),
501   mFrameCounter( 0u ),
502   mRenderedOnceCounter( 0u ),
503   mRequiresSync( false )
504 {
505 }
506
507 } // namespace SceneGraph
508
509 } // namespace Internal
510
511 } // namespace Dali