Partial update implementation, first phase.
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-renderer.cpp
1 /*
2  * Copyright (c) 2019 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( NULL),
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()
169 {
170 }
171
172 void Renderer::SetGeometry( Render::Geometry* geometry )
173 {
174   mGeometry = geometry;
175   mUpdateAttributesLocation = true;
176 }
177
178 void Renderer::SetBlending( Context& context, bool blend )
179 {
180   context.SetBlend( blend );
181   if( blend )
182   {
183     // Blend color is optional and rarely used
184     const Vector4* blendColor = mBlendingOptions.GetBlendColor();
185     if( blendColor )
186     {
187       context.SetCustomBlendColor( *blendColor );
188     }
189     else
190     {
191       context.SetDefaultBlendColor();
192     }
193
194     // Set blend source & destination factors
195     context.BlendFuncSeparate( mBlendingOptions.GetBlendSrcFactorRgb(),
196                                mBlendingOptions.GetBlendDestFactorRgb(),
197                                mBlendingOptions.GetBlendSrcFactorAlpha(),
198                                mBlendingOptions.GetBlendDestFactorAlpha() );
199
200     // Set blend equations
201     context.BlendEquationSeparate( mBlendingOptions.GetBlendEquationRgb(),
202                                    mBlendingOptions.GetBlendEquationAlpha() );
203   }
204
205   mUpdated = true;
206 }
207
208 void Renderer::GlContextDestroyed()
209 {
210   mGeometry->GlContextDestroyed();
211 }
212
213 void Renderer::GlCleanup()
214 {
215 }
216
217 void Renderer::SetUniforms( BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, const Vector3& size, Program& program )
218 {
219   // Check if the map has changed
220   DALI_ASSERT_DEBUG( mRenderDataProvider && "No Uniform map data provider available" );
221
222   const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMap();
223
224   if( uniformMapDataProvider.GetUniformMapChanged( bufferIndex ) ||
225       node.GetUniformMapChanged(bufferIndex) ||
226       mUniformIndexMap.Count() == 0 ||
227       mShaderChanged )
228   {
229     // Reset shader pointer
230     mShaderChanged = false;
231
232     const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap( bufferIndex );
233     const SceneGraph::CollectedUniformMap& uniformMapNode = node.GetUniformMap( bufferIndex );
234
235     uint32_t maxMaps = static_cast<uint32_t>( uniformMap.Count() + uniformMapNode.Count() ); // 4,294,967,295 maps should be enough
236     mUniformIndexMap.Clear(); // Clear contents, but keep memory if we don't change size
237     mUniformIndexMap.Resize( maxMaps );
238
239     uint32_t mapIndex = 0;
240     for(; mapIndex < uniformMap.Count() ; ++mapIndex )
241     {
242       mUniformIndexMap[mapIndex].propertyValue = uniformMap[mapIndex]->propertyPtr;
243       mUniformIndexMap[mapIndex].uniformIndex = program.RegisterUniform( uniformMap[mapIndex]->uniformName );
244     }
245
246     for( uint32_t nodeMapIndex = 0; nodeMapIndex < uniformMapNode.Count() ; ++nodeMapIndex )
247     {
248       uint32_t uniformIndex = program.RegisterUniform( uniformMapNode[nodeMapIndex]->uniformName );
249       bool found(false);
250       for( uint32_t i = 0; i<uniformMap.Count(); ++i )
251       {
252         if( mUniformIndexMap[i].uniformIndex == uniformIndex )
253         {
254           mUniformIndexMap[i].propertyValue = uniformMapNode[nodeMapIndex]->propertyPtr;
255           found = true;
256           break;
257         }
258       }
259
260       if( !found )
261       {
262         mUniformIndexMap[mapIndex].propertyValue = uniformMapNode[nodeMapIndex]->propertyPtr;
263         mUniformIndexMap[mapIndex].uniformIndex = uniformIndex;
264         ++mapIndex;
265       }
266     }
267
268     mUniformIndexMap.Resize( mapIndex );
269   }
270
271   // Set uniforms in local map
272   for( UniformIndexMappings::Iterator iter = mUniformIndexMap.Begin(),
273          end = mUniformIndexMap.End() ;
274        iter != end ;
275        ++iter )
276   {
277     SetUniformFromProperty( bufferIndex, program, *iter );
278   }
279
280   GLint sizeLoc = program.GetUniformLocation( Program::UNIFORM_SIZE );
281   if( -1 != sizeLoc )
282   {
283     program.SetSizeUniform3f( sizeLoc, size.x, size.y, size.z );
284   }
285 }
286
287 void Renderer::SetUniformFromProperty( BufferIndex bufferIndex, Program& program, UniformIndexMap& map )
288 {
289   GLint location = program.GetUniformLocation(map.uniformIndex);
290   if( Program::UNIFORM_UNKNOWN != location )
291   {
292     // switch based on property type to use correct GL uniform setter
293     switch ( map.propertyValue->GetType() )
294     {
295       case Property::INTEGER:
296       {
297         program.SetUniform1i( location, map.propertyValue->GetInteger( bufferIndex ) );
298         break;
299       }
300       case Property::FLOAT:
301       {
302         program.SetUniform1f( location, map.propertyValue->GetFloat( bufferIndex ) );
303         break;
304       }
305       case Property::VECTOR2:
306       {
307         Vector2 value( map.propertyValue->GetVector2( bufferIndex ) );
308         program.SetUniform2f( location, value.x, value.y );
309         break;
310       }
311
312       case Property::VECTOR3:
313       {
314         Vector3 value( map.propertyValue->GetVector3( bufferIndex ) );
315         program.SetUniform3f( location, value.x, value.y, value.z );
316         break;
317       }
318
319       case Property::VECTOR4:
320       {
321         Vector4 value( map.propertyValue->GetVector4( bufferIndex ) );
322         program.SetUniform4f( location, value.x, value.y, value.z, value.w );
323         break;
324       }
325
326       case Property::ROTATION:
327       {
328         Quaternion value( map.propertyValue->GetQuaternion( bufferIndex ) );
329         program.SetUniform4f( location, value.mVector.x, value.mVector.y, value.mVector.z, value.mVector.w );
330         break;
331       }
332
333       case Property::MATRIX:
334       {
335         const Matrix& value = map.propertyValue->GetMatrix(bufferIndex);
336         program.SetUniformMatrix4fv(location, 1, value.AsFloat() );
337         break;
338       }
339
340       case Property::MATRIX3:
341       {
342         const Matrix3& value = map.propertyValue->GetMatrix3(bufferIndex);
343         program.SetUniformMatrix3fv(location, 1, value.AsFloat() );
344         break;
345       }
346
347       default:
348       {
349         // Other property types are ignored
350         break;
351       }
352     }
353   }
354 }
355
356 bool Renderer::BindTextures( Context& context, Program& program, Vector<GLuint>& boundTextures )
357 {
358   uint32_t textureUnit = 0;
359   bool result = true;
360
361   GLint uniformLocation(-1);
362   std::vector<Render::Sampler*>& samplers( mRenderDataProvider->GetSamplers() );
363   std::vector<Render::Texture*>& textures( mRenderDataProvider->GetTextures() );
364   for( uint32_t i = 0; i < static_cast<uint32_t>( textures.size() ) && result; ++i ) // not expecting more than uint32_t of textures
365   {
366     if( textures[i] )
367     {
368       result = textures[i]->Bind(context, textureUnit, samplers[i] );
369       boundTextures.PushBack( textures[i]->GetId() );
370       if( result && program.GetSamplerUniformLocation( i, uniformLocation ) )
371       {
372         program.SetUniform1i( uniformLocation, textureUnit );
373         ++textureUnit;
374       }
375     }
376   }
377
378   return result;
379 }
380
381 void Renderer::SetFaceCullingMode( FaceCullingMode::Type mode )
382 {
383   mFaceCullingMode =  mode;
384   mUpdated = true;
385 }
386
387 void Renderer::SetBlendingBitMask( uint32_t bitmask )
388 {
389   mBlendingOptions.SetBitmask( bitmask );
390   mUpdated = true;
391 }
392
393 void Renderer::SetBlendColor( const Vector4& color )
394 {
395   mBlendingOptions.SetBlendColor( color );
396   mUpdated = true;
397 }
398
399 void Renderer::SetIndexedDrawFirstElement( uint32_t firstElement )
400 {
401   mIndexedDrawFirstElement = firstElement;
402   mUpdated = true;
403 }
404
405 void Renderer::SetIndexedDrawElementsCount( uint32_t elementsCount )
406 {
407   mIndexedDrawElementsCount = elementsCount;
408   mUpdated = true;
409 }
410
411 void Renderer::EnablePreMultipliedAlpha( bool enable )
412 {
413   mPremultipledAlphaEnabled = enable;
414   mUpdated = true;
415 }
416
417 void Renderer::SetDepthWriteMode( DepthWriteMode::Type depthWriteMode )
418 {
419   mDepthWriteMode = depthWriteMode;
420   mUpdated = true;
421 }
422
423 void Renderer::SetDepthTestMode( DepthTestMode::Type depthTestMode )
424 {
425   mDepthTestMode = depthTestMode;
426   mUpdated = true;
427 }
428
429 DepthWriteMode::Type Renderer::GetDepthWriteMode() const
430 {
431   return mDepthWriteMode;
432 }
433
434 DepthTestMode::Type Renderer::GetDepthTestMode() const
435 {
436   return mDepthTestMode;
437 }
438
439 void Renderer::SetDepthFunction( DepthFunction::Type depthFunction )
440 {
441   mDepthFunction = depthFunction;
442   mUpdated = true;
443 }
444
445 DepthFunction::Type Renderer::GetDepthFunction() const
446 {
447   return mDepthFunction;
448 }
449
450 void Renderer::SetRenderMode( RenderMode::Type renderMode )
451 {
452   mStencilParameters.renderMode = renderMode;
453   mUpdated = true;
454 }
455
456 RenderMode::Type Renderer::GetRenderMode() const
457 {
458   return mStencilParameters.renderMode;
459 }
460
461 void Renderer::SetStencilFunction( StencilFunction::Type stencilFunction )
462 {
463   mStencilParameters.stencilFunction = stencilFunction;
464   mUpdated = true;
465 }
466
467 StencilFunction::Type Renderer::GetStencilFunction() const
468 {
469   return mStencilParameters.stencilFunction;
470 }
471
472 void Renderer::SetStencilFunctionMask( int stencilFunctionMask )
473 {
474   mStencilParameters.stencilFunctionMask = stencilFunctionMask;
475   mUpdated = true;
476 }
477
478 int Renderer::GetStencilFunctionMask() const
479 {
480   return mStencilParameters.stencilFunctionMask;
481 }
482
483 void Renderer::SetStencilFunctionReference( int stencilFunctionReference )
484 {
485   mStencilParameters.stencilFunctionReference = stencilFunctionReference;
486   mUpdated = true;
487 }
488
489 int Renderer::GetStencilFunctionReference() const
490 {
491   return mStencilParameters.stencilFunctionReference;
492 }
493
494 void Renderer::SetStencilMask( int stencilMask )
495 {
496   mStencilParameters.stencilMask = stencilMask;
497   mUpdated = true;
498 }
499
500 int Renderer::GetStencilMask() const
501 {
502   return mStencilParameters.stencilMask;
503 }
504
505 void Renderer::SetStencilOperationOnFail( StencilOperation::Type stencilOperationOnFail )
506 {
507   mStencilParameters.stencilOperationOnFail = stencilOperationOnFail;
508   mUpdated = true;
509 }
510
511 StencilOperation::Type Renderer::GetStencilOperationOnFail() const
512 {
513   return mStencilParameters.stencilOperationOnFail;
514 }
515
516 void Renderer::SetStencilOperationOnZFail( StencilOperation::Type stencilOperationOnZFail )
517 {
518   mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail;
519   mUpdated = true;
520 }
521
522 StencilOperation::Type Renderer::GetStencilOperationOnZFail() const
523 {
524   return mStencilParameters.stencilOperationOnZFail;
525 }
526
527 void Renderer::SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass )
528 {
529   mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass;
530   mUpdated = true;
531 }
532
533 StencilOperation::Type Renderer::GetStencilOperationOnZPass() const
534 {
535   return mStencilParameters.stencilOperationOnZPass;
536 }
537
538 void Renderer::Upload( Context& context )
539 {
540   mGeometry->Upload( context );
541 }
542
543 void Renderer::Render( Context& context,
544                        BufferIndex bufferIndex,
545                        const SceneGraph::NodeDataProvider& node,
546                        const Matrix& modelMatrix,
547                        const Matrix& modelViewMatrix,
548                        const Matrix& viewMatrix,
549                        const Matrix& projectionMatrix,
550                        const Vector3& size,
551                        bool blend,
552                        Vector<GLuint>& boundTextures,
553                        const Dali::Internal::SceneGraph::RenderInstruction& instruction )
554 {
555   // Get the program to use:
556   Program* program = mRenderDataProvider->GetShader().GetProgram();
557   if( !program )
558   {
559     DALI_LOG_ERROR( "Failed to get program for shader at address %p.\n", reinterpret_cast< void* >( &mRenderDataProvider->GetShader() ) );
560     return;
561   }
562
563   //Set cull face  mode
564   const Dali::Internal::SceneGraph::Camera* cam = instruction.GetCamera();
565   if (cam->GetReflectionUsed())
566   {
567     auto adjFaceCullingMode = mFaceCullingMode;
568     switch( mFaceCullingMode )
569     {
570       case FaceCullingMode::Type::FRONT:
571       {
572         adjFaceCullingMode = FaceCullingMode::Type::BACK;
573         break;
574       }
575       case FaceCullingMode::Type::BACK:
576       {
577         adjFaceCullingMode = FaceCullingMode::Type::FRONT;
578         break;
579       }
580       default:
581       {
582         // nothing to do, leave culling as it is
583       }
584     }
585     context.CullFace( adjFaceCullingMode );
586   }
587   else
588   {
589     context.CullFace( mFaceCullingMode );
590   }
591
592   //Set blending mode
593   SetBlending( context, blend );
594
595   // Take the program into use so we can send uniforms to it
596   program->Use();
597
598   if( DALI_LIKELY( BindTextures( context, *program, boundTextures ) ) )
599   {
600     // Only set up and draw if we have textures and they are all valid
601
602     // set projection and view matrix if program has not yet received them yet this frame
603     SetMatrices( *program, modelMatrix, viewMatrix, projectionMatrix, modelViewMatrix );
604
605     // set color uniform
606     GLint loc = program->GetUniformLocation( Program::UNIFORM_COLOR );
607     if( Program::UNIFORM_UNKNOWN != loc )
608     {
609       const Vector4& color = node.GetRenderColor( bufferIndex );
610       if( mPremultipledAlphaEnabled )
611       {
612         float alpha = color.a * mRenderDataProvider->GetOpacity( bufferIndex );
613         program->SetUniform4f( loc, color.r * alpha, color.g * alpha, color.b * alpha, alpha );
614       }
615       else
616       {
617         program->SetUniform4f( loc, color.r, color.g, color.b, color.a * mRenderDataProvider->GetOpacity( bufferIndex ) );
618       }
619     }
620
621     SetUniforms( bufferIndex, node, size, *program );
622
623     if( mUpdateAttributesLocation || mGeometry->AttributesChanged() )
624     {
625       mGeometry->GetAttributeLocationFromProgram( mAttributesLocation, *program, bufferIndex );
626       mUpdateAttributesLocation = false;
627     }
628
629     mGeometry->Draw( context,
630                      bufferIndex,
631                      mAttributesLocation,
632                      mIndexedDrawFirstElement,
633                      mIndexedDrawElementsCount );
634
635     mUpdated = false;
636   }
637 }
638
639 void Renderer::SetSortAttributes( BufferIndex bufferIndex,
640                                   SceneGraph::RenderInstructionProcessor::SortAttributes& sortAttributes ) const
641 {
642   sortAttributes.shader = &( mRenderDataProvider->GetShader() );
643   sortAttributes.geometry = mGeometry;
644 }
645
646 void Renderer::SetShaderChanged( bool value )
647 {
648   mShaderChanged = value;
649 }
650
651 bool Renderer::Updated(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider* node)
652 {
653   if (mUpdated)
654   {
655     mUpdated = false;
656     return true;
657   }
658
659   if (mShaderChanged || mUpdateAttributesLocation || mGeometry->AttributesChanged())
660   {
661     return true;
662   }
663
664   std::vector<Render::Texture*> textures = mRenderDataProvider->GetTextures();
665   for (Render::Texture* texture : textures)
666   {
667     if (texture && texture->IsNativeImage())
668     {
669       return true;
670     }
671   }
672
673   uint64_t hash = 0xc70f6907UL;
674   const SceneGraph::CollectedUniformMap& uniformMapNode = node->GetUniformMap( bufferIndex );
675   for (const auto* uniformProperty : uniformMapNode)
676   {
677     hash = uniformProperty->propertyPtr->Hash(bufferIndex, hash);
678   }
679
680   const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMap();
681   const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap( bufferIndex );
682   for (const auto* uniformProperty : uniformMap)
683   {
684     hash = uniformProperty->propertyPtr->Hash(bufferIndex, hash);
685   }
686
687   if (mUniformsHash != hash)
688   {
689     mUniformsHash = hash;
690     return true;
691   }
692
693   return false;
694 }
695
696 } // namespace SceneGraph
697
698 } // namespace Internal
699
700 } // namespace Dali