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