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