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