0b89b26a69d7d0cfa28c256d18d4195e8ff53513
[platform/core/uifw/dali-core.git] / dali / internal / event / rendering / renderer-impl.cpp
1 /*
2  * Copyright (c) 2016 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/rendering/renderer-impl.h> // Dali::Internal::Renderer
20
21 // INTERNAL INCLUDES
22 #include <dali/devel-api/scripting/scripting.h>
23 #include <dali/public-api/object/type-registry.h>
24 #include <dali/internal/event/common/object-impl-helper.h> // Dali::Internal::ObjectHelper
25 #include <dali/internal/event/common/property-helper.h>    // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
26 #include <dali/internal/event/common/property-input-impl.h>
27 #include <dali/internal/render/renderers/render-geometry.h>
28 #include <dali/internal/update/manager/update-manager.h>
29 #include <dali/internal/update/rendering/scene-graph-renderer.h>
30
31 namespace Dali
32 {
33 namespace Internal
34 {
35
36 namespace
37 {
38
39 /**
40  * Properties: |name                              |type     |writable|animatable|constraint-input|enum for index-checking|
41  */
42 DALI_PROPERTY_TABLE_BEGIN
43 DALI_PROPERTY( "depthIndex",                      INTEGER,   true, false,  false, Dali::Renderer::Property::DEPTH_INDEX )
44 DALI_PROPERTY( "faceCullingMode",                 INTEGER,   true, false,  false, Dali::Renderer::Property::FACE_CULLING_MODE )
45 DALI_PROPERTY( "blendMode",                       INTEGER,   true, false,  false, Dali::Renderer::Property::BLEND_MODE )
46 DALI_PROPERTY( "blendEquationRgb",                INTEGER,   true, false,  false, Dali::Renderer::Property::BLEND_EQUATION_RGB )
47 DALI_PROPERTY( "blendEquationAlpha",              INTEGER,   true, false,  false, Dali::Renderer::Property::BLEND_EQUATION_ALPHA )
48 DALI_PROPERTY( "blendFactorSrcRgb",               INTEGER,   true, false,  false, Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB )
49 DALI_PROPERTY( "blendFactorDestRgb",              INTEGER,   true, false,  false, Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB )
50 DALI_PROPERTY( "blendFactorSrcAlpha",             INTEGER,   true, false,  false, Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA )
51 DALI_PROPERTY( "blendFactorDestAlpha",            INTEGER,   true, false,  false, Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA )
52 DALI_PROPERTY( "blendColor",                      VECTOR4,   true, false,  false, Dali::Renderer::Property::BLEND_COLOR )
53 DALI_PROPERTY( "blendPreMultipliedAlpha",         BOOLEAN,   true, false,  false, Dali::Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA )
54 DALI_PROPERTY( "indexRangeFirst",                 INTEGER,   true, false,  false, Dali::Renderer::Property::INDEX_RANGE_FIRST )
55 DALI_PROPERTY( "indexRangeCount",                 INTEGER,   true, false,  false, Dali::Renderer::Property::INDEX_RANGE_COUNT )
56 DALI_PROPERTY( "depthWriteMode",                  INTEGER,   true, false,  false, Dali::Renderer::Property::DEPTH_WRITE_MODE )
57 DALI_PROPERTY( "depthFunction",                   INTEGER,   true, false,  false, Dali::Renderer::Property::DEPTH_FUNCTION )
58 DALI_PROPERTY( "depthTestMode",                   INTEGER,   true, false,  false, Dali::Renderer::Property::DEPTH_TEST_MODE )
59 DALI_PROPERTY( "stencilFunction",                 INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_FUNCTION )
60 DALI_PROPERTY( "stencilFunctionMask",             INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_FUNCTION_MASK )
61 DALI_PROPERTY( "stencilFunctionReference",        INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE )
62 DALI_PROPERTY( "stencilMask",                     INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_MASK )
63 DALI_PROPERTY( "stencilMode",                     INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_MODE )
64 DALI_PROPERTY( "stencilOperationOnFail",          INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL )
65 DALI_PROPERTY( "stencilOperationOnZFail",         INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL )
66 DALI_PROPERTY( "stencilOperationOnZPass",         INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS )
67 DALI_PROPERTY( "writeToColorBuffer",              BOOLEAN,   true, false,  false, Dali::Renderer::Property::WRITE_TO_COLOR_BUFFER )
68 DALI_PROPERTY( "batchingEnabled",                 BOOLEAN,   true, false,  false, Dali::Renderer::Property::BATCHING_ENABLED )
69 DALI_PROPERTY_TABLE_END( DEFAULT_RENDERER_PROPERTY_START_INDEX )
70
71 // Property string to enumeration tables:
72
73 DALI_ENUM_TO_STRING_TABLE_BEGIN( FACE_CULLING_MODE )
74 DALI_ENUM_TO_STRING_WITH_SCOPE( FaceCullingMode, NONE )
75 DALI_ENUM_TO_STRING_WITH_SCOPE( FaceCullingMode, FRONT )
76 DALI_ENUM_TO_STRING_WITH_SCOPE( FaceCullingMode, BACK )
77 DALI_ENUM_TO_STRING_WITH_SCOPE( FaceCullingMode, FRONT_AND_BACK )
78 DALI_ENUM_TO_STRING_TABLE_END( FACE_CULLING_MODE )
79
80 DALI_ENUM_TO_STRING_TABLE_BEGIN( BLEND_MODE )
81 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendMode, OFF )
82 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendMode, AUTO )
83 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendMode, ON )
84 DALI_ENUM_TO_STRING_TABLE_END( BLEND_MODE )
85
86 DALI_ENUM_TO_STRING_TABLE_BEGIN( BLEND_EQUATION )
87 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendEquation, ADD )
88 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendEquation, SUBTRACT )
89 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendEquation, REVERSE_SUBTRACT )
90 DALI_ENUM_TO_STRING_TABLE_END( BLEND_EQUATION )
91
92 DALI_ENUM_TO_STRING_TABLE_BEGIN( BLEND_FACTOR )
93 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ZERO )
94 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE )
95 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, SRC_COLOR )
96 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_SRC_COLOR )
97 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, SRC_ALPHA )
98 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_SRC_ALPHA )
99 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, DST_ALPHA )
100 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_DST_ALPHA )
101 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, DST_COLOR )
102 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_DST_COLOR )
103 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, SRC_ALPHA_SATURATE )
104 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, CONSTANT_COLOR )
105 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_CONSTANT_COLOR )
106 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, CONSTANT_ALPHA )
107 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_CONSTANT_ALPHA )
108 DALI_ENUM_TO_STRING_TABLE_END( BLEND_FACTOR )
109
110 DALI_ENUM_TO_STRING_TABLE_BEGIN( DEPTH_WRITE_MODE )
111 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthWriteMode, OFF )
112 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthWriteMode, AUTO )
113 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthWriteMode, ON )
114 DALI_ENUM_TO_STRING_TABLE_END( DEPTH_WRITE_MODE )
115
116 DALI_ENUM_TO_STRING_TABLE_BEGIN( DEPTH_TEST_MODE )
117 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthTestMode, OFF )
118 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthTestMode, AUTO )
119 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthTestMode, ON )
120 DALI_ENUM_TO_STRING_TABLE_END( DEPTH_TEST_MODE )
121
122 DALI_ENUM_TO_STRING_TABLE_BEGIN( DEPTH_FUNCTION )
123 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, NEVER )
124 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, ALWAYS )
125 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, LESS )
126 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, GREATER )
127 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, EQUAL )
128 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, NOT_EQUAL )
129 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, LESS_EQUAL )
130 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, GREATER_EQUAL )
131 DALI_ENUM_TO_STRING_TABLE_END( DEPTH_FUNCTION )
132
133 DALI_ENUM_TO_STRING_TABLE_BEGIN( STENCIL_FUNCTION )
134 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, NEVER )
135 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, LESS )
136 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, EQUAL )
137 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, LESS_EQUAL )
138 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, GREATER )
139 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, NOT_EQUAL )
140 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, GREATER_EQUAL )
141 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, ALWAYS )
142 DALI_ENUM_TO_STRING_TABLE_END( STENCIL_FUNCTION )
143
144 DALI_ENUM_TO_STRING_TABLE_BEGIN( STENCIL_MODE )
145 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilMode, OFF )
146 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilMode, AUTO )
147 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilMode, ON )
148 DALI_ENUM_TO_STRING_TABLE_END( STENCIL_MODE )
149
150 DALI_ENUM_TO_STRING_TABLE_BEGIN( STENCIL_OPERATION )
151 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, ZERO )
152 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, KEEP )
153 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, REPLACE )
154 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, INCREMENT )
155 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, DECREMENT )
156 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, INVERT )
157 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, INCREMENT_WRAP )
158 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, DECREMENT_WRAP )
159 DALI_ENUM_TO_STRING_TABLE_END( STENCIL_OPERATION )
160
161 const ObjectImplHelper<DEFAULT_PROPERTY_COUNT> RENDERER_IMPL = { DEFAULT_PROPERTY_DETAILS };
162
163 BaseHandle Create()
164 {
165   return Dali::BaseHandle();
166 }
167
168 TypeRegistration mType( typeid( Dali::Renderer ), typeid( Dali::Handle ), Create );
169
170 } // unnamed namespace
171
172 RendererPtr Renderer::New()
173 {
174   RendererPtr rendererPtr( new Renderer() );
175   rendererPtr->Initialize();
176   return rendererPtr;
177 }
178
179 void Renderer::SetGeometry( Geometry& geometry )
180 {
181   mGeometry = &geometry;
182
183   const Render::Geometry* geometrySceneObject = geometry.GetRenderObject();
184   SetGeometryMessage( GetEventThreadServices(), *mSceneObject, *geometrySceneObject );
185 }
186
187 Geometry* Renderer::GetGeometry() const
188 {
189   return mGeometry.Get();
190 }
191
192 void Renderer::SetTextures( TextureSet& textureSet )
193 {
194   mTextureSetConnector.Set( textureSet, OnStage() );
195   const SceneGraph::TextureSet* textureSetSceneObject = textureSet.GetTextureSetSceneObject();
196   SetTexturesMessage( GetEventThreadServices(), *mSceneObject, *textureSetSceneObject );
197 }
198
199 TextureSet* Renderer::GetTextures() const
200 {
201   return mTextureSetConnector.Get().Get();
202 }
203
204 void Renderer::SetShader( Shader& shader )
205 {
206   mShader = &shader;
207   SceneGraph::Shader& sceneGraphShader = *shader.GetShaderSceneObject();
208   SceneGraph::SetShaderMessage( GetEventThreadServices(), *mSceneObject, sceneGraphShader );
209 }
210
211 Shader* Renderer::GetShader() const
212 {
213   return mShader.Get();
214 }
215
216 void Renderer::SetDepthIndex( int depthIndex )
217 {
218   if ( mDepthIndex != depthIndex )
219   {
220     mDepthIndex = depthIndex;
221     SetDepthIndexMessage( GetEventThreadServices(), *mSceneObject, depthIndex );
222   }
223 }
224
225 int Renderer::GetDepthIndex() const
226 {
227   return mDepthIndex;
228 }
229
230 void Renderer::SetBlendMode( BlendMode::Type mode )
231 {
232   if( mBlendMode != mode )
233   {
234     mBlendMode = mode;
235
236     SetBlendModeMessage( GetEventThreadServices(), *mSceneObject, mBlendMode );
237   }
238 }
239
240 BlendMode::Type Renderer::GetBlendMode() const
241 {
242   return mBlendMode;
243 }
244
245 void Renderer::SetBlendFunc( BlendFactor::Type srcFactorRgba, BlendFactor::Type destFactorRgba )
246 {
247   mBlendingOptions.SetBlendFunc( srcFactorRgba, destFactorRgba, srcFactorRgba, destFactorRgba );
248   SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
249 }
250
251 void Renderer::SetBlendFunc( BlendFactor::Type srcFactorRgb,
252                              BlendFactor::Type destFactorRgb,
253                              BlendFactor::Type srcFactorAlpha,
254                              BlendFactor::Type destFactorAlpha )
255 {
256   mBlendingOptions.SetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
257   SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
258 }
259
260 void Renderer::GetBlendFunc( BlendFactor::Type& srcFactorRgb,
261                              BlendFactor::Type& destFactorRgb,
262                              BlendFactor::Type& srcFactorAlpha,
263                              BlendFactor::Type& destFactorAlpha ) const
264 {
265   srcFactorRgb    = mBlendingOptions.GetBlendSrcFactorRgb();
266   destFactorRgb   = mBlendingOptions.GetBlendDestFactorRgb();
267   srcFactorAlpha  = mBlendingOptions.GetBlendSrcFactorAlpha();
268   destFactorAlpha = mBlendingOptions.GetBlendDestFactorAlpha();
269 }
270
271 void Renderer::SetBlendEquation( BlendEquation::Type equationRgba )
272 {
273   mBlendingOptions.SetBlendEquation( equationRgba, equationRgba );
274   SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
275 }
276
277 void Renderer::SetBlendEquation( BlendEquation::Type equationRgb,
278                                  BlendEquation::Type equationAlpha )
279 {
280   mBlendingOptions.SetBlendEquation( equationRgb, equationAlpha );
281   SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
282 }
283
284 void Renderer::GetBlendEquation( BlendEquation::Type& equationRgb,
285                                  BlendEquation::Type& equationAlpha ) const
286 {
287   // These are not animatable, the cached values are up-to-date.
288   equationRgb   = mBlendingOptions.GetBlendEquationRgb();
289   equationAlpha = mBlendingOptions.GetBlendEquationAlpha();
290 }
291
292 void Renderer::SetBlendColor( const Vector4& color )
293 {
294   if( !mBlendColor )
295   {
296     mBlendColor = new Vector4();
297   }
298   if( *mBlendColor != color )
299   {
300     *mBlendColor = color;
301     SetBlendColorMessage( GetEventThreadServices(), *mSceneObject, *mBlendColor );
302   }
303 }
304
305 Vector4 Renderer::GetBlendColor() const
306 {
307   if( mBlendColor )
308   {
309     return *mBlendColor;
310   }
311   return Color::TRANSPARENT; // GL default
312 }
313
314 void Renderer::SetIndexedDrawFirstElement( size_t firstElement )
315 {
316   if( firstElement != mIndexedDrawFirstElement )
317   {
318     mIndexedDrawFirstElement = firstElement;
319     SetIndexedDrawFirstElementMessage( GetEventThreadServices(), *mSceneObject, mIndexedDrawFirstElement );
320   }
321 }
322
323 void Renderer::SetIndexedDrawElementsCount( size_t elementsCount )
324 {
325   if( elementsCount != mIndexedDrawElementCount )
326   {
327     mIndexedDrawElementCount = elementsCount;
328     SetIndexedDrawElementsCountMessage( GetEventThreadServices(), *mSceneObject, mIndexedDrawElementCount );
329   }
330 }
331
332
333 void Renderer::EnablePreMultipliedAlpha( bool preMultipled )
334 {
335   if(  mPremultipledAlphaEnabled != preMultipled )
336   {
337     if( preMultipled )
338     {
339       SetBlendFunc( BlendFactor::ONE, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::ONE, BlendFactor::ONE );
340     }
341     mPremultipledAlphaEnabled = preMultipled;
342     SetEnablePreMultipliedAlphaMessage( GetEventThreadServices(), *mSceneObject, mPremultipledAlphaEnabled );
343   }
344 }
345
346 bool Renderer::IsPreMultipliedAlphaEnabled() const
347 {
348   return mPremultipledAlphaEnabled;
349 }
350
351 bool Renderer::IsBatchingEnabled() const
352 {
353   return mBatchingEnabled;
354 }
355
356 SceneGraph::Renderer* Renderer::GetRendererSceneObject()
357 {
358   return mSceneObject;
359 }
360
361 unsigned int Renderer::GetDefaultPropertyCount() const
362 {
363   return RENDERER_IMPL.GetDefaultPropertyCount();
364 }
365
366 void Renderer::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
367 {
368   RENDERER_IMPL.GetDefaultPropertyIndices( indices );
369 }
370
371 const char* Renderer::GetDefaultPropertyName(Property::Index index) const
372 {
373   return RENDERER_IMPL.GetDefaultPropertyName( index );
374 }
375
376 Property::Index Renderer::GetDefaultPropertyIndex( const std::string& name ) const
377 {
378   return RENDERER_IMPL.GetDefaultPropertyIndex( name );
379 }
380
381 bool Renderer::IsDefaultPropertyWritable( Property::Index index ) const
382 {
383   return RENDERER_IMPL.IsDefaultPropertyWritable( index );
384 }
385
386 bool Renderer::IsDefaultPropertyAnimatable( Property::Index index ) const
387 {
388   return RENDERER_IMPL.IsDefaultPropertyAnimatable( index );
389 }
390
391 bool Renderer::IsDefaultPropertyAConstraintInput( Property::Index index ) const
392 {
393   return RENDERER_IMPL.IsDefaultPropertyAConstraintInput( index );
394 }
395
396 Property::Type Renderer::GetDefaultPropertyType( Property::Index index ) const
397 {
398   return RENDERER_IMPL.GetDefaultPropertyType( index );
399 }
400
401 void Renderer::SetDefaultProperty( Property::Index index,
402                                    const Property::Value& propertyValue )
403 {
404   switch( index )
405   {
406     case Dali::Renderer::Property::DEPTH_INDEX:
407     {
408       SetDepthIndex( propertyValue.Get<int>() );
409       break;
410     }
411     case Dali::Renderer::Property::FACE_CULLING_MODE:
412     {
413       FaceCullingMode::Type convertedValue = mFaceCullingMode;
414       if( Scripting::GetEnumerationProperty< FaceCullingMode::Type >( propertyValue, FACE_CULLING_MODE_TABLE, FACE_CULLING_MODE_TABLE_COUNT, convertedValue ) )
415       {
416         mFaceCullingMode = convertedValue;
417         SetFaceCullingModeMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
418       }
419       break;
420     }
421     case Dali::Renderer::Property::BLEND_MODE:
422     {
423       BlendMode::Type convertedValue = mBlendMode;
424       if( Scripting::GetEnumerationProperty< BlendMode::Type >( propertyValue, BLEND_MODE_TABLE, BLEND_MODE_TABLE_COUNT, convertedValue ) )
425       {
426         SetBlendMode( convertedValue );
427       }
428       break;
429     }
430     case Dali::Renderer::Property::BLEND_EQUATION_RGB:
431     {
432       BlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationRgb();
433
434       if( Scripting::GetEnumerationProperty< BlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
435       {
436         BlendEquation::Type alphaEquation = mBlendingOptions.GetBlendEquationAlpha();
437         mBlendingOptions.SetBlendEquation( convertedValue, alphaEquation );
438         SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
439       }
440       break;
441     }
442     case Dali::Renderer::Property::BLEND_EQUATION_ALPHA:
443     {
444       BlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationAlpha();
445
446       if( Scripting::GetEnumerationProperty< BlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
447       {
448         BlendEquation::Type rgbEquation = mBlendingOptions.GetBlendEquationRgb();
449         mBlendingOptions.SetBlendEquation( rgbEquation, convertedValue );
450         SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
451       }
452       break;
453     }
454     case Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB:
455     {
456       BlendFactor::Type sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha;
457       GetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
458
459       if( Scripting::GetEnumerationProperty< BlendFactor::Type >( propertyValue, BLEND_FACTOR_TABLE, BLEND_FACTOR_TABLE_COUNT, sourceFactorRgb ) )
460       {
461         SetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
462       }
463       break;
464     }
465     case Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB:
466     {
467       BlendFactor::Type sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha;
468       GetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
469
470       if( Scripting::GetEnumerationProperty< BlendFactor::Type >( propertyValue, BLEND_FACTOR_TABLE, BLEND_FACTOR_TABLE_COUNT, destinationFactorRgb ) )
471       {
472         SetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
473       }
474       break;
475     }
476     case Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA:
477     {
478       BlendFactor::Type sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha;
479       GetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
480
481       if( Scripting::GetEnumerationProperty< BlendFactor::Type >( propertyValue, BLEND_FACTOR_TABLE, BLEND_FACTOR_TABLE_COUNT, sourceFactorAlpha ) )
482       {
483         SetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
484       }
485       break;
486     }
487     case Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA:
488     {
489       BlendFactor::Type sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha;
490       GetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
491
492       if( Scripting::GetEnumerationProperty< BlendFactor::Type >( propertyValue, BLEND_FACTOR_TABLE, BLEND_FACTOR_TABLE_COUNT, destinationFactorAlpha ) )
493       {
494         SetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
495       }
496       break;
497     }
498     case Dali::Renderer::Property::BLEND_COLOR:
499     {
500       Vector4 blendColor;
501       if( propertyValue.Get( blendColor ) )
502       {
503         SetBlendColor( blendColor );
504       }
505       break;
506     }
507     case Dali::Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA:
508     {
509       bool preMultipled;
510       if( propertyValue.Get( preMultipled ) )
511       {
512         EnablePreMultipliedAlpha( preMultipled );
513       }
514       break;
515     }
516     case Dali::Renderer::Property::INDEX_RANGE_FIRST:
517     {
518       int firstElement;
519       if( propertyValue.Get( firstElement ) )
520       {
521         SetIndexedDrawFirstElement( firstElement );
522       }
523       break;
524     }
525     case Dali::Renderer::Property::INDEX_RANGE_COUNT:
526     {
527       int elementsCount;
528       if( propertyValue.Get( elementsCount ) )
529       {
530         SetIndexedDrawElementsCount( elementsCount );
531       }
532       break;
533     }
534     case Dali::Renderer::Property::DEPTH_WRITE_MODE:
535     {
536       DepthWriteMode::Type convertedValue = mDepthWriteMode;
537       if( Scripting::GetEnumerationProperty< DepthWriteMode::Type >( propertyValue, DEPTH_WRITE_MODE_TABLE, DEPTH_WRITE_MODE_TABLE_COUNT, convertedValue ) )
538       {
539         mDepthWriteMode = convertedValue;
540         SetDepthWriteModeMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
541       }
542       break;
543     }
544     case Dali::Renderer::Property::DEPTH_FUNCTION:
545     {
546       DepthFunction::Type convertedValue = mDepthFunction;
547       if( Scripting::GetEnumerationProperty< DepthFunction::Type >( propertyValue, DEPTH_FUNCTION_TABLE, DEPTH_FUNCTION_TABLE_COUNT, convertedValue ) )
548       {
549         mDepthFunction = convertedValue;
550         SetDepthFunctionMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
551       }
552       break;
553     }
554     case Dali::Renderer::Property::DEPTH_TEST_MODE:
555     {
556       DepthTestMode::Type convertedValue = mDepthTestMode;
557       if( Scripting::GetEnumerationProperty< DepthTestMode::Type >( propertyValue, DEPTH_TEST_MODE_TABLE, DEPTH_TEST_MODE_TABLE_COUNT, convertedValue ) )
558       {
559         mDepthTestMode = convertedValue;
560         SetDepthTestModeMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
561       }
562       break;
563     }
564     case Dali::Renderer::Property::STENCIL_MODE:
565     {
566       StencilMode::Type convertedValue = mStencilParameters.stencilMode;
567       if( Scripting::GetEnumerationProperty< StencilMode::Type >( propertyValue, STENCIL_MODE_TABLE, STENCIL_MODE_TABLE_COUNT, convertedValue ) )
568       {
569         mStencilParameters.stencilMode = convertedValue;
570         SetStencilModeMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
571       }
572       break;
573     }
574     case Dali::Renderer::Property::STENCIL_FUNCTION:
575     {
576       StencilFunction::Type convertedValue = mStencilParameters.stencilFunction;
577       if( Scripting::GetEnumerationProperty< StencilFunction::Type >( propertyValue, STENCIL_FUNCTION_TABLE, STENCIL_FUNCTION_TABLE_COUNT, convertedValue ) )
578       {
579         mStencilParameters.stencilFunction = convertedValue;
580         SetStencilFunctionMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
581       }
582       break;
583     }
584     case Dali::Renderer::Property::STENCIL_FUNCTION_MASK:
585     {
586       int stencilFunctionMask;
587       if( propertyValue.Get( stencilFunctionMask ) )
588       {
589         if( stencilFunctionMask != mStencilParameters.stencilFunctionMask )
590         {
591           mStencilParameters.stencilFunctionMask = stencilFunctionMask;
592           SetStencilFunctionMaskMessage( GetEventThreadServices(), *mSceneObject, stencilFunctionMask );
593         }
594       }
595       break;
596     }
597     case Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE:
598     {
599       int stencilFunctionReference;
600       if( propertyValue.Get( stencilFunctionReference ) )
601       {
602         if( stencilFunctionReference != mStencilParameters.stencilFunctionReference )
603         {
604           mStencilParameters.stencilFunctionReference = stencilFunctionReference;
605           SetStencilFunctionReferenceMessage( GetEventThreadServices(), *mSceneObject, stencilFunctionReference );
606         }
607       }
608       break;
609     }
610     case Dali::Renderer::Property::STENCIL_MASK:
611     {
612       int stencilMask;
613       if( propertyValue.Get( stencilMask ) )
614       {
615         if( stencilMask != mStencilParameters.stencilMask )
616         {
617           mStencilParameters.stencilMask = stencilMask;
618           SetStencilMaskMessage( GetEventThreadServices(), *mSceneObject, stencilMask );
619         }
620       }
621       break;
622     }
623     case Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL:
624     {
625       StencilOperation::Type convertedValue = mStencilParameters.stencilOperationOnFail;
626       if( Scripting::GetEnumerationProperty< StencilOperation::Type >( propertyValue, STENCIL_OPERATION_TABLE, STENCIL_OPERATION_TABLE_COUNT, convertedValue ) )
627       {
628         mStencilParameters.stencilOperationOnFail = convertedValue;
629         SetStencilOperationOnFailMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
630       }
631       break;
632     }
633     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL:
634     {
635       StencilOperation::Type convertedValue = mStencilParameters.stencilOperationOnZFail;
636       if( Scripting::GetEnumerationProperty< StencilOperation::Type >( propertyValue, STENCIL_OPERATION_TABLE, STENCIL_OPERATION_TABLE_COUNT, convertedValue ) )
637       {
638         mStencilParameters.stencilOperationOnZFail = convertedValue;
639         SetStencilOperationOnZFailMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
640       }
641       break;
642     }
643     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS:
644     {
645       StencilOperation::Type convertedValue = mStencilParameters.stencilOperationOnZPass;
646       if( Scripting::GetEnumerationProperty< StencilOperation::Type >( propertyValue, STENCIL_OPERATION_TABLE, STENCIL_OPERATION_TABLE_COUNT, convertedValue ) )
647       {
648         mStencilParameters.stencilOperationOnZPass = convertedValue;
649         SetStencilOperationOnZPassMessage( GetEventThreadServices(), *mSceneObject, convertedValue );
650       }
651       break;
652     }
653     case Dali::Renderer::Property::WRITE_TO_COLOR_BUFFER:
654     {
655       bool writeToColorBuffer;
656       if( propertyValue.Get( writeToColorBuffer ) )
657       {
658         if( mWriteToColorBuffer != writeToColorBuffer )
659         {
660           mWriteToColorBuffer = writeToColorBuffer;
661           SetWriteToColorBufferMessage( GetEventThreadServices(), *mSceneObject, writeToColorBuffer );
662         }
663       }
664       break;
665     }
666     case Dali::Renderer::Property::BATCHING_ENABLED:
667     {
668       bool enabled;
669       if( propertyValue.Get( enabled ) )
670       {
671         if( mBatchingEnabled != enabled )
672         {
673           mBatchingEnabled = enabled;
674           SetBatchingEnabledMessage( GetEventThreadServices(), *mSceneObject, mBatchingEnabled );
675         }
676       }
677       break;
678     }
679   }
680 }
681
682 void Renderer::SetSceneGraphProperty( Property::Index index,
683                                       const PropertyMetadata& entry,
684                                       const Property::Value& value )
685 {
686   RENDERER_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
687   OnPropertySet(index, value);
688 }
689
690 Property::Value Renderer::GetDefaultProperty( Property::Index index ) const
691 {
692   Property::Value value;
693   switch( index )
694   {
695     case Dali::Renderer::Property::DEPTH_INDEX:
696     {
697       value = GetDepthIndex();
698       break;
699     }
700     case Dali::Renderer::Property::FACE_CULLING_MODE:
701     {
702       value = mFaceCullingMode;
703       break;
704     }
705     case Dali::Renderer::Property::BLEND_MODE:
706     {
707       value = mBlendMode;
708       break;
709     }
710     case Dali::Renderer::Property::BLEND_EQUATION_RGB:
711     {
712       value = static_cast<int>( mBlendingOptions.GetBlendEquationRgb() );
713       break;
714     }
715     case Dali::Renderer::Property::BLEND_EQUATION_ALPHA:
716     {
717       value = static_cast<int>( mBlendingOptions.GetBlendEquationAlpha() );
718       break;
719     }
720     case Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB:
721     {
722       BlendFactor::Type srcFactorRgb;
723       BlendFactor::Type destFactorRgb;
724       BlendFactor::Type srcFactorAlpha;
725       BlendFactor::Type destFactorAlpha;
726       GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
727       value = static_cast<int>( srcFactorRgb );
728       break;
729     }
730     case Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB:
731     {
732       BlendFactor::Type srcFactorRgb;
733       BlendFactor::Type destFactorRgb;
734       BlendFactor::Type srcFactorAlpha;
735       BlendFactor::Type destFactorAlpha;
736       GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
737       value = static_cast<int>( destFactorRgb );
738       break;
739     }
740     case Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA:
741     {
742       BlendFactor::Type srcFactorRgb;
743       BlendFactor::Type destFactorRgb;
744       BlendFactor::Type srcFactorAlpha;
745       BlendFactor::Type destFactorAlpha;
746       GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
747       value = static_cast<int>( srcFactorAlpha );
748       break;
749     }
750     case Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA:
751     {
752       BlendFactor::Type srcFactorRgb;
753       BlendFactor::Type destFactorRgb;
754       BlendFactor::Type srcFactorAlpha;
755       BlendFactor::Type destFactorAlpha;
756       GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
757       value = static_cast<int>( destFactorAlpha );
758       break;
759     }
760     case Dali::Renderer::Property::BLEND_COLOR:
761     {
762       if( mBlendColor )
763       {
764         value = *mBlendColor;
765       }
766       else
767       {
768         value = Color::TRANSPARENT;
769       }
770       break;
771     }
772     case Dali::Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA:
773     {
774       value = IsPreMultipliedAlphaEnabled();
775       break;
776     }
777     case Dali::Renderer::Property::INDEX_RANGE_FIRST:
778     {
779       value = static_cast<int>( mIndexedDrawFirstElement );
780       break;
781     }
782     case Dali::Renderer::Property::INDEX_RANGE_COUNT:
783     {
784       value = static_cast<int>( mIndexedDrawElementCount );
785       break;
786     }
787     case Dali::Renderer::Property::DEPTH_WRITE_MODE:
788     {
789       value = mDepthWriteMode;
790       break;
791     }
792     case Dali::Renderer::Property::BATCHING_ENABLED:
793     {
794       value = mBatchingEnabled;
795       break;
796     }
797     case Dali::Renderer::Property::DEPTH_FUNCTION:
798     {
799       value = mDepthFunction;
800       break;
801     }
802     case Dali::Renderer::Property::DEPTH_TEST_MODE:
803     {
804       value = mDepthTestMode;
805       break;
806     }
807     case Dali::Renderer::Property::STENCIL_FUNCTION:
808     {
809       value = mStencilParameters.stencilFunction;
810       break;
811     }
812     case Dali::Renderer::Property::STENCIL_FUNCTION_MASK:
813     {
814       value = mStencilParameters.stencilFunctionMask;
815       break;
816     }
817     case Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE:
818     {
819       value = mStencilParameters.stencilFunctionReference;
820       break;
821     }
822     case Dali::Renderer::Property::STENCIL_MASK:
823     {
824       value = mStencilParameters.stencilMask;
825       break;
826     }
827     case Dali::Renderer::Property::STENCIL_MODE:
828     {
829       value = mStencilParameters.stencilMode;
830       break;
831     }
832     case Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL:
833     {
834       value = mStencilParameters.stencilOperationOnFail;
835       break;
836     }
837     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL:
838     {
839       value = mStencilParameters.stencilOperationOnZFail;
840       break;
841     }
842     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS:
843     {
844       value = mStencilParameters.stencilOperationOnZPass;
845       break;
846     }
847     case Dali::Renderer::Property::WRITE_TO_COLOR_BUFFER:
848     {
849       value = mWriteToColorBuffer;
850       break;
851     }
852   }
853   return value;
854 }
855
856 const SceneGraph::PropertyOwner* Renderer::GetPropertyOwner() const
857 {
858   return mSceneObject;
859 }
860
861 const SceneGraph::PropertyOwner* Renderer::GetSceneObject() const
862 {
863   return mSceneObject;
864 }
865
866 const SceneGraph::PropertyBase* Renderer::GetSceneObjectAnimatableProperty( Property::Index index ) const
867 {
868   DALI_ASSERT_ALWAYS( IsPropertyAnimatable(index) && "Property is not animatable" );
869   const SceneGraph::PropertyBase* property = NULL;
870
871   if( OnStage() )
872   {
873     property = RENDERER_IMPL.GetRegisteredSceneGraphProperty(
874       this,
875       &Renderer::FindAnimatableProperty,
876       &Renderer::FindCustomProperty,
877       index );
878   }
879
880   return property;
881 }
882
883 const PropertyInputImpl* Renderer::GetSceneObjectInputProperty( Property::Index index ) const
884 {
885   const PropertyInputImpl* property = NULL;
886
887   if( OnStage() )
888   {
889     const SceneGraph::PropertyBase* baseProperty =
890       RENDERER_IMPL.GetRegisteredSceneGraphProperty( this,
891                                                      &Renderer::FindAnimatableProperty,
892                                                      &Renderer::FindCustomProperty,
893                                                      index );
894     property = static_cast<const PropertyInputImpl*>( baseProperty );
895   }
896
897   return property;
898 }
899
900 int Renderer::GetPropertyComponentIndex( Property::Index index ) const
901 {
902   return Property::INVALID_COMPONENT_INDEX;
903 }
904
905 bool Renderer::OnStage() const
906 {
907   return mOnStageCount > 0;
908 }
909
910 void Renderer::Connect()
911 {
912   if( mOnStageCount == 0 )
913   {
914     mTextureSetConnector.OnStageConnect();
915   }
916   ++mOnStageCount;
917 }
918
919 void Renderer::Disconnect()
920 {
921   --mOnStageCount;
922   if( mOnStageCount == 0 )
923   {
924     mTextureSetConnector.OnStageDisconnect();
925   }
926 }
927
928 Renderer::Renderer()
929 : mSceneObject (NULL ),
930   mBlendColor( NULL ),
931   mDepthIndex( 0 ),
932   mOnStageCount( 0 ),
933   mIndexedDrawFirstElement( 0 ),
934   mIndexedDrawElementCount( 0 ),
935   mStencilParameters( StencilMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP ),
936   mBlendingOptions(),
937   mDepthFunction( DepthFunction::LESS ),
938   mFaceCullingMode( FaceCullingMode::NONE ),
939   mBlendMode( BlendMode::AUTO ),
940   mDepthWriteMode( DepthWriteMode::AUTO ),
941   mDepthTestMode( DepthTestMode::AUTO ),
942   mWriteToColorBuffer( true ),
943   mPremultipledAlphaEnabled( false ),
944   mBatchingEnabled( false )
945 {
946 }
947
948 void Renderer::Initialize()
949 {
950   EventThreadServices& eventThreadServices = GetEventThreadServices();
951   SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
952
953   mSceneObject = SceneGraph::Renderer::New();
954   AddMessage( updateManager, updateManager.GetRendererOwner(), *mSceneObject );
955
956   eventThreadServices.RegisterObject( this );
957 }
958
959 Renderer::~Renderer()
960 {
961   if( EventThreadServices::IsCoreRunning() )
962   {
963     EventThreadServices& eventThreadServices = GetEventThreadServices();
964     SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
965     RemoveMessage( updateManager, updateManager.GetRendererOwner(), *mSceneObject );
966
967     eventThreadServices.UnregisterObject( this );
968   }
969 }
970
971 } // namespace Internal
972 } // namespace Dali