Merge "DALi Version 2.1.20" into devel/master
[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 //Memory pool used to allocate new renderers. Memory used by this pool will be released when shutting down DALi
44 MemoryPoolObjectAllocator<Renderer> gRendererMemoryPool;
45
46 // Flags for re-sending data to renderer.
47 enum Flags
48 {
49   RESEND_GEOMETRY                    = 1 << 0,
50   RESEND_FACE_CULLING_MODE           = 1 << 1,
51   RESEND_BLEND_COLOR                 = 1 << 2,
52   RESEND_BLEND_BIT_MASK              = 1 << 3,
53   RESEND_PREMULTIPLIED_ALPHA         = 1 << 4,
54   RESEND_INDEXED_DRAW_FIRST_ELEMENT  = 1 << 5,
55   RESEND_INDEXED_DRAW_ELEMENTS_COUNT = 1 << 6,
56   RESEND_DEPTH_WRITE_MODE            = 1 << 7,
57   RESEND_DEPTH_TEST_MODE             = 1 << 8,
58   RESEND_DEPTH_FUNCTION              = 1 << 9,
59   RESEND_RENDER_MODE                 = 1 << 10,
60   RESEND_STENCIL_FUNCTION            = 1 << 11,
61   RESEND_STENCIL_FUNCTION_MASK       = 1 << 12,
62   RESEND_STENCIL_FUNCTION_REFERENCE  = 1 << 13,
63   RESEND_STENCIL_MASK                = 1 << 14,
64   RESEND_STENCIL_OPERATION_ON_FAIL   = 1 << 15,
65   RESEND_STENCIL_OPERATION_ON_Z_FAIL = 1 << 16,
66   RESEND_STENCIL_OPERATION_ON_Z_PASS = 1 << 17,
67   RESEND_WRITE_TO_COLOR_BUFFER       = 1 << 18,
68   RESEND_SHADER                      = 1 << 19,
69   RESEND_DRAW_COMMANDS               = 1 << 20,
70   RESEND_SET_RENDER_CALLBACK         = 1 << 21
71 };
72
73 } // Anonymous namespace
74
75 Renderer* Renderer::New()
76 {
77   return new(gRendererMemoryPool.AllocateRawThreadSafe()) Renderer();
78 }
79
80 Renderer::Renderer()
81 : mSceneController(nullptr),
82   mRenderer(nullptr),
83   mTextureSet(nullptr),
84   mGeometry(nullptr),
85   mShader(nullptr),
86   mBlendColor(nullptr),
87   mStencilParameters(RenderMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP),
88   mIndexedDrawFirstElement(0u),
89   mIndexedDrawElementsCount(0u),
90   mBlendBitmask(0u),
91   mResendFlag(0u),
92   mDepthFunction(DepthFunction::LESS),
93   mFaceCullingMode(FaceCullingMode::NONE),
94   mBlendMode(BlendMode::AUTO),
95   mDepthWriteMode(DepthWriteMode::AUTO),
96   mDepthTestMode(DepthTestMode::AUTO),
97   mRenderingBehavior(DevelRenderer::Rendering::IF_REQUIRED),
98   mUpdateDecay(Renderer::Decay::INITIAL),
99   mRegenerateUniformMap(false),
100   mPremultipledAlphaEnabled(false),
101   mOpacity(1.0f),
102   mDepthIndex(0)
103 {
104   // Observe our own PropertyOwner's uniform map.
105   AddUniformMapObserver(*this);
106 }
107
108 Renderer::~Renderer()
109 {
110   if(mShader)
111   {
112     mShader->RemoveUniformMapObserver(*this);
113     mShader = nullptr;
114   }
115 }
116
117 void Renderer::operator delete(void* ptr)
118 {
119   gRendererMemoryPool.FreeThreadSafe(static_cast<Renderer*>(ptr));
120 }
121
122 bool Renderer::PrepareRender(BufferIndex updateBufferIndex)
123 {
124   bool rendererUpdated = mResendFlag || mRenderingBehavior == DevelRenderer::Rendering::CONTINUOUSLY || mUpdateDecay > 0;
125
126   if(mUniformMapChangeCounter != mUniformMaps.GetChangeCounter())
127   {
128     // The map has changed since the last time we checked.
129     rendererUpdated          = true;
130     mRegenerateUniformMap    = true;
131     mUpdateDecay             = Renderer::Decay::INITIAL; // Render at least twice if the map has changed/actor has been added
132     mUniformMapChangeCounter = mUniformMaps.GetChangeCounter();
133   }
134   if(mUpdateDecay > 0)
135   {
136     mUpdateDecay = static_cast<Renderer::Decay>(static_cast<int>(mUpdateDecay) - 1);
137   }
138
139   if(mResendFlag != 0)
140   {
141     if(mResendFlag & RESEND_GEOMETRY)
142     {
143       typedef MessageValue1<Render::Renderer, Render::Geometry*> DerivedType;
144       uint32_t*                                                  slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
145       new(slot) DerivedType(mRenderer, &Render::Renderer::SetGeometry, mGeometry);
146     }
147
148     if(mResendFlag & RESEND_DRAW_COMMANDS)
149     {
150       using DerivedType = MessageValue2<Render::Renderer, Dali::DevelRenderer::DrawCommand*, uint32_t>;
151       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
152       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDrawCommands, mDrawCommands.data(), mDrawCommands.size());
153     }
154
155     if(mResendFlag & RESEND_FACE_CULLING_MODE)
156     {
157       using DerivedType = MessageValue1<Render::Renderer, FaceCullingMode::Type>;
158       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
159       new(slot) DerivedType(mRenderer, &Render::Renderer::SetFaceCullingMode, mFaceCullingMode);
160     }
161
162     if(mResendFlag & RESEND_BLEND_BIT_MASK)
163     {
164       using DerivedType = MessageValue1<Render::Renderer, uint32_t>;
165       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
166       new(slot) DerivedType(mRenderer, &Render::Renderer::SetBlendingBitMask, mBlendBitmask);
167     }
168
169     if(mResendFlag & RESEND_BLEND_COLOR)
170     {
171       using DerivedType = MessageValue1<Render::Renderer, Vector4>;
172       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
173       new(slot) DerivedType(mRenderer, &Render::Renderer::SetBlendColor, GetBlendColor());
174     }
175
176     if(mResendFlag & RESEND_PREMULTIPLIED_ALPHA)
177     {
178       using DerivedType = MessageValue1<Render::Renderer, bool>;
179       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
180       new(slot) DerivedType(mRenderer, &Render::Renderer::EnablePreMultipliedAlpha, mPremultipledAlphaEnabled);
181     }
182
183     if(mResendFlag & RESEND_INDEXED_DRAW_FIRST_ELEMENT)
184     {
185       using DerivedType = MessageValue1<Render::Renderer, uint32_t>;
186       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
187       new(slot) DerivedType(mRenderer, &Render::Renderer::SetIndexedDrawFirstElement, mIndexedDrawFirstElement);
188     }
189
190     if(mResendFlag & RESEND_INDEXED_DRAW_ELEMENTS_COUNT)
191     {
192       using DerivedType = MessageValue1<Render::Renderer, uint32_t>;
193       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
194       new(slot) DerivedType(mRenderer, &Render::Renderer::SetIndexedDrawElementsCount, mIndexedDrawElementsCount);
195     }
196
197     if(mResendFlag & RESEND_DEPTH_WRITE_MODE)
198     {
199       using DerivedType = MessageValue1<Render::Renderer, DepthWriteMode::Type>;
200       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
201       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthWriteMode, mDepthWriteMode);
202     }
203
204     if(mResendFlag & RESEND_DEPTH_TEST_MODE)
205     {
206       using DerivedType = MessageValue1<Render::Renderer, DepthTestMode::Type>;
207       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
208       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthTestMode, mDepthTestMode);
209     }
210
211     if(mResendFlag & RESEND_DEPTH_FUNCTION)
212     {
213       using DerivedType = MessageValue1<Render::Renderer, DepthFunction::Type>;
214       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
215       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthFunction, mDepthFunction);
216     }
217
218     if(mResendFlag & RESEND_RENDER_MODE)
219     {
220       using DerivedType = MessageValue1<Render::Renderer, RenderMode::Type>;
221       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
222       new(slot) DerivedType(mRenderer, &Render::Renderer::SetRenderMode, mStencilParameters.renderMode);
223     }
224
225     if(mResendFlag & RESEND_STENCIL_FUNCTION)
226     {
227       using DerivedType = MessageValue1<Render::Renderer, StencilFunction::Type>;
228       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
229       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilFunction, mStencilParameters.stencilFunction);
230     }
231
232     if(mResendFlag & RESEND_STENCIL_FUNCTION_MASK)
233     {
234       using DerivedType = MessageValue1<Render::Renderer, int>;
235       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
236       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilFunctionMask, mStencilParameters.stencilFunctionMask);
237     }
238
239     if(mResendFlag & RESEND_STENCIL_FUNCTION_REFERENCE)
240     {
241       using DerivedType = MessageValue1<Render::Renderer, int>;
242       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
243       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilFunctionReference, mStencilParameters.stencilFunctionReference);
244     }
245
246     if(mResendFlag & RESEND_STENCIL_MASK)
247     {
248       using DerivedType = MessageValue1<Render::Renderer, int>;
249       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
250       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilMask, mStencilParameters.stencilMask);
251     }
252
253     if(mResendFlag & RESEND_STENCIL_OPERATION_ON_FAIL)
254     {
255       using DerivedType = MessageValue1<Render::Renderer, StencilOperation::Type>;
256       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
257       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnFail, mStencilParameters.stencilOperationOnFail);
258     }
259
260     if(mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_FAIL)
261     {
262       using DerivedType = MessageValue1<Render::Renderer, StencilOperation::Type>;
263       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
264       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnZFail, mStencilParameters.stencilOperationOnZFail);
265     }
266
267     if(mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_PASS)
268     {
269       using DerivedType = MessageValue1<Render::Renderer, StencilOperation::Type>;
270       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
271       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnZPass, mStencilParameters.stencilOperationOnZPass);
272     }
273
274     if(mResendFlag & RESEND_SHADER)
275     {
276       using DerivedType = MessageValue1<Render::Renderer, bool>;
277       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
278       new(slot) DerivedType(mRenderer, &Render::Renderer::SetShaderChanged, true);
279     }
280
281     if(mResendFlag & RESEND_SET_RENDER_CALLBACK)
282     {
283       using DerivedType = MessageValue1<Render::Renderer, Dali::RenderCallback*>;
284       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
285       new(slot) DerivedType(mRenderer, &Render::Renderer::SetRenderCallback, mRenderCallback);
286     }
287
288     mResendFlag = 0;
289   }
290
291   return rendererUpdated;
292 }
293
294 void Renderer::SetTextures(TextureSet* textureSet)
295 {
296   DALI_ASSERT_DEBUG(textureSet != NULL && "Texture set pointer is NULL");
297
298   mTextureSet = textureSet;
299 }
300
301 const Vector<Render::Texture*>* Renderer::GetTextures() const
302 {
303   return mTextureSet ? &(mTextureSet->GetTextures()) : nullptr;
304 }
305
306 const Vector<Render::Sampler*>* Renderer::GetSamplers() const
307 {
308   return mTextureSet ? &(mTextureSet->GetSamplers()) : nullptr;
309 }
310
311 void Renderer::SetShader(Shader* shader)
312 {
313   DALI_ASSERT_DEBUG(shader != NULL && "Shader pointer is NULL");
314
315   if(mShader)
316   {
317     mShader->RemoveUniformMapObserver(*this);
318   }
319
320   mShader = shader;
321   mShader->AddUniformMapObserver(*this);
322   mRegenerateUniformMap = true;
323   mResendFlag |= RESEND_GEOMETRY | RESEND_SHADER;
324 }
325
326 void Renderer::SetGeometry(Render::Geometry* geometry)
327 {
328   DALI_ASSERT_DEBUG(geometry != NULL && "Geometry pointer is NULL");
329   mGeometry = geometry;
330
331   if(mRenderer)
332   {
333     mResendFlag |= RESEND_GEOMETRY;
334   }
335 }
336
337 void Renderer::SetDepthIndex(int depthIndex)
338 {
339   mDepthIndex = depthIndex;
340 }
341
342 void Renderer::SetFaceCullingMode(FaceCullingMode::Type faceCullingMode)
343 {
344   mFaceCullingMode = faceCullingMode;
345   mResendFlag |= RESEND_FACE_CULLING_MODE;
346 }
347
348 FaceCullingMode::Type Renderer::GetFaceCullingMode() const
349 {
350   return mFaceCullingMode;
351 }
352
353 void Renderer::SetBlendMode(BlendMode::Type blendingMode)
354 {
355   mBlendMode = blendingMode;
356 }
357
358 BlendMode::Type Renderer::GetBlendMode() const
359 {
360   return mBlendMode;
361 }
362
363 void Renderer::SetBlendingOptions(uint32_t options)
364 {
365   if(mBlendBitmask != options)
366   {
367     mBlendBitmask = options;
368     mResendFlag |= RESEND_BLEND_BIT_MASK;
369   }
370 }
371
372 uint32_t Renderer::GetBlendingOptions() const
373 {
374   return mBlendBitmask;
375 }
376
377 void Renderer::SetBlendColor(const Vector4& blendColor)
378 {
379   if(blendColor == Color::TRANSPARENT)
380   {
381     mBlendColor = nullptr;
382   }
383   else
384   {
385     if(!mBlendColor)
386     {
387       mBlendColor = new Vector4(blendColor);
388     }
389     else
390     {
391       *mBlendColor = blendColor;
392     }
393   }
394
395   mResendFlag |= RESEND_BLEND_COLOR;
396 }
397
398 Vector4 Renderer::GetBlendColor() const
399 {
400   if(mBlendColor)
401   {
402     return *mBlendColor;
403   }
404   return Color::TRANSPARENT;
405 }
406
407 void Renderer::SetIndexedDrawFirstElement(uint32_t firstElement)
408 {
409   mIndexedDrawFirstElement = firstElement;
410   mResendFlag |= RESEND_INDEXED_DRAW_FIRST_ELEMENT;
411 }
412
413 uint32_t Renderer::GetIndexedDrawFirstElement() const
414 {
415   return mIndexedDrawFirstElement;
416 }
417
418 void Renderer::SetIndexedDrawElementsCount(uint32_t elementsCount)
419 {
420   mIndexedDrawElementsCount = elementsCount;
421   mResendFlag |= RESEND_INDEXED_DRAW_ELEMENTS_COUNT;
422 }
423
424 uint32_t Renderer::GetIndexedDrawElementsCount() const
425 {
426   return mIndexedDrawElementsCount;
427 }
428
429 void Renderer::EnablePreMultipliedAlpha(bool preMultipled)
430 {
431   mPremultipledAlphaEnabled = preMultipled;
432   mResendFlag |= RESEND_PREMULTIPLIED_ALPHA;
433 }
434
435 bool Renderer::IsPreMultipliedAlphaEnabled() const
436 {
437   return mPremultipledAlphaEnabled;
438 }
439
440 void Renderer::SetDepthWriteMode(DepthWriteMode::Type depthWriteMode)
441 {
442   mDepthWriteMode = depthWriteMode;
443   mResendFlag |= RESEND_DEPTH_WRITE_MODE;
444 }
445
446 DepthWriteMode::Type Renderer::GetDepthWriteMode() const
447 {
448   return mDepthWriteMode;
449 }
450
451 void Renderer::SetDepthTestMode(DepthTestMode::Type depthTestMode)
452 {
453   mDepthTestMode = depthTestMode;
454   mResendFlag |= RESEND_DEPTH_TEST_MODE;
455 }
456
457 DepthTestMode::Type Renderer::GetDepthTestMode() const
458 {
459   return mDepthTestMode;
460 }
461
462 void Renderer::SetDepthFunction(DepthFunction::Type depthFunction)
463 {
464   mDepthFunction = depthFunction;
465   mResendFlag |= RESEND_DEPTH_FUNCTION;
466 }
467
468 DepthFunction::Type Renderer::GetDepthFunction() const
469 {
470   return mDepthFunction;
471 }
472
473 void Renderer::SetRenderMode(RenderMode::Type mode)
474 {
475   mStencilParameters.renderMode = mode;
476   mResendFlag |= RESEND_RENDER_MODE;
477 }
478
479 void Renderer::SetStencilFunction(StencilFunction::Type stencilFunction)
480 {
481   mStencilParameters.stencilFunction = stencilFunction;
482   mResendFlag |= RESEND_STENCIL_FUNCTION;
483 }
484
485 void Renderer::SetStencilFunctionMask(int stencilFunctionMask)
486 {
487   mStencilParameters.stencilFunctionMask = stencilFunctionMask;
488   mResendFlag |= RESEND_STENCIL_FUNCTION_MASK;
489 }
490
491 void Renderer::SetStencilFunctionReference(int stencilFunctionReference)
492 {
493   mStencilParameters.stencilFunctionReference = stencilFunctionReference;
494   mResendFlag |= RESEND_STENCIL_FUNCTION_REFERENCE;
495 }
496
497 void Renderer::SetStencilMask(int stencilMask)
498 {
499   mStencilParameters.stencilMask = stencilMask;
500   mResendFlag |= RESEND_STENCIL_MASK;
501 }
502
503 void Renderer::SetStencilOperationOnFail(StencilOperation::Type stencilOperationOnFail)
504 {
505   mStencilParameters.stencilOperationOnFail = stencilOperationOnFail;
506   mResendFlag |= RESEND_STENCIL_OPERATION_ON_FAIL;
507 }
508
509 void Renderer::SetStencilOperationOnZFail(StencilOperation::Type stencilOperationOnZFail)
510 {
511   mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail;
512   mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_FAIL;
513 }
514
515 void Renderer::SetStencilOperationOnZPass(StencilOperation::Type stencilOperationOnZPass)
516 {
517   mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass;
518   mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_PASS;
519 }
520
521 void Renderer::SetRenderCallback(RenderCallback* callback)
522 {
523   mRenderCallback = callback;
524   mResendFlag |= RESEND_SET_RENDER_CALLBACK;
525 }
526
527 const Render::Renderer::StencilParameters& Renderer::GetStencilParameters() const
528 {
529   return mStencilParameters;
530 }
531
532 void Renderer::BakeOpacity(BufferIndex updateBufferIndex, float opacity)
533 {
534   mOpacity.Bake(updateBufferIndex, opacity);
535 }
536
537 float Renderer::GetOpacity(BufferIndex updateBufferIndex) const
538 {
539   return mOpacity[updateBufferIndex];
540 }
541
542 void Renderer::SetRenderingBehavior(DevelRenderer::Rendering::Type renderingBehavior)
543 {
544   mRenderingBehavior = renderingBehavior;
545 }
546
547 DevelRenderer::Rendering::Type Renderer::GetRenderingBehavior() const
548 {
549   return mRenderingBehavior;
550 }
551
552 //Called when SceneGraph::Renderer is added to update manager ( that happens when an "event-thread renderer" is created )
553 void Renderer::ConnectToSceneGraph(SceneController& sceneController, BufferIndex bufferIndex)
554 {
555   mRegenerateUniformMap = true;
556   mSceneController      = &sceneController;
557
558   mRenderer = Render::Renderer::New(this, mGeometry, mBlendBitmask, GetBlendColor(), static_cast<FaceCullingMode::Type>(mFaceCullingMode), mPremultipledAlphaEnabled, mDepthWriteMode, mDepthTestMode, mDepthFunction, mStencilParameters);
559
560   OwnerPointer<Render::Renderer> transferOwnership(mRenderer);
561   mSceneController->GetRenderMessageDispatcher().AddRenderer(transferOwnership);
562 }
563
564 //Called just before destroying the scene-graph renderer ( when the "event-thread renderer" is no longer referenced )
565 void Renderer::DisconnectFromSceneGraph(SceneController& sceneController, BufferIndex bufferIndex)
566 {
567   //Remove renderer from RenderManager
568   if(mRenderer)
569   {
570     mSceneController->GetRenderMessageDispatcher().RemoveRenderer(*mRenderer);
571     mRenderer = nullptr;
572   }
573   mSceneController = nullptr;
574 }
575
576 Render::Renderer& Renderer::GetRenderer()
577 {
578   return *mRenderer;
579 }
580
581 Renderer::OpacityType Renderer::GetOpacityType(BufferIndex updateBufferIndex, const Node& node) const
582 {
583   Renderer::OpacityType opacityType = Renderer::OPAQUE;
584
585   if(node.IsTransparent())
586   {
587     return Renderer::TRANSPARENT;
588   }
589
590   switch(mBlendMode)
591   {
592     case BlendMode::ON_WITHOUT_CULL: // If the renderer should always be use blending and never want to be transparent by alpha.
593     {
594       opacityType = Renderer::TRANSLUCENT;
595       break;
596     }
597     case BlendMode::ON: // If the renderer should always be use blending
598     {
599       float alpha = node.GetWorldColor(updateBufferIndex).a * mOpacity[updateBufferIndex];
600       if(alpha <= FULLY_TRANSPARENT)
601       {
602         opacityType = Renderer::TRANSPARENT;
603       }
604       else
605       {
606         opacityType = Renderer::TRANSLUCENT;
607       }
608       break;
609     }
610     case BlendMode::AUTO:
611     {
612       if(BlendingOptions::IsAdvancedBlendEquationIncluded(mBlendBitmask))
613       {
614         opacityType = Renderer::TRANSLUCENT;
615         break;
616       }
617
618       bool shaderRequiresBlending(mShader->HintEnabled(Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT));
619       if(shaderRequiresBlending || (mTextureSet && mTextureSet->HasAlpha()))
620       {
621         opacityType = Renderer::TRANSLUCENT;
622       }
623
624       // renderer should determine opacity using the actor color
625       float alpha = node.GetWorldColor(updateBufferIndex).a * mOpacity[updateBufferIndex];
626       if(alpha <= FULLY_TRANSPARENT)
627       {
628         opacityType = Renderer::TRANSPARENT;
629       }
630       else if(alpha <= FULLY_OPAQUE)
631       {
632         opacityType = Renderer::TRANSLUCENT;
633       }
634
635       break;
636     }
637     case BlendMode::OFF: // the renderer should never use blending
638     default:
639     {
640       opacityType = Renderer::OPAQUE;
641       break;
642     }
643   }
644
645   return opacityType;
646 }
647
648 bool Renderer::UpdateUniformMap()
649 {
650   bool updated = false;
651
652   if(mRegenerateUniformMap)
653   {
654     CollectedUniformMap& localMap = mCollectedUniformMap;
655     localMap.Clear();
656
657     const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap();
658
659     auto size = rendererUniformMap.Count();
660     if(mShader)
661     {
662       size += mShader->GetUniformMap().Count();
663     }
664
665     localMap.Reserve(size);
666     localMap.AddMappings(rendererUniformMap);
667     if(mShader)
668     {
669       localMap.AddMappings(mShader->GetUniformMap());
670     }
671     localMap.UpdateChangeCounter();
672     mRegenerateUniformMap = false;
673     updated               = true;
674   }
675   return updated;
676 }
677
678 void Renderer::SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size)
679 {
680   mDrawCommands.clear();
681   mDrawCommands.insert(mDrawCommands.end(), pDrawCommands, pDrawCommands + size);
682   mResendFlag |= RESEND_DRAW_COMMANDS;
683 }
684
685 void Renderer::UniformMappingsChanged(const UniformMap& mappings)
686 {
687   // The mappings are either from PropertyOwner base class, or the Shader
688   mRegenerateUniformMap = true; // Should remain true until this renderer is added to a RenderList.
689 }
690
691 const CollectedUniformMap& Renderer::GetCollectedUniformMap() const
692 {
693   return mCollectedUniformMap;
694 }
695
696 } // namespace SceneGraph
697 } // namespace Internal
698 } // namespace Dali