Merge branch 'devel/master(1.1.39)' into tizen
[platform/core/uifw/dali-core.git] / dali / internal / update / rendering / scene-graph-renderer.cpp
1 /*
2  * Copyright (c) 2015 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 // CLASS HEADER
18 #include "scene-graph-renderer.h"
19
20 // INTERNAL HEADERS
21 #include <dali/internal/update/controllers/scene-controller.h>
22 #include <dali/internal/render/renderers/render-geometry.h>
23 #include <dali/internal/update/controllers/render-message-dispatcher.h>
24 #include <dali/internal/update/rendering/scene-graph-texture-set.h>
25 #include <dali/internal/render/shaders/scene-graph-shader.h>
26 #include <dali/internal/render/renderers/render-renderer.h>
27 #include <dali/internal/render/data-providers/node-data-provider.h>
28 #include <dali/internal/update/nodes/node.h>
29 #include <dali/internal/render/queue/render-queue.h>
30 #include <dali/internal/common/internal-constants.h>
31 #include <dali/internal/common/memory-pool-object-allocator.h>
32
33
34 namespace // unnamed namespace
35 {
36
37 const unsigned int UNIFORM_MAP_READY      = 0;
38 const unsigned int COPY_UNIFORM_MAP       = 1;
39 const unsigned int REGENERATE_UNIFORM_MAP = 2;
40
41 //Memory pool used to allocate new renderers. Memory used by this pool will be released when shutting down DALi
42 Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::Renderer> gRendererMemoryPool;
43
44 void AddMappings( Dali::Internal::SceneGraph::CollectedUniformMap& localMap, const Dali::Internal::SceneGraph::UniformMap& uniformMap )
45 {
46   // Iterate thru uniformMap.
47   //   Any maps that aren't in localMap should be added in a single step
48   Dali::Internal::SceneGraph::CollectedUniformMap newUniformMappings;
49
50   for( unsigned int i=0, count=uniformMap.Count(); i<count; ++i )
51   {
52     Dali::Internal::SceneGraph::UniformPropertyMapping::Hash nameHash = uniformMap[i].uniformNameHash;
53     bool found = false;
54
55     for( Dali::Internal::SceneGraph::CollectedUniformMap::Iterator iter = localMap.Begin() ; iter != localMap.End() ; ++iter )
56     {
57       const Dali::Internal::SceneGraph::UniformPropertyMapping* map = (*iter);
58       if( map->uniformNameHash == nameHash )
59       {
60         if( map->uniformName == uniformMap[i].uniformName )
61         {
62           found = true;
63           break;
64         }
65       }
66     }
67     if( !found )
68     {
69       // it's a new mapping. Add raw ptr to temporary list
70       newUniformMappings.PushBack( &uniformMap[i] );
71     }
72   }
73
74   if( newUniformMappings.Count() > 0 )
75   {
76     localMap.Reserve( localMap.Count() + newUniformMappings.Count() );
77
78     for( Dali::Internal::SceneGraph::CollectedUniformMap::Iterator iter = newUniformMappings.Begin(),
79            end = newUniformMappings.End() ;
80          iter != end ;
81          ++iter )
82     {
83       const Dali::Internal::SceneGraph::UniformPropertyMapping* map = (*iter);
84       localMap.PushBack( map );
85     }
86   }
87 }
88
89 // flags for resending data to renderer
90 enum Flags
91 {
92   RESEND_DATA_PROVIDER               = 1,
93   RESEND_GEOMETRY                    = 1 << 1,
94   RESEND_FACE_CULLING_MODE           = 1 << 2,
95   RESEND_BLEND_COLOR                 = 1 << 3,
96   RESEND_BLEND_BIT_MASK              = 1 << 4,
97   RESEND_PREMULTIPLIED_ALPHA         = 1 << 5,
98   RESEND_INDEXED_DRAW_FIRST_ELEMENT  = 1 << 6,
99   RESEND_INDEXED_DRAW_ELEMENTS_COUNT = 1 << 7,
100   RESEND_DEPTH_WRITE_MODE            = 1 << 8,
101   RESEND_DEPTH_TEST_MODE             = 1 << 9,
102   RESEND_DEPTH_FUNCTION              = 1 << 10,
103 };
104
105 }
106
107 namespace Dali
108 {
109 namespace Internal
110 {
111 namespace SceneGraph
112 {
113
114 Renderer* Renderer::New()
115 {
116   return new ( gRendererMemoryPool.AllocateRawThreadSafe() ) Renderer();
117 }
118
119 Renderer::Renderer()
120 : mSceneController( 0 ),
121   mRenderer( NULL ),
122   mTextureSet( NULL ),
123   mGeometry( NULL ),
124   mShader( NULL ),
125   mBlendColor( NULL ),
126   mIndexedDrawFirstElement( 0u ),
127   mIndexedDrawElementsCount( 0u ),
128   mBlendBitmask( 0u ),
129   mReferenceCount( 0u ),
130   mRegenerateUniformMap( 0u ),
131   mResendFlag( 0u ),
132   mDepthFunction( DepthFunction::LESS ),
133   mFaceCullingMode( FaceCullingMode::NONE ),
134   mBlendMode( BlendMode::AUTO ),
135   mDepthWriteMode( DepthWriteMode::AUTO ),
136   mDepthTestMode( DepthTestMode::AUTO ),
137   mResourcesReady( false ),
138   mFinishedResourceAcquisition( false ),
139   mPremultipledAlphaEnabled( false ),
140   mDepthIndex( 0 )
141 {
142   mUniformMapChanged[0] = false;
143   mUniformMapChanged[1] = false;
144
145   // Observe our own PropertyOwner's uniform map
146   AddUniformMapObserver( *this );
147 }
148
149 Renderer::~Renderer()
150 {
151   if (mTextureSet)
152   {
153     mTextureSet->RemoveObserver(this);
154     mTextureSet=NULL;
155   }
156   if( mShader )
157   {
158     mShader->RemoveConnectionObserver(*this);
159     mShader=NULL;
160   }
161
162 }
163
164 void Renderer::operator delete( void* ptr )
165 {
166   gRendererMemoryPool.FreeThreadSafe( static_cast<Renderer*>( ptr ) );
167 }
168
169
170 void Renderer::PrepareRender( BufferIndex updateBufferIndex )
171 {
172   mResourcesReady = false;
173   mFinishedResourceAcquisition = false;
174
175   // Can only be considered ready when all the scene graph objects are connected to the renderer
176   if( mGeometry && mShader )
177   {
178     if( mTextureSet )
179     {
180       mTextureSet->GetResourcesStatus( mResourcesReady, mFinishedResourceAcquisition );
181     }
182     else
183     {
184       mResourcesReady = true;
185       mFinishedResourceAcquisition = true;
186     }
187   }
188
189   if( mRegenerateUniformMap > UNIFORM_MAP_READY )
190   {
191     DALI_ASSERT_DEBUG( mGeometry != NULL && "No geometry available in PrepareRender()" );
192     DALI_ASSERT_DEBUG( mShader != NULL && "No shader available in PrepareRender()" );
193
194     if( mRegenerateUniformMap == REGENERATE_UNIFORM_MAP)
195     {
196       CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ];
197       localMap.Resize(0);
198
199       const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap();
200       AddMappings( localMap, rendererUniformMap );
201
202       if( mShader )
203       {
204         AddMappings( localMap, mShader->GetUniformMap() );
205       }
206     }
207     else if( mRegenerateUniformMap == COPY_UNIFORM_MAP )
208     {
209       // Copy old map into current map
210       CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ];
211       CollectedUniformMap& oldMap = mCollectedUniformMap[ 1-updateBufferIndex ];
212
213       localMap.Resize( oldMap.Count() );
214
215       unsigned int index=0;
216       for( CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End() ; iter != end ; ++iter, ++index )
217       {
218         localMap[index] = *iter;
219       }
220     }
221
222     mUniformMapChanged[updateBufferIndex] = true;
223     mRegenerateUniformMap--;
224   }
225
226   if( mResendFlag != 0 )
227   {
228     if( mResendFlag & RESEND_DATA_PROVIDER )
229     {
230       RenderDataProvider* dataProvider = NewRenderDataProvider();
231
232       typedef MessageValue1< Render::Renderer, OwnerPointer<RenderDataProvider> > DerivedType;
233       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
234       new (slot) DerivedType( mRenderer, &Render::Renderer::SetRenderDataProvider, dataProvider );
235     }
236
237     if( mResendFlag & RESEND_GEOMETRY )
238     {
239       typedef MessageValue1< Render::Renderer, Render::Geometry* > DerivedType;
240       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
241
242       new (slot) DerivedType( mRenderer, &Render::Renderer::SetGeometry, mGeometry );
243     }
244
245     if( mResendFlag & RESEND_FACE_CULLING_MODE )
246     {
247       typedef MessageValue1< Render::Renderer, FaceCullingMode::Type > DerivedType;
248       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
249       new (slot) DerivedType( mRenderer, &Render::Renderer::SetFaceCullingMode, mFaceCullingMode );
250     }
251
252     if( mResendFlag & RESEND_BLEND_BIT_MASK )
253     {
254       typedef MessageValue1< Render::Renderer, unsigned int > DerivedType;
255       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
256       new (slot) DerivedType( mRenderer, &Render::Renderer::SetBlendingBitMask, mBlendBitmask );
257     }
258
259     if( mResendFlag & RESEND_BLEND_COLOR )
260     {
261       typedef MessageValue1< Render::Renderer, const Vector4* > DerivedType;
262       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
263       new (slot) DerivedType( mRenderer, &Render::Renderer::SetBlendColor, mBlendColor );
264     }
265
266     if( mResendFlag & RESEND_PREMULTIPLIED_ALPHA  )
267     {
268       typedef MessageValue1< Render::Renderer, bool > DerivedType;
269       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
270       new (slot) DerivedType( mRenderer, &Render::Renderer::EnablePreMultipliedAlpha, mPremultipledAlphaEnabled );
271     }
272
273     if( mResendFlag & RESEND_INDEXED_DRAW_FIRST_ELEMENT )
274     {
275       typedef MessageValue1< Render::Renderer, size_t > DerivedType;
276       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
277       new (slot) DerivedType( mRenderer, &Render::Renderer::SetIndexedDrawFirstElement, mIndexedDrawFirstElement );
278     }
279
280     if( mResendFlag & RESEND_INDEXED_DRAW_ELEMENTS_COUNT )
281     {
282       typedef MessageValue1< Render::Renderer, size_t > DerivedType;
283       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
284       new (slot) DerivedType( mRenderer, &Render::Renderer::SetIndexedDrawElementsCount, mIndexedDrawElementsCount );
285     }
286
287     if( mResendFlag & RESEND_DEPTH_WRITE_MODE )
288     {
289       typedef MessageValue1< Render::Renderer, DepthWriteMode::Type > DerivedType;
290       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
291       new (slot) DerivedType( mRenderer, &Render::Renderer::SetDepthWriteMode, mDepthWriteMode );
292     }
293
294     if( mResendFlag & RESEND_DEPTH_TEST_MODE )
295     {
296       typedef MessageValue1< Render::Renderer, DepthTestMode::Type > DerivedType;
297       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
298       new (slot) DerivedType( mRenderer, &Render::Renderer::SetDepthTestMode, mDepthTestMode );
299     }
300
301     if( mResendFlag & RESEND_DEPTH_FUNCTION )
302     {
303       typedef MessageValue1< Render::Renderer, DepthFunction::Type > DerivedType;
304       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
305       new (slot) DerivedType( mRenderer, &Render::Renderer::SetDepthFunction, mDepthFunction );
306     }
307
308     mResendFlag = 0;
309   }
310 }
311
312 void Renderer::SetTextures( TextureSet* textureSet )
313 {
314   DALI_ASSERT_DEBUG( textureSet != NULL && "Texture set pointer is NULL" );
315
316   if( mTextureSet )
317   {
318     mTextureSet->RemoveObserver(this);
319   }
320
321   mTextureSet = textureSet;
322   mTextureSet->AddObserver( this );
323   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
324   mResendFlag |= RESEND_DATA_PROVIDER;
325 }
326
327 void Renderer::SetShader( Shader* shader )
328 {
329   DALI_ASSERT_DEBUG( shader != NULL && "Shader pointer is NULL" );
330
331   if( mShader )
332   {
333     mShader->RemoveConnectionObserver(*this);
334   }
335
336   mShader = shader;
337   mShader->AddConnectionObserver( *this );
338   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
339   mResendFlag |= RESEND_DATA_PROVIDER;
340 }
341
342 void Renderer::SetGeometry( Render::Geometry* geometry )
343 {
344   DALI_ASSERT_DEBUG( geometry != NULL && "Geometry pointer is NULL");
345   mGeometry = geometry;
346
347   if( mRenderer )
348   {
349     mResendFlag |= RESEND_GEOMETRY;
350   }
351 }
352
353 void Renderer::SetDepthIndex( int depthIndex )
354 {
355   mDepthIndex = depthIndex;
356 }
357
358 void Renderer::SetFaceCullingMode( FaceCullingMode::Type faceCullingMode )
359 {
360   mFaceCullingMode = faceCullingMode;
361   mResendFlag |= RESEND_FACE_CULLING_MODE;
362 }
363
364 void Renderer::SetBlendMode( BlendMode::Type blendingMode )
365 {
366   mBlendMode = blendingMode;
367 }
368
369 void Renderer::SetBlendingOptions( unsigned int options )
370 {
371   if( mBlendBitmask != options)
372   {
373     mBlendBitmask = options;
374     mResendFlag |= RESEND_BLEND_BIT_MASK;
375   }
376 }
377
378 void Renderer::SetBlendColor( const Vector4& blendColor )
379 {
380   if( !mBlendColor )
381   {
382     mBlendColor = new Vector4( blendColor );
383   }
384   else
385   {
386     *mBlendColor = blendColor;
387   }
388
389   mResendFlag |= RESEND_BLEND_COLOR;
390 }
391
392 void Renderer::SetIndexedDrawFirstElement( size_t firstElement )
393 {
394   mIndexedDrawFirstElement = firstElement;
395   mResendFlag |= RESEND_INDEXED_DRAW_FIRST_ELEMENT;
396 }
397
398 void Renderer::SetIndexedDrawElementsCount( size_t elementsCount )
399 {
400   mIndexedDrawElementsCount = elementsCount;
401   mResendFlag |= RESEND_INDEXED_DRAW_ELEMENTS_COUNT;
402 }
403
404 void Renderer::EnablePreMultipliedAlpha( bool preMultipled )
405 {
406   mPremultipledAlphaEnabled = preMultipled;
407   mResendFlag |= RESEND_PREMULTIPLIED_ALPHA;
408 }
409
410 void Renderer::SetDepthWriteMode( DepthWriteMode::Type depthWriteMode )
411 {
412   mDepthWriteMode = depthWriteMode;
413   mResendFlag |= RESEND_DEPTH_WRITE_MODE;
414 }
415
416 void Renderer::SetDepthTestMode( DepthTestMode::Type depthTestMode )
417 {
418   mDepthTestMode = depthTestMode;
419   mResendFlag |= RESEND_DEPTH_TEST_MODE;
420 }
421
422 void Renderer::SetDepthFunction( DepthFunction::Type depthFunction )
423 {
424   mDepthFunction = depthFunction;
425   mResendFlag |= RESEND_DEPTH_FUNCTION;
426 }
427
428 //Called when a node with this renderer is added to the stage
429 void Renderer::OnStageConnect()
430 {
431   ++mReferenceCount;
432   if( !mRenderer)
433   {
434     RenderDataProvider* dataProvider = NewRenderDataProvider();
435
436     mRenderer = Render::Renderer::New( dataProvider, mGeometry,
437                                        mBlendBitmask, mBlendColor,
438                                        static_cast< FaceCullingMode::Type >( mFaceCullingMode ),
439                                        mPremultipledAlphaEnabled,
440                                        mDepthWriteMode,
441                                        mDepthTestMode,
442                                        mDepthFunction );
443
444     mSceneController->GetRenderMessageDispatcher().AddRenderer( *mRenderer );
445     mResendFlag = 0;
446   }
447 }
448
449 //Called when the node with this renderer has gone out of the stage
450 void Renderer::OnStageDisconnect()
451 {
452   --mReferenceCount;
453   if( mReferenceCount == 0 )
454   {
455     mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer );
456     mRenderer = NULL;
457   }
458 }
459
460 //Called when SceneGraph::Renderer is added to update manager ( that happens when an "event-thread renderer" is created )
461 void Renderer::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
462 {
463   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
464   mSceneController = &sceneController;
465 }
466
467
468 //Called just before destroying the scene-graph renderer ( when the "event-thread renderer" is no longer referenced )
469 void Renderer::DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
470 {
471   //Remove renderer from RenderManager
472   if( mRenderer )
473   {
474     mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer );
475     mRenderer = NULL;
476     mSceneController = NULL;
477   }
478 }
479
480 RenderDataProvider* Renderer::NewRenderDataProvider()
481 {
482   RenderDataProvider* dataProvider = new RenderDataProvider();
483
484   dataProvider->mUniformMapDataProvider = this;
485   dataProvider->mShader = mShader;
486
487   if( mTextureSet )
488   {
489     size_t textureCount( mTextureSet->GetTextureCount() );
490     dataProvider->mTextures.resize( textureCount );
491     dataProvider->mSamplers.resize( textureCount );
492     for( unsigned int i(0); i<textureCount; ++i )
493     {
494       dataProvider->mTextures[i] = Render::Texture( mTextureSet->GetTextureId(i),0);
495       dataProvider->mSamplers[i] = mTextureSet->GetTextureSampler(i);
496     }
497
498     textureCount = mTextureSet->GetNewTextureCount();
499     dataProvider->mNewTextures.resize( textureCount );
500     dataProvider->mSamplers.resize( textureCount );
501     for( unsigned int i(0); i<textureCount; ++i )
502     {
503       dataProvider->mNewTextures[i] = mTextureSet->GetNewTexture(i);
504       dataProvider->mSamplers[i] = mTextureSet->GetTextureSampler(i);
505     }
506   }
507
508   return dataProvider;
509 }
510
511 Render::Renderer& Renderer::GetRenderer()
512 {
513   return *mRenderer;
514 }
515
516 const CollectedUniformMap& Renderer::GetUniformMap( BufferIndex bufferIndex ) const
517 {
518   return mCollectedUniformMap[bufferIndex];
519 };
520
521 void Renderer::GetReadyAndComplete( bool& ready, bool& complete ) const
522 {
523   ready = mResourcesReady;
524   complete = mFinishedResourceAcquisition;
525 }
526
527 Renderer::Opacity Renderer::GetOpacity( BufferIndex updateBufferIndex, const Node& node ) const
528 {
529   Renderer::Opacity opacity = Renderer::OPAQUE;
530
531   switch( mBlendMode )
532   {
533     case BlendMode::ON: // If the renderer should always be use blending
534     {
535       opacity = Renderer::TRANSLUCENT;
536       break;
537     }
538     case BlendMode::AUTO:
539     {
540       bool shaderRequiresBlending( mShader->HintEnabled( Dali::Shader::HINT_OUTPUT_IS_TRANSPARENT ) );
541       if( shaderRequiresBlending || ( mTextureSet && mTextureSet->HasAlpha() ) )
542       {
543         opacity = Renderer::TRANSLUCENT;
544       }
545       else // renderer should determine opacity using the actor color
546       {
547         float alpha = node.GetWorldColor( updateBufferIndex ).a;
548         if( alpha <= FULLY_TRANSPARENT )
549         {
550           opacity = TRANSPARENT;
551         }
552         else if( alpha <= FULLY_OPAQUE )
553         {
554           opacity = TRANSLUCENT;
555         }
556       }
557       break;
558     }
559     case BlendMode::OFF: // the renderer should never use blending
560     default:
561     {
562       opacity = Renderer::OPAQUE;
563       break;
564     }
565   }
566
567
568   return opacity;
569 }
570
571 void Renderer::TextureSetChanged()
572 {
573   mResendFlag |= RESEND_DATA_PROVIDER;
574 }
575
576 void Renderer::ConnectionsChanged( PropertyOwner& object )
577 {
578   // One of our child objects has changed it's connections. Ensure the uniform
579   // map gets regenerated during PrepareRender
580   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
581
582   // Ensure the child object pointers get re-sent to the renderer
583   mResendFlag |= RESEND_DATA_PROVIDER;
584 }
585
586 void Renderer::ConnectedUniformMapChanged()
587 {
588   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
589 }
590
591 void Renderer::UniformMappingsChanged( const UniformMap& mappings )
592 {
593   // The mappings are either from PropertyOwner base class, or the Actor
594   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
595 }
596
597 void Renderer::ObservedObjectDestroyed(PropertyOwner& owner)
598 {
599   if( reinterpret_cast<PropertyOwner*>(mTextureSet) == &owner )
600   {
601     mTextureSet = NULL;
602   }
603   else if( reinterpret_cast<PropertyOwner*>(mShader) == &owner )
604   {
605     mShader = NULL;
606   }
607 }
608
609 } // namespace SceneGraph
610 } // namespace Internal
611 } // namespace Dali