DirectRendering:
[platform/core/uifw/dali-core.git] / dali / internal / update / rendering / scene-graph-renderer.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 // 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   RESEND_SET_RENDER_CALLBACK         = 1 << 21
121 };
122
123 } // Anonymous namespace
124
125 Renderer* Renderer::New()
126 {
127   return new(gRendererMemoryPool.AllocateRawThreadSafe()) Renderer();
128 }
129
130 Renderer::Renderer()
131 : mSceneController(nullptr),
132   mRenderer(nullptr),
133   mTextureSet(nullptr),
134   mGeometry(nullptr),
135   mShader(nullptr),
136   mBlendColor(nullptr),
137   mStencilParameters(RenderMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP),
138   mIndexedDrawFirstElement(0u),
139   mIndexedDrawElementsCount(0u),
140   mBlendBitmask(0u),
141   mRegenerateUniformMap(0u),
142   mResendFlag(0u),
143   mDepthFunction(DepthFunction::LESS),
144   mFaceCullingMode(FaceCullingMode::NONE),
145   mBlendMode(BlendMode::AUTO),
146   mDepthWriteMode(DepthWriteMode::AUTO),
147   mDepthTestMode(DepthTestMode::AUTO),
148   mRenderingBehavior(DevelRenderer::Rendering::IF_REQUIRED),
149   mPremultipledAlphaEnabled(false),
150   mOpacity(1.0f),
151   mDepthIndex(0)
152 {
153   mUniformMapChanged[0] = false;
154   mUniformMapChanged[1] = false;
155
156   // Observe our own PropertyOwner's uniform map
157   AddUniformMapObserver(*this);
158 }
159
160 Renderer::~Renderer()
161 {
162   if(mTextureSet)
163   {
164     mTextureSet = nullptr;
165   }
166   if(mShader)
167   {
168     mShader->RemoveConnectionObserver(*this);
169     mShader = nullptr;
170   }
171 }
172
173 void Renderer::operator delete(void* ptr)
174 {
175   gRendererMemoryPool.FreeThreadSafe(static_cast<Renderer*>(ptr));
176 }
177
178 bool Renderer::PrepareRender(BufferIndex updateBufferIndex)
179 {
180   if(mRegenerateUniformMap == UNIFORM_MAP_READY)
181   {
182     mUniformMapChanged[updateBufferIndex] = false;
183   }
184   else
185   {
186     if(mRegenerateUniformMap == REGENERATE_UNIFORM_MAP)
187     {
188       CollectedUniformMap& localMap = mCollectedUniformMap[updateBufferIndex];
189       localMap.Clear();
190
191       const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap();
192
193       auto size = rendererUniformMap.Count();
194       if(mShader)
195       {
196         size += mShader->GetUniformMap().Count();
197       }
198
199       localMap.Reserve(size);
200
201       AddMappings(localMap, rendererUniformMap);
202
203       if(mShader)
204       {
205         AddMappings(localMap, mShader->GetUniformMap());
206       }
207     }
208     else if(mRegenerateUniformMap == COPY_UNIFORM_MAP)
209     {
210       // Copy old map into current map
211       CollectedUniformMap& localMap = mCollectedUniformMap[updateBufferIndex];
212       CollectedUniformMap& oldMap   = mCollectedUniformMap[1 - updateBufferIndex];
213
214       localMap.Resize(oldMap.Count());
215
216       uint32_t index = 0;
217       for(CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End(); iter != end; ++iter, ++index)
218       {
219         localMap[index] = *iter;
220       }
221     }
222
223     mUniformMapChanged[updateBufferIndex] = true;
224     mRegenerateUniformMap--;
225   }
226
227   bool rendererUpdated = mUniformMapChanged[updateBufferIndex] || mResendFlag || mRenderingBehavior == DevelRenderer::Rendering::CONTINUOUSLY;
228
229   if(mResendFlag != 0)
230   {
231     if(mResendFlag & RESEND_GEOMETRY)
232     {
233       typedef MessageValue1<Render::Renderer, Render::Geometry*> DerivedType;
234       uint32_t*                                                  slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
235       new(slot) DerivedType(mRenderer, &Render::Renderer::SetGeometry, mGeometry);
236     }
237
238     if(mResendFlag & RESEND_DRAW_COMMANDS)
239     {
240       using DerivedType = MessageValue2<Render::Renderer, Dali::DevelRenderer::DrawCommand*, uint32_t>;
241       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
242       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDrawCommands, mDrawCommands.data(), mDrawCommands.size());
243     }
244
245     if(mResendFlag & RESEND_FACE_CULLING_MODE)
246     {
247       using DerivedType = MessageValue1<Render::Renderer, FaceCullingMode::Type>;
248       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
249       new(slot) DerivedType(mRenderer, &Render::Renderer::SetFaceCullingMode, mFaceCullingMode);
250     }
251
252     if(mResendFlag & RESEND_BLEND_BIT_MASK)
253     {
254       using DerivedType = MessageValue1<Render::Renderer, uint32_t>;
255       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
256       new(slot) DerivedType(mRenderer, &Render::Renderer::SetBlendingBitMask, mBlendBitmask);
257     }
258
259     if(mResendFlag & RESEND_BLEND_COLOR)
260     {
261       using DerivedType = MessageValue1<Render::Renderer, Vector4>;
262       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
263       new(slot) DerivedType(mRenderer, &Render::Renderer::SetBlendColor, GetBlendColor());
264     }
265
266     if(mResendFlag & RESEND_PREMULTIPLIED_ALPHA)
267     {
268       using DerivedType = MessageValue1<Render::Renderer, bool>;
269       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
270       new(slot) DerivedType(mRenderer, &Render::Renderer::EnablePreMultipliedAlpha, mPremultipledAlphaEnabled);
271     }
272
273     if(mResendFlag & RESEND_INDEXED_DRAW_FIRST_ELEMENT)
274     {
275       using DerivedType = MessageValue1<Render::Renderer, uint32_t>;
276       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
277       new(slot) DerivedType(mRenderer, &Render::Renderer::SetIndexedDrawFirstElement, mIndexedDrawFirstElement);
278     }
279
280     if(mResendFlag & RESEND_INDEXED_DRAW_ELEMENTS_COUNT)
281     {
282       using DerivedType = MessageValue1<Render::Renderer, uint32_t>;
283       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
284       new(slot) DerivedType(mRenderer, &Render::Renderer::SetIndexedDrawElementsCount, mIndexedDrawElementsCount);
285     }
286
287     if(mResendFlag & RESEND_DEPTH_WRITE_MODE)
288     {
289       using DerivedType = MessageValue1<Render::Renderer, DepthWriteMode::Type>;
290       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
291       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthWriteMode, mDepthWriteMode);
292     }
293
294     if(mResendFlag & RESEND_DEPTH_TEST_MODE)
295     {
296       using DerivedType = MessageValue1<Render::Renderer, DepthTestMode::Type>;
297       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
298       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthTestMode, mDepthTestMode);
299     }
300
301     if(mResendFlag & RESEND_DEPTH_FUNCTION)
302     {
303       using DerivedType = MessageValue1<Render::Renderer, DepthFunction::Type>;
304       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
305       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthFunction, mDepthFunction);
306     }
307
308     if(mResendFlag & RESEND_RENDER_MODE)
309     {
310       using DerivedType = MessageValue1<Render::Renderer, RenderMode::Type>;
311       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
312       new(slot) DerivedType(mRenderer, &Render::Renderer::SetRenderMode, mStencilParameters.renderMode);
313     }
314
315     if(mResendFlag & RESEND_STENCIL_FUNCTION)
316     {
317       using DerivedType = MessageValue1<Render::Renderer, StencilFunction::Type>;
318       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
319       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilFunction, mStencilParameters.stencilFunction);
320     }
321
322     if(mResendFlag & RESEND_STENCIL_FUNCTION_MASK)
323     {
324       using DerivedType = MessageValue1<Render::Renderer, int>;
325       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
326       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilFunctionMask, mStencilParameters.stencilFunctionMask);
327     }
328
329     if(mResendFlag & RESEND_STENCIL_FUNCTION_REFERENCE)
330     {
331       using DerivedType = MessageValue1<Render::Renderer, int>;
332       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
333       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilFunctionReference, mStencilParameters.stencilFunctionReference);
334     }
335
336     if(mResendFlag & RESEND_STENCIL_MASK)
337     {
338       using DerivedType = MessageValue1<Render::Renderer, int>;
339       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
340       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilMask, mStencilParameters.stencilMask);
341     }
342
343     if(mResendFlag & RESEND_STENCIL_OPERATION_ON_FAIL)
344     {
345       using DerivedType = MessageValue1<Render::Renderer, StencilOperation::Type>;
346       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
347       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnFail, mStencilParameters.stencilOperationOnFail);
348     }
349
350     if(mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_FAIL)
351     {
352       using DerivedType = MessageValue1<Render::Renderer, StencilOperation::Type>;
353       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
354       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnZFail, mStencilParameters.stencilOperationOnZFail);
355     }
356
357     if(mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_PASS)
358     {
359       using DerivedType = MessageValue1<Render::Renderer, StencilOperation::Type>;
360       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
361       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnZPass, mStencilParameters.stencilOperationOnZPass);
362     }
363
364     if(mResendFlag & RESEND_SHADER)
365     {
366       using DerivedType = MessageValue1<Render::Renderer, bool>;
367       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
368       new(slot) DerivedType(mRenderer, &Render::Renderer::SetShaderChanged, true);
369     }
370
371     if(mResendFlag & RESEND_SET_RENDER_CALLBACK)
372     {
373       using DerivedType = MessageValue1<Render::Renderer, Dali::RenderCallback*>;
374       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
375       new(slot) DerivedType(mRenderer, &Render::Renderer::SetRenderCallback, mRenderCallback);
376     }
377
378     mResendFlag = 0;
379   }
380
381   return rendererUpdated;
382 }
383
384 void Renderer::SetTextures(TextureSet* textureSet)
385 {
386   DALI_ASSERT_DEBUG(textureSet != NULL && "Texture set pointer is NULL");
387
388   mTextureSet           = textureSet;
389   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
390 }
391
392 const Vector<Render::Texture*>* Renderer::GetTextures() const
393 {
394   return mTextureSet ? &(mTextureSet->GetTextures()) : nullptr;
395 }
396
397 const Vector<Render::Sampler*>* Renderer::GetSamplers() const
398 {
399   return mTextureSet ? &(mTextureSet->GetSamplers()) : nullptr;
400 }
401
402 void Renderer::SetShader(Shader* shader)
403 {
404   DALI_ASSERT_DEBUG(shader != NULL && "Shader pointer is NULL");
405
406   if(mShader)
407   {
408     mShader->RemoveConnectionObserver(*this);
409   }
410
411   mShader = shader;
412   mShader->AddConnectionObserver(*this);
413   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
414   mResendFlag |= RESEND_GEOMETRY | RESEND_SHADER;
415 }
416
417 void Renderer::SetGeometry(Render::Geometry* geometry)
418 {
419   DALI_ASSERT_DEBUG(geometry != NULL && "Geometry pointer is NULL");
420   mGeometry = geometry;
421
422   if(mRenderer)
423   {
424     mResendFlag |= RESEND_GEOMETRY;
425   }
426 }
427
428 void Renderer::SetDepthIndex(int depthIndex)
429 {
430   mDepthIndex = depthIndex;
431 }
432
433 void Renderer::SetFaceCullingMode(FaceCullingMode::Type faceCullingMode)
434 {
435   mFaceCullingMode = faceCullingMode;
436   mResendFlag |= RESEND_FACE_CULLING_MODE;
437 }
438
439 FaceCullingMode::Type Renderer::GetFaceCullingMode() const
440 {
441   return mFaceCullingMode;
442 }
443
444 void Renderer::SetBlendMode(BlendMode::Type blendingMode)
445 {
446   mBlendMode = blendingMode;
447 }
448
449 BlendMode::Type Renderer::GetBlendMode() const
450 {
451   return mBlendMode;
452 }
453
454 void Renderer::SetBlendingOptions(uint32_t options)
455 {
456   if(mBlendBitmask != options)
457   {
458     mBlendBitmask = options;
459     mResendFlag |= RESEND_BLEND_BIT_MASK;
460   }
461 }
462
463 uint32_t Renderer::GetBlendingOptions() const
464 {
465   return mBlendBitmask;
466 }
467
468 void Renderer::SetBlendColor(const Vector4& blendColor)
469 {
470   if(blendColor == Color::TRANSPARENT)
471   {
472     mBlendColor = nullptr;
473   }
474   else
475   {
476     if(!mBlendColor)
477     {
478       mBlendColor = new Vector4(blendColor);
479     }
480     else
481     {
482       *mBlendColor = blendColor;
483     }
484   }
485
486   mResendFlag |= RESEND_BLEND_COLOR;
487 }
488
489 Vector4 Renderer::GetBlendColor() const
490 {
491   if(mBlendColor)
492   {
493     return *mBlendColor;
494   }
495   return Color::TRANSPARENT;
496 }
497
498 void Renderer::SetIndexedDrawFirstElement(uint32_t firstElement)
499 {
500   mIndexedDrawFirstElement = firstElement;
501   mResendFlag |= RESEND_INDEXED_DRAW_FIRST_ELEMENT;
502 }
503
504 uint32_t Renderer::GetIndexedDrawFirstElement() const
505 {
506   return mIndexedDrawFirstElement;
507 }
508
509 void Renderer::SetIndexedDrawElementsCount(uint32_t elementsCount)
510 {
511   mIndexedDrawElementsCount = elementsCount;
512   mResendFlag |= RESEND_INDEXED_DRAW_ELEMENTS_COUNT;
513 }
514
515 uint32_t Renderer::GetIndexedDrawElementsCount() const
516 {
517   return mIndexedDrawElementsCount;
518 }
519
520 void Renderer::EnablePreMultipliedAlpha(bool preMultipled)
521 {
522   mPremultipledAlphaEnabled = preMultipled;
523   mResendFlag |= RESEND_PREMULTIPLIED_ALPHA;
524 }
525
526 bool Renderer::IsPreMultipliedAlphaEnabled() const
527 {
528   return mPremultipledAlphaEnabled;
529 }
530
531 void Renderer::SetDepthWriteMode(DepthWriteMode::Type depthWriteMode)
532 {
533   mDepthWriteMode = depthWriteMode;
534   mResendFlag |= RESEND_DEPTH_WRITE_MODE;
535 }
536
537 DepthWriteMode::Type Renderer::GetDepthWriteMode() const
538 {
539   return mDepthWriteMode;
540 }
541
542 void Renderer::SetDepthTestMode(DepthTestMode::Type depthTestMode)
543 {
544   mDepthTestMode = depthTestMode;
545   mResendFlag |= RESEND_DEPTH_TEST_MODE;
546 }
547
548 DepthTestMode::Type Renderer::GetDepthTestMode() const
549 {
550   return mDepthTestMode;
551 }
552
553 void Renderer::SetDepthFunction(DepthFunction::Type depthFunction)
554 {
555   mDepthFunction = depthFunction;
556   mResendFlag |= RESEND_DEPTH_FUNCTION;
557 }
558
559 DepthFunction::Type Renderer::GetDepthFunction() const
560 {
561   return mDepthFunction;
562 }
563
564 void Renderer::SetRenderMode(RenderMode::Type mode)
565 {
566   mStencilParameters.renderMode = mode;
567   mResendFlag |= RESEND_RENDER_MODE;
568 }
569
570 void Renderer::SetStencilFunction(StencilFunction::Type stencilFunction)
571 {
572   mStencilParameters.stencilFunction = stencilFunction;
573   mResendFlag |= RESEND_STENCIL_FUNCTION;
574 }
575
576 void Renderer::SetStencilFunctionMask(int stencilFunctionMask)
577 {
578   mStencilParameters.stencilFunctionMask = stencilFunctionMask;
579   mResendFlag |= RESEND_STENCIL_FUNCTION_MASK;
580 }
581
582 void Renderer::SetStencilFunctionReference(int stencilFunctionReference)
583 {
584   mStencilParameters.stencilFunctionReference = stencilFunctionReference;
585   mResendFlag |= RESEND_STENCIL_FUNCTION_REFERENCE;
586 }
587
588 void Renderer::SetStencilMask(int stencilMask)
589 {
590   mStencilParameters.stencilMask = stencilMask;
591   mResendFlag |= RESEND_STENCIL_MASK;
592 }
593
594 void Renderer::SetStencilOperationOnFail(StencilOperation::Type stencilOperationOnFail)
595 {
596   mStencilParameters.stencilOperationOnFail = stencilOperationOnFail;
597   mResendFlag |= RESEND_STENCIL_OPERATION_ON_FAIL;
598 }
599
600 void Renderer::SetStencilOperationOnZFail(StencilOperation::Type stencilOperationOnZFail)
601 {
602   mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail;
603   mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_FAIL;
604 }
605
606 void Renderer::SetStencilOperationOnZPass(StencilOperation::Type stencilOperationOnZPass)
607 {
608   mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass;
609   mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_PASS;
610 }
611
612 void Renderer::SetRenderCallback(RenderCallback* callback)
613 {
614   mRenderCallback = callback;
615   mResendFlag |= RESEND_SET_RENDER_CALLBACK;
616 }
617
618 const Render::Renderer::StencilParameters& Renderer::GetStencilParameters() const
619 {
620   return mStencilParameters;
621 }
622
623 void Renderer::BakeOpacity(BufferIndex updateBufferIndex, float opacity)
624 {
625   mOpacity.Bake(updateBufferIndex, opacity);
626 }
627
628 float Renderer::GetOpacity(BufferIndex updateBufferIndex) const
629 {
630   return mOpacity[updateBufferIndex];
631 }
632
633 void Renderer::SetRenderingBehavior(DevelRenderer::Rendering::Type renderingBehavior)
634 {
635   mRenderingBehavior = renderingBehavior;
636 }
637
638 DevelRenderer::Rendering::Type Renderer::GetRenderingBehavior() const
639 {
640   return mRenderingBehavior;
641 }
642
643 //Called when SceneGraph::Renderer is added to update manager ( that happens when an "event-thread renderer" is created )
644 void Renderer::ConnectToSceneGraph(SceneController& sceneController, BufferIndex bufferIndex)
645 {
646   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
647   mSceneController      = &sceneController;
648
649   mRenderer = Render::Renderer::New(this, mGeometry, mBlendBitmask, GetBlendColor(), static_cast<FaceCullingMode::Type>(mFaceCullingMode), mPremultipledAlphaEnabled, mDepthWriteMode, mDepthTestMode, mDepthFunction, mStencilParameters);
650
651   OwnerPointer<Render::Renderer> transferOwnership(mRenderer);
652   mSceneController->GetRenderMessageDispatcher().AddRenderer(transferOwnership);
653 }
654
655 //Called just before destroying the scene-graph renderer ( when the "event-thread renderer" is no longer referenced )
656 void Renderer::DisconnectFromSceneGraph(SceneController& sceneController, BufferIndex bufferIndex)
657 {
658   //Remove renderer from RenderManager
659   if(mRenderer)
660   {
661     mSceneController->GetRenderMessageDispatcher().RemoveRenderer(*mRenderer);
662     mRenderer = nullptr;
663   }
664   mSceneController = nullptr;
665 }
666
667 Render::Renderer& Renderer::GetRenderer()
668 {
669   return *mRenderer;
670 }
671
672 const CollectedUniformMap& Renderer::GetUniformMap(BufferIndex bufferIndex) const
673 {
674   return mCollectedUniformMap[bufferIndex];
675 }
676
677 Renderer::OpacityType Renderer::GetOpacityType(BufferIndex updateBufferIndex, const Node& node) const
678 {
679   Renderer::OpacityType opacityType = Renderer::OPAQUE;
680
681   if(node.IsTransparent())
682   {
683     return Renderer::TRANSPARENT;
684   }
685
686   switch(mBlendMode)
687   {
688     case BlendMode::ON_WITHOUT_CULL: // If the renderer should always be use blending and never want to be transparent by alpha.
689     {
690       opacityType = Renderer::TRANSLUCENT;
691       break;
692     }
693     case BlendMode::ON: // If the renderer should always be use blending
694     {
695       float alpha = node.GetWorldColor(updateBufferIndex).a * mOpacity[updateBufferIndex];
696       if(alpha <= FULLY_TRANSPARENT)
697       {
698         opacityType = Renderer::TRANSPARENT;
699       }
700       else
701       {
702         opacityType = Renderer::TRANSLUCENT;
703       }
704       break;
705     }
706     case BlendMode::AUTO:
707     {
708       if(BlendingOptions::IsAdvancedBlendEquationIncluded(mBlendBitmask))
709       {
710         opacityType = Renderer::TRANSLUCENT;
711         break;
712       }
713
714       bool shaderRequiresBlending(mShader->HintEnabled(Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT));
715       if(shaderRequiresBlending || (mTextureSet && mTextureSet->HasAlpha()))
716       {
717         opacityType = Renderer::TRANSLUCENT;
718       }
719
720       // renderer should determine opacity using the actor color
721       float alpha = node.GetWorldColor(updateBufferIndex).a * mOpacity[updateBufferIndex];
722       if(alpha <= FULLY_TRANSPARENT)
723       {
724         opacityType = Renderer::TRANSPARENT;
725       }
726       else if(alpha <= FULLY_OPAQUE)
727       {
728         opacityType = Renderer::TRANSLUCENT;
729       }
730
731       break;
732     }
733     case BlendMode::OFF: // the renderer should never use blending
734     default:
735     {
736       opacityType = Renderer::OPAQUE;
737       break;
738     }
739   }
740
741   return opacityType;
742 }
743
744 void Renderer::ConnectionsChanged(PropertyOwner& object)
745 {
746   // One of our child objects has changed it's connections. Ensure the uniform
747   // map gets regenerated during PrepareRender
748   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
749 }
750
751 void Renderer::ConnectedUniformMapChanged()
752 {
753   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
754 }
755
756 void Renderer::UniformMappingsChanged(const UniformMap& mappings)
757 {
758   // The mappings are either from PropertyOwner base class, or the Actor
759   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
760 }
761
762 void Renderer::ObservedObjectDestroyed(PropertyOwner& owner)
763 {
764   if(reinterpret_cast<PropertyOwner*>(mShader) == &owner)
765   {
766     mShader = nullptr;
767   }
768 }
769
770 void Renderer::SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size)
771 {
772   mDrawCommands.clear();
773   mDrawCommands.insert(mDrawCommands.end(), pDrawCommands, pDrawCommands + size);
774   mResendFlag |= RESEND_DRAW_COMMANDS;
775 }
776
777 } // namespace SceneGraph
778 } // namespace Internal
779 } // namespace Dali