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