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>
39 RenderTask* RenderTask::New()
41 return new RenderTask();
44 RenderTask::~RenderTask()
46 // Remove exclusive flag from source node
49 if( mSourceNode && (this == mSourceNode->GetExclusiveRenderTask() ) )
51 mSourceNode->SetExclusiveRenderTask( NULL );
54 if( mFrameBufferResourceId )
56 mCompleteStatusManager->StopTrackingResource( mFrameBufferResourceId );
60 void RenderTask::SetSourceNode( Node* node )
62 // Remove exclusive flag from the old node, if necessary
64 this == mSourceNode->GetExclusiveRenderTask() )
66 mSourceNode->SetExclusiveRenderTask( NULL );
71 if ( mSourceNode && mExclusive )
73 mSourceNode->SetExclusiveRenderTask( this );
77 Node* RenderTask::GetSourceNode() const
82 void RenderTask::SetExclusive( bool exclusive )
84 mExclusive = exclusive;
90 mSourceNode->SetExclusiveRenderTask( this );
92 else if ( this == mSourceNode->GetExclusiveRenderTask() )
94 mSourceNode->SetExclusiveRenderTask( NULL );
99 bool RenderTask::IsExclusive() const
104 void RenderTask::SetCameraNode( Node* cameraNode )
107 if( cameraNode != mCameraNode )
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" );
116 mCameraNode = cameraNode;
120 void RenderTask::SetFrameBufferId( unsigned int resourceId )
122 if ( mFrameBufferResourceId != resourceId )
124 DALI_ASSERT_DEBUG(mCompleteStatusManager && "Complete status tracker is null");
125 if( mCompleteStatusManager )
127 if( resourceId && mState == RENDER_ONCE_WAITING_FOR_RESOURCES )
129 mCompleteStatusManager->TrackResource( resourceId );
132 if( mFrameBufferResourceId )
134 mCompleteStatusManager->StopTrackingResource( mFrameBufferResourceId );
138 mFrameBufferResourceId = resourceId;
142 unsigned int RenderTask::GetFrameBufferId() const
144 return mFrameBufferResourceId;
147 bool RenderTask::QueryViewport( BufferIndex bufferIndex, Viewport& viewport ) const
149 if( ! GetViewportEnabled( bufferIndex ) )
154 viewport.x = mViewportPosition[bufferIndex].x;
155 viewport.y = mViewportPosition[bufferIndex].y;
156 viewport.width = mViewportSize[bufferIndex].width;
157 viewport.height = mViewportSize[bufferIndex].height;
162 void RenderTask::SetClearColor( BufferIndex updateBufferIndex, const Vector4& value )
164 mClearColor.Set( updateBufferIndex, value );
167 const Vector4& RenderTask::GetClearColor( BufferIndex bufferIndex ) const
169 return mClearColor[bufferIndex];
172 void RenderTask::BakeClearColor( BufferIndex updateBufferIndex, const Vector4& value )
174 mClearColor.Bake( updateBufferIndex, value );
177 void RenderTask::SetClearEnabled( bool enabled )
179 mClearEnabled = enabled;
182 bool RenderTask::GetClearEnabled() const
184 return mClearEnabled;
187 void RenderTask::SetCullMode( bool mode )
192 bool RenderTask::GetCullMode() const
197 void RenderTask::SetRefreshRate( unsigned int refreshRate )
199 DALI_LOG_TRACE_METHOD_FMT(gRenderTaskLogFilter, "this:%p RefreshRate:%d\n", this, refreshRate);
201 mRefreshRate = refreshRate;
203 if( mRefreshRate > 0 )
205 mState = RENDER_CONTINUOUSLY;
207 if( mFrameBufferResourceId )
209 // Don't need tracking
210 DALI_ASSERT_DEBUG(mCompleteStatusManager && "Ready state tracker is null");
211 if( mCompleteStatusManager != NULL )
213 mCompleteStatusManager->StopTrackingResource( mFrameBufferResourceId );
219 mState = RENDER_ONCE_WAITING_FOR_RESOURCES;
220 mWaitingToRender = true;
221 mNotifyTrigger = false;
223 if( mFrameBufferResourceId )
225 DALI_ASSERT_DEBUG(mCompleteStatusManager && "Ready state tracker is null");
226 if( mCompleteStatusManager != NULL )
228 mCompleteStatusManager->TrackResource( mFrameBufferResourceId );
236 unsigned int RenderTask::GetRefreshRate() const
241 bool RenderTask::ReadyToRender( BufferIndex updateBufferIndex )
243 // If the source node of the render task is invisible we should still render
244 // We want the render task to complete and possible clear colors to happen
247 if ( NULL == mSourceNode ||
248 ( !mSourceNode->IsRoot() && NULL == mSourceNode->GetParent() ) )
250 TASK_LOG_FMT(Debug::General, " =F No source actor FC:%d\n", mFrameCounter );
252 // Source node is missing or disconnected
257 if ( NULL == mCameraNode ||
258 NULL == mCameraNode->GetParent() ||
259 !mCameraNode->HasAttachment() )
261 // Camera node is missing or disconnected
262 TASK_LOG_FMT(Debug::General, " =F No Camera FC:%d\n", mFrameCounter );
267 TASK_LOG_FMT(Debug::General, " =T (FBO ID:%d) FC:%d\n", mFrameBufferResourceId , mFrameCounter );
271 bool RenderTask::IsRenderRequired()
273 bool required = false;
277 case RENDER_CONTINUOUSLY:
278 required = (mFrameCounter == 0);
281 case RENDER_ONCE_WAITING_FOR_RESOURCES:
290 TASK_LOG_FMT( Debug::General, " State:%s = %s\n", STATE_STRING(mState), required?"T":"F" );
295 void RenderTask::SetResourcesFinished( bool resourcesFinished )
297 mResourcesFinished = resourcesFinished;
300 // Called every frame regardless of whether render was required.
301 // If render was not required, ignore resourcesFinished.
302 void RenderTask::UpdateState()
304 TASK_LOG_FMT( Debug::General, "(mResourcesFinished:%s) FC:%d State:%s RR:%d\n", mResourcesFinished?"T":"F", mFrameCounter, STATE_STRING(mState), mRefreshRate );
308 case RENDER_CONTINUOUSLY:
310 if( mRefreshRate != Dali::RenderTask::REFRESH_ALWAYS )
312 if( mFrameCounter == 0 )
314 if( mResourcesFinished )
316 ++mFrameCounter; // Only start skipping frames when resources are loaded
319 else // Continue counting to skip frames
322 if( mFrameCounter >= mRefreshRate )
332 case RENDER_ONCE_WAITING_FOR_RESOURCES:
334 if( mResourcesFinished )
336 mState = RENDERED_ONCE;
343 if( mFrameBufferResourceId > 0 )
345 // Query if the framebuffer is complete:
346 DALI_ASSERT_DEBUG(mCompleteStatusManager && "Complete status tracker is null");
347 if( mCompleteStatusManager != NULL &&
348 CompleteStatusManager::COMPLETE == mCompleteStatusManager->GetStatus( mFrameBufferResourceId ) )
350 mWaitingToRender = false;
351 mNotifyTrigger = true;
355 mWaitingToRender = true;
360 mWaitingToRender = false;
361 mNotifyTrigger = true;
370 TASK_LOG_FMT( Debug::General, " EXIT FC:%d State:%s Notify:%s\n", mFrameCounter, STATE_STRING(mState), mNotifyTrigger?"T":"F");
373 bool RenderTask::IsWaitingToRender()
375 TASK_LOG_FMT(Debug::Verbose, " State:%s waiting:%s \n", STATE_STRING(mState), mWaitingToRender?"T":"F");
376 return mWaitingToRender;
379 bool RenderTask::HasRendered()
382 if( mNotifyTrigger == true )
384 ++mRenderedOnceCounter;
385 mState = RENDERED_ONCE_AND_NOTIFIED;
386 mNotifyTrigger = false;
390 TASK_LOG_FMT(Debug::Verbose, " State:%s hasRendered:%s \n", STATE_STRING(mState), notify?"T":"F");
394 unsigned int RenderTask::GetRenderedOnceCounter() const
396 return mRenderedOnceCounter;
400 const Matrix& RenderTask::GetViewMatrix( BufferIndex bufferIndex ) const
402 DALI_ASSERT_DEBUG( NULL != mCameraAttachment );
404 return mCameraAttachment->GetViewMatrix( bufferIndex );
407 const Matrix& RenderTask::GetProjectionMatrix( BufferIndex bufferIndex ) const
409 DALI_ASSERT_DEBUG( NULL != mCameraAttachment );
411 return mCameraAttachment->GetProjectionMatrix( bufferIndex );
414 void RenderTask::PrepareRenderInstruction( RenderInstruction& instruction, BufferIndex updateBufferIndex )
416 DALI_ASSERT_DEBUG( NULL != mCameraAttachment );
418 TASK_LOG(Debug::General);
421 bool viewportSet = QueryViewport( updateBufferIndex, viewport );
423 instruction.Reset( mCameraAttachment,
425 viewportSet ? &viewport : NULL,
426 mClearEnabled ? &GetClearColor( updateBufferIndex ) : NULL );
429 bool RenderTask::ViewMatrixUpdated()
432 if( mCameraAttachment )
434 retval = mCameraAttachment->ViewMatrixUpdated();
439 void RenderTask::SetCompleteStatusManager(CompleteStatusManager* completeStatusManager)
441 mCompleteStatusManager = completeStatusManager;
444 void RenderTask::SetViewportPosition( BufferIndex updateBufferIndex, const Vector2& value )
446 mViewportPosition.Set( updateBufferIndex, value );
449 const Vector2& RenderTask::GetViewportPosition( BufferIndex bufferIndex ) const
451 return mViewportPosition[bufferIndex];
454 void RenderTask::BakeViewportPosition( BufferIndex updateBufferIndex, const Vector2& value )
456 mViewportPosition.Bake( updateBufferIndex, value );
459 void RenderTask::SetViewportSize( BufferIndex updateBufferIndex, const Vector2& value )
461 mViewportSize.Set( updateBufferIndex, value );
464 const Vector2& RenderTask::GetViewportSize( BufferIndex bufferIndex ) const
466 return mViewportSize[bufferIndex];
469 void RenderTask::BakeViewportSize( BufferIndex updateBufferIndex, const Vector2& value )
471 mViewportSize.Bake( updateBufferIndex, value );
474 bool RenderTask::GetViewportEnabled( BufferIndex bufferIndex ) const
476 if(fabsf(mViewportPosition[bufferIndex].x) > Math::MACHINE_EPSILON_1 ||
477 fabsf(mViewportPosition[bufferIndex].y) > Math::MACHINE_EPSILON_1 ||
478 fabsf(mViewportSize[bufferIndex].width) > Math::MACHINE_EPSILON_1 ||
479 fabsf(mViewportSize[bufferIndex].height) > Math::MACHINE_EPSILON_1)
487 Node* RenderTask::GetCamera() const
492 void RenderTask::ResetDefaultProperties( BufferIndex updateBufferIndex )
494 // Reset default properties
495 mViewportPosition.ResetToBaseValue( updateBufferIndex );
496 mViewportSize.ResetToBaseValue( updateBufferIndex );
497 mClearColor.ResetToBaseValue( updateBufferIndex );
500 RenderTask::RenderTask()
501 : mViewportPosition( Vector2::ZERO),
502 mViewportSize( Vector2::ZERO),
503 mClearColor( Dali::RenderTask::DEFAULT_CLEAR_COLOR ),
504 mCompleteStatusManager( NULL ),
507 mCameraAttachment( NULL ),
508 mFrameBufferResourceId( 0 ),
509 mResourcesFinished( false ),
510 mWaitingToRender( false ),
511 mNotifyTrigger( false ),
512 mExclusive( Dali::RenderTask::DEFAULT_EXCLUSIVE ),
513 mClearEnabled( Dali::RenderTask::DEFAULT_CLEAR_ENABLED ),
514 mCullMode( Dali::RenderTask::DEFAULT_CULL_MODE ),
515 mRenderTarget( NULL ),
516 mState( (Dali::RenderTask::DEFAULT_REFRESH_RATE == Dali::RenderTask::REFRESH_ALWAYS)
517 ? RENDER_CONTINUOUSLY
518 : RENDER_ONCE_WAITING_FOR_RESOURCES ),
519 mRefreshRate( Dali::RenderTask::DEFAULT_REFRESH_RATE ),
521 mRenderedOnceCounter( 0u )
525 } // namespace SceneGraph
527 } // namespace Internal