From 01caa840db38833e5e5ecab7f1c18b9fcf069ff2 Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Tue, 12 Oct 2021 23:41:28 +0900 Subject: [PATCH] Skip rendering if the damaged rect is empty Change-Id: I9424cf079d68a4afd00fda11a5e01d740be8155a --- .../dali-test-suite-utils/test-application.cpp | 4 +- .../dali/dali-test-suite-utils/test-application.h | 2 + automated-tests/src/dali/utc-Dali-Actor.cpp | 188 ++++++++++++++++++++- automated-tests/src/dali/utc-Dali-Scene.cpp | 8 + dali/internal/render/common/render-manager.cpp | 25 ++- 5 files changed, 221 insertions(+), 6 deletions(-) diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp index 5e69c95..440270a 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp @@ -19,6 +19,8 @@ namespace Dali { +const Rect TestApplication::DEFAULT_SURFACE_RECT = Rect(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT); + bool TestApplication::mLoggingEnabled = true; TestApplication::TestApplication(uint32_t surfaceWidth, @@ -225,7 +227,7 @@ bool TestApplication::PreRenderWithPartialUpdate(uint32_t intervalMilliseconds, bool TestApplication::RenderWithPartialUpdate(std::vector>& damagedRects, Rect& clippingRect) { - mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/, clippingRect); + mCore->RenderScene(mRenderStatus, mScene, true /*render the off-screen buffers*/); mCore->RenderScene(mRenderStatus, mScene, false /*render the surface*/, clippingRect); mCore->PostRender(false /*do not skip rendering*/); diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-application.h b/automated-tests/src/dali/dali-test-suite-utils/test-application.h index 4f32cd8..02143a7 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-application.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-application.h @@ -38,6 +38,8 @@ public: static const uint32_t DEFAULT_SURFACE_WIDTH = 480; static const uint32_t DEFAULT_SURFACE_HEIGHT = 800; + static const Rect DEFAULT_SURFACE_RECT; + static constexpr uint32_t DEFAULT_HORIZONTAL_DPI = 220; static constexpr uint32_t DEFAULT_VERTICAL_DPI = 217; diff --git a/automated-tests/src/dali/utc-Dali-Actor.cpp b/automated-tests/src/dali/utc-Dali-Actor.cpp index 8da28bc..66f2cbb 100644 --- a/automated-tests/src/dali/utc-Dali-Actor.cpp +++ b/automated-tests/src/dali/utc-Dali-Actor.cpp @@ -8086,6 +8086,8 @@ int utcDaliActorPartialUpdate(void) // First render pass, nothing to render, adaptor would just do swap buffer. DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION); + + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; application.RenderWithPartialUpdate(damagedRects, clippingRect); Actor actor = CreateRenderableActor(); @@ -8191,6 +8193,8 @@ int utcDaliActorPartialUpdateSetColor(void) // First render pass, nothing to render, adaptor would just do swap buffer. DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION); + + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; application.RenderWithPartialUpdate(damagedRects, clippingRect); Actor actor = CreateRenderableActor(); @@ -8286,6 +8290,8 @@ int utcDaliActorPartialUpdateSetProperty(void) // First render pass, nothing to render, adaptor would just do swap buffer. DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION); + + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; application.RenderWithPartialUpdate(damagedRects, clippingRect); Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 4u, 4u); @@ -8482,9 +8488,11 @@ int utcDaliActorPartialUpdateAnimation(void) DALI_TEST_EQUALS>(expectedRect1, damagedRects[0], TEST_LOCATION); DALI_TEST_EQUALS>(expectedRect2, damagedRects[1], TEST_LOCATION); + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; application.RenderWithPartialUpdate(damagedRects, clippingRect); damagedRects.clear(); + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); application.RenderWithPartialUpdate(damagedRects, clippingRect); @@ -8496,6 +8504,7 @@ int utcDaliActorPartialUpdateAnimation(void) application.SendNotification(); damagedRects.clear(); + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); application.RenderWithPartialUpdate(damagedRects, clippingRect); @@ -8503,6 +8512,7 @@ int utcDaliActorPartialUpdateAnimation(void) damagedRects.clear(); // In animation deley time + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); application.RenderWithPartialUpdate(damagedRects, clippingRect); @@ -8513,6 +8523,7 @@ int utcDaliActorPartialUpdateAnimation(void) damagedRects.clear(); // Also in animation deley time + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; application.PreRenderWithPartialUpdate(100, nullptr, damagedRects); application.RenderWithPartialUpdate(damagedRects, clippingRect); @@ -8540,15 +8551,17 @@ int utcDaliActorPartialUpdateAnimation(void) DALI_TEST_EQUALS>(expectedRect2, damagedRects[0], TEST_LOCATION); DALI_TEST_EQUALS>(expectedRect1, damagedRects[1], TEST_LOCATION); + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; application.RenderWithPartialUpdate(damagedRects, clippingRect); - // Finished animation, but the actior was already unparented + // Finished animation, but the actor was already unparented damagedRects.clear(); application.PreRenderWithPartialUpdate(500, nullptr, damagedRects); DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); DALI_TEST_EQUALS>(expectedRect2, damagedRects[0], TEST_LOCATION); + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; application.RenderWithPartialUpdate(damagedRects, clippingRect); END_TEST; @@ -8720,6 +8733,179 @@ int utcDaliActorPartialUpdateOnOffScene(void) END_TEST; } +int utcDaliActorPartialUpdateSkipRendering(void) +{ + TestApplication application( + TestApplication::DEFAULT_SURFACE_WIDTH, + TestApplication::DEFAULT_SURFACE_HEIGHT, + TestApplication::DEFAULT_HORIZONTAL_DPI, + TestApplication::DEFAULT_VERTICAL_DPI, + true, + true); + + tet_infoline("Check to skip rendering in case of the empty damaged rect"); + + TraceCallStack& drawTrace = application.GetGlAbstraction().GetDrawTrace(); + drawTrace.Enable(true); + drawTrace.Reset(); + + Actor actor1 = CreateRenderableActor(); + actor1.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + actor1.SetProperty(Actor::Property::SIZE, Vector3(80.0f, 80.0f, 0.0f)); + application.GetScene().Add(actor1); + + std::vector> damagedRects; + Rect clippingRect; + Rect expectedRect1; + + application.SendNotification(); + application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); + + DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); + + // Aligned by 16 + expectedRect1 = Rect(0, 720, 96, 96); // in screen coordinates, includes 3 last frames updates + DALI_TEST_EQUALS>(expectedRect1, damagedRects[0], TEST_LOCATION); + + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; + application.RenderWithPartialUpdate(damagedRects, clippingRect); + + DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION); + + damagedRects.clear(); + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; + application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); + application.RenderWithPartialUpdate(damagedRects, clippingRect); + + // Remove the actor + actor1.Unparent(); + + application.SendNotification(); + + damagedRects.clear(); + application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); + + DALI_TEST_EQUALS>(expectedRect1, damagedRects[0], TEST_LOCATION); + + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; + application.RenderWithPartialUpdate(damagedRects, clippingRect); + + // Render again without any change + damagedRects.clear(); + drawTrace.Reset(); + application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); + + DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION); + + clippingRect = Rect(); + application.RenderWithPartialUpdate(damagedRects, clippingRect); + + // Skip rendering + DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 0, TEST_LOCATION); + + // Add the actor again + application.GetScene().Add(actor1); + + application.SendNotification(); + + damagedRects.clear(); + drawTrace.Reset(); + application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); + + DALI_TEST_EQUALS>(expectedRect1, damagedRects[0], TEST_LOCATION); + + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; + application.RenderWithPartialUpdate(damagedRects, clippingRect); + + DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION); + + END_TEST; +} + +int utcDaliActorPartialUpdate3DNode(void) +{ + TestApplication application( + TestApplication::DEFAULT_SURFACE_WIDTH, + TestApplication::DEFAULT_SURFACE_HEIGHT, + TestApplication::DEFAULT_HORIZONTAL_DPI, + TestApplication::DEFAULT_VERTICAL_DPI, + true, + true); + + tet_infoline("Partial update should be ignored in case of 3d layer of 3d node"); + + TraceCallStack& drawTrace = application.GetGlAbstraction().GetDrawTrace(); + drawTrace.Enable(true); + drawTrace.Reset(); + + Actor actor1 = CreateRenderableActor(); + actor1.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + actor1.SetProperty(Actor::Property::SIZE, Vector3(80.0f, 80.0f, 0.0f)); + application.GetScene().Add(actor1); + + std::vector> damagedRects; + Rect clippingRect; + + application.SendNotification(); + application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); + + DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); + + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; + application.RenderWithPartialUpdate(damagedRects, clippingRect); + + DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION); + + // Change the layer to 3D + application.GetScene().GetRootLayer().SetProperty(Layer::Property::BEHAVIOR, Layer::LAYER_3D); + + application.SendNotification(); + + damagedRects.clear(); + application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); + + DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); + DALI_TEST_EQUALS>(TestApplication::DEFAULT_SURFACE_RECT, damagedRects[0], TEST_LOCATION); + + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; + drawTrace.Reset(); + application.RenderWithPartialUpdate(damagedRects, clippingRect); + + DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION); + + // Change the layer to 2D + application.GetScene().GetRootLayer().SetProperty(Layer::Property::BEHAVIOR, Layer::LAYER_UI); + + application.SendNotification(); + + damagedRects.clear(); + application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); + + DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); + + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; + application.RenderWithPartialUpdate(damagedRects, clippingRect); + + // Make 3D transform + actor1.SetProperty(Actor::Property::ORIENTATION, Quaternion(Degree(90.0f), Vector3::YAXIS)); + + application.SendNotification(); + + damagedRects.clear(); + application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); + + DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); + DALI_TEST_EQUALS>(TestApplication::DEFAULT_SURFACE_RECT, damagedRects[0], TEST_LOCATION); + + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; + drawTrace.Reset(); + application.RenderWithPartialUpdate(damagedRects, clippingRect); + + DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION); + + END_TEST; +} + int UtcDaliActorCaptureAllTouchAfterStartPropertyP(void) { TestApplication application; diff --git a/automated-tests/src/dali/utc-Dali-Scene.cpp b/automated-tests/src/dali/utc-Dali-Scene.cpp index 96302a2..dcaa704 100644 --- a/automated-tests/src/dali/utc-Dali-Scene.cpp +++ b/automated-tests/src/dali/utc-Dali-Scene.cpp @@ -1103,6 +1103,8 @@ int UtcDaliSceneSurfaceRotatedWithAngle0(void) application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION); + + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; application.RenderWithPartialUpdate(damagedRects, clippingRect); Actor actor = CreateRenderableActor(); @@ -1167,6 +1169,8 @@ int UtcDaliSceneSurfaceRotatedWithAngle90(void) application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION); + + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; application.RenderWithPartialUpdate(damagedRects, clippingRect); Actor actor = CreateRenderableActor(); @@ -1238,6 +1242,8 @@ int UtcDaliSceneSurfaceRotatedWithAngle180(void) application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION); + + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; application.RenderWithPartialUpdate(damagedRects, clippingRect); Actor actor = CreateRenderableActor(); @@ -1309,6 +1315,8 @@ int UtcDaliSceneSurfaceRotatedWithAngle270(void) application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION); + + clippingRect = TestApplication::DEFAULT_SURFACE_RECT; application.RenderWithPartialUpdate(damagedRects, clippingRect); Actor actor = CreateRenderableActor(); diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index 91cb4c5..5079c33 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -491,8 +491,9 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& class DamagedRectsCleaner { public: - explicit DamagedRectsCleaner(std::vector>& damagedRects) + explicit DamagedRectsCleaner(std::vector>& damagedRects, Rect& surfaceRect) : mDamagedRects(damagedRects), + mSurfaceRect(surfaceRect), mCleanOnReturn(true) { } @@ -507,18 +508,20 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& if(mCleanOnReturn) { mDamagedRects.clear(); + mDamagedRects.push_back(mSurfaceRect); } } private: std::vector>& mDamagedRects; + Rect mSurfaceRect; bool mCleanOnReturn; }; Rect surfaceRect = sceneObject->GetSurfaceRect(); // Clean collected dirty/damaged rects on exit if 3d layer or 3d node or other conditions. - DamagedRectsCleaner damagedRectCleaner(damagedRects); + DamagedRectsCleaner damagedRectCleaner(damagedRects, surfaceRect); // Mark previous dirty rects in the sorted array. The array is already sorted by node and renderer, frame number. // so you don't need to sort: std::stable_sort(itemsDirtyRects.begin(), itemsDirtyRects.end()); @@ -707,6 +710,12 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::Scene& scene, bool renderToFbo, Rect& clippingRect) { + if(mImpl->partialUpdateAvailable == Integration::PartialUpdateAvailable::TRUE && !renderToFbo && clippingRect.IsEmpty()) + { + // ClippingRect is empty. Skip rendering + return; + } + // Reset main algorithms command buffer mImpl->renderAlgorithms.ResetCommandBuffer(); @@ -719,6 +728,15 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: std::vector targetstoPresent; + Rect surfaceRect = sceneObject->GetSurfaceRect(); + if(clippingRect == surfaceRect) + { + // Full rendering case + // Make clippingRect empty because we're doing full rendering now if the clippingRect is empty. + // To reduce side effects, keep this logic now. + clippingRect = Rect(); + } + for(uint32_t i = 0; i < count; ++i) { RenderInstruction& instruction = sceneObject->GetRenderInstructions().At(mImpl->renderBufferIndex, i); @@ -733,8 +751,7 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: Rect viewportRect; - Rect surfaceRect = sceneObject->GetSurfaceRect(); - int32_t surfaceOrientation = sceneObject->GetSurfaceOrientation(); + int32_t surfaceOrientation = sceneObject->GetSurfaceOrientation(); // @todo Should these be part of scene? Integration::DepthBufferAvailable depthBufferAvailable = mImpl->depthBufferAvailable; -- 2.7.4