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.
18 #include "scene-graph-material.h"
21 #include <dali/public-api/actors/blending.h>
22 #include <dali/public-api/shader-effects/shader-effect.h>
23 #include <dali/devel-api/rendering/material.h>
24 #include <dali/internal/common/internal-constants.h>
25 #include <dali/internal/update/resources/texture-metadata.h>
26 #include <dali/internal/update/resources/resource-manager.h>
27 #include <dali/internal/render/shaders/scene-graph-shader.h>
28 #include <dali/internal/common/memory-pool-object-allocator.h>
30 namespace //Unnamed namespace
32 //Memory pool used to allocate new materials. Memory used by this pool will be released when shutting down DALi
33 Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::Material> gMaterialMemoryPool;
45 Material* Material::New()
47 return new ( gMaterialMemoryPool.AllocateRawThreadSafe() ) Material();
55 mConnectionObservers(),
56 mResourcesReady( false ),
57 mFinishedResourceAcquisition( false ),
58 mMaterialChanged( true )
60 // Observe own property-owner's uniform map
61 AddUniformMapObserver( *this );
66 mConnectionObservers.Destroy( *this );
69 void Material::operator delete( void* ptr )
71 gMaterialMemoryPool.FreeThreadSafe( static_cast<Material*>( ptr ) );
74 void Material::Prepare( const ResourceManager& resourceManager )
76 if( mMaterialChanged )
78 unsigned int opaqueCount = 0;
79 unsigned int completeCount = 0;
80 unsigned int failedCount = 0;
81 unsigned int frameBufferCount = 0;
82 const std::size_t textureCount( mTextureId.Count() );
83 if( textureCount > 0 )
85 for( unsigned int i(0); i<textureCount; ++i )
87 const ResourceId textureId = mTextureId[ i ];
88 TextureMetadata* metadata = NULL;
89 // if there is metadata, resource is loaded
90 if( resourceManager.GetTextureMetadata( textureId, metadata ) )
92 DALI_ASSERT_DEBUG( metadata );
93 // metadata is valid pointer from now on
94 if( metadata->IsFullyOpaque() )
99 if( metadata->IsFramebuffer() )
101 if( metadata->HasFrameBufferBeenRenderedTo() )
112 // loaded so will complete this frame
115 // no point checking failure as there is no metadata for failed loads
117 // if no metadata, loading can be failed
118 else if( resourceManager.HasResourceLoadFailed( textureId ) )
125 // whether the textures or the shader require the opacity to be translucent
126 mIsTranslucent = ( opaqueCount != textureCount ) || ( mShader && mShader->GeometryHintEnabled( Dali::ShaderEffect::HINT_BLENDING ) );
128 // ready for rendering when all textures are either successfully loaded or they are FBOs
129 mResourcesReady = (completeCount + frameBufferCount >= textureCount);
131 // material is complete if all resources are either loaded or failed or, if they are FBOs have been rendererd to
132 mFinishedResourceAcquisition = ( completeCount + failedCount == textureCount );
134 if( mFinishedResourceAcquisition )
136 // material is now considered not changed
137 mMaterialChanged = false;
142 void Material::SetShader( Shader* shader )
144 mMaterialChanged = true;
146 mShader->AddUniformMapObserver( *this );
148 // Inform NewRenderer about this shader: (Will force a re-load of the
149 // shader from the data providers)
150 mConnectionObservers.ConnectionsChanged(*this);
153 Shader* Material::GetShader() const
158 bool Material::IsTranslucent() const
160 return mIsTranslucent;
163 void Material::AddTexture( const std::string& name, ResourceId id, Render::Sampler* sampler )
165 mMaterialChanged = true;
166 mTextureId.PushBack( id );
167 mUniformName.push_back( name );
168 mSamplers.PushBack( sampler );
170 mConnectionObservers.ConnectionsChanged(*this);
173 void Material::RemoveTexture( size_t index )
175 mMaterialChanged = true;
176 mTextureId.Erase( mTextureId.Begin()+index );
177 mUniformName.erase( mUniformName.begin() + index );
178 mSamplers.Erase( mSamplers.Begin()+index );
179 mConnectionObservers.ConnectionsChanged( *this );
182 void Material::SetTextureImage( size_t index, ResourceId id )
184 mMaterialChanged = true;
185 mTextureId[index] = id;
186 mConnectionObservers.ConnectionsChanged(*this);
189 void Material::SetTextureSampler( size_t index, Render::Sampler* sampler)
191 // sampler does not change material blending of readiness
192 mSamplers[index] = sampler;
193 mConnectionObservers.ConnectionsChanged(*this);
196 void Material::SetTextureUniformName( size_t index, const std::string& uniformName)
198 // Uniform name does not change material blending of readiness
199 mUniformName[index] = uniformName;
200 mConnectionObservers.ConnectionsChanged(*this);
203 void Material::GetResourcesStatus( bool& resourcesReady, bool& finishedResourceAcquisition )
205 resourcesReady = mResourcesReady;
206 finishedResourceAcquisition = mFinishedResourceAcquisition;
209 void Material::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
213 void Material::DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
217 void Material::AddConnectionObserver( ConnectionChangePropagator::Observer& observer )
219 mConnectionObservers.Add(observer);
222 void Material::RemoveConnectionObserver( ConnectionChangePropagator::Observer& observer )
224 mConnectionObservers.Remove(observer);
227 void Material::UniformMappingsChanged( const UniformMap& mappings )
229 // Our uniform map, or that of one of the watched children has changed.
230 // Inform connected observers.
231 mConnectionObservers.ConnectedUniformMapChanged();
234 void Material::ConnectionsChanged( PropertyOwner& owner )
236 // this should happen in the case of shader properties changed
237 mMaterialChanged = true;
239 mConnectionObservers.ConnectionsChanged(*this);
242 void Material::ConnectedUniformMapChanged( )
244 mConnectionObservers.ConnectedUniformMapChanged();
247 } // namespace SceneGraph
249 } // namespace Internal