Merge branch 'devel/master' into tizen
[platform/core/uifw/dali-core.git] / dali / internal / update / rendering / scene-graph-renderer.cpp
1 /*
2  * Copyright (c) 2021 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/queue/render-queue.h>
26 #include <dali/internal/render/renderers/render-geometry.h>
27 #include <dali/internal/render/shaders/program.h>
28 #include <dali/internal/render/shaders/render-shader.h>
29 #include <dali/internal/update/controllers/render-message-dispatcher.h>
30 #include <dali/internal/update/controllers/scene-controller.h>
31 #include <dali/internal/update/nodes/node.h>
32 #include <dali/internal/update/rendering/scene-graph-texture-set.h>
33
34 namespace Dali
35 {
36 namespace Internal
37 {
38 namespace SceneGraph
39 {
40 namespace // unnamed namespace
41 {
42 const uint32_t UNIFORM_MAP_READY      = 0;
43 const uint32_t COPY_UNIFORM_MAP       = 1;
44 const uint32_t REGENERATE_UNIFORM_MAP = 2;
45
46 //Memory pool used to allocate new renderers. Memory used by this pool will be released when shutting down DALi
47 MemoryPoolObjectAllocator<Renderer> gRendererMemoryPool;
48
49 void AddMappings(CollectedUniformMap& localMap, const UniformMap& uniformMap)
50 {
51   // Iterate thru uniformMap.
52   // Any maps that aren't in localMap should be added in a single step
53
54   // keep a static vector to avoid temporary heap allocation.
55   // As this function gets called only from update thread we don't have to
56   // make it thread safe (so no need to keep a thread_local variable).
57   static CollectedUniformMap newUniformMappings;
58
59   newUniformMappings.Clear();
60
61   for(UniformMap::SizeType i = 0, count = uniformMap.Count(); i < count; ++i)
62   {
63     bool found = false;
64
65     for(CollectedUniformMap::Iterator iter = localMap.Begin(); iter != localMap.End(); ++iter)
66     {
67       const UniformPropertyMapping& map = (*iter);
68       if(map.uniformName == uniformMap[i].uniformName)
69       {
70         found = true;
71         break;
72       }
73     }
74     if(!found)
75     {
76       newUniformMappings.PushBack(uniformMap[i]);
77     }
78   }
79
80   if(newUniformMappings.Count() > 0)
81   {
82     localMap.Reserve(localMap.Count() + newUniformMappings.Count());
83
84     for(CollectedUniformMap::Iterator iter = newUniformMappings.Begin(),
85                                       end  = newUniformMappings.End();
86         iter != end;
87         ++iter)
88     {
89       const UniformPropertyMapping& map = (*iter);
90       localMap.PushBack(map);
91     }
92   }
93 }
94
95 // Flags for re-sending data to renderer.
96 enum Flags
97 {
98   RESEND_GEOMETRY                    = 1 << 0,
99   RESEND_FACE_CULLING_MODE           = 1 << 1,
100   RESEND_BLEND_COLOR                 = 1 << 2,
101   RESEND_BLEND_BIT_MASK              = 1 << 3,
102   RESEND_PREMULTIPLIED_ALPHA         = 1 << 4,
103   RESEND_INDEXED_DRAW_FIRST_ELEMENT  = 1 << 5,
104   RESEND_INDEXED_DRAW_ELEMENTS_COUNT = 1 << 6,
105   RESEND_DEPTH_WRITE_MODE            = 1 << 7,
106   RESEND_DEPTH_TEST_MODE             = 1 << 8,
107   RESEND_DEPTH_FUNCTION              = 1 << 9,
108   RESEND_RENDER_MODE                 = 1 << 10,
109   RESEND_STENCIL_FUNCTION            = 1 << 11,
110   RESEND_STENCIL_FUNCTION_MASK       = 1 << 12,
111   RESEND_STENCIL_FUNCTION_REFERENCE  = 1 << 13,
112   RESEND_STENCIL_MASK                = 1 << 14,
113   RESEND_STENCIL_OPERATION_ON_FAIL   = 1 << 15,
114   RESEND_STENCIL_OPERATION_ON_Z_FAIL = 1 << 16,
115   RESEND_STENCIL_OPERATION_ON_Z_PASS = 1 << 17,
116   RESEND_WRITE_TO_COLOR_BUFFER       = 1 << 18,
117   RESEND_SHADER                      = 1 << 19,
118   RESEND_DRAW_COMMANDS               = 1 << 20
119 };
120
121 } // Anonymous namespace
122
123 Renderer* Renderer::New()
124 {
125   return new(gRendererMemoryPool.AllocateRawThreadSafe()) Renderer();
126 }
127
128 Renderer::Renderer()
129 : mSceneController(nullptr),
130   mRenderer(nullptr),
131   mTextureSet(nullptr),
132   mGeometry(nullptr),
133   mShader(nullptr),
134   mRenderDataProvider(nullptr),
135   mBlendColor(nullptr),
136   mStencilParameters(RenderMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP),
137   mIndexedDrawFirstElement(0u),
138   mIndexedDrawElementsCount(0u),
139   mBlendBitmask(0u),
140   mRegenerateUniformMap(0u),
141   mResendFlag(0u),
142   mDepthFunction(DepthFunction::LESS),
143   mFaceCullingMode(FaceCullingMode::NONE),
144   mBlendMode(BlendMode::AUTO),
145   mDepthWriteMode(DepthWriteMode::AUTO),
146   mDepthTestMode(DepthTestMode::AUTO),
147   mRenderingBehavior(DevelRenderer::Rendering::IF_REQUIRED),
148   mPremultipledAlphaEnabled(false),
149   mOpacity(1.0f),
150   mDepthIndex(0)
151 {
152   mUniformMapChanged[0] = false;
153   mUniformMapChanged[1] = false;
154
155   // Observe our own PropertyOwner's uniform map
156   AddUniformMapObserver(*this);
157 }
158
159 Renderer::~Renderer()
160 {
161   if(mTextureSet)
162   {
163     mTextureSet->RemoveObserver(this);
164     mTextureSet = nullptr;
165   }
166   if(mShader)
167   {
168     mShader->RemoveConnectionObserver(*this);
169     mShader = nullptr;
170   }
171 }
172
173 void Renderer::operator delete(void* ptr)
174 {
175   gRendererMemoryPool.FreeThreadSafe(static_cast<Renderer*>(ptr));
176 }
177
178 bool Renderer::PrepareRender(BufferIndex updateBufferIndex)
179 {
180   switch(mRegenerateUniformMap)
181   {
182     case UNIFORM_MAP_READY: // Now, only set to zero on start and by render side
183     {
184       mUniformMapChanged[updateBufferIndex] = false;
185       break;
186     }
187     case REGENERATE_UNIFORM_MAP:
188     {
189       CollectedUniformMap& localMap = mCollectedUniformMap[updateBufferIndex];
190       localMap.Clear();
191
192       const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap();
193
194       auto size = rendererUniformMap.Count();
195       if(mShader)
196       {
197         size += mShader->GetUniformMap().Count();
198       }
199
200       localMap.Reserve(size);
201
202       AddMappings(localMap, rendererUniformMap);
203
204       if(mShader)
205       {
206         AddMappings(localMap, mShader->GetUniformMap());
207       }
208       mUniformMapChanged[updateBufferIndex] = true;
209       break;
210     }
211     case COPY_UNIFORM_MAP:
212     {
213       // Copy old map into current map
214       CollectedUniformMap& localMap = mCollectedUniformMap[updateBufferIndex];
215       CollectedUniformMap& oldMap   = mCollectedUniformMap[1 - updateBufferIndex];
216
217       localMap.Resize(oldMap.Count());
218
219       uint32_t index = 0;
220       for(CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End(); iter != end; ++iter, ++index)
221       {
222         localMap[index] = *iter;
223       }
224       mUniformMapChanged[updateBufferIndex] = true;
225       break;
226     }
227   }
228
229   bool rendererUpdated = mUniformMapChanged[updateBufferIndex] || mResendFlag || mRenderingBehavior == DevelRenderer::Rendering::CONTINUOUSLY;
230
231   if(mResendFlag != 0)
232   {
233     if(mResendFlag & RESEND_GEOMETRY)
234     {
235       typedef MessageValue1<Render::Renderer, Render::Geometry*> DerivedType;
236       uint32_t*                                                  slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
237       new(slot) DerivedType(mRenderer, &Render::Renderer::SetGeometry, mGeometry);
238     }
239
240     if(mResendFlag & RESEND_DRAW_COMMANDS)
241     {
242       using DerivedType = MessageValue2<Render::Renderer, Dali::DevelRenderer::DrawCommand*, uint32_t>;
243       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
244       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDrawCommands, mDrawCommands.data(), mDrawCommands.size());
245     }
246
247     if(mResendFlag & RESEND_FACE_CULLING_MODE)
248     {
249       using DerivedType = MessageValue1<Render::Renderer, FaceCullingMode::Type>;
250       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
251       new(slot) DerivedType(mRenderer, &Render::Renderer::SetFaceCullingMode, mFaceCullingMode);
252     }
253
254     if(mResendFlag & RESEND_BLEND_BIT_MASK)
255     {
256       using DerivedType = MessageValue1<Render::Renderer, uint32_t>;
257       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
258       new(slot) DerivedType(mRenderer, &Render::Renderer::SetBlendingBitMask, mBlendBitmask);
259     }
260
261     if(mResendFlag & RESEND_BLEND_COLOR)
262     {
263       using DerivedType = MessageValue1<Render::Renderer, Vector4>;
264       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
265       new(slot) DerivedType(mRenderer, &Render::Renderer::SetBlendColor, GetBlendColor());
266     }
267
268     if(mResendFlag & RESEND_PREMULTIPLIED_ALPHA)
269     {
270       using DerivedType = MessageValue1<Render::Renderer, bool>;
271       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
272       new(slot) DerivedType(mRenderer, &Render::Renderer::EnablePreMultipliedAlpha, mPremultipledAlphaEnabled);
273     }
274
275     if(mResendFlag & RESEND_INDEXED_DRAW_FIRST_ELEMENT)
276     {
277       using DerivedType = MessageValue1<Render::Renderer, uint32_t>;
278       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
279       new(slot) DerivedType(mRenderer, &Render::Renderer::SetIndexedDrawFirstElement, mIndexedDrawFirstElement);
280     }
281
282     if(mResendFlag & RESEND_INDEXED_DRAW_ELEMENTS_COUNT)
283     {
284       using DerivedType = MessageValue1<Render::Renderer, uint32_t>;
285       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
286       new(slot) DerivedType(mRenderer, &Render::Renderer::SetIndexedDrawElementsCount, mIndexedDrawElementsCount);
287     }
288
289     if(mResendFlag & RESEND_DEPTH_WRITE_MODE)
290     {
291       using DerivedType = MessageValue1<Render::Renderer, DepthWriteMode::Type>;
292       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
293       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthWriteMode, mDepthWriteMode);
294     }
295
296     if(mResendFlag & RESEND_DEPTH_TEST_MODE)
297     {
298       using DerivedType = MessageValue1<Render::Renderer, DepthTestMode::Type>;
299       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
300       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthTestMode, mDepthTestMode);
301     }
302
303     if(mResendFlag & RESEND_DEPTH_FUNCTION)
304     {
305       using DerivedType = MessageValue1<Render::Renderer, DepthFunction::Type>;
306       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
307       new(slot) DerivedType(mRenderer, &Render::Renderer::SetDepthFunction, mDepthFunction);
308     }
309
310     if(mResendFlag & RESEND_RENDER_MODE)
311     {
312       using DerivedType = MessageValue1<Render::Renderer, RenderMode::Type>;
313       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
314       new(slot) DerivedType(mRenderer, &Render::Renderer::SetRenderMode, mStencilParameters.renderMode);
315     }
316
317     if(mResendFlag & RESEND_STENCIL_FUNCTION)
318     {
319       using DerivedType = MessageValue1<Render::Renderer, StencilFunction::Type>;
320       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
321       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilFunction, mStencilParameters.stencilFunction);
322     }
323
324     if(mResendFlag & RESEND_STENCIL_FUNCTION_MASK)
325     {
326       using DerivedType = MessageValue1<Render::Renderer, int>;
327       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
328       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilFunctionMask, mStencilParameters.stencilFunctionMask);
329     }
330
331     if(mResendFlag & RESEND_STENCIL_FUNCTION_REFERENCE)
332     {
333       using DerivedType = MessageValue1<Render::Renderer, int>;
334       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
335       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilFunctionReference, mStencilParameters.stencilFunctionReference);
336     }
337
338     if(mResendFlag & RESEND_STENCIL_MASK)
339     {
340       using DerivedType = MessageValue1<Render::Renderer, int>;
341       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
342       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilMask, mStencilParameters.stencilMask);
343     }
344
345     if(mResendFlag & RESEND_STENCIL_OPERATION_ON_FAIL)
346     {
347       using DerivedType = MessageValue1<Render::Renderer, StencilOperation::Type>;
348       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
349       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnFail, mStencilParameters.stencilOperationOnFail);
350     }
351
352     if(mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_FAIL)
353     {
354       using DerivedType = MessageValue1<Render::Renderer, StencilOperation::Type>;
355       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
356       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnZFail, mStencilParameters.stencilOperationOnZFail);
357     }
358
359     if(mResendFlag & RESEND_STENCIL_OPERATION_ON_Z_PASS)
360     {
361       using DerivedType = MessageValue1<Render::Renderer, StencilOperation::Type>;
362       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
363       new(slot) DerivedType(mRenderer, &Render::Renderer::SetStencilOperationOnZPass, mStencilParameters.stencilOperationOnZPass);
364     }
365
366     if(mResendFlag & RESEND_SHADER)
367     {
368       using DerivedType = MessageValue1<Render::Renderer, bool>;
369       uint32_t* slot    = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
370       new(slot) DerivedType(mRenderer, &Render::Renderer::SetShaderChanged, true);
371     }
372
373     mResendFlag = 0;
374   }
375
376   return rendererUpdated;
377 }
378
379 void Renderer::AgeUniformMap()
380 {
381   if(mRegenerateUniformMap > 0)
382   {
383     mRegenerateUniformMap--;
384   }
385 }
386
387 void Renderer::SetTextures(TextureSet* textureSet)
388 {
389   DALI_ASSERT_DEBUG(textureSet != NULL && "Texture set pointer is NULL");
390
391   if(mTextureSet)
392   {
393     mTextureSet->RemoveObserver(this);
394   }
395
396   mTextureSet = textureSet;
397   mTextureSet->AddObserver(this);
398   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
399
400   UpdateTextureSet();
401 }
402
403 void Renderer::SetShader(Shader* shader)
404 {
405   DALI_ASSERT_DEBUG(shader != NULL && "Shader pointer is NULL");
406
407   if(mShader)
408   {
409     mShader->RemoveConnectionObserver(*this);
410   }
411
412   mShader = shader;
413   mShader->AddConnectionObserver(*this);
414   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
415   mResendFlag |= RESEND_GEOMETRY | RESEND_SHADER;
416
417   if(mRenderDataProvider)
418   {
419     mRenderDataProvider->mShader = mShader;
420   }
421 }
422
423 void Renderer::SetGeometry(Render::Geometry* geometry)
424 {
425   DALI_ASSERT_DEBUG(geometry != NULL && "Geometry pointer is NULL");
426   mGeometry = geometry;
427
428   if(mRenderer)
429   {
430     mResendFlag |= RESEND_GEOMETRY;
431   }
432 }
433
434 void Renderer::SetDepthIndex(int depthIndex)
435 {
436   mDepthIndex = depthIndex;
437 }
438
439 void Renderer::SetFaceCullingMode(FaceCullingMode::Type faceCullingMode)
440 {
441   mFaceCullingMode = faceCullingMode;
442   mResendFlag |= RESEND_FACE_CULLING_MODE;
443 }
444
445 FaceCullingMode::Type Renderer::GetFaceCullingMode() const
446 {
447   return mFaceCullingMode;
448 }
449
450 void Renderer::SetBlendMode(BlendMode::Type blendingMode)
451 {
452   mBlendMode = blendingMode;
453 }
454
455 BlendMode::Type Renderer::GetBlendMode() const
456 {
457   return mBlendMode;
458 }
459
460 void Renderer::SetBlendingOptions(uint32_t options)
461 {
462   if(mBlendBitmask != options)
463   {
464     mBlendBitmask = options;
465     mResendFlag |= RESEND_BLEND_BIT_MASK;
466   }
467 }
468
469 uint32_t Renderer::GetBlendingOptions() const
470 {
471   return mBlendBitmask;
472 }
473
474 void Renderer::SetBlendColor(const Vector4& blendColor)
475 {
476   if(blendColor == Color::TRANSPARENT)
477   {
478     mBlendColor = nullptr;
479   }
480   else
481   {
482     if(!mBlendColor)
483     {
484       mBlendColor = new Vector4(blendColor);
485     }
486     else
487     {
488       *mBlendColor = blendColor;
489     }
490   }
491
492   mResendFlag |= RESEND_BLEND_COLOR;
493 }
494
495 Vector4 Renderer::GetBlendColor() const
496 {
497   if(mBlendColor)
498   {
499     return *mBlendColor;
500   }
501   return Color::TRANSPARENT;
502 }
503
504 void Renderer::SetIndexedDrawFirstElement(uint32_t firstElement)
505 {
506   mIndexedDrawFirstElement = firstElement;
507   mResendFlag |= RESEND_INDEXED_DRAW_FIRST_ELEMENT;
508 }
509
510 uint32_t Renderer::GetIndexedDrawFirstElement() const
511 {
512   return mIndexedDrawFirstElement;
513 }
514
515 void Renderer::SetIndexedDrawElementsCount(uint32_t elementsCount)
516 {
517   mIndexedDrawElementsCount = elementsCount;
518   mResendFlag |= RESEND_INDEXED_DRAW_ELEMENTS_COUNT;
519 }
520
521 uint32_t Renderer::GetIndexedDrawElementsCount() const
522 {
523   return mIndexedDrawElementsCount;
524 }
525
526 void Renderer::EnablePreMultipliedAlpha(bool preMultipled)
527 {
528   mPremultipledAlphaEnabled = preMultipled;
529   mResendFlag |= RESEND_PREMULTIPLIED_ALPHA;
530 }
531
532 bool Renderer::IsPreMultipliedAlphaEnabled() const
533 {
534   return mPremultipledAlphaEnabled;
535 }
536
537 void Renderer::SetDepthWriteMode(DepthWriteMode::Type depthWriteMode)
538 {
539   mDepthWriteMode = depthWriteMode;
540   mResendFlag |= RESEND_DEPTH_WRITE_MODE;
541 }
542
543 DepthWriteMode::Type Renderer::GetDepthWriteMode() const
544 {
545   return mDepthWriteMode;
546 }
547
548 void Renderer::SetDepthTestMode(DepthTestMode::Type depthTestMode)
549 {
550   mDepthTestMode = depthTestMode;
551   mResendFlag |= RESEND_DEPTH_TEST_MODE;
552 }
553
554 DepthTestMode::Type Renderer::GetDepthTestMode() const
555 {
556   return mDepthTestMode;
557 }
558
559 void Renderer::SetDepthFunction(DepthFunction::Type depthFunction)
560 {
561   mDepthFunction = depthFunction;
562   mResendFlag |= RESEND_DEPTH_FUNCTION;
563 }
564
565 DepthFunction::Type Renderer::GetDepthFunction() const
566 {
567   return mDepthFunction;
568 }
569
570 void Renderer::SetRenderMode(RenderMode::Type mode)
571 {
572   mStencilParameters.renderMode = mode;
573   mResendFlag |= RESEND_RENDER_MODE;
574 }
575
576 void Renderer::SetStencilFunction(StencilFunction::Type stencilFunction)
577 {
578   mStencilParameters.stencilFunction = stencilFunction;
579   mResendFlag |= RESEND_STENCIL_FUNCTION;
580 }
581
582 void Renderer::SetStencilFunctionMask(int stencilFunctionMask)
583 {
584   mStencilParameters.stencilFunctionMask = stencilFunctionMask;
585   mResendFlag |= RESEND_STENCIL_FUNCTION_MASK;
586 }
587
588 void Renderer::SetStencilFunctionReference(int stencilFunctionReference)
589 {
590   mStencilParameters.stencilFunctionReference = stencilFunctionReference;
591   mResendFlag |= RESEND_STENCIL_FUNCTION_REFERENCE;
592 }
593
594 void Renderer::SetStencilMask(int stencilMask)
595 {
596   mStencilParameters.stencilMask = stencilMask;
597   mResendFlag |= RESEND_STENCIL_MASK;
598 }
599
600 void Renderer::SetStencilOperationOnFail(StencilOperation::Type stencilOperationOnFail)
601 {
602   mStencilParameters.stencilOperationOnFail = stencilOperationOnFail;
603   mResendFlag |= RESEND_STENCIL_OPERATION_ON_FAIL;
604 }
605
606 void Renderer::SetStencilOperationOnZFail(StencilOperation::Type stencilOperationOnZFail)
607 {
608   mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail;
609   mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_FAIL;
610 }
611
612 void Renderer::SetStencilOperationOnZPass(StencilOperation::Type stencilOperationOnZPass)
613 {
614   mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass;
615   mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_PASS;
616 }
617
618 const Render::Renderer::StencilParameters& Renderer::GetStencilParameters() const
619 {
620   return mStencilParameters;
621 }
622
623 void Renderer::BakeOpacity(BufferIndex updateBufferIndex, float opacity)
624 {
625   mOpacity.Bake(updateBufferIndex, opacity);
626 }
627
628 float Renderer::GetOpacity(BufferIndex updateBufferIndex) const
629 {
630   return mOpacity[updateBufferIndex];
631 }
632
633 void Renderer::SetRenderingBehavior(DevelRenderer::Rendering::Type renderingBehavior)
634 {
635   mRenderingBehavior = renderingBehavior;
636 }
637
638 DevelRenderer::Rendering::Type Renderer::GetRenderingBehavior() const
639 {
640   return mRenderingBehavior;
641 }
642
643 //Called when SceneGraph::Renderer is added to update manager ( that happens when an "event-thread renderer" is created )
644 void Renderer::ConnectToSceneGraph(SceneController& sceneController, BufferIndex bufferIndex)
645 {
646   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
647   mSceneController      = &sceneController;
648
649   mRenderDataProvider                          = new RenderDataProvider(mOpacity);
650   mRenderDataProvider->mUniformMapDataProvider = this;
651
652   mRenderer = Render::Renderer::New(mRenderDataProvider, mGeometry, mBlendBitmask, GetBlendColor(), static_cast<FaceCullingMode::Type>(mFaceCullingMode), mPremultipledAlphaEnabled, mDepthWriteMode, mDepthTestMode, mDepthFunction, mStencilParameters);
653
654   OwnerPointer<Render::Renderer> transferOwnership(mRenderer);
655   mSceneController->GetRenderMessageDispatcher().AddRenderer(transferOwnership);
656 }
657
658 //Called just before destroying the scene-graph renderer ( when the "event-thread renderer" is no longer referenced )
659 void Renderer::DisconnectFromSceneGraph(SceneController& sceneController, BufferIndex bufferIndex)
660 {
661   //Remove renderer from RenderManager
662   if(mRenderer)
663   {
664     mSceneController->GetRenderMessageDispatcher().RemoveRenderer(*mRenderer);
665     mRenderer = nullptr;
666   }
667   mSceneController    = nullptr;
668   mRenderDataProvider = nullptr;
669 }
670
671 void Renderer::UpdateTextureSet()
672 {
673   if(mRenderDataProvider)
674   {
675     if(mTextureSet)
676     {
677       uint32_t textureCount = mTextureSet->GetTextureCount();
678       mRenderDataProvider->mTextures.resize(textureCount);
679       mRenderDataProvider->mSamplers.resize(textureCount);
680       for(uint32_t i = 0; i < textureCount; ++i)
681       {
682         mRenderDataProvider->mTextures[i] = mTextureSet->GetTexture(i);
683         mRenderDataProvider->mSamplers[i] = mTextureSet->GetTextureSampler(i);
684       }
685     }
686     else
687     {
688       mRenderDataProvider->mTextures.clear();
689       mRenderDataProvider->mSamplers.clear();
690     }
691   }
692 }
693
694 Render::Renderer& Renderer::GetRenderer()
695 {
696   return *mRenderer;
697 }
698
699 const CollectedUniformMap& Renderer::GetUniformMap(BufferIndex bufferIndex) const
700 {
701   return mCollectedUniformMap[bufferIndex];
702 }
703
704 Renderer::OpacityType Renderer::GetOpacityType(BufferIndex updateBufferIndex, const Node& node) const
705 {
706   Renderer::OpacityType opacityType = Renderer::OPAQUE;
707
708   if(node.IsTransparent())
709   {
710     return Renderer::TRANSPARENT;
711   }
712
713   switch(mBlendMode)
714   {
715     case BlendMode::ON: // If the renderer should always be use blending
716     {
717       float alpha = node.GetWorldColor(updateBufferIndex).a * mOpacity[updateBufferIndex];
718       if(alpha <= FULLY_TRANSPARENT)
719       {
720         opacityType = Renderer::TRANSPARENT;
721       }
722       else
723       {
724         opacityType = Renderer::TRANSLUCENT;
725       }
726       break;
727     }
728     case BlendMode::AUTO:
729     {
730       if(BlendingOptions::IsAdvancedBlendEquationIncluded(mBlendBitmask))
731       {
732         opacityType = Renderer::TRANSLUCENT;
733         break;
734       }
735
736       bool shaderRequiresBlending(mShader->HintEnabled(Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT));
737       if(shaderRequiresBlending || (mTextureSet && mTextureSet->HasAlpha()))
738       {
739         opacityType = Renderer::TRANSLUCENT;
740       }
741
742       // renderer should determine opacity using the actor color
743       float alpha = node.GetWorldColor(updateBufferIndex).a * mOpacity[updateBufferIndex];
744       if(alpha <= FULLY_TRANSPARENT)
745       {
746         opacityType = Renderer::TRANSPARENT;
747       }
748       else if(alpha <= FULLY_OPAQUE)
749       {
750         opacityType = Renderer::TRANSLUCENT;
751       }
752
753       break;
754     }
755     case BlendMode::OFF: // the renderer should never use blending
756     default:
757     {
758       opacityType = Renderer::OPAQUE;
759       break;
760     }
761   }
762
763   return opacityType;
764 }
765
766 void Renderer::TextureSetChanged()
767 {
768   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
769
770   UpdateTextureSet();
771 }
772
773 void Renderer::TextureSetDeleted()
774 {
775   mTextureSet = nullptr;
776
777   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
778
779   UpdateTextureSet();
780 }
781
782 void Renderer::ConnectionsChanged(PropertyOwner& object)
783 {
784   // One of our child objects has changed it's connections. Ensure the uniform
785   // map gets regenerated during PrepareRender
786   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
787 }
788
789 void Renderer::ConnectedUniformMapChanged()
790 {
791   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
792 }
793
794 void Renderer::UniformMappingsChanged(const UniformMap& mappings)
795 {
796   // The mappings are either from PropertyOwner base class, or the Actor
797   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
798 }
799
800 void Renderer::ObservedObjectDestroyed(PropertyOwner& owner)
801 {
802   if(reinterpret_cast<PropertyOwner*>(mShader) == &owner)
803   {
804     mShader = nullptr;
805   }
806 }
807
808 void Renderer::SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size)
809 {
810   mDrawCommands.clear();
811   mDrawCommands.insert(mDrawCommands.end(), pDrawCommands, pDrawCommands + size);
812   mResendFlag |= RESEND_DRAW_COMMANDS;
813 }
814
815 } // namespace SceneGraph
816 } // namespace Internal
817 } // namespace Dali