2 * Copyright (c) 2018 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/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>
28 #include <dali/internal/update/render-tasks/scene-graph-render-task-debug.h>
38 RenderTask* RenderTask::New()
40 return new RenderTask();
43 RenderTask::~RenderTask()
47 mSourceNode->RemoveObserver( *this );
50 mSourceNode->SetExclusiveRenderTask( nullptr );
55 mCameraNode->RemoveObserver( *this );
57 if( mRenderSyncTracker )
59 mRenderMessageDispatcher->RemoveRenderTracker( *mRenderSyncTracker );
63 void RenderTask::Initialize( RenderMessageDispatcher& renderMessageDispatcher )
65 mRenderMessageDispatcher = &renderMessageDispatcher;
68 void RenderTask::SetSourceNode( Node* node )
70 // Stop observing the old node (if we were)
73 mSourceNode->RemoveObserver( *this );
74 if( this == mSourceNode->GetExclusiveRenderTask() )
76 mSourceNode->SetExclusiveRenderTask( nullptr );
84 mSourceNode->AddObserver( *this );
87 mSourceNode->SetExclusiveRenderTask( this );
93 Node* RenderTask::GetSourceNode() const
98 void RenderTask::SetExclusive( bool exclusive )
100 mExclusive = exclusive;
106 mSourceNode->SetExclusiveRenderTask( this );
108 else if ( this == mSourceNode->GetExclusiveRenderTask() )
110 mSourceNode->SetExclusiveRenderTask( nullptr );
115 bool RenderTask::IsExclusive() const
120 void RenderTask::SetCamera( Node* cameraNode, Camera* camera )
124 mCameraNode->RemoveObserver( *this );
127 mCameraNode = cameraNode;
132 mCameraNode->AddObserver( *this );
137 void RenderTask::SetFrameBuffer( Render::FrameBuffer* frameBuffer )
139 mFrameBuffer = frameBuffer;
142 Render::FrameBuffer* RenderTask::GetFrameBuffer()
147 bool RenderTask::QueryViewport( BufferIndex bufferIndex, Viewport& viewport ) const
149 if( ! GetViewportEnabled( bufferIndex ) )
154 viewport.x = static_cast<int>( mViewportPosition[bufferIndex].x ); // truncated
155 viewport.y = static_cast<int>( mViewportPosition[bufferIndex].y ); // truncated
156 viewport.width = static_cast<int>( mViewportSize[bufferIndex].width ); // truncated
157 viewport.height = static_cast<int>( mViewportSize[bufferIndex].height ); // truncated
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( uint32_t 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;
209 mState = RENDER_ONCE_WAITING_FOR_RESOURCES;
210 mWaitingToRender = true;
211 mNotifyTrigger = false;
217 uint32_t RenderTask::GetRefreshRate() const
222 bool RenderTask::ReadyToRender( BufferIndex updateBufferIndex )
227 bool RenderTask::IsRenderRequired()
229 bool required = false;
233 case RENDER_CONTINUOUSLY:
235 required = (mFrameCounter == 0);
238 case RENDER_ONCE_WAITING_FOR_RESOURCES:
250 TASK_LOG_FMT( Debug::General, " State:%s = %s\n", STATE_STRING(mState), required?"T":"F" );
255 // Called every frame regardless of whether render was required.
256 // If render was not required, ignore resourcesFinished.
257 void RenderTask::UpdateState()
259 TASK_LOG_FMT( Debug::General, "FC:%d State:%s RR:%d\n", mFrameCounter, STATE_STRING(mState), mRefreshRate );
263 case RENDER_CONTINUOUSLY:
265 if( mRefreshRate != Dali::RenderTask::REFRESH_ALWAYS )
267 if( mFrameCounter == 0 )
269 ++mFrameCounter; // Only start skipping frames when resources are loaded
271 else // Continue counting to skip frames
274 if( mFrameCounter >= mRefreshRate )
284 case RENDER_ONCE_WAITING_FOR_RESOURCES:
286 mState = RENDERED_ONCE;
292 mWaitingToRender = true;
293 mNotifyTrigger = false;
296 if( !mRenderSyncTracker || (mRenderSyncTracker && mRenderSyncTracker->IsSynced() ))
298 mWaitingToRender = false;
299 mNotifyTrigger = true;
304 mWaitingToRender = false;
305 mNotifyTrigger = true;
315 TASK_LOG_FMT( Debug::General, " EXIT FC:%d State:%s Notify:%s\n", mFrameCounter, STATE_STRING(mState), mNotifyTrigger?"T":"F");
318 bool RenderTask::IsWaitingToRender()
320 TASK_LOG_FMT(Debug::Verbose, " State:%s waiting:%s \n", STATE_STRING(mState), mWaitingToRender?"T":"F");
321 return mWaitingToRender;
324 bool RenderTask::HasRendered()
327 if( mNotifyTrigger == true )
329 ++mRenderedOnceCounter;
330 mState = RENDERED_ONCE_AND_NOTIFIED;
331 mNotifyTrigger = false;
335 TASK_LOG_FMT(Debug::Verbose, " State:%s hasRendered:%s \n", STATE_STRING(mState), notify?"T":"F");
339 uint32_t RenderTask::GetRenderedOnceCounter() const
341 return mRenderedOnceCounter;
344 const Matrix& RenderTask::GetViewMatrix( BufferIndex bufferIndex ) const
346 DALI_ASSERT_DEBUG( nullptr != mCamera );
348 return mCamera->GetViewMatrix( bufferIndex );
351 SceneGraph::Camera& RenderTask::GetCamera() const
353 DALI_ASSERT_DEBUG( nullptr != mCamera );
357 const Matrix& RenderTask::GetProjectionMatrix( BufferIndex bufferIndex ) const
359 DALI_ASSERT_DEBUG( nullptr != mCamera );
361 return mCamera->GetProjectionMatrix( bufferIndex );
364 void RenderTask::PrepareRenderInstruction( RenderInstruction& instruction, BufferIndex updateBufferIndex )
366 DALI_ASSERT_DEBUG( nullptr != mCamera );
368 TASK_LOG(Debug::General);
371 bool viewportSet = QueryViewport( updateBufferIndex, viewport );
373 instruction.Reset( mCamera,
375 viewportSet ? &viewport : nullptr,
376 mClearEnabled ? &GetClearColor( updateBufferIndex ) : nullptr );
379 mRefreshRate == Dali::RenderTask::REFRESH_ONCE )
381 // create tracker if one doesn't yet exist.
382 if( !mRenderSyncTracker )
384 mRenderSyncTracker = new Render::RenderTracker();
385 mRenderMessageDispatcher->AddRenderTracker( *mRenderSyncTracker );
387 instruction.mRenderTracker = mRenderSyncTracker;
391 // no sync needed, texture FBOs are "ready" the same frame they are rendered to
392 instruction.mRenderTracker = nullptr;
396 bool RenderTask::ViewMatrixUpdated()
401 retval = mCamera->ViewMatrixUpdated();
406 void RenderTask::SetViewportPosition( BufferIndex updateBufferIndex, const Vector2& value )
408 mViewportPosition.Set( updateBufferIndex, value );
411 const Vector2& RenderTask::GetViewportPosition( BufferIndex bufferIndex ) const
413 return mViewportPosition[bufferIndex];
416 void RenderTask::BakeViewportPosition( BufferIndex updateBufferIndex, const Vector2& value )
418 mViewportPosition.Bake( updateBufferIndex, value );
421 void RenderTask::SetViewportSize( BufferIndex updateBufferIndex, const Vector2& value )
423 mViewportSize.Set( updateBufferIndex, value );
426 const Vector2& RenderTask::GetViewportSize( BufferIndex bufferIndex ) const
428 return mViewportSize[bufferIndex];
431 void RenderTask::BakeViewportSize( BufferIndex updateBufferIndex, const Vector2& value )
433 mViewportSize.Bake( updateBufferIndex, value );
436 bool RenderTask::GetViewportEnabled( BufferIndex bufferIndex ) const
438 if(fabsf(mViewportPosition[bufferIndex].x) > Math::MACHINE_EPSILON_1 ||
439 fabsf(mViewportPosition[bufferIndex].y) > Math::MACHINE_EPSILON_1 ||
440 fabsf(mViewportSize[bufferIndex].width) > Math::MACHINE_EPSILON_1 ||
441 fabsf(mViewportSize[bufferIndex].height) > Math::MACHINE_EPSILON_1)
449 void RenderTask::SetSyncRequired( bool requiresSync )
451 mRequiresSync = requiresSync;
454 void RenderTask::PropertyOwnerConnected( PropertyOwner& owner )
456 // check if we've gone from inactive to active
460 void RenderTask::PropertyOwnerDisconnected( BufferIndex /*updateBufferIndex*/, PropertyOwner& owner )
462 mActive = false; // if either source or camera disconnected, we're no longer active
465 void RenderTask::PropertyOwnerDestroyed( PropertyOwner& owner )
467 if( static_cast<PropertyOwner*>( mSourceNode ) == &owner )
469 mSourceNode = nullptr;
471 else if( static_cast<PropertyOwner*>( mCameraNode ) == &owner )
473 mCameraNode = nullptr;
477 RenderTask::RenderTask()
478 : mViewportPosition( Vector2::ZERO),
479 mViewportSize( Vector2::ZERO),
480 mClearColor( Dali::RenderTask::DEFAULT_CLEAR_COLOR ),
481 mRenderMessageDispatcher( nullptr ),
482 mRenderSyncTracker( nullptr ),
483 mSourceNode( nullptr ),
484 mCameraNode( nullptr ),
487 mRefreshRate( Dali::RenderTask::DEFAULT_REFRESH_RATE ),
489 mRenderedOnceCounter( 0u ),
490 mState( (Dali::RenderTask::DEFAULT_REFRESH_RATE == Dali::RenderTask::REFRESH_ALWAYS)
491 ? RENDER_CONTINUOUSLY
492 : RENDER_ONCE_WAITING_FOR_RESOURCES ),
493 mRequiresSync( false ),
495 mWaitingToRender( false ),
496 mNotifyTrigger( false ),
497 mExclusive( Dali::RenderTask::DEFAULT_EXCLUSIVE ),
498 mClearEnabled( Dali::RenderTask::DEFAULT_CLEAR_ENABLED ),
499 mCullMode( Dali::RenderTask::DEFAULT_CULL_MODE )
503 void RenderTask::SetActiveStatus()
505 // must have a source and camera both connected to scene
506 mActive = ( mSourceNode && mSourceNode->ConnectedToScene() &&
507 mCameraNode && mCameraNode->ConnectedToScene() && mCamera );
508 TASK_LOG_FMT( Debug::General, " Source node(%x) active %d. Frame counter: %d\n", mSourceNode, mSourceNode && mSourceNode->ConnectedToScene(), mFrameCounter );
509 TASK_LOG_FMT( Debug::General, " Camera node(%x) active %d\n", mCameraNode, mCameraNode && mCameraNode->ConnectedToScene() );
512 } // namespace SceneGraph
514 } // namespace Internal