Add SetResolution method to SceneView 50/301950/5
authorseungho baek <sbsh.baek@samsung.com>
Tue, 28 Nov 2023 07:13:21 +0000 (16:13 +0900)
committerseungho baek <sbsh.baek@samsung.com>
Mon, 4 Dec 2023 02:12:52 +0000 (11:12 +0900)
Change-Id: Ib3b9ea2352457eb3d8d6085eed2ad58300fb24e5
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
dali-scene3d/public-api/controls/scene-view/scene-view.cpp
dali-scene3d/public-api/controls/scene-view/scene-view.h

index aaf05f6..7adb73e 100644 (file)
@@ -1034,6 +1034,50 @@ int UtcDaliSceneViewColorMode(void)
   END_TEST;
 }
 
+int UtcDaliSceneViewSetResolution(void)
+{
+  ToolkitTestApplication application;
+
+  Scene3D::SceneView view = Scene3D::SceneView::New();
+  application.GetScene().Add(view);
+  view.SetProperty(Dali::Actor::Property::SIZE, Vector2(100, 100));
+
+  DALI_TEST_EQUALS(view.GetResolutionWidth(), 100u, TEST_LOCATION);
+  DALI_TEST_EQUALS(view.GetResolutionHeight(), 100u, TEST_LOCATION);
+
+  view.SetResolution(200u, 200u);
+
+  DALI_TEST_EQUALS(view.GetResolutionWidth(), 100u, TEST_LOCATION);
+  DALI_TEST_EQUALS(view.GetResolutionHeight(), 100u, TEST_LOCATION);
+
+  view.UseFramebuffer(true);
+
+  DALI_TEST_EQUALS(view.GetResolutionWidth(), 200u, TEST_LOCATION);
+  DALI_TEST_EQUALS(view.GetResolutionHeight(), 200u, TEST_LOCATION);
+
+  view.SetResolution(300u, 0u);
+
+  DALI_TEST_EQUALS(view.GetResolutionWidth(), 100u, TEST_LOCATION);
+  DALI_TEST_EQUALS(view.GetResolutionHeight(), 100u, TEST_LOCATION);
+
+  view.SetResolution(300u, 400u);
+
+  DALI_TEST_EQUALS(view.GetResolutionWidth(), 300u, TEST_LOCATION);
+  DALI_TEST_EQUALS(view.GetResolutionHeight(), 400u, TEST_LOCATION);
+
+  view.ResetResolution();
+
+  DALI_TEST_EQUALS(view.GetResolutionWidth(), 100u, TEST_LOCATION);
+  DALI_TEST_EQUALS(view.GetResolutionHeight(), 100u, TEST_LOCATION);
+
+  view.SetProperty(Dali::Actor::Property::SIZE, Vector2(400, 400));
+
+  DALI_TEST_EQUALS(view.GetResolutionWidth(), 400u, TEST_LOCATION);
+  DALI_TEST_EQUALS(view.GetResolutionHeight(), 400u, TEST_LOCATION);
+
+  END_TEST;
+}
+
 namespace
 {
 const char* TEST_MASK_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/mask.png";
index 7e59d6a..d4f4034 100644 (file)
@@ -709,6 +709,43 @@ bool SceneView::IsUsingFramebuffer() const
   return mUseFrameBuffer;
 }
 
