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