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