From: dongsug.song Date: Tue, 17 Jan 2023 06:20:01 +0000 (+0900) Subject: Merge branch 'devel/master' into tizen X-Git-Tag: accepted/tizen/unified/20230120.182041~1 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-core.git;a=commitdiff_plain;h=d67b366a74050ddec47340ff10a0188c0d381561;hp=92713ffd473e7273cd21ed7af6a223d6c4d03260 Merge branch 'devel/master' into tizen Change-Id: Ic32154d9302bd9e7c2486619f6cbf8e595c2bbfa --- diff --git a/automated-tests/src/dali/utc-Dali-Scene.cpp b/automated-tests/src/dali/utc-Dali-Scene.cpp index 0dd5e19..959e5ee 100644 --- a/automated-tests/src/dali/utc-Dali-Scene.cpp +++ b/automated-tests/src/dali/utc-Dali-Scene.cpp @@ -2592,3 +2592,86 @@ int UtcDaliSceneSignalInterceptKeyEventN(void) END_TEST; } + +int UtcDaliSceneGetOverlayLayer(void) +{ + TestApplication application; + tet_infoline("Testing Dali::Integration::Scene::GetOverlayLayer"); + + Dali::Integration::Scene scene = application.GetScene(); + + // Check we get a valid instance. + RenderTaskList tasks = scene.GetRenderTaskList(); + + // There should be 1 task by default. + DALI_TEST_EQUALS(tasks.GetTaskCount(), 1u, TEST_LOCATION); + RenderTask defaultTask = tasks.GetTask(0u); + DALI_TEST_EQUALS(scene.GetRootLayer(), defaultTask.GetSourceActor(), TEST_LOCATION); + + Layer layer = scene.GetOverlayLayer(); + // There should be 2 task by default. + DALI_TEST_EQUALS(tasks.GetTaskCount(), 2u, TEST_LOCATION); + RenderTask overlayTask = tasks.GetTask(1u); + DALI_TEST_EQUALS(overlayTask, tasks.GetOverlayTask(), TEST_LOCATION); + DALI_TEST_CHECK(scene.GetRootLayer() != overlayTask.GetSourceActor()); + DALI_TEST_CHECK(overlayTask != defaultTask); + DALI_TEST_EQUALS(overlayTask.GetClearEnabled(), false, TEST_LOCATION); + DALI_TEST_EQUALS(overlayTask.IsExclusive(), true, TEST_LOCATION); + + // If new render task is created, the last task is overlayTask + RenderTask newTask = scene.GetRenderTaskList().CreateTask(); + DALI_TEST_EQUALS(tasks.GetTaskCount(), 3u, TEST_LOCATION); + DALI_TEST_EQUALS(newTask, tasks.GetTask(1u), TEST_LOCATION); + DALI_TEST_EQUALS(overlayTask, tasks.GetTask(2u), TEST_LOCATION); + + // Render + application.SendNotification(); + application.Render(); + + tasks.RemoveTask(overlayTask); + DALI_TEST_EQUALS(tasks.GetTaskCount(), 2u, TEST_LOCATION); + DALI_TEST_EQUALS(tasks.GetTask(0u), defaultTask, TEST_LOCATION); + DALI_TEST_EQUALS(tasks.GetTask(1u), newTask, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliSceneSurfaceResizedWithOverlayLayer(void) +{ + tet_infoline("Ensure resizing of the surface is handled properly"); + + TestApplication application; + + auto scene = application.GetScene(); + DALI_TEST_CHECK(scene); + + const RenderTaskList& tasks = scene.GetRenderTaskList(); + DALI_TEST_EQUALS(tasks.GetTaskCount(), 1u, TEST_LOCATION); + RenderTask defaultTask = tasks.GetTask(0u); + DALI_TEST_EQUALS(scene.GetRootLayer(), defaultTask.GetSourceActor(), TEST_LOCATION); + + // Ensure stage size matches the scene size + auto stage = Stage::GetCurrent(); + Vector2 sceneSize = stage.GetSize(); + Viewport sceneViewport(0, 0, sceneSize.x, sceneSize.y); + DALI_TEST_EQUALS(stage.GetSize(), scene.GetSize(), TEST_LOCATION); + Viewport defaultViewport = defaultTask.GetViewport(); + DALI_TEST_EQUALS(defaultViewport, sceneViewport, TEST_LOCATION); + + Layer layer = scene.GetOverlayLayer(); + // There should be 2 task by default. + DALI_TEST_EQUALS(tasks.GetTaskCount(), 2u, TEST_LOCATION); + RenderTask overlayTask = tasks.GetTask(1u); + Viewport overlayViewport = defaultTask.GetViewport(); + DALI_TEST_EQUALS(defaultViewport, overlayViewport, TEST_LOCATION); + + // Resize the scene + Vector2 newSize(1000.0f, 2000.0f); + DALI_TEST_CHECK(stage.GetSize() != newSize); + scene.SurfaceResized(newSize.width, newSize.height); + Viewport newViewport(0, 0, newSize.x, newSize.y); + DALI_TEST_EQUALS(newViewport, defaultTask.GetViewport(), TEST_LOCATION); + DALI_TEST_EQUALS(newViewport, defaultTask.GetViewport(), TEST_LOCATION); + + END_TEST; +} diff --git a/dali/integration-api/scene.cpp b/dali/integration-api/scene.cpp index 20f85f2..5eedf5c 100644 --- a/dali/integration-api/scene.cpp +++ b/dali/integration-api/scene.cpp @@ -103,6 +103,11 @@ Layer Scene::GetRootLayer() const return GetImplementation(*this).GetRootLayer(); } +Layer Scene::GetOverlayLayer() +{ + return GetImplementation(*this).GetOverlayLayer(); +} + uint32_t Scene::GetLayerCount() const { return GetImplementation(*this).GetLayerCount(); diff --git a/dali/integration-api/scene.h b/dali/integration-api/scene.h index aac126f..51a8572 100644 --- a/dali/integration-api/scene.h +++ b/dali/integration-api/scene.h @@ -207,6 +207,14 @@ public: Layer GetRootLayer() const; /** + * @brief Returns the Scene's Overlay Layer. + * If there is no overlay layer yet, this creates the layer and an associated render task. + * + * @return The overlay layer + */ + Layer GetOverlayLayer(); + + /** * @brief Queries the number of on-stage layers. * * Note that a default layer is always provided (count >= 1). diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp index bf91a94..ab20929 100644 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -1481,7 +1481,7 @@ void Actor::SetParent(ActorParent* parent, bool notify) Actor* parentActor = static_cast(parent); mScene = parentActor->mScene; - if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction + if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction parentActor->OnScene()) { // Instruct each actor to create a corresponding node in the scene graph @@ -1497,7 +1497,7 @@ void Actor::SetParent(ActorParent* parent, bool notify) mParent = nullptr; - if(EventThreadServices::IsCoreRunning() && // Don't emit signals or send messages during Core destruction + if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction OnScene()) { // Disconnect the Node & its children from the scene-graph. diff --git a/dali/internal/event/common/event-thread-services.cpp b/dali/internal/event/common/event-thread-services.cpp index 75b6c8a..87a42a8 100644 --- a/dali/internal/event/common/event-thread-services.cpp +++ b/dali/internal/event/common/event-thread-services.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -34,5 +34,10 @@ bool EventThreadServices::IsCoreRunning() return ThreadLocalStorage::Created(); } +bool EventThreadServices::IsShuttingDown() +{ + return ThreadLocalStorage::IsShuttingDown(); +} + } // namespace Internal } // namespace Dali diff --git a/dali/internal/event/common/event-thread-services.h b/dali/internal/event/common/event-thread-services.h index 494a722..f2c6ae7 100644 --- a/dali/internal/event/common/event-thread-services.h +++ b/dali/internal/event/common/event-thread-services.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_EVENT_THREAD_SERVICES_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -116,8 +116,17 @@ public: /** * @return true if core is still running and we can send messages + * @note It returns false if it is called from a thread other than the main thread. */ static bool IsCoreRunning(); + + /** + * @brief Check if the event thread service is shutting down. + * + * @return true if the event thread service is shutting down. + * @note It returns false if the core hasn't been initialised yet. + */ + static bool IsShuttingDown(); }; } // namespace Internal diff --git a/dali/internal/event/common/scene-impl.cpp b/dali/internal/event/common/scene-impl.cpp index ea5c689..56ed507 100644 --- a/dali/internal/event/common/scene-impl.cpp +++ b/dali/internal/event/common/scene-impl.cpp @@ -85,6 +85,11 @@ Scene::~Scene() mRootLayer.Reset(); } + if(mOverlayLayer) + { + mOverlayLayer.Reset(); + } + if(mRenderTaskList) { mRenderTaskList.Reset(); @@ -174,6 +179,26 @@ Dali::Layer Scene::GetRootLayer() const return Dali::Layer(mRootLayer.Get()); } +Dali::Layer Scene::GetOverlayLayer() +{ + if(!mOverlayLayer) + { + // Creates overlay layer. + mOverlayLayer = Layer::New(); + mOverlayLayer->SetName("OverlayLayer"); + mOverlayLayer->SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS); + mOverlayLayer->SetParentOrigin(Dali::ParentOrigin::TOP_LEFT); + mOverlayLayer->SetAnchorPoint(Dali::AnchorPoint::TOP_LEFT); + mRootLayer->Add(*mOverlayLayer); + + // Create the overlay render-task and set exclusive to true. + RenderTaskPtr renderTask = mRenderTaskList->CreateOverlayTask(mOverlayLayer.Get(), mDefaultCamera.Get()); + renderTask->SetExclusive(true); + renderTask->SetInputEnabled(true); + } + return Dali::Layer(mOverlayLayer.Get()); +} + LayerList& Scene::GetLayerList() const { return *mLayerList; @@ -337,6 +362,12 @@ void Scene::ChangedSurface(float width, float height, int32_t windowOrientation, // set default render-task viewport parameters RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask(0u); defaultRenderTask->SetViewport(newSize); + // set overlay render-task viewport parameters + RenderTaskPtr overlayRenderTask = mRenderTaskList->GetOverlayTask(); + if(overlayRenderTask) + { + overlayRenderTask->SetViewport(newSize); + } } bool Scene::IsSurfaceRectChanged() const diff --git a/dali/internal/event/common/scene-impl.h b/dali/internal/event/common/scene-impl.h index 52ea356..cda29a2 100644 --- a/dali/internal/event/common/scene-impl.h +++ b/dali/internal/event/common/scene-impl.h @@ -105,6 +105,11 @@ public: Dali::Layer GetRootLayer() const; /** + * @copydoc Dali::Integration::Scene::GetOverlayLayer + */ + Dali::Layer GetOverlayLayer(); + + /** * @copydoc Dali::Integration::Scene::GetLayerCount */ uint32_t GetLayerCount() const; @@ -380,6 +385,8 @@ private: LayerPtr mRootLayer; + LayerPtr mOverlayLayer; + // Ordered list of currently on-stage layers OwnerPointer mLayerList; diff --git a/dali/internal/event/common/thread-local-storage.cpp b/dali/internal/event/common/thread-local-storage.cpp index 6ebfc68..86e848d 100644 --- a/dali/internal/event/common/thread-local-storage.cpp +++ b/dali/internal/event/common/thread-local-storage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -51,22 +51,25 @@ namespace Internal { namespace { -thread_local ThreadLocalStorage* threadLocal = nullptr; -} +thread_local ThreadLocalStorage* threadLocal = nullptr; +thread_local bool isShuttingDown = false; +} // namespace ThreadLocalStorage::ThreadLocalStorage(Core* core) : mCore(core) { DALI_ASSERT_ALWAYS(threadLocal == nullptr && "Cannot create more than one ThreadLocalStorage object"); - threadLocal = this; + threadLocal = this; + isShuttingDown = false; } ThreadLocalStorage::~ThreadLocalStorage() = default; void ThreadLocalStorage::Remove() { - threadLocal = nullptr; + threadLocal = nullptr; + isShuttingDown = true; } ThreadLocalStorage& ThreadLocalStorage::Get() @@ -92,6 +95,11 @@ bool ThreadLocalStorage::Created() return (threadLocal != nullptr); } +bool ThreadLocalStorage::IsShuttingDown() +{ + return isShuttingDown; +} + ThreadLocalStorage* ThreadLocalStorage::GetInternal() { return threadLocal; diff --git a/dali/internal/event/common/thread-local-storage.h b/dali/internal/event/common/thread-local-storage.h index 16f3876..8baef7d 100644 --- a/dali/internal/event/common/thread-local-storage.h +++ b/dali/internal/event/common/thread-local-storage.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_THREAD_LOCAL_STORAGE_H /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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,13 @@ public: static bool Created(); /** + * Checks if the system is shutting down + * @return true if the system is shutting down + * @note It returns false if the core hasn't been initialised yet. + */ + static bool IsShuttingDown(); + + /** * Get a pointer to the TLS or NULL if not initialized * @return pointer to the TLS */ diff --git a/dali/internal/event/render-tasks/render-task-list-impl.cpp b/dali/internal/event/render-tasks/render-task-list-impl.cpp index 39a98ba..42722b8 100644 --- a/dali/internal/event/render-tasks/render-task-list-impl.cpp +++ b/dali/internal/event/render-tasks/render-task-list-impl.cpp @@ -42,6 +42,7 @@ namespace Dali { namespace Internal { + RenderTaskListPtr RenderTaskList::New() { RenderTaskListPtr taskList = new RenderTaskList(); @@ -59,12 +60,27 @@ RenderTaskPtr RenderTaskList::CreateTask() RenderTaskPtr RenderTaskList::CreateTask(Actor* sourceActor, CameraActor* cameraActor) { RenderTaskPtr task = RenderTask::New(sourceActor, cameraActor, *this); - - mTasks.push_back(task); + if(mOverlayRenderTask && mTasks.back() == mOverlayRenderTask) + { + mTasks.insert(mTasks.end() - 1, task); + } + else + { + mTasks.push_back(task); + } return task; } +RenderTaskPtr RenderTaskList::CreateOverlayTask(Actor* sourceActor, CameraActor* cameraActor) +{ + if(!mOverlayRenderTask) + { + mOverlayRenderTask = CreateTask(sourceActor, &mDefaults.GetDefaultCameraActor()); + } + return mOverlayRenderTask; +} + void RenderTaskList::RemoveTask(Internal::RenderTask& task) { for(RenderTaskContainer::iterator iter = mTasks.begin(); mTasks.end() != iter; ++iter) @@ -80,13 +96,11 @@ void RenderTaskList::RemoveTask(Internal::RenderTask& task) // send a message to remove the scene-graph RenderTask RemoveTaskMessage(mEventThreadServices, *mSceneObject, sceneObject); - for(auto exclusiveIt = mExclusives.begin(); exclusiveIt != mExclusives.end(); ++exclusiveIt) + Exclusive exclusive{ptr, ActorObserver()}; + ExclusivesContainer::iterator exclusiveIter = find(mExclusives.begin(), mExclusives.end(), exclusive); + if(exclusiveIter != mExclusives.end()) { - if(exclusiveIt->renderTaskPtr == ptr) - { - mExclusives.erase(exclusiveIt); - break; - } + mExclusives.erase(exclusiveIter); } break; // we're finished } @@ -105,6 +119,16 @@ RenderTaskPtr RenderTaskList::GetTask(uint32_t index) const return mTasks[index]; } +RenderTaskPtr RenderTaskList::GetOverlayTask() const +{ + RenderTaskPtr overlayRenderTask; + if(mOverlayRenderTask) + { + overlayRenderTask = mOverlayRenderTask; + } + return overlayRenderTask; +} + void RenderTaskList::SetExclusive(RenderTask* task, bool exclusive) { // Check to see if this rendertask has an entry? diff --git a/dali/internal/event/render-tasks/render-task-list-impl.h b/dali/internal/event/render-tasks/render-task-list-impl.h index 6a8ed44..c01b981 100644 --- a/dali/internal/event/render-tasks/render-task-list-impl.h +++ b/dali/internal/event/render-tasks/render-task-list-impl.h @@ -59,9 +59,15 @@ public: { RenderTask* renderTaskPtr; ///< Pointer for comparison with current rendertask. ActorObserver actor; ///< For comparison with current actor. + + bool operator==(const Exclusive& other) const + { + return renderTaskPtr == other.renderTaskPtr; + } }; using ExclusivesContainer = std::vector; + using ExclusiveIter = ExclusivesContainer::iterator; /** * Create a RenderTaskList. @@ -86,6 +92,16 @@ public: RenderTaskPtr CreateTask(Actor* sourceActor, CameraActor* cameraActor); /** + * @brief Creates a new RenderTask for overlay. + * This will be appended to the end of render-task list. + * @param[in] sourceActor The actor and its children to be rendered for this render task. + * @param[in] cameraActor The actor from which the scene is viewed for this render task. + * @return A valid handle to a new overlay RenderTask + * @note The Overlay RenderTask will be rendered after all the other render tasks are rendered. + */ + RenderTaskPtr CreateOverlayTask(Actor* sourceActor, CameraActor* cameraActor); + + /** * @copydoc Dali::RenderTaskList::RemoveTask() */ void RemoveTask(Internal::RenderTask& task); @@ -101,6 +117,11 @@ public: RenderTaskPtr GetTask(uint32_t index) const; /** + * @copydoc Dali::RenderTaskList::GetOverlayTask() + */ + RenderTaskPtr GetOverlayTask() const; + + /** * Retrieve the container of render-tasks. * @return The container. */ @@ -177,6 +198,7 @@ private: RenderTaskContainer mTasks; ///< Reference counted render-tasks ExclusivesContainer mExclusives; ///< List of rendertasks with exclusively owned source actors. + RenderTaskPtr mOverlayRenderTask{nullptr}; }; } // namespace Internal diff --git a/dali/internal/update/common/property-owner.cpp b/dali/internal/update/common/property-owner.cpp index e23831f..1111f94 100644 --- a/dali/internal/update/common/property-owner.cpp +++ b/dali/internal/update/common/property-owner.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -158,11 +158,13 @@ PropertyOwner::PropertyOwner() void PropertyOwner::AddUniformMapping(const UniformPropertyMapping& map) { mUniformMaps.Add(map); + OnMappingChanged(); } void PropertyOwner::RemoveUniformMapping(const ConstString& uniformName) { mUniformMaps.Remove(uniformName); + OnMappingChanged(); } const UniformMap& PropertyOwner::GetUniformMap() const @@ -170,16 +172,6 @@ const UniformMap& PropertyOwner::GetUniformMap() const return mUniformMaps; } -void PropertyOwner::AddUniformMapObserver(UniformMap::Observer& observer) -{ - mUniformMaps.AddObserver(observer); -} - -void PropertyOwner::RemoveUniformMapObserver(UniformMap::Observer& observer) -{ - mUniformMaps.RemoveObserver(observer); -} - } // namespace SceneGraph } // namespace Internal diff --git a/dali/internal/update/common/property-owner.h b/dali/internal/update/common/property-owner.h index f4329fa..9eb16d0 100644 --- a/dali/internal/update/common/property-owner.h +++ b/dali/internal/update/common/property-owner.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_SCENE_GRAPH_PROPERTY_OWNER_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -212,16 +212,6 @@ public: const UniformMap& GetUniformMap() const; /** - * @copydoc UniformMap::AddUniformMapObserver - */ - void AddUniformMapObserver(UniformMap::Observer& observer); - - /** - * @copydoc UniformMap::RemoveUniformMapObserver - */ - void RemoveUniformMapObserver(UniformMap::Observer& observer); - - /** * Query whether playing an animation is possible or not. * @return true if playing an animation is possible. */ @@ -236,6 +226,14 @@ protected: */ PropertyOwner(); + /** + * Method to inform derived classes when property maps have been modified. + */ + virtual void OnMappingChanged() + { + // Default behaviour is to do nothing + } + private: // Undefined PropertyOwner(const PropertyOwner&); diff --git a/dali/internal/update/common/uniform-map.cpp b/dali/internal/update/common/uniform-map.cpp index 76e6081..cdd979c 100644 --- a/dali/internal/update/common/uniform-map.cpp +++ b/dali/internal/update/common/uniform-map.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -25,43 +25,9 @@ namespace Internal { namespace SceneGraph { -void UniformMap::AddObserver(Observer& observer) -{ - bool foundObserver = false; - for(ObserversIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter) - { - if(*iter == &observer) - { - foundObserver = true; - break; - } - } - if(!foundObserver) - { - mObservers.PushBack(&observer); - } -} - -void UniformMap::RemoveObserver(Observer& observer) -{ - for(ObserversIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter) - { - if(*iter == &observer) - { - mObservers.Erase(iter); - return; - } - } -} - void UniformMap::MappingChanged() { ++mChangeCounter; - for(ObserversIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter) - { - Observer* observer = (*iter); - observer->UniformMappingsChanged(*this); - } } void UniformMap::Add(UniformPropertyMapping newMap) diff --git a/dali/internal/update/common/uniform-map.h b/dali/internal/update/common/uniform-map.h index f625169..015d582 100644 --- a/dali/internal/update/common/uniform-map.h +++ b/dali/internal/update/common/uniform-map.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_SCENE_GRAPH_UNIFORM_MAP_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -86,39 +86,13 @@ public: * The UniformMap class is used to map uniform names to property values. It is available * in the following rendering classes: Node, Renderer, Shader. * - * It can be observed for changes to the mapping table. + * They can test the ChangeCounter to see if the mapping has been updated. */ class UniformMap { public: using SizeType = uint32_t; - class Observer - { - public: - /** - * Inform observer that uniform mappings have been changed - * @param mappings - */ - virtual void UniformMappingsChanged(const UniformMap& mappings) = 0; - - protected: - /** - * Virtual destructor, no deletion through this interface - */ - virtual ~Observer() = default; - }; - - /** - * Add an observer that watches for changes in the mappings - */ - void AddObserver(Observer& observer); - - /** - * Remove an observer - */ - void RemoveObserver(Observer& observer); - /** * Add a map to the mappings table. */ @@ -165,11 +139,8 @@ private: private: using UniformMapContainer = Dali::Vector; using UniformMapIter = UniformMapContainer::Iterator; - using Observers = Dali::Vector; - using ObserversIter = Observers::Iterator; - UniformMapContainer mUniformMaps; ///< container of uniform maps - Observers mObservers; + UniformMapContainer mUniformMaps; ///< container of uniform maps std::size_t mChangeCounter{0u}; ///< Counter that is incremented when the map changes }; diff --git a/dali/internal/update/render-tasks/scene-graph-render-task-list.cpp b/dali/internal/update/render-tasks/scene-graph-render-task-list.cpp index 03c39fd..edbbe4a 100644 --- a/dali/internal/update/render-tasks/scene-graph-render-task-list.cpp +++ b/dali/internal/update/render-tasks/scene-graph-render-task-list.cpp @@ -41,7 +41,8 @@ RenderTaskList* RenderTaskList::New() RenderTaskList::RenderTaskList() : mNotificationObject(nullptr), - mRenderMessageDispatcher(nullptr) + mRenderMessageDispatcher(nullptr), + mOverlayRenderTask(nullptr) { } @@ -63,8 +64,21 @@ void RenderTaskList::AddTask(OwnerPointer& newTask) DALI_ASSERT_DEBUG(mRenderMessageDispatcher != NULL && "RenderMessageDispatcher is null"); newTask->Initialize(*mRenderMessageDispatcher); - // mRenderTasks container takes ownership - mRenderTasks.PushBack(newTask.Release()); + + if(mOverlayRenderTask && mRenderTasks[mRenderTasks.Size() - 1] == mOverlayRenderTask) + { + mRenderTasks.Insert(mRenderTasks.End() - 1, newTask.Release()); + } + else + { + mRenderTasks.PushBack(newTask.Release()); + } +} + +void RenderTaskList::AddOverlayTask(OwnerPointer& newTask) +{ + AddTask(newTask); + mOverlayRenderTask = mRenderTasks[mRenderTasks.Size() - 1]; } void RenderTaskList::RemoveTask(RenderTask* task) diff --git a/dali/internal/update/render-tasks/scene-graph-render-task-list.h b/dali/internal/update/render-tasks/scene-graph-render-task-list.h index 84058fc..2b7242d 100644 --- a/dali/internal/update/render-tasks/scene-graph-render-task-list.h +++ b/dali/internal/update/render-tasks/scene-graph-render-task-list.h @@ -73,6 +73,12 @@ public: void AddTask(OwnerPointer& newTask); /** + * Add a overlay RenderTask to the list. + * @param[in] newTask The RenderTaskList takes ownership of this overlay task. + */ + void AddOverlayTask(OwnerPointer& newTask); + + /** * Remove a RenderTask from the list. * @param[in] task The RenderTaskList will destroy this task. */ @@ -129,6 +135,7 @@ private: CompleteNotificationInterface* mNotificationObject; ///< object to pass in to the complete notification RenderMessageDispatcher* mRenderMessageDispatcher; ///< for sending messages to render thread RenderTaskContainer mRenderTasks; ///< A container of owned RenderTasks + RenderTask* mOverlayRenderTask; ///< OverlayRenderTask. }; // Messages for RenderTaskList diff --git a/dali/internal/update/rendering/scene-graph-renderer.cpp b/dali/internal/update/rendering/scene-graph-renderer.cpp index 1550a98..8c0d502 100644 --- a/dali/internal/update/rendering/scene-graph-renderer.cpp +++ b/dali/internal/update/rendering/scene-graph-renderer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -108,17 +108,10 @@ Renderer::Renderer() mOpacity(1.0f), mDepthIndex(0) { - // Observe our own PropertyOwner's uniform map. - AddUniformMapObserver(*this); } Renderer::~Renderer() { - if(mShader) - { - mShader->RemoveUniformMapObserver(*this); - mShader = nullptr; - } } void Renderer::operator delete(void* ptr) @@ -128,14 +121,23 @@ void Renderer::operator delete(void* ptr) bool Renderer::PrepareRender(BufferIndex updateBufferIndex) { - bool rendererUpdated = mResendFlag || mRenderingBehavior == DevelRenderer::Rendering::CONTINUOUSLY || mUpdateDecay > 0; + bool rendererUpdated = mResendFlag || mRenderingBehavior == DevelRenderer::Rendering::CONTINUOUSLY || mUpdateDecay > 0; + auto shaderMapChangeCounter = mShader ? mShader->GetUniformMap().GetChangeCounter() : 0u; + bool shaderMapChanged = mShader && (mShaderMapChangeCounter != shaderMapChangeCounter); + if(shaderMapChanged) + { + mShaderMapChangeCounter = shaderMapChangeCounter; + } - if(mUniformMapChangeCounter != mUniformMaps.GetChangeCounter()) + if(mUniformMapChangeCounter != mUniformMaps.GetChangeCounter() || shaderMapChanged) { // The map has changed since the last time we checked. - rendererUpdated = true; - mRegenerateUniformMap = true; - mUpdateDecay = Renderer::Decay::INITIAL; // Render at least twice if the map has changed/actor has been added + rendererUpdated = true; + mRegenerateUniformMap = true; + mUpdateDecay = Renderer::Decay::INITIAL; // Render at least twice if the map has changed/actor has been added + + // Update local counters to identify any future changes to maps + // (unlikely, but allowed by API). mUniformMapChangeCounter = mUniformMaps.GetChangeCounter(); } if(mUpdateDecay > 0) @@ -327,14 +329,9 @@ void Renderer::SetShader(Shader* shader) { DALI_ASSERT_DEBUG(shader != NULL && "Shader pointer is NULL"); - if(mShader) - { - mShader->RemoveUniformMapObserver(*this); - } - - mShader = shader; - mShader->AddUniformMapObserver(*this); - mRegenerateUniformMap = true; + mShader = shader; + mShaderMapChangeCounter = 0u; + mRegenerateUniformMap = true; mResendFlag |= RESEND_GEOMETRY | RESEND_SHADER; mDirtyFlag = true; } @@ -713,6 +710,7 @@ void Renderer::UpdateUniformMap(BufferIndex updateBufferIndex) localMap.AddMappings(mShader->GetUniformMap()); } localMap.UpdateChangeCounter(); + mRegenerateUniformMap = false; SetUpdated(true); } @@ -756,9 +754,9 @@ uint32_t Renderer::GetMemoryPoolCapacity() return gRendererMemoryPool.GetCapacity(); } -void Renderer::UniformMappingsChanged(const UniformMap& mappings) +void Renderer::OnMappingChanged() { - // The mappings are either from PropertyOwner base class, or the Shader + // Properties have been registered on the base class. mRegenerateUniformMap = true; // Should remain true until this renderer is added to a RenderList. } diff --git a/dali/internal/update/rendering/scene-graph-renderer.h b/dali/internal/update/rendering/scene-graph-renderer.h index 22ae4e8..49cd12b 100644 --- a/dali/internal/update/rendering/scene-graph-renderer.h +++ b/dali/internal/update/rendering/scene-graph-renderer.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_SCENE_GRAPH_RENDERER_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -140,8 +140,7 @@ struct AnimatableDecoratedVisualProperties class Renderer : public PropertyOwner, public UniformMapDataProvider, - public RenderDataProvider, - public UniformMap::Observer + public RenderDataProvider { public: enum OpacityType @@ -527,11 +526,11 @@ public: */ static uint32_t GetMemoryPoolCapacity(); -public: // UniformMap::Observer +public: // PropertyOwner::MappingChanged /** - * @copydoc UniformMap::Observer::UniformMappingsChanged + * @copydoc PropertyOwner::OnMappingChanged */ - void UniformMappingsChanged(const UniformMap& mappings) override; + void OnMappingChanged() override; public: // PropertyOwner implementation /** @@ -590,12 +589,13 @@ private: Dali::Internal::Render::Renderer::StencilParameters mStencilParameters; ///< Struct containing all stencil related options - uint64_t mUniformsHash{0}; ///< Hash of uniform map property values - uint32_t mIndexedDrawFirstElement; ///< first element index to be drawn using indexed draw - uint32_t mIndexedDrawElementsCount; ///< number of elements to be drawn using indexed draw - uint32_t mBlendBitmask; ///< The bitmask of blending options - uint32_t mResendFlag; ///< Indicate whether data should be resent to the renderer - uint32_t mUniformMapChangeCounter{0u}; ///< Value to check if uniform data should be updated + uint64_t mUniformsHash{0}; ///< Hash of uniform map property values + uint32_t mIndexedDrawFirstElement; ///< first element index to be drawn using indexed draw + uint32_t mIndexedDrawElementsCount; ///< number of elements to be drawn using indexed draw + uint32_t mBlendBitmask; ///< The bitmask of blending options + uint32_t mResendFlag; ///< Indicate whether data should be resent to the renderer + UniformMap::SizeType mUniformMapChangeCounter{0u}; ///< Value to check if uniform data should be updated + UniformMap::SizeType mShaderMapChangeCounter{0u}; ///< Value to check if uniform data should be updated DepthFunction::Type mDepthFunction : 4; ///< Local copy of the depth function FaceCullingMode::Type mFaceCullingMode : 3; ///< Local copy of the mode of face culling diff --git a/dali/public-api/dali-core-version.cpp b/dali/public-api/dali-core-version.cpp index 0adf42e..53c4e01 100644 --- a/dali/public-api/dali-core-version.cpp +++ b/dali/public-api/dali-core-version.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 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. @@ -27,7 +27,7 @@ namespace Dali { const uint32_t CORE_MAJOR_VERSION = 2; const uint32_t CORE_MINOR_VERSION = 2; -const uint32_t CORE_MICRO_VERSION = 8; +const uint32_t CORE_MICRO_VERSION = 9; const char* const CORE_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/dali/public-api/render-tasks/render-task-list.cpp b/dali/public-api/render-tasks/render-task-list.cpp index eabd958..941c6e7 100644 --- a/dali/public-api/render-tasks/render-task-list.cpp +++ b/dali/public-api/render-tasks/render-task-list.cpp @@ -63,6 +63,11 @@ RenderTask RenderTaskList::GetTask(uint32_t index) const return RenderTask(GetImplementation(*this).GetTask(index).Get()); } +RenderTask RenderTaskList::GetOverlayTask() const +{ + return RenderTask(GetImplementation(*this).GetOverlayTask().Get()); +} + RenderTaskList::RenderTaskList(Internal::RenderTaskList* internal) : BaseHandle(internal) { diff --git a/dali/public-api/render-tasks/render-task-list.h b/dali/public-api/render-tasks/render-task-list.h index ad33f96..0de427c 100644 --- a/dali/public-api/render-tasks/render-task-list.h +++ b/dali/public-api/render-tasks/render-task-list.h @@ -144,6 +144,14 @@ public: */ RenderTask GetTask(uint32_t index) const; + /** + * @brief Retrieves a RenderTask for Overlay + * @SINCE_2_2.10 + * @return A handle to the overlay RenderTask. + * If the scene has not created an overlay render task, this returns empty handle. + */ + RenderTask GetOverlayTask() const; + public: // Not intended for application developers /// @cond internal /** diff --git a/packaging/dali.spec b/packaging/dali.spec index 6a7f0de..251d3a8 100644 --- a/packaging/dali.spec +++ b/packaging/dali.spec @@ -1,6 +1,6 @@ Name: dali2 Summary: DALi 3D Engine -Version: 2.2.8 +Version: 2.2.9 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT