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/render/common/render-instruction.h>
28 #include <dali/internal/update/render-tasks/scene-graph-render-task-debug.h>
38 RenderTask* RenderTask::New()
40 return new RenderTask();
43 RenderTask::~RenderTask()
45 // Remove exclusive flag from source node
48 if( mSourceNode && (this == mSourceNode->GetExclusiveRenderTask() ) )
50 mSourceNode->SetExclusiveRenderTask( NULL );
53 if( mFrameBufferResourceId )
55 mCompleteStatusManager->StopTrackingResource( mFrameBufferResourceId );
59 void RenderTask::SetSourceNode( Node* node )
61 // Remove exclusive flag from the old node, if necessary
63 this == mSourceNode->GetExclusiveRenderTask() )
65 mSourceNode->SetExclusiveRenderTask( NULL );
70 if ( mSourceNode && mExclusive )
72 mSourceNode->SetExclusiveRenderTask( this );
76 Node* RenderTask::GetSourceNode() const
81 void RenderTask::SetExclusive( bool exclusive )
83 mExclusive = exclusive;
89 mSourceNode->SetExclusiveRenderTask( this );
91 else if ( this == mSourceNode->GetExclusiveRenderTask() )
93 mSourceNode->SetExclusiveRenderTask( NULL );
98 bool RenderTask::IsExclusive() const
103 void RenderTask::SetCameraNode( Node* cameraNode )
106 if( cameraNode != mCameraNode )
110 // get attachment. when camera node is changed we will get a message from event thread object
111 // so no need to observe the node here
112 mCameraAttachment = dynamic_cast< CameraAttachment* >( &cameraNode->GetAttachment() );
113 DALI_ASSERT_DEBUG( mCameraAttachment && "Camera without attachment" );
115 mCameraNode = cameraNode;
119 void RenderTask::SetFrameBufferId( unsigned int resourceId )
121 if ( mFrameBufferResourceId != resourceId )
123 DALI_ASSERT_DEBUG(mCompleteStatusManager && "Complete status tracker is null");
124 if( mCompleteStatusManager )
126 if( resourceId && mState == RENDER_ONCE_WAITING_FOR_RESOURCES )
128 mCompleteStatusManager->TrackResource( resourceId );
131 if( mFrameBufferResourceId )
133 mCompleteStatusManager->StopTrackingResource( mFrameBufferResourceId );
137 mFrameBufferResourceId = resourceId;
141 unsigned int RenderTask::GetFrameBufferId() const
143 return mFrameBufferResourceId;
146 bool RenderTask::QueryViewport( BufferIndex bufferIndex, Viewport& viewport ) const
148 if( ! GetViewportEnabled( bufferIndex ) )
153 viewport.x = mViewportPosition[bufferIndex].x;
154 viewport.y = mViewportPosition[bufferIndex].y;
155 viewport.width = mViewportSize[bufferIndex].width;
156 viewport.height = mViewportSize[bufferIndex].height;
161 void RenderTask::SetClearColor( BufferIndex updateBufferIndex, const Vector4& value )
163 mClearColor.Set( updateBufferIndex, value );
166 const Vector4& RenderTask::GetClearColor( BufferIndex bufferIndex ) const
168 return mClearColor[bufferIndex];
171 void RenderTask::BakeClearColor( BufferIndex updateBufferIndex, const Vector4& value )
173 mClearColor.Bake( updateBufferIndex, value );
176 void RenderTask::SetClearEnabled( bool enabled )
178 mClearEnabled = enabled;
181 bool RenderTask::GetClearEnabled() const
183 return mClearEnabled;
186 void RenderTask::SetCullMode( bool mode )
191 bool RenderTask::GetCullMode() const
196 void RenderTask::SetRefreshRate( unsigned int refreshRate )
198 DALI_LOG_TRACE_METHOD_FMT(gRenderTaskLogFilter, "this:%p RefreshRate:%d\n", this, refreshRate);
200 mRefreshRate = refreshRate;
202 if( mRefreshRate > 0 )
204 mState = RENDER_CONTINUOUSLY;
206 if( mFrameBufferResourceId )
208 // Don't need tracking
209 DALI_ASSERT_DEBUG(mCompleteStatusManager && "Ready state tracker is null");
210 if( mCompleteStatusManager != NULL )
212 mCompleteStatusManager->StopTrackingResource( mFrameBufferResourceId );
218 mState = RENDER_ONCE_WAITING_FOR_RESOURCES;
219 mWaitingToRender = true;
220 mNotifyTrigger = false;
222 if( mFrameBufferResourceId )
224 DALI_ASSERT_DEBUG(mCompleteStatusManager && "Ready state tracker is null");
225 if( mCompleteStatusManager != NULL )
227 mCompleteStatusManager->TrackResource( mFrameBufferResourceId );
235 unsigned int RenderTask::GetRefreshRate() const
240 bool RenderTask::ReadyToRender( BufferIndex updateBufferIndex )
242 // If the source node of the render task is invisible we should still render
243 // We want the render task to complete and possible clear colors to happen
246 if ( NULL == mSourceNode ||
247 ( !mSourceNode->IsRoot() && NULL == mSourceNode->GetParent() ) )
249 TASK_LOG_FMT(Debug::General, " =F No source actor FC:%d\n", mFrameCounter );
251 // Source node is missing or disconnected
256 if ( NULL == mCameraNode ||
257 NULL == mCameraNode->GetParent() ||
258 !mCameraNode->HasAttachment() )
260 // Camera node is missing or disconnected
261 TASK_LOG_FMT(Debug::General, " =F No Camera FC:%d\n", mFrameCounter );
266 TASK_LOG_FMT(Debug::General, " =T (FBO ID:%d) FC:%d\n", mFrameBufferResourceId , mFrameCounter );
270 bool RenderTask::IsRenderRequired()
272 bool required = false;
276 case RENDER_CONTINUOUSLY:
277 required = (mFrameCounter == 0);
280 case RENDER_ONCE_WAITING_FOR_RESOURCES:
289 TASK_LOG_FMT( Debug::General, " State:%s = %s\n", STATE_STRING(mState), required?"T":"F" );
294 void RenderTask::SetResourcesFinished( bool resourcesFinished )
296 mResourcesFinished = resourcesFinished;
299 // Called every frame regardless of whether render was required.
300 // If render was not required, ignore resourcesFinished.
301 void RenderTask::UpdateState()
303 TASK_LOG_FMT( Debug::General, "(mResourcesFinished:%s) FC:%d State:%s RR:%d\n", mResourcesFinished?"T":"F", mFrameCounter, STATE_STRING(mState), mRefreshRate );
307 case RENDER_CONTINUOUSLY:
309 if( mRefreshRate != Dali::RenderTask::REFRESH_ALWAYS )
311 if( mFrameCounter == 0 )
313 if( mResourcesFinished )
315 ++mFrameCounter; // Only start skipping frames when resources are loaded
318 else // Continue counting to skip frames
321 if( mFrameCounter >= mRefreshRate )
331 case RENDER_ONCE_WAITING_FOR_RESOURCES:
333 if( mResourcesFinished )
335 mState = RENDERED_ONCE;
342 if( mFrameBufferResourceId > 0 )
344 // Query if the framebuffer is complete:
345 DALI_ASSERT_DEBUG(mCompleteStatusManager && "Complete status tracker is null");
346 if( mCompleteStatusManager != NULL &&
347 CompleteStatusManager::COMPLETE == mCompleteStatusManager->GetStatus( mFrameBufferResourceId ) )
349 mWaitingToRender = false;
350 mNotifyTrigger = true;
354 mWaitingToRender = true;
359 mWaitingToRender = false;
360 mNotifyTrigger = true;
369 TASK_LOG_FMT( Debug::General, " EXIT FC:%d State:%s Notify:%s\n", mFrameCounter, STATE_STRING(mState), mNotifyTrigger?"T":"F");
372 bool RenderTask::IsWaitingToRender()
374 TASK_LOG_FMT(Debug::Verbose, " State:%s waiting:%s \n", STATE_STRING(mState), mWaitingToRender?"T":"F");
375 return mWaitingToRender;
378 bool RenderTask::HasRendered()
381 if( mNotifyTrigger == true )
383 ++mRenderedOnceCounter;
384 mState = RENDERED_ONCE_AND_NOTIFIED;
385 mNotifyTrigger = false;
389 TASK_LOG_FMT(Debug::Verbose, " State:%s hasRendered:%s \n", STATE_STRING(mState), notify?"T":"F");
393 unsigned int RenderTask::GetRenderedOnceCounter() const
395 return mRenderedOnceCounter;
399 const Matrix& RenderTask::GetViewMatrix( BufferIndex bufferIndex ) const
401 DALI_ASSERT_DEBUG( NULL != mCameraAttachment );
403 return mCameraAttachment->GetViewMatrix( bufferIndex );
406 SceneGraph::CameraAttachment& RenderTask::GetCameraAttachment() const
408 DALI_ASSERT_DEBUG( NULL != mCameraAttachment );
409 return *mCameraAttachment;
412 const Matrix& RenderTask::GetProjectionMatrix( BufferIndex bufferIndex ) const
414 DALI_ASSERT_DEBUG( NULL != mCameraAttachment );
416 return mCameraAttachment->GetProjectionMatrix( bufferIndex );
419 void RenderTask::PrepareRenderInstruction( RenderInstruction& instruction, BufferIndex updateBufferIndex )
421 DALI_ASSERT_DEBUG( NULL != mCameraAttachment );
423 TASK_LOG(Debug::General);
426 bool viewportSet = QueryViewport( updateBufferIndex, viewport );
428 instruction.Reset( mCameraAttachment,
430 viewportSet ? &viewport : NULL,
431 mClearEnabled ? &GetClearColor( updateBufferIndex ) : NULL );
434 bool RenderTask::ViewMatrixUpdated()
437 if( mCameraAttachment )
439 retval = mCameraAttachment->ViewMatrixUpdated();
444 void RenderTask::SetCompleteStatusManager(CompleteStatusManager* completeStatusManager)
446 mCompleteStatusManager = completeStatusManager;
449 void RenderTask::SetViewportPosition( BufferIndex updateBufferIndex, const Vector2& value )
451 mViewportPosition.Set( updateBufferIndex, value );
454 const Vector2& RenderTask::GetViewportPosition( BufferIndex bufferIndex ) const
456 return mViewportPosition[bufferIndex];
459 void RenderTask::BakeViewportPosition( BufferIndex updateBufferIndex, const Vector2& value )
461 mViewportPosition.Bake( updateBufferIndex, value );
464 void RenderTask::SetViewportSize( BufferIndex updateBufferIndex, const Vector2& value )
466 mViewportSize.Set( updateBufferIndex, value );
469 const Vector2& RenderTask::GetViewportSize( BufferIndex bufferIndex ) const
471 return mViewportSize[bufferIndex];
474 void RenderTask::BakeViewportSize( BufferIndex updateBufferIndex, const Vector2& value )
476 mViewportSize.Bake( updateBufferIndex, value );
479 bool RenderTask::GetViewportEnabled( BufferIndex bufferIndex ) const
481 if(fabsf(mViewportPosition[bufferIndex].x) > Math::MACHINE_EPSILON_1 ||
482 fabsf(mViewportPosition[bufferIndex].y) > Math::MACHINE_EPSILON_1 ||
483 fabsf(mViewportSize[bufferIndex].width) > Math::MACHINE_EPSILON_1 ||
484 fabsf(mViewportSize[bufferIndex].height) > Math::MACHINE_EPSILON_1)
492 Node* RenderTask::GetCamera() const
497 void RenderTask::ResetDefaultProperties( BufferIndex updateBufferIndex )
499 // Reset default properties
500 mViewportPosition.ResetToBaseValue( updateBufferIndex );
501 mViewportSize.ResetToBaseValue( updateBufferIndex );
502 mClearColor.ResetToBaseValue( updateBufferIndex );
505 RenderTask::RenderTask()
506 : mViewportPosition( Vector2::ZERO),
507 mViewportSize( Vector2::ZERO),
508 mClearColor( Dali::RenderTask::DEFAULT_CLEAR_COLOR ),
509 mCompleteStatusManager( NULL ),
512 mCameraAttachment( NULL ),
513 mFrameBufferResourceId( 0 ),
514 mResourcesFinished( false ),
515 mWaitingToRender( false ),
516 mNotifyTrigger( false ),
517 mExclusive( Dali::RenderTask::DEFAULT_EXCLUSIVE ),
518 mClearEnabled( Dali::RenderTask::DEFAULT_CLEAR_ENABLED ),
519 mCullMode( Dali::RenderTask::DEFAULT_CULL_MODE ),
520 mRenderTarget( NULL ),
521 mState( (Dali::RenderTask::DEFAULT_REFRESH_RATE == Dali::RenderTask::REFRESH_ALWAYS)
522 ? RENDER_CONTINUOUSLY
523 : RENDER_ONCE_WAITING_FOR_RESOURCES ),
524 mRefreshRate( Dali::RenderTask::DEFAULT_REFRESH_RATE ),
526 mRenderedOnceCounter( 0u )
530 } // namespace SceneGraph
532 } // namespace Internal