Fix window/screen rotation issue. 09/259309/7
authorWonsik Jung <sidein@samsung.com>
Fri, 4 Jun 2021 06:39:56 +0000 (15:39 +0900)
committerRichard Huang <r.huang@samsung.com>
Thu, 17 Jun 2021 11:09:27 +0000 (12:09 +0100)
Fix window/screen rotation issue when scissor clipping is used.

Change-Id: I2a8e6dbfcc30e36551e6a8640499d98cf05b26c9

dali/internal/render/common/render-algorithms.cpp
dali/internal/render/common/render-algorithms.h
dali/internal/render/common/render-manager.cpp

index 9727826..5998670 100644 (file)
@@ -383,11 +383,13 @@ inline void SetupDepthBuffer(const RenderItem& item, Graphics::CommandBuffer& co
  * @param[in]     item                     The current RenderItem about to be rendered
  * @param[in,out] commandBuffer            The command buffer to write into
  * @param[in]     instruction              The render-instruction to process.
+ * @param[in]     orientation              The Scene's surface orientation.
  */
 inline void RenderAlgorithms::SetupScissorClipping(
   const RenderItem&        item,
   Graphics::CommandBuffer& commandBuffer,
-  const RenderInstruction& instruction)
+  const RenderInstruction& instruction,
+  int orientation)
 {
   // Get the number of child scissors in the stack (do not include layer or root box).
   size_t         childStackDepth = mScissorStack.size() - 1u;
@@ -456,8 +458,9 @@ inline void RenderAlgorithms::SetupScissorClipping(
       {
         useScissorBox.y = (instruction.mFrameBuffer->GetHeight() - useScissorBox.height) - useScissorBox.y;
       }
-      Graphics::Rect2D scissorBox = {useScissorBox.x, useScissorBox.y, uint32_t(useScissorBox.width), uint32_t(useScissorBox.height)};
-      commandBuffer.SetScissor(scissorBox);
+
+      Graphics::Viewport graphicsViewport = ViewportFromClippingBox(mViewportRectangle, 0);
+      commandBuffer.SetScissor(Rect2DFromClippingBox(useScissorBox, orientation, graphicsViewport));
     }
   }
 }
