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