ClearScene if previous frame presented + Present if dirty rect not empty 95/321995/7
authorEunki, Hong <eunkiki.hong@samsung.com>
Wed, 2 Apr 2025 02:14:07 +0000 (11:14 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Tue, 8 Apr 2025 04:58:19 +0000 (13:58 +0900)
Their was some error if rendererAdded, but render instruction is empty.

If then, we don't swap the presented buffer. So latest rendered scene
don't cleared.

To fix this issue, let we acquire next frame if previous scene had some render
instructions to scene, but not now.

Also (for gles case) if we call eglSetDamageRegionKHR, we should call eglSwapBuffer.
If not, 0x3002 error occured.

Change-Id: Icf55be6fe92ab98def0e631b0205939c16a8f4e6
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-application.cpp
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-application.h
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-egl-application.cpp
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-egl-application.h
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-vk-application.cpp
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-vk-application.h
dali/internal/adaptor/common/combined-update-render-controller.cpp

index e5a943a51a052f1419b17f2124b86db19ac38150..e8745370db7ef2b460b2293b23d700e67c40b286 100644 (file)
@@ -220,6 +220,9 @@ bool TestApplication::Render(uint32_t intervalMilliseconds, const char* location
   {
     for(auto&& scene : mScenes)
     {
+      std::vector<Rect<int>> damagedRects;
+
+      mCore->PreRenderScene(scene, mScenePreRenderStatus, damagedRects);
       mCore->RenderScene(mRenderStatus, scene, true /*render the off-screen buffers*/);
       mCore->RenderScene(mRenderStatus, scene, false /*render the surface*/);
     }
@@ -236,7 +239,7 @@ bool TestApplication::PreRenderWithPartialUpdate(uint32_t intervalMilliseconds,
   DoUpdate(intervalMilliseconds, location);
 
   mCore->PreRender(mRenderStatus, false /*do not force clear*/);
-  mCore->PreRender(mScene, damagedRects);
+  mCore->PreRenderScene(mScene, mScenePreRenderStatus, damagedRects);
 
   return mStatus.KeepUpdating() || mRenderStatus.NeedsUpdate();
 }
@@ -267,7 +270,7 @@ bool TestApplication::RenderWithPartialUpdate(uint32_t intervalMilliseconds, con
     std::vector<Rect<int>> damagedRects;
     Rect<int>              clippingRect{};
 
-    mCore->PreRender(scene, damagedRects);
+    mCore->PreRenderScene(scene, mScenePreRenderStatus, damagedRects);
     mCore->RenderScene(mRenderStatus, scene, true /*render the off-screen buffers*/);
     for(auto&& iter : damagedRects)
     {
@@ -305,8 +308,11 @@ bool TestApplication::GetRenderNeedsPostRender()
 
 bool TestApplication::RenderOnly()
 {
+  std::vector<Rect<int>> damagedRects;
+
   // Update Time values
   mCore->PreRender(mRenderStatus, false /*do not force clear*/);
+  mCore->PreRenderScene(mScene, mScenePreRenderStatus, damagedRects);
   mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/);
   mCore->RenderScene(mRenderStatus, mScene, false /*render the surface*/);
   mCore->PostRender();
index 6876dc8c28c9d4bc159c6ca09ef21f1faa5588e1..57713b119193f483131a5456115b89cf94944a8b 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TEST_APPLICATION_H
 
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/resource-policies.h>
+#include <dali/integration-api/scene-pre-render-status.h>
 #include <dali/integration-api/scene.h>
 #include <dali/integration-api/trace.h>
 
@@ -105,8 +106,9 @@ protected:
   TestGraphicsController  mGraphicsController;
   TestRenderSurface*      mRenderSurface;
 
-  Integration::UpdateStatus mStatus;
-  Integration::RenderStatus mRenderStatus;
+  Integration::UpdateStatus         mStatus;
+  Integration::RenderStatus         mRenderStatus;
+  Integration::ScenePreRenderStatus mScenePreRenderStatus;
 
   Integration::Core*              mCore;
   Dali::Integration::Scene        mScene;
index 9abc90241410ac67b89426163100a914c6adab6e..769d9fc7e65dc13ccf6fbe8222208631a3cd5690 100644 (file)
@@ -212,7 +212,10 @@ bool TestGraphicsApplication::Render(uint32_t intervalMilliseconds, const char*
   mRenderStatus.SetNeedsUpdate(false);
   mRenderStatus.SetNeedsPostRender(false);
 
+  std::vector<Rect<int>> damagedRects;
+
   mCore->PreRender(mRenderStatus, false /*do not force clear*/);
+  mCore->PreRenderScene(mScene, mScenePreRenderStatus, damagedRects);
   mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/);
   mCore->RenderScene(mRenderStatus, mScene, false /*render the surface*/);
   mCore->PostRender();
@@ -227,7 +230,7 @@ bool TestGraphicsApplication::PreRenderWithPartialUpdate(uint32_t intervalMillis
   DoUpdate(intervalMilliseconds, location);
 
   mCore->PreRender(mRenderStatus, false /*do not force clear*/);
-  mCore->PreRender(mScene, damagedRects);
+  mCore->PreRenderScene(mScene, mScenePreRenderStatus, damagedRects);
 
   return mStatus.KeepUpdating() || mRenderStatus.NeedsUpdate();
 }
@@ -266,8 +269,11 @@ bool TestGraphicsApplication::GetRenderNeedsPostRender()
 
 bool TestGraphicsApplication::RenderOnly()
 {
+  std::vector<Rect<int>> damagedRects;
+
   // Update Time values
   mCore->PreRender(mRenderStatus, false /*do not force clear*/);
+  mCore->PreRenderScene(mScene, mScenePreRenderStatus, damagedRects);
   mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/);
   mCore->RenderScene(mRenderStatus, mScene, false /*render the surface*/);
   mCore->PostRender();
index 14bb24d62aa958a0e98fdbd333b80e467139d2da..1c92f72d89fa644c00ee9399e688e852d13c5b86 100644 (file)
@@ -20,6 +20,7 @@
 // INTERNAL INCLUDES
 #include <dali/integration-api/core.h>
 #include <dali/integration-api/resource-policies.h>
+#include <dali/integration-api/scene-pre-render-status.h>
 #include <dali/integration-api/scene.h>
 #include <dali/integration-api/trace.h>
 
@@ -386,8 +387,9 @@ protected:
   Graphics::UniquePtr<Graphics::RenderTarget> mRenderTarget{nullptr};
   Dali::DisplayConnection*                    mDisplayConnection{nullptr};
 
-  Integration::UpdateStatus mStatus;
-  Integration::RenderStatus mRenderStatus;
+  Integration::UpdateStatus         mStatus;
+  Integration::RenderStatus         mRenderStatus;
+  Integration::ScenePreRenderStatus mScenePreRenderStatus;
 
   Integration::Core*       mCore;
   Dali::Integration::Scene mScene;
index 1fe4b004366287c698fbfbc440b710c2953af8c7..26cb9ec69cc1e4048a0a0443eec966303ac34414 100644 (file)
@@ -216,7 +216,10 @@ bool TestGraphicsApplication::Render(uint32_t intervalMilliseconds, const char*
   mRenderStatus.SetNeedsUpdate(false);
   mRenderStatus.SetNeedsPostRender(false);
 
+  std::vector<Rect<int>> damagedRects;
+
   mCore->PreRender(mRenderStatus, false /*do not force clear*/);
+  mCore->PreRenderScene(mScene, mScenePreRenderStatus, damagedRects);
   mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/);
   mCore->RenderScene(mRenderStatus, mScene, false /*render the surface*/);
   mCore->PostRender();
@@ -231,7 +234,7 @@ bool TestGraphicsApplication::PreRenderWithPartialUpdate(uint32_t intervalMillis
   DoUpdate(intervalMilliseconds, location);
 
   mCore->PreRender(mRenderStatus, false /*do not force clear*/);
-  mCore->PreRender(mScene, damagedRects);
+  mCore->PreRenderScene(mScene, mScenePreRenderStatus, damagedRects);
 
   return mStatus.KeepUpdating() || mRenderStatus.NeedsUpdate();
 }
@@ -270,8 +273,11 @@ bool TestGraphicsApplication::GetRenderNeedsPostRender()
 
 bool TestGraphicsApplication::RenderOnly()
 {
+  std::vector<Rect<int>> damagedRects;
+
   // Update Time values
   mCore->PreRender(mRenderStatus, false /*do not force clear*/);
+  mCore->PreRenderScene(mScene, mScenePreRenderStatus, damagedRects);
   mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/);
   mCore->RenderScene(mRenderStatus, mScene, false /*render the surface*/);
   mCore->PostRender();
index f7d51038c0a780ff470c7eba3c62a72cfac60bd0..3fe016800ff21696d570d7689f831aba46d079d5 100644 (file)
@@ -20,6 +20,7 @@
 // INTERNAL INCLUDES
 #include <dali/integration-api/core.h>
 #include <dali/integration-api/resource-policies.h>
+#include <dali/integration-api/scene-pre-render-status.h>
 #include <dali/integration-api/scene.h>
 #include <dali/integration-api/trace.h>
 
@@ -107,8 +108,9 @@ protected:
   Graphics::VulkanGraphics mGraphics; // Use real vulkan graphics
   Dali::DisplayConnection* mDisplayConnection{nullptr};
 
-  Integration::UpdateStatus mStatus;
-  Integration::RenderStatus mRenderStatus;
+  Integration::UpdateStatus         mStatus;
+  Integration::RenderStatus         mRenderStatus;
+  Integration::ScenePreRenderStatus mScenePreRenderStatus;
 
   Integration::Core*       mCore;
   Dali::Integration::Scene mScene;
index 6befc13f84dd81a60f9d38d0dc72427424282a27..49857c60cf37eb63aeae1e84dd2930d7b3bdced8 100644 (file)
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/integration-api/platform-abstraction.h>
+#include <dali/integration-api/scene-pre-render-status.h>
 #include <dali/integration-api/shader-integ.h>
 #include <dali/public-api/common/dali-common.h>
 #include <errno.h>
@@ -854,7 +855,8 @@ void CombinedUpdateRenderController::UpdateRenderThread()
         if(scene && windowSurface)
         {
           TRACE_UPDATE_RENDER_SCOPE("DALI_RENDER_SCENE");
-          Integration::RenderStatus windowRenderStatus;
+          Integration::RenderStatus         windowRenderStatus;
+          Integration::ScenePreRenderStatus scenePreRenderStatus;
 
           const uint32_t sceneSurfaceResized = scene.GetSurfaceRectChangedCount();
 
@@ -862,25 +864,41 @@ void CombinedUpdateRenderController::UpdateRenderThread()
           mDamagedRects.clear();
 
           // Collect damage rects
-          bool willRender = mCore.PreRender(scene, mDamagedRects); // willRender is set if there are any render instructions with renderables
-          bool fullSwap   = windowSurface->GetFullSwapNextFrame(); // true on Resize|set bg color
+          mCore.PreRenderScene(scene, scenePreRenderStatus, mDamagedRects);
+
+          const bool willRenderToScene  = scenePreRenderStatus.HasRenderInstructionToScene(); // willRenderToScene is set if there are any render instructions with renderables.
+          const bool hadRenderedToScene = scenePreRenderStatus.HadRenderInstructionToScene(); // and hadRenderedToScene is set if previous frame was.
+
+          // Need to present if previous frame had rendered to scene.
+          bool presentRequired = hadRenderedToScene || willRenderToScene;
 
           Rect<int> clippingRect; // Empty for fbo rendering
 
           // Ensure surface can be drawn to; merge damaged areas for previous frames
           windowSurface->PreRender(sceneSurfaceResized > 0u, mDamagedRects, clippingRect);
-          if(mEnvironmentOptions.PartialUpdateRequired() && clippingRect.IsEmpty())
+
+          if(graphics.GetPartialUpdateRequired() == Integration::PartialUpdateAvailable::TRUE && clippingRect.IsEmpty())
           {
             DALI_LOG_INFO(gLogFilter, Debug::General, "PartialUpdate and no clip\n");
             DALI_LOG_DEBUG_INFO("ClippingRect was empty. Skip rendering\n");
-            willRender = false;
+            presentRequired = false;
           }
 
-          LOG_RENDER_SCENE("RenderThread: core.PreRender():%s  fullSwap:%s\n",
-                           willRender ? "T" : "F",
+          const bool fullSwap = windowSurface->GetFullSwapNextFrame(); // true on Resize|set bg color
+
+          LOG_RENDER_SCENE("RenderThread: HadRender:%s WillRender:%s presentRequired:%s fullSwap:%s\n",
+                           hadRenderedToScene ? "T" : "F",
+                           willRenderToScene ? "T" : "F",
+                           presentRequired ? "T" : "F",
                            fullSwap ? "T" : "F");
 
-          if(willRender || fullSwap)
+          // Forcibly present to surface if fullSwap enabled.
+          if(fullSwap)
+          {
+            presentRequired |= fullSwap;
+          }
+
+          if(presentRequired)
           {
             graphics.AcquireNextImage(windowSurface);
           }
@@ -889,7 +907,7 @@ void CombinedUpdateRenderController::UpdateRenderThread()
           mCore.RenderScene(windowRenderStatus, scene, true);
 
           bool didRender = false;
-          if(willRender)
+          if(presentRequired)
           {
             LOG_RENDER_SCENE("RenderThread: core.RenderScene() Render the surface\n");
 
@@ -898,13 +916,12 @@ void CombinedUpdateRenderController::UpdateRenderThread()
             didRender = graphics.DidPresent();
 
             LOG_RENDER_SCENE("RenderThread: Surface%s presented\n", didRender ? "" : " NOT");
-          }
 
-          // If we weren't going to draw, but need to clear; OR
-          // we were going to draw but didn't, we have acquired the image, and must present.
-          if((!willRender && fullSwap) || (willRender && !didRender))
-          {
-            mCore.ClearScene(scene);
+            // If we were going to draw but didn't, we have acquired the image, and must present.
+            if(!didRender)
+            {
+              mCore.ClearScene(scene);
+            }
           }
 
           // If surface is resized, the surface resized count is decreased.