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