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