Removed redundant resource loading & rendering code
[platform/core/uifw/dali-core.git] / dali / internal / render / renderers / render-renderer.cpp
1 /*
2  * Copyright (c) 2016 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
29 namespace Dali
30 {
31
32 namespace Internal
33 {
34
35 namespace
36 {
37
38 static Matrix gModelViewProjectionMatrix( false ); ///< a shared matrix to calculate the MVP matrix, dont want to store it in object to reduce storage overhead
39 static Matrix3 gNormalMatrix; ///< a shared matrix to calculate normal matrix, dont want to store it in object to reduce storage overhead
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::Multiply( gModelViewProjectionMatrix, modelViewMatrix, projectionMatrix );
90     program.SetUniformMatrix4fv( loc, 1, gModelViewProjectionMatrix.AsFloat() );
91   }
92
93   loc = program.GetUniformLocation( Program::UNIFORM_NORMAL_MATRIX );
94   if( Program::UNIFORM_UNKNOWN != loc )
95   {
96     gNormalMatrix = modelViewMatrix;
97     gNormalMatrix.Invert();
98     gNormalMatrix.Transpose();
99     program.SetUniformMatrix3fv( loc, 1, gNormalMatrix.AsFloat() );
100   }
101 }
102
103 }
104
105 namespace Render
106 {
107
108 Renderer* Renderer::New( SceneGraph::RenderDataProvider* dataProvider,
109                          Render::Geometry* geometry,
110                          unsigned int blendingBitmask,
111                          const Vector4* blendColor,
112                          FaceCullingMode::Type faceCullingMode,
113                          bool preMultipliedAlphaEnabled,
114                          DepthWriteMode::Type depthWriteMode,
115                          DepthTestMode::Type depthTestMode,
116                          DepthFunction::Type depthFunction,
117                          StencilParameters& stencilParameters )
118 {
119   return new Renderer( dataProvider, geometry, blendingBitmask, blendColor,
120                        faceCullingMode, preMultipliedAlphaEnabled, depthWriteMode, depthTestMode,
121                        depthFunction, stencilParameters );
122 }
123
124 Renderer::Renderer( SceneGraph::RenderDataProvider* dataProvider,
125                     Render::Geometry* geometry,
126                     unsigned int blendingBitmask,
127                     const Vector4* blendColor,
128                     FaceCullingMode::Type faceCullingMode,
129                     bool preMultipliedAlphaEnabled,
130                     DepthWriteMode::Type depthWriteMode,
131                     DepthTestMode::Type depthTestMode,
132                     DepthFunction::Type depthFunction,
133                     StencilParameters& stencilParameters )
134 : mRenderDataProvider( dataProvider ),
135   mContext( NULL),
136   mGeometry( geometry ),
137   mUniformIndexMap(),
138   mAttributesLocation(),
139   mStencilParameters( stencilParameters ),
140   mBlendingOptions(),
141   mIndexedDrawFirstElement( 0 ),
142   mIndexedDrawElementsCount( 0 ),
143   mDepthFunction( depthFunction ),
144   mFaceCullingMode( faceCullingMode ),
145   mDepthWriteMode( depthWriteMode ),
146   mDepthTestMode( depthTestMode ),
147   mUpdateAttributesLocation( true ),
148   mPremultipledAlphaEnabled( preMultipliedAlphaEnabled )
149 {
150   if(  blendingBitmask != 0u )
151   {
152     mBlendingOptions.SetBitmask( blendingBitmask );
153   }
154
155   if( blendColor )
156   {
157     mBlendingOptions.SetBlendColor( *blendColor );
158   }
159 }
160
161 void Renderer::Initialize( Context& context )
162 {
163   mContext = &context;
164 }
165
166 Renderer::~Renderer()
167 {
168 }
169
170 void Renderer::SetRenderDataProvider( SceneGraph::RenderDataProvider* dataProvider )
171 {
172   mRenderDataProvider = dataProvider;
173   mUpdateAttributesLocation = true;
174
175   //Check that the number of textures match the number of samplers in the shader
176   size_t textureCount =  dataProvider->GetTextures().size();
177   Program* program = dataProvider->GetShader().GetProgram();
178   if( program && program->GetActiveSamplerCount() != textureCount )
179   {
180     DALI_LOG_WARNING("The number of active samplers in the shader(%lu) does not match the number of textures in the TextureSet(%lu)\n",
181                    program->GetActiveSamplerCount(),
182                    textureCount );
183   }
184 }
185
186 void Renderer::SetGeometry( Render::Geometry* geometry )
187 {
188   mGeometry = geometry;
189   mUpdateAttributesLocation = true;
190 }
191
192 void Renderer::SetBlending( Context& context, bool blend )
193 {
194   context.SetBlend( blend );
195   if( blend )
196   {
197     // Blend color is optional and rarely used
198     const Vector4* blendColor = mBlendingOptions.GetBlendColor();
199     if( blendColor )
200     {
201       context.SetCustomBlendColor( *blendColor );
202     }
203     else
204     {
205       context.SetDefaultBlendColor();
206     }
207
208     // Set blend source & destination factors
209     context.BlendFuncSeparate( mBlendingOptions.GetBlendSrcFactorRgb(),
210                                mBlendingOptions.GetBlendDestFactorRgb(),
211                                mBlendingOptions.GetBlendSrcFactorAlpha(),
212                                mBlendingOptions.GetBlendDestFactorAlpha() );
213
214     // Set blend equations
215     context.BlendEquationSeparate( mBlendingOptions.GetBlendEquationRgb(),
216                                    mBlendingOptions.GetBlendEquationAlpha() );
217   }
218 }
219
220 void Renderer::GlContextDestroyed()
221 {
222   mGeometry->GlContextDestroyed();
223 }
224
225 void Renderer::GlCleanup()
226 {
227 }
228
229 void Renderer::SetUniforms( BufferIndex bufferIndex, const SceneGraph::NodeDataProvider& node, const Vector3& size, Program& program )
230 {
231   // Check if the map has changed
232   DALI_ASSERT_DEBUG( mRenderDataProvider && "No Uniform map data provider available" );
233
234   const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMap();
235
236   if( uniformMapDataProvider.GetUniformMapChanged( bufferIndex ) ||
237       node.GetUniformMapChanged(bufferIndex))
238   {
239     const SceneGraph::CollectedUniformMap& uniformMap = uniformMapDataProvider.GetUniformMap( bufferIndex );
240     const SceneGraph::CollectedUniformMap& uniformMapNode = node.GetUniformMap( bufferIndex );
241
242     unsigned int maxMaps = uniformMap.Count() + uniformMapNode.Count();
243     mUniformIndexMap.Clear(); // Clear contents, but keep memory if we don't change size
244     mUniformIndexMap.Resize( maxMaps );
245
246     unsigned int mapIndex(0);
247     for(; mapIndex < uniformMap.Count() ; ++mapIndex )
248     {
249       mUniformIndexMap[mapIndex].propertyValue = uniformMap[mapIndex]->propertyPtr;
250       mUniformIndexMap[mapIndex].uniformIndex = program.RegisterUniform( uniformMap[mapIndex]->uniformName );
251     }
252
253     for( unsigned int nodeMapIndex = 0; nodeMapIndex < uniformMapNode.Count() ; ++nodeMapIndex )
254     {
255       unsigned int uniformIndex = program.RegisterUniform( uniformMapNode[nodeMapIndex]->uniformName );
256       bool found(false);
257       for( unsigned int i(0); i<uniformMap.Count(); ++i )
258       {
259         if( mUniformIndexMap[i].uniformIndex == uniformIndex )
260         {
261           mUniformIndexMap[i].propertyValue = uniformMapNode[nodeMapIndex]->propertyPtr;
262           found = true;
263           break;
264         }
265       }
266
267       if( !found )
268       {
269         mUniformIndexMap[mapIndex].propertyValue = uniformMapNode[nodeMapIndex]->propertyPtr;
270         mUniformIndexMap[mapIndex].uniformIndex = uniformIndex;
271         ++mapIndex;
272       }
273     }
274
275     mUniformIndexMap.Resize( mapIndex );
276   }
277
278   // Set uniforms in local map
279   for( UniformIndexMappings::Iterator iter = mUniformIndexMap.Begin(),
280          end = mUniformIndexMap.End() ;
281        iter != end ;
282        ++iter )
283   {
284     SetUniformFromProperty( bufferIndex, program, *iter );
285   }
286
287   GLint sizeLoc = program.GetUniformLocation( Program::UNIFORM_SIZE );
288   if( -1 != sizeLoc )
289   {
290     program.SetSizeUniform3f( sizeLoc, size.x, size.y, size.z );
291   }
292 }
293
294 void Renderer::SetUniformFromProperty( BufferIndex bufferIndex, Program& program, UniformIndexMap& map )
295 {
296   GLint location = program.GetUniformLocation(map.uniformIndex);
297   if( Program::UNIFORM_UNKNOWN != location )
298   {
299     // switch based on property type to use correct GL uniform setter
300     switch ( map.propertyValue->GetType() )
301     {
302       case Property::INTEGER:
303       {
304         program.SetUniform1i( location, map.propertyValue->GetInteger( bufferIndex ) );
305         break;
306       }
307       case Property::FLOAT:
308       {
309         program.SetUniform1f( location, map.propertyValue->GetFloat( bufferIndex ) );
310         break;
311       }
312       case Property::VECTOR2:
313       {
314         Vector2 value( map.propertyValue->GetVector2( bufferIndex ) );
315         program.SetUniform2f( location, value.x, value.y );
316         break;
317       }
318
319       case Property::VECTOR3:
320       {
321         Vector3 value( map.propertyValue->GetVector3( bufferIndex ) );
322         program.SetUniform3f( location, value.x, value.y, value.z );
323         break;
324       }
325
326       case Property::VECTOR4:
327       {
328         Vector4 value( map.propertyValue->GetVector4( bufferIndex ) );
329         program.SetUniform4f( location, value.x, value.y, value.z, value.w );
330         break;
331       }
332
333       case Property::ROTATION:
334       {
335         Quaternion value( map.propertyValue->GetQuaternion( bufferIndex ) );
336         program.SetUniform4f( location, value.mVector.x, value.mVector.y, value.mVector.z, value.mVector.w );
337         break;
338       }
339
340       case Property::MATRIX:
341       {
342         const Matrix& value = map.propertyValue->GetMatrix(bufferIndex);
343         program.SetUniformMatrix4fv(location, 1, value.AsFloat() );
344         break;
345       }
346
347       case Property::MATRIX3:
348       {
349         const Matrix3& value = map.propertyValue->GetMatrix3(bufferIndex);
350         program.SetUniformMatrix3fv(location, 1, value.AsFloat() );
351         break;
352       }
353
354       default:
355       {
356         // Other property types are ignored
357         break;
358       }
359     }
360   }
361 }
362
363 bool Renderer::BindTextures( Context& context, Program& program )
364 {
365   unsigned int textureUnit = 0;
366   bool result = true;
367
368   GLint uniformLocation(-1);
369   std::vector<Render::Sampler*>& samplers( mRenderDataProvider->GetSamplers() );
370   std::vector<Render::Texture*>& textures( mRenderDataProvider->GetTextures() );
371   for( size_t i(0); i<textures.size() && result; ++i )
372   {
373     if( textures[i] )
374     {
375       result = textures[i]->Bind(context, textureUnit, samplers[i] );
376       if( result && program.GetSamplerUniformLocation( i, uniformLocation ) )
377       {
378         program.SetUniform1i( uniformLocation, textureUnit );
379         ++textureUnit;
380       }
381     }
382   }
383
384   return result;
385 }
386
387 void Renderer::SetFaceCullingMode( FaceCullingMode::Type mode )
388 {
389   mFaceCullingMode =  mode;
390 }
391
392 void Renderer::SetBlendingBitMask( unsigned int bitmask )
393 {
394   mBlendingOptions.SetBitmask( bitmask );
395 }
396
397 void Renderer::SetBlendColor( const Vector4* color )
398 {
399   mBlendingOptions.SetBlendColor( *color );
400 }
401
402 void Renderer::SetIndexedDrawFirstElement( size_t firstElement )
403 {
404   mIndexedDrawFirstElement = firstElement;
405 }
406
407 void Renderer::SetIndexedDrawElementsCount( size_t elementsCount )
408 {
409   mIndexedDrawElementsCount = elementsCount;
410 }
411
412 void Renderer::EnablePreMultipliedAlpha( bool enable )
413 {
414   mPremultipledAlphaEnabled = enable;
415 }
416
417 void Renderer::SetDepthWriteMode( DepthWriteMode::Type depthWriteMode )
418 {
419   mDepthWriteMode = depthWriteMode;
420 }
421
422 void Renderer::SetDepthTestMode( DepthTestMode::Type depthTestMode )
423 {
424   mDepthTestMode = depthTestMode;
425 }
426
427 DepthWriteMode::Type Renderer::GetDepthWriteMode() const
428 {
429   return mDepthWriteMode;
430 }
431
432 DepthTestMode::Type Renderer::GetDepthTestMode() const
433 {
434   return mDepthTestMode;
435 }
436
437 void Renderer::SetDepthFunction( DepthFunction::Type depthFunction )
438 {
439   mDepthFunction = depthFunction;
440 }
441
442 DepthFunction::Type Renderer::GetDepthFunction() const
443 {
444   return mDepthFunction;
445 }
446
447 void Renderer::SetRenderMode( RenderMode::Type renderMode )
448 {
449   mStencilParameters.renderMode = renderMode;
450 }
451
452 RenderMode::Type Renderer::GetRenderMode() const
453 {
454   return mStencilParameters.renderMode;
455 }
456
457 void Renderer::SetStencilFunction( StencilFunction::Type stencilFunction )
458 {
459   mStencilParameters.stencilFunction = stencilFunction;
460 }
461
462 StencilFunction::Type Renderer::GetStencilFunction() const
463 {
464   return mStencilParameters.stencilFunction;
465 }
466
467 void Renderer::SetStencilFunctionMask( int stencilFunctionMask )
468 {
469   mStencilParameters.stencilFunctionMask = stencilFunctionMask;
470 }
471
472 int Renderer::GetStencilFunctionMask() const
473 {
474   return mStencilParameters.stencilFunctionMask;
475 }
476
477 void Renderer::SetStencilFunctionReference( int stencilFunctionReference )
478 {
479   mStencilParameters.stencilFunctionReference = stencilFunctionReference;
480 }
481
482 int Renderer::GetStencilFunctionReference() const
483 {
484   return mStencilParameters.stencilFunctionReference;
485 }
486
487 void Renderer::SetStencilMask( int stencilMask )
488 {
489   mStencilParameters.stencilMask = stencilMask;
490 }
491
492 int Renderer::GetStencilMask() const
493 {
494   return mStencilParameters.stencilMask;
495 }
496
497 void Renderer::SetStencilOperationOnFail( StencilOperation::Type stencilOperationOnFail )
498 {
499   mStencilParameters.stencilOperationOnFail = stencilOperationOnFail;
500 }
501
502 StencilOperation::Type Renderer::GetStencilOperationOnFail() const
503 {
504   return mStencilParameters.stencilOperationOnFail;
505 }
506
507 void Renderer::SetStencilOperationOnZFail( StencilOperation::Type stencilOperationOnZFail )
508 {
509   mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail;
510 }
511
512 StencilOperation::Type Renderer::GetStencilOperationOnZFail() const
513 {
514   return mStencilParameters.stencilOperationOnZFail;
515 }
516
517 void Renderer::SetStencilOperationOnZPass( StencilOperation::Type stencilOperationOnZPass )
518 {
519   mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass;
520 }
521
522 StencilOperation::Type Renderer::GetStencilOperationOnZPass() const
523 {
524   return mStencilParameters.stencilOperationOnZPass;
525 }
526
527 void Renderer::Render( Context& context,
528                        BufferIndex bufferIndex,
529                        const SceneGraph::NodeDataProvider& node,
530                        SceneGraph::Shader& defaultShader,
531                        const Matrix& modelMatrix,
532                        const Matrix& modelViewMatrix,
533                        const Matrix& viewMatrix,
534                        const Matrix& projectionMatrix,
535                        const Vector3& size,
536                        bool blend )
537 {
538   // Get the program to use:
539   Program* program = mRenderDataProvider->GetShader().GetProgram();
540   if( !program )
541   {
542     // if program is NULL it means this is a custom shader with non matching geometry type so we need to use default shaders program
543     program = defaultShader.GetProgram();
544     DALI_ASSERT_DEBUG( program && "Default shader should always have a program available." );
545     if( !program )
546     {
547       DALI_LOG_ERROR( "Failed to get program for shader at address %p.\n", (void*)&mRenderDataProvider->GetShader() );
548       return;
549     }
550   }
551
552   //Set cull face  mode
553   context.CullFace( mFaceCullingMode );
554
555   //Set blending mode
556   SetBlending( context, blend );
557
558   // Take the program into use so we can send uniforms to it
559   program->Use();
560
561   if( DALI_LIKELY( BindTextures( context, *program ) ) )
562   {
563     // Only set up and draw if we have textures and they are all valid
564
565     // set projection and view matrix if program has not yet received them yet this frame
566     SetMatrices( *program, modelMatrix, viewMatrix, projectionMatrix, modelViewMatrix );
567
568     // set color uniform
569     GLint loc = program->GetUniformLocation( Program::UNIFORM_COLOR );
570     if( Program::UNIFORM_UNKNOWN != loc )
571     {
572       const Vector4& color = node.GetRenderColor( bufferIndex );
573       if( mPremultipledAlphaEnabled )
574       {
575         program->SetUniform4f( loc, color.r*color.a, color.g*color.a, color.b*color.a, color.a );
576       }
577       else
578       {
579         program->SetUniform4f( loc, color.r, color.g, color.b, color.a );
580       }
581     }
582
583     SetUniforms( bufferIndex, node, size, *program );
584
585     if( mUpdateAttributesLocation || mGeometry->AttributesChanged() )
586     {
587       mGeometry->GetAttributeLocationFromProgram( mAttributesLocation, *program, bufferIndex );
588       mUpdateAttributesLocation = false;
589     }
590
591     mGeometry->UploadAndDraw( context,
592                               bufferIndex,
593                               mAttributesLocation,
594                               mIndexedDrawFirstElement,
595                               mIndexedDrawElementsCount );
596   }
597 }
598
599 void Renderer::SetSortAttributes( BufferIndex bufferIndex,
600                                   SceneGraph::RenderInstructionProcessor::SortAttributes& sortAttributes ) const
601 {
602   sortAttributes.shader = &( mRenderDataProvider->GetShader() );
603   sortAttributes.geometry = mGeometry;
604 }
605
606 } // namespace SceneGraph
607
608 } // namespace Internal
609
610 } // namespace Dali