7be96da2373761f4fe08c8027b58b8446a3cc7f8
[platform/core/uifw/dali-core.git] / dali / internal / update / rendering / scene-graph-renderer.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 // CLASS HEADER
18 #include "scene-graph-renderer.h"
19
20 // INTERNAL INCLUDES
21 #include <dali/internal/common/blending-options.h>
22 #include <dali/internal/common/internal-constants.h>
23 #include <dali/internal/common/memory-pool-object-allocator.h>
24 #include <dali/internal/render/data-providers/node-data-provider.h>
25 #include <dali/internal/render/data-providers/render-data-provider.h>
26 #include <dali/internal/render/queue/render-queue.h>
27 #include <dali/internal/render/renderers/render-geometry.h>
28 #include <dali/internal/render/shaders/program.h>
29 #include <dali/internal/render/shaders/render-shader.h>
30 #include <dali/internal/update/controllers/render-message-dispatcher.h>
31 #include <dali/internal/update/controllers/scene-controller.h>
32 #include <dali/internal/update/nodes/node.h>
33 #include <dali/internal/update/rendering/scene-graph-texture-set.h>
34
35 namespace Dali
36 {
37 namespace Internal
38 {
39 namespace SceneGraph
40 {
41 namespace // unnamed namespace
42 {
43 const uint32_t UNIFORM_MAP_READY      = 0;
44 const uint32_t COPY_UNIFORM_MAP       = 1;
45 const uint32_t REGENERATE_UNIFORM_MAP = 2;
46
47 //Memory pool used to allocate new renderers. Memory used by this pool will be released when shutting down DALi
48 MemoryPoolObjectAllocator<Renderer> gRendererMemoryPool;
49
50 void AddMappings(CollectedUniformMap& localMap, const UniformMap& uniformMap)
51 {
52   // Iterate thru uniformMap.
53   // Any maps that aren't in localMap should be added in a single step
54
55   // keep a static vector to avoid temporary heap allocation.
56   // As this function gets called only from update thread we don't have to
57   // make it thread safe (so no need to keep a thread_local variable).
58   static CollectedUniformMap newUniformMappings;
59
60   newUniformMappings.Clear();
61
62   for(UniformMap::SizeType i = 0, count = uniformMap.Count(); i < count; ++i)
63   {
64     bool found = false;
65
66     for(CollectedUniformMap::Iterator iter = localMap.Begin(); iter != localMap.End(); ++iter)
67     {
68       const UniformPropertyMapping& map = (*iter);
69       if(map.uniformName == uniformMap[i].uniformName)
70       {
71         found = true;
72         break;
73       }
74     }
75     if(!found)
76     {
77       newUniformMappings.PushBack(uniformMap[i]);
78     }
79   }
80
81   if(newUniformMappings.Count() > 0)
82   {
83     localMap.Reserve(localMap.Count() + newUniformMappings.Count());
84
85     for(CollectedUniformMap::Iterator iter = newUniformMappings.Begin(),
86                                       end  = newUniformMappings.End();
87         iter != end;
88         ++iter)
89     {
90       const UniformPropertyMapping& map = (*iter);
91       localMap.PushBack(map);
92     }
93   }
94 }
95
96 // Flags for re-sending data to renderer.
97 enum Flags
98 {
99   RESEND_GEOMETRY                    = 1 << 0,
100   RESEND_FACE_CULLING_MODE           = 1 << 1,
101   RESEND_BLEND_COLOR                 = 1 << 2,
102   RESEND_BLEND_BIT_MASK              = 1 << 3,
103   RESEND_PREMULTIPLIED_ALPHA         = 1 << 4,
104   RESEND_INDEXED_DRAW_FIRST_ELEMENT  = 1 << 5,
105   RESEND_INDEXED_DRAW_ELEMENTS_COUNT = 1 << 6,
106   RESEND_DEPTH_WRITE_MODE            = 1 << 7,
107   RESEND_DEPTH_TEST_MODE             = 1 << 8,
108   RESEND_DEPTH_FUNCTION              = 1 << 9,
109   RESEND_RENDER_MODE                 = 1 << 10,
110   RESEND_STENCIL_FUNCTION            = 1 << 11,
111   RESEND_STENCIL_FUNCTION_MASK       = 1 << 12,
112   RESEND_STENCIL_FUNCTION_REFERENCE  = 1 << 13,
113   RESEND_STENCIL_MASK                = 1 << 14,
114   RESEND_STENCIL_OPERATION_ON_FAIL   = 1 << 15,
115   RESEND_STENCIL_OPERATION_ON_Z_FAIL = 1 << 16,
116   RESEND_STENCIL_OPERATION_ON_Z_PASS = 1 << 17,
117   RESEND_WRITE_TO_COLOR_BUFFER       = 1 << 18,
118   RESEND_SHADER                      = 1 << 19,
119   RESEND_DRAW_COMMANDS               = 1 << 20
120 };
121
122 } // Anonymous namespace
123
124 Renderer* Renderer::New()
125 {
126   return new(gRendererMemoryPool.AllocateRawThreadSafe()) Renderer();
127 }
128
129 Renderer::Renderer()
130 : mSceneController(nullptr),
131   mRenderer(nullptr),
132   mTextureSet(nullptr),
133   mGeometry(nullptr),
134   mShader(nullptr),
135   mBlendColor(nullptr),
136   mStencilParameters(RenderMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP),
137   mIndexedDrawFirstElement(0u),
138   mIndexedDrawElementsCount(0u),
139   mBlendBitmask(0u),
140   mRegenerateUniformMap(0u),
141   mResendFlag(0u),
142   mDepthFunction(DepthFunction::LESS),
143   mFaceCullingMode(FaceCullingMode::NONE),
144   mBlendMode(BlendMode::AUTO),
145   mDepthWriteMode(DepthWriteMode::AUTO),
146   mDepthTestMode(DepthTestMode::AUTO),
147   mRenderingBehavior(DevelRenderer::Rendering::IF_REQUIRED),
148   mPremultipledAlphaEnabled(false),
149   mOpacity(1.0f),
150   mDepthIndex(0)
151 {
152   mUniformMapChanged[0] = false;
153   mUniformMapChanged[1] = false;
154
155   // Observe our own PropertyOwner's uniform map
156   AddUniformMapObserver(*this);
157 }
158
159 Renderer::~Renderer()
160 {
161   if(mTextureSet)
162   {
163     mTextureSet = nullptr;
164   }
165   if(mShader)
166   {
167     mShader->RemoveConnectionObserver(*this);
168     mShader = nullptr;
169   }
170 }
171
172 void Renderer::operator delete(void* ptr)
173 {
174   gRendererMemoryPool.FreeThreadSafe(static_cast<Renderer*>(ptr));
175 }
176
177 bool Renderer::PrepareRender(BufferIndex updateBufferIndex)
178 {
179   if(mRegenerateUniformMap == UNIFORM_MAP_READY)
180   {
181     mUniformMapChanged[updateBufferIndex] = false;
182   }
183   else
184   {
185     if(mRegenerateUniformMap == REGENERATE_UNIFORM_MAP)
186     {
187       CollectedUniformMap& localMap = mCollectedUniformMap[updateBufferIndex];
188       localMap.Clear();
189
190       const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap();
191
192       auto size = rendererUniformMap.Count();
193       if(mShader)
194       {
195         size += mShader->GetUniformMap().Count();
196       }
197
198       localMap.Reserve(size);
199
200       AddMappings(localMap, rendererUniformMap);
201
202       if(mShader)
203       {
204         AddMappings(localMap, mShader->GetUniformMap());
205       }
206     }
207     else if(mRegenerateUniformMap == COPY_UNIFORM_MAP)
208     {
209       // Copy old map into current map
210       CollectedUniformMap& localMap = mCollectedUniformMap[updateBufferIndex];
211       CollectedUniformMap& oldMap   = mCollectedUniformMap[1 - updateBufferIndex];
212
213       localMap.Resize(oldMap.Count());
214
215       uint32_t index = 0;
216       for(CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End(); iter != end; ++iter, ++index)
217       {
218         localMap[index] = *iter;
219       }
220     }
221
222     mUniformMapChanged[updateBufferIndex] = true;
223     mRegenerateUniformMap--;
224   }
225
226   bool rendererUpdated = mUniformMapChanged[updateBufferIndex] || mResendFlag || mRenderingBehavior == DevelRenderer::Rendering::CONTINUOUSLY;
227
228   if(mResendFlag != 0)
229   {
230     if(mResendFlag & RESEND_GEOMETRY)
231     {
232       typedef MessageValue1<Render::Renderer, Render::Geometry*> DerivedType;
233       uint32_t*                                                  slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
234       new(slot) DerivedType(mRenderer, &Render::Renderer::SetGeometry, mGeometry);
235     }
236
237     if(mResendFlag & RESEND_DRAW_COMMANDS)
238     {
239       using DerivedType = MessageValue2<Render::Renderer, Dali::DevelRenderer::DrawCommand*, uint32_t>;
240       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
241       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDrawCommands, mDrawCommands.data(), mDrawCommands.size());
242     }
243
244     if(mResendFlag & RESEND_FACE_CULLING_MODE)
245     {
246       using DerivedType = MessageValue1<Render::Renderer, FaceCullingMode::Type>;
247       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
248       new(slot) DerivedType(mRenderer, &Render::Renderer::SetFaceCullingMode, mFaceCullingMode);
249     }
250
251     if(mResendFlag & RESEND_BLEND_BIT_MASK)
252     {
253       using DerivedType = MessageValue1<Render::Renderer, uint32_t>;
254       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
255       new(slot) DerivedType(mRenderer, &Render::Renderer::SetBlendingBitMask, mBlendBitmask);
256     }
257
258     if(mResendFlag & RESEND_BLEND_COLOR)
259     {
260       using DerivedType = MessageValue1<Render::Renderer, Vector4>;
261       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
262       new(slot) DerivedType(mRenderer, &Render::Renderer::SetBlendColor, GetBlendColor());
263     }
264
265     if(mResendFlag & RESEND_PREMULTIPLIED_ALPHA)
266     {
267       using DerivedType = MessageValue1<Render::Renderer, bool>;
268       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
269       new(slot) DerivedType(mRenderer, &Render::Renderer::EnablePreMultipliedAlpha, mPremultipledAlphaEnabled);
270     }
271
272     if(mResendFlag & RESEND_INDEXED_DRAW_FIRST_ELEMENT)
273     {
274       using DerivedType = MessageValue1<Render::Renderer, uint32_t>;
275       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
276       new(slot) DerivedType(mRenderer, &Render::Renderer::SetIndexedDrawFirstElement, mIndexedDrawFirstElement);
277     }
278
279     if(mResendFlag & RESEND_INDEXED_DRAW_ELEMENTS_COUNT)
280     {
281       using DerivedType = MessageValue1<Render::Renderer, uint32_t>;
282       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
283       new(slot) DerivedType(mRenderer, &Render::Renderer::SetIndexedDrawElementsCount, mIndexedDrawElementsCount);
284     }
285
286     if(mResendFlag & RESEND_DEPTH_WRITE_MODE)
287     {
288       using DerivedType = MessageValue1<Render::Renderer, DepthWriteMode::Type>;
289       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
290       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthWriteMode, mDepthWriteMode);
291     }
292
293     if(mResendFlag & RESEND_DEPTH_TEST_MODE)
294     {
295       using DerivedType = MessageValue1<Render::Renderer, DepthTestMode::Type>;
296       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
297       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthTestMode, mDepthTestMode);
298     }
299
300     if(mResendFlag & RESEND_DEPTH_FUNCTION)
301     {
302       using DerivedType = MessageValue1<Render::Renderer, DepthFunction::Type>;
303       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
304       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthFunction, mDepthFunction);
305     }
306
307     if(mResendFlag & RESEND_RENDER_MODE)
308     {
309       using DerivedType = MessageValue1<Render::Renderer, RenderMode::Type>;
310       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
311       new(slot) DerivedType(mRenderer, &Render::Renderer::SetRenderMode, mStencilParameters.renderMode);
312     }
313
314     if(mResendFlag & RESEND_STENCIL_FUNCTION)
315     {
316       using DerivedType = MessageValue1<Render::Renderer, StencilFunction::Type>;
317       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
318       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilFunction, mStencilParameters.stencilFunction);
319     }
320
321     if(mResendFlag & RESEND_STENCIL_FUNCTION_MASK)
322     {
323       using DerivedType = MessageValue1<Render::Renderer, int>;
324       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
325       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilFunctionMask, mStencilParameters.stencilFunctionMask);
326     }
327
328     if(mResendFlag & RESEND_STENCIL_FUNCTION_REFERENCE)
329     {
330       using DerivedType = MessageValue1<Render::Renderer, int>;
331       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
332       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilFunctionReference, mStencilParameters.stencilFunctionReference);
333     }
334
335     if(mResendFlag & RESEND_STENCIL_MASK)
336     {
337       using DerivedType = MessageValue1<Render::Renderer, int>;
338       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
339       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilMask, mStencilParameters.stencilMask);
340     }
341
342     if(mResendFlag & RESEND_STENCIL_OPERATION_ON_FAIL)
343     {
344       using DerivedType = MessageValue1<Render::Renderer, StencilOperation::Type>;
345       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
346       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnFail, mStencilParameters.stencilOperationOnFail);
347     }
348
349     if(mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_FAIL)
350     {
351       using DerivedType = MessageValue1<Render::Renderer, StencilOperation::Type>;
352       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
353       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnZFail, mStencilParameters.stencilOperationOnZFail);
354     }
355
356     if(mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_PASS)
357     {
358       using DerivedType = MessageValue1<Render::Renderer, StencilOperation::Type>;
359       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
360       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnZPass, mStencilParameters.stencilOperationOnZPass);
361     }
362
363     if(mResendFlag & RESEND_SHADER)
364     {
365       using DerivedType = MessageValue1<Render::Renderer, bool>;
366       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
367       new(slot) DerivedType(mRenderer, &Render::Renderer::SetShaderChanged, true);
368     }
369
370     mResendFlag = 0;
371   }
372
373   return rendererUpdated;
374 }
375
376 void Renderer::SetTextures(TextureSet* textureSet)
377 {
378   DALI_ASSERT_DEBUG(textureSet != NULL && "Texture set pointer is NULL");
379
380   mTextureSet           = textureSet;
381   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
382 }
383
384 const Vector<Render::Texture*>* Renderer::GetTextures() const
385 {
386   return mTextureSet ? &(mTextureSet->GetTextures()) : nullptr;
387 }
388
389 const Vector<Render::Sampler*>* Renderer::GetSamplers() const
390 {
391   return mTextureSet ? &(mTextureSet->GetSamplers()) : nullptr;
392 }
393
394 void Renderer::SetShader(Shader* shader)
395 {
396   DALI_ASSERT_DEBUG(shader != NULL && "Shader pointer is NULL");
397
398   if(mShader)
399   {
400     mShader->RemoveConnectionObserver(*this);
401   }
402
403   mShader = shader;
404   mShader->AddConnectionObserver(*this);
405   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
406   mResendFlag |= RESEND_GEOMETRY | RESEND_SHADER;
407 }
408
409 void Renderer::SetGeometry(Render::Geometry* geometry)
410 {
411   DALI_ASSERT_DEBUG(geometry != NULL && "Geometry pointer is NULL");
412   mGeometry = geometry;
413
414   if(mRenderer)
415   {
416     mResendFlag |= RESEND_GEOMETRY;
417   }
418 }
419
420 void Renderer::SetDepthIndex(int depthIndex)
421 {
422   mDepthIndex = depthIndex;
423 }
424
425 void Renderer::SetFaceCullingMode(FaceCullingMode::Type faceCullingMode)
426 {
427   mFaceCullingMode = faceCullingMode;
428   mResendFlag |= RESEND_FACE_CULLING_MODE;
429 }
430
431 FaceCullingMode::Type Renderer::GetFaceCullingMode() const
432 {
433   return mFaceCullingMode;
434 }
435
436 void Renderer::SetBlendMode(BlendMode::Type blendingMode)
437 {
438   mBlendMode = blendingMode;
439 }
440
441 BlendMode::Type Renderer::GetBlendMode() const
442 {
443   return mBlendMode;
444 }
445
446 void Renderer::SetBlendingOptions(uint32_t options)
447 {
448   if(mBlendBitmask != options)
449   {
450     mBlendBitmask = options;
451     mResendFlag |= RESEND_BLEND_BIT_MASK;
452   }
453 }
454
455 uint32_t Renderer::GetBlendingOptions() const
456 {
457   return mBlendBitmask;
458 }
459
460 void Renderer::SetBlendColor(const Vector4& blendColor)
461 {
462   if(blendColor == Color::TRANSPARENT)
463   {
464     mBlendColor = nullptr;
465   }
466   else
467   {
468     if(!mBlendColor)
469     {
470       mBlendColor = new Vector4(blendColor);
471     }
472     else
473     {
474       *mBlendColor = blendColor;
475     }
476   }
477
478   mResendFlag |= RESEND_BLEND_COLOR;
479 }
480
481 Vector4 Renderer::GetBlendColor() const
482 {
483   if(mBlendColor)
484   {
485     return *mBlendColor;
486   }
487   return Color::TRANSPARENT;
488 }
489
490 void Renderer::SetIndexedDrawFirstElement(uint32_t firstElement)
491 {
492   mIndexedDrawFirstElement = firstElement;
493   mResendFlag |= RESEND_INDEXED_DRAW_FIRST_ELEMENT;
494 }
495
496 uint32_t Renderer::GetIndexedDrawFirstElement() const
497 {
498   return mIndexedDrawFirstElement;
499 }
500
501 void Renderer::SetIndexedDrawElementsCount(uint32_t elementsCount)
502 {
503   mIndexedDrawElementsCount = elementsCount;
504   mResendFlag |= RESEND_INDEXED_DRAW_ELEMENTS_COUNT;
505 }
506
507 uint32_t Renderer::GetIndexedDrawElementsCount() const
508 {
509   return mIndexedDrawElementsCount;
510 }
511
512 void Renderer::EnablePreMultipliedAlpha(bool preMultipled)
513 {
514   mPremultipledAlphaEnabled = preMultipled;
515   mResendFlag |= RESEND_PREMULTIPLIED_ALPHA;
516 }
517
518 bool Renderer::IsPreMultipliedAlphaEnabled() const
519 {
520   return mPremultipledAlphaEnabled;
521 }
522
523 void Renderer::SetDepthWriteMode(DepthWriteMode::Type depthWriteMode)
524 {
525   mDepthWriteMode = depthWriteMode;
526   mResendFlag |= RESEND_DEPTH_WRITE_MODE;
527 }
528
529 DepthWriteMode::Type Renderer::GetDepthWriteMode() const
530 {
531   return mDepthWriteMode;
532 }
533
534 void Renderer::SetDepthTestMode(DepthTestMode::Type depthTestMode)
535 {
536   mDepthTestMode = depthTestMode;
537   mResendFlag |= RESEND_DEPTH_TEST_MODE;
538 }
539
540 DepthTestMode::Type Renderer::GetDepthTestMode() const
541 {
542   return mDepthTestMode;
543 }
544
545 void Renderer::SetDepthFunction(DepthFunction::Type depthFunction)
546 {
547   mDepthFunction = depthFunction;
548   mResendFlag |= RESEND_DEPTH_FUNCTION;
549 }
550
551 DepthFunction::Type Renderer::GetDepthFunction() const
552 {
553   return mDepthFunction;
554 }
555
556 void Renderer::SetRenderMode(RenderMode::Type mode)
557 {
558   mStencilParameters.renderMode = mode;
559   mResendFlag |= RESEND_RENDER_MODE;
560 }
561
562 void Renderer::SetStencilFunction(StencilFunction::Type stencilFunction)
563 {
564   mStencilParameters.stencilFunction = stencilFunction;
565   mResendFlag |= RESEND_STENCIL_FUNCTION;
566 }
567
568 void Renderer::SetStencilFunctionMask(int stencilFunctionMask)
569 {
570   mStencilParameters.stencilFunctionMask = stencilFunctionMask;
571   mResendFlag |= RESEND_STENCIL_FUNCTION_MASK;
572 }
573
574 void Renderer::SetStencilFunctionReference(int stencilFunctionReference)
575 {
576   mStencilParameters.stencilFunctionReference = stencilFunctionReference;
577   mResendFlag |= RESEND_STENCIL_FUNCTION_REFERENCE;
578 }
579
580 void Renderer::SetStencilMask(int stencilMask)
581 {
582   mStencilParameters.stencilMask = stencilMask;
583   mResendFlag |= RESEND_STENCIL_MASK;
584 }
585
586 void Renderer::SetStencilOperationOnFail(StencilOperation::Type stencilOperationOnFail)
587 {
588   mStencilParameters.stencilOperationOnFail = stencilOperationOnFail;
589   mResendFlag |= RESEND_STENCIL_OPERATION_ON_FAIL;
590 }
591
592 void Renderer::SetStencilOperationOnZFail(StencilOperation::Type stencilOperationOnZFail)
593 {
594   mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail;
595   mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_FAIL;
596 }
597
598 void Renderer::SetStencilOperationOnZPass(StencilOperation::Type stencilOperationOnZPass)
599 {
600   mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass;
601   mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_PASS;
602 }
603
604 const Render::Renderer::StencilParameters& Renderer::GetStencilParameters() const
605 {
606   return mStencilParameters;
607 }
608
609 void Renderer::BakeOpacity(BufferIndex updateBufferIndex, float opacity)
610 {
611   mOpacity.Bake(updateBufferIndex, opacity);
612 }
613
614 float Renderer::GetOpacity(BufferIndex updateBufferIndex) const
615 {
616   return mOpacity[updateBufferIndex];
617 }
618
619 void Renderer::SetRenderingBehavior(DevelRenderer::Rendering::Type renderingBehavior)
620 {
621   mRenderingBehavior = renderingBehavior;
622 }
623
624 DevelRenderer::Rendering::Type Renderer::GetRenderingBehavior() const
625 {
626   return mRenderingBehavior;
627 }
628
629 //Called when SceneGraph::Renderer is added to update manager ( that happens when an "event-thread renderer" is created )
630 void Renderer::ConnectToSceneGraph(SceneController& sceneController, BufferIndex bufferIndex)
631 {
632   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
633   mSceneController      = &sceneController;
634
635   mRenderer = Render::Renderer::New(this, mGeometry, mBlendBitmask, GetBlendColor(), static_cast<FaceCullingMode::Type>(mFaceCullingMode), mPremultipledAlphaEnabled, mDepthWriteMode, mDepthTestMode, mDepthFunction, mStencilParameters);
636
637   OwnerPointer<Render::Renderer> transferOwnership(mRenderer);
638   mSceneController->GetRenderMessageDispatcher().AddRenderer(transferOwnership);
639 }
640
641 //Called just before destroying the scene-graph renderer ( when the "event-thread renderer" is no longer referenced )
642 void Renderer::DisconnectFromSceneGraph(SceneController& sceneController, BufferIndex bufferIndex)
643 {
644   //Remove renderer from RenderManager
645   if(mRenderer)
646   {
647     mSceneController->GetRenderMessageDispatcher().RemoveRenderer(*mRenderer);
648     mRenderer = nullptr;
649   }
650   mSceneController = nullptr;
651 }
652
653 Render::Renderer& Renderer::GetRenderer()
654 {
655   return *mRenderer;
656 }
657
658 const CollectedUniformMap& Renderer::GetUniformMap(BufferIndex bufferIndex) const
659 {
660   return mCollectedUniformMap[bufferIndex];
661 }
662
663 Renderer::OpacityType Renderer::GetOpacityType(BufferIndex updateBufferIndex, const Node& node) const
664 {
665   Renderer::OpacityType opacityType = Renderer::OPAQUE;
666
667   if(node.IsTransparent())
668   {
669     return Renderer::TRANSPARENT;
670   }
671
672   switch(mBlendMode)
673   {
674     case BlendMode::ON_WITHOUT_CULL: // If the renderer should always be use blending and never want to be transparent by alpha.
675     {
676       opacityType = Renderer::TRANSLUCENT;
677       break;
678     }
679     case BlendMode::ON: // If the renderer should always be use blending
680     {
681       float alpha = node.GetWorldColor(updateBufferIndex).a * mOpacity[updateBufferIndex];
682       if(alpha <= FULLY_TRANSPARENT)
683       {
684         opacityType = Renderer::TRANSPARENT;
685       }
686       else
687       {
688         opacityType = Renderer::TRANSLUCENT;
689       }
690       break;
691     }
692     case BlendMode::AUTO:
693     {
694       if(BlendingOptions::IsAdvancedBlendEquationIncluded(mBlendBitmask))
695       {
696         opacityType = Renderer::TRANSLUCENT;
697         break;
698       }
699
700       bool shaderRequiresBlending(mShader->HintEnabled(Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT));
701       if(shaderRequiresBlending || (mTextureSet && mTextureSet->HasAlpha()))
702       {
703         opacityType = Renderer::TRANSLUCENT;
704       }
705
706       // renderer should determine opacity using the actor color
707       float alpha = node.GetWorldColor(updateBufferIndex).a * mOpacity[updateBufferIndex];
708       if(alpha <= FULLY_TRANSPARENT)
709       {
710         opacityType = Renderer::TRANSPARENT;
711       }
712       else if(alpha <= FULLY_OPAQUE)
713       {
714         opacityType = Renderer::TRANSLUCENT;
715       }
716
717       break;
718     }
719     case BlendMode::OFF: // the renderer should never use blending
720     default:
721     {
722       opacityType = Renderer::OPAQUE;
723       break;
724     }
725   }
726
727   return opacityType;
728 }
729
730 void Renderer::ConnectionsChanged(PropertyOwner& object)
731 {
732   // One of our child objects has changed it's connections. Ensure the uniform
733   // map gets regenerated during PrepareRender
734   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
735 }
736
737 void Renderer::ConnectedUniformMapChanged()
738 {
739   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
740 }
741
742 void Renderer::UniformMappingsChanged(const UniformMap& mappings)
743 {
744   // The mappings are either from PropertyOwner base class, or the Actor
745   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
746 }
747
748 void Renderer::ObservedObjectDestroyed(PropertyOwner& owner)
749 {
750   if(reinterpret_cast<PropertyOwner*>(mShader) == &owner)
751   {
752     mShader = nullptr;
753   }
754 }
755
756 void Renderer::SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size)
757 {
758   mDrawCommands.clear();
759   mDrawCommands.insert(mDrawCommands.end(), pDrawCommands, pDrawCommands + size);
760   mResendFlag |= RESEND_DRAW_COMMANDS;
761 }
762
763 } // namespace SceneGraph
764 } // namespace Internal
765 } // namespace Dali