Merge changes I8783ad29,I2c860a84 into 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_TABLE_END(DEFAULT_RENDERER_PROPERTY_START_INDEX, RendererDefaultProperties)
69
70 // Property string to enumeration tables:
71
72 DALI_ENUM_TO_STRING_TABLE_BEGIN(FACE_CULLING_MODE)
73   DALI_ENUM_TO_STRING_WITH_SCOPE(FaceCullingMode, NONE)
74   DALI_ENUM_TO_STRING_WITH_SCOPE(FaceCullingMode, FRONT)
75   DALI_ENUM_TO_STRING_WITH_SCOPE(FaceCullingMode, BACK)
76   DALI_ENUM_TO_STRING_WITH_SCOPE(FaceCullingMode, FRONT_AND_BACK)
77 DALI_ENUM_TO_STRING_TABLE_END(FACE_CULLING_MODE)
78
79 DALI_ENUM_TO_STRING_TABLE_BEGIN(BLEND_MODE)
80   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendMode, OFF)
81   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendMode, AUTO)
82   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendMode, ON)
83   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendMode, ON_WITHOUT_CULL)
84   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendMode, USE_ACTOR_OPACITY)
85 DALI_ENUM_TO_STRING_TABLE_END(BLEND_MODE)
86
87 DALI_ENUM_TO_STRING_TABLE_BEGIN(BLEND_EQUATION)
88   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendEquation, ADD)
89   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendEquation, SUBTRACT)
90   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendEquation, REVERSE_SUBTRACT)
91   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, MIN)
92   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, MAX)
93   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, MULTIPLY)
94   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, SCREEN)
95   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, OVERLAY)
96   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, DARKEN)
97   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, LIGHTEN)
98   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, COLOR_DODGE)
99   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, COLOR_BURN)
100   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, HARD_LIGHT)
101   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, SOFT_LIGHT)
102   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, DIFFERENCE)
103   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, EXCLUSION)
104   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, HUE)
105   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, SATURATION)
106   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, COLOR)
107   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelBlendEquation, LUMINOSITY)
108 DALI_ENUM_TO_STRING_TABLE_END(BLEND_EQUATION)
109
110 DALI_ENUM_TO_STRING_TABLE_BEGIN(BLEND_FACTOR)
111   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendFactor, ZERO)
112   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendFactor, ONE)
113   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendFactor, SRC_COLOR)
114   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendFactor, ONE_MINUS_SRC_COLOR)
115   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendFactor, SRC_ALPHA)
116   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendFactor, ONE_MINUS_SRC_ALPHA)
117   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendFactor, DST_ALPHA)
118   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendFactor, ONE_MINUS_DST_ALPHA)
119   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendFactor, DST_COLOR)
120   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendFactor, ONE_MINUS_DST_COLOR)
121   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendFactor, SRC_ALPHA_SATURATE)
122   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendFactor, CONSTANT_COLOR)
123   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendFactor, ONE_MINUS_CONSTANT_COLOR)
124   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendFactor, CONSTANT_ALPHA)
125   DALI_ENUM_TO_STRING_WITH_SCOPE(BlendFactor, ONE_MINUS_CONSTANT_ALPHA)
126 DALI_ENUM_TO_STRING_TABLE_END(BLEND_FACTOR)
127
128 DALI_ENUM_TO_STRING_TABLE_BEGIN(DEPTH_WRITE_MODE)
129   DALI_ENUM_TO_STRING_WITH_SCOPE(DepthWriteMode, OFF)
130   DALI_ENUM_TO_STRING_WITH_SCOPE(DepthWriteMode, AUTO)
131   DALI_ENUM_TO_STRING_WITH_SCOPE(DepthWriteMode, ON)
132 DALI_ENUM_TO_STRING_TABLE_END(DEPTH_WRITE_MODE)
133
134 DALI_ENUM_TO_STRING_TABLE_BEGIN(DEPTH_TEST_MODE)
135   DALI_ENUM_TO_STRING_WITH_SCOPE(DepthTestMode, OFF)
136   DALI_ENUM_TO_STRING_WITH_SCOPE(DepthTestMode, AUTO)
137   DALI_ENUM_TO_STRING_WITH_SCOPE(DepthTestMode, ON)
138 DALI_ENUM_TO_STRING_TABLE_END(DEPTH_TEST_MODE)
139
140 DALI_ENUM_TO_STRING_TABLE_BEGIN(DEPTH_FUNCTION)
141   DALI_ENUM_TO_STRING_WITH_SCOPE(DepthFunction, NEVER)
142   DALI_ENUM_TO_STRING_WITH_SCOPE(DepthFunction, ALWAYS)
143   DALI_ENUM_TO_STRING_WITH_SCOPE(DepthFunction, LESS)
144   DALI_ENUM_TO_STRING_WITH_SCOPE(DepthFunction, GREATER)
145   DALI_ENUM_TO_STRING_WITH_SCOPE(DepthFunction, EQUAL)
146   DALI_ENUM_TO_STRING_WITH_SCOPE(DepthFunction, NOT_EQUAL)
147   DALI_ENUM_TO_STRING_WITH_SCOPE(DepthFunction, LESS_EQUAL)
148   DALI_ENUM_TO_STRING_WITH_SCOPE(DepthFunction, GREATER_EQUAL)
149 DALI_ENUM_TO_STRING_TABLE_END(DEPTH_FUNCTION)
150
151 DALI_ENUM_TO_STRING_TABLE_BEGIN(STENCIL_FUNCTION)
152   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilFunction, NEVER)
153   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilFunction, LESS)
154   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilFunction, EQUAL)
155   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilFunction, LESS_EQUAL)
156   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilFunction, GREATER)
157   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilFunction, NOT_EQUAL)
158   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilFunction, GREATER_EQUAL)
159   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilFunction, ALWAYS)
160 DALI_ENUM_TO_STRING_TABLE_END(STENCIL_FUNCTION)
161
162 DALI_ENUM_TO_STRING_TABLE_BEGIN(RENDER_MODE)
163   DALI_ENUM_TO_STRING_WITH_SCOPE(RenderMode, NONE)
164   DALI_ENUM_TO_STRING_WITH_SCOPE(RenderMode, AUTO)
165   DALI_ENUM_TO_STRING_WITH_SCOPE(RenderMode, COLOR)
166   DALI_ENUM_TO_STRING_WITH_SCOPE(RenderMode, STENCIL)
167   DALI_ENUM_TO_STRING_WITH_SCOPE(RenderMode, COLOR_STENCIL)
168 DALI_ENUM_TO_STRING_TABLE_END(RENDER_MODE)
169
170 DALI_ENUM_TO_STRING_TABLE_BEGIN(STENCIL_OPERATION)
171   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilOperation, ZERO)
172   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilOperation, KEEP)
173   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilOperation, REPLACE)
174   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilOperation, INCREMENT)
175   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilOperation, DECREMENT)
176   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilOperation, INVERT)
177   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilOperation, INCREMENT_WRAP)
178   DALI_ENUM_TO_STRING_WITH_SCOPE(StencilOperation, DECREMENT_WRAP)
179 DALI_ENUM_TO_STRING_TABLE_END(STENCIL_OPERATION)
180
181 DALI_ENUM_TO_STRING_TABLE_BEGIN(RENDERING_BEHAVIOR)
182   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelRenderer::Rendering, IF_REQUIRED)
183   DALI_ENUM_TO_STRING_WITH_SCOPE(DevelRenderer::Rendering, CONTINUOUSLY)
184 DALI_ENUM_TO_STRING_TABLE_END(RENDERING_BEHAVIOR)
185
186 BaseHandle Create()
187 {
188   return Dali::BaseHandle();
189 }
190
191 TypeRegistration mType(typeid(Dali::Renderer), typeid(Dali::Handle), Create, RendererDefaultProperties);
192
193 } // unnamed namespace
194
195 RendererPtr Renderer::New()
196 {
197   // create scene object first so it's guaranteed to exist for the event side
198   auto sceneObjectKey = SceneGraph::Renderer::NewKey();
199
200   // pass the pointer to base for message passing
201   RendererPtr rendererPtr(new Renderer(sceneObjectKey.Get()));
202
203   EventThreadServices&       eventThreadServices = rendererPtr->GetEventThreadServices();
204   SceneGraph::UpdateManager& updateManager       = eventThreadServices.GetUpdateManager();
205   AddRendererMessage(updateManager, sceneObjectKey);
206
207   eventThreadServices.RegisterObject(rendererPtr.Get());
208   return rendererPtr;
209 }
210
211 void Renderer::SetGeometry(Geometry& geometry)
212 {
213   mGeometry = &geometry;
214
215   const Render::Geometry* geometrySceneObject = geometry.GetRenderObject();
216   SetGeometryMessage(GetEventThreadServices(), GetRendererSceneObject(), *geometrySceneObject);
217 }
218
219 GeometryPtr Renderer::GetGeometry() const
220 {
221   return mGeometry;
222 }
223
224 void Renderer::SetTextures(TextureSet& textureSet)
225 {
226   mTextureSet                                         = &textureSet;
227   const SceneGraph::TextureSet* textureSetSceneObject = textureSet.GetTextureSetSceneObject();
228   SetTexturesMessage(GetEventThreadServices(), GetRendererSceneObject(), *textureSetSceneObject);
229 }
230
231 TextureSetPtr Renderer::GetTextures() const
232 {
233   return mTextureSet;
234 }
235
236 void Renderer::SetShader(Shader& shader)
237 {
238   mShader                                    = &shader;
239   const SceneGraph::Shader& sceneGraphShader = shader.GetShaderSceneObject();
240   SceneGraph::SetShaderMessage(GetEventThreadServices(), GetRendererSceneObject(), sceneGraphShader);
241 }
242
243 ShaderPtr Renderer::GetShader() const
244 {
245   return mShader;
246 }
247
248 void Renderer::SetDepthIndex(int32_t depthIndex)
249 {
250   if(mDepthIndex != depthIndex)
251   {
252     mDepthIndex = depthIndex;
253     SetDepthIndexMessage(GetEventThreadServices(), GetRendererSceneObject(), depthIndex);
254   }
255 }
256
257 int32_t Renderer::GetDepthIndex() const
258 {
259   return mDepthIndex;
260 }
261
262 void Renderer::SetBlendMode(BlendMode::Type mode)
263 {
264   if(mBlendMode != mode)
265   {
266     mBlendMode = mode;
267
268     SetBlendModeMessage(GetEventThreadServices(), GetRendererSceneObject(), mBlendMode);
269   }
270 }
271
272 BlendMode::Type Renderer::GetBlendMode() const
273 {
274   return mBlendMode;
275 }
276
277 void Renderer::SetBlendFunc(BlendFactor::Type srcFactorRgba, BlendFactor::Type destFactorRgba)
278 {
279   mBlendingOptions.SetBlendFunc(srcFactorRgba, destFactorRgba, srcFactorRgba, destFactorRgba);
280   SetBlendingOptionsMessage(GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask());
281 }
282
283 void Renderer::SetBlendFunc(BlendFactor::Type srcFactorRgb,
284                             BlendFactor::Type destFactorRgb,
285                             BlendFactor::Type srcFactorAlpha,
286                             BlendFactor::Type destFactorAlpha)
287 {
288   mBlendingOptions.SetBlendFunc(srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha);
289   SetBlendingOptionsMessage(GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask());
290 }
291
292 void Renderer::GetBlendFunc(BlendFactor::Type& srcFactorRgb,
293                             BlendFactor::Type& destFactorRgb,
294                             BlendFactor::Type& srcFactorAlpha,
295                             BlendFactor::Type& destFactorAlpha) const
296 {
297   srcFactorRgb    = mBlendingOptions.GetBlendSrcFactorRgb();
298   destFactorRgb   = mBlendingOptions.GetBlendDestFactorRgb();
299   srcFactorAlpha  = mBlendingOptions.GetBlendSrcFactorAlpha();
300   destFactorAlpha = mBlendingOptions.GetBlendDestFactorAlpha();
301 }
302
303 void Renderer::SetBlendEquation(DevelBlendEquation::Type equationRgba)
304 {
305   mBlendingOptions.SetBlendEquation(equationRgba, equationRgba);
306   SetBlendingOptionsMessage(GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask());
307 }
308
309 void Renderer::SetBlendEquation(DevelBlendEquation::Type equationRgb,
310                                 DevelBlendEquation::Type equationAlpha)
311 {
312   if(mBlendingOptions.IsAdvancedBlendEquation(equationRgb) || mBlendingOptions.IsAdvancedBlendEquation(equationAlpha))
313   {
314     DALI_LOG_ERROR("Advanced blend equation requires to be set by using SetBlendEquation( DevelBlendEquation::Type equationRgba ).");
315     return;
316   }
317   mBlendingOptions.SetBlendEquation(equationRgb, equationAlpha);
318   SetBlendingOptionsMessage(GetEventThreadServices(), GetRendererSceneObject(), mBlendingOptions.GetBitmask());
319 }
320
321 void Renderer::GetBlendEquation(DevelBlendEquation::Type& equationRgb,
322                                 DevelBlendEquation::Type& equationAlpha) const
323 {
324   // These are not animatable, the cached values are up-to-date.
325   equationRgb   = mBlendingOptions.GetBlendEquationRgb();
326   equationAlpha = mBlendingOptions.GetBlendEquationAlpha();
327 }
328
329 void Renderer::SetIndexedDrawFirstElement(uint32_t firstElement)
330 {
331   if(firstElement != mIndexedDrawFirstElement)
332   {
333     mIndexedDrawFirstElement = firstElement;
334     SetIndexedDrawFirstElementMessage(GetEventThreadServices(), GetRendererSceneObject(), mIndexedDrawFirstElement);
335   }
336 }
337
338 void Renderer::SetIndexedDrawElementsCount(uint32_t elementsCount)
339 {
340   if(elementsCount != mIndexedDrawElementCount)
341   {
342     mIndexedDrawElementCount = elementsCount;
343     SetIndexedDrawElementsCountMessage(GetEventThreadServices(), GetRendererSceneObject(), mIndexedDrawElementCount);
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           auto sceneObject = const_cast<SceneGraph::Renderer*>(&GetRendererSceneObject());
669           SceneGraph::BakeOpacityMessage(GetEventThreadServices(), *sceneObject, mOpacity);
670         }
671       }
672       break;
673     }
674     case DevelRenderer::Property::RENDERING_BEHAVIOR:
675     {
676       DevelRenderer::Rendering::Type convertedValue = mRenderingBehavior;
677       if(Scripting::GetEnumerationProperty<DevelRenderer::Rendering::Type>(propertyValue, RENDERING_BEHAVIOR_TABLE, RENDERING_BEHAVIOR_TABLE_COUNT, convertedValue))
678       {
679         mRenderingBehavior = convertedValue;
680         SetRenderingBehaviorMessage(GetEventThreadServices(), GetRendererSceneObject(), convertedValue);
681       }
682       break;
683     }
684   }
685 }
686
687 Property::Value Renderer::GetDefaultProperty(Property::Index index) const
688 {
689   Property::Value value;
690
691   if(!GetCachedPropertyValue(index, value))
692   {
693     // If property value is not stored in the event-side, then it must be a scene-graph only property
694     GetCurrentPropertyValue(index, value);
695   }
696
697   return value;
698 }
699
700 Property::Value Renderer::GetDefaultPropertyCurrentValue(Property::Index index) const
701 {
702   Property::Value value;
703
704   if(!GetCurrentPropertyValue(index, value))
705   {
706     // If unable to retrieve scene-graph property value, then it must be an event-side only property
707     GetCachedPropertyValue(index, value);
708   }
709
710   return value;
711 }
712
713 void Renderer::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
714 {
715   switch(animationType)
716   {
717     case Animation::TO:
718     case Animation::BETWEEN:
719     {
720       switch(index)
721       {
722         case Dali::DevelRenderer::Property::OPACITY:
723         {
724           value.Get(mOpacity);
725           break;
726         }
727       }
728       break;
729     }
730
731     case Animation::BY:
732     {
733       switch(index)
734       {
735         case Dali::DevelRenderer::Property::OPACITY:
736         {
737           AdjustValue<float>(mOpacity, value);
738           break;
739         }
740       }
741       break;
742     }
743   }
744 }
745
746 const SceneGraph::PropertyBase* Renderer::GetSceneObjectAnimatableProperty(Property::Index index) const
747 {
748   const SceneGraph::PropertyBase* property = nullptr;
749
750   if(index == DevelRenderer::Property::OPACITY)
751   {
752     property = &GetRendererSceneObject().mOpacity;
753   }
754   if(!property)
755   {
756     // not our property, ask base
757     property = Object::GetSceneObjectAnimatableProperty(index);
758   }
759
760   return property;
761 }
762
763 const PropertyInputImpl* Renderer::GetSceneObjectInputProperty(Property::Index index) const
764 {
765   // reuse animatable property getter, Object::GetSceneObjectInputProperty does the same so no need to call that0
766   return GetSceneObjectAnimatableProperty(index);
767 }
768
769 void Renderer::AddDrawCommand(const Dali::DevelRenderer::DrawCommand& command)
770 {
771   if(!mDrawCommands.capacity())
772   {
773     mDrawCommands.reserve(8);
774   }
775
776   mDrawCommands.emplace_back(command);
777
778   Dali::Internal::SceneGraph::SetDrawCommandsMessage(GetEventThreadServices(),
779                                                      GetRendererSceneObject(),
780                                                      mDrawCommands.data(),
781                                                      uint32_t(mDrawCommands.size())
782
783   );
784 }
785
786 Renderer::Renderer(const SceneGraph::Renderer* sceneObject)
787 : Object(sceneObject),
788   mDepthIndex(0),
789   mIndexedDrawFirstElement(0),
790   mIndexedDrawElementCount(0),
791   mStencilParameters(RenderMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP),
792   mBlendingOptions(),
793   mOpacity(1.0f),
794   mDepthFunction(DepthFunction::LESS),
795   mFaceCullingMode(FaceCullingMode::NONE),
796   mBlendMode(BlendMode::AUTO),
797   mDepthWriteMode(DepthWriteMode::AUTO),
798   mDepthTestMode(DepthTestMode::AUTO),
799   mRenderingBehavior(DevelRenderer::Rendering::IF_REQUIRED),
800   mPremultipledAlphaEnabled(false)
801 {
802 }
803
804 Renderer::~Renderer()
805 {
806   if(EventThreadServices::IsCoreRunning())
807   {
808     EventThreadServices&       eventThreadServices = GetEventThreadServices();
809     SceneGraph::UpdateManager& updateManager       = eventThreadServices.GetUpdateManager();
810     RemoveRendererMessage(updateManager, SceneGraph::Renderer::GetKey(GetRendererSceneObject())); //@todo Use key throughtout
811
812     eventThreadServices.UnregisterObject(this);
813   }
814 }
815
816 bool Renderer::GetCachedPropertyValue(Property::Index index, Property::Value& value) const
817 {
818   bool valueSet = true;
819
820   switch(index)
821   {
822     case Dali::Renderer::Property::DEPTH_INDEX:
823     {
824       value = GetDepthIndex();
825       break;
826     }
827     case Dali::Renderer::Property::FACE_CULLING_MODE:
828     {
829       value = mFaceCullingMode;
830       break;
831     }
832     case Dali::Renderer::Property::BLEND_MODE:
833     {
834       value = mBlendMode;
835       break;
836     }
837     case Dali::DevelRenderer::Property::BLEND_EQUATION:
838     {
839       value = static_cast<int32_t>(mBlendingOptions.GetBlendEquationRgb());
840       break;
841     }
842     case Dali::Renderer::Property::BLEND_EQUATION_RGB:
843     {
844       value = static_cast<int32_t>(mBlendingOptions.GetBlendEquationRgb());
845       break;
846     }
847     case Dali::Renderer::Property::BLEND_EQUATION_ALPHA:
848     {
849       value = static_cast<int32_t>(mBlendingOptions.GetBlendEquationAlpha());
850       break;
851     }
852     case Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB:
853     {
854       BlendFactor::Type srcFactorRgb;
855       BlendFactor::Type destFactorRgb;
856       BlendFactor::Type srcFactorAlpha;
857       BlendFactor::Type destFactorAlpha;
858       GetBlendFunc(srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha);
859       value = static_cast<int32_t>(srcFactorRgb);
860       break;
861     }
862     case Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB:
863     {
864       BlendFactor::Type srcFactorRgb;
865       BlendFactor::Type destFactorRgb;
866       BlendFactor::Type srcFactorAlpha;
867       BlendFactor::Type destFactorAlpha;
868       GetBlendFunc(srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha);
869       value = static_cast<int32_t>(destFactorRgb);
870       break;
871     }
872     case Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA:
873     {
874       BlendFactor::Type srcFactorRgb;
875       BlendFactor::Type destFactorRgb;
876       BlendFactor::Type srcFactorAlpha;
877       BlendFactor::Type destFactorAlpha;
878       GetBlendFunc(srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha);
879       value = static_cast<int32_t>(srcFactorAlpha);
880       break;
881     }
882     case Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA:
883     {
884       BlendFactor::Type srcFactorRgb;
885       BlendFactor::Type destFactorRgb;
886       BlendFactor::Type srcFactorAlpha;
887       BlendFactor::Type destFactorAlpha;
888       GetBlendFunc(srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha);
889       value = static_cast<int32_t>(destFactorAlpha);
890       break;
891     }
892     case Dali::Renderer::Property::BLEND_COLOR:
893     {
894       value = GetBlendColor();
895       break;
896     }
897     case Dali::Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA:
898     {
899       value = IsPreMultipliedAlphaEnabled();
900       break;
901     }
902     case Dali::Renderer::Property::INDEX_RANGE_FIRST:
903     {
904       value = static_cast<int32_t>(mIndexedDrawFirstElement);
905       break;
906     }
907     case Dali::Renderer::Property::INDEX_RANGE_COUNT:
908     {
909       value = static_cast<int32_t>(mIndexedDrawElementCount);
910       break;
911     }
912     case Dali::Renderer::Property::DEPTH_WRITE_MODE:
913     {
914       value = mDepthWriteMode;
915       break;
916     }
917     case Dali::Renderer::Property::DEPTH_FUNCTION:
918     {
919       value = mDepthFunction;
920       break;
921     }
922     case Dali::Renderer::Property::DEPTH_TEST_MODE:
923     {
924       value = mDepthTestMode;
925       break;
926     }
927     case Dali::Renderer::Property::STENCIL_FUNCTION:
928     {
929       value = mStencilParameters.stencilFunction;
930       break;
931     }
932     case Dali::Renderer::Property::STENCIL_FUNCTION_MASK:
933     {
934       value = mStencilParameters.stencilFunctionMask;
935       break;
936     }
937     case Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE:
938     {
939       value = mStencilParameters.stencilFunctionReference;
940       break;
941     }
942     case Dali::Renderer::Property::STENCIL_MASK:
943     {
944       value = mStencilParameters.stencilMask;
945       break;
946     }
947     case Dali::Renderer::Property::RENDER_MODE:
948     {
949       value = mStencilParameters.renderMode;
950       break;
951     }
952     case Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL:
953     {
954       value = mStencilParameters.stencilOperationOnFail;
955       break;
956     }
957     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL:
958     {
959       value = mStencilParameters.stencilOperationOnZFail;
960       break;
961     }
962     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS:
963     {
964       value = mStencilParameters.stencilOperationOnZPass;
965       break;
966     }
967     case Dali::DevelRenderer::Property::OPACITY:
968     {
969       value = mOpacity;
970       break;
971     }
972     case Dali::DevelRenderer::Property::RENDERING_BEHAVIOR:
973     {
974       value = mRenderingBehavior;
975       break;
976     }
977     default:
978     {
979       // Must be a scene-graph only property
980       valueSet = false;
981       break;
982     }
983   }
984
985   return valueSet;
986 }
987
988 bool Renderer::GetCurrentPropertyValue(Property::Index index, Property::Value& value) const
989 {
990   bool                        valueSet    = true;
991   const SceneGraph::Renderer& sceneObject = GetRendererSceneObject();
992
993   switch(index)
994   {
995     case Dali::Renderer::Property::DEPTH_INDEX:
996     {
997       value = sceneObject.GetDepthIndex();
998       break;
999     }
1000     case Dali::Renderer::Property::FACE_CULLING_MODE:
1001     {
1002       value = sceneObject.GetFaceCullingMode();
1003       break;
1004     }
1005     case Dali::Renderer::Property::BLEND_MODE:
1006     {
1007       value = sceneObject.GetBlendMode();
1008       break;
1009     }
1010     case Dali::DevelRenderer::Property::BLEND_EQUATION:
1011     {
1012       uint32_t        bitMask = sceneObject.GetBlendingOptions();
1013       BlendingOptions blendingOptions;
1014       blendingOptions.SetBitmask(bitMask);
1015       value = static_cast<int32_t>(blendingOptions.GetBlendEquationRgb());
1016       break;
1017     }
1018     case Dali::Renderer::Property::BLEND_EQUATION_RGB:
1019     {
1020       uint32_t        bitMask = sceneObject.GetBlendingOptions();
1021       BlendingOptions blendingOptions;
1022       blendingOptions.SetBitmask(bitMask);
1023       value = static_cast<int32_t>(blendingOptions.GetBlendEquationRgb());
1024       break;
1025     }
1026     case Dali::Renderer::Property::BLEND_EQUATION_ALPHA:
1027     {
1028       uint32_t        bitMask = sceneObject.GetBlendingOptions();
1029       BlendingOptions blendingOptions;
1030       blendingOptions.SetBitmask(bitMask);
1031       value = static_cast<int32_t>(blendingOptions.GetBlendEquationAlpha());
1032       break;
1033     }
1034     case Dali::Renderer::Property::BLEND_FACTOR_SRC_RGB:
1035     {
1036       uint32_t        bitMask = sceneObject.GetBlendingOptions();
1037       BlendingOptions blendingOptions;
1038       blendingOptions.SetBitmask(bitMask);
1039       value = static_cast<int32_t>(blendingOptions.GetBlendSrcFactorRgb());
1040       break;
1041     }
1042     case Dali::Renderer::Property::BLEND_FACTOR_DEST_RGB:
1043     {
1044       uint32_t        bitMask = sceneObject.GetBlendingOptions();
1045       BlendingOptions blendingOptions;
1046       blendingOptions.SetBitmask(bitMask);
1047       value = static_cast<int32_t>(blendingOptions.GetBlendDestFactorRgb());
1048       break;
1049     }
1050     case Dali::Renderer::Property::BLEND_FACTOR_SRC_ALPHA:
1051     {
1052       uint32_t        bitMask = sceneObject.GetBlendingOptions();
1053       BlendingOptions blendingOptions;
1054       blendingOptions.SetBitmask(bitMask);
1055       value = static_cast<int32_t>(blendingOptions.GetBlendSrcFactorAlpha());
1056       break;
1057     }
1058     case Dali::Renderer::Property::BLEND_FACTOR_DEST_ALPHA:
1059     {
1060       uint32_t        bitMask = sceneObject.GetBlendingOptions();
1061       BlendingOptions blendingOptions;
1062       blendingOptions.SetBitmask(bitMask);
1063       value = static_cast<int32_t>(blendingOptions.GetBlendDestFactorAlpha());
1064       break;
1065     }
1066     case Dali::Renderer::Property::BLEND_COLOR:
1067     {
1068       value = sceneObject.GetBlendColor();
1069       break;
1070     }
1071     case Dali::Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA:
1072     {
1073       value = sceneObject.IsPreMultipliedAlphaEnabled();
1074       break;
1075     }
1076     case Dali::Renderer::Property::INDEX_RANGE_FIRST:
1077     {
1078       value = static_cast<int32_t>(sceneObject.GetIndexedDrawFirstElement());
1079       break;
1080     }
1081     case Dali::Renderer::Property::INDEX_RANGE_COUNT:
1082     {
1083       value = static_cast<int32_t>(sceneObject.GetIndexedDrawElementsCount());
1084       break;
1085     }
1086     case Dali::Renderer::Property::DEPTH_WRITE_MODE:
1087     {
1088       value = sceneObject.GetDepthWriteMode();
1089       break;
1090     }
1091     case Dali::Renderer::Property::DEPTH_FUNCTION:
1092     {
1093       value = sceneObject.GetDepthFunction();
1094       break;
1095     }
1096     case Dali::Renderer::Property::DEPTH_TEST_MODE:
1097     {
1098       value = sceneObject.GetDepthTestMode();
1099       break;
1100     }
1101     case Dali::Renderer::Property::STENCIL_FUNCTION:
1102     {
1103       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1104       value                                                 = stencilParameters.stencilFunction;
1105       break;
1106     }
1107     case Dali::Renderer::Property::STENCIL_FUNCTION_MASK:
1108     {
1109       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1110       value                                                 = stencilParameters.stencilFunctionMask;
1111       break;
1112     }
1113     case Dali::Renderer::Property::STENCIL_FUNCTION_REFERENCE:
1114     {
1115       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1116       value                                                 = stencilParameters.stencilFunctionReference;
1117       break;
1118     }
1119     case Dali::Renderer::Property::STENCIL_MASK:
1120     {
1121       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1122       value                                                 = stencilParameters.stencilMask;
1123       break;
1124     }
1125     case Dali::Renderer::Property::RENDER_MODE:
1126     {
1127       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1128       value                                                 = stencilParameters.renderMode;
1129       break;
1130     }
1131     case Dali::Renderer::Property::STENCIL_OPERATION_ON_FAIL:
1132     {
1133       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1134       value                                                 = stencilParameters.stencilOperationOnFail;
1135       break;
1136     }
1137     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_FAIL:
1138     {
1139       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1140       value                                                 = stencilParameters.stencilOperationOnZFail;
1141       break;
1142     }
1143     case Dali::Renderer::Property::STENCIL_OPERATION_ON_Z_PASS:
1144     {
1145       Render::Renderer::StencilParameters stencilParameters = sceneObject.GetStencilParameters();
1146       value                                                 = stencilParameters.stencilOperationOnZPass;
1147       break;
1148     }
1149     case Dali::DevelRenderer::Property::OPACITY:
1150     {
1151       value = sceneObject.GetOpacity(GetEventThreadServices().GetEventBufferIndex());
1152       break;
1153     }
1154     case Dali::DevelRenderer::Property::RENDERING_BEHAVIOR:
1155     {
1156       value = sceneObject.GetRenderingBehavior();
1157       break;
1158     }
1159     default:
1160     {
1161       // Must be an event-side only property
1162       valueSet = false;
1163       break;
1164     }
1165   }
1166
1167   return valueSet;
1168 }
1169
1170 void Renderer::SetBlendColor(const Vector4& blendColor)
1171 {
1172   mBlendingOptions.SetBlendColor(blendColor);
1173   SetBlendColorMessage(GetEventThreadServices(), GetRendererSceneObject(), GetBlendColor());
1174 }
1175
1176 const Vector4& Renderer::GetBlendColor() const
1177 {
1178   const Vector4* blendColor = mBlendingOptions.GetBlendColor();
1179   if(blendColor)
1180   {
1181     return *blendColor;
1182   }
1183   return Color::TRANSPARENT; // GL default
1184 }
1185
1186 void Renderer::SetRenderCallback(RenderCallback* callback)
1187 {
1188   Dali::Internal::SceneGraph::SetRenderCallbackMessage(GetEventThreadServices(),
1189                                                        GetRendererSceneObject(),
1190                                                        callback);
1191 }
1192
1193 } // namespace Internal
1194
1195 } // namespace Dali