Fix Window Rotation issue 90/282390/10
authorseungho <sbsh.baek@samsung.com>
Fri, 30 Sep 2022 10:30:47 +0000 (19:30 +0900)
committerseungho <sbsh.baek@samsung.com>
Thu, 6 Oct 2022 02:42:34 +0000 (11:42 +0900)
 - Viewport was incorrectly computed when viewport is not fullscreen and window is rotated.
 - Scissor rect was incorrectly computed when viewport is not fullscreen and window is rotated.

Change-Id: I44c64a2216f6364d2d29e0bcdd38c5e0cbc7467c
Signed-off-by: seungho <sbsh.baek@samsung.com>
automated-tests/src/dali/utc-Dali-RenderTask.cpp
automated-tests/src/dali/utc-Dali-Scene.cpp
dali/devel-api/actors/camera-actor-devel.cpp [new file with mode: 0644]
dali/devel-api/actors/camera-actor-devel.h
dali/devel-api/file.list
dali/internal/render/common/render-algorithms.cpp
dali/internal/render/common/render-algorithms.h
dali/internal/render/common/render-manager.cpp

index 53ba954..e625d29 100644 (file)
@@ -3606,4 +3606,80 @@ int UtcDaliRenderTaskViewportGuideActor(void)
   DALI_TEST_EQUALS(viewportPosition, Vector2(90, 250), TEST_LOCATION);
 
   END_TEST;
+}
+
+int UtcDaliRenderTaskViewportGuideActor02(void)
+{
+  TestApplication application(
+    TestApplication::DEFAULT_SURFACE_WIDTH,
+    TestApplication::DEFAULT_SURFACE_HEIGHT,
+    TestApplication::DEFAULT_HORIZONTAL_DPI,
+    TestApplication::DEFAULT_VERTICAL_DPI,
+    true,
+    true);
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+  TraceCallStack&    callStack     = glAbstraction.GetViewportTrace();
+  glAbstraction.EnableViewportCallTrace(true);
+  tet_infoline("Testing RenderTask with ViewportGuideActor02");
+
+  Stage   stage = Stage::GetCurrent();
+  Vector2 stageSize(stage.GetSize());
+
+  // Render and notify
+  application.SendNotification();
+  application.Render(16);
+  glAbstraction.ResetViewportCallStack();
+
+  Geometry geometry = Geometry::New();
+  Shader   shader   = Shader::New("vertexSrc", "fragmentSrc");
+  Renderer renderer = Renderer::New(geometry, shader);
+
+  Actor blue                                 = Actor::New();
+  blue[Dali::Actor::Property::NAME]          = "Blue";
+  blue[Dali::Actor::Property::ANCHOR_POINT]  = AnchorPoint::TOP_LEFT;
+  blue[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::TOP_LEFT;
+  blue[Dali::Actor::Property::SIZE]          = Vector2(400, 300);
+  blue[Dali::Actor::Property::POSITION]      = Vector2(100, 50);
+  blue.AddRenderer(renderer);
+  stage.Add(blue);
+
+  Actor green                                 = Actor::New();
+  green[Dali::Actor::Property::NAME]          = "Green";
+  green[Dali::Actor::Property::ANCHOR_POINT]  = AnchorPoint::TOP_LEFT;
+  green[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::TOP_LEFT;
+  green[Dali::Actor::Property::SIZE]          = Vector2(400, 300);
+  green[Dali::Actor::Property::POSITION]      = Vector2(100, 50);
+  green.AddRenderer(renderer);
+  stage.Add(green);
+
+  RenderTaskList renderTaskList = stage.GetRenderTaskList();
+  RenderTask     renderTask     = renderTaskList.CreateTask();
+
+  Dali::CameraActor cameraActor                     = Dali::CameraActor::New(stageSize);
+  cameraActor[Dali::Actor::Property::ANCHOR_POINT]  = AnchorPoint::CENTER;
+  cameraActor[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
+  stage.Add(cameraActor);
+
+  renderTask.SetExclusive(true);
+  renderTask.SetInputEnabled(true);
+  renderTask.SetCameraActor(cameraActor);
+  renderTask.SetSourceActor(blue);
+  renderTask.SetViewportGuideActor(blue);
+
+  application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_HEIGHT,
+                                        TestApplication::DEFAULT_SURFACE_WIDTH,
+                                        90);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render(16);
+
+  std::string viewportParams1("50, 100, 300, 400"); // to match newSize
+  std::string viewportParams2("0, 0, 480, 800"); // to match newSize
+
+  // Check that the viewport is handled properly
+  DALI_TEST_CHECK(callStack.FindIndexFromMethodAndParams("Viewport", viewportParams1) >= 0);
+  DALI_TEST_CHECK(callStack.FindIndexFromMethodAndParams("Viewport", viewportParams2) >= 0);
+
+  END_TEST;
 }
\ No newline at end of file
index 092a3af..37e3854 100644 (file)
@@ -1016,7 +1016,7 @@ int UtcDaliSceneSurfaceResizedDefaultSceneViewport(void)
   DALI_TEST_EQUALS(surfaceResized, true, TEST_LOCATION);
 
   // Check that the viewport is handled properly
-  DALI_TEST_CHECK(callStack.FindMethodAndGetParameters("Viewport", viewportParams));
+  DALI_TEST_CHECK(callStack.FindIndexFromMethodAndParams("Viewport", viewportParams) >= 0);
 
   // Check current surface rect
   newSurfaceRect = defaultScene.GetCurrentSurfaceRect();
diff --git a/dali/devel-api/actors/camera-actor-devel.cpp b/dali/devel-api/actors/camera-actor-devel.cpp
new file mode 100644 (file)
index 0000000..ed942e6
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2020 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/devel-api/actors/camera-actor-devel.h>
+#include <dali/internal/event/actors/camera-actor-impl.h>
+
+namespace Dali
+{
+namespace DevelCameraActor
+{
+
+void RotateProjection(Dali::CameraActor camera, int32_t rotationAngle)
+{
+  Dali::GetImplementation(camera).RotateProjection(rotationAngle);
+}
+
+} // namespace DevelCustomActor
+
+} // namespace Dali
index eedf33a..b42653c 100644 (file)
@@ -37,6 +37,14 @@ enum
 };
 
 } // Namespace Property
