2 * Copyright (c) 2017 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()
45 // Remove exclusive flag from source node
48 if( mSourceNode && (this == mSourceNode->GetExclusiveRenderTask() ) )
50 mSourceNode->SetExclusiveRenderTask( NULL );
53 if( mRenderSyncTracker )
55 mRenderMessageDispatcher->RemoveRenderTracker( *mRenderSyncTracker );
59 void RenderTask::Initialize( RenderMessageDispatcher& renderMessageDispatcher )
61 mRenderMessageDispatcher = &renderMessageDispatcher;
64 void RenderTask::SetSourceNode( Node* node )
66 // Remove exclusive flag from the old node, if necessary
68 this == mSourceNode->GetExclusiveRenderTask() )
70 mSourceNode->SetExclusiveRenderTask( NULL );
75 if ( mSourceNode && mExclusive )
77 mSourceNode->SetExclusiveRenderTask( this );
81 Node* RenderTask::GetSourceNode() const
86 void RenderTask::SetExclusive( bool exclusive )
88 mExclusive = exclusive;
94 mSourceNode->SetExclusiveRenderTask( this );
96 else if ( this == mSourceNode->GetExclusiveRenderTask() )
98 mSourceNode->SetExclusiveRenderTask( NULL );
103 bool RenderTask::IsExclusive() const
108 void RenderTask::SetCamera( Node* cameraNode, Camera* camera )
110 mCameraNode = cameraNode;
114 void RenderTask::SetFrameBuffer( Render::FrameBuffer* frameBuffer )
116 mFrameBuffer = frameBuffer;
119 Render::FrameBuffer* RenderTask::GetFrameBuffer()
124 bool RenderTask::QueryViewport( BufferIndex bufferIndex, Viewport& viewport ) const
126 if( ! GetViewportEnabled( bufferIndex ) )
131 viewport.x = mViewportPosition[bufferIndex].x;
132 viewport.y = mViewportPosition[bufferIndex].y;
133 viewport.width = mViewportSize[bufferIndex].width;
134 viewport.height = mViewportSize[bufferIndex].height;
139 void RenderTask::SetClearColor( BufferIndex updateBufferIndex, const Vector4& value )
141 mClearColor.Set( updateBufferIndex, value );
144 const Vector4& RenderTask::GetClearColor( BufferIndex bufferIndex ) const
146 return mClearColor[bufferIndex];
149 void RenderTask::BakeClearColor( BufferIndex updateBufferIndex, const Vector4& value )
151 mClearColor.Bake( updateBufferIndex, value );
154 void RenderTask::SetClearEnabled( bool enabled )
156 mClearEnabled = enabled;
159 bool RenderTask::GetClearEnabled() const
161 return mClearEnabled;
164 void RenderTask::SetCullMode( bool mode )
169 bool RenderTask::GetCullMode() const
174 void RenderTask::SetRefreshRate( unsigned int refreshRate )
176 DALI_LOG_TRACE_METHOD_FMT(gRenderTaskLogFilter, "this:%p RefreshRate:%d\n", this, refreshRate);
178 mRefreshRate = refreshRate;
180 if( mRefreshRate > 0 )
182 mState = RENDER_CONTINUOUSLY;
186 mState = RENDER_ONCE_WAITING_FOR_RESOURCES;
187 mWaitingToRender = true;
188 mNotifyTrigger = false;
194 unsigned int RenderTask::GetRefreshRate() const
199 bool RenderTask::ReadyToRender( BufferIndex updateBufferIndex )
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
205 if ( NULL == mSourceNode ||
206 ( !mSourceNode->IsRoot() && NULL == mSourceNode->GetParent() ) )
208 TASK_LOG_FMT(Debug::General, " =F No source actor FC:%d\n", mFrameCounter );
210 // Source node is missing or disconnected
215 if ( NULL == mCameraNode ||
216 NULL == mCameraNode->GetParent() ||
219 // Camera node is missing or disconnected
220 TASK_LOG_FMT(Debug::General, " =F No Camera FC:%d\n", mFrameCounter );
225 mCamera->Update( updateBufferIndex, *mCameraNode );
229 bool RenderTask::IsRenderRequired()
231 bool required = false;
235 case RENDER_CONTINUOUSLY:
237 required = (mFrameCounter == 0);
240 case RENDER_ONCE_WAITING_FOR_RESOURCES:
252 TASK_LOG_FMT( Debug::General, " State:%s = %s\n", STATE_STRING(mState), required?"T":"F" );
257 // Called every frame regardless of whether render was required.
258 // If render was not required, ignore resourcesFinished.
259 void RenderTask::UpdateState()
261 TASK_LOG_FMT( Debug::General, "FC:%d State:%s RR:%d\n", mFrameCounter, STATE_STRING(mState), mRefreshRate );
265 case RENDER_CONTINUOUSLY:
267 if( mRefreshRate != Dali::RenderTask::REFRESH_ALWAYS )
269 if( mFrameCounter == 0 )
271 ++mFrameCounter; // Only start skipping frames when resources are loaded
273 else // Continue counting to skip frames
276 if( mFrameCounter >= mRefreshRate )
286 case RENDER_ONCE_WAITING_FOR_RESOURCES:
288 mState = RENDERED_ONCE;
294 mWaitingToRender = true;
295 mNotifyTrigger = false;
298 if( !mRenderSyncTracker || (mRenderSyncTracker && mRenderSyncTracker->IsSynced() ))
300 mWaitingToRender = false;
301 mNotifyTrigger = true;
306 mNotifyTrigger = true;
316 TASK_LOG_FMT( Debug::General, " EXIT FC:%d State:%s Notify:%s\n", mFrameCounter, STATE_STRING(mState), mNotifyTrigger?"T":"F");
319 bool RenderTask::IsWaitingToRender()
321 TASK_LOG_FMT(Debug::Verbose, " State:%s waiting:%s \n", STATE_STRING(mState), mWaitingToRender?"T":"F");
322 return mWaitingToRender;
325 bool RenderTask::HasRendered()
328 if( mNotifyTrigger == true )
330 ++mRenderedOnceCounter;
331 mState = RENDERED_ONCE_AND_NOTIFIED;
332 mNotifyTrigger = false;
336 TASK_LOG_FMT(Debug::Verbose, " State:%s hasRendered:%s \n", STATE_STRING(mState), notify?"T":"F");
340 unsigned int RenderTask::GetRenderedOnceCounter() const
342 return mRenderedOnceCounter;
346 const Matrix& RenderTask::GetViewMatrix( BufferIndex bufferIndex ) const
348 DALI_ASSERT_DEBUG( NULL != mCamera );
350 return mCamera->GetViewMatrix( bufferIndex );
353 SceneGraph::Camera& RenderTask::GetCamera() const
355 DALI_ASSERT_DEBUG( NULL != mCamera );
359 const Matrix& RenderTask::GetProjectionMatrix( BufferIndex bufferIndex ) const
361 DALI_ASSERT_DEBUG( NULL != mCamera );
363 return mCamera->GetProjectionMatrix( bufferIndex );
366 void RenderTask::PrepareRenderInstruction( RenderInstruction& instruction, BufferIndex updateBufferIndex )
368 DALI_ASSERT_DEBUG( NULL != mCamera );
370 TASK_LOG(Debug::General);
373 bool viewportSet = QueryViewport( updateBufferIndex, viewport );
375 instruction.Reset( mCamera,
377 viewportSet ? &viewport : NULL,
378 mClearEnabled ? &GetClearColor( updateBufferIndex ) : NULL );
381 mRefreshRate == Dali::RenderTask::REFRESH_ONCE )
383 // create tracker if one doesn't yet exist.
384 if( !mRenderSyncTracker )
386 mRenderSyncTracker = new Render::RenderTracker();
387 mRenderMessageDispatcher->AddRenderTracker( *mRenderSyncTracker );
389 instruction.mRenderTracker = mRenderSyncTracker;
393 // no sync needed, texture FBOs are "ready" the same frame they are rendered to
394 instruction.mRenderTracker = NULL;
398 bool RenderTask::ViewMatrixUpdated()
403 retval = mCamera->ViewMatrixUpdated();
408 void RenderTask::SetViewportPosition( BufferIndex updateBufferIndex, const Vector2& value )
410 mViewportPosition.Set( updateBufferIndex, value );
413 const Vector2& RenderTask::GetViewportPosition( BufferIndex bufferIndex ) const
415 return mViewportPosition[bufferIndex];
418 void RenderTask::BakeViewportPosition( BufferIndex updateBufferIndex, const Vector2& value )
420 mViewportPosition.Bake( updateBufferIndex, value );
423 void RenderTask::SetViewportSize( BufferIndex updateBufferIndex, const Vector2& value )
425 mViewportSize.Set( updateBufferIndex, value );
428 const Vector2& RenderTask::GetViewportSize( BufferIndex bufferIndex ) const
430 return mViewportSize[bufferIndex];
433 void RenderTask::BakeViewportSize( BufferIndex updateBufferIndex, const Vector2& value )
435 mViewportSize.Bake( updateBufferIndex, value );
438 bool RenderTask::GetViewportEnabled( BufferIndex bufferIndex ) const
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)
451 void RenderTask::SetSyncRequired( bool requiresSync )
453 mRequiresSync = requiresSync;
456 void RenderTask::ResetDefaultProperties( BufferIndex updateBufferIndex )
458 // Reset default properties
459 mViewportPosition.ResetToBaseValue( updateBufferIndex );
460 mViewportSize.ResetToBaseValue( updateBufferIndex );
461 mClearColor.ResetToBaseValue( updateBufferIndex );
464 RenderTask::RenderTask()
465 : mViewportPosition( Vector2::ZERO),
466 mViewportSize( Vector2::ZERO),
467 mClearColor( Dali::RenderTask::DEFAULT_CLEAR_COLOR ),
468 mRenderMessageDispatcher( NULL ),
469 mRenderSyncTracker( NULL ),
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 mState( (Dali::RenderTask::DEFAULT_REFRESH_RATE == Dali::RenderTask::REFRESH_ALWAYS)
480 ? RENDER_CONTINUOUSLY
481 : RENDER_ONCE_WAITING_FOR_RESOURCES ),
482 mRefreshRate( Dali::RenderTask::DEFAULT_REFRESH_RATE ),
484 mRenderedOnceCounter( 0u ),
485 mRequiresSync( false )
489 } // namespace SceneGraph
491 } // namespace Internal