Reducing boilerplate on default property metadata
[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 RenderTask* RenderTask::New()
75 {
76   RenderTask* task( new RenderTask() );
77
78   return task;
79 }
80
81 void RenderTask::SetSourceActor( Actor* actor )
82 {
83   const Stage* stage = Stage::GetCurrent();
84   if ( stage )
85   {
86     stage->GetRenderTaskList().SetExclusive( this, mExclusive );
87   }
88   mSourceConnector.SetActor( actor );
89 }
90
91 Actor* RenderTask::GetSourceActor() const
92 {
93   return mSourceConnector.mActor;
94 }
95
96 void RenderTask::SetExclusive( bool exclusive )
97 {
98   if ( mExclusive != exclusive )
99   {
100     mExclusive = exclusive;
101
102     const Stage* stage = Stage::GetCurrent();
103     if ( stage )
104     {
105       stage->GetRenderTaskList().SetExclusive( this, exclusive );
106     }
107
108     if ( mSceneObject )
109     {
110       // mSceneObject is being used in a separate thread; queue a message to set the value
111       SetExclusiveMessage( GetEventThreadServices(), *mSceneObject, mExclusive );
112     }
113   }
114 }
115
116 bool RenderTask::IsExclusive() const
117 {
118   return mExclusive;
119 }
120
121 void RenderTask::SetInputEnabled( bool enabled )
122 {
123   mInputEnabled = enabled;
124 }
125
126 bool RenderTask::GetInputEnabled() const
127 {
128   return mInputEnabled;
129 }
130
131 void RenderTask::SetCameraActor( CameraActor* cameraActor )
132 {
133   if( cameraActor )
134   {
135     mCameraConnector.mCamera = cameraActor->GetCamera();
136   }
137   else
138   {
139     mCameraConnector.mCamera = NULL;
140   }
141   mCameraConnector.SetActor( cameraActor );
142 }
143
144 CameraActor* RenderTask::GetCameraActor() const
145 {
146   // camera connector can only point to camera actor
147   return static_cast< CameraActor* >( mCameraConnector.mActor );
148 }
149
150 void RenderTask::SetTargetFrameBuffer( FrameBufferImagePtr image )
151 {
152   mFrameBufferImage = image;
153   FrameBuffer* frameBufferPtr( NULL );
154   if( image )
155   {
156     frameBufferPtr = image->GetFrameBuffer();
157   }
158
159   SetFrameBuffer( frameBufferPtr );
160 }
161
162 void RenderTask::SetFrameBuffer( FrameBufferPtr frameBuffer )
163 {
164   mFrameBuffer = frameBuffer;
165   Render::FrameBuffer* renderFrameBufferPtr( NULL );
166   if( frameBuffer )
167   {
168     renderFrameBufferPtr = mFrameBuffer->GetRenderObject();
169   }
170
171   SetFrameBufferMessage( GetEventThreadServices(), *mSceneObject, renderFrameBufferPtr );
172 }
173
174 FrameBuffer* RenderTask::GetFrameBuffer() const
175 {
176   return mFrameBuffer.Get();
177 }
178
179 FrameBufferImage* RenderTask::GetTargetFrameBuffer() const
180 {
181   return mFrameBufferImage.Get();
182 }
183
184 void RenderTask::SetScreenToFrameBufferFunction( ScreenToFrameBufferFunction conversionFunction )
185 {
186   mScreenToFrameBufferFunction = conversionFunction;
187 }
188
189 RenderTask::ScreenToFrameBufferFunction RenderTask::GetScreenToFrameBufferFunction() const
190 {
191   return mScreenToFrameBufferFunction;
192 }
193
194 void RenderTask::SetScreenToFrameBufferMappingActor( Actor* mappingActor )
195 {
196   mMappingConnector.SetActor( mappingActor );
197 }
198
199 Actor* RenderTask::GetScreenToFrameBufferMappingActor() const
200 {
201   return mMappingConnector.mActor;
202 }
203
204 void RenderTask::SetViewportPosition(const Vector2& value)
205 {
206   mViewportPosition = value;
207
208   BakeViewportPositionMessage( GetEventThreadServices(), *mSceneObject, value );
209 }
210
211 Vector2 RenderTask::GetCurrentViewportPosition() const
212 {
213   return mSceneObject->GetViewportPosition( GetEventThreadServices().GetEventBufferIndex() );
214 }
215
216 void RenderTask::SetViewportSize(const Vector2& value)
217 {
218   mViewportSize = value;
219
220   BakeViewportSizeMessage( GetEventThreadServices(), *mSceneObject, value );
221 }
222
223 Vector2 RenderTask::GetCurrentViewportSize() const
224 {
225   return mSceneObject->GetViewportSize( GetEventThreadServices().GetEventBufferIndex() );
226 }
227
228 void RenderTask::SetViewport( const Viewport& viewport )
229 {
230   SetViewportPosition( Vector2( static_cast<float>( viewport.x ), static_cast<float>( viewport.y ) ) );
231   SetViewportSize( Vector2( static_cast<float>( viewport.width ), static_cast<float>( viewport.height ) ) );
232 }
233
234 void RenderTask::GetViewport( Viewport& viewPort ) const
235 {
236   BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
237
238   if(!mSceneObject->GetViewportEnabled( bufferIndex ))
239   {
240     if ( mFrameBufferImage )
241     {
242       viewPort.x = viewPort.y = 0;
243       viewPort.width = mFrameBufferImage->GetWidth();
244       viewPort.height = mFrameBufferImage->GetHeight();
245     }
246     else
247     {
248       Internal::Stage* stage = Internal::Stage::GetCurrent();
249       if ( stage )
250       {
251         Vector2 size( stage->GetSize() );
252         viewPort.x = viewPort.y = 0;
253         viewPort.width = static_cast<int32_t>( size.width ); // truncated
254         viewPort.height = static_cast<int32_t>( size.height ); // truncated
255       }
256     }
257   }
258   else
259   {
260     const Vector2& position = mSceneObject->GetViewportPosition(bufferIndex);
261     const Vector2& size = mSceneObject->GetViewportSize(bufferIndex);
262     viewPort.x = static_cast<int32_t>( position.x ); // truncated
263     viewPort.y = static_cast<int32_t>( position.y ); // truncated
264     viewPort.width = static_cast<int32_t>( size.width ); // truncated
265     viewPort.height = static_cast<int32_t>( size.height ); // truncated
266   }
267 }
268
269 void RenderTask::SetClearColor( const Vector4& color )
270 {
271   if ( mClearColor != color )
272   {
273     mClearColor = color;
274
275     if ( mSceneObject )
276     {
277       // mSceneObject is being used in a separate thread; queue a message to set the value
278       BakeClearColorMessage( GetEventThreadServices(), *mSceneObject, color );
279     }
280   }
281 }
282
283 const Vector4& RenderTask::GetClearColor() const
284 {
285   return mSceneObject->GetClearColor( GetEventThreadServices().GetEventBufferIndex() );
286 }
287
288 void RenderTask::SetSyncRequired( bool requiresSync )
289 {
290   if( mRequiresSync != requiresSync )
291   {
292     mRequiresSync = requiresSync;
293
294     if( mSceneObject )
295     {
296       // mSceneObject is being used in a separate thread; queue a message to set the value
297       SetSyncRequiredMessage( GetEventThreadServices(), *mSceneObject, requiresSync );
298     }
299   }
300 }
301
302 bool RenderTask::IsSyncRequired() const
303 {
304   return mRequiresSync;
305 }
306
307 void RenderTask::SetClearEnabled( bool enabled )
308 {
309   if ( mClearEnabled != enabled )
310   {
311     mClearEnabled = enabled;
312
313     if ( mSceneObject )
314     {
315       // mSceneObject is being used in a separate thread; queue a message to set the value
316       SetClearEnabledMessage( GetEventThreadServices(), *mSceneObject, mClearEnabled );
317     }
318   }
319 }
320
321 bool RenderTask::GetClearEnabled() const
322 {
323   return mClearEnabled;
324 }
325
326 void RenderTask::SetCullMode( bool mode )
327 {
328   if ( mCullMode != mode )
329   {
330     mCullMode = mode;
331
332     if ( mSceneObject )
333     {
334       // mSceneObject is being used in a separate thread; queue a message to set the value
335       SetCullModeMessage( GetEventThreadServices(), *mSceneObject, mCullMode );
336     }
337   }
338 }
339
340 bool RenderTask::GetCullMode() const
341 {
342   return mCullMode;
343 }
344
345 void RenderTask::SetRefreshRate( uint32_t refreshRate )
346 {
347   DALI_LOG_TRACE_METHOD_FMT(gLogRender, "this:%p  rate:%d\n", this, refreshRate);
348   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::SetRefreshRate(this:%p, %d)\n", this, refreshRate);
349
350   mRefreshRate = refreshRate; // cached for GetRefreshRate()
351
352   // Note - even when refreshRate is the same as mRefreshRate, a message should be sent
353
354   if ( mSceneObject )
355   {
356     // mSceneObject is being used in a separate thread; queue a message to set the value
357     SetRefreshRateMessage( GetEventThreadServices(), *mSceneObject, refreshRate );
358   }
359 }
360
361 uint32_t RenderTask::GetRefreshRate() const
362 {
363   return mRefreshRate;
364 }
365
366 bool RenderTask::IsHittable( Vector2& screenCoords ) const
367 {
368   // True when input is enabled, source & camera actor are valid
369   bool inputEnabled( false );
370
371   Actor* sourceActor = GetSourceActor();
372   CameraActor* cameraActor = GetCameraActor();
373
374   if ( mInputEnabled  &&
375        NULL != sourceActor    &&
376        sourceActor->OnStage() &&
377        NULL != cameraActor    &&
378        cameraActor->OnStage() )
379   {
380     // If the actors are rendered off-screen, then the screen coordinates must be converted
381     // and the conversion function will tell us if they are inside or outside
382     if ( TranslateCoordinates( screenCoords ) )
383     {
384       // This is a suitable render-task for input handling
385       inputEnabled = true;
386     }
387   }
388
389   return inputEnabled;
390 }
391
392 bool RenderTask::TranslateCoordinates( Vector2& screenCoords ) const
393 {
394   // return true for on-screen tasks
395   bool inside( true );
396   // If the actors are rendered off-screen, then the screen coordinates must be converted
397   // the function should only be called for offscreen tasks
398   if( mFrameBufferImage && mMappingConnector.mActor )
399   {
400     CameraActor* localCamera = GetCameraActor();
401     StagePtr stage = Stage::GetCurrent();
402     if( stage )
403     {
404       CameraActor& defaultCamera = stage->GetDefaultCameraActor();
405       if( localCamera )
406       {
407         Viewport viewport;
408         Vector2 size( stage->GetSize() );
409         viewport.x = viewport.y = 0;
410         viewport.width = static_cast<int32_t>( size.width ); // truncated
411         viewport.height = static_cast<int32_t>( size.height ); // truncated
412
413         float localX, localY;
414         inside = mMappingConnector.mActor->ScreenToLocal(defaultCamera.GetViewMatrix(), defaultCamera.GetProjectionMatrix(), viewport, localX, localY, screenCoords.x, screenCoords.y);
415         Vector3 actorSize = mMappingConnector.mActor->GetCurrentSize();
416         if( inside && localX >= 0.f && localX <= actorSize.x && localY >= 0.f && localY <= actorSize.y)
417         {
418           screenCoords.x = localX;
419           screenCoords.y = localY;
420         }
421         else
422         {
423           inside = false;
424         }
425       }
426       else
427       {
428         inside = false;
429       }
430     }
431   }
432   else if ( mFrameBufferImage && mScreenToFrameBufferFunction )
433   {
434     inside = mScreenToFrameBufferFunction( screenCoords );
435   }
436   return inside;
437 }
438
439 bool RenderTask::WorldToViewport(const Vector3 &position, float& viewportX, float& viewportY) const
440 {
441   CameraActor* cam = GetCameraActor();
442
443   Vector4 pos(position);
444   pos.w = 1.0;
445
446   Vector4 viewportPosition;
447
448   Viewport viewport;
449   GetViewport( viewport );
450
451   bool ok = ProjectFull(pos,
452                         cam->GetViewMatrix(),
453                         cam->GetProjectionMatrix(),
454                         static_cast<float>( viewport.x ), // truncated
455                         static_cast<float>( viewport.y ), // truncated
456                         static_cast<float>( viewport.width ), // truncated
457                         static_cast<float>( viewport.height ), // truncated
458                         viewportPosition);
459   if(ok)
460   {
461     viewportX = viewportPosition.x;
462     viewportY = viewportPosition.y;
463   }
464
465   return ok;
466 }
467
468 bool RenderTask::ViewportToLocal(Actor* actor, float viewportX, float viewportY, float &localX, float &localY) const
469 {
470   return actor->ScreenToLocal( *this, localX, localY, viewportX, viewportY );
471 }
472
473 SceneGraph::RenderTask* RenderTask::CreateSceneObject()
474 {
475   // This should only be called once, with no existing scene-object
476   DALI_ASSERT_DEBUG( NULL == mSceneObject );
477
478   // Keep the raw-pointer until DiscardSceneObject is called
479   mSceneObject = SceneGraph::RenderTask::New();
480
481   // Send messages to set other properties that may have changed since last time we were on stage
482   SetExclusiveMessage( GetEventThreadServices(), *mSceneObject, mExclusive );
483   SetClearColorMessage(  GetEventThreadServices(), *mSceneObject, mClearColor );
484   SetClearEnabledMessage(  GetEventThreadServices(), *mSceneObject, mClearEnabled );
485   SetCullModeMessage(  GetEventThreadServices(), *mSceneObject, mCullMode );
486   SetRefreshRateMessage(  GetEventThreadServices(), *mSceneObject, mRefreshRate );
487   SetSyncRequiredMessage( GetEventThreadServices(), *mSceneObject, mRequiresSync );
488   SetFrameBuffer( mFrameBuffer );
489
490   // Caller takes ownership
491   return mSceneObject;
492 }
493
494 SceneGraph::RenderTask* RenderTask::GetRenderTaskSceneObject()
495 {
496   return mSceneObject;
497 }
498
499 void RenderTask::DiscardSceneObject()
500 {
501   // mSceneObject is not owned; throw away the raw-pointer
502   mSceneObject = NULL;
503 }
504
505 /********************************************************************************
506  ********************************   PROPERTY METHODS   **************************
507  ********************************************************************************/
508
509 void RenderTask::SetDefaultProperty( Property::Index index, const Property::Value& property )
510 {
511   switch ( index )
512   {
513     case Dali::RenderTask::Property::VIEWPORT_POSITION:
514     {
515       SetViewportPosition( property.Get<Vector2>() );
516       break;
517     }
518     case Dali::RenderTask::Property::VIEWPORT_SIZE:
519     {
520       SetViewportSize( property.Get<Vector2>() );
521       break;
522     }
523     case Dali::RenderTask::Property::CLEAR_COLOR:
524     {
525       SetClearColor( property.Get<Vector4>() );
526       break;
527     }
528     case Dali::RenderTask::Property::REQUIRES_SYNC:
529     {
530       SetSyncRequired( property.Get<bool>() );
531       break;
532     }
533     default:
534     {
535       // nothing to do
536       break;
537     }
538   }
539 }
540
541 Property::Value RenderTask::GetDefaultProperty(Property::Index index) const
542 {
543   Property::Value value;
544
545   switch ( index )
546   {
547
548     case Dali::RenderTask::Property::VIEWPORT_POSITION:
549     {
550       value = mViewportPosition;
551       break;
552     }
553     case Dali::RenderTask::Property::VIEWPORT_SIZE:
554     {
555       value = mViewportSize;
556       break;
557     }
558     case Dali::RenderTask::Property::CLEAR_COLOR:
559     {
560       value = mClearColor;
561       break;
562     }
563     case Dali::RenderTask::Property::REQUIRES_SYNC:
564     {
565       value = IsSyncRequired();
566       break;
567     }
568
569     default:
570     {
571       DALI_ASSERT_ALWAYS(false && "RenderTask property index out of range"); // should not come here
572       break;
573     }
574   }
575
576   return value;
577 }
578
579 Property::Value RenderTask::GetDefaultPropertyCurrentValue( Property::Index index ) const
580 {
581   Property::Value value;
582
583   switch ( index )
584   {
585
586     case Dali::RenderTask::Property::VIEWPORT_POSITION:
587     {
588       value = GetCurrentViewportPosition();
589       break;
590     }
591     case Dali::RenderTask::Property::VIEWPORT_SIZE:
592     {
593       value = GetCurrentViewportSize();
594       break;
595     }
596     case Dali::RenderTask::Property::CLEAR_COLOR:
597     {
598       value = GetClearColor();
599       break;
600     }
601     case Dali::RenderTask::Property::REQUIRES_SYNC:
602     {
603       value = IsSyncRequired();
604       break;
605     }
606
607     default:
608     {
609       DALI_ASSERT_ALWAYS(false && "RenderTask property index out of range"); // should not come here
610       break;
611     }
612   }
613
614   return value;
615 }
616
617 void RenderTask::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
618 {
619   switch( animationType )
620   {
621     case Animation::TO:
622     case Animation::BETWEEN:
623     {
624       switch ( index )
625       {
626         case Dali::RenderTask::Property::VIEWPORT_POSITION:
627         {
628           value.Get( mViewportPosition );
629           break;
630         }
631         case Dali::RenderTask::Property::VIEWPORT_SIZE:
632         {
633           value.Get( mViewportSize );
634           break;
635         }
636         case Dali::RenderTask::Property::CLEAR_COLOR:
637         {
638           value.Get( mClearColor );
639           break;
640         }
641         case Dali::RenderTask::Property::REQUIRES_SYNC:
642         default:
643         {
644           // Nothing to do as not animatable
645           break;
646         }
647       }
648       break;
649     }
650
651     case Animation::BY:
652     {
653       switch ( index )
654       {
655         case Dali::RenderTask::Property::VIEWPORT_POSITION:
656         {
657           AdjustValue< Vector2 >( mViewportPosition, value );
658           break;
659         }
660         case Dali::RenderTask::Property::VIEWPORT_SIZE:
661         {
662           AdjustValue< Vector2 >( mViewportSize, value );
663           break;
664         }
665         case Dali::RenderTask::Property::CLEAR_COLOR:
666         {
667           AdjustValue< Vector4 >( mClearColor, value );
668           break;
669         }
670         case Dali::RenderTask::Property::REQUIRES_SYNC:
671         default:
672         {
673           // Nothing to do as not animatable
674           break;
675         }
676       }
677       break;
678     }
679   }
680 }
681
682 const SceneGraph::PropertyOwner* RenderTask::GetSceneObject() const
683 {
684   return mSceneObject;
685 }
686
687 const SceneGraph::PropertyBase* RenderTask::GetSceneObjectAnimatableProperty( Property::Index index ) const
688 {
689   DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
690
691   const SceneGraph::PropertyBase* property( NULL );
692
693   // This method should only return a property which is part of the scene-graph
694   if( mSceneObject != NULL )
695   {
696     switch ( index )
697     {
698       case Dali::RenderTask::Property::VIEWPORT_POSITION:
699         property = &mSceneObject->mViewportPosition;
700         break;
701
702       case Dali::RenderTask::Property::VIEWPORT_SIZE:
703         property = &mSceneObject->mViewportSize;
704         break;
705
706       case Dali::RenderTask::Property::CLEAR_COLOR:
707         property = &mSceneObject->mClearColor;
708         break;
709
710       default:
711         break;
712     }
713   }
714
715   return property;
716 }
717
718 const PropertyInputImpl* RenderTask::GetSceneObjectInputProperty( Property::Index index ) const
719 {
720   const PropertyInputImpl* property( NULL );
721   if( mSceneObject != NULL )
722   {
723     switch ( index )
724     {
725       case Dali::RenderTask::Property::VIEWPORT_POSITION:
726         property = &mSceneObject->mViewportPosition;
727         break;
728
729       case Dali::RenderTask::Property::VIEWPORT_SIZE:
730         property = &mSceneObject->mViewportSize;
731         break;
732
733       case Dali::RenderTask::Property::CLEAR_COLOR:
734         property = &mSceneObject->mClearColor;
735         break;
736
737       default:
738         break;
739     }
740   }
741
742   return property;
743 }
744
745 bool RenderTask::HasFinished()
746 {
747   bool finished = false;
748   const uint32_t counter = mSceneObject->GetRenderedOnceCounter();
749
750   if( mRefreshOnceCounter < counter )
751   {
752     finished = true;
753     mRefreshOnceCounter = counter;
754   }
755
756   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::HasFinished()=%s SCRT:%p  SC\n", finished?"T":"F", mSceneObject);
757
758   return finished;
759 }
760
761 void RenderTask::EmitSignalFinish()
762 {
763   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::EmitSignalFinish(this:%p)\n", this);
764
765   if( !mSignalFinished.Empty() )
766   {
767     Dali::RenderTask handle( this );
768     mSignalFinished.Emit(handle );
769   }
770 }
771
772 Dali::RenderTask::RenderTaskSignalType& RenderTask::FinishedSignal()
773 {
774   return mSignalFinished;
775 }
776
777 bool RenderTask::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
778 {
779   bool connected( true );
780   RenderTask* renderTask = static_cast< RenderTask* >(object); // TypeRegistry guarantees that this is the correct type.
781
782   if ( 0 == strcmp( signalName.c_str(), SIGNAL_FINISHED ) )
783   {
784     renderTask->FinishedSignal().Connect( tracker, functor );
785   }
786   else
787   {
788     // signalName does not match any signal
789     connected = false;
790   }
791
792   return connected;
793 }
794
795 RenderTask::RenderTask()
796 : mSceneObject( NULL ),
797   mSourceConnector( Connector::SOURCE_CONNECTOR, *this ),
798   mCameraConnector( Connector::CAMERA_CONNECTOR, *this ),
799   mMappingConnector( Connector::MAPPING_CONNECTOR, *this  ),
800   mClearColor( Dali::RenderTask::DEFAULT_CLEAR_COLOR ),
801   mViewportPosition( Vector2::ZERO ),
802   mViewportSize( Vector2::ZERO ),
803   mRefreshRate( Dali::RenderTask::DEFAULT_REFRESH_RATE ),
804   mRefreshOnceCounter( 0u ),
805   mScreenToFrameBufferFunction( Dali::RenderTask::DEFAULT_SCREEN_TO_FRAMEBUFFER_FUNCTION ),
806   mExclusive( Dali::RenderTask::DEFAULT_EXCLUSIVE ),
807   mInputEnabled( Dali::RenderTask::DEFAULT_INPUT_ENABLED ),
808   mClearEnabled( Dali::RenderTask::DEFAULT_CLEAR_ENABLED ),
809   mCullMode( Dali::RenderTask::DEFAULT_CULL_MODE ),
810   mRequiresSync( false )
811 {
812   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::RenderTask(this:%p)\n", this);
813 }
814
815 RenderTask::~RenderTask()
816 {
817   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::~RenderTask(this:%p)\n", this);
818 }
819
820 // Helper class for connecting Nodes to the scene-graph RenderTask
821
822 RenderTask::Connector::Connector( Type type, RenderTask& renderTask )
823 : mType( type ),
824   mRenderTask( renderTask ),
825   mActor( NULL ),
826   mCamera( NULL )
827 {
828 }
829
830 RenderTask::Connector::~Connector()
831 {
832   SetActor( NULL );
833 }
834
835 void RenderTask::Connector::SetActor( Actor* actor )
836 {
837   if ( mActor != actor )
838   {
839     if ( mActor )
840     {
841       mActor->RemoveObserver( *this );
842     }
843
844     mActor = actor;
845
846     if ( mActor )
847     {
848       mActor->AddObserver( *this );
849     }
850
851     UpdateRenderTask();
852   }
853 }
854
855 void RenderTask::Connector::SceneObjectAdded( Object& object )
856 {
857   UpdateRenderTask();
858 }
859
860 void RenderTask::Connector::SceneObjectRemoved( Object& object )
861 {
862   UpdateRenderTask();
863 }
864
865 void RenderTask::Connector::ObjectDestroyed( Object& object )
866 {
867   if ( SOURCE_CONNECTOR == mType )
868   {
869     const Stage* stage = Stage::GetCurrent();
870     if ( stage )
871     {
872       stage->GetRenderTaskList().SetExclusive( &mRenderTask, false );
873     }
874   }
875
876   mActor = NULL;
877   mCamera = NULL; // only meaningful for the camera connector but no simple way to distinguish
878
879   UpdateRenderTask();
880 }
881
882 void RenderTask::Connector::UpdateRenderTask()
883 {
884   // Guard to allow handle destruction after Core has been destroyed
885   if( Internal::Stage::IsInstalled() &&
886       mRenderTask.mSceneObject )
887   {
888     const SceneGraph::Node* node( NULL );
889
890     // Check whether a Node exists in the scene-graph
891     if ( NULL != mActor )
892     {
893       const SceneGraph::PropertyOwner* object = mActor->GetSceneObject();
894       if ( NULL != object )
895       {
896         // actors only point to nodes as their scene objects
897         node = static_cast< const SceneGraph::Node* >( object );
898       }
899     }
900
901     //the mapping node is not used in the scene graph
902     if ( SOURCE_CONNECTOR == mType )
903     {
904       SetSourceNodeMessage( mRenderTask.GetEventThreadServices(), *(mRenderTask.mSceneObject), node );
905     }
906     else if( CAMERA_CONNECTOR == mType )
907     {
908       SetCameraMessage( mRenderTask.GetEventThreadServices(), *(mRenderTask.mSceneObject), node, mCamera );
909     }
910   }
911 }
912
913 } // namespace Internal
914
915 } // namespace Dali