2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "scene-graph-renderer-attachment.h"
18 #include <dali/internal/update/effects/scene-graph-material.h>
19 #include <dali/internal/update/effects/scene-graph-sampler.h>
20 #include <dali/internal/update/common/uniform-map.h>
21 #include <dali/internal/update/geometry/scene-graph-geometry.h>
22 #include <dali/internal/update/resources/complete-status-manager.h>
23 #include <dali/internal/update/resources/resource-manager.h>
24 #include <dali/internal/render/data-providers/render-data-provider.h>
25 #include <dali/internal/render/queue/render-queue.h>
26 #include <dali/internal/render/renderers/render-renderer.h>
27 #include <dali/internal/render/shaders/scene-graph-shader.h>
29 #if defined(DEBUG_ENABLED)
30 Debug::Filter* gImageAttachmentLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_SCENE_GRAPH_IMAGE_ATTACHMENT");
32 #define ATTACHMENT_LOG(level) \
33 DALI_LOG_INFO(gImageAttachmentLogFilter, level, "SceneGraph::ImageAttachment::%s: this:%p\n", __FUNCTION__, this)
34 #define ATTACHMENT_LOG_FMT(level, format, args...) \
35 DALI_LOG_INFO(gImageAttachmentLogFilter, level, "SceneGraph::ImageAttachment::%s: this:%p " format, __FUNCTION__, this, ## args)
39 #define ATTACHMENT_LOG(level)
40 #define ATTACHMENT_LOG_FMT(level, format, args...)
45 namespace // unnamed namespace
47 const int REGENERATE_UNIFORM_MAP = 2;
48 const int COPY_UNIFORM_MAP = 1;
58 RendererAttachment* RendererAttachment::New()
60 return new RendererAttachment();
64 RendererAttachment::RendererAttachment()
65 : RenderableAttachment( false ),
69 mRegenerateUniformMap(REGENERATE_UNIFORM_MAP),
70 mResendDataProviders(false),
73 mUniformMapChanged[0]=false;
74 mUniformMapChanged[1]=false;
76 // Observe our own PropertyOwner's uniform map
77 AddUniformMapObserver( *this );
81 RendererAttachment::~RendererAttachment()
83 mMaterial->RemoveConnectionObserver(*this);
84 mGeometry->RemoveConnectionObserver(*this);
90 void RendererAttachment::Initialize2( BufferIndex updateBufferIndex )
92 DALI_ASSERT_DEBUG( mSceneController );
95 void RendererAttachment::OnDestroy2()
99 void RendererAttachment::ConnectedToSceneGraph()
101 mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
102 mParent->AddUniformMapObserver( *this ); // Watch actor's uniform maps
104 DALI_ASSERT_DEBUG( mParent != NULL );
106 RenderDataProvider* dataProvider = NewRenderDataProvider();
108 mRenderer = NewRenderer::New( *mParent, dataProvider );
109 mSceneController->GetRenderMessageDispatcher().AddRenderer( *mRenderer );
112 void RendererAttachment::DisconnectedFromSceneGraph()
114 mRegenerateUniformMap = 0;
115 mParent->RemoveUniformMapObserver( *this );
117 DALI_ASSERT_DEBUG( mSceneController );
118 mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mRenderer );
122 void RendererAttachment::SetMaterial( BufferIndex updateBufferIndex, Material* material)
124 DALI_ASSERT_DEBUG( material != NULL && "Material pointer is NULL" );
126 mMaterial = material;
127 mMaterial->AddConnectionObserver( *this );
128 mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
130 mResendDataProviders = true;
133 Material& RendererAttachment::GetMaterial()
138 void RendererAttachment::SetGeometry( BufferIndex updateBufferIndex, Geometry* geometry)
140 DALI_ASSERT_DEBUG( geometry != NULL && "Geometry pointer is NULL");
142 mGeometry = geometry;
143 mGeometry->AddConnectionObserver( *this ); // Observe geometry connections / uniform mapping changes
144 mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
146 mResendDataProviders = true;
149 Geometry& RendererAttachment::GetGeometry()
154 void RendererAttachment::SetDepthIndex( BufferIndex updateBufferIndex, int depthIndex )
156 mDepthIndex.Bake(updateBufferIndex, depthIndex);
160 // only do this if we are on-stage
161 mParent->SetDirtyFlag( SortModifierFlag );
164 // @todo MESH_REWORK Change SortTransparentRenderItems to use GetDepthIndex instead
165 mSortModifier = depthIndex;
168 void RendererAttachment::ResetToBaseValues( BufferIndex updateBufferIndex )
170 mDepthIndex.ResetToBaseValue( updateBufferIndex );
173 Renderer& RendererAttachment::GetRenderer()
178 const Renderer& RendererAttachment::GetRenderer() const
183 // Called by ProcessRenderTasks after DoPrepareRender
184 bool RendererAttachment::IsFullyOpaque( BufferIndex updateBufferIndex )
190 opaque = mParent->GetWorldColor( updateBufferIndex ).a >= FULLY_OPAQUE;
193 if( opaque && mMaterial != NULL )
195 // Calculated by material in PrepareRender step
196 opaque = ! mMaterial->GetBlendingEnabled( updateBufferIndex );
202 void RendererAttachment::SizeChanged( BufferIndex updateBufferIndex )
207 bool RendererAttachment::DoPrepareResources(
208 BufferIndex updateBufferIndex,
209 ResourceManager& resourceManager )
211 DALI_ASSERT_DEBUG( mSceneController );
213 CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
215 mFinishedResourceAcquisition = false;
217 // Can only be considered ready when all the scene graph objects are connected to the renderer
219 ( mGeometry->GetVertexBuffers().Count() > 0 ) &&
221 ( mMaterial->GetShader() != NULL ) )
223 unsigned int completeCount = 0;
224 unsigned int neverCount = 0;
225 unsigned int frameBufferCount = 0;
227 Vector<Sampler*>& samplers = mMaterial->GetSamplers();
228 for( Vector<Sampler*>::ConstIterator iter = samplers.Begin();
229 iter != samplers.End(); ++iter )
231 Sampler* sampler = *iter;
233 ResourceId textureId = sampler->GetTextureId( updateBufferIndex );
234 BitmapMetadata metaData = resourceManager.GetBitmapMetadata( textureId );
236 sampler->SetFullyOpaque( metaData.IsFullyOpaque() );
238 switch( completeStatusManager.GetStatus( textureId ) )
240 case CompleteStatusManager::NOT_READY:
243 if( metaData.GetIsFramebuffer() )
247 FollowTracker( textureId ); // @todo MESH_REWORK Trackers per sampler rather than per actor?
251 case CompleteStatusManager::COMPLETE:
257 case CompleteStatusManager::NEVER:
265 // We are ready if all samplers are complete, or those that aren't are framebuffers
266 // We are complete if all samplers are either complete or will never complete
268 ready = ( completeCount + frameBufferCount >= samplers.Count() ) ;
269 mFinishedResourceAcquisition = ( completeCount + neverCount >= samplers.Count() );
276 // Uniform maps are checked in the following priority order:
277 // Renderer (this object)
284 void RendererAttachment::DoPrepareRender( BufferIndex updateBufferIndex )
286 // @todo MESH_REWORK - call DoPrepareRender on all scene objects? in caller class?
287 mMaterial->PrepareRender( updateBufferIndex );
289 if( mRegenerateUniformMap > 0)
291 if( mRegenerateUniformMap == REGENERATE_UNIFORM_MAP)
293 DALI_ASSERT_DEBUG( mGeometry != NULL && "No geometry available in DoPrepareRender()" );
294 DALI_ASSERT_DEBUG( mMaterial != NULL && "No geometry available in DoPrepareRender()" );
296 CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ];
299 const UniformMap& rendererUniformMap = PropertyOwner::GetUniformMap();
300 AddMappings( localMap, rendererUniformMap );
302 const UniformMap& actorUniformMap = mParent->GetUniformMap();
303 AddMappings( localMap, actorUniformMap );
305 AddMappings( localMap, mMaterial->GetUniformMap() );
306 Vector<Sampler*>& samplers = mMaterial->GetSamplers();
307 for( Vector<Sampler*>::ConstIterator iter = samplers.Begin(), end = samplers.End();
311 const SceneGraph::Sampler* sampler = (*iter);
312 AddMappings( localMap, sampler->GetUniformMap() );
315 AddMappings( localMap, mMaterial->GetShader()->GetUniformMap() );
317 AddMappings( localMap, mGeometry->GetUniformMap() );
319 Vector<PropertyBuffer*>& vertexBuffers = mGeometry->GetVertexBuffers();
320 for( Vector<PropertyBuffer*>::ConstIterator iter = vertexBuffers.Begin(), end = vertexBuffers.End() ;
324 const SceneGraph::PropertyBuffer* vertexBuffer = *iter;
325 AddMappings( localMap, vertexBuffer->GetUniformMap() );
328 PropertyBuffer* indexBuffer = mGeometry->GetIndexBuffer();
331 AddMappings( localMap, indexBuffer->GetUniformMap() );
334 mUniformMapChanged[updateBufferIndex] = true;
336 else if( mRegenerateUniformMap == COPY_UNIFORM_MAP )
338 // Copy old map into current map
339 CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ];
340 CollectedUniformMap& oldMap = mCollectedUniformMap[ 1-updateBufferIndex ];
342 localMap.Resize( oldMap.Count() );
344 unsigned int index=0;
345 for( CollectedUniformMap::Iterator iter = oldMap.Begin(), end = oldMap.End() ; iter != end ; ++iter )
347 localMap[index] = *iter;
350 mUniformMapChanged[updateBufferIndex] = true;
353 mRegenerateUniformMap--;
356 if( mResendDataProviders )
358 RenderDataProvider* dataProvider = NewRenderDataProvider();
360 // Tell renderer about a new provider
361 // @todo MESH_REWORK Should we instead create a new renderer when these change?
363 typedef MessageValue1< NewRenderer, OwnerPointer<RenderDataProvider> > DerivedType;
364 unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
365 new (slot) DerivedType( mRenderer, &NewRenderer::SetRenderDataProvider, dataProvider );
366 mResendDataProviders = false;
371 void RendererAttachment::ConnectionsChanged( PropertyOwner& object )
373 // One of our child objects has changed it's connections. Ensure the uniform
374 // map gets regenerated during PrepareRender
375 mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
377 // Ensure the child object pointers get re-sent to the renderer
378 mResendDataProviders = true;
381 void RendererAttachment::ConnectedUniformMapChanged()
383 mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
386 void RendererAttachment::UniformMappingsChanged( const UniformMap& mappings )
388 // The mappings are either from PropertyOwner base class, or the Actor
389 mRegenerateUniformMap = REGENERATE_UNIFORM_MAP;
392 bool RendererAttachment::GetUniformMapChanged( BufferIndex bufferIndex ) const
394 return mUniformMapChanged[bufferIndex];
397 const CollectedUniformMap& RendererAttachment::GetUniformMap( BufferIndex bufferIndex ) const
399 return mCollectedUniformMap[ bufferIndex ];
402 void RendererAttachment::AddMappings( CollectedUniformMap& localMap, const UniformMap& uniformMap )
404 // Iterate thru uniformMap.
405 // Any maps that aren't in localMap should be added in a single step
406 CollectedUniformMap newUniformMappings;
408 for( unsigned int i=0, count=uniformMap.Count(); i<count; ++i )
410 UniformPropertyMapping::Hash nameHash = uniformMap[i].uniformNameHash;
413 for( CollectedUniformMap::Iterator iter = localMap.Begin() ; iter != localMap.End() ; ++iter )
415 const UniformPropertyMapping* map = (*iter);
416 if( map->uniformNameHash == nameHash )
418 if( map->uniformName == uniformMap[i].uniformName )
427 // it's a new mapping. Add raw ptr to temporary list
428 newUniformMappings.PushBack( &uniformMap[i] );
432 if( newUniformMappings.Count() > 0 )
434 localMap.Reserve( localMap.Count() + newUniformMappings.Count() );
436 for( CollectedUniformMap::Iterator iter = newUniformMappings.Begin(),
437 end = newUniformMappings.End() ;
441 const UniformPropertyMapping* map = (*iter);
442 localMap.PushBack( map );
444 //@todo MESH_REWORK Use memcpy to copy ptrs from one array to the other
448 RenderDataProvider* RendererAttachment::NewRenderDataProvider()
450 RenderDataProvider* dataProvider = new RenderDataProvider();
452 dataProvider->mGeometryDataProvider = mGeometry;
453 dataProvider->mMaterialDataProvider = mMaterial;
454 dataProvider->mUniformMapDataProvider = this;
455 dataProvider->mShader = mMaterial->GetShader();
456 dataProvider->mIndexBuffer = mGeometry->GetIndexBuffer();
458 Vector<PropertyBuffer*>& vertexBuffers = mGeometry->GetVertexBuffers();
459 dataProvider->mVertexBuffers.Reserve( vertexBuffers.Count() );
461 for( Vector<PropertyBuffer*>::Iterator iter = vertexBuffers.Begin() ;
462 iter != vertexBuffers.End();
465 dataProvider->mVertexBuffers.PushBack(*iter); // Convert from derived type to base type
468 Vector<Sampler*>& samplers = mMaterial->GetSamplers();
469 dataProvider->mSamplers.Reserve( samplers.Count() );
470 for( Vector<Sampler*>::Iterator iter = samplers.Begin() ;
471 iter != samplers.End();
474 dataProvider->mSamplers.PushBack(*iter); // Convert from derived type to base type
480 } // namespace SceneGraph
481 } // namespace Internal