[dali_1.0.49] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / event / rendering / geometry-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/rendering/geometry-impl.h> // Dali::Internal::Geometry
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/object/type-registry.h>
23
24 #include <dali/internal/event/common/object-impl-helper.h> // Dali::Internal::ObjectHelper
25 #include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
26 #include <dali/internal/update/common/double-buffered-property.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( "geometry-type",         STRING,   true, false,  true, Dali::Geometry::Property::GEOMETRY_TYPE )
42 DALI_PROPERTY( "geometry-center",       VECTOR3,  true, true,   true, Dali::Geometry::Property::GEOMETRY_CENTER )
43 DALI_PROPERTY( "geometry-half-extents", VECTOR3,  true, true,   true, Dali::Geometry::Property::GEOMETRY_HALF_EXTENTS )
44 DALI_PROPERTY( "requires-depth-test",   BOOLEAN,  true, false,  true, Dali::Geometry::Property::REQUIRES_DEPTH_TEST )
45 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
46
47 const ObjectImplHelper<DEFAULT_PROPERTY_COUNT> GEOMETRY_IMPL = { DEFAULT_PROPERTY_DETAILS };
48
49 BaseHandle Create()
50 {
51   return Dali::Geometry::New();
52 }
53
54 TypeRegistration mType( typeid( Dali::Geometry ), typeid( Dali::Handle ), Create );
55
56 } // unnamed namespace
57
58 GeometryPtr Geometry::New()
59 {
60   GeometryPtr geometry( new Geometry() );
61   geometry->Initialize();
62   return geometry;
63 }
64
65 std::size_t Geometry::AddVertexBuffer( PropertyBuffer& vertexBuffer )
66 {
67   PropertyBufferConnector connector;
68   connector.Set( vertexBuffer, OnStage() );
69   mVertexBufferConnectors.push_back( connector );
70
71   const SceneGraph::PropertyBuffer& sceneGraphPropertyBuffer = static_cast<const SceneGraph::PropertyBuffer&>( *vertexBuffer.GetSceneObject() );
72
73   SceneGraph::AddVertexBufferMessage( GetEventThreadServices(), *mSceneObject, sceneGraphPropertyBuffer );
74
75   return mVertexBufferConnectors.size() - 1u;
76 }
77
78 std::size_t Geometry::GetNumberOfVertexBuffers() const
79 {
80   return mVertexBufferConnectors.size();
81 }
82
83 void Geometry::RemoveVertexBuffer( std::size_t index )
84 {
85   const SceneGraph::PropertyBuffer& sceneGraphPropertyBuffer = static_cast<const SceneGraph::PropertyBuffer&>( *(mVertexBufferConnectors[index].Get()->GetSceneObject()) );
86   SceneGraph::RemoveVertexBufferMessage( GetEventThreadServices(), *mSceneObject, sceneGraphPropertyBuffer );
87
88   mVertexBufferConnectors.erase( mVertexBufferConnectors.begin() + index );
89 }
90
91 void Geometry::SetIndexBuffer( PropertyBuffer& indexBuffer )
92 {
93   mIndexBufferConnector.Set( indexBuffer, OnStage() );
94
95   const SceneGraph::PropertyBuffer& sceneGraphPropertyBuffer = dynamic_cast<const SceneGraph::PropertyBuffer&>( *indexBuffer.GetSceneObject() );
96
97   SceneGraph::SetIndexBufferMessage( GetEventThreadServices(), *mSceneObject, sceneGraphPropertyBuffer );
98 }
99
100 void Geometry::SetGeometryType( Dali::Geometry::GeometryType geometryType )
101 {
102   if( NULL != mSceneObject )
103   {
104     SceneGraph::DoubleBufferedPropertyMessage<int>::Send(
105       GetEventThreadServices(),
106       mSceneObject,
107       &mSceneObject->mGeometryType,
108       &SceneGraph::DoubleBufferedProperty<int>::Set,
109       static_cast<int>(geometryType) );
110   }
111 }
112
113 Dali::Geometry::GeometryType Geometry::GetGeometryType() const
114 {
115   return mSceneObject->GetGeometryType(GetEventThreadServices().GetEventBufferIndex());
116 }
117
118 void Geometry::SetRequiresDepthTesting( bool requiresDepthTest )
119 {
120   if( NULL != mSceneObject )
121   {
122     SceneGraph::DoubleBufferedPropertyMessage<bool>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mRequiresDepthTest, &SceneGraph::DoubleBufferedProperty<bool>::Set, static_cast<int>(requiresDepthTest) );
123   }
124 }
125
126 bool Geometry::GetRequiresDepthTesting() const
127 {
128   if( mSceneObject )
129   {
130     // mSceneObject is being used in a separate thread; copy the value from the previous update
131     return mSceneObject->GetRequiresDepthTesting(GetEventThreadServices().GetEventBufferIndex());
132   }
133   return false;
134 }
135
136 const SceneGraph::Geometry* Geometry::GetGeometrySceneObject() const
137 {
138   return mSceneObject;
139 }
140
141 unsigned int Geometry::GetDefaultPropertyCount() const
142 {
143   return GEOMETRY_IMPL.GetDefaultPropertyCount();
144 }
145
146 void Geometry::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
147 {
148   GEOMETRY_IMPL.GetDefaultPropertyIndices( indices );
149 }
150
151 const char* Geometry::GetDefaultPropertyName(Property::Index index) const
152 {
153   return GEOMETRY_IMPL.GetDefaultPropertyName( index );
154 }
155
156 Property::Index Geometry::GetDefaultPropertyIndex( const std::string& name ) const
157 {
158   return GEOMETRY_IMPL.GetDefaultPropertyIndex( name );
159 }
160
161 bool Geometry::IsDefaultPropertyWritable( Property::Index index ) const
162 {
163   return GEOMETRY_IMPL.IsDefaultPropertyWritable( index );
164 }
165
166 bool Geometry::IsDefaultPropertyAnimatable( Property::Index index ) const
167 {
168   return GEOMETRY_IMPL.IsDefaultPropertyAnimatable( index );
169 }
170
171 bool Geometry::IsDefaultPropertyAConstraintInput( Property::Index index ) const
172 {
173   return GEOMETRY_IMPL.IsDefaultPropertyAConstraintInput( index );
174 }
175
176 Property::Type Geometry::GetDefaultPropertyType( Property::Index index ) const
177 {
178   return GEOMETRY_IMPL.GetDefaultPropertyType( index );
179 }
180
181 void Geometry::SetDefaultProperty( Property::Index index,
182                                    const Property::Value& propertyValue )
183 {
184   switch( index )
185   {
186     case Dali::Geometry::Property::GEOMETRY_TYPE :
187     {
188       SceneGraph::DoubleBufferedPropertyMessage<int>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mGeometryType, &SceneGraph::DoubleBufferedProperty<int>::Set, propertyValue.Get<int>() );
189       break;
190     }
191     case Dali::Geometry::Property::GEOMETRY_CENTER :
192     {
193       SceneGraph::AnimatablePropertyMessage<Vector3>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mCenter, &SceneGraph::AnimatableProperty<Vector3>::Bake, propertyValue.Get<Vector3>() );
194       break;
195     }
196
197     case Dali::Geometry::Property::GEOMETRY_HALF_EXTENTS :
198     {
199       SceneGraph::AnimatablePropertyMessage<Vector3>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mHalfExtents, &SceneGraph::AnimatableProperty<Vector3>::Bake, propertyValue.Get<Vector3>() );
200       break;
201     }
202
203     case Dali::Geometry::Property::REQUIRES_DEPTH_TEST :
204     {
205       SceneGraph::DoubleBufferedPropertyMessage<bool>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mRequiresDepthTest, &SceneGraph::DoubleBufferedProperty<bool>::Set, propertyValue.Get<bool>() );
206       break;
207     }
208   }
209 }
210
211 void Geometry::SetSceneGraphProperty( Property::Index index,
212                                       const PropertyMetadata& entry,
213                                       const Property::Value& value )
214 {
215   GEOMETRY_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
216 }
217
218 Property::Value Geometry::GetDefaultProperty( Property::Index index ) const
219 {
220   BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
221   Property::Value value;
222
223   switch( index )
224   {
225     case Dali::Geometry::Property::GEOMETRY_TYPE :
226     {
227       if( mSceneObject )
228       {
229         value = mSceneObject->mGeometryType[bufferIndex];
230       }
231       break;
232     }
233     case Dali::Geometry::Property::GEOMETRY_CENTER :
234     {
235       if( mSceneObject )
236       {
237         value = mSceneObject->mCenter[bufferIndex];
238       }
239       break;
240     }
241
242     case Dali::Geometry::Property::GEOMETRY_HALF_EXTENTS :
243     {
244       if( mSceneObject )
245       {
246         value = mSceneObject->mHalfExtents[bufferIndex];
247       }
248       break;
249     }
250
251     case Dali::Geometry::Property::REQUIRES_DEPTH_TEST :
252     {
253       if( mSceneObject )
254       {
255         value = mSceneObject->mRequiresDepthTest[bufferIndex];
256       }
257       break;
258     }
259   }
260
261   return value;
262 }
263
264 const SceneGraph::PropertyOwner* Geometry::GetPropertyOwner() const
265 {
266   return mSceneObject;
267 }
268
269 const SceneGraph::PropertyOwner* Geometry::GetSceneObject() const
270 {
271   return mSceneObject;
272 }
273
274 const SceneGraph::PropertyBase* Geometry::GetSceneObjectAnimatableProperty( Property::Index index ) const
275 {
276   const SceneGraph::PropertyBase* property = NULL;
277
278   if( OnStage() )
279   {
280     property = GEOMETRY_IMPL.GetRegisteredSceneGraphProperty ( this,
281                                                                &Geometry::FindAnimatableProperty,
282                                                                &Geometry::FindCustomProperty,
283                                                                index );
284
285     if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
286     {
287       switch(index)
288       {
289         case Dali::Geometry::Property::GEOMETRY_CENTER :
290         {
291           property = &mSceneObject->mCenter;
292           break;
293         }
294         case Dali::Geometry::Property::GEOMETRY_HALF_EXTENTS :
295         {
296           property = &mSceneObject->mHalfExtents;
297           break;
298         }
299         default:
300         {
301           DALI_ASSERT_ALWAYS( 0 && "Property is not animatable" );
302           break;
303         }
304       }
305     }
306   }
307   return property;
308 }
309
310 const PropertyInputImpl* Geometry::GetSceneObjectInputProperty( Property::Index index ) const
311 {
312   const PropertyInputImpl* property = NULL;
313
314   if( OnStage() )
315   {
316     const SceneGraph::PropertyBase* baseProperty =
317       GEOMETRY_IMPL.GetRegisteredSceneGraphProperty ( this,
318                                                       &Geometry::FindAnimatableProperty,
319                                                       &Geometry::FindCustomProperty,
320                                                       index );
321
322     property = static_cast<const PropertyInputImpl*>( baseProperty );
323
324     if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
325     {
326       switch(index)
327       {
328         case Dali::Geometry::Property::GEOMETRY_TYPE :
329         {
330           property = &mSceneObject->mGeometryType;
331           break;
332         }
333         case Dali::Geometry::Property::GEOMETRY_CENTER :
334         {
335           property = &mSceneObject->mCenter;
336           break;
337         }
338         case Dali::Geometry::Property::GEOMETRY_HALF_EXTENTS :
339         {
340           property = &mSceneObject->mHalfExtents;
341           break;
342         }
343         case Dali::Geometry::Property::REQUIRES_DEPTH_TEST :
344         {
345           property = &mSceneObject->mRequiresDepthTest;
346           break;
347         }
348         default:
349         {
350           DALI_ASSERT_ALWAYS( 0 && "Property cannot be a constraint input");
351           break;
352         }
353       }
354     }
355   }
356
357   return property;
358 }
359
360 int Geometry::GetPropertyComponentIndex( Property::Index index ) const
361 {
362   // @todo MESH_REWORK - Change this if component properties are added for center/half-extent
363   return Property::INVALID_COMPONENT_INDEX;
364 }
365
366 bool Geometry::OnStage() const
367 {
368   return mOnStage;
369 }
370
371 void Geometry::Connect()
372 {
373   mOnStage = true;
374
375   PropertyBufferConnectorContainer::const_iterator end = mVertexBufferConnectors.end();
376   for( PropertyBufferConnectorContainer::iterator it = mVertexBufferConnectors.begin();
377        it < end;
378        ++it )
379   {
380     it->OnStageConnect();
381   }
382   mIndexBufferConnector.OnStageConnect();
383 }
384
385 void Geometry::Disconnect()
386 {
387   mOnStage = false;
388
389   PropertyBufferConnectorContainer::const_iterator end = mVertexBufferConnectors.end();
390   for( PropertyBufferConnectorContainer::iterator it = mVertexBufferConnectors.begin();
391        it < end;
392        ++it )
393   {
394     it->OnStageDisconnect();
395   }
396   mIndexBufferConnector.OnStageDisconnect();
397 }
398
399 Geometry::Geometry()
400 : mSceneObject( NULL ),
401   mOnStage( false )
402 {
403 }
404
405 void Geometry::Initialize()
406 {
407   EventThreadServices& eventThreadServices = GetEventThreadServices();
408   SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
409
410   mSceneObject = new SceneGraph::Geometry();
411   AddMessage( updateManager, updateManager.GetGeometryOwner(), *mSceneObject );
412
413   eventThreadServices.RegisterObject( this );
414 }
415
416 Geometry::~Geometry()
417 {
418   if( EventThreadServices::IsCoreRunning() )
419   {
420     EventThreadServices& eventThreadServices = GetEventThreadServices();
421     SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
422     RemoveMessage( updateManager, updateManager.GetGeometryOwner(), *mSceneObject );
423
424     eventThreadServices.UnregisterObject( this );
425   }
426 }
427
428
429 } // namespace Internal
430 } // namespace Dali