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