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