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