[dali_2.3.25] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / update / common / scene-graph-scene.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 // CLASS HEADER
18 #include <dali/internal/update/common/scene-graph-scene.h>
19
20 // INTERNAL INCLUDES
21 #include <dali/integration-api/core-enumerations.h>
22 #include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
23
24 namespace Dali
25 {
26 namespace Internal
27 {
28 namespace SceneGraph
29 {
30 Scene::Scene()
31 : mFrameRenderedCallbacks(),
32   mFramePresentedCallbacks(),
33   mSurfaceRect(),
34   mSurfaceOrientation(0),
35   mScreenOrientation(0),
36   mSurfaceRectChangedCount(0u),
37   mRotationCompletedAcknowledgement(false),
38   mSkipRendering(false),
39   mNeedFullUpdate(false),
40   mPartialUpdateEnabled(true)
41 {
42 }
43
44 Scene::~Scene()
45 {
46   mFrameRenderedCallbacks.clear();
47   mFramePresentedCallbacks.clear();
48 }
49
50 void Scene::Initialize(Graphics::Controller& graphicsController, Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable)
51 {
52   mGraphicsController = &graphicsController;
53
54   // Create the render target for the surface. It should already have been sent via message.
55   mRenderTarget = graphicsController.CreateRenderTarget(mRenderTargetCreateInfo, std::move(mRenderTarget));
56
57   // Create the render pass for the surface
58   std::vector<Graphics::AttachmentDescription> attachmentDescriptions;
59
60   // Default behaviour for color attachments is to CLEAR and STORE
61   mClearValues.clear();
62   mClearValues.emplace_back();
63
64   // Assume single color attachment
65   Graphics::AttachmentDescription desc{};
66   desc.SetLoadOp(Graphics::AttachmentLoadOp::CLEAR);
67   desc.SetStoreOp(Graphics::AttachmentStoreOp::STORE);
68   attachmentDescriptions.push_back(desc);
69
70   if(depthBufferAvailable == Integration::DepthBufferAvailable::TRUE ||
71      stencilBufferAvailable == Integration::StencilBufferAvailable::TRUE)
72   {
73     // Depth
74     desc.SetLoadOp(Graphics::AttachmentLoadOp::CLEAR);
75     desc.SetStoreOp(Graphics::AttachmentStoreOp::STORE);
76
77     // Stencil
78     desc.SetStencilLoadOp(Graphics::AttachmentLoadOp::CLEAR);
79     desc.SetStencilStoreOp(Graphics::AttachmentStoreOp::STORE);
80     attachmentDescriptions.push_back(desc);
81
82     mClearValues.emplace_back();
83     mClearValues.back().depthStencil.depth   = 0;
84     mClearValues.back().depthStencil.stencil = 0;
85   }
86
87   Graphics::RenderPassCreateInfo rpInfo{};
88   rpInfo.SetAttachments(attachmentDescriptions);
89
90   // Add default render pass (loadOp = clear)
91   mRenderPass = graphicsController.CreateRenderPass(rpInfo, nullptr); // Warning: Shallow ptr
92
93   desc.SetLoadOp(Graphics::AttachmentLoadOp::LOAD);
94   attachmentDescriptions[0] = desc;
95   if(attachmentDescriptions.size() > 1)
96   {
97     desc.SetLoadOp(Graphics::AttachmentLoadOp::LOAD);
98     desc.SetStencilLoadOp(Graphics::AttachmentLoadOp::LOAD);
99     attachmentDescriptions.back() = desc;
100   }
101
102   mRenderPassNoClear = graphicsController.CreateRenderPass(rpInfo, nullptr); // Warning: Shallow ptr
103 }
104
105 RenderInstructionContainer& Scene::GetRenderInstructions()
106 {
107   return mInstructions;
108 }
109
110 void Scene::AddFrameRenderedCallback(CallbackBase* callback, int32_t frameId)
111 {
112   mFrameRenderedCallbacks.push_back(std::make_pair(std::unique_ptr<CallbackBase>(callback), frameId));
113 }
114
115 void Scene::AddFramePresentedCallback(CallbackBase* callback, int32_t frameId)
116 {
117   mFramePresentedCallbacks.push_back(std::make_pair(std::unique_ptr<CallbackBase>(callback), frameId));
118 }
119
120 void Scene::GetFrameRenderedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks)
121 {
122   // Transfer owership of the callbacks
123   for(auto&& iter : mFrameRenderedCallbacks)
124   {
125     callbacks.push_back(std::make_pair(std::move(iter.first), iter.second));
126   }
127
128   mFrameRenderedCallbacks.clear();
129 }
130
131 void Scene::GetFramePresentedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks)
132 {
133   // Transfer owership of the callbacks
134   for(auto&& iter : mFramePresentedCallbacks)
135   {
136     callbacks.push_back(std::make_pair(std::move(iter.first), iter.second));
137   }
138
139   mFramePresentedCallbacks.clear();
140 }
141
142 void Scene::SetSkipRendering(bool skip)
143 {
144   mSkipRendering = skip;
145 }
146
147 bool Scene::IsRenderingSkipped() const
148 {
149   return mSkipRendering;
150 }
151
152 void Scene::SetSurfaceRect(const Rect<int32_t>& rect)
153 {
154   DALI_LOG_RELEASE_INFO("update surfce rect in scene-graph, from width[%d], height[%d], to width[%d], height[%d]. Changed count [%d]\n", mSurfaceRect.width, mSurfaceRect.height, rect.width, rect.height, mSurfaceRectChangedCount + 1u);
155
156   mSurfaceRect = rect;
157   ++mSurfaceRectChangedCount;
158
159   if(mRoot)
160   {
161     mRoot->SetUpdated(true);
162   }
163 }
164
165 const Rect<int32_t>& Scene::GetSurfaceRect() const
166 {
167   return mSurfaceRect;
168 }
169
170 uint32_t Scene::GetSurfaceRectChangedCount()
171 {
172   uint32_t surfaceRectChangedCount = mSurfaceRectChangedCount;
173   mSurfaceRectChangedCount         = 0u;
174
175   return surfaceRectChangedCount;
176 }
177
178 void Scene::SetSurfaceOrientations(int32_t windowOrientation, int32_t screenOrienation)
179 {
180   DALI_LOG_RELEASE_INFO("update orientation in scene-graph, from surface [%d], screen[%d], to surface [%d], screen[%d]\n", mSurfaceOrientation, mScreenOrientation, windowOrientation, screenOrienation);
181
182   mSurfaceOrientation = windowOrientation;
183   mScreenOrientation  = screenOrienation;
184
185   if(mRoot)
186   {
187     mRoot->SetUpdated(true);
188   }
189 }
190
191 int32_t Scene::GetSurfaceOrientation() const
192 {
193   return mSurfaceOrientation;
194 }
195
196 int32_t Scene::GetScreenOrientation() const
197 {
198   return mScreenOrientation;
199 }
200
201 void Scene::SetRotationCompletedAcknowledgement()
202 {
203   mRotationCompletedAcknowledgement = true;
204 }
205
206 bool Scene::IsRotationCompletedAcknowledgementSet()
207 {
208   bool setRotationCompletedAcknowledgement = mRotationCompletedAcknowledgement;
209   mRotationCompletedAcknowledgement        = false;
210   return setRotationCompletedAcknowledgement;
211 }
212
213 Scene::ItemsDirtyRectsContainer& Scene::GetItemsDirtyRects()
214 {
215   return mItemsDirtyRects;
216 }
217
218 void Scene::SetSurfaceRenderTargetCreateInfo(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo)
219 {
220   if(mRenderTarget != nullptr &&
221      mRenderTargetCreateInfo.surface != renderTargetCreateInfo.surface)
222   {
223     // Only recreate if the surface has changed.
224     mRenderTargetCreateInfo = renderTargetCreateInfo;
225     if(mGraphicsController) // shouldn't be null, as we can't have already set mRenderTarget unless graphics controller exists.
226     {
227       mRenderTarget = mGraphicsController->CreateRenderTarget(renderTargetCreateInfo, std::move(mRenderTarget));
228     }
229   }
230   else
231   {
232     // 2nd Stage initialization happens in RenderManager, not UpdateManager, so is delayed.
233     mRenderTargetCreateInfo = renderTargetCreateInfo;
234   }
235 }
236
237 void Scene::KeepRendering(float durationSeconds)
238 {
239   mKeepRenderingSeconds = std::max(mKeepRenderingSeconds, durationSeconds);
240 }
241
242 bool Scene::KeepRenderingCheck(float elapsedSeconds)
243 {
244   if(mKeepRenderingSeconds > 0.0f)
245   {
246     mNeedFullUpdate       = true; // Full update if KeepRendering is required
247     mKeepRenderingSeconds = std::max(0.0f, mKeepRenderingSeconds - elapsedSeconds);
248     return true;
249   }
250
251   mNeedFullUpdate       = false;
252   mKeepRenderingSeconds = 0.0f;
253   return false;
254 }
255
256 void Scene::SetPartialUpdateEnabled(bool enabled)
257 {
258   mPartialUpdateEnabled = enabled;
259 }
260
261 bool Scene::IsPartialUpdateEnabled() const
262 {
263   return mPartialUpdateEnabled;
264 }
265
266 } // namespace SceneGraph
267
268 } // namespace Internal
269
270 } // namespace Dali