From 15e4bf2e4f1e2789c392170ec16238af4820cb97 Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Tue, 13 Dec 2022 15:00:32 +0900 Subject: [PATCH] (Partial Update) Fix the issue when we have several RenderTasks They may render on the off-screen buffer or the camera position may be moved. Do not break the damaged rect calculation in the cases Change-Id: Ie36922355bf979c5961bb9e7c12cde44a5644116 --- automated-tests/src/dali/utc-Dali-Actor.cpp | 6 +- automated-tests/src/dali/utc-Dali-RenderTask.cpp | 139 ++++++++++++++++++++++- dali/internal/render/common/render-manager.cpp | 14 ++- 3 files changed, 147 insertions(+), 12 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-Actor.cpp b/automated-tests/src/dali/utc-Dali-Actor.cpp index a4264a4..4ac16ea 100644 --- a/automated-tests/src/dali/utc-Dali-Actor.cpp +++ b/automated-tests/src/dali/utc-Dali-Actor.cpp @@ -9353,7 +9353,7 @@ int utcDaliActorPartialUpdateChangeVisibility(void) DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); // Aligned by 16 - clippingRect = Rect(16, 768, 32, 32); // in screen coordinates, includes 3 last frames updates + clippingRect = Rect(16, 768, 32, 32); // in screen coordinates DALI_TEST_EQUALS>(clippingRect, damagedRects[0], TEST_LOCATION); application.RenderWithPartialUpdate(damagedRects, clippingRect); DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION); @@ -9365,10 +9365,6 @@ int utcDaliActorPartialUpdateChangeVisibility(void) 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); - // Ensure the damaged rect is empty DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION); diff --git a/automated-tests/src/dali/utc-Dali-RenderTask.cpp b/automated-tests/src/dali/utc-Dali-RenderTask.cpp index e3857dc..af93507 100644 --- a/automated-tests/src/dali/utc-Dali-RenderTask.cpp +++ b/automated-tests/src/dali/utc-Dali-RenderTask.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 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. @@ -3668,14 +3668,15 @@ int UtcDaliRenderTaskViewportGuideActor02(void) application.GetScene().SurfaceRotated(static_cast(TestApplication::DEFAULT_SURFACE_HEIGHT), static_cast(TestApplication::DEFAULT_SURFACE_WIDTH), - 90, 0); + 90, + 0); // Render and notify application.SendNotification(); application.Render(16); std::string viewportParams1("50, 100, 300, 400"); // to match newSize - std::string viewportParams2("0, 0, 480, 800"); // to match newSize + std::string viewportParams2("0, 0, 480, 800"); // to match newSize // Check that the viewport is handled properly DALI_TEST_CHECK(callStack.FindIndexFromMethodAndParams("Viewport", viewportParams1) >= 0); @@ -3683,3 +3684,135 @@ int UtcDaliRenderTaskViewportGuideActor02(void) END_TEST; } + +int UtcDaliRenderTaskSetPartialUpdate(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 rects with render task"); + + const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams()); + + 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); + + Actor rootActor = CreateRenderableActor(); + rootActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + rootActor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f)); + rootActor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f)); + rootActor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS); + application.GetScene().Add(rootActor); + + CameraActor cameraActor = CameraActor::New(Size(TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT)); + cameraActor.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); + cameraActor.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + application.GetScene().Add(cameraActor); + + Texture frameBufferTexture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGB888, 16, 16); + FrameBuffer frameBuffer = FrameBuffer::New(frameBufferTexture.GetWidth(), frameBufferTexture.GetHeight()); + frameBuffer.AttachColorTexture(frameBufferTexture); + + // Create a RenderTask and set a framebuffer + RenderTaskList taskList = application.GetScene().GetRenderTaskList(); + RenderTask newTask = taskList.CreateTask(); + newTask.SetCameraActor(cameraActor); + newTask.SetSourceActor(rootActor); + newTask.SetInputEnabled(false); + newTask.SetClearColor(Vector4(0.f, 0.f, 0.f, 0.f)); + newTask.SetClearEnabled(true); + newTask.SetExclusive(true); + newTask.SetRefreshRate(RenderTask::REFRESH_ALWAYS); + newTask.SetFrameBuffer(frameBuffer); + + application.SendNotification(); + + std::vector> damagedRects; + Rect clippingRect; + + application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); + + // Full update if there is off-screen rendering + clippingRect = Rect(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT); + DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); + DALI_TEST_EQUALS>(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); + + // Remove framebuffer + newTask.SetFrameBuffer(FrameBuffer()); + + application.SendNotification(); + + damagedRects.clear(); + application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); + + // Full update + clippingRect = Rect(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT); + DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); + DALI_TEST_EQUALS>(clippingRect, damagedRects[0], TEST_LOCATION); + + application.RenderWithPartialUpdate(damagedRects, clippingRect); + + // Set invalid viewport of the render task + newTask.SetViewportSize(Vector2(-100.0f, -100.0f)); + + application.SendNotification(); + + damagedRects.clear(); + application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); + + // Full update because the camera orientation is changed + clippingRect = Rect(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT); + DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); + DALI_TEST_EQUALS>(clippingRect, damagedRects[0], TEST_LOCATION); + + application.RenderWithPartialUpdate(damagedRects, clippingRect); + + newTask.SetViewportSize(Vector2(0.0f, 0.0f)); + + // Change orientation of offscreen camera + cameraActor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Degree(90.0f), Vector3::XAXIS)); + + application.SendNotification(); + + damagedRects.clear(); + application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); + + // Full update because the camera orientation is changed + clippingRect = Rect(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT); + DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); + DALI_TEST_EQUALS>(clippingRect, damagedRects[0], TEST_LOCATION); + + application.RenderWithPartialUpdate(damagedRects, clippingRect); + + // Change camera target + cameraActor.SetTargetPosition(Vector3(10.0f, 10.0f, 0.0f)); + + application.SendNotification(); + + damagedRects.clear(); + application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); + + // Full update because the camera is moved + clippingRect = Rect(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT); + DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); + DALI_TEST_EQUALS>(clippingRect, damagedRects[0], TEST_LOCATION); + + application.RenderWithPartialUpdate(damagedRects, clippingRect); + + END_TEST; +} diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index c7b88c1..fff4fe8 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -543,7 +543,8 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& if(instruction.mFrameBuffer) { - return; // TODO: reset, we don't deal with render tasks with framebuffers (for now) + cleanDamagedRect = true; + continue; // TODO: reset, we don't deal with render tasks with framebuffers (for now) } const Camera* camera = instruction.GetCamera(); @@ -564,12 +565,14 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& orientationAngle != ANGLE_180 || scale != Vector3(1.0f, 1.0f, 1.0f)) { - return; + cleanDamagedRect = true; + continue; } } else { - return; + cleanDamagedRect = true; + continue; } Rect viewportRect; @@ -579,7 +582,8 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& viewportRect.Set(instruction.mViewport.x, y, instruction.mViewport.width, instruction.mViewport.height); if(viewportRect.IsEmpty() || !viewportRect.IsValid()) { - return; // just skip funny use cases for now, empty viewport means it is set somewhere else + cleanDamagedRect = true; + continue; // just skip funny use cases for now, empty viewport means it is set somewhere else } } else @@ -682,7 +686,9 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& else { // The item is not in the list for some reason. Add it! + dirtyRect.rect = surfaceRect; itemsDirtyRects.insert(dirtyRectPos, dirtyRect); + cleanDamagedRect = true; // And make full update at this frame } } } -- 2.7.4