Fix surface deletion order issue
[platform/core/uifw/dali-core.git] / dali / internal / event / common / scene-impl.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/event/common/scene-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/event/actors/camera-actor-impl.h>
23 #include <dali/internal/event/actors/layer-impl.h>
24 #include <dali/internal/event/actors/layer-list.h>
25 #include <dali/internal/event/common/object-registry-impl.h>
26 #include <dali/internal/event/common/thread-local-storage.h>
27 #include <dali/internal/event/render-tasks/render-task-impl.h>
28 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
29 #include <dali/internal/event/rendering/frame-buffer-impl.h>
30 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
31 #include <dali/internal/update/common/scene-graph-scene.h>
32 #include <dali/internal/update/manager/update-manager.h>
33 #include <dali/internal/update/nodes/node.h>
34 #include <dali/public-api/common/constants.h>
35 #include <dali/public-api/object/type-registry.h>
36 #include <dali/public-api/render-tasks/render-task-list.h>
37
38 using Dali::Internal::SceneGraph::Node;
39
40 namespace Dali
41 {
42 namespace Internal
43 {
44 ScenePtr Scene::New(Size size, int32_t windowOrientation, int32_t screenOrientation)
45 {
46   ScenePtr scene = new Scene;
47
48   // Second-phase construction
49   scene->Initialize(size, windowOrientation, screenOrientation);
50
51   return scene;
52 }
53
54 Scene::Scene()
55 : mSceneObject(nullptr),
56   mSize(), // Don't set the proper value here, this will be set when the surface is set later
57   mDpi(),
58   mBackgroundColor(DEFAULT_BACKGROUND_COLOR),
59   mDepthTreeDirty(false),
60   mEventProcessor(*this, ThreadLocalStorage::GetInternal()->GetGestureEventProcessor()),
61   mSurfaceOrientation(0),
62   mScreenOrientation(0)
63 {
64 }
65
66 Scene::~Scene()
67 {
68   if(mDefaultCamera)
69   {
70     // its enough to release the handle so the object is released
71     // don't need to remove it from root actor as root actor will delete the object
72     mDefaultCamera.Reset();
73   }
74
75   if(mRootLayer)
76   {
77     // we are closing down so just delete the root, no point emit disconnect
78     // signals or send messages to update
79     mRootLayer.Reset();
80   }
81
82   if(mOverlayLayer)
83   {
84     mOverlayLayer.Reset();
85   }
86
87   if(mRenderTaskList)
88   {
89     mRenderTaskList.Reset();
90   }
91
92   // No need to discard this Scene from Core, as Core stores an intrusive_ptr to this scene
93   // When this destructor is called, the scene has either already been removed from Core or Core has already been destroyed
94 }
95
96 void Scene::Initialize(Size size, int32_t windowOrientation, int32_t screenOrientation)
97 {
98   ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
99
100   DALI_ASSERT_ALWAYS(tls && "Attempt to create scene before core exists!");
101
102   tls->AddScene(this);
103
104   SceneGraph::UpdateManager& updateManager = tls->GetUpdateManager();
105
106   // Create the ordered list of layers
107   mLayerList = LayerList::New(updateManager);
108
109   // The scene owns the default layer
110   mRootLayer = Layer::NewRoot(*mLayerList);
111   mRootLayer->SetName("RootLayer");
112   mRootLayer->SetScene(*this);
113
114   // The root layer needs to have a fixed resize policy (as opposed to the default USE_NATURAL_SIZE).
115   // This stops actors parented to the stage having their relayout requests propagating
116   // up to the root layer, and down through other children unnecessarily.
117   mRootLayer->SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
118
119   // Create the default camera actor first; this is needed by the RenderTaskList
120   // The default camera attributes and position is such that children of the default layer,
121   // can be positioned at (0,0) and be at the top-left of the viewport.
122   mDefaultCamera = CameraActor::New(size);
123   mDefaultCamera->SetParentOrigin(ParentOrigin::CENTER);
124   Add(*(mDefaultCamera.Get()));
125
126   // Create the list of render-tasks
127   mRenderTaskList = RenderTaskList::New();
128
129   // Create the default render-task and ensure clear is enabled on it to show the background color
130   RenderTaskPtr renderTask = mRenderTaskList->CreateTask(mRootLayer.Get(), mDefaultCamera.Get());
131   renderTask->SetClearEnabled(true);
132
133   // Create scene graph object
134   mSceneObject = new SceneGraph::Scene();
135   OwnerPointer<SceneGraph::Scene> transferOwnership(const_cast<SceneGraph::Scene*>(mSceneObject));
136   AddSceneMessage(updateManager, transferOwnership);
137
138   SurfaceRotated(size.width, size.height, windowOrientation, screenOrientation);
139 }
140
141 void Scene::Add(Actor& actor)
142 {
143   mRootLayer->Add(actor);
144 }
145
146 void Scene::Remove(Actor& actor)
147 {
148   mRootLayer->Remove(actor);
149 }
150
151 Size Scene::GetSize() const
152 {
153   return mSize;
154 }
155
156 void Scene::SetDpi(Vector2 dpi)
157 {
158   mDpi = dpi;
159 }
160
161 Vector2 Scene::GetDpi() const
162 {
163   return mDpi;
164 }
165
166 RenderTaskList& Scene::GetRenderTaskList() const
167 {
168   return *mRenderTaskList;
169 }
170
171 Dali::Layer Scene::GetRootLayer() const
172 {
173   return Dali::Layer(mRootLayer.Get());
174 }
175
176 Dali::Layer Scene::GetOverlayLayer()
177 {
178   if(!mOverlayLayer)
179   {
180     // Creates overlay layer.
181     mOverlayLayer = Layer::New();
182     mOverlayLayer->SetName("OverlayLayer");
183     mOverlayLayer->SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
184     mOverlayLayer->SetParentOrigin(Dali::ParentOrigin::TOP_LEFT);
185     mOverlayLayer->SetAnchorPoint(Dali::AnchorPoint::TOP_LEFT);
186     mRootLayer->Add(*mOverlayLayer);
187
188     // Create the overlay render-task and set exclusive to true.
189     RenderTaskPtr renderTask = mRenderTaskList->CreateOverlayTask(mOverlayLayer.Get(), mDefaultCamera.Get());
190     renderTask->SetExclusive(true);
191     renderTask->SetInputEnabled(true);
192   }
193   return Dali::Layer(mOverlayLayer.Get());
194 }
195
196 LayerList& Scene::GetLayerList() const
197 {
198   return *mLayerList;
199 }
200
201 uint32_t Scene::GetLayerCount() const
202 {
203   return mLayerList->GetLayerCount();
204 }
205
206 Dali::Layer Scene::GetLayer(uint32_t depth) const
207 {
208   return Dali::Layer(mLayerList->GetLayer(depth));
209 }
210
211 CameraActor& Scene::GetDefaultCameraActor() const
212 {
213   return *mDefaultCamera;
214 }
215
216 Actor& Scene::GetDefaultRootActor()
217 {
218   return *mRootLayer;
219 }
220
221 void Scene::SurfaceResized(float width, float height)
222 {
223   if((fabsf(mSize.width - width) > Math::MACHINE_EPSILON_1) || (fabsf(mSize.height - height) > Math::MACHINE_EPSILON_1))
224   {
225     ChangedSurface(width, height, mSurfaceOrientation, mScreenOrientation);
226   }
227 }
228
229 void Scene::SurfaceReplaced()
230 {
231   if(mSceneObject)
232   {
233     ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
234     SurfaceReplacedMessage(tls->GetUpdateManager(), *mSceneObject);
235   }
236 }
237
238 void Scene::RemoveSceneObject()
239 {
240   if(EventThreadServices::IsCoreRunning() && mSceneObject)
241   {
242     ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
243     RemoveSceneMessage(tls->GetUpdateManager(), *mSceneObject);
244     mSceneObject = nullptr;
245   }
246 }
247
248 void Scene::Discard()
249 {
250   if(EventThreadServices::IsCoreRunning())
251   {
252     ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
253     tls->RemoveScene(this);
254   }
255 }
256
257 void Scene::RequestRebuildDepthTree()
258 {
259   mDepthTreeDirty = true;
260 }
261
262 void Scene::QueueEvent(const Integration::Event& event)
263 {
264   mEventProcessor.QueueEvent(event);
265 }
266
267 void Scene::ProcessEvents()
268 {
269   mEventProcessor.ProcessEvents();
270 }
271
272 void Scene::RebuildDepthTree()
273 {
274   // If the depth tree needs rebuilding, do it in this frame only.
275   if(mDepthTreeDirty)
276   {
277     ActorPtr actor(mRootLayer.Get());
278     actor->RebuildDepthTree();
279     mDepthTreeDirty = false;
280   }
281 }
282
283 void Scene::SetBackgroundColor(const Vector4& color)
284 {
285   mBackgroundColor = color;
286
287   mRenderTaskList->GetTask(0u)->SetClearColor(color);
288   mRenderTaskList->GetTask(0u)->SetClearEnabled(true);
289 }
290
291 Vector4 Scene::GetBackgroundColor() const
292 {
293   return mBackgroundColor;
294 }
295
296 SceneGraph::Scene* Scene::GetSceneObject() const
297 {
298   return mSceneObject;
299 }
300
301 void Scene::EmitKeyEventSignal(const Dali::KeyEvent& event)
302 {
303   if(!mKeyEventSignal.Empty())
304   {
305     Dali::Integration::Scene handle(this);
306     mKeyEventSignal.Emit(event);
307   }
308 }
309
310 void Scene::SurfaceRotated(float width, float height, int32_t windowOrientation, int32_t screenOrientation)
311 {
312   ChangedSurface(width, height, windowOrientation, screenOrientation);
313 }
314
315 int32_t Scene::GetCurrentSurfaceOrientation() const
316 {
317   return mSceneObject ? mSceneObject->GetSurfaceOrientation() : 0;
318 }
319
320 int32_t Scene::GetCurrentScreenOrientation() const
321 {
322   return mSceneObject ? mSceneObject->GetScreenOrientation() : 0;
323 }
324
325 const Rect<int32_t>& Scene::GetCurrentSurfaceRect() const
326 {
327   static Rect<int32_t> emptyRect{};
328   return mSceneObject ? mSceneObject->GetSurfaceRect() : emptyRect;
329 }
330
331 void Scene::ChangedSurface(float width, float height, int32_t windowOrientation, int32_t screenOrientation)
332 {
333   bool          changedOrientation = false;
334   Rect<int32_t> newSize(0, 0, static_cast<int32_t>(width), static_cast<int32_t>(height)); // truncated
335   mSize.width  = width;
336   mSize.height = height;
337
338   if(mSurfaceOrientation != windowOrientation || mScreenOrientation != screenOrientation)
339   {
340     changedOrientation = true;
341   }
342
343   mSurfaceOrientation = windowOrientation;
344   mScreenOrientation  = screenOrientation;
345
346   // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
347   mDefaultCamera->SetPerspectiveProjection(mSize);
348   // Set the surface orientation to Default camera for window/screen rotation
349   if(changedOrientation)
350   {
351     int32_t orientation = (windowOrientation + screenOrientation) % 360;
352     mDefaultCamera->RotateProjection(orientation);
353   }
354
355   mRootLayer->SetSize(width, height);
356
357   // Send the surface rectangle/orientation to SceneGraph::Scene for calculating glViewport/Scissor
358   ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
359   DALI_LOG_RELEASE_INFO("Send Surface Rect Message, width[%d], height[%d]\n", newSize.width, newSize.height);
360   SetSurfaceRectMessage(tls->GetEventThreadServices(), *mSceneObject, newSize);
361   if(changedOrientation)
362   {
363     DALI_LOG_RELEASE_INFO("Send Surface Orientation Message, surface orientation[%d], screen orientation[%d]\n", mSurfaceOrientation, mScreenOrientation);
364     SetSurfaceOrientationsMessage(tls->GetEventThreadServices(), *mSceneObject, mSurfaceOrientation, mScreenOrientation);
365   }
366
367   // set default render-task viewport parameters
368   RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask(0u);
369   defaultRenderTask->SetViewport(newSize);
370   // set overlay render-task viewport parameters
371   RenderTaskPtr overlayRenderTask = mRenderTaskList->GetOverlayTask();
372   if(overlayRenderTask)
373   {
374     overlayRenderTask->SetViewport(newSize);
375   }
376 }
377
378 bool Scene::IsSurfaceRectChanged() const
379 {
380   return mSceneObject ? mSceneObject->IsSurfaceRectChanged() : false;
381 }
382
383 bool Scene::IsRotationCompletedAcknowledgementSet() const
384 {
385   return mSceneObject ? mSceneObject->IsRotationCompletedAcknowledgementSet() : false;
386 }
387
388 void Scene::SetRotationCompletedAcknowledgement()
389 {
390   ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
391   SetRotationCompletedAcknowledgementMessage(tls->GetEventThreadServices(), *mSceneObject);
392 }
393
394 void Scene::SetSurfaceRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo)
395 {
396   // Send the surface render target to SceneGraph::Scene
397   ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
398   SetSurfaceRenderTargetCreateInfoMessage(tls->GetEventThreadServices(), *mSceneObject, renderTargetCreateInfo);
399 }
400
401 bool Scene::EmitKeyEventGeneratedSignal(const Dali::KeyEvent& event)
402 {
403   // Emit the KeyEventGenerated signal when KeyEvent is generated
404   Dali::Integration::Scene handle(this);
405   return mKeyEventGeneratedSignal.Emit(event);
406 }
407
408 bool Scene::EmitInterceptKeyEventSignal(const Dali::KeyEvent& event)
409 {
410   // Emit the InterceptKeyEvent signal
411   Dali::Integration::Scene handle(this);
412   return mInterceptKeyEventSignal.Emit(event);
413 }
414
415 void Scene::EmitEventProcessingFinishedSignal()
416 {
417   if(!mEventProcessingFinishedSignal.Empty())
418   {
419     Dali::Integration::Scene handle(this);
420     mEventProcessingFinishedSignal.Emit();
421   }
422 }
423
424 void Scene::EmitTouchedSignal(const Dali::TouchEvent& touch)
425 {
426   Dali::Integration::Scene handle(this);
427   if(!mTouchedSignal.Empty())
428   {
429     mTouchedSignal.Emit(touch);
430   }
431 }
432
433 void Scene::EmitWheelEventSignal(const Dali::WheelEvent& event)
434 {
435   if(!mWheelEventSignal.Empty())
436   {
437     Dali::Integration::Scene handle(this);
438     mWheelEventSignal.Emit(event);
439   }
440 }
441
442 bool Scene::EmitWheelEventGeneratedSignal(const Dali::WheelEvent& event)
443 {
444   // Emit the WheelEventGenerated signal when WheelEvent is generated
445   Dali::Integration::Scene handle(this);
446   return mWheelEventGeneratedSignal.Emit(event);
447 }
448
449 void Scene::AddFrameRenderedCallback(std::unique_ptr<CallbackBase> callback, int32_t frameId)
450 {
451   ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
452   AddFrameRenderedCallbackMessage(tls->GetEventThreadServices(), *mSceneObject, callback.release(), frameId);
453 }
454
455 void Scene::AddFramePresentedCallback(std::unique_ptr<CallbackBase> callback, int32_t frameId)
456 {
457   ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
458   AddFramePresentedCallbackMessage(tls->GetEventThreadServices(), *mSceneObject, callback.release(), frameId);
459 }
460
461 void Scene::GetFrameRenderedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks)
462 {
463   if(mSceneObject)
464   {
465     mSceneObject->GetFrameRenderedCallback(callbacks);
466   }
467 }
468
469 void Scene::GetFramePresentedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks)
470 {
471   if(mSceneObject)
472   {
473     mSceneObject->GetFramePresentedCallback(callbacks);
474   }
475 }
476
477 Integration::Scene::KeyEventSignalType& Scene::KeyEventSignal()
478 {
479   return mKeyEventSignal;
480 }
481
482 Integration::Scene::KeyEventGeneratedSignalType& Scene::KeyEventGeneratedSignal()
483 {
484   return mKeyEventGeneratedSignal;
485 }
486
487 Integration::Scene::KeyEventGeneratedSignalType& Scene::InterceptKeyEventSignal()
488 {
489   return mInterceptKeyEventSignal;
490 }
491
492 Integration::Scene::EventProcessingFinishedSignalType& Scene::EventProcessingFinishedSignal()
493 {
494   return mEventProcessingFinishedSignal;
495 }
496
497 Integration::Scene::TouchEventSignalType& Scene::TouchedSignal()
498 {
499   return mTouchedSignal;
500 }
501
502 Integration::Scene::WheelEventSignalType& Scene::WheelEventSignal()
503 {
504   return mWheelEventSignal;
505 }
506
507 Integration::Scene::WheelEventGeneratedSignalType& Scene::WheelEventGeneratedSignal()
508 {
509   return mWheelEventGeneratedSignal;
510 }
511
512 } // namespace Internal
513
514 } // namespace Dali