[dali_2.0.3] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-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
18 // CLASS HEADER
19 #include <dali/internal/render/renderers/render-renderer.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/common/image-sampler.h>
23 #include <dali/internal/render/gl-resources/context.h>
24 #include <dali/internal/render/renderers/render-sampler.h>
25 #include <dali/internal/render/shaders/scene-graph-shader.h>
26 #include <dali/internal/render/shaders/program.h>
27 #include <dali/internal/render/data-providers/node-data-provider.h>
28 #include <dali/internal/render/data-providers/uniform-map-data-provider.h>
29 #include <dali/internal/render/common/render-instruction.h>
30
31 namespace Dali
32 {
33
34 namespace Internal
35 {
36
37 namespace
38 {
39
40
41 /**
42  * Helper to set view and projection matrices once per program
43  * @param program to set the matrices to
44  * @param modelMatrix to set
45  * @param viewMatrix to set
46  * @param projectionMatrix to set
47  * @param modelViewMatrix to set
48  * @param modelViewProjectionMatrix to set
49  */
50 inline void SetMatrices( Program& program,
51                          const Matrix& modelMatrix,
52                          const Matrix& viewMatrix,
53                          const Matrix& projectionMatrix,
54                          const Matrix& modelViewMatrix )
55 {
56   GLint loc = program.GetUniformLocation( Program::UNIFORM_MODEL_MATRIX );
57   if( Program::UNIFORM_UNKNOWN != loc )
58   {
59     program.SetUniformMatrix4fv( loc, 1, modelMatrix.AsFloat() );
60   }
61   loc = program.GetUniformLocation( Program::UNIFORM_VIEW_MATRIX );
62   if( Program::UNIFORM_UNKNOWN != loc )
63   {
64     if( program.GetViewMatrix() != &viewMatrix )
65     {
66       program.SetViewMatrix( &viewMatrix );
67       program.SetUniformMatrix4fv( loc, 1, viewMatrix.AsFloat() );
68     }
69   }
70   // set projection matrix if program has not yet received it this frame or if it is dirty
71   loc = program.GetUniformLocation( Program::UNIFORM_PROJECTION_MATRIX );
72   if( Program::UNIFORM_UNKNOWN != loc )
73   {
74     if( program.GetProjectionMatrix() != &projectionMatrix )
75     {
76       program.SetProjectionMatrix( &projectionMatrix );
77       program.SetUniformMatrix4fv( loc, 1, projectionMatrix.AsFloat() );
78     }
79   }
80   loc = program.GetUniformLocation(Program::UNIFORM_MODELVIEW_MATRIX);
81   if( Program::UNIFORM_UNKNOWN != loc )
82   {
83     program.SetUniformMatrix4fv( loc, 1, modelViewMatrix.AsFloat() );
84   }
85
86   loc = program.GetUniformLocation( Program::UNIFORM_MVP_MATRIX );
87   if( Program::UNIFORM_UNKNOWN != loc )
88   {
89     Matrix modelViewProjectionMatrix(false);
90     Matrix::Multiply( modelViewProjectionMatrix, modelViewMatrix, projectionMatrix );
91     program.SetUniformMatrix4fv( loc, 1, modelViewProjectionMatrix.AsFloat() );
92   }
93
94   loc = program.GetUniformLocation( Program::UNIFORM_NORMAL_MATRIX );
95   if( Program::UNIFORM_UNKNOWN != loc )
96   {
97     Matrix3 normalMatrix;
98     normalMatrix = modelViewMatrix;
99     normalMatrix.Invert();
100     normalMatrix.Transpose();
101     program.SetUniformMatrix3fv( loc, 1, normalMatrix.AsFloat() );
102   }
103 }
104
105 }
106
107 namespace Render
108 {
109
110 Renderer* Renderer::New( SceneGraph::RenderDataProvider* dataProvider,
111                          Render::Geometry* geometry,
112                          uint32_t blendingBitmask,
113                          const Vector4& blendColor,
114                          FaceCullingMode::Type faceCullingMode,
115                          bool preMultipliedAlphaEnabled,
116                          DepthWriteMode::Type depthWriteMode,
117                          DepthTestMode::Type depthTestMode,
118                          DepthFunction::Type depthFunction,
119                          StencilParameters& stencilParameters )
120 {
121   return new Renderer( dataProvider, geometry, blendingBitmask, blendColor,
122                        faceCullingMode, preMultipliedAlphaEnabled, depthWriteMode, depthTestMode,
123                        depthFunction, stencilParameters );
124 }
125
126 Renderer::Renderer( SceneGraph::RenderDataProvider* dataProvider,
127                     Render::Geometry* geometry,
128                     uint32_t blendingBitmask,
129                     const Vector4& blendColor,
130                     FaceCullingMode::Type faceCullingMode,
131                     bool preMultipliedAlphaEnabled,
132                     DepthWriteMode::Type depthWriteMode,
133                     DepthTestMode::Type depthTestMode,
134                     DepthFunction::Type depthFunction,
135                     StencilParameters& stencilParameters )
136 : mRenderDataProvider( dataProvider ),
137   mContext( nullptr),
138   mGeometry( geometry ),
139   mUniformIndexMap(),
140   mAttributesLocation(),
141   mUniformsHash(),
142   mStencilParameters( stencilParameters ),
143   mBlendingOptions(),
144   mIndexedDrawFirstElement( 0 ),
145   mIndexedDrawElementsCount( 0 ),
146   mDepthFunction( depthFunction ),
147   mFaceCullingMode( faceCullingMode ),
148   mDepthWriteMode( depthWriteMode ),
149   mDepthTestMode( depthTestMode ),
150   mUpdateAttributesLocation( true ),
151   mPremultipledAlphaEnabled( preMultipliedAlphaEnabled ),
152   mShaderChanged( false ),
153   mUpdated( true )
154 {
155   if( blendingBitmask != 0u )
156   {
157     mBlendingOptions.SetBitmask( blendingBitmask );
158   }
159
160   mBlendingOptions.SetBlendColor( blendColor );
161 }
162
163 void Renderer::Initialize( Context& context )
164 {
165   mContext = &context;
166 }
167
168 Renderer::~Renderer() = default;
169
170 void Renderer::SetGeometry( Render::Geometry* geometry )
171 {
172   mGeometry = geometry;
173   mUpdateAttributesLocation = true;
174 }
175 void Renderer::SetDrawCommands( Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size )
176 {
177   mDrawCommands.clear();
178   mDrawCommands.insert( mDrawCommands.end(), pDrawCommands, pDrawCommands+size );
179 }
180
181 void Renderer::SetBlending( Context& context, bool blend )
182 {
183   context.SetBlend( blend );
184   if( blend )
185   {
186     // Blend color is optional and rarely used
187     const Vector4* blendColor = mBlendingOptions.GetBlendColor();
188     if( blendColor )
189     {
190       context.SetCustomBlendColor( *blendColor );
191     }
192     else
193     {
194       context.SetDefaultBlendColor();
195     }
196
197     // Set blend source & destination factors
198     context.BlendFuncSeparate( mBlendingOptions.GetBlendSrcFactorRgb(),
199                                mBlendingOptions.GetBlendDestFactorRgb(),
200                                mBlendingOptions.GetBlendSrcFactorAlpha(),
201                                mBlendingOptions.GetBlendDestFactorAlpha() );
202
203     // Set blend equations
204     Dali::DevelBlendEquation::Type rgbEquation   = mBlendingOptions.GetBlendEquationRgb();
205     Dali::DevelBlendEquation::Type alphaEquation = mBlendingOptions.GetBlendEquationAlpha();
206
207     if( mBlendingOptions.IsAdvancedBlendEquationApplied() && mPremultipledAlphaEnabled )
208     {
209       if( rgbEquation != alphaEquation )
210       {
211         DALI_LOG_ERROR( "Advanced Blend Equation have to be appried by using BlendEquation.\n" );
212       }
213       context.BlendEquation( rgbEquation );
214     }
215     else
216     {
217       context.BlendEquationSeparate( rgbEquation, alphaEquation );
218     }
219   }
220
221   mUpdated = true;
222 }
223
224 void Renderer::GlContextDestroyed()
225 {
226   mGeometry->GlContextDestroyed();
227 }
228
229 void Renderer::GlCleanup()
230 {
231 }
232
233 void Renderer::SetUniforms( BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, const Vector3& size, Program& program )
234 {
235   // Check if the map has changed
236   DALI_ASSERT_DEBUG( mRenderDataProvider && "No Uniform map data provider available" );
237
238   const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMap();
239
240   if( uniformMapDataProvider.GetUniformMapChanged( bufferIndex ) ||
241       node.GetUniformMapChanged(bufferIndex) ||
242       mUniformIndexMap.Count() == 0 ||
243       mShaderChanged )
244   {
245     // Reset shader pointer
246     mShaderChanged = false;
247
248     const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap( bufferIndex );
249     const SceneGraph::CollectedUniformMap& uniformMapNode = node.GetUniformMap( bufferIndex );
250
251     uint32_t maxMaps = static_cast<uint32_t>( uniformMap.Count() + uniformMapNode.Count() ); // 4,294,967,295 maps should be enough
252     mUniformIndexMap.Clear(); // Clear contents, but keep memory if we don't change size
253     mUniformIndexMap.Resize( maxMaps );
254
255     uint32_t mapIndex = 0;
256     for(; mapIndex < uniformMap.Count() ; ++mapIndex )
257     {
258       mUniformIndexMap[mapIndex].propertyValue = uniformMap[mapIndex]->propertyPtr;
259       mUniformIndexMap[mapIndex].uniformIndex = program.RegisterUniform( uniformMap[mapIndex]->uniformName );
260     }
261
262     for( uint32_t nodeMapIndex = 0; nodeMapIndex < uniformMapNode.Count() ; ++nodeMapIndex )
263     {
264       uint32_t uniformIndex = program.RegisterUniform( uniformMapNode[nodeMapIndex]->uniformName );
265       bool found(false);
266       for( uint32_t i = 0; i<uniformMap.Count(); ++i )
267       {
268         if( mUniformIndexMap[i].uniformIndex == uniformIndex )
269         {
270           mUniformIndexMap[i].propertyValue = uniformMapNode[nodeMapIndex]->propertyPtr;
271           found = true;
272           break;
273         }
274       }
275
276       if( !found )
277       {
278         mUniformIndexMap[mapIndex].propertyValue = uniformMapNode[nodeMapIndex]->propertyPtr;
279         mUniformIndexMap[mapIndex].uniformIndex = uniformIndex;
280         ++mapIndex;
281       }
282     }
283
284     mUniformIndexMap.Resize( mapIndex );
285   }
286
287   // Set uniforms in local map
288   for( UniformIndexMappings::Iterator iter = mUniformIndexMap.Begin(),
289          end = mUniformIndexMap.End() ;
290        iter != end ;
291        ++iter )
292   {
293     SetUniformFromProperty( bufferIndex, program, *iter );
294   }
295
296   GLint sizeLoc = program.GetUniformLocation( Program::UNIFORM_SIZE );
297   if( -1 != sizeLoc )
298   {
299     program.SetSizeUniform3f( sizeLoc, size.x, size.y, size.z );
300   }
301 }
302
303 void Renderer::SetUniformFromProperty( BufferIndex bufferIndex, Program& program, UniformIndexMap& map )
304 {
305   GLint location = program.GetUniformLocation(map.uniformIndex);
306   if( Program::UNIFORM_UNKNOWN != location )
307   {
308     // switch based on property type to use correct GL uniform setter
309     switch ( map.propertyValue->GetType() )
310     {
311       case Property::INTEGER:
312       {
313         program.SetUniform1i( location, map.propertyValue->GetInteger( bufferIndex ) );
314         break;
315       }
316       case Property::FLOAT:
317       {
318         program.SetUniform1f( location, map.propertyValue->GetFloat( bufferIndex ) );
319         break;
320       }
321       case Property::VECTOR2:
322       {
323         Vector2 value( map.propertyValue->GetVector2( bufferIndex ) );
324         program.SetUniform2f( location, value.x, value.y );
325         break;
326       }
327
328       case Property::VECTOR3:
329       {
330         Vector3 value( map.propertyValue->GetVector3( bufferIndex ) );
331         program.SetUniform3f( location, value.x, value.y, value.z );
332         break;
333       }
334
335       case Property::VECTOR4:
336       {
337         Vector4 value( map.propertyValue->GetVector4( bufferIndex ) );
338         program.SetUniform4f( location, value.x, value.y, value.z, value.w );
339         break;
340       }
341
342       case Property::ROTATION:
343       {
344         Quaternion value( map.propertyValue->GetQuaternion( bufferIndex ) );
345         program.SetUniform4f( location, value.mVector.x, value.mVector.y, value.mVector.z, value.mVector.w );
346         break;
347       }
348
349       case Property::MATRIX:
350       {
351         const Matrix& value = map.propertyValue->GetMatrix(bufferIndex);
352         program.SetUniformMatrix4fv(location, 1, value.AsFloat() );
353         break;
354       }
355
356       case Property::MATRIX3:
357       {
358         const Matrix3& value = map.propertyValue->GetMatrix3(bufferIndex);
359         program.SetUniformMatrix3fv(location, 1, value.AsFloat() );
360         break;
361       }
362
363       default:
364       {
365         // Other property types are ignored
366         break;
367       }
368     }
369   }
370 }
371
372 bool Renderer::BindTextures( Context& context, Program& program, Vector<GLuint>& boundTextures )
373 {
374   uint32_t textureUnit = 0;
375   bool result = true;
376
377   GLint uniformLocation(-1);
378   std::vector<Render::Sampler*>& samplers( mRenderDataProvider->GetSamplers() );
379   std::vector<Render::Texture*>& textures( mRenderDataProvider->GetTextures() );
380   for( uint32_t i = 0; i < static_cast<uint32_t>( textures.size() ) && result; ++i ) // not expecting more than uint32_t of textures
381   {
382     if( textures[i] )
383     {
384       result = textures[i]->Bind(context, textureUnit, samplers[i] );
385       boundTextures.PushBack( textures[i]->GetId() );
386       if( result && program.GetSamplerUniformLocation( i, uniformLocation ) )
387       {
388         program.SetUniform1i( uniformLocation, textureUnit );
389         ++textureUnit;
390       }
391     }
392   }
393
394   return result;
395 }
396
397 void Renderer::SetFaceCullingMode( FaceCullingMode::Type mode )
398 {
399   mFaceCullingMode =  mode;
400   mUpdated = true;
401 }
402
403 void Renderer::SetBlendingBitMask( uint32_t bitmask )
404 {
405   mBlendingOptions.SetBitmask( bitmask );
406   mUpdated = true;
407 }
408
409 void Renderer::SetBlendColor( const Vector4& color )
410 {
411   mBlendingOptions.SetBlendColor( color );
412   mUpdated = true;
413 }
414
415 void Renderer::SetIndexedDrawFirstElement( uint32_t firstElement )
416 {
417   mIndexedDrawFirstElement = firstElement;
418   mUpdated = true;
419 }
420
421 void Renderer::SetIndexedDrawElementsCount( uint32_t elementsCount )
422 {
423   mIndexedDrawElementsCount = elementsCount;
424   mUpdated = true;
425 }
426
427 void Renderer::EnablePreMultipliedAlpha( bool enable )
428 {
429   mPremultipledAlphaEnabled = enable;
430   mUpdated = true;
431 }
432
433 void Renderer::SetDepthWriteMode( DepthWriteMode::Type depthWriteMode )
434 {
435   mDepthWriteMode = depthWriteMode;
436   mUpdated = true;
437 }
438
439 void Renderer::SetDepthTestMode( DepthTestMode::Type depthTestMode )
440 {
441   mDepthTestMode = depthTestMode;
442   mUpdated = true;
443 }
444
445 DepthWriteMode::Type Renderer::GetDepthWriteMode() const
446 {
447   return mDepthWriteMode;
448 }
449
450 DepthTestMode::Type Renderer::GetDepthTestMode() const
451 {
452   return mDepthTestMode;
453 }
454
455 void Renderer::SetDepthFunction( DepthFunction::Type depthFunction )
456 {
457   mDepthFunction = depthFunction;
458   mUpdated = true;
459 }
460
461 DepthFunction::Type Renderer::GetDepthFunction() const
462 {
463   return mDepthFunction;
464 }
465
466 void Renderer::SetRenderMode( RenderMode::Type renderMode )
467 {
468   mStencilParameters.renderMode = renderMode;
469   mUpdated = true;
470 }
471
472 RenderMode::Type Renderer::GetRenderMode() const
473 {
474   return mStencilParameters.renderMode;
475 }
476
477 void Renderer::SetStencilFunction( StencilFunction::Type stencilFunction )
478 {
479   mStencilParameters.stencilFunction = stencilFunction;
480   mUpdated = true;
481 }
482
483 StencilFunction::Type Renderer::GetStencilFunction() const
484 {
485   return mStencilParameters.stencilFunction;
486 }
487
488 void Renderer::SetStencilFunctionMask( int stencilFunctionMask )
489 {
490   mStencilParameters.stencilFunctionMask = stencilFunctionMask;
491   mUpdated = true;
492 }
493
494 int Renderer::GetStencilFunctionMask() const
495 {
496   return mStencilParameters.stencilFunctionMask;
497 }
498
499 void Renderer::SetStencilFunctionReference( int stencilFunctionReference )
500 {
501   mStencilParameters.stencilFunctionReference = stencilFunctionReference;
502   mUpdated = true;
503 }
504
505 int Renderer::GetStencilFunctionReference() const
506 {
507   return mStencilParameters.stencilFunctionReference;
508 }
509
510 void Renderer::SetStencilMask( int stencilMask )
511 {
512   mStencilParameters.stencilMask = stencilMask;
513   mUpdated = true;
514 }
515
516 int Renderer::GetStencilMask() const
517 {
518   return mStencilParameters.stencilMask;
519 }
520
521 void Renderer::SetStencilOperationOnFail( StencilOperation::Type stencilOperationOnFail )
522 {
523   mStencilParameters.stencilOperationOnFail = stencilOperationOnFail;
524   mUpdated = true;
525 }
526
527 StencilOperation::Type Renderer::GetStencilOperationOnFail() const
528 {
529   return mStencilParameters.stencilOperationOnFail;
530 }
531
532 void Renderer::SetStencilOperationOnZFail( StencilOperation::Type stencilOperationOnZFail )
533 {
534   mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail;
535   mUpdated = true;
536 }
537
538 StencilOperation::Type Renderer::GetStencilOperationOnZFail() const
539 {
540   return mStencilParameters.stencilOperationOnZFail;
541 }
542
543 void Renderer::SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass )
544 {
545   mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass;
546   mUpdated = true;
547 }
548
549 StencilOperation::Type Renderer::GetStencilOperationOnZPass() const
550 {
551   return mStencilParameters.stencilOperationOnZPass;
552 }
553
554 void Renderer::Upload( Context& context )
555 {
556   mGeometry->Upload( context );
557 }
558
559 void Renderer::Render( Context& context,
560                        BufferIndex bufferIndex,
561                        const SceneGraph::NodeDataProvider& node,
562                        const Matrix& modelMatrix,
563                        const Matrix& modelViewMatrix,
564                        const Matrix& viewMatrix,
565                        const Matrix& projectionMatrix,
566                        const Vector3& size,
567                        bool blend,
568                        Vector<GLuint>& boundTextures,
569                        const Dali::Internal::SceneGraph::RenderInstruction& instruction,
570                        uint32_t queueIndex )
571 {
572   // Before doing anything test if the call happens in the right queue
573   if( mDrawCommands.empty() && queueIndex > 0 )
574   {
575     return;
576   }
577
578   // Prepare commands
579   std::vector<DevelRenderer::DrawCommand*> commands;
580   for( auto& cmd : mDrawCommands )
581   {
582     if(cmd.queue == queueIndex)
583     {
584       commands.emplace_back( &cmd );
585     }
586   }
587
588   // Have commands but nothing to be drawn - abort
589   if(!mDrawCommands.empty() && commands.empty())
590   {
591     return;
592   }
593
594   // Get the program to use:
595   Program* program = mRenderDataProvider->GetShader().GetProgram();
596   if( !program )
597   {
598     DALI_LOG_ERROR( "Failed to get program for shader at address %p.\n", reinterpret_cast< void* >( &mRenderDataProvider->GetShader() ) );
599     return;
600   }
601
602   //Set cull face  mode
603   const Dali::Internal::SceneGraph::Camera* cam = instruction.GetCamera();
604   if (cam->GetReflectionUsed())
605   {
606     auto adjFaceCullingMode = mFaceCullingMode;
607     switch( mFaceCullingMode )
608     {
609       case FaceCullingMode::Type::FRONT:
610       {
611         adjFaceCullingMode = FaceCullingMode::Type::BACK;
612         break;
613       }
614       case FaceCullingMode::Type::BACK:
615       {
616         adjFaceCullingMode = FaceCullingMode::Type::FRONT;
617         break;
618       }
619       default:
620       {
621         // nothing to do, leave culling as it is
622       }
623     }
624     context.CullFace( adjFaceCullingMode );
625   }
626   else
627   {
628     context.CullFace( mFaceCullingMode );
629   }
630
631   // Take the program into use so we can send uniforms to it
632   program->Use();
633
634   if( DALI_LIKELY( BindTextures( context, *program, boundTextures ) ) )
635   {
636     // Only set up and draw if we have textures and they are all valid
637
638     // set projection and view matrix if program has not yet received them yet this frame
639     SetMatrices( *program, modelMatrix, viewMatrix, projectionMatrix, modelViewMatrix );
640
641     // set color uniform
642     GLint loc = program->GetUniformLocation( Program::UNIFORM_COLOR );
643     if( Program::UNIFORM_UNKNOWN != loc )
644     {
645       const Vector4& color = node.GetRenderColor( bufferIndex );
646       if( mPremultipledAlphaEnabled )
647       {
648         float alpha = color.a * mRenderDataProvider->GetOpacity( bufferIndex );
649         program->SetUniform4f( loc, color.r * alpha, color.g * alpha, color.b * alpha, alpha );
650       }
651       else
652       {
653         program->SetUniform4f( loc, color.r, color.g, color.b, color.a * mRenderDataProvider->GetOpacity( bufferIndex ) );
654       }
655     }
656
657     SetUniforms( bufferIndex, node, size, *program );
658
659     if( mUpdateAttributesLocation || mGeometry->AttributesChanged() )
660     {
661       mGeometry->GetAttributeLocationFromProgram( mAttributesLocation, *program, bufferIndex );
662       mUpdateAttributesLocation = false;
663     }
664
665     if( mBlendingOptions.IsAdvancedBlendEquationApplied() && mPremultipledAlphaEnabled )
666     {
667       context.BlendBarrier();
668     }
669
670     if(mDrawCommands.empty())
671     {
672       SetBlending( context, blend );
673
674       mGeometry->Draw( context,
675                        bufferIndex,
676                        mAttributesLocation,
677                        mIndexedDrawFirstElement,
678                        mIndexedDrawElementsCount );
679     }
680     else
681     {
682       for(auto& cmd : commands )
683       {
684         if(cmd->queue == queueIndex )
685         {
686           //Set blending mode
687           SetBlending(context, cmd->queue == DevelRenderer::RENDER_QUEUE_OPAQUE ? false : blend);
688           mGeometry->Draw(context, bufferIndex, mAttributesLocation,
689                           cmd->firstIndex, cmd->elementCount);
690         }
691       }
692     }
693     mUpdated = false;
694   }
695 }
696
697 void Renderer::SetSortAttributes( BufferIndex bufferIndex,
698                                   SceneGraph::RenderInstructionProcessor::SortAttributes& sortAttributes ) const
699 {
700   sortAttributes.shader = &( mRenderDataProvider->GetShader() );
701   sortAttributes.geometry = mGeometry;
702 }
703
704 void Renderer::SetShaderChanged( bool value )
705 {
706   mShaderChanged = value;
707 }
708
709 bool Renderer::Updated(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider* node)
710 {
711   if (mUpdated)
712   {
713     mUpdated = false;
714     return true;
715   }
716
717   if (mShaderChanged || mUpdateAttributesLocation || mGeometry->AttributesChanged())
718   {
719     return true;
720   }
721
722   for( const auto& texture : mRenderDataProvider->GetTextures() )
723   {
724     if (texture && texture->IsNativeImage())
725     {
726       return true;
727     }
728   }
729
730   uint64_t hash = 0xc70f6907UL;
731   const SceneGraph::CollectedUniformMap& uniformMapNode = node->GetUniformMap( bufferIndex );
732   for (const auto* uniformProperty : uniformMapNode)
733   {
734     hash = uniformProperty->propertyPtr->Hash(bufferIndex, hash);
735   }
736
737   const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMap();
738   const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap( bufferIndex );
739   for (const auto* uniformProperty : uniformMap)
740   {
741     hash = uniformProperty->propertyPtr->Hash(bufferIndex, hash);
742   }
743
744   if (mUniformsHash != hash)
745   {
746     mUniformsHash = hash;
747     return true;
748   }
749
750   return false;
751 }
752
753 } // namespace SceneGraph
754
755 } // namespace Internal
756
757 } // namespace Dali