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