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