Fix a crash of the RenderTask
[platform/core/uifw/dali-core.git] / dali / internal / event / render-tasks / render-task-impl.cpp
index 14bc16b..99b74c7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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)
@@ -71,14 +71,17 @@ SignalConnectorType signalConnector1( mType, SIGNAL_FINISHED, &RenderTask::DoCon
 
 } // Unnamed namespace
 
-RenderTaskPtr RenderTask::New( Actor* sourceActor, CameraActor* cameraActor, SceneGraph::RenderTaskList& parentSceneObject )
+RenderTaskPtr RenderTask::New( Actor* sourceActor, CameraActor* cameraActor, RenderTaskList& renderTaskList )
 {
   // create scene object first so it's guaranteed to exist for the event side
   auto sceneObject = SceneGraph::RenderTask::New();
-  OwnerPointer< SceneGraph::RenderTask > transferOwnership( sceneObject );
+
   // pass the pointer to base for message passing
-  RenderTaskPtr task( new RenderTask( sceneObject ) );
+  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
@@ -91,26 +94,23 @@ RenderTaskPtr RenderTask::New( Actor* sourceActor, CameraActor* cameraActor, Sce
 
 void RenderTask::SetSourceActor( Actor* actor )
 {
-  mSourceActor = actor;
-  if ( mSourceActor )
+  mSourceActor.SetActor( actor );
+  if ( actor )
   {
-    SetSourceNodeMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), &mSourceActor->GetNode() );
+    SetSourceNodeMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), &actor->GetNode() );
   }
   else
   {
     SetSourceNodeMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), nullptr );
   }
+
   // set the actor on exclusive container for hit testing
-  const Stage* stage = Stage::GetCurrent();
-  if ( stage )
-  {
-    stage->GetRenderTaskList().SetExclusive( this, mExclusive );
-  }
+  mRenderTaskList.SetExclusive( this, mExclusive );
 }
 
 Actor* RenderTask::GetSourceActor() const
 {
-  return mSourceActor;
+  return mSourceActor.GetActor();
 }
 
 void RenderTask::SetExclusive( bool exclusive )
@@ -119,11 +119,7 @@ void RenderTask::SetExclusive( bool exclusive )
   {
     mExclusive = exclusive;
 
-    const Stage* stage = Stage::GetCurrent();
-    if ( stage )
-    {
-      stage->GetRenderTaskList().SetExclusive( this, exclusive );
-    }
+    mRenderTaskList.SetExclusive( this, exclusive );
 
     // scene object is being used in a separate thread; queue a message to set the value
     SetExclusiveMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), mExclusive );
@@ -147,20 +143,27 @@ bool RenderTask::GetInputEnabled() const
 
 void RenderTask::SetCameraActor( CameraActor* cameraActor )
 {
-  mCameraActor = cameraActor;
-  if( mCameraActor )
+  mCameraActor.SetActor( cameraActor );
+  if( cameraActor )
   {
-    SetCameraMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), &mCameraActor->GetNode(), mCameraActor->GetCamera() );
+    SetCameraMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), &cameraActor->GetNode(), cameraActor->GetCamera() );
   }
   else
   {
     SetCameraMessage( GetEventThreadServices(), GetRenderTaskSceneObject(), nullptr, nullptr );
   }
+
+  // set the actor on exclusive container for hit testing
+  mRenderTaskList.SetExclusive( this, mExclusive );
 }
 
 CameraActor* RenderTask::GetCameraActor() const
 {
-  return mCameraActor;
+  if( mCameraActor.GetActor() )
+  {
+    return static_cast< CameraActor* >( mCameraActor.GetActor() );
+  }
+  return nullptr;
 }
 
 void RenderTask::SetTargetFrameBuffer( FrameBufferImagePtr image )
@@ -265,6 +268,13 @@ void RenderTask::GetViewport( Viewport& viewPort ) const
       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
@@ -403,19 +413,27 @@ bool RenderTask::TranslateCoordinates( Vector2& screenCoords ) const
     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 = inputMappingActor->ScreenToLocal(defaultCamera.GetViewMatrix(), defaultCamera.GetProjectionMatrix(), viewport, localX, localY, screenCoords.x, screenCoords.y);
+        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)
         {
@@ -479,6 +497,11 @@ const SceneGraph::RenderTask& RenderTask::GetRenderTaskSceneObject() const
   return *static_cast<const SceneGraph::RenderTask*>( mUpdateObject );
 }
 
+RenderTaskList& RenderTask::GetRenderTaskList() const
+{
+  return mRenderTaskList;
+}
+
 /********************************************************************************
  ********************************   PROPERTY METHODS   **************************
  ********************************************************************************/
@@ -521,7 +544,6 @@ Property::Value RenderTask::GetDefaultProperty(Property::Index index) const
 
   switch ( index )
   {
-
     case Dali::RenderTask::Property::VIEWPORT_POSITION:
     {
       value = mViewportPosition;
@@ -559,7 +581,6 @@ Property::Value RenderTask::GetDefaultPropertyCurrentValue( Property::Index inde
 
   switch ( index )
   {
-
     case Dali::RenderTask::Property::VIEWPORT_POSITION:
     {
       value = GetCurrentViewportPosition();
@@ -747,11 +768,12 @@ bool RenderTask::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface
   return connected;
 }
 
-RenderTask::RenderTask( const SceneGraph::RenderTask* sceneObject )
+RenderTask::RenderTask( const SceneGraph::RenderTask* sceneObject, RenderTaskList& renderTaskList )
 : Object( sceneObject ),
-  mSourceActor( nullptr ),
-  mCameraActor( nullptr ),
+  mSourceActor(),
+  mCameraActor(),
   mInputMappingActor(),
+  mRenderTaskList( renderTaskList ),
   mClearColor( Dali::RenderTask::DEFAULT_CLEAR_COLOR ),
   mViewportPosition( Vector2::ZERO ),
   mViewportSize( Vector2::ZERO ),