+void SceneView::SetResolution(uint32_t width, uint32_t height)
+{
+  if(mWindowWidth != width || mWindowHeight != height)
+  {
+    mWindowWidth  = width;
+    mWindowHeight = height;
+    if(mUseFrameBuffer)
+    {
+      mWindowSizeChanged = true;
+      UpdateRenderTask();
+    }
+  }
+}
+
+uint32_t SceneView::GetResolutionWidth()
+{
+  if(!mUseFrameBuffer || mWindowWidth == 0u || mWindowHeight == 0u)
+  {
+    return static_cast<uint32_t>(Self().GetProperty<float>(Dali::Actor::Property::SIZE_WIDTH));
+  }
+  return mWindowWidth;
+}
+
+uint32_t SceneView::GetResolutionHeight()
+{
+  if(!mUseFrameBuffer || mWindowWidth == 0u || mWindowHeight == 0u)
+  {
+    return static_cast<uint32_t>(Self().GetProperty<float>(Dali::Actor::Property::SIZE_HEIGHT));
+  }
+  return mWindowHeight;
+}
+
+void SceneView::ResetResolution()
+{
+  SetResolution(0u, 0u);
+}
+
 void SceneView::SetFramebufferMultiSamplingLevel(uint8_t multiSamplingLevel)
 {
   if(mFrameBufferMultiSamplingLevel != multiSamplingLevel)
@@ -1080,27 +1117,31 @@ void SceneView::UpdateRenderTask()
     }
 
     Vector3     size        = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
-    const float aspectRatio = size.width / size.height;
-    mSelectedCamera.SetAspectRatio(aspectRatio);
+    float aspectRatio = size.width / size.height;
 
     uint32_t shadowMapBufferSize = std::min(static_cast<uint32_t>(std::max(size.width, size.height)), MAXIMUM_SIZE_SHADOW_MAP);
     UpdateShadowMapBuffer(shadowMapBufferSize);
 
     if(mUseFrameBuffer)
     {
+      uint32_t width  = (mWindowWidth == 0 || mWindowHeight == 0) ? static_cast<uint32_t>(size.width) : mWindowWidth;
+      uint32_t height = (mWindowWidth == 0 || mWindowHeight == 0) ? static_cast<uint32_t>(size.height) : mWindowHeight;
+      aspectRatio     = static_cast<float>(width) / static_cast<float>(height);
+
       Dali::FrameBuffer currentFrameBuffer = mRenderTask.GetFrameBuffer();
       if(!currentFrameBuffer ||
          !Dali::Equals(currentFrameBuffer.GetColorTexture().GetWidth(), size.width) ||
          !Dali::Equals(currentFrameBuffer.GetColorTexture().GetHeight(), size.height) ||
-         mMaskingPropertyChanged)
+         mMaskingPropertyChanged ||
+         mWindowSizeChanged)
       {
         mRootLayer.SetProperty(Dali::Actor::Property::COLOR_MODE, ColorMode::USE_OWN_COLOR);
         mRenderTask.ResetViewportGuideActor();
         mRenderTask.SetViewport(Dali::Viewport(Vector4::ZERO));
 
         // create offscreen buffer of new size to render our child actors to
-        mTexture     = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, unsigned(size.width), unsigned(size.height));
-        mFrameBuffer = FrameBuffer::New(size.width, size.height, FrameBuffer::Attachment::DEPTH_STENCIL);
+        mTexture     = Dali::Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+        mFrameBuffer = FrameBuffer::New(width, height, FrameBuffer::Attachment::DEPTH_STENCIL);
         mFrameBuffer.AttachColorTexture(mTexture);
         DevelFrameBuffer::SetMultiSamplingLevel(mFrameBuffer, mFrameBufferMultiSamplingLevel);
         Dali::Toolkit::ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(mFrameBuffer, 0u);
@@ -1119,7 +1160,6 @@ void SceneView::UpdateRenderTask()
           imagePropertyMap.Insert(Toolkit::DevelImageVisual::Property::MASKING_TYPE, Toolkit::DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
           Self().RegisterProperty(Y_FLIP_MASK_TEXTURE, FLIP_MASK_TEXTURE);
         }
-        mMaskingPropertyChanged = false;
 
         mVisual = Toolkit::VisualFactory::Get().CreateVisual(imagePropertyMap);
         Toolkit::DevelControl::RegisterVisual(*this, RENDERING_BUFFER, mVisual);
@@ -1127,6 +1167,9 @@ void SceneView::UpdateRenderTask()
         mRenderTask.SetFrameBuffer(mFrameBuffer);
         mRenderTask.SetClearEnabled(true);
         mRenderTask.SetClearColor(Color::TRANSPARENT);
+
+        mMaskingPropertyChanged = false;
+        mWindowSizeChanged = false;
       }
     }
     else
