Make SceneView::Capture always emit CaptureFinished event 78/316478/4
authorSeungho Baek <sbsh.baek@samsung.com>
Thu, 22 Aug 2024 04:43:11 +0000 (13:43 +0900)
committerSeungho Baek <sbsh.baek@samsung.com>
Thu, 22 Aug 2024 08:52:03 +0000 (17:52 +0900)
Change-Id: I86262bf1cfdbd3785116b7ef8972a7f88bfd38f5
Signed-off-by: Seungho Baek <sbsh.baek@samsung.com>
automated-tests/src/dali-scene3d/utc-Dali-SceneView.cpp
dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp
dali-scene3d/internal/controls/scene-view/scene-view-impl.h

index bc9baaa..7b70199 100644 (file)
@@ -1297,6 +1297,68 @@ int UtcDaliSceneViewCapture01(void)
   END_TEST;
 }
 
+int UtcDaliSceneViewCapture02(void)
+{
+  ToolkitTestApplication application;
+
+  Scene3D::SceneView view = Scene3D::SceneView::New();
+  view.CaptureFinishedSignal().Connect(OnCaptureMultipleFinished);
+  view.SetProperty(Dali::Actor::Property::SIZE, Vector2(100, 100));
+
+  application.GetScene().Add(view);
+
+  application.SendNotification();
+  application.Render();
+
+  Scene3D::Model modelView1 = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
+  view.Add(modelView1);
+
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+  application.SendNotification();
+  application.Render();
+
+  CameraActor camera = Dali::CameraActor::New();
+  camera.SetProperty(Dali::Actor::Property::NAME, "camera");
+  camera.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+  camera.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+  camera.SetFieldOfView(0.5f);
+  camera.SetNearClippingPlane(1.0f);
+  camera.SetFarClippingPlane(5000.0f);
+  camera.SetProperty(Dali::Actor::Property::POSITION, Vector3(20, 30, 40));
+
+  view.Add(camera);
+
+  gCapturedCount = 0;
+  gCaptureIds.clear();
+  gCapturedImageUrls.clear();
+  int32_t captureId = view.Capture(camera, Vector2(300, 300));
+  int32_t captureId2 = view.Capture(camera, Vector2(300, 300));
+
+  application.SendNotification();
+  application.Render();
+  application.SendNotification();
+  application.Render();
+  application.SendNotification();
+
+  DALI_TEST_EQUALS(gCapturedCount, 2, TEST_LOCATION);
+  DALI_TEST_EQUALS(gCaptureIds.size(), 2, TEST_LOCATION);
+  auto idIter1 = std::find(gCaptureIds.begin(), gCaptureIds.end(), captureId);
+  bool isIter1 = idIter1 != gCaptureIds.end();
+  DALI_TEST_EQUALS(isIter1, true, TEST_LOCATION);
+  auto idIter2 = std::find(gCaptureIds.begin(), gCaptureIds.end(), captureId2);
+  bool isIter2 = idIter2 != gCaptureIds.end();
+  DALI_TEST_EQUALS(isIter2, true, TEST_LOCATION);
+
+  DALI_TEST_EQUALS(gCapturedImageUrls.size(), 2, TEST_LOCATION);
+  DALI_TEST_EQUALS(!!gCapturedImageUrls[0], true, TEST_LOCATION);
+  DALI_TEST_EQUALS(!!gCapturedImageUrls[1], true, TEST_LOCATION);
+  DALI_TEST_NOT_EQUALS(gCapturedImageUrls[0], gCapturedImageUrls[1], 0.1f, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliSceneViewCaptureCancel(void)
 {
   ToolkitTestApplication application;
@@ -1418,28 +1480,19 @@ int UtcDaliSceneViewCaptureFailed(void)
   END_TEST;
 }
 
-int UtcDaliSceneViewCapture02(void)
+int UtcDaliSceneViewCaptureFailed2(void)
 {
   ToolkitTestApplication application;
 
   Scene3D::SceneView view = Scene3D::SceneView::New();
-  view.CaptureFinishedSignal().Connect(OnCaptureMultipleFinished);
+  view.CaptureFinishedSignal().Connect(OnCaptureFinished);
   view.SetProperty(Dali::Actor::Property::SIZE, Vector2(100, 100));
 
-  application.GetScene().Add(view);
+  // not add on Scene.
 
   application.SendNotification();
   application.Render();
 
-  Scene3D::Model modelView1 = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
-  view.Add(modelView1);
-
-  application.SendNotification();
-  application.Render();
-  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
-  application.SendNotification();
-  application.Render();
-
   CameraActor camera = Dali::CameraActor::New();
   camera.SetProperty(Dali::Actor::Property::NAME, "camera");
   camera.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
@@ -1451,31 +1504,16 @@ int UtcDaliSceneViewCapture02(void)
 
   view.Add(camera);
 
-  gCapturedCount = 0;
-  gCaptureIds.clear();
-  gCapturedImageUrls.clear();
+  gCaptureFinishedCalled = false;
+  gCaptureId = -1;
+  gCapturedImageUrl.Reset();
   int32_t captureId = view.Capture(camera, Vector2(300, 300));
-  int32_t captureId2 = view.Capture(camera, Vector2(300, 300));
 
-  application.SendNotification();
-  application.Render();
-  application.SendNotification();
-  application.Render();
-  application.SendNotification();
+  application.RunIdles();
 
-  DALI_TEST_EQUALS(gCapturedCount, 2, TEST_LOCATION);
-  DALI_TEST_EQUALS(gCaptureIds.size(), 2, TEST_LOCATION);
-  auto idIter1 = std::find(gCaptureIds.begin(), gCaptureIds.end(), captureId);
-  bool isIter1 = idIter1 != gCaptureIds.end();
-  DALI_TEST_EQUALS(isIter1, true, TEST_LOCATION);
-  auto idIter2 = std::find(gCaptureIds.begin(), gCaptureIds.end(), captureId2);
-  bool isIter2 = idIter2 != gCaptureIds.end();
-  DALI_TEST_EQUALS(isIter2, true, TEST_LOCATION);
-
-  DALI_TEST_EQUALS(gCapturedImageUrls.size(), 2, TEST_LOCATION);
-  DALI_TEST_EQUALS(!!gCapturedImageUrls[0], true, TEST_LOCATION);
-  DALI_TEST_EQUALS(!!gCapturedImageUrls[1], true, TEST_LOCATION);
-  DALI_TEST_NOT_EQUALS(gCapturedImageUrls[0], gCapturedImageUrls[1], 0.1f, TEST_LOCATION);
+  DALI_TEST_EQUALS(gCaptureFinishedCalled, true, TEST_LOCATION);
+  DALI_TEST_EQUALS(gCaptureId, captureId, TEST_LOCATION);
+  DALI_TEST_EQUALS(!!gCapturedImageUrl, false, TEST_LOCATION);
 
   END_TEST;
 }
index 11b0a67..7b83c24 100644 (file)
@@ -67,13 +67,13 @@ DALI_PROPERTY_REGISTRATION(Scene3D, SceneView, "CropToMask", BOOLEAN, CROP_TO_MA
 DALI_TYPE_REGISTRATION_END()
 
 Property::Index    RENDERING_BUFFER        = Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX + 1;
-constexpr int32_t  DEFAULT_ORIENTATION     = 0;
-constexpr int32_t  INVALID_INDEX           = -1;
-constexpr int32_t  INVALID_CAPTURE_ID      = -1;
-constexpr uint32_t MAXIMUM_SIZE_SHADOW_MAP = 2048;
+static constexpr float    MIM_CAPTURE_SIZE        = 1.0f;
+static constexpr int32_t  DEFAULT_ORIENTATION     = 0;
+static constexpr int32_t  INVALID_INDEX           = -1;
+static constexpr uint32_t MAXIMUM_SIZE_SHADOW_MAP = 2048;
 
-constexpr int32_t SCENE_ORDER_INDEX  = 100;
-constexpr int32_t SHADOW_ORDER_INDEX = 99;
+static constexpr int32_t SCENE_ORDER_INDEX  = 100;
+static constexpr int32_t SHADOW_ORDER_INDEX = 99;
 
 static constexpr std::string_view SKYBOX_INTENSITY_STRING = "uIntensity";
 static constexpr std::string_view Y_FLIP_MASK_TEXTURE     = "uYFlipMaskTexture";
@@ -328,6 +328,7 @@ void ConvertFovFromHorizontalToVertical(float aspect, float& fov)
 SceneView::SceneView()
 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
   mWindowOrientation(DEFAULT_ORIENTATION),
+  mFailedCaptureCallbacks(nullptr),
   mSkybox(),
   mSkyboxOrientation(Quaternion()),
   mSkyboxIntensity(1.0f),
@@ -370,6 +371,12 @@ SceneView::~SceneView()
     mCaptureContainer.clear();
     ResetCaptureTimer();
 
+    if(mFailedCaptureCallbacks && Adaptor::IsAvailable())
+    {
+      // Removes the callback from the callback manager in case the control is destroyed before the callback is executed.
+      Adaptor::Get().RemoveIdle(mFailedCaptureCallbacks);
+    }
+
     Adaptor::Get().UnregisterProcessorOnce(*this);
 
     // Request image resource GC
@@ -911,10 +918,11 @@ Quaternion SceneView::GetSkyboxOrientation() const
 
 int32_t SceneView::Capture(Dali::CameraActor camera, const Vector2& size)
 {
-  if(size.x < 0.0f || size.y < 0.0f)
+  bool capturePossible = true;
+  if(size.x < MIM_CAPTURE_SIZE || size.y < MIM_CAPTURE_SIZE)
   {
     DALI_LOG_ERROR("The width and height should be positive.\n");
-    return INVALID_CAPTURE_ID;
+    capturePossible = false;
   }
 
   uint32_t width = std::max(1u, unsigned(size.width));
@@ -922,82 +930,97 @@ int32_t SceneView::Capture(Dali::CameraActor camera, const Vector2& size)
   if(width > Dali::GetMaxTextureSize() || height > Dali::GetMaxTextureSize())
   {
     DALI_LOG_ERROR("The input size is too large.\n");
-    return INVALID_CAPTURE_ID;
+    capturePossible = false;
   }
 
   if(!mRootLayer.GetProperty<bool>(Dali::Actor::Property::CONNECTED_TO_SCENE))
   {
     DALI_LOG_ERROR("Current SceneView is not connected on scene tree\n");
-    return INVALID_CAPTURE_ID;
+    capturePossible = false;
   }
 
-  if(!camera.GetProperty<bool>(Dali::Actor::Property::CONNECTED_TO_SCENE))
+  if(!capturePossible)
   {
-    mRootLayer.Add(camera);
+    mFailedCaptureRequests.push_back(mCaptureId);
+    if(!mFailedCaptureCallbacks && DALI_LIKELY(Adaptor::IsAvailable()))
+    {
+      mFailedCaptureCallbacks = MakeCallback(this, &SceneView::OnCaptureFailedIdle);
+      if(!Adaptor::Get().AddIdle(mFailedCaptureCallbacks, false))
+      {
+        mFailedCaptureCallbacks = nullptr;
+      }
+    }
   }
-
-  std::shared_ptr<CaptureData> captureData = std::make_shared<CaptureData>();
-  captureData->mCaptureId                  = mCaptureId;
-  captureData->mCaptureTexture             = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
-  captureData->mCaptureFrameBuffer         = Dali::FrameBuffer::New(captureData->mCaptureTexture.GetWidth(), captureData->mCaptureTexture.GetHeight(), Dali::FrameBuffer::Attachment::DEPTH_STENCIL);
-  DevelFrameBuffer::SetMultiSamplingLevel(captureData->mCaptureFrameBuffer, mFrameBufferMultiSamplingLevel);
-  captureData->mCaptureFrameBuffer.AttachColorTexture(captureData->mCaptureTexture);
-
-  captureData->mCaptureCamera = camera;
-  captureData->mCaptureCameraOriginalAspectRatio = captureData->mCaptureCamera.GetAspectRatio();
-  captureData->mCaptureCamera.SetAspectRatio((float)width/(float)height);
-
-  RenderTaskList taskList   = mSceneHolder.GetRenderTaskList();
-  captureData->mCaptureTask = taskList.CreateTask();
-  captureData->mCaptureTask.SetSourceActor(mRootLayer);
-  captureData->mCaptureTask.SetExclusive(true);
-  captureData->mCaptureTask.SetCullMode(false);
-  captureData->mCaptureTask.SetOrderIndex(SCENE_ORDER_INDEX + 1);
-  captureData->mCaptureTask.SetCameraActor(captureData->mCaptureCamera);
-  captureData->mCaptureTask.SetFrameBuffer(captureData->mCaptureFrameBuffer);
-  captureData->mCaptureTask.SetClearEnabled(true);
-  captureData->mCaptureTask.SetClearColor(Color::TRANSPARENT);
-  captureData->mCaptureTask.SetRefreshRate(Dali::RenderTask::REFRESH_ONCE);
-
-  captureData->mCaptureInvertCamera = Dali::CameraActor::New(size);
-  captureData->mCaptureInvertCamera.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
-  captureData->mCaptureInvertCamera.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
-  captureData->mCaptureInvertCamera.SetProperty(Dali::Actor::Property::POSITION_X, size.x / 2.0f);
-  captureData->mCaptureInvertCamera.SetProperty(Dali::Actor::Property::POSITION_Y, size.y / 2.0f);
-
-  captureData->mCaptureUrl       = Dali::Toolkit::Image::GenerateUrl(captureData->mCaptureFrameBuffer, 0u);
-  captureData->mCaptureImageView = Dali::Toolkit::ImageView::New(captureData->mCaptureUrl.GetUrl());
-  captureData->mCaptureImageView.SetProperty(Dali::Actor::Property::SIZE, size);
-  captureData->mCaptureImageView.Add(captureData->mCaptureInvertCamera);
-
-  Window window = DevelWindow::Get(Self());
-  window.Add(captureData->mCaptureImageView);
-
-  captureData->mCaptureInvertTexture     = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
-  captureData->mCaptureInvertFrameBuffer = Dali::FrameBuffer::New(captureData->mCaptureInvertTexture.GetWidth(), captureData->mCaptureInvertTexture.GetHeight(), Dali::FrameBuffer::Attachment::DEPTH_STENCIL);
-  captureData->mCaptureInvertFrameBuffer.AttachColorTexture(captureData->mCaptureInvertTexture);
-
-  captureData->mCaptureInvertTask = taskList.CreateTask();
-  captureData->mCaptureInvertTask.SetSourceActor(captureData->mCaptureImageView);
-  captureData->mCaptureInvertTask.SetExclusive(true);
-  captureData->mCaptureInvertTask.SetCullMode(false);
-  captureData->mCaptureInvertTask.SetOrderIndex(SCENE_ORDER_INDEX + 2);
-  captureData->mCaptureInvertTask.SetCameraActor(captureData->mCaptureInvertCamera);
-  captureData->mCaptureInvertTask.SetFrameBuffer(captureData->mCaptureInvertFrameBuffer);
-  captureData->mCaptureInvertTask.SetClearEnabled(true);
-  captureData->mCaptureInvertTask.SetClearColor(Color::TRANSPARENT);
-  captureData->mCaptureInvertTask.SetRefreshRate(Dali::RenderTask::REFRESH_ONCE);
-  captureData->mCaptureInvertTask.FinishedSignal().Connect(this, &SceneView::OnCaptureFinished);
-
-  captureData->mStartTick = mTimerTickCount;
-
-  mCaptureContainer.push_back(std::make_pair(captureData->mCaptureInvertTask, captureData));
-
-  if(!mCaptureTimer)
+  else
   {
-    mCaptureTimer = Dali::Timer::New(1000);
-    mCaptureTimer.TickSignal().Connect(this, &SceneView::OnTimeOut);
-    mCaptureTimer.Start();
+    if(!camera.GetProperty<bool>(Dali::Actor::Property::CONNECTED_TO_SCENE))
+    {
+      mRootLayer.Add(camera);
+    }
+
+    std::shared_ptr<CaptureData> captureData = std::make_shared<CaptureData>();
+    captureData->mCaptureId                  = mCaptureId;
+    captureData->mCaptureTexture             = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+    captureData->mCaptureFrameBuffer         = Dali::FrameBuffer::New(captureData->mCaptureTexture.GetWidth(), captureData->mCaptureTexture.GetHeight(), Dali::FrameBuffer::Attachment::DEPTH_STENCIL);
+    DevelFrameBuffer::SetMultiSamplingLevel(captureData->mCaptureFrameBuffer, mFrameBufferMultiSamplingLevel);
+    captureData->mCaptureFrameBuffer.AttachColorTexture(captureData->mCaptureTexture);
+
+    captureData->mCaptureCamera                    = camera;
+    captureData->mCaptureCameraOriginalAspectRatio = captureData->mCaptureCamera.GetAspectRatio();
+    captureData->mCaptureCamera.SetAspectRatio((float)width / (float)height);
+
+    RenderTaskList taskList   = mSceneHolder.GetRenderTaskList();
+    captureData->mCaptureTask = taskList.CreateTask();
+    captureData->mCaptureTask.SetSourceActor(mRootLayer);
+    captureData->mCaptureTask.SetExclusive(true);
+    captureData->mCaptureTask.SetCullMode(false);
+    captureData->mCaptureTask.SetOrderIndex(SCENE_ORDER_INDEX + 1);
+    captureData->mCaptureTask.SetCameraActor(captureData->mCaptureCamera);
+    captureData->mCaptureTask.SetFrameBuffer(captureData->mCaptureFrameBuffer);
+    captureData->mCaptureTask.SetClearEnabled(true);
+    captureData->mCaptureTask.SetClearColor(Color::TRANSPARENT);
+    captureData->mCaptureTask.SetRefreshRate(Dali::RenderTask::REFRESH_ONCE);
+
+    captureData->mCaptureInvertCamera = Dali::CameraActor::New(size);
+    captureData->mCaptureInvertCamera.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+    captureData->mCaptureInvertCamera.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+    captureData->mCaptureInvertCamera.SetProperty(Dali::Actor::Property::POSITION_X, size.x / 2.0f);
+    captureData->mCaptureInvertCamera.SetProperty(Dali::Actor::Property::POSITION_Y, size.y / 2.0f);
+
+    captureData->mCaptureUrl       = Dali::Toolkit::Image::GenerateUrl(captureData->mCaptureFrameBuffer, 0u);
+    captureData->mCaptureImageView = Dali::Toolkit::ImageView::New(captureData->mCaptureUrl.GetUrl());
+    captureData->mCaptureImageView.SetProperty(Dali::Actor::Property::SIZE, size);
+    captureData->mCaptureImageView.Add(captureData->mCaptureInvertCamera);
+
+    Window window = DevelWindow::Get(Self());
+    window.Add(captureData->mCaptureImageView);
+
+    captureData->mCaptureInvertTexture     = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+    captureData->mCaptureInvertFrameBuffer = Dali::FrameBuffer::New(captureData->mCaptureInvertTexture.GetWidth(), captureData->mCaptureInvertTexture.GetHeight(), Dali::FrameBuffer::Attachment::DEPTH_STENCIL);
+    captureData->mCaptureInvertFrameBuffer.AttachColorTexture(captureData->mCaptureInvertTexture);
+
+    captureData->mCaptureInvertTask = taskList.CreateTask();
+    captureData->mCaptureInvertTask.SetSourceActor(captureData->mCaptureImageView);
+    captureData->mCaptureInvertTask.SetExclusive(true);
+    captureData->mCaptureInvertTask.SetCullMode(false);
+    captureData->mCaptureInvertTask.SetOrderIndex(SCENE_ORDER_INDEX + 2);
+    captureData->mCaptureInvertTask.SetCameraActor(captureData->mCaptureInvertCamera);
+    captureData->mCaptureInvertTask.SetFrameBuffer(captureData->mCaptureInvertFrameBuffer);
+    captureData->mCaptureInvertTask.SetClearEnabled(true);
+    captureData->mCaptureInvertTask.SetClearColor(Color::TRANSPARENT);
+    captureData->mCaptureInvertTask.SetRefreshRate(Dali::RenderTask::REFRESH_ONCE);
+    captureData->mCaptureInvertTask.FinishedSignal().Connect(this, &SceneView::OnCaptureFinished);
+
+    captureData->mStartTick = mTimerTickCount;
+
+    mCaptureContainer.push_back(std::make_pair(captureData->mCaptureInvertTask, captureData));
+
+    if(!mCaptureTimer)
+    {
+      mCaptureTimer = Dali::Timer::New(1000);
+      mCaptureTimer.TickSignal().Connect(this, &SceneView::OnTimeOut);
+      mCaptureTimer.Start();
+    }
   }
   return mCaptureId++;
 }
@@ -1628,16 +1651,13 @@ void SceneView::UpdateShadowMapBuffer(uint32_t shadowMapSize)
 
 void SceneView::OnCaptureFinished(Dali::RenderTask& task)
 {
-  int32_t                 captureId = INVALID_CAPTURE_ID;
-  Dali::Toolkit::ImageUrl imageUrl;
-
   auto iter = std::find_if(mCaptureContainer.begin(), mCaptureContainer.end(), [task](std::pair<Dali::RenderTask, std::shared_ptr<CaptureData>> item)
                            { return item.first == task; });
 
   if(iter != mCaptureContainer.end())
   {
-    captureId = iter->second->mCaptureId;
-    imageUrl  = Dali::Toolkit::ImageUrl::New(iter->second->mCaptureInvertTexture);
+    int32_t                 captureId = iter->second->mCaptureId;
+    Dali::Toolkit::ImageUrl imageUrl  = Dali::Toolkit::ImageUrl::New(iter->second->mCaptureInvertTexture);
 
     ResetCaptureData(iter->second);
     mCaptureContainer.erase(iter);
@@ -1898,6 +1918,17 @@ void SceneView::Process(bool postProcessor)
   mIsProcessorRegistered = false;
 }
 
+void SceneView::OnCaptureFailedIdle()
+{
+  for(auto&& captureId : mFailedCaptureRequests)
+  {
+    auto                     self = Self();
+    Dali::Scene3D::SceneView handle(Dali::Scene3D::SceneView::DownCast(self));
+    mCaptureFinishedSignal.Emit(handle, captureId, Dali::Toolkit::ImageUrl());
+  }
+  mFailedCaptureCallbacks = nullptr;
+}
+
 } // namespace Internal
 } // namespace Scene3D
 } // namespace Dali
index bf24adc..694594d 100644 (file)
@@ -531,6 +531,11 @@ private:
    */
   void ResetCaptureTimer();
 
+  /**
+   * @brief Emit capture failed event on idle.
+   */
+  void OnCaptureFailedIdle();
+
 private: // Implementation of Processor
   /**
    * @copydoc Dali::Integration::Processor::Process()
@@ -567,6 +572,8 @@ private: // Implementation of Processor
   float                                               mSkyboxIntensity{1.0f};
   uint8_t                                             mFrameBufferMultiSamplingLevel{0u};
   Dali::Scene3D::SceneView::CaptureFinishedSignalType mCaptureFinishedSignal;
+  std::vector<int32_t>                                mFailedCaptureRequests;
+  CallbackBase*                                       mFailedCaptureCallbacks;
 
   // camera Transition
   CameraActor                                                  mTransitionCamera;