+
+/**
+ * @brief Request to rotate window after MVP matrix is multiplied.
+ * It is used in case that the target buffer orientation is different from the window orientation.
+ * @param [in] camera Dali::CameraActor that will be rotated.
+ * @param [in] rotationAngle The rotation angle (0, 90, 180, and 270. See Dali::WindowOrientation.)
+ */
+DALI_CORE_API void RotateProjection(Dali::CameraActor camera, int32_t rotationAngle);
 } // namespace DevelCameraActor
 } // Namespace Dali
 
index 7f48c24..ab12aaf 100644 (file)
@@ -4,6 +4,7 @@ SET( devel_api_src_dir ${ROOT_SRC_DIR}/dali/devel-api )
 # Add devel source files here for DALi internal developer files used by Adaptor & Toolkit
 SET( devel_api_src_files
   ${devel_api_src_dir}/actors/actor-devel.cpp
+  ${devel_api_src_dir}/actors/camera-actor-devel.cpp
   ${devel_api_src_dir}/actors/custom-actor-devel.cpp
   ${devel_api_src_dir}/animation/animation-data.cpp
   ${devel_api_src_dir}/animation/animation-devel.cpp
index 2cfd8a9..0a301cb 100644 (file)
@@ -143,15 +143,30 @@ struct GraphicsStencilOp
   Graphics::StencilOp op{Graphics::StencilOp::KEEP};
 };
 
-inline Graphics::Viewport ViewportFromClippingBox(ClippingBox clippingBox, int orientation)
+inline Graphics::Viewport ViewportFromClippingBox(const Uint16Pair& sceneSize, ClippingBox clippingBox, int orientation)
 {
   Graphics::Viewport viewport{static_cast<float>(clippingBox.x), static_cast<float>(clippingBox.y), static_cast<float>(clippingBox.width), static_cast<float>(clippingBox.height), 0.0f, 0.0f};
 
   if(orientation == 90 || orientation == 270)
   {
+    if(orientation == 90)
+    {
+      viewport.x = sceneSize.GetY() - (clippingBox.y + clippingBox.height);
+      viewport.y = clippingBox.x;
+    }
+    else // orientation == 270
+    {
+      viewport.x = clippingBox.y;
+      viewport.y = sceneSize.GetX() - (clippingBox.x + clippingBox.width);
+    }
     viewport.width  = static_cast<float>(clippingBox.height);
     viewport.height = static_cast<float>(clippingBox.width);
   }
+  else if(orientation == 180)
+  {
+    viewport.x = sceneSize.GetX() - (clippingBox.x + clippingBox.width);
+    viewport.y = sceneSize.GetY() - (clippingBox.y + clippingBox.height);
+  }
   return viewport;
 }
 
@@ -459,7 +474,7 @@ inline void RenderAlgorithms::SetupScissorClipping(
         useScissorBox.y = (instruction.mFrameBuffer->GetHeight() - useScissorBox.height) - useScissorBox.y;
       }
 
-      Graphics::Viewport graphicsViewport = ViewportFromClippingBox(mViewportRectangle, 0);
+      Graphics::Viewport graphicsViewport = ViewportFromClippingBox(Uint16Pair{0, 0}, mViewportRectangle, 0);
       commandBuffer.SetScissor(Rect2DFromClippingBox(useScissorBox, orientation, graphicsViewport));
     }
   }
@@ -574,7 +589,8 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
                                                 const RenderInstruction&            instruction,
                                                 const Rect<int32_t>&                viewport,
                                                 const Rect<int>&                    rootClippingRect,
