[Tizen](Partial Update) Mark as not rendered if the node is transparent or culled 99/268699/1
authorHeeyong Song <heeyong.song@samsung.com>
Tue, 30 Nov 2021 09:15:40 +0000 (18:15 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Thu, 30 Dec 2021 05:03:59 +0000 (14:03 +0900)
Change-Id: Ie53434476c12840d97e030b386a43b903a6a69f7

automated-tests/src/dali/utc-Dali-Actor.cpp
dali/internal/render/data-providers/node-data-provider.h
dali/internal/update/manager/render-instruction-processor.cpp

index b9f8dba..35a756c 100644 (file)
@@ -9156,6 +9156,128 @@ int utcDaliActorPartialUpdateNotRenderableActor(void)
   END_TEST;
 }
 
+int utcDaliActorPartialUpdateChangeTransparency(void)
+{
+  TestApplication application(
+    TestApplication::DEFAULT_SURFACE_WIDTH,
+    TestApplication::DEFAULT_SURFACE_HEIGHT,
+    TestApplication::DEFAULT_HORIZONTAL_DPI,
+    TestApplication::DEFAULT_VERTICAL_DPI,
+    true,
+    true);
+
+  tet_infoline("Check the damaged rect with changing transparency");
+
+  const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+  Actor actor                          = CreateRenderableActor();
+  actor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT;
+  actor[Actor::Property::POSITION]     = Vector3(16.0f, 16.0f, 0.0f);
+  actor[Actor::Property::SIZE]         = Vector3(16.0f, 16.0f, 0.0f);
+  actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+
+  std::vector<Rect<int>> damagedRects;
+
+  // Actor added, damaged rect is added size of actor
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+  // Aligned by 16
+  Rect<int> clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates, includes 3 last frames updates
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+  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);
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // Make the actor transparent by changing opacity of the Renderer
+  // It changes a uniform value
+  Renderer renderer                          = actor.GetRendererAt(0);
+  renderer[DevelRenderer::Property::OPACITY] = 0.0f;
+
+  application.SendNotification();
+
+  // The damaged rect should be same
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+  DALI_TEST_CHECK(damagedRects.size() > 0);
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // Ensure the damaged rect is empty
+  DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+  // Make the actor opaque again
+  renderer[DevelRenderer::Property::OPACITY] = 1.0f;
+
+  application.SendNotification();
+
+  // The damaged rect should not be empty
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // Make the actor culled
+  actor[Actor::Property::SIZE] = Vector3(0.0f, 0.0f, 0.0f);
+
+  application.SendNotification();
+
+  // The damaged rect should be same
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+  DALI_TEST_CHECK(damagedRects.size() > 0);
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // Ensure the damaged rect is empty
+  DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+  // Make the actor not culled again
+  actor[Actor::Property::SIZE] = Vector3(16.0f, 16.0f, 16.0f);
+
+  application.SendNotification();
+
+  // The damaged rect should not be empty
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliActorCaptureAllTouchAfterStartPropertyP(void)
 {
   TestApplication application;
index f2f8c0a..c0a143f 100644 (file)
@@ -72,7 +72,7 @@ struct PartialRenderingNodeData
    */
   bool IsUpdated()
   {
-    return 0 != memcmp(&mData[0], &mData[1], sizeof(PartialRenderingCacheInfo));
+    return (0 != memcmp(&mData[0], &mData[1], sizeof(PartialRenderingCacheInfo)) || !mRendered);
   }
 
   /**
@@ -86,6 +86,7 @@ struct PartialRenderingNodeData
   PartialRenderingCacheInfo mData[2u];         /// Double-buffered data
   uint8_t                   mCurrentIndex{0u}; /// Current buffer index
   bool                      mVisible{true};    /// Visible state
+  bool                      mRendered{false};  /// Rendering state
 };
 
 /**
index 9f9bdd3..a395436 100644 (file)
@@ -290,19 +290,26 @@ inline void AddRendererToRenderList(BufferIndex         updateBufferIndex,
       partialRenderingCacheInfo.updatedSize = item.mUpdateSize;
 
       item.mIsUpdated = partialRenderingData.IsUpdated() || item.mIsUpdated;
+
+      partialRenderingData.mRendered = true;
+
       partialRenderingData.SwapBuffers();
     }
     else
     {
-      // Mark as invisible
-      auto& partialRenderingData    = node->GetPartialRenderingData();
-      partialRenderingData.mVisible = false;
+      // Mark as not rendered
+      auto& partialRenderingData     = node->GetPartialRenderingData();
+      partialRenderingData.mRendered = false;
     }
 
     node->SetCulled(updateBufferIndex, false);
   }
   else
   {
+    // Mark as not rendered
+    auto& partialRenderingData     = node->GetPartialRenderingData();
+    partialRenderingData.mRendered = false;
+
     node->SetCulled(updateBufferIndex, true);
   }
 }