Supports to acknowledge for completing window rotation 71/262971/13
authorWonsik Jung <sidein@samsung.com>
Tue, 24 Aug 2021 06:16:28 +0000 (15:16 +0900)
committerWonsik Jung <sidein@samsung.com>
Tue, 19 Oct 2021 05:41:45 +0000 (14:41 +0900)
It is waited the window rotation completing until a view finishes to draw.
The view is drawn on the other thread.
It means asychronous rendering occurs between dali render thread and the other thread when window is rotated.

Change-Id: Ia9ac33e3719a874c35c58acf91e92b96ac802c7f

automated-tests/src/dali/utc-Dali-Scene.cpp
dali/integration-api/scene.cpp
dali/integration-api/scene.h
dali/internal/event/common/scene-impl.cpp
dali/internal/event/common/scene-impl.h
dali/internal/update/common/scene-graph-scene.cpp
dali/internal/update/common/scene-graph-scene.h

index dcaa704..fc19ea7 100644 (file)
@@ -1368,6 +1368,84 @@ int UtcDaliSceneSurfaceRotatedWithAngle270(void)
   END_TEST;
 }
 
+int UtcDaliSceneSetRotationCompletedAcknowledgementWithAngle90(void)
+{
+  tet_infoline("Ensure to acknowledge for completing surface 90 angle rotaiton");
+
+  TestApplication application(
+    TestApplication::DEFAULT_SURFACE_WIDTH,
+    TestApplication::DEFAULT_SURFACE_HEIGHT,
+    TestApplication::DEFAULT_HORIZONTAL_DPI,
+    TestApplication::DEFAULT_VERTICAL_DPI,
+    true,
+    true);
+
+  const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+  std::vector<Rect<int>> damagedRects;
+  Rect<int>              clippingRect;
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+  DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  Actor actor = CreateRenderableActor();
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  actor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
+  actor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+  actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+
+  damagedRects.clear();
+  application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
+                                        TestApplication::DEFAULT_SURFACE_HEIGHT,
+                                        90);
+
+  // Check current surface orientation
+  int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
+
+  // It should not be changed yet.
+  DALI_TEST_EQUALS(orientation, 0, TEST_LOCATION);
+
+  application.GetScene().SetRotationCompletedAcknowledgement();
+
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+  clippingRect = Rect<int>(CLIPPING_RECT_X, CLIPPING_RECT_Y, CLIPPING_RECT_WIDTH, CLIPPING_RECT_HEIGHT); // in screen coordinates, includes 3 last frames updates
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // It is recalculation for glScissor.
+  // Because surface is rotated and glScissor is called with recalcurated value.
+  clippingRect.x      = TestApplication::DEFAULT_SURFACE_HEIGHT - (CLIPPING_RECT_Y + CLIPPING_RECT_HEIGHT);
+  clippingRect.y      = CLIPPING_RECT_X;
+  clippingRect.width  = CLIPPING_RECT_HEIGHT;
+  clippingRect.height = CLIPPING_RECT_WIDTH;
+
+  DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+  // Check current surface orientation
+  orientation = application.GetScene().GetCurrentSurfaceOrientation();
+
+  // It should be changed.
+  DALI_TEST_EQUALS(orientation, 90, TEST_LOCATION);
+
+  bool isSetRotationCompletedAcknowledgementSet = application.GetScene().IsRotationCompletedAcknowledgementSet();
+  DALI_TEST_EQUALS(isSetRotationCompletedAcknowledgementSet, true, TEST_LOCATION);
+
+  END_TEST;
+}
+
+
+
 int UtcDaliSceneKeyEventGeneratedSignalP(void)
 {
   TestApplication          application;
index b835576..8fb7a7c 100644 (file)
@@ -184,6 +184,16 @@ bool Scene::IsSurfaceRectChanged() const
   return GetImplementation(*this).IsSurfaceRectChanged();
 }
 
