2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
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>
29 #include <dali/internal/update/render-tasks/scene-graph-render-task-debug.h>
33 const unsigned int NUM_FRAMES_BEFORE_NOTIFY_FINISHED(3);
34 const unsigned int COUNTDOWN_COMPLETE(-1);
35 } // anonymous namespace
45 RenderTask* RenderTask::New()
47 return new RenderTask();
50 RenderTask::~RenderTask()
52 // Remove exclusive flag from source node
55 if( mSourceNode && (this == mSourceNode->GetExclusiveRenderTask() ) )
57 mSourceNode->SetExclusiveRenderTask( NULL );
60 if( mFrameBufferResourceId )
62 mCompleteStatusManager->StopTrackingResource( mFrameBufferResourceId );
66 void RenderTask::SetSourceNode( Node* node )
68 // Remove exclusive flag from the old node, if necessary
70 this == mSourceNode->GetExclusiveRenderTask() )
72 mSourceNode->SetExclusiveRenderTask( NULL );
77 if ( mSourceNode && mExclusive )
79 mSourceNode->SetExclusiveRenderTask( this );
83 Node* RenderTask::GetSourceNode() const
88 void RenderTask::SetExclusive( bool exclusive )
90 mExclusive = exclusive;
96 mSourceNode->SetExclusiveRenderTask( this );
98 else if ( this == mSourceNode->GetExclusiveRenderTask() )
100 mSourceNode->SetExclusiveRenderTask( NULL );
105 bool RenderTask::IsExclusive() const
110 void RenderTask::SetCameraNode( Node* cameraNode )
113 if( cameraNode != mCameraNode )
117 // get attachment. when camera node is changed we will get a message from event thread object
118 // so no need to observe the node here
119 mCameraAttachment = dynamic_cast< CameraAttachment* >( &cameraNode->GetAttachment() );
120 DALI_ASSERT_DEBUG( mCameraAttachment && "Camera without attachment" );
122 mCameraNode = cameraNode;
126 void RenderTask::SetFrameBufferId( unsigned int resourceId )
128 if ( mFrameBufferResourceId != resourceId )
130 DALI_ASSERT_DEBUG(mCompleteStatusManager && "Complete status tracker is null");
131 if( mCompleteStatusManager )
133 if( resourceId && mState == RENDER_ONCE_WAITING_FOR_RESOURCES )
135 mCompleteStatusManager->TrackResource( resourceId );
138 if( mFrameBufferResourceId )
140 mCompleteStatusManager->StopTrackingResource( mFrameBufferResourceId );
144 mFrameBufferResourceId = resourceId;
148 unsigned int RenderTask::GetFrameBufferId() const
150 return mFrameBufferResourceId;
153 bool RenderTask::QueryViewport( BufferIndex bufferIndex, Viewport& viewport ) const
155 if( ! GetViewportEnabled( bufferIndex ) )
160 viewport.x = mViewportPosition[bufferIndex].x;
161 viewport.y = mViewportPosition[bufferIndex].y;
162 viewport.width = mViewportSize[bufferIndex].width;
163 viewport.height = mViewportSize[bufferIndex].height;
168 void RenderTask::SetClearColor( BufferIndex updateBufferIndex, const Vector4& value )
170 mClearColor.Set( updateBufferIndex, value );
173 const Vector4& RenderTask::GetClearColor( BufferIndex bufferIndex ) const
175 return mClearColor[bufferIndex];
178 void RenderTask::BakeClearColor( BufferIndex updateBufferIndex, const Vector4& value )
180 mClearColor.Bake( updateBufferIndex, value );
183 void RenderTask::SetClearEnabled( bool enabled )
185 mClearEnabled = enabled;
188 bool RenderTask::GetClearEnabled() const
190 return mClearEnabled;
193 void RenderTask::SetCullMode( bool mode )
198 bool RenderTask::GetCullMode() const
203 void RenderTask::SetRefreshRate( unsigned int refreshRate )
205 DALI_LOG_TRACE_METHOD_FMT(gRenderTaskLogFilter, "this:%p RefreshRate:%d\n", this, refreshRate);
207 mRefreshRate = refreshRate;
209 if( mRefreshRate > 0 )
211 mState = RENDER_CONTINUOUSLY;
213 if( mFrameBufferResourceId )
215 // Don't need tracking
216 DALI_ASSERT_DEBUG(mCompleteStatusManager && "Ready state tracker is null");
217 if( mCompleteStatusManager != NULL )
219 mCompleteStatusManager->StopTrackingResource( mFrameBufferResourceId );
225 mState = RENDER_ONCE_WAITING_FOR_RESOURCES;
226 mWaitingToRender = true;
227 mNotifyTrigger = false;
229 if( mFrameBufferResourceId )
231 DALI_ASSERT_DEBUG(mCompleteStatusManager && "Ready state tracker is null");
232 if( mCompleteStatusManager != NULL )
234 mCompleteStatusManager->TrackResource( mFrameBufferResourceId );
242 unsigned int RenderTask::GetRefreshRate() const
247 bool RenderTask::ReadyToRender( BufferIndex updateBufferIndex )
249 if ( NULL == mSourceNode ||
250 ( !mSourceNode->IsRoot() && NULL == mSourceNode->GetParent() ) )
252 TASK_LOG_FMT(Debug::General, " =F No source actor FC:%d\n", mFrameCounter );
254 // Source node is missing or disconnected
258 // Check if the source node (root actor) and all its ancestors are visible.
259 if( !mSourceNode->IsFullyVisible( updateBufferIndex ) )
261 TASK_LOG_FMT(Debug::General, " =F No visible source FC:%d\n", mFrameCounter );
265 if ( NULL == mCameraNode ||
266 NULL == mCameraNode->GetParent() ||
267 !mCameraNode->HasAttachment() )
269 // Camera node is missing or disconnected
270 TASK_LOG_FMT(Debug::General, " =F No Camera FC:%d\n", mFrameCounter );
275 TASK_LOG_FMT(Debug::General, " =T (FBO ID:%d) FC:%d\n", mFrameBufferResourceId , mFrameCounter );
279 bool RenderTask::IsRenderRequired()
281 bool required = false;
285 case RENDER_CONTINUOUSLY:
286 required = (mFrameCounter == 0);
289 case RENDER_ONCE_WAITING_FOR_RESOURCES:
298 TASK_LOG_FMT( Debug::General, " State:%s = %s\n", STATE_STRING(mState), required?"T":"F" );
303 void RenderTask::SetResourcesFinished( bool resourcesFinished )
305 mResourcesFinished = resourcesFinished;
308 // Called every frame regardless of whether render was required.
309 // If render was not required, ignore resourcesFinished.
310 void RenderTask::UpdateState()
312 TASK_LOG_FMT( Debug::General, "(mResourcesFinished:%s) FC:%d State:%s RR:%d\n", mResourcesFinished?"T":"F", mFrameCounter, STATE_STRING(mState), mRefreshRate );
316 case RENDER_CONTINUOUSLY:
318 if( mRefreshRate != Dali::RenderTask::REFRESH_ALWAYS )
320 if( mFrameCounter == 0 )
322 if( mResourcesFinished )
324 ++mFrameCounter; // Only start skipping frames when resources are loaded
327 else // Continue counting to skip frames
330 if( mFrameCounter >= mRefreshRate )
340 case RENDER_ONCE_WAITING_FOR_RESOURCES:
342 if( mResourcesFinished )
344 mState = RENDERED_ONCE;
351 if( mFrameBufferResourceId > 0 )
353 // Query if the framebuffer is complete:
354 DALI_ASSERT_DEBUG(mCompleteStatusManager && "Complete status tracker is null");
355 if( mCompleteStatusManager != NULL &&
356 CompleteStatusManager::COMPLETE == mCompleteStatusManager->GetStatus( mFrameBufferResourceId ) )
358 mWaitingToRender = false;
359 mNotifyTrigger = true;
363 mWaitingToRender = true;
368 mWaitingToRender = false;
369 mNotifyTrigger = true;
378 TASK_LOG_FMT( Debug::General, " EXIT FC:%d State:%s Notify:%s\n", mFrameCounter, STATE_STRING(mState), mNotifyTrigger?"T":"F");
381 bool RenderTask::IsWaitingToRender()
383 TASK_LOG_FMT(Debug::Verbose, " State:%s waiting:%s \n", STATE_STRING(mState), mWaitingToRender?"T":"F");
384 return mWaitingToRender;
387 bool RenderTask::HasRendered()
390 if( mNotifyTrigger == true )
392 ++mRenderedOnceCounter;
393 mState = RENDERED_ONCE_AND_NOTIFIED;
394 mNotifyTrigger = false;
398 TASK_LOG_FMT(Debug::Verbose, " State:%s hasRendered:%s \n", STATE_STRING(mState), notify?"T":"F");
402 unsigned int RenderTask::GetRenderedOnceCounter() const
404 return mRenderedOnceCounter;
408 const Matrix& RenderTask::GetViewMatrix( BufferIndex bufferIndex ) const
410 DALI_ASSERT_DEBUG( NULL != mCameraAttachment );
412 return mCameraAttachment->GetViewMatrix( bufferIndex );
415 const Matrix& RenderTask::GetProjectionMatrix( BufferIndex bufferIndex ) const
417 DALI_ASSERT_DEBUG( NULL != mCameraAttachment );
419 return mCameraAttachment->GetProjectionMatrix( bufferIndex );
422 void RenderTask::PrepareRenderInstruction( RenderInstruction& instruction, BufferIndex updateBufferIndex )
424 DALI_ASSERT_DEBUG( NULL != mCameraAttachment );
426 TASK_LOG(Debug::General);
429 bool viewportSet = QueryViewport( updateBufferIndex, viewport );
431 instruction.Reset( mCameraAttachment,
433 viewportSet ? &viewport : NULL,
434 mClearEnabled ? &GetClearColor( updateBufferIndex ) : NULL );
437 bool RenderTask::ViewMatrixUpdated()
440 if( mCameraAttachment )
442 retval = mCameraAttachment->ViewMatrixUpdated();
447 void RenderTask::SetCompleteStatusManager(CompleteStatusManager* completeStatusManager)
449 mCompleteStatusManager = completeStatusManager;
452 void RenderTask::SetViewportPosition( BufferIndex updateBufferIndex, const Vector2& value )
454 mViewportPosition.Set( updateBufferIndex, value );
457 const Vector2& RenderTask::GetViewportPosition( BufferIndex bufferIndex ) const
459 return mViewportPosition[bufferIndex];
462 void RenderTask::BakeViewportPosition( BufferIndex updateBufferIndex, const Vector2& value )
464 mViewportPosition.Bake( updateBufferIndex, value );
467 void RenderTask::SetViewportSize( BufferIndex updateBufferIndex, const Vector2& value )
469 mViewportSize.Set( updateBufferIndex, value );
472 const Vector2& RenderTask::GetViewportSize( BufferIndex bufferIndex ) const
474 return mViewportSize[bufferIndex];
477 void RenderTask::BakeViewportSize( BufferIndex updateBufferIndex, const Vector2& value )
479 mViewportSize.Bake( updateBufferIndex, value );
482 bool RenderTask::GetViewportEnabled( BufferIndex bufferIndex ) const
484 if(fabsf(mViewportPosition[bufferIndex].x) > Math::MACHINE_EPSILON_1 ||
485 fabsf(mViewportPosition[bufferIndex].y) > Math::MACHINE_EPSILON_1 ||
486 fabsf(mViewportSize[bufferIndex].width) > Math::MACHINE_EPSILON_1 ||
487 fabsf(mViewportSize[bufferIndex].height) > Math::MACHINE_EPSILON_1)
495 Node* RenderTask::GetCamera() const
500 void RenderTask::ResetDefaultProperties( BufferIndex updateBufferIndex )
502 // Reset default properties
503 mViewportPosition.ResetToBaseValue( updateBufferIndex );
504 mViewportSize.ResetToBaseValue( updateBufferIndex );
505 mClearColor.ResetToBaseValue( updateBufferIndex );
508 RenderTask::RenderTask()
509 : mViewportPosition( Vector2::ZERO),
510 mViewportSize( Vector2::ZERO),
511 mClearColor( Dali::RenderTask::DEFAULT_CLEAR_COLOR ),
512 mCompleteStatusManager( NULL ),
515 mCameraAttachment( NULL ),
516 mFrameBufferResourceId( 0 ),
517 mResourcesFinished( false ),
518 mWaitingToRender( false ),
519 mNotifyTrigger( false ),
520 mExclusive( Dali::RenderTask::DEFAULT_EXCLUSIVE ),
521 mClearEnabled( Dali::RenderTask::DEFAULT_CLEAR_ENABLED ),
522 mCullMode( Dali::RenderTask::DEFAULT_CULL_MODE ),
523 mRenderTarget( NULL ),
524 mState( (Dali::RenderTask::DEFAULT_REFRESH_RATE == Dali::RenderTask::REFRESH_ALWAYS)
525 ? RENDER_CONTINUOUSLY
526 : RENDER_ONCE_WAITING_FOR_RESOURCES ),
527 mRefreshRate( Dali::RenderTask::DEFAULT_REFRESH_RATE ),
529 mRenderedOnceCounter( 0u )
533 } // namespace SceneGraph
535 } // namespace Internal