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