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