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