From: Eunki, Hong Date: Tue, 18 Jun 2024 03:58:10 +0000 (+0900) Subject: (CanvasView) Support rasterization request manually X-Git-Tag: dali_2.3.29~5^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=aeae30762d42679c89e5f8d70c5ea38237ba38e8;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git (CanvasView) Support rasterization request manually Let we support to make user request rasterization manually. If user mark it as true, we should call RequestRasterization manullay. It will be reduce overhead when user add CanvasView very large amount. Change-Id: Ib404b0b3fd0adb76cf9c5f85476be26eefa4def9 Signed-off-by: Eunki, Hong --- diff --git a/automated-tests/src/dali-toolkit/utc-Dali-CanvasView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-CanvasView.cpp index 6d29bf568b..febdf970e2 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-CanvasView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-CanvasView.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 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. @@ -30,8 +30,8 @@ #include #include #include -#include #include +#include using namespace Dali; using namespace Toolkit; @@ -357,7 +357,7 @@ int UtcDaliCanvasViewRasterizeThreadRasterizationCompletedSignalP(void) gRasterizationCompletedSignal = false; - Dali::Toolkit::CanvasView canvasView = Dali::Toolkit::CanvasView::New(Vector2(100, 100)); + Dali::Toolkit::CanvasView canvasView = Dali::Toolkit::CanvasView::New(Vector2(100, 100)); Dali::CanvasRenderer dummyCanvasRenderer = Dali::CanvasRenderer::New(Vector2(100, 100)); DALI_TEST_CHECK(dummyCanvasRenderer); @@ -503,3 +503,85 @@ int UtcDaliCanvasViewSychronousLoading(void) END_TEST; } + +int UtcDaliCanvasViewRasterizationRequestManually(void) +{ + ToolkitTestApplication application; + + CanvasView canvasView = CanvasView::New(Vector2(300, 300)); + DALI_TEST_CHECK(canvasView); + + application.GetScene().Add(canvasView); + + canvasView.SetProperty(Actor::Property::SIZE, Vector2(300, 300)); + canvasView.SetProperty(Toolkit::CanvasView::Property::SYNCHRONOUS_LOADING, false); + + Dali::CanvasRenderer::Shape shape = Dali::CanvasRenderer::Shape::New(); + + shape.AddRect(Rect(10, 10, 10, 10), Vector2(0, 0)); + + canvasView.AddDrawable(shape); + + application.SendNotification(); + application.Render(); + + // Rasterization occured + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + bool isRasterizationManually = canvasView.GetProperty(Toolkit::CanvasView::Property::RASTERIZATION_REQUEST_MANUALLY).Get(); + DALI_TEST_EQUALS(isRasterizationManually, false, TEST_LOCATION); + + shape.AddRect(Rect(10, 10, 10, 10), Vector2(0, 0)); + application.SendNotification(); + application.Render(); + + shape.AddRect(Rect(10, 10, 10, 10), Vector2(0, 0)); + application.SendNotification(); + application.Render(); + + // Check if the canvasView is rasterized. + // Rasterization occured + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + canvasView.SetProperty(Toolkit::CanvasView::Property::RASTERIZATION_REQUEST_MANUALLY, true); + + application.SendNotification(); + application.Render(); + + // Rasterization occured + // (Note that we cannot 'cancel' the latest rasterization request even if we set RASTERIZATION_REQUEST_MANUALLY to true) + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + isRasterizationManually = canvasView.GetProperty(Toolkit::CanvasView::Property::RASTERIZATION_REQUEST_MANUALLY).Get(); + DALI_TEST_EQUALS(isRasterizationManually, true, TEST_LOCATION); + + shape.AddRect(Rect(10, 10, 10, 10), Vector2(0, 0)); + application.SendNotification(); + application.Render(); + + // Check if the canvasView is not rasterized. + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, 0), false, TEST_LOCATION); + + Dali::CanvasRenderer::Shape shape2 = Dali::CanvasRenderer::Shape::New(); + + shape2.AddRect(Rect(10, 10, 10, 10), Vector2(0, 0)); + + canvasView.AddDrawable(shape2); + + application.SendNotification(); + application.Render(); + + // Check whether the canvasView is not rasterized even if we add drawables. + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1, 0), false, TEST_LOCATION); + + // Request rasterize manually + canvasView.RequestRasterization(); + + application.SendNotification(); + application.Render(); + + // Check if the canvasView is rasterized. + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + END_TEST; +} diff --git a/dali-toolkit/devel-api/controls/canvas-view/canvas-view.cpp b/dali-toolkit/devel-api/controls/canvas-view/canvas-view.cpp index a00cd35be1..db2c5da9f5 100644 --- a/dali-toolkit/devel-api/controls/canvas-view/canvas-view.cpp +++ b/dali-toolkit/devel-api/controls/canvas-view/canvas-view.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 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. @@ -83,6 +83,11 @@ void CanvasView::RemoveAllDrawables() Dali::Toolkit::GetImpl(*this).RemoveAllDrawables(); } +void CanvasView::RequestRasterization() +{ + Dali::Toolkit::GetImpl(*this).RequestRasterization(); +} + CanvasView::CanvasView(Internal::CanvasView& implementation) : Control(implementation) { diff --git a/dali-toolkit/devel-api/controls/canvas-view/canvas-view.h b/dali-toolkit/devel-api/controls/canvas-view/canvas-view.h index 026d3faedd..db5c90079e 100644 --- a/dali-toolkit/devel-api/controls/canvas-view/canvas-view.h +++ b/dali-toolkit/devel-api/controls/canvas-view/canvas-view.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_CANVAS_VIEW_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 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. @@ -87,10 +87,19 @@ public: /** * @brief Whether to load the canvas synchronously. * @details Name "synchronousLoading", type Property::BOOLEAN. + * @note Default is true. */ SYNCHRONOUS_LOADING, + + /** + * @brief Whether to request rasterize canvas manually or automatically + * @details Name "rasterizationRequestManually", type Property::BOOLEAN. + * @note Default is false. + */ + RASTERIZATION_REQUEST_MANUALLY, }; }; + public: /** * @brief Creates an uninitialized CanvasView. @@ -180,6 +189,11 @@ public: */ void RemoveAllDrawables(); + /** + * @brief Request to rasterize the CanvasView. + */ + void RequestRasterization(); + public: // Not intended for application developers /// @cond internal /** diff --git a/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp b/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp index 282ebb4476..1b3cae79a6 100644 --- a/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp +++ b/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.cpp @@ -47,6 +47,7 @@ BaseHandle Create() DALI_TYPE_REGISTRATION_BEGIN(Toolkit::CanvasView, Toolkit::Control, Create); DALI_PROPERTY_REGISTRATION(Toolkit, CanvasView, "viewBox", VECTOR2, VIEW_BOX) DALI_PROPERTY_REGISTRATION(Toolkit, CanvasView, "synchronousLoading", BOOLEAN, SYNCHRONOUS_LOADING) +DALI_PROPERTY_REGISTRATION(Toolkit, CanvasView, "rasterizationRequestManually", BOOLEAN, RASTERIZATION_REQUEST_MANUALLY) DALI_TYPE_REGISTRATION_END() } // anonymous namespace @@ -58,17 +59,22 @@ CanvasView::CanvasView(const Vector2& viewBox) mTexture(), mTextureSet(), mSize(viewBox), - mIsSynchronous(true) + mIsSynchronous(true), + mManualRasterization(false), + mProcessorRegistered(false) { } CanvasView::~CanvasView() { - if(Adaptor::IsAvailable()) + if(Adaptor::IsAvailable() && mProcessorRegistered) { - Dali::AsyncTaskManager::Get().RemoveTask(mRasterizingTask); - mRasterizingTask.Reset(); - Adaptor::Get().UnregisterProcessor(*this, true); + if(mRasterizingTask) + { + Dali::AsyncTaskManager::Get().RemoveTask(mRasterizingTask); + mRasterizingTask.Reset(); + } + Adaptor::Get().UnregisterProcessorOnce(*this, true); } } @@ -94,7 +100,8 @@ void CanvasView::OnInitialize() Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::IMAGE); - Adaptor::Get().RegisterProcessor(*this, true); + // Request rasterization once at very first time. + RequestRasterization(); } void CanvasView::OnRelayout(const Vector2& size, RelayoutContainer& container) @@ -147,6 +154,15 @@ void CanvasView::SetProperty(BaseObject* object, Property::Index propertyIndex, } break; } + case Toolkit::CanvasView::Property::RASTERIZATION_REQUEST_MANUALLY: + { + bool isRasterizationManually; + if(value.Get(isRasterizationManually)) + { + canvasViewImpl.SetRasterizationRequestManually(isRasterizationManually); + } + break; + } } } } @@ -173,6 +189,11 @@ Property::Value CanvasView::GetProperty(BaseObject* object, Property::Index prop value = canvasViewImpl.IsSynchronous(); break; } + case Toolkit::CanvasView::Property::RASTERIZATION_REQUEST_MANUALLY: + { + value = canvasViewImpl.IsRasterizationRequestManually(); + break; + } } } return value; @@ -180,27 +201,39 @@ Property::Value CanvasView::GetProperty(BaseObject* object, Property::Index prop void CanvasView::Process(bool postProcessor) { + mProcessorRegistered = false; + if(mCanvasRenderer && mCanvasRenderer.IsCanvasChanged() && mSize.width > 0 && mSize.height > 0) { AddRasterizationTask(); } + + // If we are not doing manual rasterization, register processor once again. + // TODO : Could we reqest it only if IsCanvasChagned() is true? + if(!mManualRasterization) + { + RequestRasterization(); + } } void CanvasView::AddRasterizationTask() { - mRasterizingTask = new CanvasRendererRasterizingTask(mCanvasRenderer, MakeCallback(this, &CanvasView::ApplyRasterizedImage)); - - if(mCanvasRenderer.Commit()) + if(mCanvasRenderer && mCanvasRenderer.Commit()) { if(mIsSynchronous) { - mRasterizingTask->Process(); - ApplyRasterizedImage(mRasterizingTask); - mRasterizingTask.Reset(); // We don't need it anymore. + CanvasRendererRasterizingTaskPtr rasterizingTask = new CanvasRendererRasterizingTask(mCanvasRenderer, MakeCallback(this, &CanvasView::ApplyRasterizedImage)); + rasterizingTask->Process(); + ApplyRasterizedImage(rasterizingTask); + rasterizingTask.Reset(); // We don't need it anymore. } else { - AsyncTaskManager::Get().AddTask(mRasterizingTask); + if(!mRasterizingTask) + { + mRasterizingTask = new CanvasRendererRasterizingTask(mCanvasRenderer, MakeCallback(this, &CanvasView::ApplyRasterizedImage)); + AsyncTaskManager::Get().AddTask(mRasterizingTask); + } } } } @@ -230,10 +263,13 @@ void CanvasView::ApplyRasterizedImage(CanvasRendererRasterizingTaskPtr task) } } - mRasterizingTask.Reset(); // We don't need it anymore + if(task == mRasterizingTask) + { + mRasterizingTask.Reset(); // We don't need it anymore + } //If there are accumulated changes to CanvasRenderer during Rasterize, Rasterize once again. - if(!mIsSynchronous && mCanvasRenderer && mCanvasRenderer.IsCanvasChanged()) + if(!mIsSynchronous && !mManualRasterization && mCanvasRenderer && mCanvasRenderer.IsCanvasChanged()) { AddRasterizationTask(); } @@ -266,6 +302,15 @@ bool CanvasView::RemoveAllDrawables() return false; } +void CanvasView::RequestRasterization() +{ + if(!mProcessorRegistered && Adaptor::IsAvailable()) + { + mProcessorRegistered = true; + Adaptor::Get().RegisterProcessorOnce(*this, true); + } +} + bool CanvasView::SetViewBox(const Vector2& viewBox) { if(mCanvasRenderer && mCanvasRenderer.SetViewBox(viewBox)) @@ -289,11 +334,28 @@ void CanvasView::SetSynchronous(const bool isSynchronous) mIsSynchronous = isSynchronous; } -const bool CanvasView::IsSynchronous() +const bool CanvasView::IsSynchronous() const { return mIsSynchronous; } +void CanvasView::SetRasterizationRequestManually(const bool isRasterizationManually) +{ + if(mManualRasterization != isRasterizationManually) + { + mManualRasterization = isRasterizationManually; + if(!mManualRasterization) + { + RequestRasterization(); + } + } +} + +const bool CanvasView::IsRasterizationRequestManually() const +{ + return mManualRasterization; +} + } // namespace Internal } // namespace Toolkit } // namespace Dali diff --git a/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.h b/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.h index 6f0fa11dba..82f7ff3675 100644 --- a/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.h +++ b/dali-toolkit/internal/controls/canvas-view/canvas-view-impl.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_INTERNAL_CANVAS_VIEW_H /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 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. @@ -90,6 +90,11 @@ public: */ bool RemoveAllDrawables(); + /** + * @copydoc Toolkit::Control::CanvasView::RequestRasterization + */ + void RequestRasterization(); + private: // From Control /** * @copydoc Control::OnRelayout @@ -131,7 +136,21 @@ private: // From Control * * @return Returns true if synchronously. */ - const bool IsSynchronous(); + const bool IsSynchronous() const; + + /** + * @brief Set to request rasterize canvas manually or automatically + * + * @param isRasterizationManually True if rasterize canvas manually. + */ + void SetRasterizationRequestManually(const bool isRasterizationManually); + + /** + * @brief Whether to request rasterize canvas manually or automatically + * + * @return Returns true if rasterize canvas manually. + */ + const bool IsRasterizationRequestManually() const; /** * @bried Rasterize the canvas, and add it to the view. @@ -172,7 +191,9 @@ private: TextureSet mTextureSet; Vector2 mSize; CanvasRendererRasterizingTaskPtr mRasterizingTask; - bool mIsSynchronous; + bool mIsSynchronous : 1; + bool mManualRasterization : 1; + bool mProcessorRegistered : 1; }; } // namespace Internal