Remove Geometry scene object
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / image-actor-impl.cpp
1 /*
2  * Copyright (c) 2014 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/actors/image-actor-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <cstring> // for strcmp
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/animation/constraints.h> // for EqualToConstraint
26 #include <dali/public-api/object/type-registry.h>
27 #include <dali/devel-api/scripting/scripting.h>
28 #include <dali/internal/event/animation/constraint-impl.h>
29 #include <dali/internal/event/common/property-helper.h>
30 #include <dali/internal/event/effects/shader-effect-impl.h>
31 #include <dali/internal/event/images/image-connector.h>
32 #include <dali/internal/event/images/nine-patch-image-impl.h>
33
34 namespace Dali
35 {
36
37 namespace Internal
38 {
39
40 namespace
41 {
42
43 // Properties
44
45 //              Name           Type   writable animatable constraint-input  enum for index-checking
46 DALI_PROPERTY_TABLE_BEGIN
47 DALI_PROPERTY( "pixelArea",    RECTANGLE, true,    false,   true,    Dali::ImageActor::Property::PIXEL_AREA )
48 DALI_PROPERTY( "style",        STRING,    true,    false,   true,    Dali::ImageActor::Property::STYLE      )
49 DALI_PROPERTY( "border",       VECTOR4,   true,    false,   true,    Dali::ImageActor::Property::BORDER     )
50 DALI_PROPERTY( "image",        MAP,       true,    false,   false,   Dali::ImageActor::Property::IMAGE      )
51 DALI_PROPERTY_TABLE_END( DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX )
52
53 BaseHandle Create()
54 {
55   return Dali::ImageActor::New();
56 }
57
58 TypeRegistration mType( typeid( Dali::ImageActor ), typeid( Dali::Actor ), Create );
59
60 struct GridVertex
61 {
62   GridVertex( float positionX, float positionY, const Vector2& size )
63   : mPosition( positionX*size.x, positionY*size.y, 0.f ),
64     mTextureCoord( positionX+0.5f, positionY+0.5f )
65   {
66   }
67
68   Vector3 mPosition;
69   Vector2 mTextureCoord;
70 };
71
72 GeometryPtr CreateGeometry( unsigned int gridWidth, unsigned int gridHeight, const Vector2& size )
73 {
74   // Create vertices
75   std::vector< GridVertex > vertices;
76   vertices.reserve( ( gridWidth + 1 ) * ( gridHeight + 1 ) );
77
78   for( unsigned int y = 0u; y < gridHeight + 1; ++y )
79   {
80     float yPos = (float)y / gridHeight;
81     for( unsigned int x = 0u; x < gridWidth + 1; ++x )
82     {
83       float xPos = (float)x / gridWidth;
84       vertices.push_back( GridVertex( xPos - 0.5f, yPos - 0.5f, size ) );
85     }
86   }
87
88   // Create indices
89   Vector< unsigned short > indices;
90   indices.Reserve( ( gridWidth + 2 ) * gridHeight * 2 - 2);
91
92   for( unsigned int row = 0u; row < gridHeight; ++row )
93   {
94     unsigned int rowStartIndex = row*(gridWidth+1u);
95     unsigned int nextRowStartIndex = rowStartIndex + gridWidth +1u;
96
97     if( row != 0u ) // degenerate index on non-first row
98     {
99       indices.PushBack( rowStartIndex );
100     }
101
102     for( unsigned int column = 0u; column < gridWidth+1u; column++) // main strip
103     {
104       indices.PushBack( rowStartIndex + column);
105       indices.PushBack( nextRowStartIndex + column);
106     }
107
108     if( row != gridHeight-1u ) // degenerate index on non-last row
109     {
110       indices.PushBack( nextRowStartIndex + gridWidth );
111     }
112   }
113
114   Property::Map vertexFormat;
115   vertexFormat[ "aPosition" ] = Property::VECTOR3;
116   vertexFormat[ "aTexCoord" ] = Property::VECTOR2;
117   PropertyBufferPtr vertexPropertyBuffer = PropertyBuffer::New( vertexFormat );
118   if( vertices.size() > 0 )
119   {
120     vertexPropertyBuffer->SetData( &vertices[ 0 ], vertices.size() );
121   }
122
123   // Create the geometry object
124   GeometryPtr geometry = Geometry::New();
125   geometry->AddVertexBuffer( *vertexPropertyBuffer );
126   if( indices.Size() > 0 )
127   {
128     geometry->SetIndexBuffer( &indices[0], indices.Size() );
129   }
130   geometry->SetGeometryType( Dali::Geometry::TRIANGLE_STRIP );
131
132   return geometry;
133 }
134
135 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
136   attribute mediump vec3 aPosition;\n
137   attribute mediump vec2 aTexCoord;\n
138   varying mediump vec2 vTexCoord;\n
139   uniform mediump mat4 uMvpMatrix;\n
140   uniform mediump vec3 uSize;\n
141   uniform mediump vec4 sTextureRect;\n
142   \n
143   void main()\n
144   {\n
145     gl_Position = uMvpMatrix * vec4(aPosition, 1.0);\n
146     vTexCoord = aTexCoord;\n
147   }\n
148 );
149
150 const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
151   varying mediump vec2 vTexCoord;\n
152   uniform sampler2D sTexture;\n
153   uniform lowp vec4 uColor;\n
154   \n
155   void main()\n
156   {\n
157     gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
158   }\n
159 );
160
161 const char * const TEXTURE_RECT_UNIFORM_NAME( "sTextureRect" );
162
163 const int INVALID_RENDERER_ID = -1;
164 const uint16_t MAXIMUM_GRID_SIZE = 2048;
165 }
166
167 ImageActorPtr ImageActor::New()
168 {
169   ImageActorPtr actor( new ImageActor );
170
171   // Second-phase construction of base class
172   actor->Initialize();
173
174   //Create the renderer
175   actor->mRenderer = Renderer::New();
176
177   GeometryPtr quad  = CreateGeometry( 1u, 1u, Vector2::ONE );
178   actor->mRenderer->SetGeometry( *quad );
179
180   ShaderPtr shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER, Dali::Shader::HINT_NONE );
181   actor->mRenderer->SetShader( *shader );
182   TextureSetPtr textureSet = TextureSet::New();
183   actor->mRenderer->SetTextures( *textureSet );
184
185   return actor;
186 }
187
188 void ImageActor::OnInitialize()
189 {
190   // TODO: Remove this, at the moment its needed for size negotiation to work
191   SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
192 }
193
194 void ImageActor::SetImage( ImagePtr& image )
195 {
196   if( !image )
197   {
198     if( mRendererIndex != INVALID_RENDERER_ID )
199     {
200       RemoveRenderer( mRendererIndex );
201       mRendererIndex = INVALID_RENDERER_ID;
202     }
203   }
204   else
205   {
206     SamplerPtr sampler = Sampler::New();
207     sampler->SetFilterMode( mMinFilter, mMagFilter );
208
209     TextureSet* textureSet( mRenderer->GetTextures() );
210     textureSet->SetImage( 0u, image.Get() );
211     textureSet->SetSampler( 0u, sampler );
212
213     if( mRendererIndex == INVALID_RENDERER_ID )
214     {
215       mRendererIndex = AddRenderer( *mRenderer );
216     }
217
218     if( !mIsPixelAreaSet )
219     {
220       mPixelArea = PixelArea( 0, 0, image->GetWidth(), image->GetHeight() );
221     }
222
223     RelayoutRequest();
224     UpdateTexureRect();
225   }
226 }
227
228 ImagePtr ImageActor::GetImage() const
229 {
230   return mRenderer->GetTextures()->GetImage( 0u );
231 }
232
233 void ImageActor::SetPixelArea( const PixelArea& pixelArea )
234 {
235   mPixelArea = pixelArea;
236   mIsPixelAreaSet = true;
237
238   RelayoutRequest();
239   UpdateTexureRect();
240 }
241
242 const ImageActor::PixelArea& ImageActor::GetPixelArea() const
243 {
244   return mPixelArea;
245 }
246
247 bool ImageActor::IsPixelAreaSet() const
248 {
249   return mIsPixelAreaSet;
250 }
251
252 void ImageActor::ClearPixelArea()
253 {
254   mIsPixelAreaSet = false;
255
256   int imageWidth = 0;
257   int imageHeight = 0;
258   ImagePtr image = GetImage();
259   if( image )
260   {
261     imageWidth = image->GetWidth();
262     imageHeight = image->GetHeight();
263   }
264
265   mPixelArea = PixelArea( 0, 0, imageWidth, imageHeight );
266
267   RelayoutRequest();
268   UpdateTexureRect();
269 }
270
271 void ImageActor::SetStyle( Dali::ImageActor::Style style )
272 {
273   DALI_LOG_WARNING( "SetStyle Deprecated. Only STYLE_QUAD supported." );
274   mStyle = style;
275 }
276
277 Dali::ImageActor::Style ImageActor::GetStyle() const
278 {
279   DALI_LOG_WARNING( "GetStyle Deprecated. Only STYLE_QUAD supported." );
280   return mStyle;
281 }
282
283 void ImageActor::SetNinePatchBorder( const Vector4& border )
284 {
285   DALI_LOG_WARNING( "SetNinePatchBorder Deprecated. Only STYLE_QUAD supported." );
286   mNinePatchBorder = border;
287 }
288
289 Vector4 ImageActor::GetNinePatchBorder() const
290 {
291   DALI_LOG_WARNING( "GetNinePatchBorder Deprecated. Only STYLE_QUAD supported." );
292   return mNinePatchBorder;
293 }
294
295 ImageActor::ImageActor()
296 : Actor( Actor::BASIC ),
297   mActorSize( Vector2::ZERO ),
298   mGridSize( 1u, 1u ),
299   mRendererIndex( INVALID_RENDERER_ID ),
300   mMinFilter( FilterMode::DEFAULT ),
301   mMagFilter( FilterMode::DEFAULT ),
302   mStyle( Dali::ImageActor::STYLE_QUAD ),
303   mIsPixelAreaSet( false )
304 {
305 }
306
307 ImageActor::~ImageActor()
308 {
309 }
310
311 Vector3 ImageActor::GetNaturalSize() const
312 {
313   Vector2 naturalSize( CalculateNaturalSize() );
314   return Vector3( naturalSize.width, naturalSize.height, 0.f );
315 }
316
317 Vector2 ImageActor::CalculateNaturalSize() const
318 {
319   // if no image then natural size is 0
320   Vector2 size( 0.0f, 0.0f );
321
322   ImagePtr image = GetImage();
323   if( image )
324   {
325     if( IsPixelAreaSet() )
326     {
327       PixelArea area(GetPixelArea());
328       size.width = area.width;
329       size.height = area.height;
330     }
331     else
332     {
333       size = image->GetNaturalSize();
334     }
335   }
336
337   return size;
338 }
339
340 void ImageActor::UpdateGeometry()
341 {
342   uint16_t gridWidth = 1u;
343   uint16_t gridHeight = 1u;
344
345   if( mShaderEffect )
346   {
347     Vector2 gridSize = mShaderEffect->GetGridSize( Vector2(mPixelArea.width, mPixelArea.height) );
348
349     //limit the grid size
350     gridWidth = std::min( MAXIMUM_GRID_SIZE, static_cast<uint16_t>(gridSize.width) );
351     gridHeight = std::min( MAXIMUM_GRID_SIZE, static_cast<uint16_t>(gridSize.height) );
352   }
353
354   mGridSize.SetWidth( gridWidth );
355   mGridSize.SetHeight( gridHeight );
356
357   GeometryPtr geometry = CreateGeometry( gridWidth, gridHeight, mActorSize );
358   mRenderer->SetGeometry( *geometry );
359 }
360 void ImageActor::UpdateTexureRect()
361 {
362   Vector4 textureRect( 0.f, 0.f, 1.f, 1.f );
363
364   ImagePtr image = GetImage();
365   if( mIsPixelAreaSet && image )
366   {
367     const float uScale = 1.0f / float(image->GetWidth());
368     const float vScale = 1.0f / float(image->GetHeight());
369     // bottom left
370     textureRect.x = uScale * float(mPixelArea.x);
371     textureRect.y = vScale * float(mPixelArea.y);
372     // top right
373     textureRect.z  = uScale * float(mPixelArea.x + mPixelArea.width);
374     textureRect.w = vScale * float(mPixelArea.y + mPixelArea.height);
375   }
376
377   TextureSet* textureSet = mRenderer->GetTextures();
378   textureSet->RegisterProperty( TEXTURE_RECT_UNIFORM_NAME, textureRect );
379 }
380
381 unsigned int ImageActor::GetDefaultPropertyCount() const
382 {
383   return Actor::GetDefaultPropertyCount() + DEFAULT_PROPERTY_COUNT;
384 }
385
386 void ImageActor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
387 {
388   Actor::GetDefaultPropertyIndices( indices ); // Actor class properties
389
390   indices.Reserve( indices.Size() + DEFAULT_PROPERTY_COUNT );
391
392   int index = DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
393   for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i, ++index )
394   {
395     indices.PushBack( index );
396   }
397 }
398
399 bool ImageActor::IsDefaultPropertyWritable( Property::Index index ) const
400 {
401   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
402   {
403     return Actor::IsDefaultPropertyWritable(index);
404   }
405
406   index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
407   if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
408   {
409     return DEFAULT_PROPERTY_DETAILS[ index ].writable;
410   }
411
412   return false;
413 }
414
415 bool ImageActor::IsDefaultPropertyAnimatable( Property::Index index ) const
416 {
417   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
418   {
419     return Actor::IsDefaultPropertyAnimatable( index );
420   }
421
422   index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
423   if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
424   {
425     return DEFAULT_PROPERTY_DETAILS[ index ].animatable;
426   }
427
428   return false;
429 }
430
431 bool ImageActor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
432 {
433   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
434   {
435     return Actor::IsDefaultPropertyAConstraintInput( index );
436   }
437
438   index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
439   if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
440   {
441     return DEFAULT_PROPERTY_DETAILS[ index ].constraintInput;
442   }
443
444   return false;
445 }
446
447 Property::Type ImageActor::GetDefaultPropertyType( Property::Index index ) const
448 {
449   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
450   {
451     return Actor::GetDefaultPropertyType( index );
452   }
453
454   index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
455   if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
456   {
457     return DEFAULT_PROPERTY_DETAILS[index].type;
458   }
459
460   // index out-of-bounds
461   return Property::NONE;
462 }
463
464 const char* ImageActor::GetDefaultPropertyName( Property::Index index ) const
465 {
466   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
467   {
468     return Actor::GetDefaultPropertyName(index);
469   }
470
471   index -= DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
472   if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
473   {
474     return DEFAULT_PROPERTY_DETAILS[index].name;
475   }
476
477   // index out-of-bounds
478   return NULL;
479 }
480
481 Property::Index ImageActor::GetDefaultPropertyIndex(const std::string& name) const
482 {
483   Property::Index index = Property::INVALID_INDEX;
484
485   // Look for name in default properties
486   for( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
487   {
488     const Internal::PropertyDetails* property = &DEFAULT_PROPERTY_DETAILS[ i ];
489     if( 0 == strcmp( name.c_str(), property->name ) ) // Don't want to convert rhs to string
490     {
491       index = i + DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX;
492       break;
493     }
494   }
495
496   // If not found, check in base class
497   if( Property::INVALID_INDEX == index )
498   {
499     index = Actor::GetDefaultPropertyIndex( name );
500   }
501   return index;
502 }
503
504 void ImageActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
505 {
506   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
507   {
508     Actor::SetDefaultProperty( index, propertyValue );
509   }
510   else
511   {
512     switch(index)
513     {
514       case Dali::ImageActor::Property::PIXEL_AREA:
515       {
516         SetPixelArea(propertyValue.Get<Rect<int> >());
517         break;
518       }
519       case Dali::ImageActor::Property::STYLE:
520       {
521         //not supported
522         break;
523       }
524       case Dali::ImageActor::Property::BORDER:
525       {
526         //not supported
527         break;
528       }
529       case Dali::ImageActor::Property::IMAGE:
530       {
531         Dali::Image img = Scripting::NewImage( propertyValue );
532         if(img)
533         {
534           ImagePtr image( &GetImplementation(img) );
535           SetImage( image );
536         }
537         else
538         {
539           DALI_LOG_WARNING("Cannot create image from property value\n");
540         }
541         break;
542       }
543       default:
544       {
545         DALI_LOG_WARNING("Unknown property (%d)\n", index);
546         break;
547       }
548     } // switch(index)
549
550   } // else
551 }
552
553 Property::Value ImageActor::GetDefaultProperty( Property::Index index ) const
554 {
555   Property::Value ret;
556   if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
557   {
558     ret = Actor::GetDefaultProperty( index );
559   }
560   else
561   {
562     switch( index )
563     {
564       case Dali::ImageActor::Property::PIXEL_AREA:
565       {
566         Rect<int> r = GetPixelArea();
567         ret = r;
568         break;
569       }
570       case Dali::ImageActor::Property::STYLE:
571       {
572         //not supported
573         break;
574       }
575       case Dali::ImageActor::Property::BORDER:
576       {
577         //not supported
578         break;
579       }
580       case Dali::ImageActor::Property::IMAGE:
581       {
582         Property::Map map;
583         Scripting::CreatePropertyMap( Dali::Image( GetImage().Get() ), map );
584         ret = Property::Value( map );
585         break;
586       }
587       default:
588       {
589         DALI_LOG_WARNING( "Unknown property (%d)\n", index );
590         break;
591       }
592     } // switch(index)
593   }
594
595   return ret;
596 }
597
598 void ImageActor::SetSortModifier(float modifier)
599 {
600   mRenderer->SetDepthIndex( modifier );
601 }
602
603 float ImageActor::GetSortModifier() const
604 {
605   return mRenderer->GetDepthIndex();
606 }
607
608 void ImageActor::SetBlendMode( BlendingMode::Type mode )
609 {
610   mRenderer->SetBlendMode( mode );
611 }
612
613 BlendingMode::Type ImageActor::GetBlendMode() const
614 {
615   return mRenderer->GetBlendMode();
616 }
617
618 void ImageActor::SetBlendFunc( BlendingFactor::Type srcFactorRgba,   BlendingFactor::Type destFactorRgba )
619 {
620   mRenderer->SetBlendFunc( srcFactorRgba, destFactorRgba, srcFactorRgba, destFactorRgba );
621 }
622
623 void ImageActor::SetBlendFunc( BlendingFactor::Type srcFactorRgb,   BlendingFactor::Type destFactorRgb,
624                                BlendingFactor::Type srcFactorAlpha, BlendingFactor::Type destFactorAlpha )
625 {
626   mRenderer->SetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
627 }
628
629 void ImageActor::GetBlendFunc( BlendingFactor::Type& srcFactorRgb,   BlendingFactor::Type& destFactorRgb,
630                                BlendingFactor::Type& srcFactorAlpha, BlendingFactor::Type& destFactorAlpha ) const
631 {
632   mRenderer->GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
633 }
634
635 void ImageActor::SetBlendEquation( BlendingEquation::Type equationRgba )
636 {
637   mRenderer->SetBlendEquation( equationRgba, equationRgba );
638 }
639
640 void ImageActor::SetBlendEquation( BlendingEquation::Type equationRgb, BlendingEquation::Type equationAlpha )
641 {
642   mRenderer->SetBlendEquation( equationRgb, equationAlpha );
643 }
644
645 void ImageActor::GetBlendEquation( BlendingEquation::Type& equationRgb, BlendingEquation::Type& equationAlpha ) const
646 {
647   mRenderer->GetBlendEquation( equationRgb, equationAlpha );
648 }
649
650 void ImageActor::SetBlendColor( const Vector4& color )
651 {
652   mBlendColor = color;
653   mRenderer->SetBlendColor( mBlendColor );
654 }
655
656 const Vector4& ImageActor::GetBlendColor() const
657 {
658   return mBlendColor;
659 }
660
661 void ImageActor::SetFilterMode( FilterMode::Type minFilter, FilterMode::Type magFilter )
662 {
663   mMinFilter = minFilter;
664   mMagFilter = magFilter;
665
666   SamplerPtr sampler = Sampler::New();
667   sampler->SetFilterMode( minFilter, magFilter );
668   mRenderer->GetTextures()->SetSampler( 0u, sampler.Get() );
669 }
670
671 void ImageActor::GetFilterMode( FilterMode::Type& minFilter, FilterMode::Type& magFilter ) const
672 {
673   minFilter = mMinFilter;
674   magFilter = mMagFilter;
675 }
676
677 void ImageActor::SetShaderEffect( ShaderEffect& effect )
678 {
679   if( mShaderEffect )
680   {
681     mShaderEffect->Disconnect( this );
682   }
683
684   mShaderEffect = ShaderEffectPtr( &effect );
685   effect.Connect( this );
686
687   ShaderPtr shader = mShaderEffect->GetShader();
688   mRenderer->SetShader( *shader );
689
690   EffectImageUpdated();
691
692   UpdateGeometry();
693 }
694
695 ShaderEffectPtr ImageActor::GetShaderEffect() const
696 {
697   return mShaderEffect;
698 }
699
700 void ImageActor::RemoveShaderEffect()
701 {
702   if( mShaderEffect )
703   {
704     mShaderEffect->Disconnect( this );
705     // change to the standard shader and quad geometry
706     ShaderPtr shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER, Dali::Shader::HINT_NONE );
707     mRenderer->SetShader( *shader );
708     mShaderEffect.Reset();
709
710     UpdateGeometry();
711   }
712 }
713
714 void ImageActor::EffectImageUpdated()
715 {
716   if( mShaderEffect )
717   {
718     Dali::Image effectImage = mShaderEffect->GetEffectImage();
719     if( effectImage )
720     {
721       Image& effectImageImpl = GetImplementation( effectImage );
722       mRenderer->GetTextures()->SetImage( 1u, &effectImageImpl );
723     }
724     else
725     {
726        mRenderer->GetTextures()->SetImage( 1u, 0 );
727     }
728   }
729 }
730
731 void ImageActor::OnRelayout( const Vector2& size, RelayoutContainer& container )
732 {
733   if( mActorSize != size )
734   {
735     mActorSize = size;
736     UpdateGeometry();
737   }
738 }
739
740 void ImageActor::OnSizeSet( const Vector3& targetSize )
741 {
742   Vector2 size( targetSize.x, targetSize.y );
743   if( mActorSize != size )
744   {
745     mActorSize = size;
746     UpdateGeometry();
747   }
748 }
749
750 } // namespace Internal
751
752 } // namespace Dali