Merge "Moved TextureCache dispatch methods to their own class" into devel/master
[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_FUNCTION = 1 << 9,
102 };
103
104 }
105
106 namespace Dali
107 {
108 namespace Internal
109 {
110 namespace SceneGraph
111 {
112
113 Renderer* Renderer::New()
114 {
115   return new ( gRendererMemoryPool.AllocateRawThreadSafe() ) Renderer();
116 }
117
118 Renderer::Renderer()
119 :mSceneController( 0 ),
120  mRenderer( NULL ),
121  mTextureSet( NULL ),
122  mGeometry( NULL ),
123  mShader( NULL ),
124  mBlendColor( NULL ),
125  mBlendBitmask( 0u ),
126  mFaceCullingMode( FaceCullingMode::NONE ),
127  mBlendMode( BlendMode::AUTO ),
128  mDepthWriteMode( DepthWriteMode::AUTO ),
129  mDepthFunction( DepthFunction::LESS ),
130  mIndexedDrawFirstElement( 0 ),
131  mIndexedDrawElementsCount( 0 ),
132  mReferenceCount( 0 ),
133  mRegenerateUniformMap( 0 ),
134  mResendFlag( 0 ),
135  mResourcesReady( false ),
136  mFinishedResourceAcquisition( false ),
137  mPremultipledAlphaEnabled(false),
138  mDepthIndex( 0 )
139 {
140   mUniformMapChanged[0] = false;
141   mUniformMapChanged[1] = false;
142
143   // Observe our own PropertyOwner's uniform map
144   AddUniformMapObserver( *this );
145 }
146
147 Renderer::~Renderer()
148 {
149   if (mTextureSet)
150   {
151     mTextureSet->RemoveObserver(this);
152     mTextureSet=NULL;
153   }
154   if( mShader )
155   {
156     mShader->RemoveConnectionObserver(*this);
157     mShader=NULL;
158   }
159
160 }
161
162 void Renderer::operator delete( void* ptr )
163 {
164   gRendererMemoryPool.FreeThreadSafe( static_cast<Renderer*>( ptr ) );
165 }
166
167
168 void Renderer::PrepareRender( BufferIndex updateBufferIndex )
169 {
170   mResourcesReady = false;
171   mFinishedResourceAcquisition = false;
172
173   // Can only be considered ready when all the scene graph objects are connected to the renderer
174   if( mGeometry && mShader )
175   {
176     if( mTextureSet )
177     {
178       mTextureSet->GetResourcesStatus( mResourcesReady, mFinishedResourceAcquisition );
179     }
180     else
181     {
182       mResourcesReady = true;
183       mFinishedResourceAcquisition = true;
184     }
185   }
186
187   if( mRegenerateUniformMap > UNIFORM_MAP_READY )
188   {
189     DALI_ASSERT_DEBUG( mGeometry != NULL && "No geometry available in PrepareRender()" );
190     DALI_ASSERT_DEBUG( mShader != NULL && "No shader available in PrepareRender()" );
191
192     if( mRegenerateUniformMap == REGENERATE_UNIFORM_MAP)
193     {
194       CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ];
195       localMap.Resize(0);
196
197       const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap();
198       AddMappings( localMap, rendererUniformMap );
199       AddMappings( localMap, mShader->GetUniformMap() );
200     }
201     else if( mRegenerateUniformMap == COPY_UNIFORM_MAP )
202     {
203       // Copy old map into current map
204       CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ];
205       CollectedUniformMap& oldMap = mCollectedUniformMap[ 1-updateBufferIndex ];
206
207       localMap.Resize( oldMap.Count() );
208
209       unsigned int index=0;
210       for( CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End() ; iter != end ; ++iter, ++index )
211       {
212         localMap[index] = *iter;
213       }
214     }
215
216     mUniformMapChanged[updateBufferIndex] = true;
217     mRegenerateUniformMap--;
218   }
219
220   if( mResendFlag != 0 )
221   {
222     if( mResendFlag & RESEND_DATA_PROVIDER )
223     {
224       RenderDataProvider* dataProvider = NewRenderDataProvider();
225
226       typedef MessageValue1< Render::Renderer, OwnerPointer<RenderDataProvider> > DerivedType;
227       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
228       new (slot) DerivedType( mRenderer, &Render::Renderer::SetRenderDataProvider, dataProvider );
229     }
230
231     if( mResendFlag & RESEND_GEOMETRY )
232     {
233       typedef MessageValue1< Render::Renderer, Render::Geometry* > DerivedType;
234       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
235
236       new (slot) DerivedType( mRenderer, &Render::Renderer::SetGeometry, mGeometry );
237     }
238
239     if( mResendFlag & RESEND_FACE_CULLING_MODE )
240     {
241       typedef MessageValue1< Render::Renderer, FaceCullingMode::Type > DerivedType;
242       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
243       new (slot) DerivedType( mRenderer, &Render::Renderer::SetFaceCullingMode, mFaceCullingMode );
244     }
245
246     if( mResendFlag & RESEND_BLEND_BIT_MASK )
247     {
248       typedef MessageValue1< Render::Renderer, unsigned int > DerivedType;
249       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
250       new (slot) DerivedType( mRenderer, &Render::Renderer::SetBlendingBitMask, mBlendBitmask );
251     }
252
253     if( mResendFlag & RESEND_BLEND_COLOR )
254     {
255       typedef MessageValue1< Render::Renderer, const Vector4* > DerivedType;
256       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
257       new (slot) DerivedType( mRenderer, &Render::Renderer::SetBlendColor, mBlendColor );
258     }
259
260     if( mResendFlag & RESEND_PREMULTIPLIED_ALPHA  )
261     {
262       typedef MessageValue1< Render::Renderer, bool > DerivedType;
263       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
264       new (slot) DerivedType( mRenderer, &Render::Renderer::EnablePreMultipliedAlpha, mPremultipledAlphaEnabled );
265     }
266
267     if( mResendFlag & RESEND_INDEXED_DRAW_FIRST_ELEMENT )
268     {
269       typedef MessageValue1< Render::Renderer, size_t > DerivedType;
270       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
271       new (slot) DerivedType( mRenderer, &Render::Renderer::SetIndexedDrawFirstElement, mIndexedDrawFirstElement );
272     }
273
274     if( mResendFlag & RESEND_INDEXED_DRAW_ELEMENTS_COUNT )
275     {
276       typedef MessageValue1< Render::Renderer, size_t > DerivedType;
277       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
278       new (slot) DerivedType( mRenderer, &Render::Renderer::SetIndexedDrawElementsCount, mIndexedDrawElementsCount );
279     }
280
281     if( mResendFlag & RESEND_DEPTH_WRITE_MODE )
282     {
283       typedef MessageValue1< Render::Renderer, DepthWriteMode::Type > DerivedType;
284       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
285       new (slot) DerivedType( mRenderer, &Render::Renderer::SetDepthWriteMode, mDepthWriteMode );
286     }
287
288     if( mResendFlag & RESEND_DEPTH_FUNCTION )
289     {
290       typedef MessageValue1< Render::Renderer, DepthFunction::Type > DerivedType;
291       unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
292       new (slot) DerivedType( mRenderer, &Render::Renderer::SetDepthFunction, mDepthFunction );
293     }
294
295     mResendFlag = 0;
296   }
297 }
298
299 void Renderer::SetTextures( TextureSet* textureSet )
300 {
301   DALI_ASSERT_DEBUG( textureSet != NULL && "Texture set pointer is NULL" );
302
303   if( mTextureSet )
304   {
305     mTextureSet->RemoveObserver(this);
306   }
307
308   mTextureSet = textureSet;
309   mTextureSet->AddObserver( this );
310   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
311   mResendFlag |= RESEND_DATA_PROVIDER;
312 }
313
314 void Renderer::SetShader( Shader* shader )
315 {
316   DALI_ASSERT_DEBUG( shader != NULL && "Shader pointer is NULL" );
317
318   if( mShader )
319   {
320     mShader->RemoveConnectionObserver(*this);
321   }
322
323   mShader = shader;
324   mShader->AddConnectionObserver( *this );
325   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
326   mResendFlag |= RESEND_DATA_PROVIDER;
327 }
328
329 void Renderer::SetGeometry( Render::Geometry* geometry )
330 {
331   DALI_ASSERT_DEBUG( geometry != NULL && "Geometry pointer is NULL");
332   mGeometry = geometry;
333
334   if( mRenderer )
335   {
336     mResendFlag |= RESEND_GEOMETRY;
337   }
338 }
339
340 void Renderer::SetDepthIndex( int depthIndex )
341 {
342   mDepthIndex = depthIndex;
343 }
344
345 void Renderer::SetFaceCullingMode( FaceCullingMode::Type faceCullingMode )
346 {
347   mFaceCullingMode = faceCullingMode;
348   mResendFlag |= RESEND_FACE_CULLING_MODE;
349 }
350
351 void Renderer::SetBlendMode( BlendMode::Type blendingMode )
352 {
353   mBlendMode = blendingMode;
354 }
355
356 void Renderer::SetBlendingOptions( unsigned int options )
357 {
358   if( mBlendBitmask != options)
359   {
360     mBlendBitmask = options;
361     mResendFlag |= RESEND_BLEND_BIT_MASK;
362   }
363 }
364
365 void Renderer::SetBlendColor( const Vector4& blendColor )
366 {
367   if( !mBlendColor )
368   {
369     mBlendColor = new Vector4( blendColor );
370   }
371   else
372   {
373     *mBlendColor = blendColor;
374   }
375
376   mResendFlag |= RESEND_BLEND_COLOR;
377 }
378
379 void Renderer::SetIndexedDrawFirstElement( size_t firstElement )
380 {
381   mIndexedDrawFirstElement = firstElement;
382   mResendFlag |= RESEND_INDEXED_DRAW_FIRST_ELEMENT;
383 }
384
385 void Renderer::SetIndexedDrawElementsCount( size_t elementsCount )
386 {
387   mIndexedDrawElementsCount = elementsCount;
388   mResendFlag |= RESEND_INDEXED_DRAW_ELEMENTS_COUNT;
389 }
390
391 void Renderer::EnablePreMultipliedAlpha( bool preMultipled )
392 {
393   mPremultipledAlphaEnabled = preMultipled;
394   mResendFlag |= RESEND_PREMULTIPLIED_ALPHA;
395 }
396
397 void Renderer::SetDepthWriteMode( DepthWriteMode::Type depthWriteMode )
398 {
399   mDepthWriteMode = depthWriteMode;
400   mResendFlag |= RESEND_DEPTH_WRITE_MODE;
401 }
402
403 void Renderer::SetDepthFunction( DepthFunction::Type depthFunction )
404 {
405   mDepthFunction = depthFunction;
406   mResendFlag |= RESEND_DEPTH_FUNCTION;
407 }
408
409 //Called when a node with this renderer is added to the stage
410 void Renderer::OnStageConnect()
411 {
412   ++mReferenceCount;
413   if( !mRenderer)
414   {
415     RenderDataProvider* dataProvider = NewRenderDataProvider();
416
417     mRenderer = Render::Renderer::New( dataProvider, mGeometry,
418                                        mBlendBitmask, mBlendColor,
419                                        static_cast< FaceCullingMode::Type >( mFaceCullingMode ),
420                                        mPremultipledAlphaEnabled,
421                                        mDepthWriteMode,
422                                        mDepthFunction );
423
424     mSceneController->GetRenderMessageDispatcher().AddRenderer( *mRenderer );
425     mResendFlag = 0;
426   }
427 }
428
429 //Called when the node with this renderer has gone out of the stage
430 void Renderer::OnStageDisconnect()
431 {
432   --mReferenceCount;
433   if( mReferenceCount == 0 )
434   {
435     mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer );
436     mRenderer = NULL;
437   }
438 }
439
440 //Called when SceneGraph::Renderer is added to update manager ( that happens when an "event-thread renderer" is created )
441 void Renderer::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
442 {
443   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
444   mSceneController = &sceneController;
445 }
446
447
448 //Called just before destroying the scene-graph renderer ( when the "event-thread renderer" is no longer referenced )
449 void Renderer::DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
450 {
451   //Remove renderer from RenderManager
452   if( mRenderer )
453   {
454     mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer );
455     mRenderer = NULL;
456     mSceneController = NULL;
457   }
458 }
459
460 RenderDataProvider* Renderer::NewRenderDataProvider()
461 {
462   RenderDataProvider* dataProvider = new RenderDataProvider();
463
464   dataProvider->mUniformMapDataProvider = this;
465   dataProvider->mShader = mShader;
466
467   if( mTextureSet )
468   {
469     size_t textureCount( mTextureSet->GetTextureCount() );
470     dataProvider->mTextures.resize( textureCount );
471     for( unsigned int i(0); i<textureCount; ++i )
472     {
473       dataProvider->mTextures[i] = Render::Texture( mTextureSet->GetTextureId(i),
474                                                     mTextureSet->GetTextureSampler(i));
475     }
476   }
477
478   return dataProvider;
479 }
480
481 Render::Renderer& Renderer::GetRenderer()
482 {
483   return *mRenderer;
484 }
485
486 const CollectedUniformMap& Renderer::GetUniformMap( BufferIndex bufferIndex ) const
487 {
488   return mCollectedUniformMap[bufferIndex];
489 };
490
491 void Renderer::GetReadyAndComplete( bool& ready, bool& complete ) const
492 {
493   ready = mResourcesReady;
494   complete = mFinishedResourceAcquisition;
495 }
496
497 Renderer::Opacity Renderer::GetOpacity( BufferIndex updateBufferIndex, const Node& node ) const
498 {
499   Renderer::Opacity opacity = Renderer::OPAQUE;
500
501   switch( mBlendMode )
502   {
503     case BlendMode::ON: // If the renderer should always be use blending
504     {
505       opacity = Renderer::TRANSLUCENT;
506       break;
507     }
508     case BlendMode::AUTO:
509     {
510       bool shaderRequiresBlending( mShader->HintEnabled( Dali::Shader::HINT_OUTPUT_IS_TRANSPARENT ) );
511       if( shaderRequiresBlending || ( mTextureSet && mTextureSet->HasAlpha() ) )
512       {
513         opacity = Renderer::TRANSLUCENT;
514       }
515       else // renderer should determine opacity using the actor color
516       {
517         float alpha = node.GetWorldColor( updateBufferIndex ).a;
518         if( alpha <= FULLY_TRANSPARENT )
519         {
520           opacity = TRANSPARENT;
521         }
522         else if( alpha <= FULLY_OPAQUE )
523         {
524           opacity = TRANSLUCENT;
525         }
526       }
527       break;
528     }
529     case BlendMode::OFF: // the renderer should never use blending
530     default:
531     {
532       opacity = Renderer::OPAQUE;
533       break;
534     }
535   }
536
537
538   return opacity;
539 }
540
541 void Renderer::TextureSetChanged()
542 {
543   mResendFlag |= RESEND_DATA_PROVIDER;
544 }
545
546 void Renderer::ConnectionsChanged( PropertyOwner& object )
547 {
548   // One of our child objects has changed it's connections. Ensure the uniform
549   // map gets regenerated during PrepareRender
550   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
551
552   // Ensure the child object pointers get re-sent to the renderer
553   mResendFlag |= RESEND_DATA_PROVIDER;
554 }
555
556 void Renderer::ConnectedUniformMapChanged()
557 {
558   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
559 }
560
561 void Renderer::UniformMappingsChanged( const UniformMap& mappings )
562 {
563   // The mappings are either from PropertyOwner base class, or the Actor
564   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
565 }
566
567 void Renderer::ObservedObjectDestroyed(PropertyOwner& owner)
568 {
569   if( reinterpret_cast<PropertyOwner*>(mTextureSet) == &owner )
570   {
571     mTextureSet = NULL;
572   }
573   else if( reinterpret_cast<PropertyOwner*>(mShader) == &owner )
574   {
575     mShader = NULL;
576   }
577 }
578
579 } // namespace SceneGraph
580 } // namespace Internal
581 } // namespace Dali