DALi Version 2.2.14
[platform/core/uifw/dali-core.git] / dali / internal / event / render-tasks / render-task-impl.cpp
1 /*
2  * Copyright (c) 2022 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/render-tasks/render-task-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <cstring> // for strcmp
23
24 // INTERNAL INCLUDES
25 #include <dali/internal/event/actors/actor-impl.h>
26 #include <dali/internal/event/actors/camera-actor-impl.h>
27 #include <dali/internal/event/common/event-thread-services.h>
28 #include <dali/internal/event/common/projection.h>
29 #include <dali/internal/event/common/property-helper.h>
30 #include <dali/internal/event/common/scene-impl.h>
31 #include <dali/internal/event/common/stage-impl.h>
32 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
33 #include <dali/internal/update/nodes/node.h>
34 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
35 #include <dali/public-api/common/dali-common.h>
36 #include <dali/public-api/object/type-registry.h>
37
38 #if defined(DEBUG_ENABLED)
39 namespace
40 {
41 Debug::Filter* gLogRender = Debug::Filter::New(Debug::Concise, false, "LOG_RENDER_TASK");
42 }
43 #endif
44
45 namespace Dali
46 {
47 namespace Internal
48 {
49 namespace // For internal properties
50 {
51 // Properties
52
53 //              Name                 Type     writable animatable constraint-input  enum for index-checking
54 DALI_PROPERTY_TABLE_BEGIN
55 DALI_PROPERTY("viewportPosition", VECTOR2, true, true, true, Dali::RenderTask::Property::VIEWPORT_POSITION)
56 DALI_PROPERTY("viewportSize", VECTOR2, true, true, true, Dali::RenderTask::Property::VIEWPORT_SIZE)
57 DALI_PROPERTY("clearColor", VECTOR4, true, true, true, Dali::RenderTask::Property::CLEAR_COLOR)
58 DALI_PROPERTY("requiresSync", BOOLEAN, true, false, false, Dali::RenderTask::Property::REQUIRES_SYNC)
59 DALI_PROPERTY_TABLE_END(DEFAULT_OBJECT_PROPERTY_START_INDEX, RenderTaskDefaultProperties)
60
61 // Signals
62
63 const char* const SIGNAL_FINISHED = "finished";
64
65 TypeRegistration mType(typeid(Dali::RenderTask), typeid(Dali::BaseHandle), nullptr, RenderTaskDefaultProperties);
66
67 SignalConnectorType signalConnector1(mType, SIGNAL_FINISHED, &RenderTask::DoConnectSignal);
68
69 } // Unnamed namespace
70
71 RenderTaskPtr RenderTask::New(Actor* sourceActor, CameraActor* cameraActor, RenderTaskList& renderTaskList, bool isOverlayTask)
72 {
73   // create scene object first so it's guaranteed to exist for the event side
74   auto sceneObject = SceneGraph::RenderTask::New();
75
76   // pass the pointer to base for message passing
77   RenderTaskPtr task(new RenderTask(sceneObject, renderTaskList));
78
79   // transfer scene object ownership to update manager
80   const SceneGraph::RenderTaskList&    parentSceneObject = renderTaskList.GetSceneObject();
81   OwnerPointer<SceneGraph::RenderTask> transferOwnership(sceneObject);
82   if(isOverlayTask)
83   {
84     AddOverlayTaskMessage(task->GetEventThreadServices(), parentSceneObject, transferOwnership);
85   }
86   else
87   {
88     AddTaskMessage(task->GetEventThreadServices(), parentSceneObject, transferOwnership);
89   }
90
91   // Set the default source & camera actors
92   task->SetSourceActor(sourceActor);
93   task->SetCameraActor(cameraActor);
94
95   // no need for additional messages as scene objects defaults match ours
96   return task;
97 }
98
99 void RenderTask::SetSourceActor(Actor* actor)
100 {
101   mSourceActor.SetActor(actor);
102   if(actor)
103   {
104     SetSourceNodeMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), &actor->GetNode());
105   }
106   else
107   {
108     SetSourceNodeMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), nullptr);
109   }
110
111   // set the actor on exclusive container for hit testing
112   mRenderTaskList.SetExclusive(this, mExclusive);
113 }
114
115 Actor* RenderTask::GetSourceActor() const
116 {
117   return mSourceActor.GetActor();
118 }
119
120 void RenderTask::SetExclusive(bool exclusive)
121 {
122   if(mExclusive != exclusive)
123   {
124     mExclusive = exclusive;
125
126     mRenderTaskList.SetExclusive(this, exclusive);
127
128     // scene object is being used in a separate thread; queue a message to set the value
129     SetExclusiveMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), mExclusive);
130   }
131 }
132
133 bool RenderTask::IsExclusive() const
134 {
135   return mExclusive;
136 }
137
138 void RenderTask::SetInputEnabled(bool enabled)
139 {
140   mInputEnabled = enabled;
141 }
142
143 bool RenderTask::GetInputEnabled() const
144 {
145   return mInputEnabled;
146 }
147
148 void RenderTask::SetCameraActor(CameraActor* cameraActor)
149 {
150   mCameraActor.SetActor(cameraActor);
151   if(cameraActor)
152   {
153     SetCameraMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), &cameraActor->GetNode(), &cameraActor->GetCameraSceneObject());
154   }
155   else
156   {
157     SetCameraMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), nullptr, nullptr);
158   }
159
160   // set the actor on exclusive container for hit testing
161   mRenderTaskList.SetExclusive(this, mExclusive);
162 }
163
164 CameraActor* RenderTask::GetCameraActor() const
165 {
166   if(mCameraActor.GetActor())
167   {
168     return static_cast<CameraActor*>(mCameraActor.GetActor());
169   }
170   return nullptr;
171 }
172
173 void RenderTask::SetFrameBuffer(FrameBufferPtr frameBuffer)
174 {
175   mFrameBuffer = frameBuffer;
176   Render::FrameBuffer* renderFrameBufferPtr(nullptr);
177   if(frameBuffer)
178   {
179     renderFrameBufferPtr = mFrameBuffer->GetRenderObject();
180   }
181
182   SetFrameBufferMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), renderFrameBufferPtr);
183 }
184
185 FrameBuffer* RenderTask::GetFrameBuffer() const
186 {
187   return mFrameBuffer.Get();
188 }
189
190 void RenderTask::SetScreenToFrameBufferFunction(ScreenToFrameBufferFunction conversionFunction)
191 {
192   mScreenToFrameBufferFunction = conversionFunction;
193 }
194
195 RenderTask::ScreenToFrameBufferFunction RenderTask::GetScreenToFrameBufferFunction() const
196 {
197   return mScreenToFrameBufferFunction;
198 }
199
200 void RenderTask::SetScreenToFrameBufferMappingActor(Dali::Actor& mappingActor)
201 {
202   mInputMappingActor = WeakHandle<Dali::Actor>(mappingActor);
203 }
204
205 Dali::Actor RenderTask::GetScreenToFrameBufferMappingActor() const
206 {
207   return mInputMappingActor.GetHandle();
208 }
209
210 void RenderTask::SetViewportGuideActor(Actor* actor)
211 {
212   mViewportGuideActor.SetActor(actor);
213   if(actor)
214   {
215     SetViewportGuideNodeMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), &actor->GetNode());
216   }
217   else
218   {
219     SetViewportGuideNodeMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), nullptr);
220   }
221 }
222
223 Actor* RenderTask::GetViewportGuideActor() const
224 {
225   return mViewportGuideActor.GetActor();
226 }
227
228 void RenderTask::ResetViewportGuideActor()
229 {
230   SetViewportGuideActor(nullptr);
231
232   BakeViewportPositionMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), mViewportPosition);
233   BakeViewportSizeMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), mViewportSize);
234 }
235
236 void RenderTask::SetViewportPosition(const Vector2& value)
237 {
238   mViewportPosition = value;
239
240   BakeViewportPositionMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), value);
241 }
242
243 Vector2 RenderTask::GetCurrentViewportPosition() const
244 {
245   return GetRenderTaskSceneObject().GetViewportPosition(GetEventThreadServices().GetEventBufferIndex());
246 }
247
248 void RenderTask::SetViewportSize(const Vector2& value)
249 {
250   mViewportSize = value;
251
252   BakeViewportSizeMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), value);
253 }
254
255 Vector2 RenderTask::GetCurrentViewportSize() const
256 {
257   return GetRenderTaskSceneObject().GetViewportSize(GetEventThreadServices().GetEventBufferIndex());
258 }
259
260 void RenderTask::SetViewport(const Viewport& viewport)
261 {
262   SetViewportPosition(Vector2(static_cast<float>(viewport.x), static_cast<float>(viewport.y)));
263   SetViewportSize(Vector2(static_cast<float>(viewport.width), static_cast<float>(viewport.height)));
264 }
265
266 void RenderTask::GetViewport(Viewport& viewPort) const
267 {
268   BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
269
270   if(!GetRenderTaskSceneObject().GetViewportEnabled(bufferIndex))
271   {
272     Internal::Stage* stage = Internal::Stage::GetCurrent();
273     if(stage)
274     {
275       Vector2 size(stage->GetSize());
276       Actor*  sourceActor = mSourceActor.GetActor();
277       if(sourceActor && sourceActor->OnScene())
278       {
279         Scene& scene = sourceActor->GetScene();
280         size         = scene.GetSize();
281       }
282
283       viewPort.x = viewPort.y = 0;
284       viewPort.width          = static_cast<int32_t>(size.width);  // truncated
285       viewPort.height         = static_cast<int32_t>(size.height); // truncated
286     }
287   }
288   else
289   {
290     const Vector2& position = GetRenderTaskSceneObject().GetViewportPosition(bufferIndex);
291     const Vector2& size     = GetRenderTaskSceneObject().GetViewportSize(bufferIndex);
292     viewPort.x              = static_cast<int32_t>(position.x);  // truncated
293     viewPort.y              = static_cast<int32_t>(position.y);  // truncated
294     viewPort.width          = static_cast<int32_t>(size.width);  // truncated
295     viewPort.height         = static_cast<int32_t>(size.height); // truncated
296   }
297 }
298
299 void RenderTask::SetClearColor(const Vector4& color)
300 {
301   if(mClearColor != color)
302   {
303     mClearColor = color;
304
305     // scene object is being used in a separate thread; queue a message to set the value
306     BakeClearColorMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), color);
307   }
308 }
309
310 const Vector4& RenderTask::GetClearColor() const
311 {
312   return GetRenderTaskSceneObject().GetClearColor(GetEventThreadServices().GetEventBufferIndex());
313 }
314
315 void RenderTask::SetSyncRequired(bool requiresSync)
316 {
317   if(mRequiresSync != requiresSync)
318   {
319     mRequiresSync = requiresSync;
320
321     // scene object is being used in a separate thread; queue a message to set the value
322     SetSyncRequiredMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), requiresSync);
323   }
324 }
325
326 bool RenderTask::IsSyncRequired() const
327 {
328   return mRequiresSync;
329 }
330
331 void RenderTask::SetClearEnabled(bool enabled)
332 {
333   if(mClearEnabled != enabled)
334   {
335     mClearEnabled = enabled;
336
337     // scene object is being used in a separate thread; queue a message to set the value
338     SetClearEnabledMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), mClearEnabled);
339   }
340 }
341
342 bool RenderTask::GetClearEnabled() const
343 {
344   return mClearEnabled;
345 }
346
347 void RenderTask::SetCullMode(bool mode)
348 {
349   if(mCullMode != mode)
350   {
351     mCullMode = mode;
352
353     // scene object is being used in a separate thread; queue a message to set the value
354     SetCullModeMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), mCullMode);
355   }
356 }
357
358 bool RenderTask::GetCullMode() const
359 {
360   return mCullMode;
361 }
362
363 void RenderTask::SetRefreshRate(uint32_t refreshRate)
364 {
365   DALI_LOG_TRACE_METHOD_FMT(gLogRender, "this:%p  rate:%d\n", this, refreshRate);
366   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::SetRefreshRate(this:%p, %d)\n", this, refreshRate);
367
368   mRefreshRate = refreshRate; // cached for GetRefreshRate()
369
370   // Note - even when refreshRate is the same as mRefreshRate, a message should be sent
371
372   // sceneObject is being used in a separate thread; queue a message to set the value
373   SetRefreshRateMessage(GetEventThreadServices(), GetRenderTaskSceneObject(), refreshRate);
374 }
375
376 uint32_t RenderTask::GetRefreshRate() const
377 {
378   return mRefreshRate;
379 }
380
381 bool RenderTask::IsHittable(Vector2& screenCoords) const
382 {
383   // True when input is enabled, source & camera actor are valid
384   bool inputEnabled(false);
385
386   Actor*       sourceActor = GetSourceActor();
387   CameraActor* cameraActor = GetCameraActor();
388
389   if(mInputEnabled &&
390      nullptr != sourceActor &&
391      sourceActor->OnScene() &&
392      nullptr != cameraActor &&
393      cameraActor->OnScene())
394   {
395     // If the actors are rendered off-screen, then the screen coordinates must be converted
396     // and the conversion function will tell us if they are inside or outside
397     if(TranslateCoordinates(screenCoords))
398     {
399       // This is a suitable render-task for input handling
400       inputEnabled = true;
401     }
402   }
403
404   return inputEnabled;
405 }
406
407 bool RenderTask::TranslateCoordinates(Vector2& screenCoords) const
408 {
409   // return true for on-screen tasks
410   bool inside(true);
411   // If the actors are rendered off-screen, then the screen coordinates must be converted
412   // the function should only be called for offscreen tasks
413   Dali::Actor mappingActor = GetScreenToFrameBufferMappingActor();
414
415   if(mFrameBuffer && mappingActor)
416   {
417     Internal::Actor* inputMappingActor = &GetImplementation(mappingActor);
418     CameraActor*     localCamera       = GetCameraActor();
419     StagePtr         stage             = Stage::GetCurrent();
420     if(stage)
421     {
422       Vector2      size(stage->GetSize());
423       CameraActor* defaultCamera(&stage->GetDefaultCameraActor());
424       Actor*       sourceActor = mSourceActor.GetActor();
425       if(sourceActor && sourceActor->OnScene())
426       {
427         Scene& scene  = sourceActor->GetScene();
428         size          = scene.GetSize();
429         defaultCamera = &scene.GetDefaultCameraActor();
430       }
431
432       if(localCamera)
433       {
434         Viewport viewport;
435         viewport.x = viewport.y = 0;
436         viewport.width          = static_cast<int32_t>(size.width);  // truncated
437         viewport.height         = static_cast<int32_t>(size.height); // truncated
438
439         float localX, localY;
440         inside            = inputMappingActor->ScreenToLocal(defaultCamera->GetViewMatrix(), defaultCamera->GetProjectionMatrix(), viewport, localX, localY, screenCoords.x, screenCoords.y);
441         Vector3 actorSize = inputMappingActor->GetCurrentSize();
442         if(inside && localX >= 0.f && localX <= actorSize.x && localY >= 0.f && localY <= actorSize.y)
443         {
444           screenCoords.x = localX;
445           screenCoords.y = localY;
446         }
447         else
448         {
449           inside = false;
450         }
451       }
452       else
453       {
454         inside = false;
455       }
456     }
457   }
458   else if(mFrameBuffer && mScreenToFrameBufferFunction)
459   {
460     inside = mScreenToFrameBufferFunction(screenCoords);
461   }
462   return inside;
463 }
464
465 bool RenderTask::WorldToViewport(const Vector3& position, float& viewportX, float& viewportY) const
466 {
467   CameraActor* cam = GetCameraActor();
468
469   Vector4 pos(position);
470   pos.w = 1.0;
471
472   Vector4 viewportPosition;
473
474   Viewport viewport;
475   GetViewport(viewport);
476
477   bool ok = ProjectFull(pos,
478                         cam->GetViewMatrix(),
479                         cam->GetProjectionMatrix(),
480                         static_cast<float>(viewport.x),      // truncated
481                         static_cast<float>(viewport.y),      // truncated
482                         static_cast<float>(viewport.width),  // truncated
483                         static_cast<float>(viewport.height), // truncated
484                         viewportPosition);
485   if(ok)
486   {
487     viewportX = viewportPosition.x;
488     viewportY = viewportPosition.y;
489   }
490
491   return ok;
492 }
493
494 bool RenderTask::ViewportToLocal(Actor* actor, float viewportX, float viewportY, float& localX, float& localY) const
495 {
496   return actor->ScreenToLocal(*this, localX, localY, viewportX, viewportY);
497 }
498
499 const SceneGraph::RenderTask& RenderTask::GetRenderTaskSceneObject() const
500 {
501   return *static_cast<const SceneGraph::RenderTask*>(mUpdateObject);
502 }
503
504 RenderTaskList& RenderTask::GetRenderTaskList() const
505 {
506   return mRenderTaskList;
507 }
508
509 /********************************************************************************
510  ********************************   PROPERTY METHODS   **************************
511  ********************************************************************************/
512
513 void RenderTask::SetDefaultProperty(Property::Index index, const Property::Value& property)
514 {
515   switch(index)
516   {
517     case Dali::RenderTask::Property::VIEWPORT_POSITION:
518     {
519       SetViewportPosition(property.Get<Vector2>());
520       break;
521     }
522     case Dali::RenderTask::Property::VIEWPORT_SIZE:
523     {
524       SetViewportSize(property.Get<Vector2>());
525       break;
526     }
527     case Dali::RenderTask::Property::CLEAR_COLOR:
528     {
529       SetClearColor(property.Get<Vector4>());
530       break;
531     }
532     case Dali::RenderTask::Property::REQUIRES_SYNC:
533     {
534       SetSyncRequired(property.Get<bool>());
535       break;
536     }
537     default:
538     {
539       // nothing to do
540       break;
541     }
542   }
543 }
544
545 Property::Value RenderTask::GetDefaultProperty(Property::Index index) const
546 {
547   Property::Value value;
548
549   switch(index)
550   {
551     case Dali::RenderTask::Property::VIEWPORT_POSITION:
552     {
553       value = mViewportPosition;
554       break;
555     }
556     case Dali::RenderTask::Property::VIEWPORT_SIZE:
557     {
558       value = mViewportSize;
559       break;
560     }
561     case Dali::RenderTask::Property::CLEAR_COLOR:
562     {
563       value = mClearColor;
564       break;
565     }
566     case Dali::RenderTask::Property::REQUIRES_SYNC:
567     {
568       value = IsSyncRequired();
569       break;
570     }
571
572     default:
573     {
574       DALI_ASSERT_ALWAYS(false && "RenderTask property index out of range"); // should not come here
575       break;
576     }
577   }
578
579   return value;
580 }
581
582 Property::Value RenderTask::GetDefaultPropertyCurrentValue(Property::Index index) const
583 {
584   Property::Value value;
585
586   switch(index)
587   {
588     case Dali::RenderTask::Property::VIEWPORT_POSITION:
589     {
590       value = GetCurrentViewportPosition();
591       break;
592     }
593     case Dali::RenderTask::Property::VIEWPORT_SIZE:
594     {
595       value = GetCurrentViewportSize();
596       break;
597     }
598     case Dali::RenderTask::Property::CLEAR_COLOR:
599     {
600       value = GetClearColor();
601       break;
602     }
603     case Dali::RenderTask::Property::REQUIRES_SYNC:
604     {
605       value = IsSyncRequired();
606       break;
607     }
608
609     default:
610     {
611       DALI_ASSERT_ALWAYS(false && "RenderTask property index out of range"); // should not come here
612       break;
613     }
614   }
615
616   return value;
617 }
618
619 void RenderTask::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
620 {
621   switch(animationType)
622   {
623     case Animation::TO:
624     case Animation::BETWEEN:
625     {
626       switch(index)
627       {
628         case Dali::RenderTask::Property::VIEWPORT_POSITION:
629         {
630           value.Get(mViewportPosition);
631           break;
632         }
633         case Dali::RenderTask::Property::VIEWPORT_SIZE:
634         {
635           value.Get(mViewportSize);
636           break;
637         }
638         case Dali::RenderTask::Property::CLEAR_COLOR:
639         {
640           value.Get(mClearColor);
641           break;
642         }
643         case Dali::RenderTask::Property::REQUIRES_SYNC:
644         default:
645         {
646           // Nothing to do as not animatable
647           break;
648         }
649       }
650       break;
651     }
652
653     case Animation::BY:
654     {
655       switch(index)
656       {
657         case Dali::RenderTask::Property::VIEWPORT_POSITION:
658         {
659           AdjustValue<Vector2>(mViewportPosition, value);
660           break;
661         }
662         case Dali::RenderTask::Property::VIEWPORT_SIZE:
663         {
664           AdjustValue<Vector2>(mViewportSize, value);
665           break;
666         }
667         case Dali::RenderTask::Property::CLEAR_COLOR:
668         {
669           AdjustValue<Vector4>(mClearColor, value);
670           break;
671         }
672         case Dali::RenderTask::Property::REQUIRES_SYNC:
673         default:
674         {
675           // Nothing to do as not animatable
676           break;
677         }
678       }
679       break;
680     }
681   }
682 }
683
684 const SceneGraph::PropertyBase* RenderTask::GetSceneObjectAnimatableProperty(Property::Index index) const
685 {
686   const SceneGraph::PropertyBase* property(nullptr);
687
688   switch(index)
689   {
690     case Dali::RenderTask::Property::VIEWPORT_POSITION:
691     {
692       property = &GetRenderTaskSceneObject().mViewportPosition;
693       break;
694     }
695     case Dali::RenderTask::Property::VIEWPORT_SIZE:
696     {
697       property = &GetRenderTaskSceneObject().mViewportSize;
698       break;
699     }
700     case Dali::RenderTask::Property::CLEAR_COLOR:
701     {
702       property = &GetRenderTaskSceneObject().mClearColor;
703       break;
704     }
705     default:
706     {
707       break;
708     }
709   }
710   if(!property)
711   {
712     // not our property, ask base
713     property = Object::GetSceneObjectAnimatableProperty(index);
714   }
715
716   return property;
717 }
718
719 const PropertyInputImpl* RenderTask::GetSceneObjectInputProperty(Property::Index index) const
720 {
721   // animatable properties are input as well, Object::GetSceneObjectInputProperty does the same so no need to call it
722   return GetSceneObjectAnimatableProperty(index);
723 }
724
725 bool RenderTask::HasFinished()
726 {
727   bool           finished = false;
728   const uint32_t counter  = GetRenderTaskSceneObject().GetRenderedOnceCounter();
729
730   if(mRefreshOnceCounter < counter)
731   {
732     finished            = true;
733     mRefreshOnceCounter = counter;
734   }
735
736   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::HasFinished()=%s SCRT:%p  SC\n", finished ? "T" : "F", &GetRenderTaskSceneObject());
737
738   return finished;
739 }
740
741 void RenderTask::EmitSignalFinish()
742 {
743   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::EmitSignalFinish(this:%p)\n", this);
744
745   if(!mSignalFinished.Empty())
746   {
747     Dali::RenderTask handle(this);
748     mSignalFinished.Emit(handle);
749   }
750 }
751
752 Dali::RenderTask::RenderTaskSignalType& RenderTask::FinishedSignal()
753 {
754   return mSignalFinished;
755 }
756
757 bool RenderTask::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
758 {
759   bool        connected(true);
760   RenderTask* renderTask = static_cast<RenderTask*>(object); // TypeRegistry guarantees that this is the correct type.
761
762   if(0 == strcmp(signalName.c_str(), SIGNAL_FINISHED))
763   {
764     renderTask->FinishedSignal().Connect(tracker, functor);
765   }
766   else
767   {
768     // signalName does not match any signal
769     connected = false;
770   }
771
772   return connected;
773 }
774
775 RenderTask::RenderTask(const SceneGraph::RenderTask* sceneObject, RenderTaskList& renderTaskList)
776 : Object(sceneObject),
777   mSourceActor(),
778   mCameraActor(),
779   mViewportGuideActor(),
780   mInputMappingActor(),
781   mRenderTaskList(renderTaskList),
782   mClearColor(Dali::RenderTask::DEFAULT_CLEAR_COLOR),
783   mViewportPosition(Vector2::ZERO),
784   mViewportSize(Vector2::ZERO),
785   mRefreshRate(Dali::RenderTask::DEFAULT_REFRESH_RATE),
786   mRefreshOnceCounter(0u),
787   mScreenToFrameBufferFunction(Dali::RenderTask::DEFAULT_SCREEN_TO_FRAMEBUFFER_FUNCTION),
788   mExclusive(Dali::RenderTask::DEFAULT_EXCLUSIVE),
789   mInputEnabled(Dali::RenderTask::DEFAULT_INPUT_ENABLED),
790   mClearEnabled(Dali::RenderTask::DEFAULT_CLEAR_ENABLED),
791   mCullMode(Dali::RenderTask::DEFAULT_CULL_MODE),
792   mRequiresSync(false)
793 {
794   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::RenderTask(this:%p)\n", this);
795   // scene object handles observation of source and camera
796 }
797
798 RenderTask::~RenderTask()
799 {
800   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::~RenderTask(this:%p)\n", this);
801   // scene object deletion is handled by our parent
802   // scene object handles observation of source and camera
803 }
804
805 } // namespace Internal
806
807 } // namespace Dali