DALi Version 2.2.14
[platform/core/uifw/dali-core.git] / dali / internal / event / rendering / decorated-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/decorated-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("cornerRadius", VECTOR4, true, true, true, Dali::DecoratedVisualRenderer::Property::CORNER_RADIUS)
41 DALI_PROPERTY("cornerRadiusPolicy", FLOAT, true, false, true, Dali::DecoratedVisualRenderer::Property::CORNER_RADIUS_POLICY)
42 DALI_PROPERTY("borderlineWidth", FLOAT, true, true, true, Dali::DecoratedVisualRenderer::Property::BORDERLINE_WIDTH)
43 DALI_PROPERTY("borderlineColor", VECTOR4, true, true, true, Dali::DecoratedVisualRenderer::Property::BORDERLINE_COLOR)
44 DALI_PROPERTY("borderlineOffset", FLOAT, true, true, true, Dali::DecoratedVisualRenderer::Property::BORDERLINE_OFFSET)
45 DALI_PROPERTY("blurRadius", FLOAT, true, true, true, Dali::DecoratedVisualRenderer::Property::BLUR_RADIUS)
46 DALI_PROPERTY_TABLE_END(Dali::DecoratedVisualRenderer::Property::CORNER_RADIUS, DecoratedVisualRendererDefaultProperties)
47
48 BaseHandle Create()
49 {
50   return Dali::BaseHandle();
51 }
52
53 TypeRegistration mType(typeid(Dali::DecoratedVisualRenderer), typeid(Dali::VisualRenderer), Create, DecoratedVisualRendererDefaultProperties);
54
55 /**
56  * Sets both the cached value of a property and sends a message to set the animatable property in the Update thread.
57  * @tparam T The property type
58  * @param eventThreadServices The event thread services
59  * @param propertyValue The new property value given
60  * @param cachedValue The local cached value of the property
61  * @param animatableProperty The animatable property to set on the update-thread
62  */
63 template<typename T>
64 void SetValue(EventThreadServices& eventThreadServices, const Property::Value& propertyValue, T& cachedValue, const SceneGraph::AnimatableProperty<T>& animatableProperty)
65 {
66   if(propertyValue.Get(cachedValue))
67   {
68     BakeMessage<T>(eventThreadServices, animatableProperty, cachedValue);
69   }
70 }
71
72 } // unnamed namespace
73
74 DecoratedVisualRendererPtr DecoratedVisualRenderer::New()
75 {
76   // create scene object first so it's guaranteed to exist for the event side
77   auto sceneObjectKey = SceneGraph::Renderer::NewKey();
78
79   auto animatableVisualProperties          = new SceneGraph::VisualRenderer::AnimatableVisualProperties();
80   auto animatableDecoratedVisualProperties = new SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties();
81
82   // Append extended properties as AnimatableDecoratedVisualProperties.
83   animatableVisualProperties->mExtendedProperties               = animatableDecoratedVisualProperties;
84   animatableVisualProperties->mExtendedPropertiesDeleteFunction = SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties::DeleteFunction;
85
86   sceneObjectKey->SetVisualProperties(animatableVisualProperties);
87
88   // pass the pointer to base for message passing
89   DecoratedVisualRendererPtr rendererPtr(new DecoratedVisualRenderer(sceneObjectKey.Get()));
90
91   rendererPtr->AddUniformMappings(); // Ensure properties are mapped to uniforms
92
93   EventThreadServices&       eventThreadServices = rendererPtr->GetEventThreadServices();
94   SceneGraph::UpdateManager& updateManager       = eventThreadServices.GetUpdateManager();
95   AddRendererMessage(updateManager, sceneObjectKey);
96
97   eventThreadServices.RegisterObject(rendererPtr.Get());
98   return rendererPtr;
99 }
100
101 DecoratedVisualRenderer::DecoratedVisualRenderer(const SceneGraph::Renderer* sceneObject)
102 : VisualRenderer(sceneObject),
103   mDecoratedPropertyCache(),
104   mAddUniformFlag(0u)
105 {
106 }
107
108 DecoratedVisualRenderer::~DecoratedVisualRenderer() = default; // The scene object will be deleted by ~VisualRenderer
109
110 void DecoratedVisualRenderer::SetDefaultProperty(Property::Index        index,
111                                                  const Property::Value& propertyValue)
112 {
113   if(index < Dali::DecoratedVisualRenderer::Property::DEFAULT_DECORATED_VISUAL_RENDERER_PROPERTY_START_INDEX)
114   {
115     VisualRenderer::SetDefaultProperty(index, propertyValue);
116   }
117   else
118   {
119     const SceneGraph::Renderer& sceneObject      = GetVisualRendererSceneObject();
120     auto                        visualProperties = sceneObject.GetVisualProperties();
121
122     if(visualProperties)
123     {
124       auto decoratedVisualProperties = static_cast<SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties*>(visualProperties->mExtendedProperties);
125
126       if(decoratedVisualProperties)
127       {
128         EventThreadServices& eventThreadServices = GetEventThreadServices();
129
130         switch(index)
131         {
132           case Dali::DecoratedVisualRenderer::Property::CORNER_RADIUS:
133           {
134             SetValue(eventThreadServices, propertyValue, mDecoratedPropertyCache.mCornerRadius, decoratedVisualProperties->mCornerRadius);
135             break;
136           }
137
138           case Dali::DecoratedVisualRenderer::Property::CORNER_RADIUS_POLICY:
139           {
140             SetValue(eventThreadServices, propertyValue, mDecoratedPropertyCache.mCornerRadiusPolicy, decoratedVisualProperties->mCornerRadiusPolicy);
141             break;
142           }
143
144           case Dali::DecoratedVisualRenderer::Property::BORDERLINE_WIDTH:
145           {
146             SetValue(eventThreadServices, propertyValue, mDecoratedPropertyCache.mBorderlineWidth, decoratedVisualProperties->mBorderlineWidth);
147             break;
148           }
149
150           case Dali::DecoratedVisualRenderer::Property::BORDERLINE_COLOR:
151           {
152             SetValue(eventThreadServices, propertyValue, mDecoratedPropertyCache.mBorderlineColor, decoratedVisualProperties->mBorderlineColor);
153             break;
154           }
155
156           case Dali::DecoratedVisualRenderer::Property::BORDERLINE_OFFSET:
157           {
158             SetValue(eventThreadServices, propertyValue, mDecoratedPropertyCache.mBorderlineOffset, decoratedVisualProperties->mBorderlineOffset);
159             break;
160           }
161
162           case Dali::DecoratedVisualRenderer::Property::BLUR_RADIUS:
163           {
164             SetValue(eventThreadServices, propertyValue, mDecoratedPropertyCache.mBlurRadius, decoratedVisualProperties->mBlurRadius);
165             break;
166           }
167         }
168       }
169     }
170   }
171 }
172
173 Property::Value DecoratedVisualRenderer::GetDefaultProperty(Property::Index index) const
174 {
175   Property::Value value;
176
177   if(index < Dali::DecoratedVisualRenderer::Property::DEFAULT_DECORATED_VISUAL_RENDERER_PROPERTY_START_INDEX)
178   {
179     value = VisualRenderer::GetDefaultProperty(index);
180   }
181   else
182   {
183     switch(index)
184     {
185       case Dali::DecoratedVisualRenderer::Property::CORNER_RADIUS:
186       {
187         value = mDecoratedPropertyCache.mCornerRadius;
188         break;
189       }
190       case Dali::DecoratedVisualRenderer::Property::CORNER_RADIUS_POLICY:
191       {
192         value = mDecoratedPropertyCache.mCornerRadiusPolicy;
193         break;
194       }
195       case Dali::DecoratedVisualRenderer::Property::BORDERLINE_WIDTH:
196       {
197         value = mDecoratedPropertyCache.mBorderlineWidth;
198         break;
199       }
200       case Dali::DecoratedVisualRenderer::Property::BORDERLINE_COLOR:
201       {
202         value = mDecoratedPropertyCache.mBorderlineColor;
203         break;
204       }
205       case Dali::DecoratedVisualRenderer::Property::BORDERLINE_OFFSET:
206       {
207         value = mDecoratedPropertyCache.mBorderlineOffset;
208         break;
209       }
210       case Dali::DecoratedVisualRenderer::Property::BLUR_RADIUS:
211       {
212         value = mDecoratedPropertyCache.mBlurRadius;
213         break;
214       }
215       default:
216       {
217         break;
218       }
219     }
220   }
221
222   return value;
223 }
224
225 Property::Value DecoratedVisualRenderer::GetDefaultPropertyCurrentValue(Property::Index index) const
226 {
227   Property::Value value;
228
229   if(index < Dali::DecoratedVisualRenderer::Property::DEFAULT_DECORATED_VISUAL_RENDERER_PROPERTY_START_INDEX)
230   {
231     value = VisualRenderer::GetDefaultPropertyCurrentValue(index);
232   }
233   else
234   {
235     const SceneGraph::Renderer& sceneObject = GetVisualRendererSceneObject();
236
237     switch(index)
238     {
239       case Dali::DecoratedVisualRenderer::Property::CORNER_RADIUS:
240       {
241         auto visualProperties = sceneObject.GetVisualProperties();
242         if(visualProperties)
243         {
244           auto decoratedVisualProperties = static_cast<SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties*>(visualProperties->mExtendedProperties);
245           if(decoratedVisualProperties)
246           {
247             value = decoratedVisualProperties->mCornerRadius[GetEventThreadServices().GetEventBufferIndex()];
248           }
249         }
250         break;
251       }
252       case Dali::DecoratedVisualRenderer::Property::CORNER_RADIUS_POLICY:
253       {
254         auto visualProperties = sceneObject.GetVisualProperties();
255         if(visualProperties)
256         {
257           auto decoratedVisualProperties = static_cast<SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties*>(visualProperties->mExtendedProperties);
258           if(decoratedVisualProperties)
259           {
260             value = decoratedVisualProperties->mCornerRadiusPolicy[GetEventThreadServices().GetEventBufferIndex()];
261           }
262         }
263         break;
264       }
265       case Dali::DecoratedVisualRenderer::Property::BORDERLINE_WIDTH:
266       {
267         auto visualProperties = sceneObject.GetVisualProperties();
268         if(visualProperties)
269         {
270           auto decoratedVisualProperties = static_cast<SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties*>(visualProperties->mExtendedProperties);
271           if(decoratedVisualProperties)
272           {
273             value = decoratedVisualProperties->mBorderlineWidth[GetEventThreadServices().GetEventBufferIndex()];
274           }
275         }
276         break;
277       }
278       case Dali::DecoratedVisualRenderer::Property::BORDERLINE_COLOR:
279       {
280         auto visualProperties = sceneObject.GetVisualProperties();
281         if(visualProperties)
282         {
283           auto decoratedVisualProperties = static_cast<SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties*>(visualProperties->mExtendedProperties);
284           if(decoratedVisualProperties)
285           {
286             value = decoratedVisualProperties->mBorderlineColor[GetEventThreadServices().GetEventBufferIndex()];
287           }
288         }
289         break;
290       }
291       case Dali::DecoratedVisualRenderer::Property::BORDERLINE_OFFSET:
292       {
293         auto visualProperties = sceneObject.GetVisualProperties();
294         if(visualProperties)
295         {
296           auto decoratedVisualProperties = static_cast<SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties*>(visualProperties->mExtendedProperties);
297           if(decoratedVisualProperties)
298           {
299             value = decoratedVisualProperties->mBorderlineOffset[GetEventThreadServices().GetEventBufferIndex()];
300           }
301         }
302         break;
303       }
304       case Dali::DecoratedVisualRenderer::Property::BLUR_RADIUS:
305       {
306         auto visualProperties = sceneObject.GetVisualProperties();
307         if(visualProperties)
308         {
309           auto decoratedVisualProperties = static_cast<SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties*>(visualProperties->mExtendedProperties);
310           if(decoratedVisualProperties)
311           {
312             value = decoratedVisualProperties->mBlurRadius[GetEventThreadServices().GetEventBufferIndex()];
313           }
314         }
315         break;
316       }
317     }
318   }
319   return value;
320 }
321
322 void DecoratedVisualRenderer::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
323 {
324   if(index < Dali::DecoratedVisualRenderer::Property::DEFAULT_DECORATED_VISUAL_RENDERER_PROPERTY_START_INDEX)
325   {
326     VisualRenderer::OnNotifyDefaultPropertyAnimation(animation, index, value, animationType);
327   }
328   else
329   {
330     switch(animationType)
331     {
332       case Animation::TO:
333       case Animation::BETWEEN:
334       {
335         switch(index)
336         {
337           case Dali::DecoratedVisualRenderer::Property::CORNER_RADIUS:
338           {
339             value.Get(mDecoratedPropertyCache.mCornerRadius);
340             break;
341           }
342           case Dali::DecoratedVisualRenderer::Property::BORDERLINE_WIDTH:
343           {
344             value.Get(mDecoratedPropertyCache.mBorderlineWidth);
345             break;
346           }
347           case Dali::DecoratedVisualRenderer::Property::BORDERLINE_COLOR:
348           {
349             value.Get(mDecoratedPropertyCache.mBorderlineColor);
350             break;
351           }
352           case Dali::DecoratedVisualRenderer::Property::BORDERLINE_OFFSET:
353           {
354             value.Get(mDecoratedPropertyCache.mBorderlineOffset);
355             break;
356           }
357           case Dali::DecoratedVisualRenderer::Property::BLUR_RADIUS:
358           {
359             value.Get(mDecoratedPropertyCache.mBlurRadius);
360             break;
361           }
362         }
363         break;
364       }
365
366       case Animation::BY:
367       {
368         switch(index)
369         {
370           case Dali::DecoratedVisualRenderer::Property::CORNER_RADIUS:
371           {
372             AdjustValue<Vector4>(mDecoratedPropertyCache.mCornerRadius, value);
373             break;
374           }
375           case Dali::DecoratedVisualRenderer::Property::BORDERLINE_WIDTH:
376           {
377             AdjustValue<float>(mDecoratedPropertyCache.mBorderlineWidth, value);
378             break;
379           }
380           case Dali::DecoratedVisualRenderer::Property::BORDERLINE_COLOR:
381           {
382             AdjustValue<Vector4>(mDecoratedPropertyCache.mBorderlineColor, value);
383             break;
384           }
385           case Dali::DecoratedVisualRenderer::Property::BORDERLINE_OFFSET:
386           {
387             AdjustValue<float>(mDecoratedPropertyCache.mBorderlineOffset, value);
388             break;
389           }
390           case Dali::DecoratedVisualRenderer::Property::BLUR_RADIUS:
391           {
392             AdjustValue<float>(mDecoratedPropertyCache.mBlurRadius, value);
393             break;
394           }
395         }
396         break;
397       }
398     }
399   }
400 }
401
402 const SceneGraph::PropertyBase* DecoratedVisualRenderer::GetSceneObjectAnimatableProperty(Property::Index index) const
403 {
404   const SceneGraph::PropertyBase* property = nullptr;
405
406   switch(index)
407   {
408     case Dali::DecoratedVisualRenderer::Property::CORNER_RADIUS:
409     {
410       auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
411       if(visualProperties)
412       {
413         auto decoratedVisualProperties = static_cast<SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties*>(visualProperties->mExtendedProperties);
414         if(decoratedVisualProperties)
415         {
416           property = &decoratedVisualProperties->mCornerRadius;
417         }
418       }
419       break;
420     }
421     case Dali::DecoratedVisualRenderer::Property::BORDERLINE_WIDTH:
422     {
423       auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
424       if(visualProperties)
425       {
426         auto decoratedVisualProperties = static_cast<SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties*>(visualProperties->mExtendedProperties);
427         if(decoratedVisualProperties)
428         {
429           property = &decoratedVisualProperties->mBorderlineWidth;
430         }
431       }
432       break;
433     }
434     case Dali::DecoratedVisualRenderer::Property::BORDERLINE_COLOR:
435     {
436       auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
437       if(visualProperties)
438       {
439         auto decoratedVisualProperties = static_cast<SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties*>(visualProperties->mExtendedProperties);
440         if(decoratedVisualProperties)
441         {
442           property = &decoratedVisualProperties->mBorderlineColor;
443         }
444       }
445       break;
446     }
447     case Dali::DecoratedVisualRenderer::Property::BORDERLINE_OFFSET:
448     {
449       auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
450       if(visualProperties)
451       {
452         auto decoratedVisualProperties = static_cast<SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties*>(visualProperties->mExtendedProperties);
453         if(decoratedVisualProperties)
454         {
455           property = &decoratedVisualProperties->mBorderlineOffset;
456         }
457       }
458       break;
459     }
460     case Dali::DecoratedVisualRenderer::Property::BLUR_RADIUS:
461     {
462       auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
463       if(visualProperties)
464       {
465         auto decoratedVisualProperties = static_cast<SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties*>(visualProperties->mExtendedProperties);
466         if(decoratedVisualProperties)
467         {
468           property = &decoratedVisualProperties->mBlurRadius;
469         }
470       }
471       break;
472     }
473   }
474
475   if(!property)
476   {
477     // not our property, ask base
478     property = VisualRenderer::GetSceneObjectAnimatableProperty(index);
479   }
480
481   return property;
482 }
483
484 const PropertyInputImpl* DecoratedVisualRenderer::GetSceneObjectInputProperty(Property::Index index) const
485 {
486   if(index < Dali::DecoratedVisualRenderer::Property::DEFAULT_DECORATED_VISUAL_RENDERER_PROPERTY_START_INDEX)
487   {
488     return VisualRenderer::GetSceneObjectInputProperty(index);
489   }
490   switch(index)
491   {
492     case Dali::DecoratedVisualRenderer::Property::CORNER_RADIUS_POLICY:
493     {
494       auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
495       if(visualProperties)
496       {
497         auto decoratedVisualProperties = static_cast<SceneGraph::VisualRenderer::AnimatableDecoratedVisualProperties*>(visualProperties->mExtendedProperties);
498         if(decoratedVisualProperties)
499         {
500           return &decoratedVisualProperties->mCornerRadiusPolicy;
501         }
502       }
503       break;
504     }
505     default:
506     {
507       return GetSceneObjectAnimatableProperty(index);
508     }
509   }
510   return nullptr;
511 }
512
513 void DecoratedVisualRenderer::RegisterCornerRadiusUniform()
514 {
515   AddUniformFlag(DECORATED_VISUAL_RENDERER_USE_CORNER_RADIUS);
516 }
517
518 void DecoratedVisualRenderer::RegisterBorderlineUniform()
519 {
520   AddUniformFlag(DECORATED_VISUAL_RENDERER_USE_BORDERLINE);
521 }
522
523 void DecoratedVisualRenderer::RegisterBlurRadiusUniform()
524 {
525   AddUniformFlag(DECORATED_VISUAL_RENDERER_USE_BLUR_RADIUS);
526 }
527
528 void DecoratedVisualRenderer::AddUniformFlag(uint8_t newAddFlag)
529 {
530   const uint8_t diffUniformFlag = (~mAddUniformFlag) & newAddFlag;
531   if(diffUniformFlag)
532   {
533     if(diffUniformFlag & DECORATED_VISUAL_RENDERER_USE_CORNER_RADIUS)
534     {
535       AddUniformMapping(Dali::DecoratedVisualRenderer::Property::CORNER_RADIUS, ConstString("cornerRadius"));
536       AddUniformMapping(Dali::DecoratedVisualRenderer::Property::CORNER_RADIUS_POLICY, ConstString("cornerRadiusPolicy"));
537     }
538     if(diffUniformFlag & DECORATED_VISUAL_RENDERER_USE_BORDERLINE)
539     {
540       AddUniformMapping(Dali::DecoratedVisualRenderer::Property::BORDERLINE_WIDTH, ConstString("borderlineWidth"));
541       AddUniformMapping(Dali::DecoratedVisualRenderer::Property::BORDERLINE_COLOR, ConstString("borderlineColor"));
542       AddUniformMapping(Dali::DecoratedVisualRenderer::Property::BORDERLINE_OFFSET, ConstString("borderlineOffset"));
543     }
544     if(diffUniformFlag & DECORATED_VISUAL_RENDERER_USE_BLUR_RADIUS)
545     {
546       AddUniformMapping(Dali::DecoratedVisualRenderer::Property::BLUR_RADIUS, ConstString("blurRadius"));
547     }
548
549     // Note. Let we don't remove UniformMapping due to the performane issue.
550     mAddUniformFlag |= newAddFlag;
551   }
552 }
553
554 } // namespace Internal
555
556 } // namespace Dali