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