2da87a4a28169250c35dc399ca7701b8a9bc3895
[platform/core/uifw/dali-core.git] / dali / internal / event / effects / material-impl.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
18 // CLASS HEADER
19 #include <dali/internal/event/effects/material-impl.h> // Dali::Internal::Material
20
21 // INTERNAL INCLUDES
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>
28
29 namespace Dali
30 {
31 namespace Internal
32 {
33
34 namespace
35 {
36
37 /**
38  *            |name                              |type     |writable|animatable|constraint-input|enum for index-checking|
39  */
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,  true, Dali::Material::Property::FACE_CULLING_MODE )
43 DALI_PROPERTY( "blending-mode",                   STRING,   true, false,  true, Dali::Material::Property::BLENDING_MODE )
44 DALI_PROPERTY( "blend-equation",                  STRING,   true, false,  true, Dali::Material::Property::BLEND_EQUATION )
45 DALI_PROPERTY( "source-blend-factor-rgb",         STRING,   true, false,  true, Dali::Material::Property::BLENDING_SRC_FACTOR_RGB )
46 DALI_PROPERTY( "destination-blend-factor-rgb",    STRING,   true, false,  true, Dali::Material::Property::BLENDING_DEST_FACTOR_RGB )
47 DALI_PROPERTY( "source-blend-factor-alpha",       STRING,   true, false,  true, Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA )
48 DALI_PROPERTY( "destination-blend-factor-alpha",  STRING,   true, false,  true, Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA )
49 DALI_PROPERTY( "blend-color",                     VECTOR4,  true, true,   true, Dali::Material::Property::BLEND_COLOR )
50 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
51
52 const ObjectImplHelper<DEFAULT_PROPERTY_COUNT> MATERIAL_IMPL = { DEFAULT_PROPERTY_DETAILS };
53
54 } // unnamed namespace
55
56 MaterialPtr Material::New()
57 {
58   MaterialPtr material( new Material() );
59   material->Initialize();
60   return material;
61 }
62
63 void Material::SetShader( Shader& shader )
64 {
65   DALI_ASSERT_DEBUG( mSceneObject )
66   mShaderConnector.Set( shader, OnStage() );
67
68   const SceneGraph::Shader& sceneGraphShader = dynamic_cast<const SceneGraph::Shader&>( *shader.GetSceneObject() );
69   SceneGraph::SetShaderMessage( GetEventThreadServices(), *mSceneObject, sceneGraphShader );
70 }
71
72 void Material::AddSampler( Sampler& sampler )
73 {
74   SamplerConnector connector;
75   connector.Set( sampler, OnStage() );
76   mSamplerConnectors.push_back( connector );
77
78   const SceneGraph::Sampler& sceneGraphSampler = dynamic_cast<const SceneGraph::Sampler&>( *sampler.GetSceneObject() );
79   SceneGraph::AddSamplerMessage( GetEventThreadServices(), *mSceneObject, sceneGraphSampler );
80 }
81
82 std::size_t Material::GetNumberOfSamplers() const
83 {
84   return mSamplerConnectors.size();
85 }
86
87 void Material::RemoveSampler( std::size_t index )
88 {
89   mSamplerConnectors.erase( mSamplerConnectors.begin() + index );
90 }
91
92 void Material::SetFaceCullingMode( Dali::Material::FaceCullingMode cullingMode )
93 {
94   // TODO: MESH_REWORK
95   DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
96 }
97
98 void Material::SetBlendMode( BlendingMode::Type mode )
99 {
100   // TODO: MESH_REWORK
101   DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
102 }
103
104 BlendingMode::Type Material::GetBlendMode() const
105 {
106   // TODO: MESH_REWORK
107   DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
108   return BlendingMode::AUTO;
109 }
110
111 void Material::SetBlendFunc( BlendingFactor::Type srcFactorRgba, BlendingFactor::Type destFactorRgba )
112 {
113   // TODO: MESH_REWORK
114   DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
115 }
116
117 void Material::SetBlendFunc( BlendingFactor::Type srcFactorRgb,
118                              BlendingFactor::Type destFactorRgb,
119                              BlendingFactor::Type srcFactorAlpha,
120                              BlendingFactor::Type destFactorAlpha )
121 {
122   // TODO: MESH_REWORK
123   DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
124 }
125
126 void Material::GetBlendFunc( BlendingFactor::Type& srcFactorRgb,
127                              BlendingFactor::Type& destFactorRgb,
128                              BlendingFactor::Type& srcFactorAlpha,
129                              BlendingFactor::Type& destFactorAlpha ) const
130 {
131   // TODO: MESH_REWORK
132   DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
133 }
134
135 void Material::SetBlendEquation( BlendingEquation::Type equationRgba )
136 {
137   // TODO: MESH_REWORK
138   DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
139 }
140
141 void Material::SetBlendEquation( BlendingEquation::Type equationRgb,
142                                  BlendingEquation::Type equationAlpha )
143 {
144   // TODO: MESH_REWORK
145   DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
146 }
147
148 void Material::GetBlendEquation( BlendingEquation::Type& equationRgb,
149                                  BlendingEquation::Type& equationAlpha ) const
150 {
151   // TODO: MESH_REWORK
152   DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
153 }
154
155 void Material::SetBlendColor( const Vector4& color )
156 {
157   // TODO: MESH_REWORK
158   DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
159 }
160
161 const Vector4& Material::GetBlendColor() const
162 {
163   // TODO: MESH_REWORK
164   DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
165   return Color::WHITE;
166 }
167
168 const SceneGraph::Material* Material::GetMaterialSceneObject() const
169 {
170   return mSceneObject;
171 }
172
173 unsigned int Material::GetDefaultPropertyCount() const
174 {
175   return MATERIAL_IMPL.GetDefaultPropertyCount();
176 }
177
178 void Material::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
179 {
180   MATERIAL_IMPL.GetDefaultPropertyIndices( indices );
181 }
182
183 const char* Material::GetDefaultPropertyName(Property::Index index) const
184 {
185   return MATERIAL_IMPL.GetDefaultPropertyName( index );
186 }
187
188 Property::Index Material::GetDefaultPropertyIndex( const std::string& name ) const
189 {
190   return MATERIAL_IMPL.GetDefaultPropertyIndex( name );
191 }
192
193 bool Material::IsDefaultPropertyWritable( Property::Index index ) const
194 {
195   return MATERIAL_IMPL.IsDefaultPropertyWritable( index );
196 }
197
198 bool Material::IsDefaultPropertyAnimatable( Property::Index index ) const
199 {
200   return MATERIAL_IMPL.IsDefaultPropertyAnimatable( index );
201 }
202
203 bool Material::IsDefaultPropertyAConstraintInput( Property::Index index ) const
204 {
205   return MATERIAL_IMPL.IsDefaultPropertyAConstraintInput( index );
206 }
207
208 Property::Type Material::GetDefaultPropertyType( Property::Index index ) const
209 {
210   return MATERIAL_IMPL.GetDefaultPropertyType( index );
211 }
212
213 void Material::SetDefaultProperty( Property::Index index,
214                                    const Property::Value& propertyValue )
215 {
216   switch( index )
217   {
218     case Dali::Material::Property::COLOR:
219     {
220       SceneGraph::PropertyMessage<Vector4>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mColor, &SceneGraph::AnimatableProperty<Vector4>::Bake, propertyValue.Get<Vector4>() );
221       break;
222     }
223     case Dali::Material::Property::FACE_CULLING_MODE:
224     {
225       DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
226       break;
227     }
228     case Dali::Material::Property::BLENDING_MODE:
229     {
230       DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
231       break;
232     }
233     case Dali::Material::Property::BLEND_EQUATION:
234     {
235       DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
236       break;
237     }
238     case Dali::Material::Property::BLENDING_SRC_FACTOR_RGB:
239     {
240       DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
241       break;
242     }
243     case Dali::Material::Property::BLENDING_DEST_FACTOR_RGB:
244     {
245       DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
246       break;
247     }
248     case Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA:
249     {
250       DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
251       break;
252     }
253     case Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA:
254     {
255       DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
256       break;
257     }
258     case Dali::Material::Property::BLEND_COLOR:
259     {
260       SceneGraph::PropertyMessage<Vector4>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mBlendColor, &SceneGraph::AnimatableProperty<Vector4>::Bake, propertyValue.Get<Vector4>() );
261       break;
262     }
263   }
264 }
265
266 void Material::SetSceneGraphProperty( Property::Index index,
267                                       const PropertyMetadata& entry,
268                                       const Property::Value& value )
269 {
270   MATERIAL_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
271   OnPropertySet(index, value);
272 }
273
274 Property::Value Material::GetDefaultProperty( Property::Index index ) const
275 {
276   BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
277   Property::Value value;
278
279   switch( index )
280   {
281     case Dali::Material::Property::COLOR:
282     {
283       if( mSceneObject )
284       {
285         value = mSceneObject->mColor[bufferIndex];
286       }
287       break;
288     }
289     case Dali::Material::Property::FACE_CULLING_MODE:
290     {
291       DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
292       break;
293     }
294     case Dali::Material::Property::BLENDING_MODE:
295     {
296       DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
297       break;
298     }
299     case Dali::Material::Property::BLEND_EQUATION:
300     {
301       DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
302       break;
303     }
304     case Dali::Material::Property::BLENDING_SRC_FACTOR_RGB:
305     {
306       DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
307       break;
308     }
309     case Dali::Material::Property::BLENDING_DEST_FACTOR_RGB:
310     {
311       DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
312       break;
313     }
314     case Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA:
315     {
316       DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
317       break;
318     }
319     case Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA:
320     {
321       DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
322       break;
323     }
324     case Dali::Material::Property::BLEND_COLOR:
325     {
326       if( mSceneObject )
327       {
328         value = mSceneObject->mBlendColor[bufferIndex];
329       }
330       break;
331     }
332   }
333
334   return value;
335 }
336
337 const SceneGraph::PropertyOwner* Material::GetPropertyOwner() const
338 {
339   return mSceneObject;
340 }
341
342 const SceneGraph::PropertyOwner* Material::GetSceneObject() const
343 {
344   return mSceneObject;
345 }
346
347 const SceneGraph::PropertyBase* Material::GetSceneObjectAnimatableProperty( Property::Index index ) const
348 {
349   DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
350
351   const SceneGraph::PropertyBase* property = NULL;
352
353   if( OnStage() )
354   {
355     property = MATERIAL_IMPL.GetRegisteredSceneGraphProperty( this,
356                                                               &Material::FindAnimatableProperty,
357                                                               &Material::FindCustomProperty,
358                                                               index );
359
360     if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
361     {
362       switch(index)
363       {
364         case Dali::Material::Property::COLOR:
365         {
366           property = &mSceneObject->mColor;
367           break;
368         }
369         case Dali::Material::Property::BLEND_COLOR:
370         {
371           property = &mSceneObject->mBlendColor;
372           break;
373         }
374         default:
375         {
376           DALI_ASSERT_ALWAYS( 0 && "Property is not animatable");
377           break;
378         }
379       }
380     }
381   }
382
383   return property;
384 }
385
386 const PropertyInputImpl* Material::GetSceneObjectInputProperty( Property::Index index ) const
387 {
388   const PropertyInputImpl* property = NULL;
389
390   if( OnStage() )
391   {
392     const SceneGraph::PropertyBase* baseProperty =
393       MATERIAL_IMPL.GetRegisteredSceneGraphProperty( this,
394                                                      &Material::FindAnimatableProperty,
395                                                      &Material::FindCustomProperty,
396                                                      index );
397     property = static_cast<const PropertyInputImpl*>( baseProperty );
398
399     if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
400     {
401       switch(index)
402       {
403         case Dali::Material::Property::COLOR:
404         {
405           property = &mSceneObject->mColor;
406           break;
407         }
408         case Dali::Material::Property::FACE_CULLING_MODE:
409         {
410           DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
411           break;
412         }
413         case Dali::Material::Property::BLENDING_MODE:
414         {
415           DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
416           break;
417         }
418         case Dali::Material::Property::BLEND_EQUATION:
419         {
420           DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
421           break;
422         }
423         case Dali::Material::Property::BLENDING_SRC_FACTOR_RGB:
424         {
425           DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
426           break;
427         }
428         case Dali::Material::Property::BLENDING_DEST_FACTOR_RGB:
429         {
430           DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
431           break;
432         }
433         case Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA:
434         {
435           DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
436           break;
437         }
438         case Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA:
439         {
440           DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
441           break;
442         }
443         case Dali::Material::Property::BLEND_COLOR:
444         {
445           property = &mSceneObject->mBlendColor;
446           break;
447         }
448         default:
449         {
450           DALI_ASSERT_ALWAYS( 0 && "Property cannot be a constraint input");
451           break;
452         }
453       }
454     }
455   }
456
457   return property;
458 }
459
460 int Material::GetPropertyComponentIndex( Property::Index index ) const
461 {
462   return Property::INVALID_COMPONENT_INDEX;
463 }
464
465 bool Material::OnStage() const
466 {
467   return mOnStage;
468 }
469
470 void Material::Connect()
471 {
472   mOnStage = true;
473
474   SamplerConnectorContainer::const_iterator end = mSamplerConnectors.end();
475   for( SamplerConnectorContainer::iterator it = mSamplerConnectors.begin();
476        it < end;
477        ++it )
478   {
479     it->OnStageConnect();
480   }
481 }
482
483 void Material::Disconnect()
484 {
485   mOnStage = false;
486
487   SamplerConnectorContainer::const_iterator end = mSamplerConnectors.end();
488   for( SamplerConnectorContainer::iterator it = mSamplerConnectors.begin();
489        it < end;
490        ++it )
491   {
492     it->OnStageDisconnect();
493   }
494 }
495
496 Material::Material()
497 : mSceneObject( NULL ),
498   mOnStage( false )
499 {
500 }
501
502 void Material::Initialize()
503 {
504   EventThreadServices& eventThreadServices = GetEventThreadServices();
505   SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
506
507   DALI_ASSERT_ALWAYS( EventThreadServices::IsCoreRunning() && "Core is not running" );
508
509   mSceneObject = new SceneGraph::Material();
510   AddMessage( updateManager, updateManager.GetMaterialOwner(), *mSceneObject );
511 }
512
513 Material::~Material()
514 {
515   if( EventThreadServices::IsCoreRunning() )
516   {
517     EventThreadServices& eventThreadServices = GetEventThreadServices();
518     SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
519     RemoveMessage( updateManager, updateManager.GetMaterialOwner(), *mSceneObject );
520   }
521 }
522
523 } // namespace Internal
524 } // namespace Dali