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