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