30024b63c2c2747425a9c853d1216d73f0ac3a59
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / scene-graph-frame-callback.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/update/manager/scene-graph-frame-callback.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/devel-api/threading/mutex.h>
23 #include <dali/devel-api/update/frame-callback-interface.h>
24 #include <dali/devel-api/update/update-proxy.h>
25 #include <dali/internal/event/update/frame-callback-interface-impl.h>
26
27 namespace Dali
28 {
29 namespace Internal
30 {
31 namespace SceneGraph
32 {
33 FrameCallback* FrameCallback::New(FrameCallbackInterface& frameCallbackInterface)
34 {
35   return new FrameCallback(&frameCallbackInterface);
36 }
37
38 FrameCallback::~FrameCallback()
39 {
40   if(mUpdateProxy)
41   {
42     mUpdateProxy->GetRootNode().RemoveObserver(*this);
43     mUpdateProxy->AddNodeResetters();
44   }
45
46   Invalidate();
47 }
48
49 void FrameCallback::ConnectToSceneGraph(UpdateManager& updateManager, TransformManager& transformManager, Node& rootNode, SceneGraphTravelerPtr traveler)
50 {
51   mUpdateProxy = std::unique_ptr<UpdateProxy>(new UpdateProxy(updateManager, transformManager, rootNode, traveler));
52   rootNode.AddObserver(*this);
53 }
54
55 FrameCallback::RequestFlags FrameCallback::Update(BufferIndex bufferIndex, float elapsedSeconds, bool nodeHierarchyChanged)
56 {
57   bool continueCalling = false;
58   bool keepRendering   = false;
59
60   if(mUpdateProxy)
61   {
62     mUpdateProxy->SetCurrentBufferIndex(bufferIndex);
63
64     while(!mSyncPoints.empty())
65     {
66       mUpdateProxy->Notify(mSyncPoints.front());
67       mSyncPoints.pop_front();
68     }
69
70     if(nodeHierarchyChanged)
71     {
72       mUpdateProxy->NodeHierarchyChanged();
73     }
74
75     Mutex::ScopedLock lock(mMutex);
76     if(mFrameCallbackInterface && mValid)
77     {
78       Dali::UpdateProxy updateProxy(*mUpdateProxy);
79       keepRendering   = mFrameCallbackInterface->Update(updateProxy, elapsedSeconds);
80       continueCalling = true;
81     }
82   }
83
84   return static_cast<FrameCallback::RequestFlags>(continueCalling | (keepRendering << 1));
85 }
86
87 void FrameCallback::Notify(Dali::UpdateProxy::NotifySyncPoint syncPoint)
88 {
89   mSyncPoints.push_back(syncPoint);
90 }
91
92 void FrameCallback::Invalidate()
93 {
94   Mutex::ScopedLock lock(mMutex);
95   if(mFrameCallbackInterface && mValid)
96   {
97     FrameCallbackInterface::Impl::Get(*mFrameCallbackInterface).DisconnectFromSceneGraphObject();
98     mValid = false;
99     // Do not set mFrameCallbackInterface to nullptr as it is used for comparison checks by the comparison operator
100   }
101 }
102
103 void FrameCallback::PropertyOwnerDestroyed(PropertyOwner& owner)
104 {
105   mUpdateProxy.reset(); // Root node is being destroyed so no point keeping the update-proxy either
106
107   Invalidate();
108 }
109
110 FrameCallback::FrameCallback(FrameCallbackInterface* frameCallbackInterface)
111 : mMutex(),
112   mFrameCallbackInterface(frameCallbackInterface)
113 {
114   if(frameCallbackInterface)
115   {
116     FrameCallbackInterface::Impl::Get(*mFrameCallbackInterface).ConnectToSceneGraphObject(*this);
117   }
118 }
119
120 } // namespace SceneGraph
121
122 } // namespace Internal
123
124 } // namespace Dali