DALi Version 2.2.14
[platform/core/uifw/dali-core.git] / dali / internal / event / rendering / visual-renderer-impl.cpp
1 /*
2  * Copyright (c) 2022 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/visual-renderer-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/devel-api/rendering/renderer-devel.h>
23 #include <dali/devel-api/scripting/scripting.h>
24 #include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
25 #include <dali/internal/event/common/property-input-impl.h>
26 #include <dali/internal/update/manager/update-manager.h>
27 #include <dali/internal/update/rendering/scene-graph-renderer.h>
28 #include <dali/public-api/object/type-registry.h>
29
30 namespace Dali
31 {
32 namespace Internal
33 {
34 namespace
35 {
36 /**
37  * Properties: |name                              |type     |writable|animatable|constraint-input|enum for index-checking|
38  */
39 DALI_PROPERTY_TABLE_BEGIN
40 DALI_PROPERTY("transformOffset", VECTOR2, true, true, true, Dali::VisualRenderer::Property::TRANSFORM_OFFSET)
41 DALI_PROPERTY("transformSize", VECTOR2, true, true, true, Dali::VisualRenderer::Property::TRANSFORM_SIZE)
42 DALI_PROPERTY("transformOrigin", VECTOR2, true, false, false, Dali::VisualRenderer::Property::TRANSFORM_ORIGIN)
43 DALI_PROPERTY("transformAnchorPoint", VECTOR2, true, false, false, Dali::VisualRenderer::Property::TRANSFORM_ANCHOR_POINT)
44 DALI_PROPERTY("transformOffsetSizeMode", VECTOR4, true, false, false, Dali::VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE)
45 DALI_PROPERTY("extraSize", VECTOR2, true, true, true, Dali::VisualRenderer::Property::EXTRA_SIZE)
46 DALI_PROPERTY("visualMixColor", VECTOR3, true, true, true, Dali::VisualRenderer::Property::VISUAL_MIX_COLOR)
47 DALI_PROPERTY("preMultipliedAlpha", FLOAT, true, false, false, Dali::VisualRenderer::Property::VISUAL_PRE_MULTIPLIED_ALPHA)
48 DALI_PROPERTY_TABLE_END(Dali::VisualRenderer::Property::DEFAULT_VISUAL_RENDERER_PROPERTY_START_INDEX, VisualRendererDefaultProperties)
49
50 // Property string to enumeration tables:
51
52 DALI_ENUM_TO_STRING_TABLE_BEGIN(TRANSFORM_POLICY)
53   DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::VisualRenderer::TransformPolicy::Type, RELATIVE)
54   DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::VisualRenderer::TransformPolicy::Type, ABSOLUTE)
55 DALI_ENUM_TO_STRING_TABLE_END(TRANSFORM_POLICY)
56
57 BaseHandle Create()
58 {
59   return Dali::BaseHandle();
60 }
61
62 TypeRegistration mType(typeid(Dali::VisualRenderer), typeid(Dali::Renderer), Create, VisualRendererDefaultProperties);
63
64 } // unnamed namespace
65
66 VisualRendererPtr VisualRenderer::New()
67 {
68   // create scene object first so it's guaranteed to exist for the event side
69   auto sceneObjectKey = SceneGraph::Renderer::NewKey();
70
71   sceneObjectKey->SetVisualProperties(new SceneGraph::VisualRenderer::AnimatableVisualProperties());
72
73   // pass the pointer to base for message passing
74   VisualRendererPtr rendererPtr(new VisualRenderer(sceneObjectKey.Get()));
75
76   rendererPtr->AddUniformMappings(); // Ensure properties are mapped to uniforms
77
78   // transfer scene object ownership to update manager
79   EventThreadServices&       eventThreadServices = rendererPtr->GetEventThreadServices();
80   SceneGraph::UpdateManager& updateManager       = eventThreadServices.GetUpdateManager();
81   AddRendererMessage(updateManager, sceneObjectKey);
82
83   eventThreadServices.RegisterObject(rendererPtr.Get());
84   return rendererPtr;
85 }
86
87 VisualRenderer::VisualRenderer(const SceneGraph::Renderer* sceneObject)
88 : Renderer(sceneObject)
89 {
90 }
91
92 VisualRenderer::~VisualRenderer()
93 {
94   // The scene object will be deleted by ~Renderer
95 }
96
97 const SceneGraph::Renderer& VisualRenderer::GetVisualRendererSceneObject() const
98 {
99   return static_cast<const SceneGraph::Renderer&>(GetSceneObject());
100 }
101
102 void VisualRenderer::SetDefaultProperty(Property::Index        index,
103                                         const Property::Value& propertyValue)
104 {
105   if(index < Dali::VisualRenderer::Property::DEFAULT_VISUAL_RENDERER_PROPERTY_START_INDEX)
106   {
107     Renderer::SetDefaultProperty(index, propertyValue);
108   }
109   else
110   {
111     switch(index)
112     {
113       case Dali::VisualRenderer::Property::TRANSFORM_OFFSET:
114       {
115         if(propertyValue.Get(mPropertyCache.mTransformOffset))
116         {
117           const SceneGraph::Renderer& sceneObject      = GetVisualRendererSceneObject();
118           auto                        visualProperties = sceneObject.GetVisualProperties();
119
120           if(visualProperties)
121           {
122             BakeMessage<Vector2>(GetEventThreadServices(), visualProperties->mTransformOffset, mPropertyCache.mTransformOffset);
123           }
124         }
125         break;
126       }
127
128       case Dali::VisualRenderer::Property::TRANSFORM_SIZE:
129       {
130         if(propertyValue.Get(mPropertyCache.mTransformSize))
131         {
132           const SceneGraph::Renderer& sceneObject      = GetVisualRendererSceneObject();
133           auto                        visualProperties = sceneObject.GetVisualProperties();
134           if(visualProperties)
135           {
136             BakeMessage<Vector2>(GetEventThreadServices(), visualProperties->mTransformSize, mPropertyCache.mTransformSize);
137           }
138         }
139         break;
140       }
141       case Dali::VisualRenderer::Property::TRANSFORM_ORIGIN:
142       {
143         if(propertyValue.Get(mPropertyCache.mTransformOrigin))
144         {
145           const SceneGraph::Renderer& sceneObject      = GetVisualRendererSceneObject();
146           auto                        visualProperties = sceneObject.GetVisualProperties();
147           if(visualProperties)
148           {
149             BakeMessage<Vector2>(GetEventThreadServices(), visualProperties->mTransformOrigin, mPropertyCache.mTransformOrigin);
150           }
151         }
152         break;
153       }
154       case Dali::VisualRenderer::Property::TRANSFORM_ANCHOR_POINT:
155       {
156         if(propertyValue.Get(mPropertyCache.mTransformAnchorPoint))
157         {
158           const SceneGraph::Renderer& sceneObject      = GetVisualRendererSceneObject();
159           auto                        visualProperties = sceneObject.GetVisualProperties();
160           if(visualProperties)
161           {
162             BakeMessage<Vector2>(GetEventThreadServices(), visualProperties->mTransformAnchorPoint, mPropertyCache.mTransformAnchorPoint);
163           }
164         }
165         break;
166       }
167       case Dali::VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE:
168       {
169         if(propertyValue.Get(mPropertyCache.mTransformOffsetSizeMode))
170         {
171           const SceneGraph::Renderer& sceneObject      = GetVisualRendererSceneObject();
172           auto                        visualProperties = sceneObject.GetVisualProperties();
173           if(visualProperties)
174           {
175             BakeMessage<Vector4>(GetEventThreadServices(), visualProperties->mTransformOffsetSizeMode, mPropertyCache.mTransformOffsetSizeMode);
176           }
177         }
178         break;
179       }
180       case Dali::VisualRenderer::Property::EXTRA_SIZE:
181       {
182         if(propertyValue.Get(mPropertyCache.mExtraSize))
183         {
184           const SceneGraph::Renderer& sceneObject      = GetVisualRendererSceneObject();
185           auto                        visualProperties = sceneObject.GetVisualProperties();
186           if(visualProperties)
187           {
188             BakeMessage<Vector2>(GetEventThreadServices(), visualProperties->mExtraSize, mPropertyCache.mExtraSize);
189           }
190         }
191         break;
192       }
193       case Dali::VisualRenderer::Property::VISUAL_MIX_COLOR:
194       {
195         if(propertyValue.Get(mPropertyCache.mMixColor))
196         {
197           const SceneGraph::Renderer& sceneObject      = GetVisualRendererSceneObject();
198           auto                        visualProperties = sceneObject.GetVisualProperties();
199           if(visualProperties)
200           {
201             BakeMessage<Vector3>(GetEventThreadServices(), visualProperties->mMixColor, mPropertyCache.mMixColor);
202           }
203         }
204         break;
205       }
206       case Dali::VisualRenderer::Property::VISUAL_PRE_MULTIPLIED_ALPHA:
207       {
208         float preMultipliedAlpha;
209         if(propertyValue.Get(preMultipliedAlpha))
210         {
211           if(!Equals(mPropertyCache.mPreMultipliedAlpha, preMultipliedAlpha))
212           {
213             const SceneGraph::Renderer& sceneObject      = GetVisualRendererSceneObject();
214             auto                        visualProperties = sceneObject.GetVisualProperties();
215             if(visualProperties)
216             {
217               mPropertyCache.mPreMultipliedAlpha = preMultipliedAlpha;
218               BakeMessage<float>(GetEventThreadServices(), visualProperties->mPreMultipliedAlpha, preMultipliedAlpha);
219             }
220           }
221         }
222         break;
223       }
224     }
225   }
226 }
227
228 Property::Value VisualRenderer::GetDefaultProperty(Property::Index index) const
229 {
230   Property::Value value;
231
232   if(index < Dali::VisualRenderer::Property::DEFAULT_VISUAL_RENDERER_PROPERTY_START_INDEX)
233   {
234     value = Renderer::GetDefaultProperty(index);
235   }
236   else
237   {
238     switch(index)
239     {
240       case Dali::VisualRenderer::Property::TRANSFORM_OFFSET:
241       {
242         value = mPropertyCache.mTransformOffset;
243         break;
244       }
245       case Dali::VisualRenderer::Property::TRANSFORM_SIZE:
246       {
247         value = mPropertyCache.mTransformSize;
248         break;
249       }
250       case Dali::VisualRenderer::Property::TRANSFORM_ORIGIN:
251       {
252         value = mPropertyCache.mTransformOrigin;
253         break;
254       }
255       case Dali::VisualRenderer::Property::TRANSFORM_ANCHOR_POINT:
256       {
257         value = mPropertyCache.mTransformAnchorPoint;
258         break;
259       }
260       case Dali::VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE:
261       {
262         value = mPropertyCache.mTransformOffsetSizeMode;
263         break;
264       }
265       case Dali::VisualRenderer::Property::EXTRA_SIZE:
266       {
267         value = mPropertyCache.mExtraSize;
268         break;
269       }
270       case Dali::VisualRenderer::Property::VISUAL_MIX_COLOR:
271       {
272         value = mPropertyCache.mMixColor;
273         break;
274       }
275       case Dali::VisualRenderer::Property::VISUAL_PRE_MULTIPLIED_ALPHA:
276       {
277         value = mPropertyCache.mPreMultipliedAlpha;
278         break;
279       }
280       default:
281       {
282         break;
283       }
284     }
285   }
286
287   return value;
288 }
289
290 Property::Value VisualRenderer::GetDefaultPropertyCurrentValue(Property::Index index) const
291 {
292   Property::Value value;
293
294   if(index < Dali::VisualRenderer::Property::DEFAULT_VISUAL_RENDERER_PROPERTY_START_INDEX)
295   {
296     value = Renderer::GetDefaultPropertyCurrentValue(index);
297   }
298   else
299   {
300     const SceneGraph::Renderer& sceneObject = GetVisualRendererSceneObject();
301
302     switch(index)
303     {
304       case Dali::VisualRenderer::Property::TRANSFORM_OFFSET:
305       {
306         auto visualProperties = sceneObject.GetVisualProperties();
307         if(visualProperties)
308         {
309           value = visualProperties->mTransformOffset[GetEventThreadServices().GetEventBufferIndex()];
310         }
311         break;
312       }
313       case Dali::VisualRenderer::Property::TRANSFORM_SIZE:
314       {
315         auto visualProperties = sceneObject.GetVisualProperties();
316         if(visualProperties)
317         {
318           value = visualProperties->mTransformSize[GetEventThreadServices().GetEventBufferIndex()];
319         }
320         break;
321       }
322       case Dali::VisualRenderer::Property::TRANSFORM_ORIGIN:
323       {
324         auto visualProperties = sceneObject.GetVisualProperties();
325         if(visualProperties)
326         {
327           value = visualProperties->mTransformOrigin[GetEventThreadServices().GetEventBufferIndex()];
328         }
329         break;
330       }
331       case Dali::VisualRenderer::Property::TRANSFORM_ANCHOR_POINT:
332       {
333         auto visualProperties = sceneObject.GetVisualProperties();
334         if(visualProperties)
335         {
336           value = visualProperties->mTransformAnchorPoint[GetEventThreadServices().GetEventBufferIndex()];
337         }
338         break;
339       }
340       case Dali::VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE:
341       {
342         auto visualProperties = sceneObject.GetVisualProperties();
343         if(visualProperties)
344         {
345           value = visualProperties->mTransformOffsetSizeMode[GetEventThreadServices().GetEventBufferIndex()];
346         }
347         break;
348       }
349       case Dali::VisualRenderer::Property::EXTRA_SIZE:
350       {
351         auto visualProperties = sceneObject.GetVisualProperties();
352         if(visualProperties)
353         {
354           value = visualProperties->mExtraSize[GetEventThreadServices().GetEventBufferIndex()];
355         }
356         break;
357       }
358       case Dali::VisualRenderer::Property::VISUAL_MIX_COLOR:
359       {
360         auto visualProperties = sceneObject.GetVisualProperties();
361         if(visualProperties)
362         {
363           value = visualProperties->mMixColor[GetEventThreadServices().GetEventBufferIndex()];
364         }
365         break;
366       }
367       case Dali::VisualRenderer::Property::VISUAL_PRE_MULTIPLIED_ALPHA:
368       {
369         auto visualProperties = sceneObject.GetVisualProperties();
370         if(visualProperties)
371         {
372           value = visualProperties->mPreMultipliedAlpha[GetEventThreadServices().GetEventBufferIndex()];
373         }
374         break;
375       }
376     }
377   }
378   return value;
379 }
380
381 void VisualRenderer::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
382 {
383   if(index < Dali::VisualRenderer::Property::DEFAULT_VISUAL_RENDERER_PROPERTY_START_INDEX)
384   {
385     Renderer::OnNotifyDefaultPropertyAnimation(animation, index, value, animationType);
386   }
387   else
388   {
389     switch(animationType)
390     {
391       case Animation::TO:
392       case Animation::BETWEEN:
393       {
394         switch(index)
395         {
396           case Dali::VisualRenderer::Property::TRANSFORM_OFFSET:
397           {
398             value.Get(mPropertyCache.mTransformOffset);
399             break;
400           }
401           case Dali::VisualRenderer::Property::TRANSFORM_SIZE:
402           {
403             value.Get(mPropertyCache.mTransformSize);
404             break;
405           }
406           case Dali::VisualRenderer::Property::EXTRA_SIZE:
407           {
408             value.Get(mPropertyCache.mExtraSize);
409             break;
410           }
411           case Dali::VisualRenderer::Property::VISUAL_MIX_COLOR:
412           {
413             value.Get(mPropertyCache.mMixColor);
414             break;
415           }
416         }
417         break;
418       }
419
420       case Animation::BY:
421       {
422         switch(index)
423         {
424           case Dali::VisualRenderer::Property::TRANSFORM_OFFSET:
425           {
426             AdjustValue<Vector2>(mPropertyCache.mTransformOffset, value);
427             break;
428           }
429           case Dali::VisualRenderer::Property::TRANSFORM_SIZE:
430           {
431             AdjustValue<Vector2>(mPropertyCache.mTransformSize, value);
432             break;
433           }
434           case Dali::VisualRenderer::Property::EXTRA_SIZE:
435           {
436             AdjustValue<Vector2>(mPropertyCache.mExtraSize, value);
437             break;
438           }
439           case Dali::VisualRenderer::Property::VISUAL_MIX_COLOR:
440           {
441             AdjustValue<Vector3>(mPropertyCache.mMixColor, value);
442             break;
443           }
444         }
445         break;
446       }
447     }
448   }
449 }
450
451 const SceneGraph::PropertyBase* VisualRenderer::GetSceneObjectAnimatableProperty(Property::Index index) const
452 {
453   const SceneGraph::PropertyBase* property = nullptr;
454
455   switch(index)
456   {
457     case Dali::VisualRenderer::Property::TRANSFORM_OFFSET:
458     {
459       auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
460       if(visualProperties)
461       {
462         property = &visualProperties->mTransformOffset;
463       }
464       break;
465     }
466     case Dali::VisualRenderer::Property::TRANSFORM_SIZE:
467     {
468       auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
469       if(visualProperties)
470       {
471         property = &visualProperties->mTransformSize;
472       }
473       break;
474     }
475     case Dali::VisualRenderer::Property::EXTRA_SIZE:
476     {
477       auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
478       if(visualProperties)
479       {
480         property = &visualProperties->mExtraSize;
481       }
482       break;
483     }
484     case Dali::VisualRenderer::Property::VISUAL_MIX_COLOR:
485     {
486       auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
487       if(visualProperties)
488       {
489         property = &visualProperties->mMixColor;
490       }
491       break;
492     }
493   }
494
495   if(!property)
496   {
497     // not our property, ask base
498     property = Renderer::GetSceneObjectAnimatableProperty(index);
499   }
500
501   return property;
502 }
503
504 const PropertyInputImpl* VisualRenderer::GetSceneObjectInputProperty(Property::Index index) const
505 {
506   switch(index)
507   {
508     case Dali::VisualRenderer::Property::TRANSFORM_ORIGIN:
509     {
510       auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
511       if(visualProperties)
512       {
513         return &visualProperties->mTransformOrigin;
514       }
515       break;
516     }
517     case Dali::VisualRenderer::Property::TRANSFORM_ANCHOR_POINT:
518     {
519       auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
520       if(visualProperties)
521       {
522         return &visualProperties->mTransformAnchorPoint;
523       }
524       break;
525     }
526     case Dali::VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE:
527     {
528       auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
529       if(visualProperties)
530       {
531         return &visualProperties->mTransformOffsetSizeMode;
532       }
533       break;
534     }
535     case Dali::VisualRenderer::Property::VISUAL_PRE_MULTIPLIED_ALPHA:
536     {
537       auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
538       if(visualProperties)
539       {
540         return &visualProperties->mPreMultipliedAlpha;
541       }
542       break;
543     }
544     default:
545     {
546       return GetSceneObjectAnimatableProperty(index);
547     }
548   }
549   return nullptr;
550 }
551
552 void VisualRenderer::AddUniformMappings()
553 {
554   AddUniformMapping(Dali::VisualRenderer::Property::TRANSFORM_OFFSET, ConstString("offset"));
555   AddUniformMapping(Dali::VisualRenderer::Property::TRANSFORM_SIZE, ConstString("size"));
556   AddUniformMapping(Dali::VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE, ConstString("offsetSizeMode"));
557   AddUniformMapping(Dali::VisualRenderer::Property::TRANSFORM_ORIGIN, ConstString("origin"));
558   AddUniformMapping(Dali::VisualRenderer::Property::TRANSFORM_ANCHOR_POINT, ConstString("anchorPoint"));
559   AddUniformMapping(Dali::VisualRenderer::Property::EXTRA_SIZE, ConstString("extraSize"));
560   AddUniformMapping(Dali::VisualRenderer::Property::VISUAL_MIX_COLOR, ConstString("mixColor"));
561   AddUniformMapping(Dali::VisualRenderer::Property::VISUAL_PRE_MULTIPLIED_ALPHA, ConstString("preMultipliedAlpha"));
562 }
563
564 } // namespace Internal
565
566 } // namespace Dali