Remove uniform hash
[platform/core/uifw/dali-core.git] / dali / internal / update / rendering / scene-graph-renderer.cpp
1 /*
2  * Copyright (c) 2023 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 #include <dali/integration-api/debug.h>
36
37 namespace Dali
38 {
39 namespace Internal
40 {
41 namespace SceneGraph
42 {
43 namespace // unnamed namespace
44 {
45 #ifdef DEBUG_ENABLED
46 Debug::Filter* gSceneGraphRendererLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_SG_RENDERER");
47 #endif
48
49 // Memory pool used to allocate new renderers. Memory used by this pool will be released when shutting down DALi
50 MemoryPoolObjectAllocator<Renderer>& GetRendererMemoryPool()
51 {
52   static MemoryPoolObjectAllocator<Renderer> gRendererMemoryPool;
53   return gRendererMemoryPool;
54 }
55
56 // Flags for re-sending data to renderer.
57 enum Flags
58 {
59   RESEND_GEOMETRY                    = 1 << 0,
60   RESEND_FACE_CULLING_MODE           = 1 << 1,
61   RESEND_BLEND_COLOR                 = 1 << 2,
62   RESEND_BLEND_BIT_MASK              = 1 << 3,
63   RESEND_PREMULTIPLIED_ALPHA         = 1 << 4,
64   RESEND_INDEXED_DRAW_FIRST_ELEMENT  = 1 << 5,
65   RESEND_INDEXED_DRAW_ELEMENTS_COUNT = 1 << 6,
66   RESEND_DEPTH_WRITE_MODE            = 1 << 7,
67   RESEND_DEPTH_TEST_MODE             = 1 << 8,
68   RESEND_DEPTH_FUNCTION              = 1 << 9,
69   RESEND_RENDER_MODE                 = 1 << 10,
70   RESEND_STENCIL_FUNCTION            = 1 << 11,
71   RESEND_STENCIL_FUNCTION_MASK       = 1 << 12,
72   RESEND_STENCIL_FUNCTION_REFERENCE  = 1 << 13,
73   RESEND_STENCIL_MASK                = 1 << 14,
74   RESEND_STENCIL_OPERATION_ON_FAIL   = 1 << 15,
75   RESEND_STENCIL_OPERATION_ON_Z_FAIL = 1 << 16,
76   RESEND_STENCIL_OPERATION_ON_Z_PASS = 1 << 17,
77   RESEND_WRITE_TO_COLOR_BUFFER       = 1 << 18,
78   RESEND_SHADER                      = 1 << 19,
79   RESEND_DRAW_COMMANDS               = 1 << 20,
80   RESEND_SET_RENDER_CALLBACK         = 1 << 21
81 };
82
83 } // Anonymous namespace
84
85 RendererKey Renderer::NewKey()
86 {
87   void* ptr = GetRendererMemoryPool().AllocateRawThreadSafe();
88   auto  key = GetRendererMemoryPool().GetKeyFromPtr(static_cast<Renderer*>(ptr));
89   new(ptr) Renderer();
90   return RendererKey(key);
91 }
92
93 Renderer::Renderer()
94 : mSceneController(nullptr),
95   mRenderer{},
96   mTextureSet(nullptr),
97   mGeometry(nullptr),
98   mShader(nullptr),
99   mBlendColor(nullptr),
100   mStencilParameters(RenderMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP),
101   mIndexedDrawFirstElement(0u),
102   mIndexedDrawElementsCount(0u),
103   mBlendBitmask(0u),
104   mResendFlag(0u),
105   mDepthFunction(DepthFunction::LESS),
106   mFaceCullingMode(FaceCullingMode::NONE),
107   mBlendMode(BlendMode::AUTO),
108   mDepthWriteMode(DepthWriteMode::AUTO),
109   mDepthTestMode(DepthTestMode::AUTO),
110   mRenderingBehavior(DevelRenderer::Rendering::IF_REQUIRED),
111   mUpdateDecay(Renderer::Decay::INITIAL),
112   mRegenerateUniformMap(false),
113   mPremultipledAlphaEnabled(false),
114   mDirtyFlag(true),
115   mOpacity(1.0f),
116   mDepthIndex(0)
117 {
118 }
119
120 Renderer::~Renderer()
121 {
122 }
123
124 void Renderer::operator delete(void* ptr)
125 {
126   GetRendererMemoryPool().FreeThreadSafe(static_cast<Renderer*>(ptr));
127 }
128
129 Renderer* Renderer::Get(RendererKey::KeyType rendererKey)
130 {
131   return GetRendererMemoryPool().GetPtrFromKey(rendererKey);
132 }
133
134 RendererKey Renderer::GetKey(const Renderer& renderer)
135 {
136   return RendererKey(GetRendererMemoryPool().GetKeyFromPtr(const_cast<Renderer*>(&renderer)));
137 }
138
139 RendererKey Renderer::GetKey(Renderer* renderer)
140 {
141   return RendererKey(GetRendererMemoryPool().GetKeyFromPtr(renderer));
142 }
143
144 bool Renderer::PrepareRender(BufferIndex updateBufferIndex)
145 {
146   bool rendererUpdated        = mResendFlag || mRenderingBehavior == DevelRenderer::Rendering::CONTINUOUSLY || mUpdateDecay > 0;
147   auto shaderMapChangeCounter = mShader ? mShader->GetUniformMap().GetChangeCounter() : 0u;
148   bool shaderMapChanged       = mShader && (mShaderMapChangeCounter != shaderMapChangeCounter);
149   if(shaderMapChanged)
150   {
151     mShaderMapChangeCounter = shaderMapChangeCounter;
152   }
153
154   if(mUniformMapChangeCounter != mUniformMaps.GetChangeCounter() || shaderMapChanged)
155   {
156     // The map has changed since the last time we checked.
157     rendererUpdated       = true;
158     mRegenerateUniformMap = true;
159     mUpdateDecay          = Renderer::Decay::INITIAL; // Render at least twice if the map has changed/actor has been added
160
161     // Update local counters to identify any future changes to maps
162     // (unlikely, but allowed by API).
163     mUniformMapChangeCounter = mUniformMaps.GetChangeCounter();
164   }
165   if(mUpdateDecay > 0)
166   {
167     mUpdateDecay = static_cast<Renderer::Decay>(static_cast<int>(mUpdateDecay) - 1);
168   }
169
170   if(mResendFlag != 0)
171   {
172     Render::Renderer* rendererPtr = mRenderer.Get();
173     if(mResendFlag & RESEND_GEOMETRY)
174     {
175       typedef MessageValue1<Render::Renderer, Render::Geometry*> DerivedType;
176       uint32_t*                                                  slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
177       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetGeometry, mGeometry);
178     }
179
180     if(mResendFlag & RESEND_DRAW_COMMANDS)
181     {
182       using DerivedType = MessageValue2<Render::Renderer, Dali::DevelRenderer::DrawCommand*, uint32_t>;
183       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
184       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetDrawCommands, mDrawCommands.data(), mDrawCommands.size());
185     }
186
187     if(mResendFlag & RESEND_FACE_CULLING_MODE)
188     {
189       using DerivedType = MessageValue1<Render::Renderer, FaceCullingMode::Type>;
190       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
191       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetFaceCullingMode, mFaceCullingMode);
192     }
193
194     if(mResendFlag & RESEND_BLEND_BIT_MASK)
195     {
196       using DerivedType = MessageValue1<Render::Renderer, uint32_t>;
197       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
198       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetBlendingBitMask, mBlendBitmask);
199     }
200
201     if(mResendFlag & RESEND_BLEND_COLOR)
202     {
203       using DerivedType = MessageValue1<Render::Renderer, Vector4>;
204       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
205       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetBlendColor, GetBlendColor());
206     }
207
208     if(mResendFlag & RESEND_PREMULTIPLIED_ALPHA)
209     {
210       using DerivedType = MessageValue1<Render::Renderer, bool>;
211       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
212       new(slot) DerivedType(rendererPtr, &Render::Renderer::EnablePreMultipliedAlpha, mPremultipledAlphaEnabled);
213     }
214
215     if(mResendFlag & RESEND_INDEXED_DRAW_FIRST_ELEMENT)
216     {
217       using DerivedType = MessageValue1<Render::Renderer, uint32_t>;
218       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
219       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetIndexedDrawFirstElement, mIndexedDrawFirstElement);
220     }
221
222     if(mResendFlag & RESEND_INDEXED_DRAW_ELEMENTS_COUNT)
223     {
224       using DerivedType = MessageValue1<Render::Renderer, uint32_t>;
225       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
226       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetIndexedDrawElementsCount, mIndexedDrawElementsCount);
227     }
228
229     if(mResendFlag & RESEND_DEPTH_WRITE_MODE)
230     {
231       using DerivedType = MessageValue1<Render::Renderer, DepthWriteMode::Type>;
232       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
233       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetDepthWriteMode, mDepthWriteMode);
234     }
235
236     if(mResendFlag & RESEND_DEPTH_TEST_MODE)
237     {
238       using DerivedType = MessageValue1<Render::Renderer, DepthTestMode::Type>;
239       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
240       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetDepthTestMode, mDepthTestMode);
241     }
242
243     if(mResendFlag & RESEND_DEPTH_FUNCTION)
244     {
245       using DerivedType = MessageValue1<Render::Renderer, DepthFunction::Type>;
246       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
247       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetDepthFunction, mDepthFunction);
248     }
249
250     if(mResendFlag & RESEND_RENDER_MODE)
251     {
252       using DerivedType = MessageValue1<Render::Renderer, RenderMode::Type>;
253       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
254       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetRenderMode, mStencilParameters.renderMode);
255     }
256
257     if(mResendFlag & RESEND_STENCIL_FUNCTION)
258     {
259       using DerivedType = MessageValue1<Render::Renderer, StencilFunction::Type>;
260       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
261       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetStencilFunction, mStencilParameters.stencilFunction);
262     }
263
264     if(mResendFlag & RESEND_STENCIL_FUNCTION_MASK)
265     {
266       using DerivedType = MessageValue1<Render::Renderer, int>;
267       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
268       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetStencilFunctionMask, mStencilParameters.stencilFunctionMask);
269     }
270
271     if(mResendFlag & RESEND_STENCIL_FUNCTION_REFERENCE)
272     {
273       using DerivedType = MessageValue1<Render::Renderer, int>;
274       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
275       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetStencilFunctionReference, mStencilParameters.stencilFunctionReference);
276     }
277
278     if(mResendFlag & RESEND_STENCIL_MASK)
279     {
280       using DerivedType = MessageValue1<Render::Renderer, int>;
281       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
282       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetStencilMask, mStencilParameters.stencilMask);
283     }
284
285     if(mResendFlag & RESEND_STENCIL_OPERATION_ON_FAIL)
286     {
287       using DerivedType = MessageValue1<Render::Renderer, StencilOperation::Type>;
288       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
289       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetStencilOperationOnFail, mStencilParameters.stencilOperationOnFail);
290     }
291
292     if(mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_FAIL)
293     {
294       using DerivedType = MessageValue1<Render::Renderer, StencilOperation::Type>;
295       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
296       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetStencilOperationOnZFail, mStencilParameters.stencilOperationOnZFail);
297     }
298
299     if(mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_PASS)
300     {
301       using DerivedType = MessageValue1<Render::Renderer, StencilOperation::Type>;
302       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
303       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetStencilOperationOnZPass, mStencilParameters.stencilOperationOnZPass);
304     }
305
306     if(mResendFlag & RESEND_SHADER)
307     {
308       using DerivedType = MessageValue1<Render::Renderer, bool>;
309       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
310       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetShaderChanged, true);
311     }
312
313     if(mResendFlag & RESEND_SET_RENDER_CALLBACK)
314     {
315       using DerivedType = MessageValue1<Render::Renderer, Dali::RenderCallback*>;
316       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
317       new(slot) DerivedType(rendererPtr, &Render::Renderer::SetRenderCallback, mRenderCallback);
318     }
319
320     SetUpdated(true);
321
322     mResendFlag = 0;
323   }
324
325   // Ensure collected map is up to date
326   UpdateUniformMap(updateBufferIndex);
327
328   return rendererUpdated;
329 }
330
331 void Renderer::SetTextures(TextureSet* textureSet)
332 {
333   DALI_ASSERT_DEBUG(textureSet != NULL && "Texture set pointer is NULL");
334
335   mTextureSet = textureSet;
336
337   mDirtyFlag = true;
338   SetUpdated(true);
339 }
340
341 const Vector<Render::TextureKey>* Renderer::GetTextures() const
342 {
343   return mTextureSet ? &(mTextureSet->GetTextures()) : nullptr;
344 }
345
346 const Vector<Render::Sampler*>* Renderer::GetSamplers() const
347 {
348   return mTextureSet ? &(mTextureSet->GetSamplers()) : nullptr;
349 }
350
351 void Renderer::SetShader(Shader* shader)
352 {
353   DALI_ASSERT_DEBUG(shader != NULL && "Shader pointer is NULL");
354
355   mShader                 = shader;
356   mShaderMapChangeCounter = 0u;
357   mRegenerateUniformMap   = true;
358   mResendFlag |= RESEND_GEOMETRY | RESEND_SHADER;
359   mDirtyFlag = true;
360 }
361
362 void Renderer::SetGeometry(Render::Geometry* geometry)
363 {
364   DALI_ASSERT_DEBUG(geometry != NULL && "Geometry pointer is NULL");
365   mGeometry = geometry;
366
367   if(mRenderer)
368   {
369     mResendFlag |= RESEND_GEOMETRY;
370   }
371 }
372
373 void Renderer::SetDepthIndex(int depthIndex)
374 {
375   mDepthIndex = depthIndex;
376
377   mDirtyFlag = true;
378   SetUpdated(true);
379 }
380
381 void Renderer::SetFaceCullingMode(FaceCullingMode::Type faceCullingMode)
382 {
383   mFaceCullingMode = faceCullingMode;
384   mResendFlag |= RESEND_FACE_CULLING_MODE;
385 }
386
387 FaceCullingMode::Type Renderer::GetFaceCullingMode() const
388 {
389   return mFaceCullingMode;
390 }
391
392 void Renderer::SetBlendMode(BlendMode::Type blendingMode)
393 {
394   mBlendMode = blendingMode;
395
396   mDirtyFlag = true;
397   SetUpdated(true);
398 }
399
400 BlendMode::Type Renderer::GetBlendMode() const
401 {
402   return mBlendMode;
403 }
404
405 void Renderer::SetBlendingOptions(uint32_t options)
406 {
407   if(mBlendBitmask != options)
408   {
409     mBlendBitmask = options;
410     mResendFlag |= RESEND_BLEND_BIT_MASK;
411     mDirtyFlag = true;
412   }
413 }
414
415 uint32_t Renderer::GetBlendingOptions() const
416 {
417   return mBlendBitmask;
418 }
419
420 void Renderer::SetBlendColor(const Vector4& blendColor)
421 {
422   if(blendColor == Color::TRANSPARENT)
423   {
424     mBlendColor = nullptr;
425   }
426   else
427   {
428     if(!mBlendColor)
429     {
430       mBlendColor = new Vector4(blendColor);
431     }
432     else
433     {
434       *mBlendColor = blendColor;
435     }
436   }
437
438   mResendFlag |= RESEND_BLEND_COLOR;
439 }
440
441 Vector4 Renderer::GetBlendColor() const
442 {
443   if(mBlendColor)
444   {
445     return *mBlendColor;
446   }
447   return Color::TRANSPARENT;
448 }
449
450 void Renderer::SetIndexedDrawFirstElement(uint32_t firstElement)
451 {
452   mIndexedDrawFirstElement = firstElement;
453   mResendFlag |= RESEND_INDEXED_DRAW_FIRST_ELEMENT;
454 }
455
456 uint32_t Renderer::GetIndexedDrawFirstElement() const
457 {
458   return mIndexedDrawFirstElement;
459 }
460
461 void Renderer::SetIndexedDrawElementsCount(uint32_t elementsCount)
462 {
463   mIndexedDrawElementsCount = elementsCount;
464   mResendFlag |= RESEND_INDEXED_DRAW_ELEMENTS_COUNT;
465 }
466
467 uint32_t Renderer::GetIndexedDrawElementsCount() const
468 {
469   return mIndexedDrawElementsCount;
470 }
471
472 void Renderer::EnablePreMultipliedAlpha(bool preMultipled)
473 {
474   mPremultipledAlphaEnabled = preMultipled;
475   mResendFlag |= RESEND_PREMULTIPLIED_ALPHA;
476 }
477
478 bool Renderer::IsPreMultipliedAlphaEnabled() const
479 {
480   return mPremultipledAlphaEnabled;
481 }
482
483 void Renderer::SetDepthWriteMode(DepthWriteMode::Type depthWriteMode)
484 {
485   mDepthWriteMode = depthWriteMode;
486   mResendFlag |= RESEND_DEPTH_WRITE_MODE;
487 }
488
489 DepthWriteMode::Type Renderer::GetDepthWriteMode() const
490 {
491   return mDepthWriteMode;
492 }
493
494 void Renderer::SetDepthTestMode(DepthTestMode::Type depthTestMode)
495 {
496   mDepthTestMode = depthTestMode;
497   mResendFlag |= RESEND_DEPTH_TEST_MODE;
498 }
499
500 DepthTestMode::Type Renderer::GetDepthTestMode() const
501 {
502   return mDepthTestMode;
503 }
504
505 void Renderer::SetDepthFunction(DepthFunction::Type depthFunction)
506 {
507   mDepthFunction = depthFunction;
508   mResendFlag |= RESEND_DEPTH_FUNCTION;
509 }
510
511 DepthFunction::Type Renderer::GetDepthFunction() const
512 {
513   return mDepthFunction;
514 }
515
516 void Renderer::SetRenderMode(RenderMode::Type mode)
517 {
518   mStencilParameters.renderMode = mode;
519   mResendFlag |= RESEND_RENDER_MODE;
520 }
521
522 void Renderer::SetStencilFunction(StencilFunction::Type stencilFunction)
523 {
524   mStencilParameters.stencilFunction = stencilFunction;
525   mResendFlag |= RESEND_STENCIL_FUNCTION;
526 }
527
528 void Renderer::SetStencilFunctionMask(int stencilFunctionMask)
529 {
530   mStencilParameters.stencilFunctionMask = stencilFunctionMask;
531   mResendFlag |= RESEND_STENCIL_FUNCTION_MASK;
532 }
533
534 void Renderer::SetStencilFunctionReference(int stencilFunctionReference)
535 {
536   mStencilParameters.stencilFunctionReference = stencilFunctionReference;
537   mResendFlag |= RESEND_STENCIL_FUNCTION_REFERENCE;
538 }
539
540 void Renderer::SetStencilMask(int stencilMask)
541 {
542   mStencilParameters.stencilMask = stencilMask;
543   mResendFlag |= RESEND_STENCIL_MASK;
544 }
545
546 void Renderer::SetStencilOperationOnFail(StencilOperation::Type stencilOperationOnFail)
547 {
548   mStencilParameters.stencilOperationOnFail = stencilOperationOnFail;
549   mResendFlag |= RESEND_STENCIL_OPERATION_ON_FAIL;
550 }
551
552 void Renderer::SetStencilOperationOnZFail(StencilOperation::Type stencilOperationOnZFail)
553 {
554   mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail;
555   mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_FAIL;
556 }
557
558 void Renderer::SetStencilOperationOnZPass(StencilOperation::Type stencilOperationOnZPass)
559 {
560   mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass;
561   mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_PASS;
562 }
563
564 void Renderer::SetRenderCallback(RenderCallback* callback)
565 {
566   mRenderCallback = callback;
567   mResendFlag |= RESEND_SET_RENDER_CALLBACK;
568   mDirtyFlag = true;
569 }
570
571 const Render::Renderer::StencilParameters& Renderer::GetStencilParameters() const
572 {
573   return mStencilParameters;
574 }
575
576 void Renderer::BakeOpacity(BufferIndex updateBufferIndex, float opacity)
577 {
578   mOpacity.Bake(updateBufferIndex, opacity);
579
580   mDirtyFlag = true;
581   SetUpdated(true);
582 }
583
584 float Renderer::GetOpacity(BufferIndex updateBufferIndex) const
585 {
586   return mOpacity[updateBufferIndex];
587 }
588
589 void Renderer::SetRenderingBehavior(DevelRenderer::Rendering::Type renderingBehavior)
590 {
591   mRenderingBehavior = renderingBehavior;
592   SetUpdated(true);
593 }
594
595 DevelRenderer::Rendering::Type Renderer::GetRenderingBehavior() const
596 {
597   return mRenderingBehavior;
598 }
599
600 // Called when SceneGraph::Renderer is added to update manager ( that happens when an "event-thread renderer" is created )
601 void Renderer::ConnectToSceneGraph(SceneController& sceneController, BufferIndex bufferIndex)
602 {
603   mRegenerateUniformMap = true;
604   mSceneController      = &sceneController;
605
606   mRenderer = Render::Renderer::NewKey(this, mGeometry, mBlendBitmask, GetBlendColor(), static_cast<FaceCullingMode::Type>(mFaceCullingMode), mPremultipledAlphaEnabled, mDepthWriteMode, mDepthTestMode, mDepthFunction, mStencilParameters);
607
608   mSceneController->GetRenderMessageDispatcher().AddRenderer(mRenderer);
609 }
610
611 // Called just before destroying the scene-graph renderer ( when the "event-thread renderer" is no longer referenced )
612 void Renderer::DisconnectFromSceneGraph(SceneController& sceneController, BufferIndex bufferIndex)
613 {
614   // Remove renderer from RenderManager
615   if(mRenderer)
616   {
617     mSceneController->GetRenderMessageDispatcher().RemoveRenderer(mRenderer);
618     mRenderer = Render::RendererKey{};
619   }
620   mSceneController = nullptr;
621 }
622
623 Render::RendererKey Renderer::GetRenderer()
624 {
625   return mRenderer;
626 }
627
628 Renderer::OpacityType Renderer::GetOpacityType(BufferIndex updateBufferIndex, const Node& node) const
629 {
630   Renderer::OpacityType opacityType = Renderer::OPAQUE;
631
632   if(node.IsTransparent())
633   {
634     return Renderer::TRANSPARENT;
635   }
636
637   switch(mBlendMode)
638   {
639     case BlendMode::ON_WITHOUT_CULL: // If the renderer should always be use blending and never want to be transparent by alpha.
640     {
641       opacityType = Renderer::TRANSLUCENT;
642       break;
643     }
644     case BlendMode::ON: // If the renderer should always be use blending
645     {
646       float alpha = node.GetWorldColor(updateBufferIndex).a * mOpacity[updateBufferIndex];
647       if(alpha <= FULLY_TRANSPARENT)
648       {
649         opacityType = Renderer::TRANSPARENT;
650       }
651       else
652       {
653         opacityType = Renderer::TRANSLUCENT;
654       }
655       break;
656     }
657     case BlendMode::AUTO:
658     {
659       if(BlendingOptions::IsAdvancedBlendEquationIncluded(mBlendBitmask))
660       {
661         opacityType = Renderer::TRANSLUCENT;
662         break;
663       }
664
665       bool shaderRequiresBlending(mShader->HintEnabled(Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT));
666       if(shaderRequiresBlending || (mTextureSet && mTextureSet->HasAlpha()))
667       {
668         opacityType = Renderer::TRANSLUCENT;
669       }
670
671       // renderer should determine opacity using the actor color
672       float alpha = node.GetWorldColor(updateBufferIndex).a * mOpacity[updateBufferIndex];
673       if(alpha <= FULLY_TRANSPARENT)
674       {
675         opacityType = Renderer::TRANSPARENT;
676       }
677       else if(alpha <= FULLY_OPAQUE)
678       {
679         opacityType = Renderer::TRANSLUCENT;
680       }
681
682       break;
683     }
684     case BlendMode::USE_ACTOR_OPACITY: // the renderer should never use blending
685     {
686       // renderer should determine opacity using the actor color
687       float alpha = node.GetWorldColor(updateBufferIndex).a;
688       if(alpha <= FULLY_TRANSPARENT)
689       {
690         opacityType = Renderer::TRANSPARENT;
691       }
692       else if(alpha < FULLY_OPAQUE)
693       {
694         opacityType = Renderer::TRANSLUCENT;
695       }
696       else
697       {
698         opacityType = Renderer::OPAQUE;
699       }
700       break;
701     }
702     case BlendMode::OFF: // the renderer should never use blending
703     default:
704     {
705       opacityType = Renderer::OPAQUE;
706       break;
707     }
708   }
709
710   return opacityType;
711 }
712
713 void Renderer::UpdateUniformMap(BufferIndex updateBufferIndex)
714 {
715   if(mRegenerateUniformMap)
716   {
717     CollectedUniformMap& localMap = mCollectedUniformMap;
718     localMap.Clear();
719
720     const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap();
721
722     auto size = rendererUniformMap.Count();
723     if(mShader)
724     {
725       size += mShader->GetUniformMap().Count();
726     }
727
728     localMap.Reserve(size);
729     localMap.AddMappings(rendererUniformMap);
730     if(mShader)
731     {
732       localMap.AddMappings(mShader->GetUniformMap());
733     }
734     localMap.UpdateChangeCounter();
735
736     mRegenerateUniformMap = false;
737     SetUpdated(true);
738   }
739 }
740
741 void Renderer::SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size)
742 {
743   mDrawCommands.clear();
744   mDrawCommands.insert(mDrawCommands.end(), pDrawCommands, pDrawCommands + size);
745   mResendFlag |= RESEND_DRAW_COMMANDS;
746 }
747
748 bool Renderer::IsDirty() const
749 {
750   // Check whether the opacity property has changed
751   return (mDirtyFlag || !mOpacity.IsClean());
752 }
753
754 void Renderer::ResetDirtyFlag()
755 {
756   mDirtyFlag = false;
757
758   SetUpdated(false);
759 }
760
761 uint32_t Renderer::GetMemoryPoolCapacity()
762 {
763   return GetRendererMemoryPool().GetCapacity();
764 }
765
766 void Renderer::OnMappingChanged()
767 {
768   // Properties have been registered on the base class.
769   mRegenerateUniformMap = true; // Should remain true until this renderer is added to a RenderList.
770 }
771
772 const CollectedUniformMap& Renderer::GetCollectedUniformMap() const
773 {
774   return mCollectedUniformMap;
775 }
776
777 bool Renderer::IsUpdated() const
778 {
779   if(Updated() || (mShader && mShader->Updated()))
780   {
781     return true;
782   }
783   return false;
784 }
785
786 Vector4 Renderer::GetVisualTransformedUpdateArea(BufferIndex updateBufferIndex, const Vector4& originalUpdateArea) noexcept
787 {
788   if(mVisualProperties)
789   {
790     auto& coefficient = mVisualProperties->mCoefficient;
791
792     // TODO : We may need to get some method that visual properties changed, without hash.
793     // Or, need to call this API in PreRender side.
794
795     uint64_t hash = 0xc70f6907UL;
796
797     hash = mVisualProperties->mTransformOffset.Hash(updateBufferIndex, hash);
798     hash = mVisualProperties->mTransformOffsetSizeMode.Hash(updateBufferIndex, hash);
799     hash = mVisualProperties->mTransformSize.Hash(updateBufferIndex, hash);
800     hash = mVisualProperties->mTransformOrigin.Hash(updateBufferIndex, hash);
801     hash = mVisualProperties->mTransformAnchorPoint.Hash(updateBufferIndex, hash);
802     hash = mVisualProperties->mExtraSize.Hash(updateBufferIndex, hash);
803
804     if(coefficient.hash != hash)
805     {
806       coefficient.hash = hash;
807
808       // VisualProperty
809       const Vector2 transformOffset         = mVisualProperties->mTransformOffset.Get(updateBufferIndex);
810       const Vector4 transformOffsetSizeMode = mVisualProperties->mTransformOffsetSizeMode.Get(updateBufferIndex);
811       const Vector2 transformSize           = mVisualProperties->mTransformSize.Get(updateBufferIndex);
812       const Vector2 transformOrigin         = mVisualProperties->mTransformOrigin.Get(updateBufferIndex);
813       const Vector2 transformAnchorPoint    = mVisualProperties->mTransformAnchorPoint.Get(updateBufferIndex);
814       const Vector2 extraSize               = mVisualProperties->mExtraSize.Get(updateBufferIndex);
815
816       DALI_LOG_INFO(gSceneGraphRendererLogFilter, Debug::Verbose, "transform size   %5.3f %5.3f\n", transformSize.x, transformSize.y);
817       DALI_LOG_INFO(gSceneGraphRendererLogFilter, Debug::Verbose, "transform offset %5.3f %5.3f\n", transformOffset.x, transformOffset.y);
818       DALI_LOG_INFO(gSceneGraphRendererLogFilter, Debug::Verbose, "transform origin %5.3f %5.3f\n", transformOrigin.x, transformOrigin.y);
819       DALI_LOG_INFO(gSceneGraphRendererLogFilter, Debug::Verbose, "transform anchor %5.3f %5.3f\n", transformAnchorPoint.x, transformAnchorPoint.y);
820       DALI_LOG_INFO(gSceneGraphRendererLogFilter, Debug::Verbose, "extra size       %5.3f %5.3f\n", extraSize.x, extraSize.y);
821
822       // const Vector2 visualSize = Vector2(Dali::Lerp(transformOffsetSizeMode.z, originalSize.x * transformSize.x, transformSize.x),
823       //                                    Dali::Lerp(transformOffsetSizeMode.w, originalSize.y * transformSize.y, transformSize.y)) +
824       //                            extraSize;
825       // const Vector2 visualOffset = Vector2(Dali::Lerp(transformOffsetSizeMode.x, originalSize.x * transformOffset.x, transformOffset.x),
826       //                                      Dali::Lerp(transformOffsetSizeMode.y, originalSize.y * transformOffset.y, transformOffset.y));
827
828       // const float decoratedBorderlineWidth = std::max((1.0f + Dali::Clamp(borderlineOffset, -1.0f, 1.0f)) * borderlineWidth, 2.0f * blurRadius);
829       // const Vector2 decoratedVisualSize    = visualSize + Vector2(decoratedBorderlineWidth, decoratedBorderlineWidth);
830
831       // Note : vertexPositoin.xy = aPosition * decoratedVisualSize
832       //                          + anchorPoint * visualSize
833       //                          + origin * uSize.xy
834       //                          + visualOffset;
835
836       // Calculate same logic of visual's vertex shader transform.
837       // minVertexPosition = -0.5f * decoratedVisualSize + transformAnchorPoint * visualSize + transformOrigin * originalSize.xy + visualOffset
838       // maxVertexPosition =  0.5f * decoratedVisualSize + transformAnchorPoint * visualSize + transformOrigin * originalSize.xy + visualOffset
839
840       // Update cached VisualTransformedUpdateSizeCoefficientCache
841
842       // Note : vertexPosition = (XA * aPosition + XB) * originalSize + (CA * aPosition + CB) + Vector2(D, D) * aPosition
843
844       // XA = transformSize * (1.0 - transformOffsetSizeMode.zw)
845       // XB = transformSize * (1.0 - transformOffsetSizeMode.zw) * transformAnchorPoint
846       //    + transformOffset * (1.0 - transformOffsetSizeMode.xy)
847       //    + transformOrigin
848       // CA = transformSize * transformOffsetSizeMode.zw + extraSize
849       // CB = (transformSize * transformOffsetSizeMode.zw + extraSize) * transformAnchorPoint
850       //    + transformOffset * transformOffsetSizeMode.xy
851       // D = max((1.0 + clamp(borderlineOffset, -1.0, 1.0)) * borderlineWidth, 2.0 * blurRadius)
852
853       coefficient.coefXA = transformSize * Vector2(1.0f - transformOffsetSizeMode.z, 1.0f - transformOffsetSizeMode.w);
854       coefficient.coefXB = coefficient.coefXA * transformAnchorPoint + transformOffset * Vector2(1.0f - transformOffsetSizeMode.x, 1.0f - transformOffsetSizeMode.y) + transformOrigin;
855       coefficient.coefCA = transformSize * Vector2(transformOffsetSizeMode.z, transformOffsetSizeMode.w) + extraSize;
856       coefficient.coefCB = coefficient.coefCA * transformAnchorPoint + transformOffset * Vector2(transformOffsetSizeMode.x, transformOffsetSizeMode.y);
857     }
858     if(mVisualProperties->mExtendedProperties)
859     {
860       const auto decoratedVisualProperties = static_cast<VisualRenderer::AnimatableDecoratedVisualProperties*>(mVisualProperties->mExtendedProperties);
861
862       uint64_t decoratedHash = 0xc70f6907UL;
863
864       decoratedHash = decoratedVisualProperties->mBorderlineWidth.Hash(updateBufferIndex, decoratedHash);
865       decoratedHash = decoratedVisualProperties->mBorderlineOffset.Hash(updateBufferIndex, decoratedHash);
866       decoratedHash = decoratedVisualProperties->mBlurRadius.Hash(updateBufferIndex, decoratedHash);
867
868       if(coefficient.decoratedHash != decoratedHash)
869       {
870         coefficient.decoratedHash = decoratedHash;
871
872         // DecoratedVisualProperty
873         const float borderlineWidth  = decoratedVisualProperties->mBorderlineWidth.Get(updateBufferIndex);
874         const float borderlineOffset = decoratedVisualProperties->mBorderlineOffset.Get(updateBufferIndex);
875         const float blurRadius       = decoratedVisualProperties->mBlurRadius.Get(updateBufferIndex);
876
877         DALI_LOG_INFO(gSceneGraphRendererLogFilter, Debug::Verbose, "borderline width  %5.3f\n", borderlineWidth);
878         DALI_LOG_INFO(gSceneGraphRendererLogFilter, Debug::Verbose, "borderline offset %5.3f\n", borderlineOffset);
879         DALI_LOG_INFO(gSceneGraphRendererLogFilter, Debug::Verbose, "blur radius       %5.3f\n", blurRadius);
880
881         // D coefficients be used only decoratedVisual.
882         // It can be calculated parallely with transform.
883
884         coefficient.coefD = std::max((1.0f + Dali::Clamp(borderlineOffset, -1.0f, 1.0f)) * borderlineWidth, 2.0f * blurRadius);
885       }
886     }
887
888     // Calculate vertex position by coefficient
889     // It will reduce the number of operations
890
891     // const Vector2 minVertexPosition = (XA * -0.5 + XB) * originalSize + (CA * -0.5 + CB) + Vector2(D, D) * -0.5;
892     // const Vector2 maxVertexPosition = (XA * +0.5 + XB) * originalSize + (CA * +0.5 + CB) + Vector2(D, D) * +0.5;
893
894     // When we set
895     // basicVertexPosition = XB * originalSize + CB
896     // scaleVertexPosition = XA * originalSize + CA + D
897
898     // --> minVertexPosition = basicVertexPosition + scaleVertexPosition * -0.5
899     //     maxVertexPosition = basicVertexPosition + scaleVertexPosition * +0.5
900
901     // Then, resultSize = 2.0f * max(-minVertexPosition, maxVertexPosition);
902     //                  = 2.0f * max(scaleVertexPosition * 0.5 - basicVertexPosition, scaleVertexPosition * 0.5 + basicVertexPosition)
903     //                  = scaleVertexPosition + 2.0f * abs(basicVertexPosition)
904     // Cause transform matrix will think center of vertex is (0, 0)
905
906     const Vector2 originalXY = Vector2(originalUpdateArea.x, originalUpdateArea.y);
907     const Vector2 originalWH = Vector2(originalUpdateArea.z, originalUpdateArea.w);
908
909     const Vector2 basicVertexPosition = coefficient.coefXB * originalWH + coefficient.coefCB;
910     const Vector2 scaleVertexPosition = coefficient.coefXA * originalWH + coefficient.coefCA;
911
912     // TODO : We need to re-generate coefficient to consitder area width/height
913     const Vector4 resultArea = Vector4(originalXY.x,
914                                        originalXY.y,
915                                        scaleVertexPosition.x + 2.0f * abs(basicVertexPosition.x) + coefficient.coefD,
916                                        scaleVertexPosition.y + 2.0f * abs(basicVertexPosition.y) + coefficient.coefD);
917
918     DALI_LOG_INFO(gSceneGraphRendererLogFilter, Debug::Verbose, "%f %f %f %f--> %f %f %f %f\n", originalUpdateArea.x, originalUpdateArea.y, originalUpdateArea.z, originalUpdateArea.w, resultArea.x, resultArea.y, resultArea.z, resultArea.w);
919
920     return resultArea;
921   }
922   return originalUpdateArea;
923 }
924
925 } // namespace SceneGraph
926 } // namespace Internal
927 } // namespace Dali