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.
19 #include <dali/internal/event/effects/material-impl.h> // Dali::Internal::Material
22 #include <dali/public-api/shader-effects/material.h> // Dali::Internal::Material
23 #include <dali/internal/event/common/object-impl-helper.h> // Dali::Internal::ObjectHelper
24 #include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
25 #include <dali/internal/update/effects/scene-graph-material.h>
26 #include <dali/internal/update/effects/scene-graph-sampler.h>
27 #include <dali/internal/update/manager/update-manager.h>
38 * |name |type |writable|animatable|constraint-input|enum for index-checking|
40 DALI_PROPERTY_TABLE_BEGIN
41 DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Material::Property::COLOR )
42 DALI_PROPERTY( "face-culling-mode", STRING, true, false, false, Dali::Material::Property::FACE_CULLING_MODE )
43 DALI_PROPERTY( "blending-mode", STRING, true, false, false, Dali::Material::Property::BLENDING_MODE )
44 DALI_PROPERTY( "blend-equation-rgb", STRING, true, false, false, Dali::Material::Property::BLEND_EQUATION_RGB )
45 DALI_PROPERTY( "blend-equation-alpha", STRING, true, false, false, Dali::Material::Property::BLEND_EQUATION_ALPHA )
46 DALI_PROPERTY( "source-blend-factor-rgb", STRING, true, false, false, Dali::Material::Property::BLENDING_SRC_FACTOR_RGB )
47 DALI_PROPERTY( "destination-blend-factor-rgb", STRING, true, false, false, Dali::Material::Property::BLENDING_DEST_FACTOR_RGB )
48 DALI_PROPERTY( "source-blend-factor-alpha", STRING, true, false, false, Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA )
49 DALI_PROPERTY( "destination-blend-factor-alpha", STRING, true, false, false, Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA )
50 DALI_PROPERTY( "blend-color", VECTOR4, true, true, true, Dali::Material::Property::BLEND_COLOR )
51 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
53 const ObjectImplHelper<DEFAULT_PROPERTY_COUNT> MATERIAL_IMPL = { DEFAULT_PROPERTY_DETAILS };
55 } // unnamed namespace
57 MaterialPtr Material::New()
59 MaterialPtr material( new Material() );
60 material->Initialize();
64 void Material::SetShader( Shader& shader )
66 DALI_ASSERT_DEBUG( mSceneObject )
67 mShaderConnector.Set( shader, OnStage() );
69 const SceneGraph::Shader& sceneGraphShader = dynamic_cast<const SceneGraph::Shader&>( *shader.GetSceneObject() );
70 SceneGraph::SetShaderMessage( GetEventThreadServices(), *mSceneObject, sceneGraphShader );
73 void Material::AddSampler( Sampler& sampler )
75 SamplerConnector connector;
76 connector.Set( sampler, OnStage() );
77 mSamplerConnectors.push_back( connector );
79 const SceneGraph::Sampler& sceneGraphSampler = dynamic_cast<const SceneGraph::Sampler&>( *sampler.GetSceneObject() );
80 SceneGraph::AddSamplerMessage( GetEventThreadServices(), *mSceneObject, sceneGraphSampler );
83 std::size_t Material::GetNumberOfSamplers() const
85 return mSamplerConnectors.size();
88 void Material::RemoveSampler( std::size_t index )
90 mSamplerConnectors.erase( mSamplerConnectors.begin() + index );
93 Sampler* Material::GetSamplerAt( unsigned int index ) const
95 return mSamplerConnectors[index].Get().Get();
98 void Material::SetFaceCullingMode( Dali::Material::FaceCullingMode cullingMode )
100 if( NULL != mSceneObject )
102 SceneGraph::DoubleBufferedPropertyMessage<int>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mFaceCullingMode, &SceneGraph::DoubleBufferedProperty<int>::Set, static_cast<int>(cullingMode) );
106 void Material::SetBlendMode( BlendingMode::Type mode )
108 mBlendingMode = mode;
110 if( NULL != mSceneObject )
112 SceneGraph::DoubleBufferedPropertyMessage<int>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mBlendingMode, &SceneGraph::DoubleBufferedProperty<int>::Set, static_cast<int>(mode) );
116 BlendingMode::Type Material::GetBlendMode() const
118 return mBlendingMode;
121 void Material::SetBlendFunc( BlendingFactor::Type srcFactorRgba, BlendingFactor::Type destFactorRgba )
123 mBlendingOptions.SetBlendFunc( srcFactorRgba, destFactorRgba, srcFactorRgba, destFactorRgba );
124 SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
127 void Material::SetBlendFunc( BlendingFactor::Type srcFactorRgb,
128 BlendingFactor::Type destFactorRgb,
129 BlendingFactor::Type srcFactorAlpha,
130 BlendingFactor::Type destFactorAlpha )
132 mBlendingOptions.SetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
133 SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
136 void Material::GetBlendFunc( BlendingFactor::Type& srcFactorRgb,
137 BlendingFactor::Type& destFactorRgb,
138 BlendingFactor::Type& srcFactorAlpha,
139 BlendingFactor::Type& destFactorAlpha ) const
141 srcFactorRgb = mBlendingOptions.GetBlendSrcFactorRgb();
142 destFactorRgb = mBlendingOptions.GetBlendDestFactorRgb();
143 srcFactorAlpha = mBlendingOptions.GetBlendSrcFactorAlpha();
144 destFactorAlpha = mBlendingOptions.GetBlendDestFactorAlpha();
147 void Material::SetBlendEquation( BlendingEquation::Type equationRgba )
149 mBlendingOptions.SetBlendEquation( equationRgba, equationRgba );
150 SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
153 void Material::SetBlendEquation( BlendingEquation::Type equationRgb,
154 BlendingEquation::Type equationAlpha )
156 mBlendingOptions.SetBlendEquation( equationRgb, equationAlpha );
157 SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
160 void Material::GetBlendEquation( BlendingEquation::Type& equationRgb,
161 BlendingEquation::Type& equationAlpha ) const
163 // These are not animatable, the cached values are up-to-date.
164 equationRgb = mBlendingOptions.GetBlendEquationRgb();
165 equationAlpha = mBlendingOptions.GetBlendEquationAlpha();
168 void Material::SetBlendColor( const Vector4& color )
172 SceneGraph::AnimatablePropertyMessage<Vector4>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mBlendColor, &SceneGraph::AnimatableProperty<Vector4>::Bake, color );
176 const Vector4& Material::GetBlendColor() const
178 return mSceneObject->mBlendColor[ GetEventThreadServices().GetEventBufferIndex() ];
181 const SceneGraph::Material* Material::GetMaterialSceneObject() const
186 unsigned int Material::GetDefaultPropertyCount() const
188 return MATERIAL_IMPL.GetDefaultPropertyCount();
191 void Material::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
193 MATERIAL_IMPL.GetDefaultPropertyIndices( indices );
196 const char* Material::GetDefaultPropertyName(Property::Index index) const
198 return MATERIAL_IMPL.GetDefaultPropertyName( index );
201 Property::Index Material::GetDefaultPropertyIndex( const std::string& name ) const
203 return MATERIAL_IMPL.GetDefaultPropertyIndex( name );
206 bool Material::IsDefaultPropertyWritable( Property::Index index ) const
208 return MATERIAL_IMPL.IsDefaultPropertyWritable( index );
211 bool Material::IsDefaultPropertyAnimatable( Property::Index index ) const
213 return MATERIAL_IMPL.IsDefaultPropertyAnimatable( index );
216 bool Material::IsDefaultPropertyAConstraintInput( Property::Index index ) const
218 return MATERIAL_IMPL.IsDefaultPropertyAConstraintInput( index );
221 Property::Type Material::GetDefaultPropertyType( Property::Index index ) const
223 return MATERIAL_IMPL.GetDefaultPropertyType( index );
226 void Material::SetDefaultProperty( Property::Index index,
227 const Property::Value& propertyValue )
231 case Dali::Material::Property::COLOR:
233 SceneGraph::AnimatablePropertyMessage<Vector4>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mColor, &SceneGraph::AnimatableProperty<Vector4>::Bake, propertyValue.Get<Vector4>() );
236 case Dali::Material::Property::FACE_CULLING_MODE:
238 SceneGraph::DoubleBufferedPropertyMessage<int>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mFaceCullingMode, &SceneGraph::DoubleBufferedProperty<int>::Set, propertyValue.Get<int>() );
241 case Dali::Material::Property::BLENDING_MODE:
245 SceneGraph::DoubleBufferedPropertyMessage<int>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mBlendingMode, &SceneGraph::DoubleBufferedProperty<int>::Set, propertyValue.Get<int>() );
249 case Dali::Material::Property::BLEND_EQUATION_RGB:
251 BlendingEquation::Type alphaEquation = mBlendingOptions.GetBlendEquationAlpha();
252 mBlendingOptions.SetBlendEquation( static_cast<BlendingEquation::Type>(propertyValue.Get<int>()), alphaEquation );
255 case Dali::Material::Property::BLEND_EQUATION_ALPHA:
257 BlendingEquation::Type rgbEquation = mBlendingOptions.GetBlendEquationRgb();
258 mBlendingOptions.SetBlendEquation( rgbEquation, static_cast<BlendingEquation::Type>(propertyValue.Get<int>()) );
261 case Dali::Material::Property::BLENDING_SRC_FACTOR_RGB:
263 BlendingFactor::Type srcFactorRgb;
264 BlendingFactor::Type destFactorRgb;
265 BlendingFactor::Type srcFactorAlpha;
266 BlendingFactor::Type destFactorAlpha;
267 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
268 SetBlendFunc( static_cast<BlendingFactor::Type>(propertyValue.Get<int>()),
274 case Dali::Material::Property::BLENDING_DEST_FACTOR_RGB:
276 BlendingFactor::Type srcFactorRgb;
277 BlendingFactor::Type destFactorRgb;
278 BlendingFactor::Type srcFactorAlpha;
279 BlendingFactor::Type destFactorAlpha;
280 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
281 SetBlendFunc( srcFactorRgb,
282 static_cast<BlendingFactor::Type>(propertyValue.Get<int>()),
287 case Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA:
289 BlendingFactor::Type srcFactorRgb;
290 BlendingFactor::Type destFactorRgb;
291 BlendingFactor::Type srcFactorAlpha;
292 BlendingFactor::Type destFactorAlpha;
293 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
294 SetBlendFunc( srcFactorRgb,
296 static_cast<BlendingFactor::Type>(propertyValue.Get<int>()),
300 case Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA:
302 BlendingFactor::Type srcFactorRgb;
303 BlendingFactor::Type destFactorRgb;
304 BlendingFactor::Type srcFactorAlpha;
305 BlendingFactor::Type destFactorAlpha;
306 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
307 SetBlendFunc( srcFactorRgb,
310 static_cast<BlendingFactor::Type>(propertyValue.Get<int>()) );
313 case Dali::Material::Property::BLEND_COLOR:
315 SceneGraph::AnimatablePropertyMessage<Vector4>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mBlendColor, &SceneGraph::AnimatableProperty<Vector4>::Bake, propertyValue.Get<Vector4>() );
321 void Material::SetSceneGraphProperty( Property::Index index,
322 const PropertyMetadata& entry,
323 const Property::Value& value )
325 MATERIAL_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
326 OnPropertySet(index, value);
329 Property::Value Material::GetDefaultProperty( Property::Index index ) const
331 BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
332 Property::Value value;
336 case Dali::Material::Property::COLOR:
340 value = mSceneObject->mColor[bufferIndex];
344 case Dali::Material::Property::FACE_CULLING_MODE:
348 value = mSceneObject->mFaceCullingMode[bufferIndex];
352 case Dali::Material::Property::BLENDING_MODE:
356 value = mSceneObject->mBlendingMode[bufferIndex];
360 case Dali::Material::Property::BLEND_EQUATION_RGB:
362 value = static_cast<int>( mBlendingOptions.GetBlendEquationRgb() );
365 case Dali::Material::Property::BLEND_EQUATION_ALPHA:
367 value = static_cast<int>( mBlendingOptions.GetBlendEquationAlpha() );
370 case Dali::Material::Property::BLENDING_SRC_FACTOR_RGB:
372 BlendingFactor::Type srcFactorRgb;
373 BlendingFactor::Type destFactorRgb;
374 BlendingFactor::Type srcFactorAlpha;
375 BlendingFactor::Type destFactorAlpha;
376 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
377 value = static_cast<int>( srcFactorRgb );
380 case Dali::Material::Property::BLENDING_DEST_FACTOR_RGB:
382 BlendingFactor::Type srcFactorRgb;
383 BlendingFactor::Type destFactorRgb;
384 BlendingFactor::Type srcFactorAlpha;
385 BlendingFactor::Type destFactorAlpha;
386 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
387 value = static_cast<int>( destFactorRgb );
390 case Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA:
392 BlendingFactor::Type srcFactorRgb;
393 BlendingFactor::Type destFactorRgb;
394 BlendingFactor::Type srcFactorAlpha;
395 BlendingFactor::Type destFactorAlpha;
396 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
397 value = static_cast<int>( srcFactorAlpha );
400 case Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA:
402 BlendingFactor::Type srcFactorRgb;
403 BlendingFactor::Type destFactorRgb;
404 BlendingFactor::Type srcFactorAlpha;
405 BlendingFactor::Type destFactorAlpha;
406 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
407 value = static_cast<int>( destFactorAlpha );
410 case Dali::Material::Property::BLEND_COLOR:
414 value = mSceneObject->mBlendColor[bufferIndex];
423 const SceneGraph::PropertyOwner* Material::GetPropertyOwner() const
428 const SceneGraph::PropertyOwner* Material::GetSceneObject() const
433 const SceneGraph::PropertyBase* Material::GetSceneObjectAnimatableProperty( Property::Index index ) const
435 DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
437 const SceneGraph::PropertyBase* property = NULL;
441 property = MATERIAL_IMPL.GetRegisteredSceneGraphProperty( this,
442 &Material::FindAnimatableProperty,
443 &Material::FindCustomProperty,
446 if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
450 case Dali::Material::Property::COLOR:
452 property = &mSceneObject->mColor;
455 case Dali::Material::Property::BLEND_COLOR:
457 property = &mSceneObject->mBlendColor;
462 DALI_ASSERT_ALWAYS( 0 && "Property is not animatable");
472 const PropertyInputImpl* Material::GetSceneObjectInputProperty( Property::Index index ) const
474 const PropertyInputImpl* property = NULL;
478 const SceneGraph::PropertyBase* baseProperty =
479 MATERIAL_IMPL.GetRegisteredSceneGraphProperty( this,
480 &Material::FindAnimatableProperty,
481 &Material::FindCustomProperty,
483 property = static_cast<const PropertyInputImpl*>( baseProperty );
485 if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
489 case Dali::Material::Property::COLOR:
491 property = &mSceneObject->mColor;
494 case Dali::Material::Property::FACE_CULLING_MODE:
496 property = &mSceneObject->mFaceCullingMode;
499 case Dali::Material::Property::BLEND_COLOR:
501 property = &mSceneObject->mBlendColor;
506 DALI_ASSERT_ALWAYS( 0 && "Property cannot be a constraint input");
516 int Material::GetPropertyComponentIndex( Property::Index index ) const
518 // @todo MESH_REWORK - Change this if component properties are added for color/blend-color
519 return Property::INVALID_COMPONENT_INDEX;
522 bool Material::OnStage() const
527 void Material::Connect()
531 SamplerConnectorContainer::const_iterator end = mSamplerConnectors.end();
532 for( SamplerConnectorContainer::iterator it = mSamplerConnectors.begin();
536 it->OnStageConnect();
538 mShaderConnector.OnStageConnect();
541 void Material::Disconnect()
545 SamplerConnectorContainer::const_iterator end = mSamplerConnectors.end();
546 for( SamplerConnectorContainer::iterator it = mSamplerConnectors.begin();
550 it->OnStageDisconnect();
552 mShaderConnector.OnStageDisconnect();
556 : mSceneObject( NULL ),
561 void Material::Initialize()
563 EventThreadServices& eventThreadServices = GetEventThreadServices();
564 SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
566 DALI_ASSERT_ALWAYS( EventThreadServices::IsCoreRunning() && "Core is not running" );
568 mSceneObject = new SceneGraph::Material();
569 AddMessage( updateManager, updateManager.GetMaterialOwner(), *mSceneObject );
572 Material::~Material()
574 if( EventThreadServices::IsCoreRunning() )
576 EventThreadServices& eventThreadServices = GetEventThreadServices();
577 SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
578 RemoveMessage( updateManager, updateManager.GetMaterialOwner(), *mSceneObject );
582 } // namespace Internal