Removing rendering backend
[platform/core/uifw/dali-core.git] / dali / internal / update / rendering / scene-graph-renderer.cpp
1 /*
2  * Copyright (c) 2018 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 #pragma GCC diagnostic push
18 #pragma GCC diagnostic ignored "-Wunused-variable"
19 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
20 #pragma GCC diagnostic ignored "-Wunused-function"
21
22 // CLASS HEADER
23 #include "scene-graph-renderer.h"
24
25 // INTERNAL INCLUDES
26 #include <dali/internal/common/internal-constants.h>
27 #include <dali/internal/common/memory-pool-object-allocator.h>
28 #include <dali/internal/update/nodes/node.h>
29 #include <dali/internal/update/rendering/data-providers/node-data-provider.h>
30 #include <dali/internal/update/rendering/scene-graph-geometry.h>
31 #include <dali/internal/update/rendering/scene-graph-property-buffer.h>
32 #include <dali/internal/update/rendering/scene-graph-texture-set.h>
33 #include <dali/internal/update/rendering/scene-graph-shader.h>
34
35 #include <dali/graphics-api/graphics-api-controller.h>
36 #include <dali/graphics-api/graphics-api-render-command.h>
37 #include <dali/graphics-api/graphics-api-shader.h>
38 #include <dali/graphics-api/graphics-api-shader-details.h>
39
40 #include <cstring>
41
42
43 namespace
44 {
45
46 /**
47  * Helper to set view and projection matrices once per program
48  * @param program to set the matrices to
49  * @param modelMatrix to set
50  * @param viewMatrix to set
51  * @param projectionMatrix to set
52  * @param modelViewMatrix to set
53  * @param modelViewProjectionMatrix to set
54  */
55 inline void SetMatrices(
56                          const Dali::Matrix& modelMatrix,
57                          const Dali::Matrix& viewMatrix,
58                          const Dali::Matrix& projectionMatrix,
59                          const Dali::Matrix& modelViewMatrix )
60 {
61
62 }
63
64 }
65
66 namespace // unnamed namespace
67 {
68
69 const unsigned int UNIFORM_MAP_READY      = 0;
70 const unsigned int COPY_UNIFORM_MAP       = 1;
71 const unsigned int REGENERATE_UNIFORM_MAP = 2;
72
73 //Memory pool used to allocate new renderers. Memory used by this pool will be released when shutting down DALi
74 Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::Renderer> gRendererMemoryPool;
75
76 void AddMappings( Dali::Internal::SceneGraph::CollectedUniformMap& localMap, const Dali::Internal::SceneGraph::UniformMap& uniformMap )
77 {
78   // Iterate thru uniformMap.
79   //   Any maps that aren't in localMap should be added in a single step
80   Dali::Internal::SceneGraph::CollectedUniformMap newUniformMappings;
81
82   for( unsigned int i=0, count=uniformMap.Count(); i<count; ++i )
83   {
84     Dali::Internal::SceneGraph::UniformPropertyMapping::Hash nameHash = uniformMap[i].uniformNameHash;
85     bool found = false;
86
87     for( Dali::Internal::SceneGraph::CollectedUniformMap::Iterator iter = localMap.Begin() ; iter != localMap.End() ; ++iter )
88     {
89       const Dali::Internal::SceneGraph::UniformPropertyMapping* map = (*iter);
90       if( map->uniformNameHash == nameHash )
91       {
92         if( map->uniformName == uniformMap[i].uniformName )
93         {
94           found = true;
95           break;
96         }
97       }
98     }
99     if( !found )
100     {
101       // it's a new mapping. Add raw ptr to temporary list
102       newUniformMappings.PushBack( &uniformMap[i] );
103     }
104   }
105
106   if( newUniformMappings.Count() > 0 )
107   {
108     localMap.Reserve( localMap.Count() + newUniformMappings.Count() );
109
110     for( Dali::Internal::SceneGraph::CollectedUniformMap::Iterator iter = newUniformMappings.Begin(),
111            end = newUniformMappings.End() ;
112          iter != end ;
113          ++iter )
114     {
115       const Dali::Internal::SceneGraph::UniformPropertyMapping* map = (*iter);
116       localMap.PushBack( map );
117     }
118   }
119 }
120
121 // Flags for re-sending data to renderer.
122 enum Flags
123 {
124   RESEND_DATA_PROVIDER               = 1 << 0,
125   RESEND_GEOMETRY                    = 1 << 1,
126   RESEND_FACE_CULLING_MODE           = 1 << 2,
127   RESEND_BLEND_COLOR                 = 1 << 3,
128   RESEND_BLEND_BIT_MASK              = 1 << 4,
129   RESEND_PREMULTIPLIED_ALPHA         = 1 << 5,
130   RESEND_INDEXED_DRAW_FIRST_ELEMENT  = 1 << 6,
131   RESEND_INDEXED_DRAW_ELEMENTS_COUNT = 1 << 7,
132   RESEND_DEPTH_WRITE_MODE            = 1 << 8,
133   RESEND_DEPTH_TEST_MODE             = 1 << 9,
134   RESEND_DEPTH_FUNCTION              = 1 << 10,
135   RESEND_RENDER_MODE                 = 1 << 11,
136   RESEND_STENCIL_FUNCTION            = 1 << 12,
137   RESEND_STENCIL_FUNCTION_MASK       = 1 << 13,
138   RESEND_STENCIL_FUNCTION_REFERENCE  = 1 << 14,
139   RESEND_STENCIL_MASK                = 1 << 15,
140   RESEND_STENCIL_OPERATION_ON_FAIL   = 1 << 16,
141   RESEND_STENCIL_OPERATION_ON_Z_FAIL = 1 << 17,
142   RESEND_STENCIL_OPERATION_ON_Z_PASS = 1 << 18,
143   RESEND_WRITE_TO_COLOR_BUFFER       = 1 << 19,
144 };
145
146 } // Anonymous namespace
147
148 namespace Dali
149 {
150 namespace Internal
151 {
152 namespace SceneGraph
153 {
154
155 Renderer* Renderer::New()
156 {
157   return new ( gRendererMemoryPool.AllocateRawThreadSafe() ) Renderer();
158 }
159
160 Renderer::Renderer()
161 : mRenderDataProvider(),
162   mTextureSet( NULL ),
163   mGeometry( NULL ),
164   mShader( NULL ),
165   mBlendColor( NULL ),
166   mStencilParameters( RenderMode::AUTO, StencilFunction::ALWAYS, 0xFF, 0x00, 0xFF, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP ),
167   mIndexedDrawFirstElement( 0u ),
168   mIndexedDrawElementsCount( 0u ),
169   mBlendBitmask( 0u ),
170   mRegenerateUniformMap( 0u ),
171   mResendFlag( 0u ),
172   mDepthFunction( DepthFunction::LESS ),
173   mFaceCullingMode( FaceCullingMode::NONE ),
174   mBlendMode( BlendMode::AUTO ),
175   mDepthWriteMode( DepthWriteMode::AUTO ),
176   mDepthTestMode( DepthTestMode::AUTO ),
177   mPremultipledAlphaEnabled( false ),
178   mGfxRenderCommand(),
179   mDepthIndex( 0 )
180 {
181   mUniformMapChanged[0] = false;
182   mUniformMapChanged[1] = false;
183
184   // Observe our own PropertyOwner's uniform map
185   AddUniformMapObserver( *this );
186 }
187
188 Renderer::~Renderer()
189 {
190   if( mTextureSet )
191   {
192     mTextureSet->RemoveObserver( this );
193     mTextureSet = NULL;
194   }
195   if( mShader )
196   {
197     mShader->RemoveConnectionObserver( *this );
198     mShader = NULL;
199   }
200 }
201
202 void Renderer::operator delete( void* ptr )
203 {
204   gRendererMemoryPool.FreeThreadSafe( static_cast<Renderer*>( ptr ) );
205 }
206
207
208 void* AllocateUniformBufferMemory( size_t size )
209 {
210   return nullptr;
211 }
212
213
214
215 void Renderer::PrepareRender( Graphics::API::Controller& controller, BufferIndex updateBufferIndex )
216 {
217   // prepare all stuff
218   auto gfxShader = mShader->GetGfxObject();
219
220   if( !mGfxRenderCommand )
221   {
222     mGfxRenderCommand = controller.AllocateRenderCommand();
223   }
224
225   /**
226    * Prepare vertex attribute buffer bindings
227    */
228   uint32_t bindingIndex { 0u };
229   uint32_t locationIndex { 0u };
230   auto vertexAttributeBindings = Graphics::API::RenderCommand::NewVertexAttributeBufferBindings();
231   for( auto&& vertexBuffer : mGeometry->GetVertexBuffers() )
232   {
233     auto attributeCountInForBuffer = vertexBuffer->GetAttributeCount();
234
235     // update vertex buffer if necessary
236     vertexBuffer->Update( controller );
237
238     for( auto i = 0u; i < attributeCountInForBuffer; ++i )
239     {
240       // create binding per attribute
241       auto binding = Graphics::API::RenderCommand::VertexAttributeBufferBinding{}
242         .SetOffset( (vertexBuffer->GetFormat()->components[i]).offset )
243         .SetBinding( bindingIndex )
244         .SetBuffer( vertexBuffer->GetGfxObject() )
245         .SetInputAttributeRate( Graphics::API::RenderCommand::InputAttributeRate::PER_VERTEX )
246         .SetLocation( locationIndex + i )
247         .SetStride( vertexBuffer->GetFormat()->size );
248       vertexAttributeBindings.emplace_back( binding );
249     }
250   }
251
252   /**
253    * REGENERATE UNIFORM MAP
254    */
255   if( mRegenerateUniformMap > UNIFORM_MAP_READY )
256   {
257     if( mRegenerateUniformMap == REGENERATE_UNIFORM_MAP)
258     {
259       CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ];
260       localMap.Resize(0);
261
262       const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap();
263       AddMappings( localMap, rendererUniformMap );
264
265       if( mShader )
266       {
267         AddMappings( localMap, mShader->GetUniformMap() );
268       }
269     }
270     else if( mRegenerateUniformMap == COPY_UNIFORM_MAP )
271     {
272       // Copy old map into current map
273       CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ];
274       CollectedUniformMap& oldMap = mCollectedUniformMap[ 1-updateBufferIndex ];
275
276       localMap.Resize( oldMap.Count() );
277
278       unsigned int index = 0;
279       for( CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End() ; iter != end ; ++iter, ++index )
280       {
281         localMap[index] = *iter;
282       }
283     }
284
285     mUniformMapChanged[updateBufferIndex] = true;
286     mRegenerateUniformMap--;
287   }
288
289   auto& shader = mShader->GetGfxObject().Get();
290   auto uboCount = shader.GetUniformBlockCount();
291
292   auto pushConstantsBindings = Graphics::API::RenderCommand::NewPushConstantsBindings( uboCount );
293
294   // allocate new command ( may be not necessary at all )
295  // mGfxRenderCommand = Graphics::API::RenderCommandBuilder().Build();
296
297   // see if we need to reallocate memory for each UBO
298   // todo: do it only when shader has changed
299   if( mUboMemory.size() != uboCount )
300   {
301     mUboMemory.resize(uboCount);
302   }
303
304   for( auto i = 0u; i < uboCount; ++i )
305   {
306     Graphics::API::ShaderDetails::UniformBlockInfo ubInfo;
307
308     std::cout<<sizeof(ubInfo) << std::endl;
309
310     shader.GetUniformBlock( i, ubInfo );
311
312     if( mUboMemory[i].size() != ubInfo.size )
313     {
314       mUboMemory[i].resize( ubInfo.size );
315     }
316
317     // Set push constant bindings
318     auto &pushBinding = pushConstantsBindings[i];
319     pushBinding.data = mUboMemory[i].data();
320     pushBinding.size = uint32_t(mUboMemory[i].size());
321     pushBinding.binding = ubInfo.binding;
322   }
323
324   // add built-in uniforms
325
326   // write to memory
327   for( auto&& i : mCollectedUniformMap )
328   {
329     for( auto&& j : i )
330     {
331       auto uniformInfo = Graphics::API::ShaderDetails::UniformInfo{};
332       if( shader.GetNamedUniform( j->uniformName, uniformInfo ) )
333       {
334         // write into correct uniform buffer
335         auto dst = (mUboMemory[uniformInfo.bufferIndex].data()+uniformInfo.offset);
336         switch( j->propertyPtr->GetType() )
337         {
338           case Property::Type::FLOAT:
339           case Property::Type::INTEGER:
340           case Property::Type::BOOLEAN:
341           {
342             std::cout << uniformInfo.name << ":["<<uniformInfo.bufferIndex<<"]: " << "Writing 32bit offset: " << uniformInfo.offset << ", size: " << sizeof(float) << std::endl;
343             memcpy( dst, &j->propertyPtr->GetFloat( updateBufferIndex ), sizeof(float) );
344             break;
345           }
346           case Property::Type::VECTOR2:
347           {
348             std::cout << uniformInfo.name << ":["<<uniformInfo.bufferIndex<<"]: " << "Writing vec2 offset: " << uniformInfo.offset << ", size: " << sizeof(Vector2) << std::endl;
349             memcpy( dst, &j->propertyPtr->GetVector2( updateBufferIndex ), sizeof(Vector2) );
350             break;
351           }
352           case Property::Type::VECTOR3:
353           {
354             std::cout << uniformInfo.name << ":["<<uniformInfo.bufferIndex<<"]: " <<  "Writing vec3 offset: " << uniformInfo.offset << ", size: " << sizeof(Vector3) << std::endl;
355             memcpy( dst, &j->propertyPtr->GetVector3( updateBufferIndex ), sizeof(Vector3) );
356             break;
357           }
358           case Property::Type::VECTOR4:
359           {
360             std::cout << uniformInfo.name << ":["<<uniformInfo.bufferIndex<<"]: " << "Writing vec4 offset: " << uniformInfo.offset << ", size: " << sizeof(Vector4) << std::endl;
361             memcpy( dst, &j->propertyPtr->GetVector4( updateBufferIndex ), sizeof(Vector4) );
362             break;
363           }
364           case Property::Type::MATRIX:
365           {
366             std::cout << uniformInfo.name << ":["<<uniformInfo.bufferIndex<<"]: " << "Writing mat4 offset: " << uniformInfo.offset << ", size: " << sizeof(Matrix) << std::endl;
367             memcpy( dst, &j->propertyPtr->GetMatrix( updateBufferIndex ), sizeof(Matrix) );
368             break;
369           }
370           case Property::Type::MATRIX3:
371           {
372             std::cout << uniformInfo.name << ":["<<uniformInfo.bufferIndex<<"]: " << "Writing mat3 offset: " << uniformInfo.offset << ", size: " << sizeof(Matrix3) << std::endl;
373             memcpy( dst, &j->propertyPtr->GetMatrix3( updateBufferIndex ), sizeof(Matrix3) );
374             break;
375           }
376           default:
377           {}
378         }
379       }
380     }
381   }
382
383   /**
384    * Prepare textures
385    */
386   auto textureBindings = Graphics::API::RenderCommand::NewTextureBindings();
387   auto samplers = shader.GetSamplers();
388
389   for( auto i = 0u; i < mTextureSet->GetTextureCount(); ++i )
390   {
391     auto texture = mTextureSet->GetTexture( i );
392     auto gfxTexture = texture->GetGfxObject();
393     auto binding = Graphics::API::RenderCommand::TextureBinding{}
394         .SetBinding( samplers[i].binding )
395         .SetTexture( texture->GetGfxObject() )
396         .SetSampler( nullptr );
397
398     textureBindings.emplace_back( binding );
399   }
400
401   // Build render command
402   // todo: this may be deferred until all render items are sorted, otherwise
403   // certain optimisations cannot be done
404
405   const auto& vb = mGeometry->GetVertexBuffers()[0];
406   //vb->Update()
407   mGfxRenderCommand->PushConstants( std::move(pushConstantsBindings) );
408   mGfxRenderCommand->BindVertexBuffers( std::move(vertexAttributeBindings) );
409   mGfxRenderCommand->BindTextures( std::move(textureBindings) );
410   mGfxRenderCommand->BindRenderState( std::move( Graphics::API::RenderCommand::RenderState{}
411                                        .SetShader( mShader->GetGfxObject() ) ) );
412   mGfxRenderCommand->Draw( std::move(Graphics::API::RenderCommand::DrawCommand{}
413                    .SetFirstVertex(0u)
414                    .SetDrawType( Graphics::API::RenderCommand::DrawType::VERTEX_DRAW )
415                    .SetFirstInstance(0u)
416                    .SetVertexCount( vb->GetElementCount() )
417                    .SetInstanceCount( 1u )));
418
419   std::cout << "done\n";
420 }
421
422 void Renderer::WriteUniform( const std::string& name, const void* data, uint32_t size )
423 {
424   auto& gfxShader = mShader->GetGfxObject().Get();
425   auto uniformInfo = Graphics::API::ShaderDetails::UniformInfo{};
426   if( gfxShader.GetNamedUniform( name, uniformInfo ) )
427   {
428     auto dst = (mUboMemory[uniformInfo.bufferIndex].data()+uniformInfo.offset);
429     memcpy( dst, data, size );
430   }
431 }
432
433 void Renderer::PrepareRender( BufferIndex updateBufferIndex )
434 {
435
436   if( mRegenerateUniformMap > UNIFORM_MAP_READY )
437   {
438     if( mRegenerateUniformMap == REGENERATE_UNIFORM_MAP)
439     {
440       CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ];
441       localMap.Resize(0);
442
443       const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap();
444       AddMappings( localMap, rendererUniformMap );
445
446       if( mShader )
447       {
448         AddMappings( localMap, mShader->GetUniformMap() );
449       }
450     }
451     else if( mRegenerateUniformMap == COPY_UNIFORM_MAP )
452     {
453       // Copy old map into current map
454       CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ];
455       CollectedUniformMap& oldMap = mCollectedUniformMap[ 1-updateBufferIndex ];
456
457       localMap.Resize( oldMap.Count() );
458
459       unsigned int index=0;
460       for( CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End() ; iter != end ; ++iter, ++index )
461       {
462         localMap[index] = *iter;
463       }
464     }
465
466     mUniformMapChanged[updateBufferIndex] = true;
467     mRegenerateUniformMap--;
468   }
469
470   if( mResendFlag != 0 )
471   {
472     // This used to send messages to obsolete Render::Renderer at this point
473     mResendFlag = 0;
474   }
475 }
476
477 void Renderer::SetTextures( TextureSet* textureSet )
478 {
479   DALI_ASSERT_DEBUG( textureSet != NULL && "Texture set pointer is NULL" );
480
481   if( mTextureSet )
482   {
483     mTextureSet->RemoveObserver(this);
484   }
485
486   mTextureSet = textureSet;
487   mTextureSet->AddObserver( this );
488   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
489   mResendFlag |= RESEND_DATA_PROVIDER;
490 }
491
492 void Renderer::SetShader( Shader* shader )
493 {
494   DALI_ASSERT_DEBUG( shader != NULL && "Shader pointer is NULL" );
495
496   if( mShader )
497   {
498     mShader->RemoveConnectionObserver(*this);
499   }
500
501   mShader = shader;
502   mShader->AddConnectionObserver( *this );
503   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
504   mResendFlag |= RESEND_DATA_PROVIDER;
505 }
506
507 void Renderer::SetGeometry( SceneGraph::Geometry* geometry )
508 {
509   DALI_ASSERT_DEBUG( geometry != NULL && "Geometry pointer is NULL");
510   mGeometry = geometry;
511 }
512
513 void Renderer::SetDepthIndex( int depthIndex )
514 {
515   mDepthIndex = depthIndex;
516 }
517
518 void Renderer::SetFaceCullingMode( FaceCullingMode::Type faceCullingMode )
519 {
520   mFaceCullingMode = faceCullingMode;
521   mResendFlag |= RESEND_FACE_CULLING_MODE;
522 }
523
524 void Renderer::SetBlendMode( BlendMode::Type blendingMode )
525 {
526   mBlendMode = blendingMode;
527 }
528
529 void Renderer::SetBlendingOptions( unsigned int options )
530 {
531   if( mBlendBitmask != options)
532   {
533     mBlendBitmask = options;
534     mResendFlag |= RESEND_BLEND_BIT_MASK;
535   }
536 }
537
538 void Renderer::SetBlendColor( const Vector4& blendColor )
539 {
540   if( blendColor == Color::TRANSPARENT )
541   {
542     mBlendColor = NULL;
543   }
544   else
545   {
546     if( !mBlendColor )
547     {
548       mBlendColor = new Vector4( blendColor );
549     }
550     else
551     {
552       *mBlendColor = blendColor;
553     }
554   }
555
556   mResendFlag |= RESEND_BLEND_COLOR;
557 }
558
559 void Renderer::SetIndexedDrawFirstElement( size_t firstElement )
560 {
561   mIndexedDrawFirstElement = firstElement;
562   mResendFlag |= RESEND_INDEXED_DRAW_FIRST_ELEMENT;
563 }
564
565 void Renderer::SetIndexedDrawElementsCount( size_t elementsCount )
566 {
567   mIndexedDrawElementsCount = elementsCount;
568   mResendFlag |= RESEND_INDEXED_DRAW_ELEMENTS_COUNT;
569 }
570
571 void Renderer::EnablePreMultipliedAlpha( bool preMultipled )
572 {
573   mPremultipledAlphaEnabled = preMultipled;
574   mResendFlag |= RESEND_PREMULTIPLIED_ALPHA;
575 }
576
577 void Renderer::SetDepthWriteMode( DepthWriteMode::Type depthWriteMode )
578 {
579   mDepthWriteMode = depthWriteMode;
580   mResendFlag |= RESEND_DEPTH_WRITE_MODE;
581 }
582
583 void Renderer::SetDepthTestMode( DepthTestMode::Type depthTestMode )
584 {
585   mDepthTestMode = depthTestMode;
586   mResendFlag |= RESEND_DEPTH_TEST_MODE;
587 }
588
589 void Renderer::SetDepthFunction( DepthFunction::Type depthFunction )
590 {
591   mDepthFunction = depthFunction;
592   mResendFlag |= RESEND_DEPTH_FUNCTION;
593 }
594
595 void Renderer::SetRenderMode( RenderMode::Type mode )
596 {
597   mStencilParameters.renderMode = mode;
598   mResendFlag |= RESEND_RENDER_MODE;
599 }
600
601 void Renderer::SetStencilFunction( StencilFunction::Type stencilFunction )
602 {
603   mStencilParameters.stencilFunction = stencilFunction;
604   mResendFlag |= RESEND_STENCIL_FUNCTION;
605 }
606
607 void Renderer::SetStencilFunctionMask( int stencilFunctionMask )
608 {
609   mStencilParameters.stencilFunctionMask = stencilFunctionMask;
610   mResendFlag |= RESEND_STENCIL_FUNCTION_MASK;
611 }
612
613 void Renderer::SetStencilFunctionReference( int stencilFunctionReference )
614 {
615   mStencilParameters.stencilFunctionReference = stencilFunctionReference;
616   mResendFlag |= RESEND_STENCIL_FUNCTION_REFERENCE;
617 }
618
619 void Renderer::SetStencilMask( int stencilMask )
620 {
621   mStencilParameters.stencilMask = stencilMask;
622   mResendFlag |= RESEND_STENCIL_MASK;
623 }
624
625 void Renderer::SetStencilOperationOnFail( StencilOperation::Type stencilOperationOnFail )
626 {
627   mStencilParameters.stencilOperationOnFail = stencilOperationOnFail;
628   mResendFlag |= RESEND_STENCIL_OPERATION_ON_FAIL;
629 }
630
631 void Renderer::SetStencilOperationOnZFail( StencilOperation::Type stencilOperationOnZFail )
632 {
633   mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail;
634   mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_FAIL;
635 }
636
637 void Renderer::SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass )
638 {
639   mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass;
640   mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_PASS;
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( BufferIndex bufferIndex )
645 {
646   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
647
648   mRenderDataProvider = std::make_unique< RenderDataProvider >();
649
650   mRenderDataProvider->mUniformMapDataProvider = this;
651   mRenderDataProvider->mShader = mShader;
652
653   if( mTextureSet )
654   {
655     size_t textureCount = mTextureSet->GetTextureCount();
656     mRenderDataProvider->mTextures.resize( textureCount );
657     mRenderDataProvider->mSamplers.resize( textureCount );
658     for( unsigned int i(0); i<textureCount; ++i )
659     {
660       mRenderDataProvider->mTextures[i] = mTextureSet->GetTexture(i);
661       mRenderDataProvider->mSamplers[i] = mTextureSet->GetTextureSampler(i);
662     }
663   }
664 }
665
666 //Called just before destroying the scene-graph renderer ( when the "event-thread renderer" is no longer referenced )
667 void Renderer::DisconnectFromSceneGraph(  BufferIndex bufferIndex )
668 {
669 }
670
671 const Vector4& Renderer::GetBlendColor() const
672 {
673   if( mBlendColor )
674   {
675     return *mBlendColor;
676   }
677   return Color::TRANSPARENT;
678 }
679
680 const CollectedUniformMap& Renderer::GetUniformMap( BufferIndex bufferIndex ) const
681 {
682   return mCollectedUniformMap[bufferIndex];
683 }
684
685 Renderer::Opacity Renderer::GetOpacity( BufferIndex updateBufferIndex, const Node& node ) const
686 {
687   Renderer::Opacity opacity = Renderer::OPAQUE;
688
689   switch( mBlendMode )
690   {
691     case BlendMode::ON: // If the renderer should always be use blending
692     {
693       opacity = Renderer::TRANSLUCENT;
694       break;
695     }
696     case BlendMode::AUTO:
697     {
698       bool shaderRequiresBlending( mShader->HintEnabled( Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT ) );
699       if( shaderRequiresBlending || ( mTextureSet && mTextureSet->HasAlpha() ) )
700       {
701         opacity = Renderer::TRANSLUCENT;
702       }
703       else // renderer should determine opacity using the actor color
704       {
705         float alpha = node.GetWorldColor( updateBufferIndex ).a;
706         if( alpha <= FULLY_TRANSPARENT )
707         {
708           opacity = TRANSPARENT;
709         }
710         else if( alpha <= FULLY_OPAQUE )
711         {
712           opacity = TRANSLUCENT;
713         }
714       }
715       break;
716     }
717     case BlendMode::OFF: // the renderer should never use blending
718     default:
719     {
720       opacity = Renderer::OPAQUE;
721       break;
722     }
723   }
724
725   return opacity;
726 }
727
728 void Renderer::TextureSetChanged()
729 {
730   mResendFlag |= RESEND_DATA_PROVIDER;
731 }
732
733 void Renderer::TextureSetDeleted()
734 {
735   mTextureSet = NULL;
736
737   mResendFlag |= RESEND_DATA_PROVIDER;
738 }
739 void Renderer::ConnectionsChanged( PropertyOwner& object )
740 {
741   // One of our child objects has changed it's connections. Ensure the uniform
742   // map gets regenerated during PrepareRender
743   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
744
745   // Ensure the child object pointers get re-sent to the renderer
746   mResendFlag |= RESEND_DATA_PROVIDER;
747 }
748
749 void Renderer::ConnectedUniformMapChanged()
750 {
751   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
752 }
753
754 void Renderer::UniformMappingsChanged( const UniformMap& mappings )
755 {
756   // The mappings are either from PropertyOwner base class, or the Actor
757   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
758 }
759
760 void Renderer::ObservedObjectDestroyed(PropertyOwner& owner)
761 {
762   if( reinterpret_cast<PropertyOwner*>(mShader) == &owner )
763   {
764     mShader = NULL;
765   }
766 }
767
768 } // namespace SceneGraph
769 } // namespace Internal
770 } // namespace Dali
771
772 #pragma GCC diagnostic pop