-                                                int                                 orientation)
+                                                int                                 orientation,
+                                                const Uint16Pair&                   sceneSize)
 {
   DALI_PRINT_RENDER_LIST(renderList);
 
@@ -594,8 +610,7 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
   auto* mutableRenderList      = const_cast<RenderList*>(&renderList);
   auto& secondaryCommandBuffer = mutableRenderList->GetCommandBuffer(mGraphicsController);
   secondaryCommandBuffer.Reset();
-
-  secondaryCommandBuffer.SetViewport(ViewportFromClippingBox(mViewportRectangle, orientation));
+  secondaryCommandBuffer.SetViewport(ViewportFromClippingBox(sceneSize, mViewportRectangle, orientation));
   mHasLayerScissor = false;
 
   // Setup Scissor testing (for both viewport and per-node scissor)
@@ -605,7 +620,7 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
   // on the bottom of the stack
   if(!rootClippingRect.IsEmpty())
   {
-    Graphics::Viewport graphicsViewport = ViewportFromClippingBox(mViewportRectangle, 0);
+    Graphics::Viewport graphicsViewport = ViewportFromClippingBox(sceneSize, mViewportRectangle, 0);
     secondaryCommandBuffer.SetScissorTestEnable(true);
     secondaryCommandBuffer.SetScissor(Rect2DFromRect(rootClippingRect, orientation, graphicsViewport));
     mScissorStack.push_back(rootClippingRect);
@@ -619,7 +634,7 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
 
   if(renderList.IsClipping())
   {
-    Graphics::Viewport graphicsViewport = ViewportFromClippingBox(mViewportRectangle, 0);
+    Graphics::Viewport graphicsViewport = ViewportFromClippingBox(sceneSize, mViewportRectangle, 0);
     secondaryCommandBuffer.SetScissorTestEnable(true);
     const ClippingBox& layerScissorBox = renderList.GetClippingBox();
     secondaryCommandBuffer.SetScissor(Rect2DFromClippingBox(layerScissorBox, orientation, graphicsViewport));
@@ -723,7 +738,8 @@ void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction&
                                                 Vector<Graphics::Texture*>&         boundTextures,
                                                 const Rect<int32_t>&                viewport,
                                                 const Rect<int>&                    rootClippingRect,
-                                                int                                 orientation)
+                                                int                                 orientation,
+                                                const Uint16Pair&                   sceneSize)
 {
   DALI_PRINT_RENDER_INSTRUCTION(instruction, bufferIndex);
 
@@ -756,7 +772,8 @@ void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction&
                           instruction, //added for reflection effect
                           viewport,
                           rootClippingRect,
-                          orientation);
+                          orientation,
+                          sceneSize);
 
         // Execute command buffer
         auto* commandBuffer = renderList->GetCommandBuffer();
index 84d5807..4639811 100644 (file)
@@ -61,6 +61,7 @@ public:
    * @param[in] viewport               The viewport for drawing
    * @param[in] rootClippingRect       The clipping rectangle
    * @param[in] orientation            The Scene's surface orientation.
+   * @param[in] sceneSize              The Scene's surface size.
    */
   void ProcessRenderInstruction(const SceneGraph::RenderInstruction& instruction,
                                 BufferIndex                          bufferIndex,
@@ -69,7 +70,8 @@ public:
                                 Vector<Graphics::Texture*>&          boundTextures,
                                 const Rect<int32_t>&                 viewport,
                                 const Rect<int>&                     rootClippingRect,
-                                int                                  orientation);
+                                int                                  orientation,
+                                const Uint16Pair&                    sceneSize);
 
   /**
    * Resets main command buffer (per scene)
@@ -155,6 +157,7 @@ private:
    * @param[in] viewport               The Viewport
    * @param[in] rootClippingRect       The root clipping rectangle
    * @param[in] orientation            The Scene's surface orientation
+   * @param[in] sceneSize              The Scene's surface size.
    */
   inline void ProcessRenderList(const Dali::Internal::SceneGraph::RenderList&        renderList,
                                 BufferIndex                                          bufferIndex,
@@ -166,7 +169,8 @@ private:
                                 const Dali::Internal::SceneGraph::RenderInstruction& instruction, // in the case of reflection, things like CullFace need to be adjusted for reflection world
                                 const Rect<int32_t>&                                 viewport,
                                 const Rect<int>&                                     rootClippingRect,
-                                int                                                  orientation);
+                                int                                                  orientation,
+                                const Uint16Pair&                                    sceneSize);
 
   // Member variables:
 
index 6f28e02..3c6af61 100644 (file)
@@ -908,7 +908,7 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
     // Scissor's value should be set based on the default system coordinates.
     // When the surface is rotated, the input values already were set with the rotated angle.
     // So, re-calculation is needed.
-    scissorArea = RecalculateScissorArea(scissorArea, surfaceOrientation, viewportRect);
+    scissorArea = RecalculateScissorArea(scissorArea, surfaceOrientation, surfaceRect);
 
     // Begin render pass
     mainCommandBuffer->BeginRenderPass(
@@ -933,7 +933,8 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
       mImpl->boundTextures,
       viewportRect,
       clippingRect,
-      surfaceOrientation);
+      surfaceOrientation,
+      Uint16Pair(surfaceRect.width, surfaceRect.height));
 
     Graphics::SyncObject* syncObject{nullptr};
     // If the render instruction has an associated render tracker (owned separately)