@@ -468,7 +471,8 @@ inline void RenderAlgorithms::SetupClipping(const RenderItem&
                                             uint32_t&                           lastClippingDepth,
                                             uint32_t&                           lastClippingId,
                                             Integration::StencilBufferAvailable stencilBufferAvailable,
-                                            const RenderInstruction&            instruction)
+                                            const RenderInstruction&            instruction,
+                                            int                                 orientation)
 {
   RenderMode::Type renderMode = RenderMode::AUTO;
   const Renderer*  renderer   = item.mRenderer;
@@ -490,7 +494,7 @@ inline void RenderAlgorithms::SetupClipping(const RenderItem&
       // As both scissor and stencil clips can be nested, we may be simultaneously traversing up the scissor tree, requiring a scissor to be un-done. Whilst simultaneously adding a new stencil clip.
       // We process both based on our current and old clipping depths for each mode.
       // Both methods with return rapidly if there is nothing to be done for that type of clipping.
-      SetupScissorClipping(item, commandBuffer, instruction);
+      SetupScissorClipping(item, commandBuffer, instruction, orientation);
 
       if(stencilBufferAvailable == Integration::StencilBufferAvailable::TRUE)
       {
@@ -637,7 +641,7 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
 
     // Set up clipping based on both the Renderer and Actor APIs.
     // The Renderer API will be used if specified. If AUTO, the Actors automatic clipping feature will be used.
-    SetupClipping(item, secondaryCommandBuffer, usedStencilBuffer, lastClippingDepth, lastClippingId, stencilBufferAvailable, instruction);
+    SetupClipping(item, secondaryCommandBuffer, usedStencilBuffer, lastClippingDepth, lastClippingId, stencilBufferAvailable, instruction, orientation);
 
     if(DALI_LIKELY(item.mRenderer))
     {
index 8cfcacc..84d5807 100644 (file)
@@ -60,7 +60,7 @@ public:
    * @param[in] boundTextures          The textures bound for rendering
    * @param[in] viewport               The viewport for drawing
    * @param[in] rootClippingRect       The clipping rectangle
-   * @param[in] orientation            The surface orientation
+   * @param[in] orientation            The Scene's surface orientation.
    */
   void ProcessRenderInstruction(const SceneGraph::RenderInstruction& instruction,
                                 BufferIndex                          bufferIndex,
@@ -115,11 +115,13 @@ private:
    * @param[in] commandBuffer The command buffer to write into
 
    * @param[in] instruction   The render-instruction to process.
+   * @param[in] orientation   The Scene's surface orientation.
    */
   inline void SetupScissorClipping(
     const Dali::Internal::SceneGraph::RenderItem&        item,
     Graphics::CommandBuffer&                             commandBuffer,
-    const Dali::Internal::SceneGraph::RenderInstruction& instruction);
+    const Dali::Internal::SceneGraph::RenderInstruction& instruction,
+    int orientation);
 
   /**
    * @brief Set up the clipping based on the specified clipping settings.
@@ -130,6 +132,7 @@ private:
    * @param[in/out] lastClippingId           The clipping ID of the last renderer drawn.   Used by the clipping feature.
    * @param[in]     stencilBufferAvailable   Whether the stencil buffer is available
    * @param[in]     instruction              The render-instruction to process.
+   * @param[in]     orientation              The Scene's surface orientation.
    */
   inline void SetupClipping(const Dali::Internal::SceneGraph::RenderItem&        item,
                             Graphics::CommandBuffer&                             commandBuffer,
@@ -137,7 +140,8 @@ private:
                             uint32_t&                                            lastClippingDepth,
                             uint32_t&                                            lastClippingId,
                             Integration::StencilBufferAvailable                  stencilBufferAvailable,
-                            const Dali::Internal::SceneGraph::RenderInstruction& instruction);
+                            const Dali::Internal::SceneGraph::RenderInstruction& instruction,
+                            int                                                  orientation);
 
   /**
    * @brief Process a render-list.
index 9263260..803f35a 100644 (file)
@@ -58,6 +58,43 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_REN
 } // unnamed namespace
 #endif
 
+namespace
+{
+inline Graphics::Rect2D RecalculateScissorArea(Graphics::Rect2D scissorArea, int orientation, Rect<int32_t> viewportRect)
+{
+  Graphics::Rect2D newScissorArea;
+
+  if(orientation == 90)
+  {
+    newScissorArea.x      = viewportRect.height - (scissorArea.y + scissorArea.height);
+    newScissorArea.y      = scissorArea.x;
+    newScissorArea.width  = scissorArea.height;
+    newScissorArea.height = scissorArea.width;
+  }
+  else if(orientation == 180)
+  {
+    newScissorArea.x      = viewportRect.width - (scissorArea.x + scissorArea.width);
+    newScissorArea.y      = viewportRect.height - (scissorArea.y + scissorArea.height);
+    newScissorArea.width  = scissorArea.width;
+    newScissorArea.height = scissorArea.height;
+  }
+  else if(orientation == 270)
+  {
+    newScissorArea.x      = scissorArea.y;
+    newScissorArea.y      = viewportRect.width - (scissorArea.x + scissorArea.width);
+    newScissorArea.width  = scissorArea.height;
+    newScissorArea.height = scissorArea.width;
+  }
+  else
+  {
+    newScissorArea.x      = scissorArea.x;
+    newScissorArea.y      = scissorArea.y;
+    newScissorArea.width  = scissorArea.width;
+    newScissorArea.height = scissorArea.height;
+  }
+  return newScissorArea;
+}
+} // namespace
 /**
  * Structure to contain internal data
  */
@@ -878,6 +915,11 @@ 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);
+
     // Begin render pass
     mainCommandBuffer->BeginRenderPass(
       currentRenderPass,