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