[SRUK] Initial copy from Tizen 2.2 version
[platform/core/uifw/dali-core.git] / dali / internal / event / render-tasks / render-task-impl.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 // CLASS HEADER
18 #include <dali/internal/event/render-tasks/render-task-impl.h>
19
20 // INTERNAL INCLUDES
21 #include <dali/public-api/common/dali-common.h>
22 #include <dali/internal/common/event-to-update.h>
23 #include <dali/internal/event/actors/actor-impl.h>
24 #include <dali/internal/event/actors/camera-actor-impl.h>
25 #include <dali/internal/event/common/stage-impl.h>
26 #include <dali/internal/event/common/thread-local-storage.h>
27 #include <dali/internal/event/images/frame-buffer-image-impl.h>
28 #include <dali/internal/update/render-tasks/scene-graph-render-task.h>
29 #include <dali/internal/update/nodes/node.h>
30
31 #if defined(DEBUG_ENABLED)
32 namespace
33 {
34 Debug::Filter* gLogRender = Debug::Filter::New(Debug::Concise, false, "LOG_RENDER_TASK");
35 }
36 #endif
37
38 namespace Dali
39 {
40
41 const Property::Index RenderTask::VIEWPORT_POSITION         = 0;
42 const Property::Index RenderTask::VIEWPORT_SIZE             = 1;
43 const Property::Index RenderTask::CLEAR_COLOR               = 2;
44
45 namespace Internal
46 {
47
48 namespace // For internal properties
49 {
50
51 const std::string DEFAULT_PROPERTY_NAMES[] =
52 {
53   "viewport-position",
54   "viewport-size",
55   "clear-color"
56 };
57 const int DEFAULT_PROPERTY_COUNT = sizeof( DEFAULT_PROPERTY_NAMES ) / sizeof( std::string );
58
59 const Property::Type DEFAULT_PROPERTY_TYPES[DEFAULT_PROPERTY_COUNT] =
60 {
61   Property::VECTOR2,    // viewport-position
62   Property::VECTOR2,    // viewport-size
63   Property::VECTOR4,    // clear-color
64 };
65
66 }// unnamed namespace
67
68 RenderTask::DefaultPropertyLookup* RenderTask::sDefaultPropertyLookup = NULL;
69
70 RenderTask* RenderTask::New( bool isSystemLevel )
71 {
72   RenderTask* task( new RenderTask( ThreadLocalStorage::Get().GetEventToUpdate(), isSystemLevel ) );
73
74   return task;
75 }
76
77 void RenderTask::SetSourceActor( Actor* actor )
78 {
79   mSourceConnector.SetActor( actor );
80 }
81
82 Actor* RenderTask::GetSourceActor() const
83 {
84   return mSourceConnector.mActor;
85 }
86
87 void RenderTask::SetExclusive( bool exclusive )
88 {
89   if ( mExclusive != exclusive )
90   {
91     mExclusive = exclusive;
92
93     if ( mSceneObject )
94     {
95       // mSceneObject is being used in a separate thread; queue a message to set the value
96       SetExclusiveMessage( mEventToUpdate, *mSceneObject, mExclusive );
97     }
98   }
99 }
100
101 bool RenderTask::IsExclusive() const
102 {
103   return mExclusive;
104 }
105
106 void RenderTask::SetInputEnabled( bool enabled )
107 {
108   mInputEnabled = enabled;
109 }
110
111 bool RenderTask::GetInputEnabled() const
112 {
113   return mInputEnabled;
114 }
115
116 void RenderTask::SetCameraActor( CameraActor* cameraActor )
117 {
118   mCameraConnector.SetActor( cameraActor );
119 }
120
121 CameraActor* RenderTask::GetCameraActor() const
122 {
123   // camera connector can only point to camera actor
124   return static_cast< CameraActor* >( mCameraConnector.mActor );
125 }
126
127 void RenderTask::SetTargetFrameBuffer( Dali::FrameBufferImage image )
128 {
129   if ( mFrameBufferImage != image )
130   {
131     // if we have a scene object we need to track connection status and set frame buffer id as well as updating target frame buffer
132     if ( mSceneObject )
133     {
134       if(mFrameBufferImage)
135       {
136         GetImplementation(mFrameBufferImage).Disconnect();
137       }
138
139       // update target frame buffer
140       mFrameBufferImage = image;
141
142       unsigned int resourceId = 0;
143       if(mFrameBufferImage)
144       {
145         GetImplementation(mFrameBufferImage).Connect();
146
147         resourceId = GetImplementation( mFrameBufferImage ).GetResourceId();
148       }
149
150       // mSceneObject is being used in a separate thread; queue a message to set the value
151       SetFrameBufferIdMessage( mEventToUpdate, *mSceneObject, resourceId );
152     }
153     else
154     {
155       // update target frame buffer
156       mFrameBufferImage = image;
157     }
158   }
159 }
160
161 Dali::FrameBufferImage RenderTask::GetTargetFrameBuffer() const
162 {
163   return mFrameBufferImage;
164 }
165
166 void RenderTask::SetScreenToFrameBufferFunction( ScreenToFrameBufferFunction conversionFunction )
167 {
168   mScreenToFrameBufferFunction = conversionFunction;
169 }
170
171 RenderTask::ScreenToFrameBufferFunction RenderTask::GetScreenToFrameBufferFunction() const
172 {
173   return mScreenToFrameBufferFunction;
174 }
175
176 void RenderTask::SetScreenToFrameBufferMappingActor( Actor* mappingActor )
177 {
178   mMappingConnector.SetActor( mappingActor );
179 }
180
181 Actor* RenderTask::GetScreenToFrameBufferMappingActor() const
182 {
183   return mMappingConnector.mActor;
184 }
185
186 void RenderTask::SetViewportPosition(const Vector2& value)
187 {
188   StagePtr stage = Stage::GetCurrent();
189   BakeViewportPositionMessage( stage->GetUpdateInterface(), *mSceneObject, value );
190 }
191
192 Vector2 RenderTask::GetCurrentViewportPosition() const
193 {
194   StagePtr stage = Stage::GetCurrent();
195   return mSceneObject->GetViewportPosition(stage->GetEventBufferIndex());
196 }
197
198 void RenderTask::SetViewportSize(const Vector2& value)
199 {
200   StagePtr stage = Stage::GetCurrent();
201   BakeViewportSizeMessage( stage->GetUpdateInterface(), *mSceneObject, value );
202 }
203
204 Vector2 RenderTask::GetCurrentViewportSize() const
205 {
206   StagePtr stage = Stage::GetCurrent();
207   return mSceneObject->GetViewportSize(stage->GetEventBufferIndex());
208 }
209
210 void RenderTask::SetViewport( const Viewport& viewport )
211 {
212   SetViewportPosition(Vector2(viewport.x, viewport.y));
213   SetViewportSize(Vector2(viewport.width, viewport.height));
214 }
215
216 void RenderTask::GetViewport( Viewport& viewPort ) const
217 {
218   BufferIndex bufferIndex = Stage::GetCurrent()->GetEventBufferIndex();
219
220   if(!mSceneObject->GetViewportEnabled( bufferIndex ))
221   {
222     if ( mFrameBufferImage )
223     {
224       viewPort.x = viewPort.y = 0;
225       viewPort.width = mFrameBufferImage.GetWidth();
226       viewPort.height = mFrameBufferImage.GetHeight();
227     }
228     else
229     {
230       Vector2 size( Stage::GetCurrent()->GetSize() );
231       viewPort.x = viewPort.y = 0;
232       viewPort.width = size.width;
233       viewPort.height = size.height;
234     }
235   }
236   else
237   {
238     const Vector2& position = mSceneObject->GetViewportPosition(bufferIndex);
239     const Vector2& size = mSceneObject->GetViewportSize(bufferIndex);
240     viewPort.x = position.x;
241     viewPort.y = position.y;
242     viewPort.width = size.width;
243     viewPort.height = size.height;
244   }
245 }
246
247 void RenderTask::SetClearColor( const Vector4& color )
248 {
249   if ( mClearColor != color )
250   {
251     mClearColor = color;
252
253     if ( mSceneObject )
254     {
255       // mSceneObject is being used in a separate thread; queue a message to set the value
256       StagePtr stage = Stage::GetCurrent();
257       BakeClearColorMessage( stage->GetUpdateInterface(), *mSceneObject, color );
258     }
259   }
260 }
261
262 const Vector4& RenderTask::GetClearColor() const
263 {
264   StagePtr stage = Stage::GetCurrent();
265   return mSceneObject->GetClearColor(stage->GetEventBufferIndex());
266 }
267
268 void RenderTask::SetClearEnabled( bool enabled )
269 {
270   if ( mClearEnabled != enabled )
271   {
272     mClearEnabled = enabled;
273
274     if ( mSceneObject )
275     {
276       // mSceneObject is being used in a separate thread; queue a message to set the value
277       SetClearEnabledMessage( mEventToUpdate, *mSceneObject, mClearEnabled );
278     }
279   }
280 }
281
282 bool RenderTask::GetClearEnabled() const
283 {
284   return mClearEnabled;
285 }
286
287 void RenderTask::SetRefreshRate( unsigned int refreshRate )
288 {
289   DALI_LOG_TRACE_METHOD_FMT(gLogRender, "this:%p  rate:%d\n", this, refreshRate);
290   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::SetRefreshRate(this:%p, %d)\n", this, refreshRate);
291
292   mRefreshRate = refreshRate; // cached for GetRefreshRate()
293
294   // Note - even when refreshRate is the same as mRefreshRate, a message should be sent
295
296   if ( mSceneObject )
297   {
298     // mSceneObject is being used in a separate thread; queue a message to set the value
299     SetRefreshRateMessage( mEventToUpdate, *mSceneObject, refreshRate );
300   }
301 }
302
303 unsigned int RenderTask::GetRefreshRate() const
304 {
305   return mRefreshRate;
306 }
307
308 bool RenderTask::IsHittable( Vector2& screenCoords ) const
309 {
310   // True when input is enabled, source & camera actor are valid
311   bool inputEnabled( false );
312
313   Actor* sourceActor = GetSourceActor();
314   CameraActor* cameraActor = GetCameraActor();
315
316   if ( mInputEnabled  &&
317        NULL != sourceActor    &&
318        sourceActor->OnStage() &&
319        NULL != cameraActor    &&
320        cameraActor->OnStage() )
321   {
322     // If the actors are rendered off-screen, then the screen coordinates must be converted
323     // and the conversion function will tell us if they are inside or outside
324     if ( TranslateCoordinates( screenCoords ) )
325     {
326       // This is a suitable render-task for input handling
327       inputEnabled = true;
328     }
329   }
330
331   return inputEnabled;
332 }
333
334 bool RenderTask::TranslateCoordinates( Vector2& screenCoords ) const
335 {
336   // return true for on-screen tasks
337   bool inside( true );
338   // If the actors are rendered off-screen, then the screen coordinates must be converted
339   // the function should only be called for offscreen tasks
340   if( mFrameBufferImage && mMappingConnector.mActor )
341   {
342     CameraActor* localCamera = GetCameraActor();
343     StagePtr stage = Stage::GetCurrent();
344     CameraActor& defaultCamera = stage->GetDefaultCameraActor();
345     if( localCamera )
346     {
347       Viewport viewport;
348       Vector2 size( stage->GetSize() );
349       viewport.x = viewport.y = 0;
350       viewport.width = size.width;
351       viewport.height = size.height;
352
353       float localX, localY;
354       inside = mMappingConnector.mActor->ScreenToLocal(defaultCamera.GetViewMatrix(), defaultCamera.GetProjectionMatrix(), viewport, localX, localY, screenCoords.x, screenCoords.y);
355       Vector3 actorSize = mMappingConnector.mActor->GetCurrentSize();
356       if( inside && localX >= 0.f && localX <= actorSize.x && localY >= 0.f && localY <= actorSize.y)
357       {
358         screenCoords.x = localX;
359         screenCoords.y = localY;
360         if( !localCamera->GetInvertYAxis() )
361         {
362           screenCoords.y = actorSize.y - localY;
363         }
364       }
365       else
366       {
367         inside = false;
368       }
369     }
370     else
371     {
372       inside = false;
373     }
374   }
375   else if ( mFrameBufferImage && mScreenToFrameBufferFunction )
376   {
377     inside = mScreenToFrameBufferFunction( screenCoords );
378   }
379   return inside;
380 }
381
382 bool RenderTask::IsSystemLevel() const
383 {
384   return mIsSystemLevel;
385 }
386
387 SceneGraph::RenderTask* RenderTask::CreateSceneObject()
388 {
389   // This should only be called once, with no existing scene-object
390   DALI_ASSERT_DEBUG( NULL == mSceneObject );
391
392   // Keep the raw-pointer until DiscardSceneObject is called
393   mSceneObject = SceneGraph::RenderTask::New();
394
395   // if we have a frame buffer we need to track connection status then send a message to set the frame buffer id in case it has changed since last time we were on stage
396   unsigned int resourceId = 0;
397   if(mFrameBufferImage)
398   {
399     GetImplementation(mFrameBufferImage).Connect();
400
401     resourceId = GetImplementation( mFrameBufferImage ).GetResourceId();
402   }
403
404   // mSceneObject is being used in a separate thread; queue a message to set the value
405   SetFrameBufferIdMessage( mEventToUpdate, *mSceneObject, resourceId );
406
407   // Send messages to set other properties that may have changed since last time we were on stage
408   SetExclusiveMessage( mEventToUpdate, *mSceneObject, mExclusive );
409   SetClearColorMessage(  mEventToUpdate, *mSceneObject, mClearColor );
410   SetClearEnabledMessage(  mEventToUpdate, *mSceneObject, mClearEnabled );
411   SetRefreshRateMessage(  mEventToUpdate, *mSceneObject, mRefreshRate );
412
413   // Caller takes ownership
414   return mSceneObject;
415 }
416
417 SceneGraph::RenderTask* RenderTask::GetRenderTaskSceneObject()
418 {
419   return mSceneObject;
420 }
421
422 void RenderTask::DiscardSceneObject()
423 {
424   // mSceneObject is not owned; throw away the raw-pointer
425   mSceneObject = NULL;
426
427   // if we have a frame buffer we need to track connection status
428   if(mFrameBufferImage)
429   {
430     GetImplementation(mFrameBufferImage).Disconnect();
431   }
432 }
433
434 /********************************************************************************
435  ********************************************************************************
436  ********************************   PROPERTY METHODS   **************************
437  ********************************************************************************
438  ********************************************************************************/
439
440 bool RenderTask::IsSceneObjectRemovable() const
441 {
442   return false; // The scene object is permanently "on stage" whilst this object is alive
443 }
444
445 unsigned int RenderTask::GetDefaultPropertyCount() const
446 {
447   return DEFAULT_PROPERTY_COUNT;
448 }
449
450 const std::string& RenderTask::GetDefaultPropertyName( Property::Index index ) const
451 {
452   // ProxyObject guarantees that index is within range
453   return DEFAULT_PROPERTY_NAMES[index];
454 }
455
456 Property::Index RenderTask::GetDefaultPropertyIndex(const std::string& name) const
457 {
458   Property::Index index = Property::INVALID_INDEX;
459
460   // Lazy initialization of static sDefaultPropertyLookup
461   if (!sDefaultPropertyLookup)
462   {
463     sDefaultPropertyLookup = new DefaultPropertyLookup();
464
465     for (int i=0; i<DEFAULT_PROPERTY_COUNT; ++i)
466     {
467       (*sDefaultPropertyLookup)[DEFAULT_PROPERTY_NAMES[i]] = i;
468     }
469   }
470   DALI_ASSERT_DEBUG( NULL != sDefaultPropertyLookup );
471
472   // Look for name in default properties
473   DefaultPropertyLookup::const_iterator result = sDefaultPropertyLookup->find( name );
474   if ( sDefaultPropertyLookup->end() != result )
475   {
476     index = result->second;
477   }
478
479   return index;
480 }
481
482 bool RenderTask::IsDefaultPropertyWritable(Property::Index index) const
483 {
484   return true;
485 }
486
487 bool RenderTask::IsDefaultPropertyAnimatable(Property::Index index) const
488 {
489   return true;
490 }
491
492 Property::Type RenderTask::GetDefaultPropertyType(Property::Index index) const
493 {
494   // ProxyObject guarantees that index is within range
495   return DEFAULT_PROPERTY_TYPES[index];
496 }
497
498 void RenderTask::SetDefaultProperty( Property::Index index, const Property::Value& property )
499 {
500   // ProxyObject guarantees the property is writable and index is in range
501   switch ( index )
502   {
503     case Dali::RenderTask::VIEWPORT_POSITION:
504     {
505       SetViewportPosition( property.Get<Vector2>() );
506       break;
507     }
508     case Dali::RenderTask::VIEWPORT_SIZE:
509     {
510       SetViewportSize( property.Get<Vector2>() );
511       break;
512     }
513     case Dali::RenderTask::CLEAR_COLOR:
514     {
515       SetClearColor( property.Get<Vector4>() );
516       break;
517     }
518
519     default:
520     {
521       DALI_ASSERT_ALWAYS(false && "RenderTask property index out of range"); // should not come here
522       break;
523     }
524   }
525 }
526
527 void RenderTask::SetCustomProperty( Property::Index /*index*/, const CustomProperty& /*entry*/, const Property::Value& /*value*/ )
528 {
529   // TODO: support them, it doesn't hurt.
530   DALI_ASSERT_ALWAYS( 0 && "RenderTask does not support custom properties");
531 }
532
533 Property::Value RenderTask::GetDefaultProperty(Property::Index index) const
534 {
535   Property::Value value;
536
537   // ProxyObject guarantees that index is within range
538   switch ( index )
539   {
540
541     case Dali::RenderTask::VIEWPORT_POSITION:
542     {
543       value = GetCurrentViewportPosition();
544       break;
545     }
546     case Dali::RenderTask::VIEWPORT_SIZE:
547     {
548       value = GetCurrentViewportSize();
549       break;
550     }
551     case Dali::RenderTask::CLEAR_COLOR:
552     {
553       value = GetClearColor();
554       break;
555     }
556
557     default:
558     {
559       DALI_ASSERT_ALWAYS(false && "RenderTask property index out of range"); // should not come here
560       break;
561     }
562   }
563
564   return value;
565 }
566
567 void RenderTask::InstallSceneObjectProperty( SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index )
568 {
569   // TODO: support them, it doesn't hurt.
570   DALI_ASSERT_ALWAYS( 0 && "RenderTask does not support custom properties" );
571 }
572
573 const SceneGraph::PropertyOwner* RenderTask::GetSceneObject() const
574 {
575   return mSceneObject;
576 }
577
578 const SceneGraph::PropertyBase* RenderTask::GetSceneObjectAnimatableProperty( Property::Index index ) const
579 {
580   DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
581
582   const SceneGraph::PropertyBase* property( NULL );
583
584   // This method should only return a property which is part of the scene-graph
585   if( mSceneObject != NULL )
586   {
587     switch ( index )
588     {
589       case Dali::RenderTask::VIEWPORT_POSITION:
590         property = &mSceneObject->mViewportPosition;
591         break;
592
593       case Dali::RenderTask::VIEWPORT_SIZE:
594         property = &mSceneObject->mViewportSize;
595         break;
596
597       case Dali::RenderTask::CLEAR_COLOR:
598         property = &mSceneObject->mClearColor;
599         break;
600
601       default:
602         break;
603     }
604   }
605
606   return property;
607 }
608
609 const PropertyInputImpl* RenderTask::GetSceneObjectInputProperty( Property::Index index ) const
610 {
611   const PropertyInputImpl* property( NULL );
612   if( mSceneObject != NULL )
613   {
614     switch ( index )
615     {
616       case Dali::RenderTask::VIEWPORT_POSITION:
617         property = &mSceneObject->mViewportPosition;
618         break;
619
620       case Dali::RenderTask::VIEWPORT_SIZE:
621         property = &mSceneObject->mViewportSize;
622         break;
623
624       case Dali::RenderTask::CLEAR_COLOR:
625         property = &mSceneObject->mViewportSize;
626         break;
627
628       default:
629         break;
630     }
631   }
632
633   return property;
634 }
635
636 bool RenderTask::HasFinished()
637 {
638   bool finished = false;
639   const unsigned int counter = mSceneObject->GetRenderedOnceCounter();
640
641   if( mRefreshOnceCounter < counter )
642   {
643     finished = true;
644     mRefreshOnceCounter = counter;
645   }
646
647   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::HasFinished()=%s SCRT:%p  SC\n", finished?"T":"F", mSceneObject);
648
649   return finished;
650 }
651
652 void RenderTask::EmitSignalFinish()
653 {
654   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::EmitSignalFinish(this:%p)\n", this);
655
656   if( !mSignalFinishedV2.Empty() )
657   {
658     Dali::RenderTask handle( this );
659     mSignalFinishedV2.Emit(handle );
660   }
661 }
662
663 Dali::RenderTask::RenderTaskSignalV2& RenderTask::FinishedSignal()
664 {
665   return mSignalFinishedV2;
666 }
667
668 bool RenderTask::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
669 {
670   bool connected( true );
671   RenderTask* renderTask = dynamic_cast<RenderTask*>(object);
672
673   if ( Dali::RenderTask::SIGNAL_FINISHED == signalName )
674   {
675     renderTask->FinishedSignal().Connect( tracker, functor );
676   }
677   else
678   {
679     // signalName does not match any signal
680     connected = false;
681   }
682
683   return connected;
684 }
685
686 RenderTask::RenderTask( EventToUpdate& eventToUpdate, bool isSystemLevel )
687 : mEventToUpdate( eventToUpdate ),
688   mSceneObject( NULL ),
689   mSourceConnector( Connector::SOURCE_CONNECTOR, *this ),
690   mCameraConnector( Connector::CAMERA_CONNECTOR, *this ),
691   mMappingConnector( Connector::MAPPING_CONNECTOR, *this  ),
692   mClearColor( Dali::RenderTask::DEFAULT_CLEAR_COLOR ),
693   mRefreshRate( Dali::RenderTask::DEFAULT_REFRESH_RATE ),
694   mRefreshOnceCounter( 0u ),
695   mScreenToFrameBufferFunction( Dali::RenderTask::DEFAULT_SCREEN_TO_FRAMEBUFFER_FUNCTION ),
696   mExclusive( Dali::RenderTask::DEFAULT_EXCLUSIVE ),
697   mInputEnabled( Dali::RenderTask::DEFAULT_INPUT_ENABLED ),
698   mClearEnabled( Dali::RenderTask::DEFAULT_CLEAR_ENABLED ),
699   mIsSystemLevel( isSystemLevel )
700 {
701   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::RenderTask(this:%p)\n", this);
702 }
703
704 RenderTask::~RenderTask()
705 {
706   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::~RenderTask(this:%p)\n", this);
707 }
708
709 // Helper class for connecting Nodes to the scene-graph RenderTask
710
711 RenderTask::Connector::Connector( Type type, RenderTask& renderTask )
712 : mType( type ),
713   mRenderTask( renderTask ),
714   mActor( NULL )
715 {
716 }
717
718 RenderTask::Connector::~Connector()
719 {
720   SetActor( NULL );
721 }
722
723 void RenderTask::Connector::SetActor( Actor* actor )
724 {
725   if ( mActor != actor )
726   {
727     if ( mActor )
728     {
729       mActor->RemoveObserver( *this );
730     }
731
732     mActor = actor;
733
734     if ( mActor )
735     {
736       mActor->AddObserver( *this );
737     }
738
739     UpdateRenderTask();
740   }
741 }
742
743 void RenderTask::Connector::SceneObjectAdded( ProxyObject& proxy )
744 {
745   UpdateRenderTask();
746 }
747
748 void RenderTask::Connector::SceneObjectRemoved( ProxyObject& proxy )
749 {
750   UpdateRenderTask();
751 }
752
753 void RenderTask::Connector::ProxyDestroyed( ProxyObject& proxy )
754 {
755   mActor = NULL;
756
757   UpdateRenderTask();
758 }
759
760 void RenderTask::Connector::UpdateRenderTask()
761 {
762   // Guard to allow handle destruction after Core has been destroyed
763   if( Internal::Stage::IsInstalled() &&
764       mRenderTask.mSceneObject )
765   {
766     const SceneGraph::Node* node( NULL );
767
768     // Check whether a Node exists in the scene-graph
769     if ( NULL != mActor )
770     {
771       const SceneGraph::PropertyOwner* object = mActor->GetSceneObject();
772       if ( NULL != object )
773       {
774         // actors only point to nodes as their scene objects
775         node = static_cast< const SceneGraph::Node* >( object );
776       }
777     }
778
779     //the mapping node is not used in the scene graph
780     if ( SOURCE_CONNECTOR == mType )
781     {
782       SetSourceNodeMessage( mRenderTask.mEventToUpdate, *(mRenderTask.mSceneObject), node );
783     }
784     else if( CAMERA_CONNECTOR == mType )
785     {
786       SetCameraNodeMessage( mRenderTask.mEventToUpdate, *(mRenderTask.mSceneObject), node );
787     }
788   }
789 }
790
791 } // namespace Internal
792
793 } // namespace Dali