Merge "Clean up the code to build successfully on macOS" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / event / rendering / renderer-impl.cpp
1 /*
2  * Copyright (c) 2020 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/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  * Properties: |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( "renderMode",                      INTEGER,   true, false,  false, Dali::Renderer::Property::RENDER_MODE )
59 DALI_PROPERTY( "stencilFunction",                 INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_FUNCTION )
60 DALI_PROPERTY( "stencilFunctionMask",             INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_FUNCTION_MASK )
61 DALI_PROPERTY( "stencilFunctionReference",        INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE )
62 DALI_PROPERTY( "stencilMask",                     INTEGER,   true, false,  false, Dali::Renderer::Property::STENCIL_MASK )
63 DALI_PROPERTY( "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( "opacity",                         FLOAT,     true, true,   true,  Dali::DevelRenderer::Property::OPACITY )
67 DALI_PROPERTY( "renderingBehavior",               INTEGER,   true, false,  false, Dali::DevelRenderer::Property::RENDERING_BEHAVIOR )
68 DALI_PROPERTY( "blendEquation",                   INTEGER,   true, false,  false, Dali::DevelRenderer::Property::BLEND_EQUATION )
69 DALI_PROPERTY_TABLE_END( DEFAULT_RENDERER_PROPERTY_START_INDEX, RendererDefaultProperties )
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_WITH_SCOPE( DevelBlendEquation, MIN )
91 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, MAX )
92 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, MULTIPLY )
93 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, SCREEN )
94 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, OVERLAY )
95 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, DARKEN )
96 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, LIGHTEN )
97 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, COLOR_DODGE )
98 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, COLOR_BURN )
99 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, HARD_LIGHT )
100 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, SOFT_LIGHT )
101 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, DIFFERENCE )
102 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, EXCLUSION )
103 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, HUE )
104 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, SATURATION )
105 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, COLOR )
106 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelBlendEquation, LUMINOSITY )
107 DALI_ENUM_TO_STRING_TABLE_END( BLEND_EQUATION )
108
109 DALI_ENUM_TO_STRING_TABLE_BEGIN( BLEND_FACTOR )
110 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ZERO )
111 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE )
112 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, SRC_COLOR )
113 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_SRC_COLOR )
114 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, SRC_ALPHA )
115 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_SRC_ALPHA )
116 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, DST_ALPHA )
117 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_DST_ALPHA )
118 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, DST_COLOR )
119 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_DST_COLOR )
120 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, SRC_ALPHA_SATURATE )
121 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, CONSTANT_COLOR )
122 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_CONSTANT_COLOR )
123 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, CONSTANT_ALPHA )
124 DALI_ENUM_TO_STRING_WITH_SCOPE( BlendFactor, ONE_MINUS_CONSTANT_ALPHA )
125 DALI_ENUM_TO_STRING_TABLE_END( BLEND_FACTOR )
126
127 DALI_ENUM_TO_STRING_TABLE_BEGIN( DEPTH_WRITE_MODE )
128 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthWriteMode, OFF )
129 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthWriteMode, AUTO )
130 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthWriteMode, ON )
131 DALI_ENUM_TO_STRING_TABLE_END( DEPTH_WRITE_MODE )
132
133 DALI_ENUM_TO_STRING_TABLE_BEGIN( DEPTH_TEST_MODE )
134 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthTestMode, OFF )
135 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthTestMode, AUTO )
136 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthTestMode, ON )
137 DALI_ENUM_TO_STRING_TABLE_END( DEPTH_TEST_MODE )
138
139 DALI_ENUM_TO_STRING_TABLE_BEGIN( DEPTH_FUNCTION )
140 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, NEVER )
141 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, ALWAYS )
142 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, LESS )
143 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, GREATER )
144 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, EQUAL )
145 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, NOT_EQUAL )
146 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, LESS_EQUAL )
147 DALI_ENUM_TO_STRING_WITH_SCOPE( DepthFunction, GREATER_EQUAL )
148 DALI_ENUM_TO_STRING_TABLE_END( DEPTH_FUNCTION )
149
150 DALI_ENUM_TO_STRING_TABLE_BEGIN( STENCIL_FUNCTION )
151 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, NEVER )
152 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, LESS )
153 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, EQUAL )
154 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, LESS_EQUAL )
155 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, GREATER )
156 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, NOT_EQUAL )
157 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, GREATER_EQUAL )
158 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilFunction, ALWAYS )
159 DALI_ENUM_TO_STRING_TABLE_END( STENCIL_FUNCTION )
160
161 DALI_ENUM_TO_STRING_TABLE_BEGIN( RENDER_MODE )
162 DALI_ENUM_TO_STRING_WITH_SCOPE( RenderMode, NONE )
163 DALI_ENUM_TO_STRING_WITH_SCOPE( RenderMode, AUTO )
164 DALI_ENUM_TO_STRING_WITH_SCOPE( RenderMode, COLOR )
165 DALI_ENUM_TO_STRING_WITH_SCOPE( RenderMode, STENCIL )
166 DALI_ENUM_TO_STRING_WITH_SCOPE( RenderMode, COLOR_STENCIL )
167 DALI_ENUM_TO_STRING_TABLE_END( RENDER_MODE )
168
169 DALI_ENUM_TO_STRING_TABLE_BEGIN( STENCIL_OPERATION )
170 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, ZERO )
171 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, KEEP )
172 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, REPLACE )
173 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, INCREMENT )
174 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, DECREMENT )
175 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, INVERT )
176 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, INCREMENT_WRAP )
177 DALI_ENUM_TO_STRING_WITH_SCOPE( StencilOperation, DECREMENT_WRAP )
178 DALI_ENUM_TO_STRING_TABLE_END( STENCIL_OPERATION )
179
180 DALI_ENUM_TO_STRING_TABLE_BEGIN( RENDERING_BEHAVIOR )
181 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelRenderer::Rendering, IF_REQUIRED )
182 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelRenderer::Rendering, CONTINUOUSLY )
183 DALI_ENUM_TO_STRING_TABLE_END( RENDERING_BEHAVIOR )
184
185 BaseHandle Create()
186 {
187   return Dali::BaseHandle();
188 }
189
190 TypeRegistration mType( typeid( Dali::Renderer ), typeid( Dali::Handle ), Create, RendererDefaultProperties );
191
192 } // unnamed namespace
193
194 RendererPtr Renderer::New()
195 {
196   // create scene object first so it's guaranteed to exist for the event side
197   auto sceneObject = SceneGraph::Renderer::New();
198   OwnerPointer< SceneGraph::Renderer > transferOwnership( sceneObject );
199   // pass the pointer to base for message passing
200   RendererPtr rendererPtr( new Renderer( sceneObject ) );
201   // transfer scene object ownership to update manager
202   EventThreadServices& eventThreadServices = rendererPtr->GetEventThreadServices();
203   SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
204   AddRendererMessage( updateManager, transferOwnership );
205
206   eventThreadServices.RegisterObject( rendererPtr.Get() );
207   return rendererPtr;
208 }
209
210 void Renderer::SetGeometry( Geometry& geometry )
211 {
212   mGeometry = &geometry;
213
214   const Render::Geometry* geometrySceneObject = geometry.GetRenderObject();
215   SetGeometryMessage( GetEventThreadServices(), GetRendererSceneObject(), *geometrySceneObject );
216 }
217
218 GeometryPtr Renderer::GetGeometry() const
219 {
220   return mGeometry;
221 }
222
223 void Renderer::SetTextures( TextureSet& textureSet )
224 {
225   mTextureSet = &textureSet;
226   const SceneGraph::TextureSet* textureSetSceneObject = textureSet.GetTextureSetSceneObject();
227   SetTexturesMessage( GetEventThreadServices(), GetRendererSceneObject(), *textureSetSceneObject );
228 }
229
230 TextureSetPtr Renderer::GetTextures() const
231 {
232   return mTextureSet;
233 }
234
235 void Renderer::SetShader( Shader& shader )
236 {
237   mShader = &shader;
238   const SceneGraph::Shader& sceneGraphShader = shader.GetShaderSceneObject();
239   SceneGraph::SetShaderMessage( GetEventThreadServices(), GetRendererSceneObject(), sceneGraphShader );
240 }
241
242 ShaderPtr Renderer::GetShader() const
243 {
244   return mShader;
245 }
246
247 void Renderer::SetDepthIndex( int32_t depthIndex )
248 {
249   if ( mDepthIndex != depthIndex )
250   {
251     mDepthIndex = depthIndex;
252     SetDepthIndexMessage( GetEventThreadServices(), GetRendererSceneObject(), depthIndex );
253   }
254 }
255
256 int32_t Renderer::GetDepthIndex() const
257 {
258   return mDepthIndex;
259 }
260
261 void Renderer::SetBlendMode( BlendMode::Type mode )
262 {
263   if( mBlendMode != mode )
264   {
265     mBlendMode = mode;
266
267     SetBlendModeMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendMode );
268   }
269 }
270
271 BlendMode::Type Renderer::GetBlendMode() const
272 {
273   return mBlendMode;
274 }
275
276 void Renderer::SetBlendFunc( BlendFactor::Type srcFactorRgba, BlendFactor::Type destFactorRgba )
277 {
278   mBlendingOptions.SetBlendFunc( srcFactorRgba, destFactorRgba, srcFactorRgba, destFactorRgba );
279   SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
280 }
281
282 void Renderer::SetBlendFunc( BlendFactor::Type srcFactorRgb,
283                              BlendFactor::Type destFactorRgb,
284                              BlendFactor::Type srcFactorAlpha,
285                              BlendFactor::Type destFactorAlpha )
286 {
287   mBlendingOptions.SetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
288   SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
289 }
290
291 void Renderer::GetBlendFunc( BlendFactor::Type& srcFactorRgb,
292                              BlendFactor::Type& destFactorRgb,
293                              BlendFactor::Type& srcFactorAlpha,
294                              BlendFactor::Type& destFactorAlpha ) const
295 {
296   srcFactorRgb    = mBlendingOptions.GetBlendSrcFactorRgb();
297   destFactorRgb   = mBlendingOptions.GetBlendDestFactorRgb();
298   srcFactorAlpha  = mBlendingOptions.GetBlendSrcFactorAlpha();
299   destFactorAlpha = mBlendingOptions.GetBlendDestFactorAlpha();
300 }
301
302 void Renderer::SetBlendEquation( DevelBlendEquation::Type equationRgba )
303 {
304   mBlendingOptions.SetBlendEquation( equationRgba, equationRgba );
305   SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
306 }
307
308 void Renderer::SetBlendEquation( DevelBlendEquation::Type equationRgb,
309                                  DevelBlendEquation::Type equationAlpha )
310 {
311   if( mBlendingOptions.IsAdvancedBlendEquation( equationRgb ) || mBlendingOptions.IsAdvancedBlendEquation( equationAlpha ) )
312   {
313     DALI_LOG_ERROR("Advanced blend equation requires to be set by using SetBlendEquation( DevelBlendEquation::Type equationRgba ).");
314     return;
315   }
316   mBlendingOptions.SetBlendEquation( equationRgb, equationAlpha );
317   SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
318 }
319
320 void Renderer::GetBlendEquation( DevelBlendEquation::Type& equationRgb,
321                                  DevelBlendEquation::Type& equationAlpha ) const
322 {
323   // These are not animatable, the cached values are up-to-date.
324   equationRgb   = mBlendingOptions.GetBlendEquationRgb();
325   equationAlpha = mBlendingOptions.GetBlendEquationAlpha();
326 }
327
328 void Renderer::SetIndexedDrawFirstElement( uint32_t firstElement )
329 {
330   if( firstElement != mIndexedDrawFirstElement )
331   {
332     mIndexedDrawFirstElement = firstElement;
333     SetIndexedDrawFirstElementMessage( GetEventThreadServices(), GetRendererSceneObject(), mIndexedDrawFirstElement );
334   }
335 }
336
337 void Renderer::SetIndexedDrawElementsCount( uint32_t elementsCount )
338 {
339   if( elementsCount != mIndexedDrawElementCount )
340   {
341     mIndexedDrawElementCount = elementsCount;
342     SetIndexedDrawElementsCountMessage( GetEventThreadServices(), GetRendererSceneObject(), mIndexedDrawElementCount );
343   }
344 }
345
346
347 void Renderer::EnablePreMultipliedAlpha( bool preMultipled )
348 {
349   if(  mPremultipledAlphaEnabled != preMultipled )
350   {
351     if( preMultipled )
352     {
353       SetBlendFunc( BlendFactor::ONE, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::ONE, BlendFactor::ONE_MINUS_SRC_ALPHA );
354     }
355     else
356     {
357       SetBlendFunc( BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::ONE, BlendFactor::ONE_MINUS_SRC_ALPHA );
358     }
359     mPremultipledAlphaEnabled = preMultipled;
360     SetEnablePreMultipliedAlphaMessage( GetEventThreadServices(), GetRendererSceneObject(), mPremultipledAlphaEnabled );
361   }
362 }
363
364 bool Renderer::IsPreMultipliedAlphaEnabled() const
365 {
366   return mPremultipledAlphaEnabled;
367 }
368
369 bool Renderer::IsAdvancedBlendEquationApplied() const
370 {
371   DevelBlendEquation::Type equationRgb, equationAlpha;
372   GetBlendEquation( equationRgb, equationAlpha );
373
374   if( equationRgb != equationAlpha )
375   {
376     return false;
377   }
378
379   return mBlendingOptions.IsAdvancedBlendEquation( equationRgb );
380 }
381
382 const SceneGraph::Renderer& Renderer::GetRendererSceneObject() const
383 {
384   return static_cast<const SceneGraph::Renderer&>( GetSceneObject() );
385 }
386
387 void Renderer::SetDefaultProperty( Property::Index index,
388                                    const Property::Value& propertyValue )
389 {
390   switch( index )
391   {
392     case Dali::Renderer::Property::DEPTH_INDEX:
393     {
394       SetDepthIndex( propertyValue.Get<int32_t>() );
395       break;
396     }
397     case Dali::Renderer::Property::FACE_CULLING_MODE:
398     {
399       FaceCullingMode::Type convertedValue = mFaceCullingMode;
400       if( Scripting::GetEnumerationProperty< FaceCullingMode::Type >( propertyValue, FACE_CULLING_MODE_TABLE, FACE_CULLING_MODE_TABLE_COUNT, convertedValue ) )
401       {
402         mFaceCullingMode = convertedValue;
403         SetFaceCullingModeMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
404       }
405       break;
406     }
407     case Dali::Renderer::Property::BLEND_MODE:
408     {
409       BlendMode::Type convertedValue = mBlendMode;
410       if( Scripting::GetEnumerationProperty< BlendMode::Type >( propertyValue, BLEND_MODE_TABLE, BLEND_MODE_TABLE_COUNT, convertedValue ) )
411       {
412         SetBlendMode( convertedValue );
413       }
414       break;
415     }
416     case Dali::DevelRenderer::Property::BLEND_EQUATION:
417     {
418       DevelBlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationRgb();
419
420       if( Scripting::GetEnumerationProperty< DevelBlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
421       {
422         mBlendingOptions.SetBlendEquation( convertedValue, convertedValue );
423         SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
424       }
425       break;
426     }
427     case Dali::Renderer::Property::BLEND_EQUATION_RGB:
428     {
429       DevelBlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationRgb();
430
431       if( Scripting::GetEnumerationProperty< DevelBlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
432       {
433         if( mBlendingOptions.IsAdvancedBlendEquation( convertedValue ) )
434         {
435           DALI_LOG_ERROR("Advanced blend equation requires to be set by using DevelBlendEquation::BLEND_EQUATION.");
436           break;
437         }
438         DevelBlendEquation::Type alphaEquation = mBlendingOptions.GetBlendEquationAlpha();
439         mBlendingOptions.SetBlendEquation( convertedValue, alphaEquation );
440         SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
441       }
442       break;
443     }
444     case Dali::Renderer::Property::BLEND_EQUATION_ALPHA:
445     {
446       DevelBlendEquation::Type convertedValue = mBlendingOptions.GetBlendEquationAlpha();
447
448       if( Scripting::GetEnumerationProperty< DevelBlendEquation::Type >( propertyValue, BLEND_EQUATION_TABLE, BLEND_EQUATION_TABLE_COUNT, convertedValue ) )
449       {
450         if( mBlendingOptions.IsAdvancedBlendEquation( convertedValue ) )
451         {
452           DALI_LOG_ERROR("Advanced blend equation requires to be set by using DevelBlendEquation::BLEND_EQUATION.");
453           break;
454         }
455         DevelBlendEquation::Type rgbEquation = mBlendingOptions.GetBlendEquationRgb();
456         mBlendingOptions.SetBlendEquation( rgbEquation, convertedValue );
457         SetBlendingOptionsMessage( GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask() );
458       }
459       break;
460     }
461     case Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB:
462     {
463       BlendFactor::Type sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha;
464       GetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
465
466       if( Scripting::GetEnumerationProperty< BlendFactor::Type >( propertyValue, BLEND_FACTOR_TABLE, BLEND_FACTOR_TABLE_COUNT, sourceFactorRgb ) )
467       {
468         SetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
469       }
470       break;
471     }
472     case Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB:
473     {
474       BlendFactor::Type sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha;
475       GetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
476
477       if( Scripting::GetEnumerationProperty< BlendFactor::Type >( propertyValue, BLEND_FACTOR_TABLE, BLEND_FACTOR_TABLE_COUNT, destinationFactorRgb ) )
478       {
479         SetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
480       }
481       break;
482     }
483     case Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA:
484     {
485       BlendFactor::Type sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha;
486       GetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
487
488       if( Scripting::GetEnumerationProperty< BlendFactor::Type >( propertyValue, BLEND_FACTOR_TABLE, BLEND_FACTOR_TABLE_COUNT, sourceFactorAlpha ) )
489       {
490         SetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
491       }
492       break;
493     }
494     case Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA:
495     {
496       BlendFactor::Type sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha;
497       GetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
498
499       if( Scripting::GetEnumerationProperty< BlendFactor::Type >( propertyValue, BLEND_FACTOR_TABLE, BLEND_FACTOR_TABLE_COUNT, destinationFactorAlpha ) )
500       {
501         SetBlendFunc( sourceFactorRgb, destinationFactorRgb, sourceFactorAlpha, destinationFactorAlpha );
502       }
503       break;
504     }
505     case Dali::Renderer::Property::BLEND_COLOR:
506     {
507       Vector4 blendColor;
508       if( propertyValue.Get( blendColor ) )
509       {
510         SetBlendColor( blendColor );
511       }
512       break;
513     }
514     case Dali::Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA:
515     {
516       bool preMultipled;
517       if( propertyValue.Get( preMultipled ) )
518       {
519         EnablePreMultipliedAlpha( preMultipled );
520       }
521       break;
522     }
523     case Dali::Renderer::Property::INDEX_RANGE_FIRST:
524     {
525       int32_t firstElement;
526       if( propertyValue.Get( firstElement ) )
527       {
528         SetIndexedDrawFirstElement( firstElement );
529       }
530       break;
531     }
532     case Dali::Renderer::Property::INDEX_RANGE_COUNT:
533     {
534       int32_t elementsCount;
535       if( propertyValue.Get( elementsCount ) )
536       {
537         SetIndexedDrawElementsCount( elementsCount );
538       }
539       break;
540     }
541     case Dali::Renderer::Property::DEPTH_WRITE_MODE:
542     {
543       DepthWriteMode::Type convertedValue = mDepthWriteMode;
544       if( Scripting::GetEnumerationProperty< DepthWriteMode::Type >( propertyValue, DEPTH_WRITE_MODE_TABLE, DEPTH_WRITE_MODE_TABLE_COUNT, convertedValue ) )
545       {
546         mDepthWriteMode = convertedValue;
547         SetDepthWriteModeMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
548       }
549       break;
550     }
551     case Dali::Renderer::Property::DEPTH_FUNCTION:
552     {
553       DepthFunction::Type convertedValue = mDepthFunction;
554       if( Scripting::GetEnumerationProperty< DepthFunction::Type >( propertyValue, DEPTH_FUNCTION_TABLE, DEPTH_FUNCTION_TABLE_COUNT, convertedValue ) )
555       {
556         mDepthFunction = convertedValue;
557         SetDepthFunctionMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
558       }
559       break;
560     }
561     case Dali::Renderer::Property::DEPTH_TEST_MODE:
562     {
563       DepthTestMode::Type convertedValue = mDepthTestMode;
564       if( Scripting::GetEnumerationProperty< DepthTestMode::Type >( propertyValue, DEPTH_TEST_MODE_TABLE, DEPTH_TEST_MODE_TABLE_COUNT, convertedValue ) )
565       {
566         mDepthTestMode = convertedValue;
567         SetDepthTestModeMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
568       }
569       break;
570     }
571     case Dali::Renderer::Property::RENDER_MODE:
572     {
573       RenderMode::Type convertedValue = mStencilParameters.renderMode;
574       if( Scripting::GetEnumerationProperty< RenderMode::Type >( propertyValue, RENDER_MODE_TABLE, RENDER_MODE_TABLE_COUNT, convertedValue ) )
575       {
576         mStencilParameters.renderMode = convertedValue;
577         SetRenderModeMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
578       }
579       break;
580     }
581     case Dali::Renderer::Property::STENCIL_FUNCTION:
582     {
583       StencilFunction::Type convertedValue = mStencilParameters.stencilFunction;
584       if( Scripting::GetEnumerationProperty< StencilFunction::Type >( propertyValue, STENCIL_FUNCTION_TABLE, STENCIL_FUNCTION_TABLE_COUNT, convertedValue ) )
585       {
586         mStencilParameters.stencilFunction = convertedValue;
587         SetStencilFunctionMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
588       }
589       break;
590     }
591     case Dali::Renderer::Property::STENCIL_FUNCTION_MASK:
592     {
593       int32_t stencilFunctionMask;
594       if( propertyValue.Get( stencilFunctionMask ) )
595       {
596         if( stencilFunctionMask != mStencilParameters.stencilFunctionMask )
597         {
598           mStencilParameters.stencilFunctionMask = stencilFunctionMask;
599           SetStencilFunctionMaskMessage( GetEventThreadServices(), GetRendererSceneObject(), stencilFunctionMask );
600         }
601       }
602       break;
603     }
604     case Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE:
605     {
606       int32_t stencilFunctionReference;
607       if( propertyValue.Get( stencilFunctionReference ) )
608       {
609         if( stencilFunctionReference != mStencilParameters.stencilFunctionReference )
610         {
611           mStencilParameters.stencilFunctionReference = stencilFunctionReference;
612           SetStencilFunctionReferenceMessage( GetEventThreadServices(), GetRendererSceneObject(), stencilFunctionReference );
613         }
614       }
615       break;
616     }
617     case Dali::Renderer::Property::STENCIL_MASK:
618     {
619       int32_t stencilMask;
620       if( propertyValue.Get( stencilMask ) )
621       {
622         if( stencilMask != mStencilParameters.stencilMask )
623         {
624           mStencilParameters.stencilMask = stencilMask;
625           SetStencilMaskMessage( GetEventThreadServices(), GetRendererSceneObject(), stencilMask );
626         }
627       }
628       break;
629     }
630     case Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL:
631     {
632       StencilOperation::Type convertedValue = mStencilParameters.stencilOperationOnFail;
633       if( Scripting::GetEnumerationProperty< StencilOperation::Type >( propertyValue, STENCIL_OPERATION_TABLE, STENCIL_OPERATION_TABLE_COUNT, convertedValue ) )
634       {
635         mStencilParameters.stencilOperationOnFail = convertedValue;
636         SetStencilOperationOnFailMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
637       }
638       break;
639     }
640     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL:
641     {
642       StencilOperation::Type convertedValue = mStencilParameters.stencilOperationOnZFail;
643       if( Scripting::GetEnumerationProperty< StencilOperation::Type >( propertyValue, STENCIL_OPERATION_TABLE, STENCIL_OPERATION_TABLE_COUNT, convertedValue ) )
644       {
645         mStencilParameters.stencilOperationOnZFail = convertedValue;
646         SetStencilOperationOnZFailMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
647       }
648       break;
649     }
650     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS:
651     {
652       StencilOperation::Type convertedValue = mStencilParameters.stencilOperationOnZPass;
653       if( Scripting::GetEnumerationProperty< StencilOperation::Type >( propertyValue, STENCIL_OPERATION_TABLE, STENCIL_OPERATION_TABLE_COUNT, convertedValue ) )
654       {
655         mStencilParameters.stencilOperationOnZPass = convertedValue;
656         SetStencilOperationOnZPassMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
657       }
658       break;
659     }
660     case Dali::DevelRenderer::Property::OPACITY:
661     {
662       float opacity;
663       if( propertyValue.Get( opacity ) )
664       {
665         if( !Equals( mOpacity, opacity ) )
666         {
667           mOpacity = opacity;
668           BakeOpacityMessage( GetEventThreadServices(), GetRendererSceneObject(), mOpacity );
669         }
670       }
671       break;
672     }
673     case DevelRenderer::Property::RENDERING_BEHAVIOR:
674     {
675       DevelRenderer::Rendering::Type convertedValue = mRenderingBehavior;
676       if( Scripting::GetEnumerationProperty< DevelRenderer::Rendering::Type >( propertyValue, RENDERING_BEHAVIOR_TABLE, RENDERING_BEHAVIOR_TABLE_COUNT, convertedValue ) )
677       {
678         mRenderingBehavior = convertedValue;
679         SetRenderingBehaviorMessage( GetEventThreadServices(), GetRendererSceneObject(), convertedValue );
680       }
681       break;
682     }
683   }
684 }
685
686 Property::Value Renderer::GetDefaultProperty( Property::Index index ) const
687 {
688   Property::Value value;
689
690   if( ! GetCachedPropertyValue( index, value ) )
691   {
692     // If property value is not stored in the event-side, then it must be a scene-graph only property
693     GetCurrentPropertyValue( index, value );
694   }
695
696   return value;
697 }
698
699 Property::Value Renderer::GetDefaultPropertyCurrentValue( Property::Index index ) const
700 {
701   Property::Value value;
702
703   if( ! GetCurrentPropertyValue( index, value ) )
704   {
705     // If unable to retrieve scene-graph property value, then it must be an event-side only property
706     GetCachedPropertyValue( index, value );
707   }
708
709   return value;
710 }
711
712 void Renderer::OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
713 {
714   switch( animationType )
715   {
716     case Animation::TO:
717     case Animation::BETWEEN:
718     {
719       switch( index )
720       {
721         case Dali::DevelRenderer::Property::OPACITY:
722         {
723           value.Get( mOpacity );
724           break;
725         }
726       }
727       break;
728     }
729
730     case Animation::BY:
731     {
732       switch( index )
733       {
734         case Dali::DevelRenderer::Property::OPACITY:
735         {
736           AdjustValue< float >( mOpacity, value );
737           break;
738         }
739       }
740       break;
741     }
742   }
743 }
744
745 const SceneGraph::PropertyBase* Renderer::GetSceneObjectAnimatableProperty( Property::Index index ) const
746 {
747   const SceneGraph::PropertyBase* property = nullptr;
748
749   if( index == DevelRenderer::Property::OPACITY )
750   {
751     property = &GetRendererSceneObject().mOpacity;
752   }
753   if( !property )
754   {
755     // not our property, ask base
756     property = Object::GetSceneObjectAnimatableProperty( index );
757   }
758
759   return property;
760 }
761
762 const PropertyInputImpl* Renderer::GetSceneObjectInputProperty( Property::Index index ) const
763 {
764   // reuse animatable property getter, Object::GetSceneObjectInputProperty does the same so no need to call that0
765   return GetSceneObjectAnimatableProperty( index );
766 }
767
768 Renderer::Renderer( const SceneGraph::Renderer* sceneObject )
769 : Object( sceneObject ),
770   mDepthIndex( 0 ),
771   mIndexedDrawFirstElement( 0 ),
772   mIndexedDrawElementCount( 0 ),
773   mStencilParameters( RenderMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP ),
774   mBlendingOptions(),
775   mOpacity( 1.0f ),
776   mDepthFunction( DepthFunction::LESS ),
777   mFaceCullingMode( FaceCullingMode::NONE ),
778   mBlendMode( BlendMode::AUTO ),
779   mDepthWriteMode( DepthWriteMode::AUTO ),
780   mDepthTestMode( DepthTestMode::AUTO ),
781   mRenderingBehavior( DevelRenderer::Rendering::IF_REQUIRED ),
782   mPremultipledAlphaEnabled( false )
783 {
784 }
785
786 void Renderer::SetBlendColor( const Vector4& blendColor )
787 {
788   mBlendingOptions.SetBlendColor( blendColor );
789   SetBlendColorMessage( GetEventThreadServices(), GetRendererSceneObject(), GetBlendColor() );
790 }
791
792 const Vector4& Renderer::GetBlendColor() const
793 {
794   const Vector4* blendColor = mBlendingOptions.GetBlendColor();
795   if( blendColor )
796   {
797     return *blendColor;
798   }
799   return Color::TRANSPARENT; // GL default
800 }
801
802 Renderer::~Renderer()
803 {
804   if( EventThreadServices::IsCoreRunning() )
805   {
806     EventThreadServices& eventThreadServices = GetEventThreadServices();
807     SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
808     RemoveRendererMessage( updateManager, GetRendererSceneObject() );
809
810     eventThreadServices.UnregisterObject( this );
811   }
812 }
813
814 bool Renderer::GetCachedPropertyValue( Property::Index index, Property::Value& value ) const
815 {
816   bool valueSet = true;
817
818   switch( index )
819   {
820     case Dali::Renderer::Property::DEPTH_INDEX:
821     {
822       value = GetDepthIndex();
823       break;
824     }
825     case Dali::Renderer::Property::FACE_CULLING_MODE:
826     {
827       value = mFaceCullingMode;
828       break;
829     }
830     case Dali::Renderer::Property::BLEND_MODE:
831     {
832       value = mBlendMode;
833       break;
834     }
835     case Dali::DevelRenderer::Property::BLEND_EQUATION:
836     {
837       value = static_cast<int32_t>( mBlendingOptions.GetBlendEquationRgb() );
838       break;
839     }
840     case Dali::Renderer::Property::BLEND_EQUATION_RGB:
841     {
842       value = static_cast<int32_t>( mBlendingOptions.GetBlendEquationRgb() );
843       break;
844     }
845     case Dali::Renderer::Property::BLEND_EQUATION_ALPHA:
846     {
847       value = static_cast<int32_t>( mBlendingOptions.GetBlendEquationAlpha() );
848       break;
849     }
850     case Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB:
851     {
852       BlendFactor::Type srcFactorRgb;
853       BlendFactor::Type destFactorRgb;
854       BlendFactor::Type srcFactorAlpha;
855       BlendFactor::Type destFactorAlpha;
856       GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
857       value = static_cast<int32_t>( srcFactorRgb );
858       break;
859     }
860     case Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB:
861     {
862       BlendFactor::Type srcFactorRgb;
863       BlendFactor::Type destFactorRgb;
864       BlendFactor::Type srcFactorAlpha;
865       BlendFactor::Type destFactorAlpha;
866       GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
867       value = static_cast<int32_t>( destFactorRgb );
868       break;
869     }
870     case Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA:
871     {
872       BlendFactor::Type srcFactorRgb;
873       BlendFactor::Type destFactorRgb;
874       BlendFactor::Type srcFactorAlpha;
875       BlendFactor::Type destFactorAlpha;
876       GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
877       value = static_cast<int32_t>( srcFactorAlpha );
878       break;
879     }
880     case Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA:
881     {
882       BlendFactor::Type srcFactorRgb;
883       BlendFactor::Type destFactorRgb;
884       BlendFactor::Type srcFactorAlpha;
885       BlendFactor::Type destFactorAlpha;
886       GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
887       value = static_cast<int32_t>( destFactorAlpha );
888       break;
889     }
890     case Dali::Renderer::Property::BLEND_COLOR:
891     {
892       value = GetBlendColor();
893       break;
894     }
895     case Dali::Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA:
896     {
897       value = IsPreMultipliedAlphaEnabled();
898       break;
899     }
900     case Dali::Renderer::Property::INDEX_RANGE_FIRST:
901     {
902       value = static_cast<int32_t>( mIndexedDrawFirstElement );
903       break;
904     }
905     case Dali::Renderer::Property::INDEX_RANGE_COUNT:
906     {
907       value = static_cast<int32_t>( mIndexedDrawElementCount );
908       break;
909     }
910     case Dali::Renderer::Property::DEPTH_WRITE_MODE:
911     {
912       value = mDepthWriteMode;
913       break;
914     }
915     case Dali::Renderer::Property::DEPTH_FUNCTION:
916     {
917       value = mDepthFunction;
918       break;
919     }
920     case Dali::Renderer::Property::DEPTH_TEST_MODE:
921     {
922       value = mDepthTestMode;
923       break;
924     }
925     case Dali::Renderer::Property::STENCIL_FUNCTION:
926     {
927       value = mStencilParameters.stencilFunction;
928       break;
929     }
930     case Dali::Renderer::Property::STENCIL_FUNCTION_MASK:
931     {
932       value = mStencilParameters.stencilFunctionMask;
933       break;
934     }
935     case Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE:
936     {
937       value = mStencilParameters.stencilFunctionReference;
938       break;
939     }
940     case Dali::Renderer::Property::STENCIL_MASK:
941     {
942       value = mStencilParameters.stencilMask;
943       break;
944     }
945     case Dali::Renderer::Property::RENDER_MODE:
946     {
947       value = mStencilParameters.renderMode;
948       break;
949     }
950     case Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL:
951     {
952       value = mStencilParameters.stencilOperationOnFail;
953       break;
954     }
955     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL:
956     {
957       value = mStencilParameters.stencilOperationOnZFail;
958       break;
959     }
960     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS:
961     {
962       value = mStencilParameters.stencilOperationOnZPass;
963       break;
964     }
965     case Dali::DevelRenderer::Property::OPACITY:
966     {
967       value = mOpacity;
968       break;
969     }
970     case Dali::DevelRenderer::Property::RENDERING_BEHAVIOR:
971     {
972       value = mRenderingBehavior;
973       break;
974     }
975     default:
976     {
977       // Must be a scene-graph only property
978       valueSet = false;
979       break;
980     }
981   }
982
983   return valueSet;
984 }
985
986 bool Renderer::GetCurrentPropertyValue( Property::Index index, Property::Value& value  ) const
987 {
988   bool valueSet = true;
989   const SceneGraph::Renderer& sceneObject = GetRendererSceneObject();
990
991   switch( index )
992   {
993     case Dali::Renderer::Property::DEPTH_INDEX:
994     {
995       value = sceneObject.GetDepthIndex();
996       break;
997     }
998     case Dali::Renderer::Property::FACE_CULLING_MODE:
999     {
1000       value = sceneObject.GetFaceCullingMode();
1001       break;
1002     }
1003     case Dali::Renderer::Property::BLEND_MODE:
1004     {
1005       value = sceneObject.GetBlendMode();
1006       break;
1007     }
1008     case Dali::DevelRenderer::Property::BLEND_EQUATION:
1009     {
1010       uint32_t bitMask = sceneObject.GetBlendingOptions();
1011       BlendingOptions blendingOptions;
1012       blendingOptions.SetBitmask( bitMask );
1013       value = static_cast<int32_t>( blendingOptions.GetBlendEquationRgb() );
1014       break;
1015     }
1016     case Dali::Renderer::Property::BLEND_EQUATION_RGB:
1017     {
1018       uint32_t bitMask = sceneObject.GetBlendingOptions();
1019       BlendingOptions blendingOptions;
1020       blendingOptions.SetBitmask( bitMask );
1021       value = static_cast<int32_t>( blendingOptions.GetBlendEquationRgb() );
1022       break;
1023     }
1024     case Dali::Renderer::Property::BLEND_EQUATION_ALPHA:
1025     {
1026       uint32_t bitMask = sceneObject.GetBlendingOptions();
1027       BlendingOptions blendingOptions;
1028       blendingOptions.SetBitmask( bitMask );
1029       value = static_cast<int32_t>( blendingOptions.GetBlendEquationAlpha() );
1030       break;
1031     }
1032     case Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB:
1033     {
1034       uint32_t bitMask = sceneObject.GetBlendingOptions();
1035       BlendingOptions blendingOptions;
1036       blendingOptions.SetBitmask( bitMask );
1037       value = static_cast<int32_t>( blendingOptions.GetBlendSrcFactorRgb() );
1038       break;
1039     }
1040     case Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB:
1041     {
1042       uint32_t bitMask = sceneObject.GetBlendingOptions();
1043       BlendingOptions blendingOptions;
1044       blendingOptions.SetBitmask( bitMask );
1045       value = static_cast<int32_t>( blendingOptions.GetBlendDestFactorRgb() );
1046       break;
1047     }
1048     case Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA:
1049     {
1050       uint32_t bitMask = sceneObject.GetBlendingOptions();
1051       BlendingOptions blendingOptions;
1052       blendingOptions.SetBitmask( bitMask );
1053       value = static_cast<int32_t>( blendingOptions.GetBlendSrcFactorAlpha() );
1054       break;
1055     }
1056     case Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA:
1057     {
1058       uint32_t bitMask = sceneObject.GetBlendingOptions();
1059       BlendingOptions blendingOptions;
1060       blendingOptions.SetBitmask( bitMask );
1061       value = static_cast<int32_t>( blendingOptions.GetBlendDestFactorAlpha() );
1062       break;
1063     }
1064     case Dali::Renderer::Property::BLEND_COLOR:
1065     {
1066       value = sceneObject.GetBlendColor();
1067       break;
1068     }
1069     case Dali::Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA:
1070     {
1071       value = sceneObject.IsPreMultipliedAlphaEnabled();
1072       break;
1073     }
1074     case Dali::Renderer::Property::INDEX_RANGE_FIRST:
1075     {
1076       value = static_cast<int32_t>( sceneObject.GetIndexedDrawFirstElement() );
1077       break;
1078     }
1079     case Dali::Renderer::Property::INDEX_RANGE_COUNT:
1080     {
1081       value = static_cast<int32_t>( sceneObject.GetIndexedDrawElementsCount() );
1082       break;
1083     }
1084     case Dali::Renderer::Property::DEPTH_WRITE_MODE:
1085     {
1086       value = sceneObject.GetDepthWriteMode();
1087       break;
1088     }
1089     case Dali::Renderer::Property::DEPTH_FUNCTION:
1090     {
1091       value = sceneObject.GetDepthFunction();
1092       break;
1093     }
1094     case Dali::Renderer::Property::DEPTH_TEST_MODE:
1095     {
1096       value = sceneObject.GetDepthTestMode();
1097       break;
1098     }
1099     case Dali::Renderer::Property::STENCIL_FUNCTION:
1100     {
1101       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1102       value = stencilParameters.stencilFunction;
1103       break;
1104     }
1105     case Dali::Renderer::Property::STENCIL_FUNCTION_MASK:
1106     {
1107       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1108       value = stencilParameters.stencilFunctionMask;
1109       break;
1110     }
1111     case Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE:
1112     {
1113       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1114       value = stencilParameters.stencilFunctionReference;
1115       break;
1116     }
1117     case Dali::Renderer::Property::STENCIL_MASK:
1118     {
1119       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1120       value = stencilParameters.stencilMask;
1121       break;
1122     }
1123     case Dali::Renderer::Property::RENDER_MODE:
1124     {
1125       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1126       value = stencilParameters.renderMode;
1127       break;
1128     }
1129     case Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL:
1130     {
1131       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1132       value = stencilParameters.stencilOperationOnFail;
1133       break;
1134     }
1135     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL:
1136     {
1137       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1138       value = stencilParameters.stencilOperationOnZFail;
1139       break;
1140     }
1141     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS:
1142     {
1143       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1144       value = stencilParameters.stencilOperationOnZPass;
1145       break;
1146     }
1147     case Dali::DevelRenderer::Property::OPACITY:
1148     {
1149       value = sceneObject.GetOpacity( GetEventThreadServices().GetEventBufferIndex() );
1150       break;
1151     }
1152     case Dali::DevelRenderer::Property::RENDERING_BEHAVIOR:
1153     {
1154       value = sceneObject.GetRenderingBehavior();
1155       break;
1156     }
1157     default:
1158     {
1159       // Must be an event-side only property
1160       valueSet = false;
1161       break;
1162     }
1163   }
1164
1165   return valueSet;
1166 }
1167
1168 void Renderer::AddDrawCommand( const Dali::DevelRenderer::DrawCommand& command )
1169 {
1170   if(!mDrawCommands.capacity())
1171   {
1172     mDrawCommands.reserve(8);
1173   }
1174
1175   mDrawCommands.emplace_back( command );
1176
1177   Dali::Internal::SceneGraph::SetDrawCommandsMessage( GetEventThreadServices(),
1178                                                       GetRendererSceneObject(),
1179                                                       mDrawCommands.data(),
1180                                                       uint32_t(mDrawCommands.size())
1181
1182   );
1183 }
1184
1185
1186 } // namespace Internal
1187
1188 } // namespace Dali