/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
#include <dali/internal/event/actors/camera-actor-impl.h>
#include <dali/internal/event/common/property-helper.h>
#include <dali/internal/event/common/stage-impl.h>
+#include <dali/internal/event/common/scene-impl.h>
#include <dali/internal/event/common/projection.h>
#include <dali/internal/event/images/frame-buffer-image-impl.h>
#include <dali/internal/update/nodes/node.h>
-#include <dali/internal/event/render-tasks/render-task-list-impl.h>
#include <dali/internal/update/render-tasks/scene-graph-render-task.h>
#if defined(DEBUG_ENABLED)
} // Unnamed namespace
-RenderTask* RenderTask::New()
+RenderTaskPtr RenderTask::New( Actor* sourceActor, CameraActor* cameraActor, RenderTaskList& renderTaskList )
{
- RenderTask* task( new RenderTask() );
+ // create scene object first so it's guaranteed to exist for the event side
+ auto sceneObject = SceneGraph::RenderTask::New();
+ // pass the pointer to base for message passing
+ RenderTaskPtr task( new RenderTask( sceneObject, renderTaskList ) );
+
+ // transfer scene object ownership to update manager
+ const SceneGraph::RenderTaskList& parentSceneObject = renderTaskList.GetSceneObject();
+ OwnerPointer< SceneGraph::RenderTask > transferOwnership( sceneObject );
+ AddTaskMessage( task->GetEventThreadServices(), parentSceneObject, transferOwnership );
+
+ // Set the default source & camera actors
+ task->SetSourceActor( sourceActor );
+ task->SetCameraActor( cameraActor );
+
+ // no need for additional messages as scene objects defaults match ours
return task;
}
void RenderTask::SetSourceActor( Actor* actor )
{
- const Stage* stage = Stage::GetCurrent();
- if ( stage )
+ mSourceActor.SetActor( actor );
+ if ( actor )
+ {
+ SetSourceNodeMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), &actor->GetNode() );
+ }
+ else
{
- stage->GetRenderTaskList().SetExclusive( this, mExclusive );
+ SetSourceNodeMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), nullptr );
}
- mSourceConnector.SetActor( actor );
+
+ // set the actor on exclusive container for hit testing
+ mRenderTaskList.SetExclusive( this, mExclusive );
}
Actor* RenderTask::GetSourceActor() const
{
- return mSourceConnector.mActor;
+ return mSourceActor.GetActor();
}
void RenderTask::SetExclusive( bool exclusive )
{
mExclusive = exclusive;
- const Stage* stage = Stage::GetCurrent();
- if ( stage )
- {
- stage->GetRenderTaskList().SetExclusive( this, exclusive );
- }
+ mRenderTaskList.SetExclusive( this, exclusive );
- if ( mSceneObject )
- {
- // mSceneObject is being used in a separate thread; queue a message to set the value
- SetExclusiveMessage( GetEventThreadServices(), *mSceneObject, mExclusive );
- }
+ // scene object is being used in a separate thread; queue a message to set the value
+ SetExclusiveMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), mExclusive );
}
}
void RenderTask::SetCameraActor( CameraActor* cameraActor )
{
+ mCameraActor.SetActor( cameraActor );
if( cameraActor )
{
- mCameraConnector.mCamera = cameraActor->GetCamera();
+ SetCameraMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), &cameraActor->GetNode(), cameraActor->GetCamera() );
}
else
{
- mCameraConnector.mCamera = NULL;
+ SetCameraMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), nullptr, nullptr );
}
- mCameraConnector.SetActor( cameraActor );
+
+ // set the actor on exclusive container for hit testing
+ mRenderTaskList.SetExclusive( this, mExclusive );
}
CameraActor* RenderTask::GetCameraActor() const
{
- // camera connector can only point to camera actor
- return static_cast< CameraActor* >( mCameraConnector.mActor );
+ if( mCameraActor.GetActor() )
+ {
+ return static_cast< CameraActor* >( mCameraActor.GetActor() );
+ }
+ return nullptr;
}
void RenderTask::SetTargetFrameBuffer( FrameBufferImagePtr image )
renderFrameBufferPtr = mFrameBuffer->GetRenderObject();
}
- SetFrameBufferMessage( GetEventThreadServices(), *mSceneObject, renderFrameBufferPtr );
+ SetFrameBufferMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), renderFrameBufferPtr );
}
FrameBuffer* RenderTask::GetFrameBuffer() const
return mScreenToFrameBufferFunction;
}
-void RenderTask::SetScreenToFrameBufferMappingActor( Actor* mappingActor )
+void RenderTask::SetScreenToFrameBufferMappingActor( Dali::Actor& mappingActor )
{
- mMappingConnector.SetActor( mappingActor );
+ mInputMappingActor = WeakHandle<Dali::Actor>( mappingActor );
}
-Actor* RenderTask::GetScreenToFrameBufferMappingActor() const
+Dali::Actor RenderTask::GetScreenToFrameBufferMappingActor() const
{
- return mMappingConnector.mActor;
+ return mInputMappingActor.GetHandle();
}
void RenderTask::SetViewportPosition(const Vector2& value)
{
mViewportPosition = value;
- BakeViewportPositionMessage( GetEventThreadServices(), *mSceneObject, value );
+ BakeViewportPositionMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), value );
}
Vector2 RenderTask::GetCurrentViewportPosition() const
{
- return mSceneObject->GetViewportPosition( GetEventThreadServices().GetEventBufferIndex() );
+ return GetRenderTaskSceneObject().GetViewportPosition( GetEventThreadServices().GetEventBufferIndex() );
}
void RenderTask::SetViewportSize(const Vector2& value)
{
mViewportSize = value;
- BakeViewportSizeMessage( GetEventThreadServices(), *mSceneObject, value );
+ BakeViewportSizeMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), value );
}
Vector2 RenderTask::GetCurrentViewportSize() const
{
- return mSceneObject->GetViewportSize( GetEventThreadServices().GetEventBufferIndex() );
+ return GetRenderTaskSceneObject().GetViewportSize( GetEventThreadServices().GetEventBufferIndex() );
}
void RenderTask::SetViewport( const Viewport& viewport )
{
BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
- if(!mSceneObject->GetViewportEnabled( bufferIndex ))
+ if( !GetRenderTaskSceneObject().GetViewportEnabled( bufferIndex ) )
{
if ( mFrameBufferImage )
{
if ( stage )
{
Vector2 size( stage->GetSize() );
+ Actor* sourceActor = mSourceActor.GetActor();
+ if ( sourceActor && sourceActor->OnStage() )
+ {
+ Scene& scene = sourceActor->GetScene();
+ size = scene.GetSize();
+ }
+
viewPort.x = viewPort.y = 0;
viewPort.width = static_cast<int32_t>( size.width ); // truncated
viewPort.height = static_cast<int32_t>( size.height ); // truncated
}
else
{
- const Vector2& position = mSceneObject->GetViewportPosition(bufferIndex);
- const Vector2& size = mSceneObject->GetViewportSize(bufferIndex);
+ const Vector2& position = GetRenderTaskSceneObject().GetViewportPosition(bufferIndex);
+ const Vector2& size = GetRenderTaskSceneObject().GetViewportSize(bufferIndex);
viewPort.x = static_cast<int32_t>( position.x ); // truncated
viewPort.y = static_cast<int32_t>( position.y ); // truncated
viewPort.width = static_cast<int32_t>( size.width ); // truncated
{
mClearColor = color;
- if ( mSceneObject )
- {
- // mSceneObject is being used in a separate thread; queue a message to set the value
- BakeClearColorMessage( GetEventThreadServices(), *mSceneObject, color );
- }
+ // scene object is being used in a separate thread; queue a message to set the value
+ BakeClearColorMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), color );
}
}
const Vector4& RenderTask::GetClearColor() const
{
- return mSceneObject->GetClearColor( GetEventThreadServices().GetEventBufferIndex() );
+ return GetRenderTaskSceneObject().GetClearColor( GetEventThreadServices().GetEventBufferIndex() );
}
void RenderTask::SetSyncRequired( bool requiresSync )
{
mRequiresSync = requiresSync;
- if( mSceneObject )
- {
- // mSceneObject is being used in a separate thread; queue a message to set the value
- SetSyncRequiredMessage( GetEventThreadServices(), *mSceneObject, requiresSync );
- }
+ // scene object is being used in a separate thread; queue a message to set the value
+ SetSyncRequiredMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), requiresSync );
}
}
{
mClearEnabled = enabled;
- if ( mSceneObject )
- {
- // mSceneObject is being used in a separate thread; queue a message to set the value
- SetClearEnabledMessage( GetEventThreadServices(), *mSceneObject, mClearEnabled );
- }
+ // scene object is being used in a separate thread; queue a message to set the value
+ SetClearEnabledMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), mClearEnabled );
}
}
{
mCullMode = mode;
- if ( mSceneObject )
- {
- // mSceneObject is being used in a separate thread; queue a message to set the value
- SetCullModeMessage( GetEventThreadServices(), *mSceneObject, mCullMode );
- }
+ // scene object is being used in a separate thread; queue a message to set the value
+ SetCullModeMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), mCullMode );
}
}
// Note - even when refreshRate is the same as mRefreshRate, a message should be sent
- if ( mSceneObject )
- {
- // mSceneObject is being used in a separate thread; queue a message to set the value
- SetRefreshRateMessage( GetEventThreadServices(), *mSceneObject, refreshRate );
- }
+ // sceneObject is being used in a separate thread; queue a message to set the value
+ SetRefreshRateMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), refreshRate );
}
uint32_t RenderTask::GetRefreshRate() const
CameraActor* cameraActor = GetCameraActor();
if ( mInputEnabled &&
- NULL != sourceActor &&
+ nullptr != sourceActor &&
sourceActor->OnStage() &&
- NULL != cameraActor &&
+ nullptr != cameraActor &&
cameraActor->OnStage() )
{
// If the actors are rendered off-screen, then the screen coordinates must be converted
bool inside( true );
// If the actors are rendered off-screen, then the screen coordinates must be converted
// the function should only be called for offscreen tasks
- if( mFrameBufferImage && mMappingConnector.mActor )
+ Dali::Actor mappingActor = GetScreenToFrameBufferMappingActor();
+
+ if( mFrameBufferImage && mappingActor )
{
+ Internal::Actor* inputMappingActor = &GetImplementation( mappingActor );
CameraActor* localCamera = GetCameraActor();
StagePtr stage = Stage::GetCurrent();
- if( stage )
+ if ( stage )
{
- CameraActor& defaultCamera = stage->GetDefaultCameraActor();
+ Vector2 size( stage->GetSize() );
+ CameraActor* defaultCamera( &stage->GetDefaultCameraActor() );
+ Actor* sourceActor = mSourceActor.GetActor();
+ if ( sourceActor && sourceActor->OnStage() )
+ {
+ Scene& scene = sourceActor->GetScene();
+ size = scene.GetSize();
+ defaultCamera = &scene.GetDefaultCameraActor();
+ }
+
if( localCamera )
{
Viewport viewport;
- Vector2 size( stage->GetSize() );
viewport.x = viewport.y = 0;
viewport.width = static_cast<int32_t>( size.width ); // truncated
viewport.height = static_cast<int32_t>( size.height ); // truncated
float localX, localY;
- inside = mMappingConnector.mActor->ScreenToLocal(defaultCamera.GetViewMatrix(), defaultCamera.GetProjectionMatrix(), viewport, localX, localY, screenCoords.x, screenCoords.y);
- Vector3 actorSize = mMappingConnector.mActor->GetCurrentSize();
+ inside = inputMappingActor->ScreenToLocal(defaultCamera->GetViewMatrix(), defaultCamera->GetProjectionMatrix(), viewport, localX, localY, screenCoords.x, screenCoords.y);
+ Vector3 actorSize = inputMappingActor->GetCurrentSize();
if( inside && localX >= 0.f && localX <= actorSize.x && localY >= 0.f && localY <= actorSize.y)
{
screenCoords.x = localX;
return actor->ScreenToLocal( *this, localX, localY, viewportX, viewportY );
}
-SceneGraph::RenderTask* RenderTask::CreateSceneObject()
-{
- // This should only be called once, with no existing scene-object
- DALI_ASSERT_DEBUG( NULL == mSceneObject );
-
- // Keep the raw-pointer until DiscardSceneObject is called
- mSceneObject = SceneGraph::RenderTask::New();
-
- // Send messages to set other properties that may have changed since last time we were on stage
- SetExclusiveMessage( GetEventThreadServices(), *mSceneObject, mExclusive );
- SetClearColorMessage( GetEventThreadServices(), *mSceneObject, mClearColor );
- SetClearEnabledMessage( GetEventThreadServices(), *mSceneObject, mClearEnabled );
- SetCullModeMessage( GetEventThreadServices(), *mSceneObject, mCullMode );
- SetRefreshRateMessage( GetEventThreadServices(), *mSceneObject, mRefreshRate );
- SetSyncRequiredMessage( GetEventThreadServices(), *mSceneObject, mRequiresSync );
- SetFrameBuffer( mFrameBuffer );
-
- // Caller takes ownership
- return mSceneObject;
-}
-
-SceneGraph::RenderTask* RenderTask::GetRenderTaskSceneObject()
+const SceneGraph::RenderTask& RenderTask::GetRenderTaskSceneObject() const
{
- return mSceneObject;
+ return *static_cast<const SceneGraph::RenderTask*>( mUpdateObject );
}
-void RenderTask::DiscardSceneObject()
+RenderTaskList& RenderTask::GetRenderTaskList() const
{
- // mSceneObject is not owned; throw away the raw-pointer
- mSceneObject = NULL;
+ return mRenderTaskList;
}
/********************************************************************************
switch ( index )
{
-
case Dali::RenderTask::Property::VIEWPORT_POSITION:
{
value = mViewportPosition;
switch ( index )
{
-
case Dali::RenderTask::Property::VIEWPORT_POSITION:
{
value = GetCurrentViewportPosition();
}
}
-const SceneGraph::PropertyOwner* RenderTask::GetSceneObject() const
-{
- return mSceneObject;
-}
-
const SceneGraph::PropertyBase* RenderTask::GetSceneObjectAnimatableProperty( Property::Index index ) const
{
- DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
-
const SceneGraph::PropertyBase* property( NULL );
- // This method should only return a property which is part of the scene-graph
- if( mSceneObject != NULL )
+ switch ( index )
{
- switch ( index )
+ case Dali::RenderTask::Property::VIEWPORT_POSITION:
{
- case Dali::RenderTask::Property::VIEWPORT_POSITION:
- property = &mSceneObject->mViewportPosition;
- break;
-
- case Dali::RenderTask::Property::VIEWPORT_SIZE:
- property = &mSceneObject->mViewportSize;
- break;
-
- case Dali::RenderTask::Property::CLEAR_COLOR:
- property = &mSceneObject->mClearColor;
- break;
-
- default:
- break;
+ property = &GetRenderTaskSceneObject().mViewportPosition;
+ break;
+ }
+ case Dali::RenderTask::Property::VIEWPORT_SIZE:
+ {
+ property = &GetRenderTaskSceneObject().mViewportSize;
+ break;
}
+ case Dali::RenderTask::Property::CLEAR_COLOR:
+ {
+ property = &GetRenderTaskSceneObject().mClearColor;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ if( !property )
+ {
+ // not our property, ask base
+ property = Object::GetSceneObjectAnimatableProperty( index );
}
return property;
const PropertyInputImpl* RenderTask::GetSceneObjectInputProperty( Property::Index index ) const
{
- const PropertyInputImpl* property( NULL );
- if( mSceneObject != NULL )
- {
- switch ( index )
- {
- case Dali::RenderTask::Property::VIEWPORT_POSITION:
- property = &mSceneObject->mViewportPosition;
- break;
-
- case Dali::RenderTask::Property::VIEWPORT_SIZE:
- property = &mSceneObject->mViewportSize;
- break;
-
- case Dali::RenderTask::Property::CLEAR_COLOR:
- property = &mSceneObject->mClearColor;
- break;
-
- default:
- break;
- }
- }
-
- return property;
+ // animatable properties are input as well, Object::GetSceneObjectInputProperty does the same so no need to call it
+ return GetSceneObjectAnimatableProperty( index );
}
bool RenderTask::HasFinished()
{
bool finished = false;
- const uint32_t counter = mSceneObject->GetRenderedOnceCounter();
+ const uint32_t counter = GetRenderTaskSceneObject().GetRenderedOnceCounter();
if( mRefreshOnceCounter < counter )
{
mRefreshOnceCounter = counter;
}
- DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::HasFinished()=%s SCRT:%p SC\n", finished?"T":"F", mSceneObject);
+ DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::HasFinished()=%s SCRT:%p SC\n", finished?"T":"F", &GetRenderTaskSceneObject());
return finished;
}
return connected;
}
-RenderTask::RenderTask()
-: mSceneObject( NULL ),
- mSourceConnector( Connector::SOURCE_CONNECTOR, *this ),
- mCameraConnector( Connector::CAMERA_CONNECTOR, *this ),
- mMappingConnector( Connector::MAPPING_CONNECTOR, *this ),
+RenderTask::RenderTask( const SceneGraph::RenderTask* sceneObject, RenderTaskList& renderTaskList )
+: Object( sceneObject ),
+ mSourceActor(),
+ mCameraActor(),
+ mInputMappingActor(),
+ mRenderTaskList( renderTaskList ),
mClearColor( Dali::RenderTask::DEFAULT_CLEAR_COLOR ),
mViewportPosition( Vector2::ZERO ),
mViewportSize( Vector2::ZERO ),
mRequiresSync( false )
{
DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::RenderTask(this:%p)\n", this);
+ // scene object handles observation of source and camera
}
RenderTask::~RenderTask()
{
DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::~RenderTask(this:%p)\n", this);
-}
-
-// Helper class for connecting Nodes to the scene-graph RenderTask
-
-RenderTask::Connector::Connector( Type type, RenderTask& renderTask )
-: mType( type ),
- mRenderTask( renderTask ),
- mActor( NULL ),
- mCamera( NULL )
-{
-}
-
-RenderTask::Connector::~Connector()
-{
- SetActor( NULL );
-}
-
-void RenderTask::Connector::SetActor( Actor* actor )
-{
- if ( mActor != actor )
- {
- if ( mActor )
- {
- mActor->RemoveObserver( *this );
- }
-
- mActor = actor;
-
- if ( mActor )
- {
- mActor->AddObserver( *this );
- }
-
- UpdateRenderTask();
- }
-}
-
-void RenderTask::Connector::SceneObjectAdded( Object& object )
-{
- UpdateRenderTask();
-}
-
-void RenderTask::Connector::SceneObjectRemoved( Object& object )
-{
- UpdateRenderTask();
-}
-
-void RenderTask::Connector::ObjectDestroyed( Object& object )
-{
- if ( SOURCE_CONNECTOR == mType )
- {
- const Stage* stage = Stage::GetCurrent();
- if ( stage )
- {
- stage->GetRenderTaskList().SetExclusive( &mRenderTask, false );
- }
- }
-
- mActor = NULL;
- mCamera = NULL; // only meaningful for the camera connector but no simple way to distinguish
-
- UpdateRenderTask();
-}
-
-void RenderTask::Connector::UpdateRenderTask()
-{
- // Guard to allow handle destruction after Core has been destroyed
- if( Internal::Stage::IsInstalled() &&
- mRenderTask.mSceneObject )
- {
- const SceneGraph::Node* node( NULL );
-
- // Check whether a Node exists in the scene-graph
- if ( NULL != mActor )
- {
- const SceneGraph::PropertyOwner* object = mActor->GetSceneObject();
- if ( NULL != object )
- {
- // actors only point to nodes as their scene objects
- node = static_cast< const SceneGraph::Node* >( object );
- }
- }
-
- //the mapping node is not used in the scene graph
- if ( SOURCE_CONNECTOR == mType )
- {
- SetSourceNodeMessage( mRenderTask.GetEventThreadServices(), *(mRenderTask.mSceneObject), node );
- }
- else if( CAMERA_CONNECTOR == mType )
- {
- SetCameraMessage( mRenderTask.GetEventThreadServices(), *(mRenderTask.mSceneObject), node, mCamera );
- }
- }
+ // scene object deletion is handled by our parent
+ // scene object handles observation of source and camera
}
} // namespace Internal