@@ -1147,6 +1190,8 @@ void SceneView::UpdateRenderTask()
       }
     }
 
+    mSelectedCamera.SetAspectRatio(aspectRatio);
+
     RotateCamera();
   }
 }
index ce9641a..769484c 100644 (file)
@@ -181,6 +181,26 @@ public:
   bool IsUsingFramebuffer() const;
 
   /**
+   * @copydoc SceneView::SetResolution()
+   */
+  void SetResolution(uint32_t width, uint32_t height);
+
+  /**
+   * @copydoc SceneView::GetResolutionWidth()
+   */
+  uint32_t GetResolutionWidth();
+
+  /**
+   * @copydoc SceneView::GetResolutionHeight()
+   */
+  uint32_t GetResolutionHeight();
+
+  /**
+   * @copydoc SceneView::ResetResolution()
+   */
+  void ResetResolution();
+
+  /**
    * @copydoc SceneView::SetFramebufferMultiSamplingLevel()
    */
   void SetFramebufferMultiSamplingLevel(uint8_t multiSamplingLevel);
@@ -425,6 +445,10 @@ private:
   float                                          mSkyboxIntensity{1.0f};
   uint8_t                                        mFrameBufferMultiSamplingLevel{0u};
 
+  bool mWindowSizeChanged{false};
+  uint32_t mWindowWidth{0};
+  uint32_t mWindowHeight{0};
+
   // Masking
   std::string mAlphaMaskUrl;
   float       mMaskContentScaleFactor{1.0f};
index 1bfc81e..8a1efb9 100644 (file)
@@ -132,6 +132,26 @@ bool SceneView::IsUsingFramebuffer() const
   return GetImpl(*this).IsUsingFramebuffer();
 }
 
+void SceneView::SetResolution(uint32_t width, uint32_t height)
+{
+  GetImpl(*this).SetResolution(width, height);
+}
+
+uint32_t SceneView::GetResolutionWidth()
+{
+  return GetImpl(*this).GetResolutionWidth();
+}
+
+uint32_t SceneView::GetResolutionHeight()
+{
+  return GetImpl(*this).GetResolutionHeight();
+}
+
+void SceneView::ResetResolution()
+{
+  GetImpl(*this).ResetResolution();
+}
+
 void SceneView::SetFramebufferMultiSamplingLevel(uint8_t multiSamplingLevel)
 {
   GetImpl(*this).SetFramebufferMultiSamplingLevel(multiSamplingLevel);
index 41b9e17..3c6f064 100644 (file)
@@ -369,6 +369,42 @@ public:
   bool IsUsingFramebuffer() const;
 
   /**
+   * @brief Sets SceneView's resolution manually.
+   * @note This manual resolution is only available when the SceneView uses FBO for rendering by using UseFrameBuffer(true).
+   * @note If the aspect ratio of input width/height is different with SceneView's aspect ratio, the rendered result is stretched to fill SceneView's area.
+   *
+   * @SINCE_2_3.2
+   * @param[in] width The input width.
+   * @param[in] height The input height.
+   */
+  void SetResolution(uint32_t width, uint32_t height);
+
+  /**
+   * @brief Retrieves width of resolution of the SceneView.
+   * @note If the SceneView not uses FBO, this method returns SceneView's width.
+   *
+   * @SINCE_2_3.2
+   * @return Width value of resolution of the SceneView.
+   */
+  uint32_t GetResolutionWidth();
+
+  /**
+   * @brief Retrieves height of resolution of the SceneView.
+   * @note If the SceneView not uses FBO, this method returns SceneView's height.
+   *
+   * @SINCE_2_3.2
+   * @return Height value of resolution of the SceneView.
+   */
+  uint32_t GetResolutionHeight();
+
+  /**
+   * @brief Resets SceneView's resolution to the current size of SceneView.
+   *
+   * @SINCE_2_3.2
+   */
+  void ResetResolution();
+
+  /**
    * @brief Sets Multisampling level when we use Framebuffer.
    * Default is 0.
    *