2 * Copyright (c) 2021 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/internal/render/common/render-instruction.h>
23 #include <dali/internal/render/common/render-tracker.h>
24 #include <dali/internal/update/controllers/render-message-dispatcher.h>
25 #include <dali/internal/update/nodes/node.h>
26 #include <dali/public-api/math/matrix.h>
28 #include <dali/internal/update/render-tasks/scene-graph-render-task-debug.h>
36 RenderTask* RenderTask::New()
38 return new RenderTask();
41 RenderTask::~RenderTask()
45 mSourceNode->RemoveObserver(*this);
48 mSourceNode->SetExclusiveRenderTask(nullptr);
53 mCameraNode->RemoveObserver(*this);
55 if(mRenderSyncTracker)
57 mRenderMessageDispatcher->RemoveRenderTracker(*mRenderSyncTracker);
61 void RenderTask::Initialize(RenderMessageDispatcher& renderMessageDispatcher)
63 mRenderMessageDispatcher = &renderMessageDispatcher;
66 void RenderTask::SetSourceNode(Node* node)
68 // Stop observing the old node (if we were)
71 mSourceNode->RemoveObserver(*this);
72 if(this == mSourceNode->GetExclusiveRenderTask())
74 mSourceNode->SetExclusiveRenderTask(nullptr);
82 mSourceNode->AddObserver(*this);
85 mSourceNode->SetExclusiveRenderTask(this);
91 Node* RenderTask::GetSourceNode() const
96 void RenderTask::SetExclusive(bool exclusive)
98 mExclusive = exclusive;
104 mSourceNode->SetExclusiveRenderTask(this);
106 else if(this == mSourceNode->GetExclusiveRenderTask())
108 mSourceNode->SetExclusiveRenderTask(nullptr);
113 bool RenderTask::IsExclusive() const
118 void RenderTask::SetCamera(Node* cameraNode, Camera* camera)
122 mCameraNode->RemoveObserver(*this);
125 mCameraNode = cameraNode;
130 mCameraNode->AddObserver(*this);
135 void RenderTask::SetFrameBuffer(Render::FrameBuffer* frameBuffer)
137 mFrameBuffer = frameBuffer;
140 Render::FrameBuffer* RenderTask::GetFrameBuffer()
145 bool RenderTask::QueryViewport(BufferIndex bufferIndex, Viewport& viewport) const
147 if(!GetViewportEnabled(bufferIndex))
152 viewport.x = static_cast<int>(mViewportPosition[bufferIndex].x); // truncated
153 viewport.y = static_cast<int>(mViewportPosition[bufferIndex].y); // truncated
154 viewport.width = static_cast<int>(mViewportSize[bufferIndex].width); // truncated
155 viewport.height = static_cast<int>(mViewportSize[bufferIndex].height); // truncated
160 void RenderTask::SetClearColor(BufferIndex updateBufferIndex, const Vector4& value)
162 mClearColor.Set(updateBufferIndex, value);
165 const Vector4& RenderTask::GetClearColor(BufferIndex bufferIndex) const
167 return mClearColor[bufferIndex];
170 void RenderTask::BakeClearColor(BufferIndex updateBufferIndex, const Vector4& value)
172 mClearColor.Bake(updateBufferIndex, value);
175 void RenderTask::SetClearEnabled(bool enabled)
177 mClearEnabled = enabled;
180 bool RenderTask::GetClearEnabled() const
182 return mClearEnabled;
185 void RenderTask::SetCullMode(bool mode)
190 bool RenderTask::GetCullMode() const
195 void RenderTask::SetRefreshRate(uint32_t refreshRate)
197 DALI_LOG_TRACE_METHOD_FMT(gRenderTaskLogFilter, "this:%p RefreshRate:%d\n", this, refreshRate);
199 mRefreshRate = refreshRate;
203 mState = RENDER_CONTINUOUSLY;
207 mState = RENDER_ONCE_WAITING_FOR_RESOURCES;
208 mWaitingToRender = true;
209 mNotifyTrigger = false;
215 uint32_t RenderTask::GetRefreshRate() const
220 bool RenderTask::ReadyToRender(BufferIndex updateBufferIndex)
225 bool RenderTask::IsRenderRequired()
227 bool required = false;
231 case RENDER_CONTINUOUSLY:
233 required = (mFrameCounter == 0);
236 case RENDER_ONCE_WAITING_FOR_RESOURCES:
248 TASK_LOG_FMT(Debug::General, " State:%s = %s\n", STATE_STRING(mState), required ? "T" : "F");
253 // Called every frame regardless of whether render was required.
254 // If render was not required, ignore resourcesFinished.
255 void RenderTask::UpdateState()
257 TASK_LOG_FMT(Debug::General, "FC:%d State:%s RR:%d\n", mFrameCounter, STATE_STRING(mState), mRefreshRate);
261 case RENDER_CONTINUOUSLY:
263 if(mRefreshRate != Dali::RenderTask::REFRESH_ALWAYS)
265 if(mFrameCounter == 0)
267 ++mFrameCounter; // Only start skipping frames when resources are loaded
269 else // Continue counting to skip frames
272 if(mFrameCounter >= mRefreshRate)
282 case RENDER_ONCE_WAITING_FOR_RESOURCES:
284 mState = RENDERED_ONCE;
290 mWaitingToRender = true;
291 mNotifyTrigger = false;
294 if(!mRenderSyncTracker || (mRenderSyncTracker && mRenderSyncTracker->IsSynced()))
296 mWaitingToRender = false;
297 mNotifyTrigger = true;
302 mWaitingToRender = false;
303 mNotifyTrigger = true;
313 TASK_LOG_FMT(Debug::General, " EXIT FC:%d State:%s Notify:%s\n", mFrameCounter, STATE_STRING(mState), mNotifyTrigger ? "T" : "F");
316 bool RenderTask::IsWaitingToRender()
318 TASK_LOG_FMT(Debug::Verbose, " State:%s waiting:%s \n", STATE_STRING(mState), mWaitingToRender ? "T" : "F");
319 return mWaitingToRender;
322 bool RenderTask::HasRendered()
325 if(mNotifyTrigger == true)
327 ++mRenderedOnceCounter;
328 mState = RENDERED_ONCE_AND_NOTIFIED;
329 mNotifyTrigger = false;
333 TASK_LOG_FMT(Debug::Verbose, " State:%s hasRendered:%s \n", STATE_STRING(mState), notify ? "T" : "F");
337 uint32_t RenderTask::GetRenderedOnceCounter() const
339 return mRenderedOnceCounter;
342 const Matrix& RenderTask::GetViewMatrix(BufferIndex bufferIndex) const
344 DALI_ASSERT_DEBUG(nullptr != mCamera);
346 return mCamera->GetViewMatrix(bufferIndex);
349 SceneGraph::Camera& RenderTask::GetCamera() const
351 DALI_ASSERT_DEBUG(nullptr != mCamera);
355 const Matrix& RenderTask::GetProjectionMatrix(BufferIndex bufferIndex) const
357 DALI_ASSERT_DEBUG(nullptr != mCamera);
359 return mCamera->GetProjectionMatrix(bufferIndex);
362 RenderInstruction& RenderTask::PrepareRenderInstruction(BufferIndex updateBufferIndex)
364 DALI_ASSERT_DEBUG(nullptr != mCamera);
366 TASK_LOG(Debug::General);
369 bool viewportSet = QueryViewport(updateBufferIndex, viewport);
371 mRenderInstruction[updateBufferIndex].Reset(mCamera,
373 viewportSet ? &viewport : nullptr,
374 mClearEnabled ? &GetClearColor(updateBufferIndex) : nullptr);
377 mRefreshRate == Dali::RenderTask::REFRESH_ONCE)
379 // create tracker if one doesn't yet exist.
380 if(!mRenderSyncTracker)
382 mRenderSyncTracker = new Render::RenderTracker();
383 mRenderMessageDispatcher->AddRenderTracker(*mRenderSyncTracker);
385 mRenderInstruction[updateBufferIndex].mRenderTracker = mRenderSyncTracker;
389 // no sync needed, texture FBOs are "ready" the same frame they are rendered to
390 mRenderInstruction[updateBufferIndex].mRenderTracker = nullptr;
393 return mRenderInstruction[updateBufferIndex];
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),
486 mFrameBuffer(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