Fix capture issue of to capture sub-scene. 27/240227/12
authorseungho <seungho@seungho.tn.corp.samsungelectronics.net>
Tue, 4 Aug 2020 11:25:55 +0000 (20:25 +0900)
committerseungho <seungho@seungho.tn.corp.samsungelectronics.net>
Fri, 21 Aug 2020 08:00:16 +0000 (17:00 +0900)
 - new camera that generated inside Capture has size of Scene and default position.
 - but, if a source is not a rootLayer, the position and size are needed to be set with that of the source.
 - in this patch, we get position input. the position is top-left position of area to be captured in window space.
 - camera actor has position and size those get by input position and size
 - create new method to set jpeg quality to remove it from the argument of Start method

Change-Id: Ie5232e0ef61f34fae101fee5243a39abb29242b5
Signed-off-by: seungho <seungho@seungho.tn.corp.samsungelectronics.net>
dali/internal/system/common/capture-impl.cpp
dali/internal/system/common/capture-impl.h
dali/public-api/capture/capture.cpp
dali/public-api/capture/capture.h

index 49dae75..7f0fa9b 100644 (file)
@@ -21,7 +21,6 @@
 // EXTERNAL INCLUDES
 #include <fstream>
 #include <string.h>
-#include <dali/devel-api/common/stage.h>
 #include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/render-tasks/render-task-list.h>
 #include <dali/integration-api/debug.h>
@@ -29,6 +28,7 @@
 // INTERNAL INCLUDES
 #include <dali/integration-api/adaptor-framework/adaptor.h>
 #include <dali/devel-api/adaptor-framework/native-image-source-devel.h>
+#include <dali/devel-api/adaptor-framework/window-devel.h>
 
 namespace
 {
@@ -82,13 +82,13 @@ CapturePtr Capture::New( Dali::CameraActor cameraActor )
   return pWorker;
 }
 
-void Capture::Start( Dali::Actor source, const Dali::Vector2& size, const std::string &path, const Dali::Vector4& clearColor, const uint32_t quality )
+void Capture::Start( Dali::Actor source, const Dali::Vector2& position, const Dali::Vector2& size, const std::string &path, const Dali::Vector4& clearColor, const uint32_t quality )
 {
   mQuality = quality;
-  Start( source, size, path, clearColor );
+  Start( source, position, size, path, clearColor );
 }
 
-void Capture::Start( Dali::Actor source, const Dali::Vector2& size, const std::string &path, const Dali::Vector4& clearColor )
+void Capture::Start( Dali::Actor source, const Dali::Vector2& position, const Dali::Vector2& size, const std::string &path, const Dali::Vector4& clearColor )
 {
   DALI_ASSERT_ALWAYS(path.size() > 4 && "Path is invalid.");
 
@@ -104,7 +104,12 @@ void Capture::Start( Dali::Actor source, const Dali::Vector2& size, const std::s
   DALI_ASSERT_ALWAYS(source && "Source is NULL.");
 
   UnsetResources();
-  SetupResources( size, clearColor, source );
+  SetupResources( position, size, clearColor, source );
+}
+
+void Capture::SetImageQuality( uint32_t quality )
+{
+  mQuality = quality;
 }
 
 Dali::NativeImageSourcePtr Capture::GetNativeImageSource() const
@@ -166,35 +171,38 @@ bool Capture::IsFrameBufferCreated()
   return mFrameBuffer;
 }
 
