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