X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Frender-tasks%2Fscene-graph-render-task.cpp;h=d49af14292a8d6e952ec59fafaa12ffb8e5e2457;hb=1fdfbc2906bc1dcae714eedfbe6c7f94cd6f9364;hp=dfc59ace2b6651e57eac5120d05ab35ac4afda5c;hpb=fab6bd2494d4c9420bd6722e992be1a22ec104da;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/update/render-tasks/scene-graph-render-task.cpp b/dali/internal/update/render-tasks/scene-graph-render-task.cpp index dfc59ac..d49af14 100644 --- a/dali/internal/update/render-tasks/scene-graph-render-task.cpp +++ b/dali/internal/update/render-tasks/scene-graph-render-task.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,11 +19,11 @@ #include // INTERNAL INCLUDES -#include -#include -#include #include #include +#include +#include +#include #include @@ -31,10 +31,8 @@ namespace Dali { namespace Internal { - namespace SceneGraph { - RenderTask* RenderTask::New() { return new RenderTask(); @@ -42,40 +40,52 @@ RenderTask* RenderTask::New() RenderTask::~RenderTask() { - // Remove exclusive flag from source node - if( mExclusive ) + if(mSourceNode) { - if( mSourceNode && (this == mSourceNode->GetExclusiveRenderTask() ) ) + mSourceNode->RemoveObserver(*this); + if(mExclusive) { - mSourceNode->SetExclusiveRenderTask( NULL ); + mSourceNode->SetExclusiveRenderTask(nullptr); } } - if( mRenderSyncTracker ) + if(mCameraNode) + { + mCameraNode->RemoveObserver(*this); + } + if(mRenderSyncTracker) { - mRenderMessageDispatcher->RemoveRenderTracker( *mRenderSyncTracker ); + mRenderMessageDispatcher->RemoveRenderTracker(*mRenderSyncTracker); } } -void RenderTask::Initialize( RenderMessageDispatcher& renderMessageDispatcher ) +void RenderTask::Initialize(RenderMessageDispatcher& renderMessageDispatcher) { mRenderMessageDispatcher = &renderMessageDispatcher; } -void RenderTask::SetSourceNode( Node* node ) +void RenderTask::SetSourceNode(Node* node) { - // Remove exclusive flag from the old node, if necessary - if ( mSourceNode && - this == mSourceNode->GetExclusiveRenderTask() ) + // Stop observing the old node (if we were) + if(mSourceNode) { - mSourceNode->SetExclusiveRenderTask( NULL ); + mSourceNode->RemoveObserver(*this); + if(this == mSourceNode->GetExclusiveRenderTask()) + { + mSourceNode->SetExclusiveRenderTask(nullptr); + } } mSourceNode = node; - if ( mSourceNode && mExclusive ) + if(mSourceNode) { - mSourceNode->SetExclusiveRenderTask( this ); + mSourceNode->AddObserver(*this); + if(mExclusive) + { + mSourceNode->SetExclusiveRenderTask(this); + } } + SetActiveStatus(); } Node* RenderTask::GetSourceNode() const @@ -83,19 +93,29 @@ Node* RenderTask::GetSourceNode() const return mSourceNode; } -void RenderTask::SetExclusive( bool exclusive ) +void RenderTask::SetViewportGuideNode(Node* node) +{ + mViewportGuideNode = node; +} + +Node* RenderTask::GetViewportGuideNode() const +{ + return mViewportGuideNode; +} + +void RenderTask::SetExclusive(bool exclusive) { mExclusive = exclusive; - if ( mSourceNode ) + if(mSourceNode) { - if ( mExclusive ) + if(mExclusive) { - mSourceNode->SetExclusiveRenderTask( this ); + mSourceNode->SetExclusiveRenderTask(this); } - else if ( this == mSourceNode->GetExclusiveRenderTask() ) + else if(this == mSourceNode->GetExclusiveRenderTask()) { - mSourceNode->SetExclusiveRenderTask( NULL ); + mSourceNode->SetExclusiveRenderTask(nullptr); } } } @@ -105,13 +125,24 @@ bool RenderTask::IsExclusive() const return mExclusive; } -void RenderTask::SetCamera( Node* cameraNode, Camera* camera ) +void RenderTask::SetCamera(Node* cameraNode, Camera* camera) { + if(mCameraNode) + { + mCameraNode->RemoveObserver(*this); + } + mCameraNode = cameraNode; - mCamera = camera; + mCamera = camera; + + if(mCameraNode) + { + mCameraNode->AddObserver(*this); + } + SetActiveStatus(); } -void RenderTask::SetFrameBuffer( Render::FrameBuffer* frameBuffer ) +void RenderTask::SetFrameBuffer(Render::FrameBuffer* frameBuffer) { mFrameBuffer = frameBuffer; } @@ -121,37 +152,27 @@ Render::FrameBuffer* RenderTask::GetFrameBuffer() return mFrameBuffer; } -bool RenderTask::QueryViewport( BufferIndex bufferIndex, Viewport& viewport ) const +bool RenderTask::QueryViewport(BufferIndex bufferIndex, Viewport& viewport) const { - if( ! GetViewportEnabled( bufferIndex ) ) + if(!GetViewportEnabled(bufferIndex)) { return false; } - viewport.x = static_cast( mViewportPosition[bufferIndex].x ); // truncated - viewport.y = static_cast( mViewportPosition[bufferIndex].y ); // truncated - viewport.width = static_cast( mViewportSize[bufferIndex].width ); // truncated - viewport.height = static_cast( mViewportSize[bufferIndex].height ); // truncated + viewport.x = static_cast(mViewportPosition[bufferIndex].x); // truncated + viewport.y = static_cast(mViewportPosition[bufferIndex].y); // truncated + viewport.width = static_cast(mViewportSize[bufferIndex].width); // truncated + viewport.height = static_cast(mViewportSize[bufferIndex].height); // truncated return true; } -void RenderTask::SetClearColor( BufferIndex updateBufferIndex, const Vector4& value ) -{ - mClearColor.Set( updateBufferIndex, value ); -} - -const Vector4& RenderTask::GetClearColor( BufferIndex bufferIndex ) const +const Vector4& RenderTask::GetClearColor(BufferIndex bufferIndex) const { return mClearColor[bufferIndex]; } -void RenderTask::BakeClearColor( BufferIndex updateBufferIndex, const Vector4& value ) -{ - mClearColor.Bake( updateBufferIndex, value ); -} - -void RenderTask::SetClearEnabled( bool enabled ) +void RenderTask::SetClearEnabled(bool enabled) { mClearEnabled = enabled; } @@ -161,7 +182,7 @@ bool RenderTask::GetClearEnabled() const return mClearEnabled; } -void RenderTask::SetCullMode( bool mode ) +void RenderTask::SetCullMode(bool mode) { mCullMode = mode; } @@ -171,21 +192,21 @@ bool RenderTask::GetCullMode() const return mCullMode; } -void RenderTask::SetRefreshRate( uint32_t refreshRate ) +void RenderTask::SetRefreshRate(uint32_t refreshRate) { DALI_LOG_TRACE_METHOD_FMT(gRenderTaskLogFilter, "this:%p RefreshRate:%d\n", this, refreshRate); mRefreshRate = refreshRate; - if( mRefreshRate > 0 ) + if(mRefreshRate > 0) { mState = RENDER_CONTINUOUSLY; } else { - mState = RENDER_ONCE_WAITING_FOR_RESOURCES; + mState = RENDER_ONCE_WAITING_FOR_RESOURCES; mWaitingToRender = true; - mNotifyTrigger = false; + mNotifyTrigger = false; } mFrameCounter = 0u; @@ -196,39 +217,16 @@ uint32_t RenderTask::GetRefreshRate() const return mRefreshRate; } -bool RenderTask::ReadyToRender( BufferIndex updateBufferIndex ) +bool RenderTask::ReadyToRender(BufferIndex updateBufferIndex) { - // If the source node of the render task is invisible we should still render - // We want the render task to complete and possible clear colors to happen - - // Check the source node. - if( NULL == mSourceNode || - ( !mSourceNode->IsRoot() && NULL == mSourceNode->GetParent() ) ) - { - TASK_LOG_FMT( Debug::General, " Source actor not on stage. Frame counter: %d\n", mFrameCounter ); - - // The source node is missing or disconnected. - return false; - } - - // Check camera node - if( NULL == mCameraNode || - NULL == mCameraNode->GetParent() || - NULL == mCamera ) - { - // The camera node is missing or disconnected. - TASK_LOG_FMT(Debug::General, " =F No Camera FC:%d\n", mFrameCounter ); - return false; - } - - return true; + return mActive; } bool RenderTask::IsRenderRequired() { bool required = false; - switch( mState ) + switch(mState) { case RENDER_CONTINUOUSLY: { @@ -247,7 +245,7 @@ bool RenderTask::IsRenderRequired() } } - TASK_LOG_FMT( Debug::General, " State:%s = %s\n", STATE_STRING(mState), required?"T":"F" ); + TASK_LOG_FMT(Debug::General, " State:%s = %s\n", STATE_STRING(mState), required ? "T" : "F"); return required; } @@ -256,22 +254,22 @@ bool RenderTask::IsRenderRequired() // If render was not required, ignore resourcesFinished. void RenderTask::UpdateState() { - TASK_LOG_FMT( Debug::General, "FC:%d State:%s RR:%d\n", mFrameCounter, STATE_STRING(mState), mRefreshRate ); + TASK_LOG_FMT(Debug::General, "FC:%d State:%s RR:%d\n", mFrameCounter, STATE_STRING(mState), mRefreshRate); - switch( mState ) + switch(mState) { case RENDER_CONTINUOUSLY: { - if( mRefreshRate != Dali::RenderTask::REFRESH_ALWAYS ) + if(mRefreshRate != Dali::RenderTask::REFRESH_ALWAYS) { - if( mFrameCounter == 0 ) + if(mFrameCounter == 0) { ++mFrameCounter; // Only start skipping frames when resources are loaded } else // Continue counting to skip frames { ++mFrameCounter; - if( mFrameCounter >= mRefreshRate ) + if(mFrameCounter >= mRefreshRate) { mFrameCounter = 0; } @@ -290,19 +288,19 @@ void RenderTask::UpdateState() case RENDERED_ONCE: { mWaitingToRender = true; - mNotifyTrigger = false; - if( mFrameBuffer ) + mNotifyTrigger = false; + if(mFrameBuffer) { - if( !mRenderSyncTracker || (mRenderSyncTracker && mRenderSyncTracker->IsSynced() )) + if(!mRenderSyncTracker || (mRenderSyncTracker && mRenderSyncTracker->IsSynced())) { mWaitingToRender = false; - mNotifyTrigger = true; + mNotifyTrigger = true; } } else { mWaitingToRender = false; - mNotifyTrigger = true; + mNotifyTrigger = true; } } @@ -312,27 +310,27 @@ void RenderTask::UpdateState() break; } - TASK_LOG_FMT( Debug::General, " EXIT FC:%d State:%s Notify:%s\n", mFrameCounter, STATE_STRING(mState), mNotifyTrigger?"T":"F"); + TASK_LOG_FMT(Debug::General, " EXIT FC:%d State:%s Notify:%s\n", mFrameCounter, STATE_STRING(mState), mNotifyTrigger ? "T" : "F"); } bool RenderTask::IsWaitingToRender() { - TASK_LOG_FMT(Debug::Verbose, " State:%s waiting:%s \n", STATE_STRING(mState), mWaitingToRender?"T":"F"); + TASK_LOG_FMT(Debug::Verbose, " State:%s waiting:%s \n", STATE_STRING(mState), mWaitingToRender ? "T" : "F"); return mWaitingToRender; } bool RenderTask::HasRendered() { bool notify = false; - if( mNotifyTrigger == true ) + if(mNotifyTrigger == true) { ++mRenderedOnceCounter; - mState = RENDERED_ONCE_AND_NOTIFIED; + mState = RENDERED_ONCE_AND_NOTIFIED; mNotifyTrigger = false; - notify = true; + notify = true; } - TASK_LOG_FMT(Debug::Verbose, " State:%s hasRendered:%s \n", STATE_STRING(mState), notify?"T":"F"); + TASK_LOG_FMT(Debug::Verbose, " State:%s hasRendered:%s \n", STATE_STRING(mState), notify ? "T" : "F"); return notify; } @@ -341,100 +339,102 @@ uint32_t RenderTask::GetRenderedOnceCounter() const return mRenderedOnceCounter; } - -const Matrix& RenderTask::GetViewMatrix( BufferIndex bufferIndex ) const +const Matrix& RenderTask::GetViewMatrix(BufferIndex bufferIndex) const { - DALI_ASSERT_DEBUG( NULL != mCamera ); + DALI_ASSERT_DEBUG(nullptr != mCamera); - return mCamera->GetViewMatrix( bufferIndex ); + return mCamera->GetViewMatrix(bufferIndex); } -SceneGraph::Camera& RenderTask::GetCamera() const +const SceneGraph::Camera& RenderTask::GetCamera() const { - DALI_ASSERT_DEBUG( NULL != mCamera ); + DALI_ASSERT_DEBUG(nullptr != mCamera); return *mCamera; } -const Matrix& RenderTask::GetProjectionMatrix( BufferIndex bufferIndex ) const +const Matrix& RenderTask::GetProjectionMatrix(BufferIndex bufferIndex) const { - DALI_ASSERT_DEBUG( NULL != mCamera ); + DALI_ASSERT_DEBUG(nullptr != mCamera); - return mCamera->GetProjectionMatrix( bufferIndex ); + return mCamera->GetProjectionMatrix(bufferIndex); } -void RenderTask::PrepareRenderInstruction( RenderInstruction& instruction, BufferIndex updateBufferIndex ) +RenderInstruction& RenderTask::PrepareRenderInstruction(BufferIndex updateBufferIndex) { - DALI_ASSERT_DEBUG( NULL != mCamera ); + DALI_ASSERT_DEBUG(nullptr != mCamera); TASK_LOG(Debug::General); Viewport viewport; - bool viewportSet = QueryViewport( updateBufferIndex, viewport ); + bool viewportSet = QueryViewport(updateBufferIndex, viewport); - instruction.Reset( mCamera, - GetFrameBuffer(), - viewportSet ? &viewport : NULL, - mClearEnabled ? &GetClearColor( updateBufferIndex ) : NULL ); + mRenderInstruction[updateBufferIndex].Reset(mCamera, + GetFrameBuffer(), + viewportSet ? &viewport : nullptr, + mClearEnabled ? &GetClearColor(updateBufferIndex) : nullptr); - if( mRequiresSync && - mRefreshRate == Dali::RenderTask::REFRESH_ONCE ) + if(mRequiresSync && + mRefreshRate == Dali::RenderTask::REFRESH_ONCE) { // create tracker if one doesn't yet exist. - if( !mRenderSyncTracker ) + if(!mRenderSyncTracker) { mRenderSyncTracker = new Render::RenderTracker(); - mRenderMessageDispatcher->AddRenderTracker( *mRenderSyncTracker ); + mRenderMessageDispatcher->AddRenderTracker(*mRenderSyncTracker); } - instruction.mRenderTracker = mRenderSyncTracker; + mRenderInstruction[updateBufferIndex].mRenderTracker = mRenderSyncTracker; } else { // no sync needed, texture FBOs are "ready" the same frame they are rendered to - instruction.mRenderTracker = NULL; + mRenderInstruction[updateBufferIndex].mRenderTracker = nullptr; } + + return mRenderInstruction[updateBufferIndex]; } bool RenderTask::ViewMatrixUpdated() { bool retval = false; - if( mCamera ) + if(mCamera) { retval = mCamera->ViewMatrixUpdated(); } return retval; } -void RenderTask::SetViewportPosition( BufferIndex updateBufferIndex, const Vector2& value ) +void RenderTask::UpdateViewport(BufferIndex updateBufferIndex, Vector2 sceneSize, Vector3 cameraPosition) { - mViewportPosition.Set( updateBufferIndex, value ); + if(GetViewportGuideNode() && GetViewportGuideNode()->ConnectedToScene()) + { + Vector3 worldPosition = GetViewportGuideNode()->GetWorldPosition(updateBufferIndex); + worldPosition -= cameraPosition; + + Vector3 nodeSize = GetViewportGuideNode()->GetSize(updateBufferIndex) * GetViewportGuideNode()->GetWorldScale(updateBufferIndex); + Vector2 halfSceneSize(sceneSize.width * 0.5f, sceneSize.height * 0.5f); // World position origin is center of scene + Vector3 halfNodeSize(nodeSize * 0.5f); + Vector2 screenPosition(halfSceneSize.width + worldPosition.x - halfNodeSize.x, + halfSceneSize.height + worldPosition.y - halfNodeSize.y); + + /* This is an implicit constraint - the properties will be dirty until the node + * is removed. (RenderTask::Impl manages this) + */ + mViewportPosition.Set(updateBufferIndex, screenPosition); + mViewportSize.Set(updateBufferIndex, Vector2(nodeSize)); + } } -const Vector2& RenderTask::GetViewportPosition( BufferIndex bufferIndex ) const +const Vector2& RenderTask::GetViewportPosition(BufferIndex bufferIndex) const { return mViewportPosition[bufferIndex]; } -void RenderTask::BakeViewportPosition( BufferIndex updateBufferIndex, const Vector2& value ) -{ - mViewportPosition.Bake( updateBufferIndex, value ); -} - -void RenderTask::SetViewportSize( BufferIndex updateBufferIndex, const Vector2& value ) -{ - mViewportSize.Set( updateBufferIndex, value ); -} - -const Vector2& RenderTask::GetViewportSize( BufferIndex bufferIndex ) const +const Vector2& RenderTask::GetViewportSize(BufferIndex bufferIndex) const { return mViewportSize[bufferIndex]; } -void RenderTask::BakeViewportSize( BufferIndex updateBufferIndex, const Vector2& value ) -{ - mViewportSize.Bake( updateBufferIndex, value ); -} - -bool RenderTask::GetViewportEnabled( BufferIndex bufferIndex ) const +bool RenderTask::GetViewportEnabled(BufferIndex bufferIndex) const { if(fabsf(mViewportPosition[bufferIndex].x) > Math::MACHINE_EPSILON_1 || fabsf(mViewportPosition[bufferIndex].y) > Math::MACHINE_EPSILON_1 || @@ -447,35 +447,68 @@ bool RenderTask::GetViewportEnabled( BufferIndex bufferIndex ) const return false; } -void RenderTask::SetSyncRequired( bool requiresSync ) +void RenderTask::SetSyncRequired(bool requiresSync) { mRequiresSync = requiresSync; } +void RenderTask::PropertyOwnerConnected(PropertyOwner& owner) +{ + // check if we've gone from inactive to active + SetActiveStatus(); +} -RenderTask::RenderTask() -: mViewportPosition( Vector2::ZERO), - mViewportSize( Vector2::ZERO), - mClearColor( Dali::RenderTask::DEFAULT_CLEAR_COLOR ), - mRenderMessageDispatcher( NULL ), - mRenderSyncTracker( NULL ), - mSourceNode( NULL ), - mCameraNode( NULL ), - mCamera( NULL ), - mFrameBuffer(0), - mWaitingToRender( false ), - mNotifyTrigger( false ), - mExclusive( Dali::RenderTask::DEFAULT_EXCLUSIVE ), - mClearEnabled( Dali::RenderTask::DEFAULT_CLEAR_ENABLED ), - mCullMode( Dali::RenderTask::DEFAULT_CULL_MODE ), - mState( (Dali::RenderTask::DEFAULT_REFRESH_RATE == Dali::RenderTask::REFRESH_ALWAYS) - ? RENDER_CONTINUOUSLY - : RENDER_ONCE_WAITING_FOR_RESOURCES ), - mRefreshRate( Dali::RenderTask::DEFAULT_REFRESH_RATE ), - mFrameCounter( 0u ), - mRenderedOnceCounter( 0u ), - mRequiresSync( false ) +void RenderTask::PropertyOwnerDisconnected(BufferIndex /*updateBufferIndex*/, PropertyOwner& owner) { + mActive = false; // if either source or camera disconnected, we're no longer active +} + +void RenderTask::PropertyOwnerDestroyed(PropertyOwner& owner) +{ + if(static_cast(mSourceNode) == &owner) + { + mSourceNode = nullptr; + } + else if(static_cast(mCameraNode) == &owner) + { + mCameraNode = nullptr; + } +} + +RenderTask::RenderTask() +: mViewportPosition(Vector2::ZERO), + mViewportSize(Vector2::ZERO), + mClearColor(Dali::RenderTask::DEFAULT_CLEAR_COLOR), + mRenderMessageDispatcher(nullptr), + mRenderSyncTracker(nullptr), + mSourceNode(nullptr), + mCameraNode(nullptr), + mViewportGuideNode(nullptr), + mCamera(nullptr), + mFrameBuffer(nullptr), + mRefreshRate(Dali::RenderTask::DEFAULT_REFRESH_RATE), + mFrameCounter(0u), + mRenderedOnceCounter(0u), + mState((Dali::RenderTask::DEFAULT_REFRESH_RATE == Dali::RenderTask::REFRESH_ALWAYS) + ? RENDER_CONTINUOUSLY + : RENDER_ONCE_WAITING_FOR_RESOURCES), + mRequiresSync(false), + mActive(false), + mWaitingToRender(false), + mNotifyTrigger(false), + mExclusive(Dali::RenderTask::DEFAULT_EXCLUSIVE), + mClearEnabled(Dali::RenderTask::DEFAULT_CLEAR_ENABLED), + mCullMode(Dali::RenderTask::DEFAULT_CULL_MODE) +{ +} + +void RenderTask::SetActiveStatus() +{ + // must have a source and camera both connected to scene + mActive = (mSourceNode && mSourceNode->ConnectedToScene() && + mCameraNode && mCameraNode->ConnectedToScene() && mCamera); + TASK_LOG_FMT(Debug::General, " Source node(%x) active %d. Frame counter: %d\n", mSourceNode, mSourceNode && mSourceNode->ConnectedToScene(), mFrameCounter); + TASK_LOG_FMT(Debug::General, " Camera node(%x) active %d\n", mCameraNode, mCameraNode && mCameraNode->ConnectedToScene()); } } // namespace SceneGraph