-void Capture::SetupRenderTask( Dali::Actor source, const Dali::Vector4& clearColor )
+void Capture::SetupRenderTask( const Dali::Vector2& position, const Dali::Vector2& size, Dali::Actor source, const Dali::Vector4& clearColor )
 {
   DALI_ASSERT_ALWAYS(source && "Source is empty.");
 
-  mSource = source;
-
-  // Check the original parent about source.
-  mParent = mSource.GetParent();
-
-  Dali::Stage stage = Dali::Stage::GetCurrent();
-  Dali::Size stageSize = stage.GetSize();
+  Dali::Window window = DevelWindow::Get( source );
+  if( !window )
+  {
+    DALI_LOG_ERROR("The source is not added on the window\n");
+    return;
+  }
 
-  // Add to stage for rendering the source. If source isn't on the stage then it never be rendered.
-  stage.Add( mSource );
+  mSource = source;
 
   if( !mCameraActor )
   {
-    mCameraActor = Dali::CameraActor::New( stageSize );
-    mCameraActor.SetProperty( Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
+    mCameraActor = Dali::CameraActor::New( size );
+    // Because input position and size are for 2 dimentional area,
+    // default z-directional position of the camera is required to be used for the new camera position.
+    float cameraDefaultZPosition = mCameraActor.GetProperty<float>( Dali::Actor::Property::POSITION_Z );
+    Vector2 positionTransition = position + size / 2;
+    mCameraActor.SetProperty( Dali::Actor::Property::POSITION, Vector3( positionTransition.x, positionTransition.y, cameraDefaultZPosition ) );
+    mCameraActor.SetProperty( Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
     mCameraActor.SetProperty( Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
   }
 
-  stage.Add( mCameraActor );
+  window.Add( mCameraActor );
 
   DALI_ASSERT_ALWAYS(mFrameBuffer && "Framebuffer is NULL.");
 
   DALI_ASSERT_ALWAYS(!mRenderTask && "RenderTask is already created.");
 
-  Dali::RenderTaskList taskList = stage.GetRenderTaskList();
+  Dali::RenderTaskList taskList = window.GetRenderTaskList();
   mRenderTask = taskList.CreateTask();
   mRenderTask.SetRefreshRate( Dali::RenderTask::REFRESH_ONCE );
   mRenderTask.SetSourceActor( source );
@@ -216,19 +224,6 @@ void Capture::UnsetRenderTask()
 {
   DALI_ASSERT_ALWAYS(mCameraActor && "CameraActor is NULL.");
 
-  if( mParent )
-  {
-    // Restore the parent of source.
-    mParent.Add( mSource );
-    mParent.Reset();
-  }
-  else
-  {
-    mSource.Unparent();
-  }
-
-  mSource.Reset();
-
   mTimer.Reset();
 
   mCameraActor.Unparent();
@@ -236,9 +231,11 @@ void Capture::UnsetRenderTask()
 
   DALI_ASSERT_ALWAYS( mRenderTask && "RenderTask is NULL." );
 
-  Dali::RenderTaskList taskList = Dali::Stage::GetCurrent().GetRenderTaskList();
+  Dali::Window window = DevelWindow::Get( mSource );
+  Dali::RenderTaskList taskList = window.GetRenderTaskList();
   taskList.RemoveTask( mRenderTask );
   mRenderTask.Reset();
+  mSource.Reset();
 }
 
 bool Capture::IsRenderTaskSetup()
@@ -246,13 +243,13 @@ bool Capture::IsRenderTaskSetup()
   return mCameraActor && mRenderTask;
 }
 
-void Capture::SetupResources( const Dali::Vector2& size, const Dali::Vector4& clearColor, Dali::Actor source )
+void Capture::SetupResources( const Dali::Vector2& position, const Dali::Vector2& size, const Dali::Vector4& clearColor, Dali::Actor source )
 {
   CreateNativeImageSource( size );
 
   CreateFrameBuffer();
 
-  SetupRenderTask( source, clearColor );
+  SetupRenderTask( position, size, source, clearColor );
 }
 
 void Capture::UnsetResources()
index 11c29e9..00281e1 100644 (file)
@@ -71,12 +71,17 @@ public:
   /**
    * @copydoc Dali::Capture::Start
    */
-  void Start( Dali::Actor source, const Dali::Vector2& size, const std::string &path, const Dali::Vector4& clearColor, const uint32_t quality );
+  void Start( Dali::Actor source, const Dali::Vector2& position, const Dali::Vector2& size, const std::string &path, const Dali::Vector4& clearColor, const uint32_t quality );
 
   /**
    * @copydoc Dali::Capture::Start
    */
-  void Start( Dali::Actor source, const Dali::Vector2& size, const std::string &path, const Dali::Vector4& clearColor );
+  void Start( Dali::Actor source, const Dali::Vector2& position, const Dali::Vector2& size, const std::string &path, const Dali::Vector4& clearColor );
+
+  /**
+   * @copydoc Dali::Capture::SetImageQuality
+   */
+  void SetImageQuality( uint32_t quality );
 
   /**
    * @copydoc Dali::Capture::GetNativeImageSource
@@ -133,10 +138,13 @@ private:
   /**
    * @brief Setup render task.
    *
-   * @param[in] source is captured.
+   * @param[in] position top-left position of area to be captured
+   *            this position is defined in the window.
+   * @param[in] size two dimensional size of area to be captured
+   * @param[in] source sub-scene tree to be captured.
    * @param[in] clearColor background color
    */
-  void SetupRenderTask( Dali::Actor source, const Dali::Vector4& clearColor );
+  void SetupRenderTask( const Dali::Vector2& position, const Dali::Vector2& size, Dali::Actor source, const Dali::Vector4& clearColor );
 
   /**
    * @brief Unset render task.
@@ -153,11 +161,13 @@ private:
   /**
    * @brief Setup resources for capture.
    *
-   * @param[in] size is surface size.
-   * @param[in] clearColor is clear color of surface.
-   * @param[in] source is captured.
+   * @param[in] position top-left position of area to be captured
+   *            this position is defined in the window.
+   * @param[in] size two dimensional size of area to be captured
+   * @param[in] clearColor color to clear background surface.
+   * @param[in] source sub-scene tree to be captured.
    */
-  void SetupResources( const Dali::Vector2& size, const Dali::Vector4& clearColor, Dali::Actor source );
+  void SetupResources( const Dali::Vector2& position, const Dali::Vector2& size, const Dali::Vector4& clearColor, Dali::Actor source );
 
   /**
    * @brief Unset resources for capture.
@@ -198,7 +208,6 @@ private:
   Dali::Texture                               mNativeTexture;
   Dali::FrameBuffer                           mFrameBuffer;
   Dali::RenderTask                            mRenderTask;
-  Dali::Actor                                 mParent;
   Dali::Actor                                 mSource;
   Dali::CameraActor                           mCameraActor;
   Dali::Timer                                 mTimer;           ///< For timeout.
index 9d288e8..60dbc4a 100644 (file)
@@ -59,19 +59,29 @@ Capture::Capture( Capture&& rhs ) = default;
 
 Capture& Capture::operator=( Capture&& rhs ) = default;
 
+void Capture::Start( Actor source, const Vector2& position, const Vector2& size, const std::string &path, const Vector4& clearColor )
+{
+  GetImpl( *this ).Start( source, position, size, path, clearColor );
+}
+
 void Capture::Start( Actor source, const Vector2& size, const std::string &path, const Vector4& clearColor, const uint32_t quality )
 {
-  GetImpl( *this ).Start( source, size, path, clearColor, quality );
+  GetImpl( *this ).Start( source, Vector2::ZERO, size, path, clearColor, quality );
 }
 
 void Capture::Start( Actor source, const Vector2& size, const std::string &path, const Vector4& clearColor )
 {
-  GetImpl( *this ).Start( source, size, path, clearColor );
+  GetImpl( *this ).Start( source, Vector2::ZERO, size, path, clearColor );
 }
 
 void Capture::Start( Actor source, const Vector2& size, const std::string &path )
 {
-  GetImpl( *this ).Start( source, size, path, Dali::Color::TRANSPARENT );
+  GetImpl( *this ).Start( source, Vector2::ZERO, size, path, Dali::Color::TRANSPARENT );
+}
+
+void Capture::SetImageQuality( uint32_t quality )
+{
+  return GetImpl( *this ).SetImageQuality( quality );
 }
 
 Dali::NativeImageSourcePtr Capture::GetNativeImageSource() const
index 7113eee..5a6a049 100755 (executable)
@@ -188,9 +188,28 @@ public:
   /**
    * @brief Start capture and save the image as a file.
    *
+   * @SINCE_1_9.27
+   * @param[in] source source actor to be used for capture.
+   *            This source must be added on the window in advance.
+   * @param[in] position top-left position of area to be captured
+   *            this position is defined in the window.
+   * @param[in] size captured size.
+   * @param[in] path image file path to be saved as a file.
+   *            If path is empty string, the captured result is not be saved as a file.
+   * @param[in] clearColor background color of captured scene
+   * @note suppose that we want to capture actor 'A'. And, the actor 'A' is overlapped by another actor 'B' that is not a child of 'A'.
+   *       in this case, if source is root of scene, the captured image includes a part of actor 'B' on the 'A'.
+   *       however, if source is just actor 'A', the result includes only 'A'.
+   */
+  void Start( Actor source, const Vector2& position, const Vector2& size, const std::string &path, const Vector4& clearColor );
+
+  /**
+   * @brief Start capture and save the image as a file.
+   *
    * @SINCE_1_9.12
    *
    * @param[in] source source actor to be used for capture.
+   *            This source must be added on the window in advance.
    * @param[in] size captured size.
    * @param[in] path image file path to be saved as a file.
    *            If path is empty string, the captured result is not be saved as a file.
@@ -205,6 +224,7 @@ public:
    * @SINCE_1_3_4
    *
    * @param[in] source source actor to be used for capture.
+   *            This source must be added on the window in advance.
    * @param[in] size captured size.
    * @param[in] path image file path to be saved as a file.
    *            If path is empty string, the captured result is not be saved as a file.
@@ -218,6 +238,7 @@ public:
    * @SINCE_1_3_4
    *
    * @param[in] source source actor to be used for capture.
+   *            This source must be added on the window in advance.
    * @param[in] size captured size.
    * @param[in] path image file path to be saved as a file.
    *            If path is empty string, the captured result is not be saved as a file.
@@ -226,6 +247,13 @@ public:
   void Start( Actor source, const Vector2& size, const std::string &path );
 
   /**
+   * @brief Set result image quality in case of jpeg
+   *
+   * @param[in] quality The value to control image quality for jpeg file format in the range [1, 100]
+   */
+  void SetImageQuality( uint32_t quality );
+
+  /**
    * @brief Get NativeImageSourcePtr that is saved captured image.
    *
    * @SINCE_1_9.10