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