eac06efc5d8ed8ffde9f352048d5c609f9592e4d
[platform/core/uifw/dali-core.git] / dali / internal / update / node-attachments / scene-graph-renderer-attachment.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 #include "scene-graph-renderer-attachment.h"
18 #include <dali/internal/update/common/uniform-map.h>
19 #include <dali/internal/update/manager/prepare-render-instructions.h>
20 #include <dali/internal/update/rendering/scene-graph-geometry.h>
21 #include <dali/internal/update/rendering/scene-graph-material.h>
22 #include <dali/internal/update/rendering/scene-graph-sampler.h>
23 #include <dali/internal/update/resources/complete-status-manager.h>
24 #include <dali/internal/update/resources/resource-manager.h>
25 #include <dali/internal/render/data-providers/render-data-provider.h>
26 #include <dali/internal/render/queue/render-queue.h>
27 #include <dali/internal/render/renderers/render-renderer.h>
28 #include <dali/internal/render/shaders/scene-graph-shader.h>
29
30 #if defined(DEBUG_ENABLED)
31 Debug::Filter* gImageAttachmentLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_SCENE_GRAPH_IMAGE_ATTACHMENT");
32
33 #define ATTACHMENT_LOG(level)                                                 \
34   DALI_LOG_INFO(gImageAttachmentLogFilter, level, "SceneGraph::ImageAttachment::%s: this:%p\n", __FUNCTION__, this)
35 #define ATTACHMENT_LOG_FMT(level, format, args...) \
36   DALI_LOG_INFO(gImageAttachmentLogFilter, level, "SceneGraph::ImageAttachment::%s: this:%p " format, __FUNCTION__, this, ## args)
37
38 #else
39
40 #define ATTACHMENT_LOG(level)
41 #define ATTACHMENT_LOG_FMT(level, format, args...)
42
43 #endif
44
45
46 namespace // unnamed namespace
47 {
48 const int REGENERATE_UNIFORM_MAP = 2;
49 const int COPY_UNIFORM_MAP       = 1;
50 }
51
52 namespace Dali
53 {
54 namespace Internal
55 {
56 namespace SceneGraph
57 {
58
59 RendererAttachment* RendererAttachment::New()
60 {
61   return new RendererAttachment();
62 }
63
64
65 RendererAttachment::RendererAttachment()
66 : RenderableAttachment( false ),
67   mRenderer(NULL),
68   mMaterial(NULL),
69   mGeometry(NULL),
70   mRegenerateUniformMap(REGENERATE_UNIFORM_MAP),
71   mResendDataProviders(false),
72   mResendGeometry(false),
73   mDepthIndex(0)
74 {
75   mUniformMapChanged[0]=false;
76   mUniformMapChanged[1]=false;
77
78   // Observe our own PropertyOwner's uniform map
79   AddUniformMapObserver( *this );
80 }
81
82
83 RendererAttachment::~RendererAttachment()
84 {
85   if (mMaterial)
86   {
87     mMaterial->RemoveConnectionObserver(*this);
88     mMaterial=NULL;
89   }
90   if (mGeometry)
91   {
92     mGeometry->RemoveConnectionObserver(*this);
93     mGeometry=NULL;
94   }
95 }
96
97 void RendererAttachment::Initialize2( BufferIndex updateBufferIndex )
98 {
99   DALI_ASSERT_DEBUG( mSceneController );
100 }
101
102 void RendererAttachment::OnDestroy2()
103 {
104 }
105
106 void RendererAttachment::ConnectedToSceneGraph()
107 {
108   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
109   mParent->AddUniformMapObserver( *this ); // Watch actor's uniform maps
110
111   DALI_ASSERT_DEBUG( mParent != NULL );
112
113   RenderDataProvider* dataProvider = NewRenderDataProvider();
114
115   RenderGeometry* renderGeometry = mGeometry->GetRenderGeometry(mSceneController);
116   mRenderer = NewRenderer::New( *mParent, dataProvider, renderGeometry );
117   mSceneController->GetRenderMessageDispatcher().AddRenderer( *mRenderer );
118 }
119
120 void RendererAttachment::DisconnectedFromSceneGraph()
121 {
122   mRegenerateUniformMap = 0;
123   mParent->RemoveUniformMapObserver( *this );
124
125   mGeometry->OnRendererDisconnect();
126
127   DALI_ASSERT_DEBUG( mSceneController );
128   mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer );
129   mRenderer = NULL;
130 }
131
132 void RendererAttachment::SetMaterial( BufferIndex updateBufferIndex, Material* material)
133 {
134   DALI_ASSERT_DEBUG( material != NULL && "Material pointer is NULL" );
135
136   mMaterial = material;
137   mMaterial->AddConnectionObserver( *this );
138   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
139
140   mResendDataProviders = true;
141 }
142
143 Material& RendererAttachment::GetMaterial()
144 {
145   return *mMaterial;
146 }
147
148 void RendererAttachment::SetGeometry( BufferIndex updateBufferIndex, Geometry* geometry)
149 {
150   DALI_ASSERT_DEBUG( geometry != NULL && "Geometry pointer is NULL");
151   if( mGeometry)
152   {
153     mGeometry->RemoveConnectionObserver(*this);
154     mGeometry->OnRendererDisconnect();
155   }
156
157   mGeometry = geometry;
158   mGeometry->AddConnectionObserver( *this ); // Observe geometry connections / uniform mapping changes
159   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
160
161   if( mRenderer )
162   {
163     mResendGeometry = true;
164   }
165 }
166
167 Geometry& RendererAttachment::GetGeometry()
168 {
169   return *mGeometry;
170 }
171
172 void RendererAttachment::SetSortAttributes( BufferIndex bufferIndex, RendererWithSortAttributes& sortAttributes )
173 {
174   sortAttributes.shader = mMaterial->GetShader();
175   sortAttributes.material = mMaterial;
176   sortAttributes.geometry = mGeometry;
177 }
178
179 void RendererAttachment::SetDepthIndex( int depthIndex )
180 {
181   mDepthIndex = depthIndex;
182
183   if( mParent )
184   {
185     // only do this if we are on-stage. Ensures the render lists are re-sorted
186     mParent->SetDirtyFlag( SortModifierFlag );
187   }
188 }
189
190 Renderer& RendererAttachment::GetRenderer()
191 {
192   return *mRenderer;
193 }
194
195 const Renderer& RendererAttachment::GetRenderer() const
196 {
197   return *mRenderer;
198 }
199
200 // Called by ProcessRenderTasks after DoPrepareRender
201 bool RendererAttachment::IsFullyOpaque( BufferIndex updateBufferIndex )
202 {
203   bool opaque = false;
204
205   if( mMaterial != NULL )
206   {
207     Material::BlendPolicy blendPolicy = mMaterial->GetBlendPolicy();
208     switch( blendPolicy )
209     {
210       case Material::OPAQUE:
211       {
212         opaque = true;
213         break;
214       }
215       case Material::TRANSPARENT:
216       {
217         opaque = false;
218         break;
219       }
220       case Material::USE_ACTOR_COLOR:
221       {
222         if( mParent )
223         {
224           opaque = mParent->GetWorldColor( updateBufferIndex ).a >= FULLY_OPAQUE;
225         }
226         break;
227       }
228     }
229   }
230
231   return opaque;
232 }
233
234 void RendererAttachment::SizeChanged( BufferIndex updateBufferIndex )
235 {
236   // Do nothing.
237 }
238
239 bool RendererAttachment::DoPrepareResources(
240   BufferIndex updateBufferIndex,
241   ResourceManager& resourceManager )
242 {
243   DALI_ASSERT_DEBUG( mSceneController );
244
245   CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
246   bool ready = false;
247   mFinishedResourceAcquisition = false;
248
249   // Can only be considered ready when all the scene graph objects are connected to the renderer
250   if( ( mGeometry ) &&
251       ( mGeometry->GetVertexBuffers().Count() > 0 ) &&
252       ( mMaterial ) &&
253       ( mMaterial->GetShader() != NULL ) )
254   {
255     unsigned int completeCount = 0;
256     unsigned int neverCount = 0;
257     unsigned int frameBufferCount = 0;
258
259     Vector<Sampler*>& samplers = mMaterial->GetSamplers();
260     for( Vector<Sampler*>::ConstIterator iter = samplers.Begin();
261          iter != samplers.End(); ++iter )
262     {
263       Sampler* sampler = *iter;
264
265       ResourceId textureId = sampler->GetTextureId( updateBufferIndex );
266       BitmapMetadata metaData = resourceManager.GetBitmapMetadata( textureId );
267
268       sampler->SetFullyOpaque( metaData.IsFullyOpaque() );
269
270       switch( completeStatusManager.GetStatus( textureId ) )
271       {
272         case CompleteStatusManager::NOT_READY:
273         {
274           if( metaData.GetIsFramebuffer() )
275           {
276             frameBufferCount++;
277           }
278           FollowTracker( textureId ); // @todo MESH_REWORK Trackers per sampler rather than per actor?
279         }
280         break;
281
282         case CompleteStatusManager::COMPLETE:
283         {
284           completeCount++;
285         }
286         break;
287
288         case CompleteStatusManager::NEVER:
289         {
290           neverCount++;
291         }
292         break;
293       }
294     }
295
296     // We are ready if all samplers are complete, or those that aren't are framebuffers
297     // We are complete if all samplers are either complete or will never complete
298
299     ready = ( completeCount + frameBufferCount >= samplers.Count() ) ;
300     mFinishedResourceAcquisition = ( completeCount + neverCount >= samplers.Count() );
301   }
302
303   return ready;
304 }
305
306
307 // Uniform maps are checked in the following priority order:
308 //   Renderer (this object)
309 //   Actor
310 //   Material
311 //   Samplers
312 //   Shader
313 //   Geometry
314 //   VertexBuffers
315 void RendererAttachment::DoPrepareRender( BufferIndex updateBufferIndex )
316 {
317   // @todo MESH_REWORK - call DoPrepareRender on all scene objects? in caller class?
318   mMaterial->PrepareRender( updateBufferIndex );
319
320   if( mRegenerateUniformMap > 0)
321   {
322     if( mRegenerateUniformMap == REGENERATE_UNIFORM_MAP)
323     {
324       DALI_ASSERT_DEBUG( mGeometry != NULL && "No geometry available in DoPrepareRender()" );
325       DALI_ASSERT_DEBUG( mMaterial != NULL && "No geometry available in DoPrepareRender()" );
326
327       CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ];
328       localMap.Resize(0);
329
330       const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap();
331       AddMappings( localMap, rendererUniformMap );
332
333       const UniformMap& actorUniformMap = mParent->GetUniformMap();
334       AddMappings( localMap, actorUniformMap );
335
336       AddMappings( localMap, mMaterial->GetUniformMap() );
337       Vector<Sampler*>& samplers = mMaterial->GetSamplers();
338       for( Vector<Sampler*>::ConstIterator iter = samplers.Begin(), end = samplers.End();
339            iter != end ;
340            ++iter )
341       {
342         const SceneGraph::Sampler* sampler = (*iter);
343         AddMappings( localMap, sampler->GetUniformMap() );
344       }
345
346       AddMappings( localMap, mMaterial->GetShader()->GetUniformMap() );
347
348       AddMappings( localMap, mGeometry->GetUniformMap() );
349
350       Vector<PropertyBuffer*>& vertexBuffers = mGeometry->GetVertexBuffers();
351       for( Vector<PropertyBuffer*>::ConstIterator iter = vertexBuffers.Begin(), end = vertexBuffers.End() ;
352            iter != end ;
353            ++iter )
354       {
355         const SceneGraph::PropertyBuffer* vertexBuffer = *iter;
356         AddMappings( localMap, vertexBuffer->GetUniformMap() );
357       }
358
359       PropertyBuffer* indexBuffer = mGeometry->GetIndexBuffer();
360       if( indexBuffer )
361       {
362         AddMappings( localMap, indexBuffer->GetUniformMap() );
363       }
364
365       mUniformMapChanged[updateBufferIndex] = true;
366     }
367     else if( mRegenerateUniformMap == COPY_UNIFORM_MAP )
368     {
369       // Copy old map into current map
370       CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ];
371       CollectedUniformMap& oldMap = mCollectedUniformMap[ 1-updateBufferIndex ];
372
373       localMap.Resize( oldMap.Count() );
374
375       unsigned int index=0;
376       for( CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End() ; iter != end ; ++iter, ++index )
377       {
378         localMap[index] = *iter;
379       }
380
381       mUniformMapChanged[updateBufferIndex] = true;
382     }
383
384     mRegenerateUniformMap--;
385   }
386
387   if( mResendDataProviders )
388   {
389     RenderDataProvider* dataProvider = NewRenderDataProvider();
390
391     // Tell renderer about a new provider
392     // @todo MESH_REWORK Should we instead create a new renderer when these change?
393
394     typedef MessageValue1< NewRenderer, OwnerPointer<RenderDataProvider> > DerivedType;
395     unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
396     new (slot) DerivedType( mRenderer, &NewRenderer::SetRenderDataProvider, dataProvider );
397     mResendDataProviders = false;
398   }
399
400   if( mResendGeometry )
401   {
402     // The first call to GetRenderGeometry() creates the geometry and sends it in a message
403     RenderGeometry* geometry = mGeometry->GetRenderGeometry( mSceneController );
404
405     typedef MessageValue1< NewRenderer, RenderGeometry* > DerivedType;
406     unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
407
408     new (slot) DerivedType( mRenderer, &NewRenderer::SetGeometry, geometry );
409     mResendGeometry = false;
410   }
411 }
412
413 void RendererAttachment::ConnectionsChanged( PropertyOwner& object )
414 {
415   // One of our child objects has changed it's connections. Ensure the uniform
416   // map gets regenerated during PrepareRender
417   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
418
419   // Ensure the child object pointers get re-sent to the renderer
420   mResendDataProviders = true;
421 }
422
423 void RendererAttachment::ConnectedUniformMapChanged()
424 {
425   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
426 }
427
428 void RendererAttachment::UniformMappingsChanged( const UniformMap& mappings )
429 {
430   // The mappings are either from PropertyOwner base class, or the Actor
431   mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
432 }
433
434 bool RendererAttachment::GetUniformMapChanged( BufferIndex bufferIndex ) const
435 {
436   return mUniformMapChanged[bufferIndex];
437 }
438
439 const CollectedUniformMap& RendererAttachment::GetUniformMap( BufferIndex bufferIndex ) const
440 {
441   return mCollectedUniformMap[ bufferIndex ];
442 }
443
444 void RendererAttachment::AddMappings( CollectedUniformMap& localMap, const UniformMap& uniformMap )
445 {
446   // Iterate thru uniformMap.
447   //   Any maps that aren't in localMap should be added in a single step
448   CollectedUniformMap newUniformMappings;
449
450   for( unsigned int i=0, count=uniformMap.Count(); i<count; ++i )
451   {
452     UniformPropertyMapping::Hash nameHash = uniformMap[i].uniformNameHash;
453     bool found = false;
454
455     for( CollectedUniformMap::Iterator iter = localMap.Begin() ; iter != localMap.End() ; ++iter )
456     {
457       const UniformPropertyMapping* map = (*iter);
458       if( map->uniformNameHash == nameHash )
459       {
460         if( map->uniformName == uniformMap[i].uniformName )
461         {
462           found = true;
463           break;
464         }
465       }
466     }
467     if( !found )
468     {
469       // it's a new mapping. Add raw ptr to temporary list
470       newUniformMappings.PushBack( &uniformMap[i] );
471     }
472   }
473
474   if( newUniformMappings.Count() > 0 )
475   {
476     localMap.Reserve( localMap.Count() + newUniformMappings.Count() );
477
478     for( CollectedUniformMap::Iterator iter = newUniformMappings.Begin(),
479            end = newUniformMappings.End() ;
480          iter != end ;
481          ++iter )
482     {
483       const UniformPropertyMapping* map = (*iter);
484       localMap.PushBack( map );
485     }
486     //@todo MESH_REWORK Use memcpy to copy ptrs from one array to the other
487   }
488 }
489
490 RenderDataProvider* RendererAttachment::NewRenderDataProvider()
491 {
492   RenderDataProvider* dataProvider = new RenderDataProvider();
493
494   dataProvider->mMaterialDataProvider = mMaterial;
495   dataProvider->mUniformMapDataProvider = this;
496   dataProvider->mShader = mMaterial->GetShader();
497
498   Vector<Sampler*>& samplers = mMaterial->GetSamplers();
499   dataProvider->mSamplers.Reserve( samplers.Count() );
500   for( Vector<Sampler*>::Iterator iter = samplers.Begin() ;
501        iter != samplers.End();
502        ++iter )
503   {
504     dataProvider->mSamplers.PushBack(*iter); // Convert from derived type to base type
505   }
506   return dataProvider;
507 }
508
509
510 } // namespace SceneGraph
511 } // namespace Internal
512 } // namespace Dali