+void Scene::SetRotationCompletedAcknowledgement()
+{
+  GetImplementation(*this).SetRotationCompletedAcknowledgement();
+}
+
+bool Scene::IsRotationCompletedAcknowledgementSet() const
+{
+  return GetImplementation(*this).IsRotationCompletedAcknowledgementSet();
+}
+
 Scene::EventProcessingFinishedSignalType& Scene::EventProcessingFinishedSignal()
 {
   return GetImplementation(*this).EventProcessingFinishedSignal();
index dc1db99..d137773 100644 (file)
@@ -326,6 +326,30 @@ public:
   bool IsSurfaceRectChanged() const;
 
   /**
+   * @brief Send message to acknowledge for completing window rotation with current window orientation.
+   *
+   * If this function is called, the message is sent to render thread, then mSurfaceRectChanged in scene-graph-scene is set with true.
+   * After that, render thread checks whether window rotation event is received, mSurfaceRectChanged and the neccessary flag are set.
+   * If they are all true, rotation done function is called to complete window rotation.
+   */
+  void SetRotationCompletedAcknowledgement();
+
+  /**
+   * @brief Query wheter is set to acknowledge for completing surface rotation.
+   * @return true it should be acknowledged.
+   *
+   * If SetRotationCompletedAcknowledgement() is called and the related message is received to scene-graph-scene,
+   * then mSurfaceRectChanged in scene-graph-scene is set with true.
+   *
+   * When this function is called, the mSurfaceRectChanged in scene-graph-scene is return.
+   * Then, the flag will be reset.
+   *
+   * @note This function should be not called the application's main thread.
+   * Because this function should be called in windwow surface's postrender() function to complete window rotation manually.
+   */
+  bool IsRotationCompletedAcknowledgementSet() const;
+
+  /**
    * @brief This signal is emitted just after the event processing is finished.
    *
    * @return The signal to connect to
index a32e414..6a251c9 100644 (file)
@@ -321,6 +321,17 @@ bool Scene::IsSurfaceRectChanged() const
   return mSceneObject->IsSurfaceRectChanged();
 }
 
+bool Scene::IsRotationCompletedAcknowledgementSet() const
+{
+  return mSceneObject->IsRotationCompletedAcknowledgementSet();
+}
+
+void Scene::SetRotationCompletedAcknowledgement()
+{
+  ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
+  SetRotationCompletedAcknowledgementMessage(tls->GetEventThreadServices(), *mSceneObject);
+}
+
 void Scene::SetSurfaceRenderTarget(Graphics::RenderTarget* renderTarget)
 {
   // Send the surface render target to SceneGraph::Scene
index 9574326..6686d9d 100644 (file)
@@ -245,6 +245,16 @@ public:
   void SurfaceRotated(float width, float height, int32_t orientation);
 
   /**
+   * @copydoc Dali::Integration::Scene::SetRotationCompletedAcknowledgement
+   */
+  void SetRotationCompletedAcknowledgement();
+
+  /**
+   * @copydoc Dali::Integration::Scene::IsRotationCompletedAcknowledgementSet
+   */
+  bool IsRotationCompletedAcknowledgementSet() const;
+
+  /**
    * @copydoc Dali::Integration::Scene::GetCurrentSurfaceOrientation
    */
   int32_t GetCurrentSurfaceOrientation() const;
index 224bddb..55e94c7 100644 (file)
@@ -33,7 +33,8 @@ Scene::Scene()
   mSkipRendering(false),
   mSurfaceRect(),
   mSurfaceOrientation(0),
-  mSurfaceRectChanged(false)
+  mSurfaceRectChanged(false),
+  mRotationCompletedAcknowledgement(false)
 {
 }
 
@@ -169,6 +170,18 @@ bool Scene::IsSurfaceRectChanged()
   return surfaceRectChanged;
 }
 
+void Scene::SetRotationCompletedAcknowledgement()
+{
+  mRotationCompletedAcknowledgement = true;
+}
+
+bool Scene::IsRotationCompletedAcknowledgementSet()
+{
+  bool setRotationCompletedAcknowledgement = mRotationCompletedAcknowledgement;
+  mRotationCompletedAcknowledgement     = false;
+  return setRotationCompletedAcknowledgement;
+}
+
 } // namespace SceneGraph
 
 } // namespace Internal
index 0aaf50e..14bcb08 100644 (file)
@@ -138,7 +138,6 @@ public:
   /**
    * Set the surface orientation when surface is rotated.
    *
-   * @param[in] scene The rotated scene.
    * @param[in] orientation The orientation value representing the surface.
    */
   void SetSurfaceOrientation(int32_t orientation);
@@ -157,6 +156,17 @@ public:
   bool IsSurfaceRectChanged();
 
   /**
+   * @brief Set the internal flag to acknowledge surface rotation.
+   */
+  void SetRotationCompletedAcknowledgement();
+
+  /**
+   * @brief Query wheter is set to acknowledge for completing surface rotation.
+   * @return true it should be acknowledged.
+   */
+  bool IsRotationCompletedAcknowledgementSet();
+
+  /**
    * Set the render target of the surface
    *
    * @param[in] renderTarget The render target.
@@ -217,6 +227,7 @@ private:
   Rect<int32_t> mSurfaceRect;        ///< The rectangle of surface which is related ot this scene.
   int32_t       mSurfaceOrientation; ///< The orientation of surface which is related of this scene
   bool          mSurfaceRectChanged; ///< The flag of surface's rectangle is changed when is resized, moved or rotated.
+  bool          mRotationCompletedAcknowledgement; ///< The flag of sending the acknowledgement to complete window rotation.
 
   // Render pass and render target
 
@@ -278,6 +289,17 @@ inline void SetSurfaceOrientationMessage(EventThreadServices& eventThreadService
   new(slot) LocalType(&scene, &Scene::SetSurfaceOrientation, orientation);
 }
 
+inline void SetRotationCompletedAcknowledgementMessage(EventThreadServices& eventThreadServices, const Scene& scene)
+{
+  using LocalType = Message<Scene>;
+
+  // Reserve some memory inside the message queue
+  uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new(slot) LocalType(&scene, &Scene::SetRotationCompletedAcknowledgement);
+}
+
 inline void SetSurfaceRenderTargetMessage(EventThreadServices& eventThreadServices, const Scene& scene, Graphics::RenderTarget* renderTarget)
 {
   using LocalType = MessageValue1<Scene, Graphics::RenderTarget*>;