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