2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/event/common/scene-impl.h>
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>
38 using Dali::Internal::SceneGraph::Node;
44 ScenePtr Scene::New(Size size, int32_t windowOrientation, int32_t screenOrientation)
46 ScenePtr scene = new Scene;
48 // Second-phase construction
49 scene->Initialize(size, windowOrientation, screenOrientation);
55 : mSceneObject(nullptr),
56 mSize(), // Don't set the proper value here, this will be set when the surface is set later
58 mBackgroundColor(DEFAULT_BACKGROUND_COLOR),
59 mDepthTreeDirty(false),
60 mPartialUpdateEnabled(true),
61 mGeometryHittest(false),
62 mEventProcessor(*this, ThreadLocalStorage::GetInternal()->GetGestureEventProcessor()),
63 mSurfaceOrientation(0),
64 mScreenOrientation(0),
73 // its enough to release the handle so the object is released
74 // don't need to remove it from root actor as root actor will delete the object
75 mDefaultCamera.Reset();
80 // we are closing down so just delete the root, no point emit disconnect
81 // signals or send messages to update
87 mOverlayLayer.Reset();
92 mRenderTaskList.Reset();
95 // No need to discard this Scene from Core, as Core stores an intrusive_ptr to this scene
96 // When this destructor is called, the scene has either already been removed from Core or Core has already been destroyed
99 void Scene::Initialize(Size size, int32_t windowOrientation, int32_t screenOrientation)
101 ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
103 DALI_ASSERT_ALWAYS(tls && "Attempt to create scene before core exists!");
107 SceneGraph::UpdateManager& updateManager = tls->GetUpdateManager();
109 // Create the ordered list of layers
110 mLayerList = LayerList::New(updateManager);
112 // The scene owns the default layer
113 mRootLayer = Layer::NewRoot(*mLayerList);
114 mRootLayer->SetName("RootLayer");
115 mRootLayer->SetScene(*this);
117 // The root layer needs to have a fixed resize policy (as opposed to the default USE_NATURAL_SIZE).
118 // This stops actors parented to the stage having their relayout requests propagating
119 // up to the root layer, and down through other children unnecessarily.
120 mRootLayer->SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
122 // Create the default camera actor first; this is needed by the RenderTaskList
123 // The default camera attributes and position is such that children of the default layer,
124 // can be positioned at (0,0) and be at the top-left of the viewport.
125 mDefaultCamera = CameraActor::New(size);
126 mDefaultCamera->SetParentOrigin(ParentOrigin::CENTER);
127 Add(*(mDefaultCamera.Get()));
129 // Create the list of render-tasks
130 mRenderTaskList = RenderTaskList::New();
132 // Create the default render-task and ensure clear is enabled on it to show the background color
133 RenderTaskPtr renderTask = mRenderTaskList->CreateTask(mRootLayer.Get(), mDefaultCamera.Get());
134 renderTask->SetClearEnabled(true);
136 // Create scene graph object
137 mSceneObject = new SceneGraph::Scene();
138 OwnerPointer<SceneGraph::Scene> transferOwnership(const_cast<SceneGraph::Scene*>(mSceneObject));
139 AddSceneMessage(updateManager, transferOwnership);
141 SurfaceRotated(size.width, size.height, windowOrientation, screenOrientation);
144 void Scene::Add(Actor& actor)
146 mRootLayer->Add(actor);
149 void Scene::Remove(Actor& actor)
151 mRootLayer->Remove(actor);
154 Size Scene::GetSize() const
159 void Scene::SetDpi(Vector2 dpi)
164 Vector2 Scene::GetDpi() const
169 RenderTaskList& Scene::GetRenderTaskList() const
171 return *mRenderTaskList;
174 Dali::Layer Scene::GetRootLayer() const
176 return Dali::Layer(mRootLayer.Get());
179 Dali::Layer Scene::GetOverlayLayer()
183 // Creates overlay layer.
184 mOverlayLayer = Layer::New();
185 mOverlayLayer->SetName("OverlayLayer");
186 mOverlayLayer->SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
187 mOverlayLayer->SetParentOrigin(Dali::ParentOrigin::TOP_LEFT);
188 mOverlayLayer->SetAnchorPoint(Dali::AnchorPoint::TOP_LEFT);
189 mRootLayer->Add(*mOverlayLayer);
191 // Create the overlay render-task and set exclusive to true.
192 RenderTaskPtr renderTask = mRenderTaskList->CreateOverlayTask(mOverlayLayer.Get(), mDefaultCamera.Get());
193 renderTask->SetExclusive(true);
194 renderTask->SetInputEnabled(true);
196 return Dali::Layer(mOverlayLayer.Get());
199 LayerList& Scene::GetLayerList() const
204 uint32_t Scene::GetLayerCount() const
206 return mLayerList->GetLayerCount();
209 Dali::Layer Scene::GetLayer(uint32_t depth) const
211 return Dali::Layer(mLayerList->GetLayer(depth));
214 CameraActor& Scene::GetDefaultCameraActor() const
216 return *mDefaultCamera;
219 Actor& Scene::GetDefaultRootActor()
224 void Scene::SurfaceResized(float width, float height)
226 if((fabsf(mSize.width - width) > Math::MACHINE_EPSILON_1) || (fabsf(mSize.height - height) > Math::MACHINE_EPSILON_1))
228 ChangedSurface(width, height, mSurfaceOrientation, mScreenOrientation);
232 void Scene::SurfaceReplaced()
236 ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
237 SurfaceReplacedMessage(tls->GetUpdateManager(), *mSceneObject);
241 void Scene::RemoveSceneObject()
243 if(EventThreadServices::IsCoreRunning() && mSceneObject)
245 ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
246 RemoveSceneMessage(tls->GetUpdateManager(), *mSceneObject);
247 mSceneObject = nullptr;
251 void Scene::Discard()
253 if(EventThreadServices::IsCoreRunning())
255 ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
256 tls->RemoveScene(this);
260 void Scene::RequestRebuildDepthTree()
262 mDepthTreeDirty = true;
265 void Scene::QueueEvent(const Integration::Event& event)
267 mEventProcessor.QueueEvent(event);
270 void Scene::ProcessEvents()
272 mEventProcessor.ProcessEvents();
275 void Scene::SendInterruptedEvents(Dali::Internal::Actor* actor)
277 mEventProcessor.SendInterruptedEvents(actor);
280 void Scene::RebuildDepthTree()
282 // If the depth tree needs rebuilding, do it in this frame only.
285 ActorPtr actor(mRootLayer.Get());
286 actor->RebuildDepthTree();
287 mDepthTreeDirty = false;
289 mRenderTaskList->SortTasks();
292 void Scene::SetBackgroundColor(const Vector4& color)
294 mBackgroundColor = color;
296 mRenderTaskList->GetTask(0u)->SetClearColor(color);
297 mRenderTaskList->GetTask(0u)->SetClearEnabled(true);
300 Vector4 Scene::GetBackgroundColor() const
302 return mBackgroundColor;
305 SceneGraph::Scene* Scene::GetSceneObject() const
310 void Scene::EmitKeyEventSignal(const Dali::KeyEvent& event)
312 if(!mKeyEventSignal.Empty())
314 Dali::Integration::Scene handle(this);
315 mKeyEventSignal.Emit(event);
319 void Scene::SurfaceRotated(float width, float height, int32_t windowOrientation, int32_t screenOrientation)
321 ChangedSurface(width, height, windowOrientation, screenOrientation);
324 int32_t Scene::GetCurrentSurfaceOrientation() const
326 return mSceneObject ? mSceneObject->GetSurfaceOrientation() : 0;
329 int32_t Scene::GetCurrentScreenOrientation() const
331 return mSceneObject ? mSceneObject->GetScreenOrientation() : 0;
334 const Rect<int32_t>& Scene::GetCurrentSurfaceRect() const
336 static Rect<int32_t> emptyRect{};
337 return mSceneObject ? mSceneObject->GetSurfaceRect() : emptyRect;
340 void Scene::ChangedSurface(float width, float height, int32_t windowOrientation, int32_t screenOrientation)
342 bool changedOrientation = false;
343 Rect<int32_t> newSize(0, 0, static_cast<int32_t>(width), static_cast<int32_t>(height)); // truncated
345 mSize.height = height;
347 if(mSurfaceOrientation != windowOrientation || mScreenOrientation != screenOrientation)
349 changedOrientation = true;
352 mSurfaceOrientation = windowOrientation;
353 mScreenOrientation = screenOrientation;
355 // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
356 mDefaultCamera->SetPerspectiveProjection(mSize);
357 // Set the surface orientation to Default camera for window/screen rotation
358 if(changedOrientation)
360 int32_t orientation = (windowOrientation + screenOrientation) % 360;
361 mDefaultCamera->RotateProjection(orientation);
364 mRootLayer->SetSize(width, height);
366 // Send the surface rectangle/orientation to SceneGraph::Scene for calculating glViewport/Scissor
367 ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
368 DALI_LOG_RELEASE_INFO("Send Surface Rect Message, width[%d], height[%d]\n", newSize.width, newSize.height);
369 SetSurfaceRectMessage(tls->GetEventThreadServices(), *mSceneObject, newSize);
370 if(changedOrientation)
372 DALI_LOG_RELEASE_INFO("Send Surface Orientation Message, surface orientation[%d], screen orientation[%d]\n", mSurfaceOrientation, mScreenOrientation);
373 SetSurfaceOrientationsMessage(tls->GetEventThreadServices(), *mSceneObject, mSurfaceOrientation, mScreenOrientation);
376 // set default render-task viewport parameters
377 RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask(0u);
378 defaultRenderTask->SetViewport(newSize);
379 // set overlay render-task viewport parameters
380 RenderTaskPtr overlayRenderTask = mRenderTaskList->GetOverlayTask();
381 if(overlayRenderTask)
383 overlayRenderTask->SetViewport(newSize);
387 uint32_t Scene::GetSurfaceRectChangedCount() const
389 return mSceneObject ? mSceneObject->GetSurfaceRectChangedCount() : 0u;
392 bool Scene::IsRotationCompletedAcknowledgementSet() const
394 return mSceneObject ? mSceneObject->IsRotationCompletedAcknowledgementSet() : false;
397 void Scene::SetRotationCompletedAcknowledgement()
399 ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
400 SetRotationCompletedAcknowledgementMessage(tls->GetEventThreadServices(), *mSceneObject);
403 void Scene::SetSurfaceRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo)
405 // Send the surface render target to SceneGraph::Scene
406 ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
407 SetSurfaceRenderTargetCreateInfoMessage(tls->GetEventThreadServices(), *mSceneObject, renderTargetCreateInfo);
410 bool Scene::EmitKeyEventGeneratedSignal(const Dali::KeyEvent& event)
412 // Emit the KeyEventGenerated signal when KeyEvent is generated
413 Dali::Integration::Scene handle(this);
414 return mKeyEventGeneratedSignal.Emit(event);
417 bool Scene::EmitInterceptKeyEventSignal(const Dali::KeyEvent& event)
419 // Emit the InterceptKeyEvent signal
420 Dali::Integration::Scene handle(this);
421 return mInterceptKeyEventSignal.Emit(event);
424 void Scene::EmitEventProcessingFinishedSignal()
426 if(!mEventProcessingFinishedSignal.Empty())
428 Dali::Integration::Scene handle(this);
429 mEventProcessingFinishedSignal.Emit();
433 void Scene::EmitTouchedSignal(const Dali::TouchEvent& touch)
435 Dali::Integration::Scene handle(this);
436 if(!mTouchedSignal.Empty())
438 mTouchedSignal.Emit(touch);
442 void Scene::EmitWheelEventSignal(const Dali::WheelEvent& event)
444 if(!mWheelEventSignal.Empty())
446 Dali::Integration::Scene handle(this);
447 mWheelEventSignal.Emit(event);
451 bool Scene::EmitWheelEventGeneratedSignal(const Dali::WheelEvent& event)
453 // Emit the WheelEventGenerated signal when WheelEvent is generated
454 Dali::Integration::Scene handle(this);
455 return mWheelEventGeneratedSignal.Emit(event);
458 void Scene::AddFrameRenderedCallback(std::unique_ptr<CallbackBase> callback, int32_t frameId)
460 ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
461 AddFrameRenderedCallbackMessage(tls->GetEventThreadServices(), *mSceneObject, callback.release(), frameId);
464 void Scene::AddFramePresentedCallback(std::unique_ptr<CallbackBase> callback, int32_t frameId)
466 ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
467 AddFramePresentedCallbackMessage(tls->GetEventThreadServices(), *mSceneObject, callback.release(), frameId);
470 void Scene::GetFrameRenderedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks)
474 mSceneObject->GetFrameRenderedCallback(callbacks);
478 void Scene::GetFramePresentedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks)
482 mSceneObject->GetFramePresentedCallback(callbacks);
486 void Scene::KeepRendering(float durationSeconds)
488 ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
489 KeepRenderingMessage(tls->GetEventThreadServices(), *mSceneObject, durationSeconds);
492 void Scene::SetPartialUpdateEnabled(bool enabled)
494 mPartialUpdateEnabled = enabled;
496 ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
497 SetPartialUpdateEnabledMessage(tls->GetEventThreadServices(), *mSceneObject, enabled);
500 bool Scene::IsPartialUpdateEnabled() const
502 return mPartialUpdateEnabled;
505 void Scene::SetGeometryHittestEnabled(bool enabled)
507 mGeometryHittest = enabled;
510 bool Scene::IsGeometryHittestEnabled() const
512 return mGeometryHittest;
515 void Scene::SetNativeId(int32_t nativeId)
517 mNativeId = nativeId;
520 int32_t Scene::GetNativeId() const
525 Integration::Scene::KeyEventSignalType& Scene::KeyEventSignal()
527 return mKeyEventSignal;
530 Integration::Scene::KeyEventGeneratedSignalType& Scene::KeyEventGeneratedSignal()
532 return mKeyEventGeneratedSignal;
535 Integration::Scene::KeyEventGeneratedSignalType& Scene::InterceptKeyEventSignal()
537 return mInterceptKeyEventSignal;
540 Integration::Scene::EventProcessingFinishedSignalType& Scene::EventProcessingFinishedSignal()
542 return mEventProcessingFinishedSignal;
545 Integration::Scene::TouchEventSignalType& Scene::TouchedSignal()
547 return mTouchedSignal;
550 Integration::Scene::WheelEventSignalType& Scene::WheelEventSignal()
552 return mWheelEventSignal;
555 Integration::Scene::WheelEventGeneratedSignalType& Scene::WheelEventGeneratedSignal()
557 return mWheelEventGeneratedSignal;
560 } // namespace Internal