1 /* 2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 /** 17 * @addtogroup RenderNodeDisplay 18 * @{ 19 * 20 * @brief Display render nodes. 21 */ 22 23 /** 24 * @file rs_property.h 25 * 26 * @brief Defines the properties and methods of RSPropertyBase and its derived classes. 27 */ 28 29 #ifndef RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_PROPERTY_H 30 #define RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_PROPERTY_H 31 32 #include <type_traits> 33 #include <unistd.h> 34 35 #include "animation/rs_animation_callback.h" 36 #include "animation/rs_animation_trace_utils.h" 37 #include "animation/rs_implicit_animator.h" 38 #include "animation/rs_implicit_animator_map.h" 39 #include "animation/rs_motion_path_option.h" 40 #include "command/rs_node_showing_command.h" 41 #include "common/rs_color.h" 42 #include "common/rs_common_def.h" 43 #include "common/rs_macros.h" 44 #include "common/rs_vector2.h" 45 #include "common/rs_vector4.h" 46 #include "modifier/rs_animatable_arithmetic.h" 47 #include "modifier/rs_render_property.h" 48 #include "pipeline/rs_node_map.h" 49 #include "transaction/rs_transaction_proxy.h" 50 #include "ui/rs_node.h" 51 #include "ui/rs_ui_context.h" 52 53 #ifdef _WIN32 54 #include <windows.h> 55 #define gettid GetCurrentThreadId 56 #endif 57 58 #ifdef __APPLE__ 59 #define gettid getpid 60 #endif 61 62 #ifdef __gnu_linux__ 63 #include <sys/types.h> 64 #include <sys/syscall.h> 65 #define gettid []() -> int32_t { return static_cast<int32_t>(syscall(SYS_gettid)); } 66 #endif 67 68 namespace OHOS { 69 namespace Rosen { 70 namespace ModifierNG { 71 class RSModifier; 72 class RSForegroundFilterModifier; 73 class RSBackgroundFilterModifier; 74 } 75 class RSFilter; 76 class RSImage; 77 class RSMask; 78 class RSPath; 79 class RSNGFilterBase; 80 class RSNGMaskBase; 81 class RSLinearGradientBlurPara; 82 class MotionBlurParam; 83 class RSMagnifierParams; 84 class ParticleNoiseFields; 85 class RSShader; 86 class RSNGEffectUtils; 87 88 /** 89 * @brief Defines different types of thresholds for spring animation. 90 * 91 * Used to determine when the spring animation ends visually 92 */ 93 enum class ThresholdType { 94 /** 0.5f for properties like position, as the difference in properties by 0.5 appears visually unchanged. */ 95 LAYOUT, 96 /** 1.0f / 256.0f */ 97 COARSE, 98 /** 1.0f / 1000.0f */ 99 MEDIUM, 100 /** 1.0f / 3072.0f */ 101 FINE, 102 /** 0.0f */ 103 COLOR, 104 /** 1.0f / 256.0f */ 105 DEFAULT, 106 /** 0.0f for noanimatable property */ 107 ZERO, 108 }; 109 110 /** 111 * @class RSPropertyBase 112 * 113 * @brief The base class for properties. 114 * 115 * This class provides a common interface for all property types. 116 */ 117 class RSC_EXPORT RSPropertyBase : public std::enable_shared_from_this<RSPropertyBase> { 118 public: 119 /** 120 * @brief Constructor for RSPropertyBase. 121 */ 122 RSPropertyBase(); 123 124 /** 125 * @brief Destructor for RSPropertyBase. 126 */ 127 virtual ~RSPropertyBase() = default; 128 129 /** 130 * @brief Gets the ID of the property. 131 * 132 * @return The ID of the property. 133 */ GetId()134 PropertyId GetId() const 135 { 136 return id_; 137 } 138 139 /** 140 * @brief Sets the threshold type for the property. 141 * 142 * @param thresholdType Indicates the threshold type to be set. 143 */ SetThresholdType(ThresholdType thresholdType)144 virtual void SetThresholdType(ThresholdType thresholdType) {} 145 146 /** 147 * @brief Gets the threshold type for the property. 148 * 149 * @return The threshold type of the property. 150 */ GetThreshold()151 virtual float GetThreshold() const 152 { 153 return 0.0f; 154 } 155 156 /** 157 * @brief Sets the value of the property from the render. 158 * 159 * @param rsRenderPropertyBase A shared pointer to the RSRenderPropertyBase object. 160 */ SetValueFromRender(const std::shared_ptr<const RSRenderPropertyBase> & rsRenderPropertyBase)161 virtual void SetValueFromRender(const std::shared_ptr<const RSRenderPropertyBase>& rsRenderPropertyBase) {} 162 GetPropertyTypeNG()163 virtual ModifierNG::RSPropertyType GetPropertyTypeNG() const 164 { 165 return ModifierNG::RSPropertyType::INVALID; 166 } 167 SetPropertyTypeNG(const ModifierNG::RSPropertyType type)168 virtual void SetPropertyTypeNG(const ModifierNG::RSPropertyType type) {} 169 IsPathAnimatable()170 inline bool IsPathAnimatable() const 171 { 172 auto type = GetPropertyTypeNG(); 173 return (type == ModifierNG::RSPropertyType::BOUNDS || type == ModifierNG::RSPropertyType::FRAME || 174 type == ModifierNG::RSPropertyType::TRANSLATE); 175 } 176 177 protected: 178 virtual void SetIsCustom(bool isCustom) = 0; 179 virtual bool GetIsCustom() const = 0; 180 virtual void SetValue(const std::shared_ptr<RSPropertyBase>& value) = 0; 181 virtual std::shared_ptr<RSPropertyBase> Clone() const = 0; SetMotionPathOption(const std::shared_ptr<RSMotionPathOption> & motionPathOption)182 virtual void SetMotionPathOption(const std::shared_ptr<RSMotionPathOption>& motionPathOption) {} 183 184 virtual RSPropertyType GetPropertyType() const = 0; 185 186 float GetThresholdByModifierType() const; 187 UpdateOnAllAnimationFinish()188 virtual void UpdateOnAllAnimationFinish() {} UpdateCustomAnimation()189 virtual void UpdateCustomAnimation() {} AddPathAnimation()190 virtual void AddPathAnimation() {} RemovePathAnimation()191 virtual void RemovePathAnimation() {} 192 UpdateShowingValue(const std::shared_ptr<const RSRenderPropertyBase> & property)193 virtual void UpdateShowingValue(const std::shared_ptr<const RSRenderPropertyBase>& property) {} 194 195 void Attach(RSNode& node, std::weak_ptr<ModifierNG::RSModifier> modifier = {}) 196 { 197 target_ = node.weak_from_this(); 198 modifierNG_ = modifier; 199 node.RegisterProperty(shared_from_this()); 200 OnAttach(node, modifier); 201 } 202 OnAttach(RSNode & node,std::weak_ptr<ModifierNG::RSModifier> modifier)203 virtual void OnAttach(RSNode& node, std::weak_ptr<ModifierNG::RSModifier> modifier) {} 204 Detach()205 void Detach() 206 { 207 if (auto node = target_.lock()) { 208 node->UnregisterProperty(GetId()); 209 } 210 OnDetach(); 211 target_.reset(); 212 modifierNG_.reset(); 213 } 214 OnDetach()215 virtual void OnDetach() {} 216 AttachModifier(const std::shared_ptr<ModifierNG::RSModifier> & modifier)217 void AttachModifier(const std::shared_ptr<ModifierNG::RSModifier>& modifier) 218 { 219 modifierNG_ = modifier; 220 } 221 222 void MarkCustomModifierDirty(); 223 224 void MarkNodeDirty(); 225 226 void UpdateExtendModifierForGeometry(const std::shared_ptr<RSNode>& node); 227 228 virtual std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() = 0; 229 GetShowingValueAndCancelAnimation()230 virtual bool GetShowingValueAndCancelAnimation() 231 { 232 return false; 233 } 234 235 float GetThresholdByThresholdType(ThresholdType thresholdType) const; 236 237 PropertyId id_; 238 std::weak_ptr<RSNode> target_; 239 std::weak_ptr<ModifierNG::RSModifier> modifierNG_; 240 241 private: Add(const std::shared_ptr<const RSPropertyBase> & value)242 virtual std::shared_ptr<RSPropertyBase> Add(const std::shared_ptr<const RSPropertyBase>& value) 243 { 244 return shared_from_this(); 245 } 246 Minus(const std::shared_ptr<const RSPropertyBase> & value)247 virtual std::shared_ptr<RSPropertyBase> Minus(const std::shared_ptr<const RSPropertyBase>& value) 248 { 249 return shared_from_this(); 250 } 251 Multiply(const float scale)252 virtual std::shared_ptr<RSPropertyBase> Multiply(const float scale) 253 { 254 return shared_from_this(); 255 } 256 IsEqual(const std::shared_ptr<const RSPropertyBase> & value)257 virtual bool IsEqual(const std::shared_ptr<const RSPropertyBase>& value) const 258 { 259 return true; 260 } 261 262 friend std::shared_ptr<RSPropertyBase> operator+=( 263 const std::shared_ptr<RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 264 friend std::shared_ptr<RSPropertyBase> operator-=( 265 const std::shared_ptr<RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 266 friend std::shared_ptr<RSPropertyBase> operator*=(const std::shared_ptr<RSPropertyBase>& value, const float scale); 267 friend std::shared_ptr<RSPropertyBase> operator+( 268 const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 269 friend std::shared_ptr<RSPropertyBase> operator-( 270 const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 271 friend std::shared_ptr<RSPropertyBase> operator*( 272 const std::shared_ptr<const RSPropertyBase>& value, const float scale); 273 friend bool operator==( 274 const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 275 friend bool operator!=( 276 const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 277 friend class RSTransition; 278 friend class RSSpringAnimation; 279 friend class RSPropertyAnimation; 280 friend class RSPathAnimation; 281 friend class RSModifier; 282 friend class ModifierNG::RSModifier; 283 friend class RSNode; 284 friend class RSBackgroundUIFilterModifier; 285 friend class RSForegroundUIFilterModifier; 286 friend class RSKeyframeAnimation; 287 friend class RSInterpolatingSpringAnimation; 288 friend class RSImplicitTransitionParam; 289 friend class RSImplicitSpringAnimationParam; 290 friend class RSImplicitKeyframeAnimationParam; 291 friend class RSImplicitInterpolatingSpringAnimationParam; 292 friend class RSImplicitCancelAnimationParam; 293 friend class RSImplicitCurveAnimationParam; 294 friend class RSImplicitAnimator; 295 friend class RSGeometryTransModifier; 296 friend class RSExtendedModifier; 297 friend class RSCustomTransitionEffect; 298 friend class RSCurveAnimation; 299 friend class ModifierNG::RSForegroundFilterModifier; 300 friend class ModifierNG::RSBackgroundFilterModifier; 301 template<typename T> 302 friend class RSAnimatableProperty; 303 template<uint16_t commandType, uint16_t commandSubType> 304 friend class RSGetShowingValueAndCancelAnimationTask; 305 friend class RSNGEffectUtils; 306 }; 307 308 /** 309 * @struct RSRenderPropertyTraits 310 * 311 * @brief Helper for getting type of RSRenderProperty. 312 */ 313 template<typename T> 314 struct RSRenderPropertyTraits { 315 using Type = RSRenderProperty<T>; 316 }; 317 318 template<> 319 struct RSRenderPropertyTraits<std::shared_ptr<RSNGFilterBase>> { 320 using Type = RSRenderProperty<std::shared_ptr<RSNGRenderFilterBase>>; 321 }; 322 323 template<> 324 struct RSRenderPropertyTraits<std::shared_ptr<RSNGShaderBase>> { 325 using Type = RSRenderProperty<std::shared_ptr<RSNGRenderShaderBase>>; 326 }; 327 328 template<> 329 struct RSRenderPropertyTraits<std::shared_ptr<RSNGMaskBase>> { 330 using Type = RSRenderProperty<std::shared_ptr<RSNGRenderMaskBase>>; 331 }; 332 333 /** 334 * @class RSProperty 335 * 336 * @brief The class for properties. 337 */ 338 template<typename T> 339 class RSProperty : public RSPropertyBase { 340 static_assert(std::is_base_of_v<RSArithmetic<T>, T> || supports_arithmetic<T>::value); 341 342 public: 343 /** 344 * @brief Constructor for RSProperty. 345 */ 346 RSProperty() : RSPropertyBase() {} 347 348 /** 349 * @brief Constructor for RSProperty. 350 * 351 * @param value Indicates the staging value. 352 */ 353 explicit RSProperty(const T& value) : RSPropertyBase() 354 { 355 stagingValue_ = value; 356 } 357 358 /** 359 * @brief Destructor for RSProperty. 360 */ 361 ~RSProperty() override = default; 362 363 using ValueType = T; 364 365 using RenderPropertyType = typename RSRenderPropertyTraits<T>::Type; 366 367 virtual void Set(const T& value) 368 { 369 if (ROSEN_EQ(value, stagingValue_) || !IsValid(value)) { 370 return; 371 } 372 373 stagingValue_ = value; 374 auto node = target_.lock(); 375 if (node == nullptr) { 376 return; 377 } 378 379 MarkNodeDirty(); 380 UpdateExtendModifierForGeometry(node); 381 if (isCustom_) { 382 MarkCustomModifierDirty(); 383 } else { 384 UpdateToRender(stagingValue_, UPDATE_TYPE_OVERWRITE); 385 } 386 } 387 388 /** 389 * @brief Gets the value of the staging. 390 * 391 * @return The value of the staging. 392 */ 393 virtual T Get() const 394 { 395 return stagingValue_; 396 } 397 398 ModifierNG::RSPropertyType GetPropertyTypeNG() const override 399 { 400 return typeNG_; 401 } 402 403 void SetPropertyTypeNG(const ModifierNG::RSPropertyType type) override 404 { 405 typeNG_ = type; 406 } 407 408 protected: 409 RSPropertyType GetPropertyType() const override { return type_; } 410 411 void UpdateToRender(const T& value, PropertyUpdateType type) const 412 {} 413 414 void SetValue(const std::shared_ptr<RSPropertyBase>& value) override 415 { 416 auto property = std::static_pointer_cast<RSProperty<T>>(value); 417 if (property != nullptr) { 418 stagingValue_ = property->stagingValue_; 419 } 420 } 421 422 std::shared_ptr<RSPropertyBase> Clone() const override 423 { 424 return std::make_shared<RSProperty<T>>(stagingValue_); 425 } 426 427 void OnAttach(RSNode& node, std::weak_ptr<ModifierNG::RSModifier> modifier) override {} 428 429 void OnDetach() override {} 430 431 bool IsValid(const T& value) 432 { 433 return true; 434 } 435 436 void SetIsCustom(bool isCustom) override 437 { 438 isCustom_ = isCustom; 439 } 440 441 bool GetIsCustom() const override 442 { 443 return isCustom_; 444 } 445 446 std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() override 447 { 448 return std::make_shared<RSRenderProperty<T>>(stagingValue_, id_); 449 } 450 451 inline static const RSPropertyType type_ = RSPropertyType::INVALID; 452 ModifierNG::RSPropertyType typeNG_ = ModifierNG::RSPropertyType::INVALID; 453 454 T stagingValue_ {}; 455 bool isCustom_ { false }; 456 457 friend class RSPathAnimation; 458 friend class RSImplicitAnimator; 459 friend class RSExtendedModifier; 460 friend class RSModifier; 461 friend class RSNGEffectUtils; 462 }; 463 464 /** 465 * @class RSAnimatableProperty 466 * 467 * @brief The class for animatable properties. 468 */ 469 template<typename T> 470 class RSAnimatableProperty : public RSProperty<T> { 471 static_assert(std::is_floating_point_v<T> || std::is_same_v<Color, T> || std::is_same_v<Matrix3f, T> || 472 std::is_same_v<Vector2f, T> || std::is_same_v<Vector3f, T> || std::is_same_v<Vector4f, T> || 473 std::is_same_v<Quaternion, T> || std::is_same_v<Vector4<Color>, T> || 474 supports_animatable_arithmetic<T>::value || std::is_base_of_v<RSAnimatableArithmetic<T>, T> || 475 std::is_same_v<RRect, T>); 476 477 public: 478 /** 479 * @brief Constructor for RSAnimatableProperty. 480 */ 481 RSAnimatableProperty() : RSProperty<T>() {} 482 483 /** 484 * @brief Constructor for RSAnimatableProperty. 485 * 486 * @param value Indicates the showing value. 487 */ 488 explicit RSAnimatableProperty(const T& value) : RSProperty<T>(value) 489 { 490 showingValue_ = value; 491 } 492 493 /** 494 * @brief Destructor for RSAnimatableProperty. 495 */ 496 virtual ~RSAnimatableProperty() = default; 497 498 using ValueType = T; 499 500 using RenderPropertyType = RSRenderAnimatableProperty<T>; 501 502 void Set(const T& value) override 503 { 504 if (ROSEN_EQ(value, RSProperty<T>::stagingValue_) || !RSProperty<T>::IsValid(value)) { 505 return; 506 } 507 508 auto node = RSProperty<T>::target_.lock(); 509 if (node == nullptr) { 510 RSProperty<T>::stagingValue_ = value; 511 return; 512 } 513 514 RSProperty<T>::MarkNodeDirty(); 515 RSProperty<T>::UpdateExtendModifierForGeometry(node); 516 auto rsUIContext = node->GetRSUIContext(); 517 auto implicitAnimator = rsUIContext ? rsUIContext->GetRSImplicitAnimator() : 518 RSImplicitAnimatorMap::Instance().GetAnimator(gettid()); 519 if (implicitAnimator && implicitAnimator->NeedImplicitAnimation()) { 520 auto startValue = std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_); 521 auto endValue = std::make_shared<RSAnimatableProperty<T>>(value); 522 if (motionPathOption_ != nullptr) { 523 implicitAnimator->BeginImplicitPathAnimation(motionPathOption_); 524 implicitAnimator->CreateImplicitAnimation( 525 node, RSProperty<T>::shared_from_this(), startValue, endValue); 526 implicitAnimator->EndImplicitPathAnimation(); 527 } else { 528 implicitAnimator->CreateImplicitAnimation( 529 node, RSProperty<T>::shared_from_this(), startValue, endValue); 530 } 531 return; 532 } 533 534 if (runningPathNum_ > 0) { 535 return; 536 } 537 538 bool hasPropertyAnimation = node->HasPropertyAnimation(RSProperty<T>::id_); 539 T sendValue = value; 540 if (hasPropertyAnimation) { 541 sendValue = value - RSProperty<T>::stagingValue_; 542 auto endValue = std::make_shared<RSAnimatableProperty<T>>(value); 543 RSAnimationTraceUtils::GetInstance().AddChangeAnimationValueTrace( 544 RSProperty<T>::id_, endValue->GetRenderProperty()); 545 } 546 RSProperty<T>::stagingValue_ = value; 547 if (RSProperty<T>::isCustom_) { 548 UpdateExtendedAnimatableProperty(sendValue, hasPropertyAnimation); 549 } else { 550 RSProperty<T>::UpdateToRender( 551 sendValue, hasPropertyAnimation ? UPDATE_TYPE_INCREMENTAL : UPDATE_TYPE_OVERWRITE); 552 } 553 } 554 555 /** 556 * @brief Requests the cancellation of an ongoing implicit animation. 557 */ 558 void RequestCancelAnimation() 559 { 560 auto node = RSProperty<T>::target_.lock(); 561 if (node == nullptr) { 562 return; 563 } 564 auto rsUIContext = node->GetRSUIContext(); 565 auto implicitAnimator = rsUIContext ? rsUIContext->GetRSImplicitAnimator() 566 : RSImplicitAnimatorMap::Instance().GetAnimator(gettid()); 567 if (implicitAnimator && implicitAnimator->NeedImplicitAnimation()) { 568 implicitAnimator->CancelImplicitAnimation(node, RSProperty<T>::shared_from_this()); 569 } 570 } 571 572 T Get() const override 573 { 574 if (RSProperty<T>::isCustom_) { 575 return showingValue_; 576 } 577 return RSProperty<T>::stagingValue_; 578 } 579 580 /** 581 * @brief Gets the staging value of the property. 582 * @return The staging value. 583 */ 584 T GetStagingValue() const 585 { 586 return RSProperty<T>::stagingValue_; 587 } 588 589 /** 590 * @brief Gets the showing value of the property and cancels the animation. 591 * 592 * @return true if the showing value was successfully got and the animation was canceled, or if no 593 * animation was present or the property is custom; false if the task timed out or the property 594 * could not be retrieved. 595 */ 596 bool GetShowingValueAndCancelAnimation() override 597 { 598 auto node = RSProperty<T>::target_.lock(); 599 if (node == nullptr) { 600 return false; 601 } 602 if (!node->HasPropertyAnimation(this->id_) || this->GetIsCustom()) { 603 return true; 604 } 605 auto task = std::make_shared<RSNodeGetShowingPropertyAndCancelAnimation>(node->GetId(), GetRenderProperty()); 606 auto rsUIContext = node->GetRSUIContext(); 607 if (rsUIContext != nullptr) { 608 auto transaction = rsUIContext->GetRSTransaction(); 609 if (transaction != nullptr) { 610 transaction->ExecuteSynchronousTask(task, node->IsRenderServiceNode()); 611 } 612 } else { 613 auto transactionProxy = RSTransactionProxy::GetInstance(); 614 if (transactionProxy != nullptr) { 615 transactionProxy->ExecuteSynchronousTask(task, node->IsRenderServiceNode()); 616 } 617 } 618 619 // when task is timeout, the caller need to decide whether to call this function again 620 if (!task || task->IsTimeout()) { 621 return false; 622 } 623 624 // We also need to send a command to cancel animation, cause: 625 // case 1. some new animations have been added, but not flushed to render side, 626 // resulting these animations not canceled in task. 627 // case 2. the node or modifier has not yet been created on the render side, resulting in task failure. 628 node->CancelAnimationByProperty(this->id_, !RSProperty<T>::isCustom_); 629 630 if (!task->IsSuccess()) { 631 // corresponding to case 2, as the new showing value is the same as staging value, 632 // need not to update the value 633 return true; 634 } 635 636 auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(task->GetProperty()); 637 if (!renderProperty) { 638 return false; 639 } 640 RSProperty<T>::stagingValue_ = renderProperty->Get(); 641 return true; 642 } 643 644 /** 645 * @brief Sets the value of the property from render. 646 * 647 * @param rsRenderPropertyBase A shared pointer to the RSRenderPropertyBase object. 648 */ 649 void SetValueFromRender(const std::shared_ptr<const RSRenderPropertyBase>& rsRenderPropertyBase) override 650 { 651 auto renderProperty = std::static_pointer_cast<const RSRenderAnimatableProperty<T>>(rsRenderPropertyBase); 652 if (!renderProperty) { 653 return; 654 } 655 RSProperty<T>::stagingValue_ = renderProperty->Get(); 656 } 657 658 /** 659 * @brief Sets the callback function to be called when the property is updated. 660 * 661 * @param updateCallback The callback function to be set. 662 */ 663 void SetUpdateCallback(const std::function<void(T)>& updateCallback) 664 { 665 propertyChangeListener_ = updateCallback; 666 } 667 668 /** 669 * @brief Plays the animation. 670 * 671 * @param timingProtocol The protocol specifying the timing parameters for the animation (e.g., duration, delay). 672 * @param timingCurve The curve defining the pacing of the animation (e.g., linear, ease-in, custom). 673 * @param targetValue The target value to animate to, wrapped in a shared pointer to RSPropertyBase. 674 * @param velocity (Optional) The initial velocity for the animation, wrapped in a shared pointer to RSAnimatableProperty<T>. 675 * @param finishCallback (Optional) A callback function to be invoked when the animation finishes. 676 * @param repeatCallback (Optional) A callback function to be invoked when the animation repeats. 677 * @return std::vector<std::shared_ptr<RSAnimation>> A vector of shared pointers to the created RSAnimation objects. 678 * Returns an empty vector if the animation could not be created. 679 */ 680 std::vector<std::shared_ptr<RSAnimation>> AnimateWithInitialVelocity( 681 const RSAnimationTimingProtocol& timingProtocol, const RSAnimationTimingCurve& timingCurve, 682 const std::shared_ptr<RSPropertyBase>& targetValue, 683 const std::shared_ptr<RSAnimatableProperty<T>>& velocity = nullptr, 684 const std::function<void()>& finishCallback = nullptr, const std::function<void()>& repeatCallback = nullptr) 685 { 686 auto endValue = std::static_pointer_cast<RSAnimatableProperty<T>>(targetValue); 687 if (!endValue) { 688 return {}; 689 } 690 691 auto node = RSProperty<T>::target_.lock(); 692 if (!node) { 693 RSProperty<T>::stagingValue_ = endValue->Get(); 694 return {}; 695 } 696 auto rsUIContext = node->GetRSUIContext(); 697 const auto& implicitAnimator = rsUIContext ? rsUIContext->GetRSImplicitAnimator() : 698 RSImplicitAnimatorMap::Instance().GetAnimator(gettid()); 699 if (!implicitAnimator) { 700 RSProperty<T>::stagingValue_ = endValue->Get(); 701 return {}; 702 } 703 704 std::shared_ptr<AnimationFinishCallback> animationFinishCallback; 705 if (finishCallback) { 706 animationFinishCallback = 707 std::make_shared<AnimationFinishCallback>(finishCallback, timingProtocol.GetFinishCallbackType()); 708 } 709 710 std::shared_ptr<AnimationRepeatCallback> animationRepeatCallback; 711 if (repeatCallback) { 712 animationRepeatCallback = std::make_shared<AnimationRepeatCallback>(repeatCallback); 713 } 714 715 implicitAnimator->OpenImplicitAnimation( 716 timingProtocol, timingCurve, std::move(animationFinishCallback), std::move(animationRepeatCallback)); 717 auto startValue = std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_); 718 if (velocity) { 719 implicitAnimator->CreateImplicitAnimationWithInitialVelocity( 720 node, RSProperty<T>::shared_from_this(), startValue, endValue, velocity); 721 } else { 722 implicitAnimator->CreateImplicitAnimation(node, RSProperty<T>::shared_from_this(), startValue, endValue); 723 } 724 725 return implicitAnimator->CloseImplicitAnimation(); 726 } 727 728 /** 729 * @brief Sets the property unit. 730 * 731 * @param unit The property unit to be set. 732 */ 733 void SetPropertyUnit(RSPropertyUnit unit) 734 { 735 propertyUnit_ = unit; 736 } 737 738 protected: 739 void UpdateOnAllAnimationFinish() override 740 { 741 RSProperty<T>::UpdateToRender(RSProperty<T>::stagingValue_, UPDATE_TYPE_FORCE_OVERWRITE); 742 } 743 744 void UpdateCustomAnimation() override 745 { 746 if (RSProperty<T>::isCustom_) { 747 UpdateExtendedAnimatableProperty(RSProperty<T>::stagingValue_, false); 748 } 749 } 750 751 void UpdateExtendedAnimatableProperty(const T& value, bool isDelta) 752 { 753 if (isDelta) { 754 if (renderProperty_ != nullptr) { 755 renderProperty_->Set(renderProperty_->Get() + value); 756 } 757 } else { 758 showingValue_ = value; 759 RSProperty<T>::MarkCustomModifierDirty(); 760 if (renderProperty_ != nullptr) { 761 renderProperty_->Set(value); 762 } else { 763 NotifyPropertyChange(); 764 } 765 } 766 } 767 768 void AddPathAnimation() override 769 { 770 runningPathNum_ += 1; 771 } 772 773 void RemovePathAnimation() override 774 { 775 runningPathNum_ -= 1; 776 } 777 778 void UpdateShowingValue(const std::shared_ptr<const RSRenderPropertyBase>& property) override 779 { 780 auto renderProperty = std::static_pointer_cast<const RSRenderProperty<T>>(property); 781 if (renderProperty != nullptr) { 782 showingValue_ = renderProperty->Get(); 783 NotifyPropertyChange(); 784 RSProperty<T>::MarkCustomModifierDirty(); 785 } 786 } 787 788 void SetValue(const std::shared_ptr<RSPropertyBase>& value) override 789 { 790 auto property = std::static_pointer_cast<RSAnimatableProperty<T>>(value); 791 if (property != nullptr && property->GetPropertyType() == RSProperty<T>::GetPropertyType()) { 792 RSProperty<T>::stagingValue_ = property->stagingValue_; 793 } 794 } 795 796 std::shared_ptr<RSPropertyBase> Clone() const override 797 { 798 return std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_); 799 } 800 801 void SetMotionPathOption(const std::shared_ptr<RSMotionPathOption>& motionPathOption) override 802 { 803 motionPathOption_ = motionPathOption; 804 } 805 806 std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() override 807 { 808 if (!RSProperty<T>::isCustom_) { 809 return std::make_shared<RSRenderAnimatableProperty<T>>( 810 RSProperty<T>::stagingValue_, RSProperty<T>::id_, propertyUnit_); 811 } 812 813 if (renderProperty_ == nullptr) { 814 renderProperty_ = std::make_shared<RSRenderAnimatableProperty<T>>( 815 RSProperty<T>::stagingValue_, RSProperty<T>::id_, propertyUnit_); 816 auto weak = RSProperty<T>::weak_from_this(); 817 renderProperty_->SetUpdateUIPropertyFunc( 818 [weak](const std::shared_ptr<RSRenderPropertyBase>& renderProperty) { 819 auto property = weak.lock(); 820 if (property == nullptr) { 821 return; 822 } 823 property->UpdateShowingValue(renderProperty); 824 }); 825 } 826 return renderProperty_; 827 } 828 829 void NotifyPropertyChange() 830 { 831 if (propertyChangeListener_) { 832 propertyChangeListener_(showingValue_); 833 } 834 } 835 836 void SetThresholdType(ThresholdType thresholdType) override 837 { 838 thresholdType_ = thresholdType; 839 } 840 841 float GetThreshold() const override 842 { 843 return RSProperty<T>::GetThresholdByThresholdType(thresholdType_); 844 } 845 846 T showingValue_ {}; 847 std::shared_ptr<RSRenderAnimatableProperty<T>> renderProperty_; 848 int runningPathNum_ { 0 }; 849 std::shared_ptr<RSMotionPathOption> motionPathOption_ {}; 850 std::function<void(T)> propertyChangeListener_; 851 ThresholdType thresholdType_ { ThresholdType::DEFAULT }; 852 RSPropertyUnit propertyUnit_ { RSPropertyUnit::UNKNOWN }; 853 854 private: 855 std::shared_ptr<RSPropertyBase> Add(const std::shared_ptr<const RSPropertyBase>& value) override 856 { 857 auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value); 858 if (animatableProperty != nullptr) { 859 RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ + animatableProperty->stagingValue_; 860 } 861 return RSProperty<T>::shared_from_this(); 862 } 863 864 std::shared_ptr<RSPropertyBase> Minus(const std::shared_ptr<const RSPropertyBase>& value) override 865 { 866 auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value); 867 if (animatableProperty != nullptr) { 868 RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ - animatableProperty->stagingValue_; 869 } 870 return RSProperty<T>::shared_from_this(); 871 } 872 873 std::shared_ptr<RSPropertyBase> Multiply(const float scale) override 874 { 875 RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ * scale; 876 return RSProperty<T>::shared_from_this(); 877 } 878 879 bool IsEqual(const std::shared_ptr<const RSPropertyBase>& value) const override 880 { 881 auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value); 882 if (animatableProperty != nullptr) { 883 return RSProperty<T>::stagingValue_ == animatableProperty->stagingValue_; 884 } 885 return true; 886 } 887 888 friend class RSPropertyAnimation; 889 friend class RSPathAnimation; 890 friend class RSExtendedModifier; 891 friend class RSModifier; 892 friend class RSNGEffectUtils; 893 }; 894 895 template<> 896 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGFilterBase>>::OnAttach(RSNode& node, 897 std::weak_ptr<ModifierNG::RSModifier> modifier); 898 template<> 899 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGFilterBase>>::OnDetach(); 900 template<> 901 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGFilterBase>>::Set(const std::shared_ptr<RSNGFilterBase>& value); 902 template<> 903 RSC_EXPORT std::shared_ptr<RSRenderPropertyBase> RSProperty<std::shared_ptr<RSNGFilterBase>>::GetRenderProperty(); 904 template<> 905 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGShaderBase>>::OnAttach(RSNode& node, 906 std::weak_ptr<ModifierNG::RSModifier> modifier); 907 template<> 908 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGShaderBase>>::OnDetach(); 909 template<> 910 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGShaderBase>>::Set(const std::shared_ptr<RSNGShaderBase>& value); 911 template<> 912 RSC_EXPORT std::shared_ptr<RSRenderPropertyBase> RSProperty<std::shared_ptr<RSNGShaderBase>>::GetRenderProperty(); 913 914 template<> 915 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGMaskBase>>::OnAttach(RSNode& node, 916 std::weak_ptr<ModifierNG::RSModifier> modifier); 917 template<> 918 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGMaskBase>>::OnDetach(); 919 template<> 920 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGMaskBase>>::Set(const std::shared_ptr<RSNGMaskBase>& value); 921 template<> 922 RSC_EXPORT std::shared_ptr<RSRenderPropertyBase> RSProperty<std::shared_ptr<RSNGMaskBase>>::GetRenderProperty(); 923 924 template<> 925 RSC_EXPORT void RSProperty<bool>::UpdateToRender(const bool& value, PropertyUpdateType type) const; 926 template<> 927 RSC_EXPORT void RSProperty<float>::UpdateToRender(const float& value, PropertyUpdateType type) const; 928 template <> 929 RSC_EXPORT void RSProperty<std::vector<float>>::UpdateToRender( 930 const std::vector<float> &value, PropertyUpdateType type) const; 931 template <> 932 RSC_EXPORT void RSProperty<int>::UpdateToRender(const int &value, PropertyUpdateType type) const; 933 template<> 934 RSC_EXPORT void RSProperty<Color>::UpdateToRender(const Color& value, PropertyUpdateType type) const; 935 template<> 936 RSC_EXPORT void RSProperty<Gravity>::UpdateToRender(const Gravity& value, PropertyUpdateType type) const; 937 template<> 938 RSC_EXPORT void RSProperty<Matrix3f>::UpdateToRender(const Matrix3f& value, PropertyUpdateType type) const; 939 template<> 940 RSC_EXPORT void RSProperty<Quaternion>::UpdateToRender(const Quaternion& value, PropertyUpdateType type) const; 941 template<> 942 RSC_EXPORT void RSProperty<std::shared_ptr<RSImage>>::UpdateToRender( 943 const std::shared_ptr<RSImage>& value, PropertyUpdateType type) const; 944 template<> 945 RSC_EXPORT void RSProperty<std::shared_ptr<RSMask>>::UpdateToRender( 946 const std::shared_ptr<RSMask>& value, PropertyUpdateType type) const; 947 template<> 948 RSC_EXPORT void RSProperty<std::shared_ptr<RSPath>>::UpdateToRender( 949 const std::shared_ptr<RSPath>& value, PropertyUpdateType type) const; 950 template<> 951 RSC_EXPORT void RSProperty<RSWaterRipplePara>::UpdateToRender( 952 const RSWaterRipplePara& value, PropertyUpdateType type) const; 953 template<> 954 RSC_EXPORT void RSProperty<RSFlyOutPara>::UpdateToRender( 955 const RSFlyOutPara& value, PropertyUpdateType type) const; 956 template<> 957 RSC_EXPORT void RSProperty<std::shared_ptr<RSLinearGradientBlurPara>>::UpdateToRender( 958 const std::shared_ptr<RSLinearGradientBlurPara>& value, PropertyUpdateType type) const; 959 template<> 960 RSC_EXPORT void RSProperty<std::shared_ptr<MotionBlurParam>>::UpdateToRender( 961 const std::shared_ptr<MotionBlurParam>& value, PropertyUpdateType type) const; 962 template<> 963 RSC_EXPORT void RSProperty<std::shared_ptr<RSMagnifierParams>>::UpdateToRender( 964 const std::shared_ptr<RSMagnifierParams>& value, PropertyUpdateType type) const; 965 template<> 966 RSC_EXPORT void RSProperty<std::vector<std::shared_ptr<EmitterUpdater>>>::UpdateToRender( 967 const std::vector<std::shared_ptr<EmitterUpdater>>& value, PropertyUpdateType type) const; 968 template<> 969 RSC_EXPORT void RSProperty<std::shared_ptr<ParticleNoiseFields>>::UpdateToRender( 970 const std::shared_ptr<ParticleNoiseFields>& value, PropertyUpdateType type) const; 971 template<> 972 RSC_EXPORT void RSProperty<std::shared_ptr<RSShader>>::UpdateToRender( 973 const std::shared_ptr<RSShader>& value, PropertyUpdateType type) const; 974 template<> 975 RSC_EXPORT void RSProperty<Vector2f>::UpdateToRender(const Vector2f& value, PropertyUpdateType type) const; 976 template<> 977 RSC_EXPORT void RSProperty<Vector3f>::UpdateToRender(const Vector3f& value, PropertyUpdateType type) const; 978 template<> 979 RSC_EXPORT void RSProperty<Vector4<uint32_t>>::UpdateToRender( 980 const Vector4<uint32_t>& value, PropertyUpdateType type) const; 981 template<> 982 RSC_EXPORT void RSProperty<Vector4<Color>>::UpdateToRender( 983 const Vector4<Color>& value, PropertyUpdateType type) const; 984 template<> 985 RSC_EXPORT void RSProperty<Vector4f>::UpdateToRender(const Vector4f& value, PropertyUpdateType type) const; 986 template<> 987 RSC_EXPORT void RSProperty<RRect>::UpdateToRender(const RRect& value, PropertyUpdateType type) const; 988 template<> 989 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGFilterBase>>::UpdateToRender( 990 const std::shared_ptr<RSNGFilterBase>& value, PropertyUpdateType type) const; 991 template<> 992 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGShaderBase>>::UpdateToRender( 993 const std::shared_ptr<RSNGShaderBase>& value, PropertyUpdateType type) const; 994 template<> 995 RSC_EXPORT void RSProperty<std::shared_ptr<RSNGMaskBase>>::UpdateToRender( 996 const std::shared_ptr<RSNGMaskBase>& value, PropertyUpdateType type) const; 997 998 template<> 999 RSC_EXPORT bool RSProperty<float>::IsValid(const float& value); 1000 template<> 1001 RSC_EXPORT bool RSProperty<Vector2f>::IsValid(const Vector2f& value); 1002 template<> 1003 RSC_EXPORT bool RSProperty<Vector4f>::IsValid(const Vector4f& value); 1004 1005 #define DECLARE_PROPERTY(T, TYPE_ENUM) \ 1006 template<> \ 1007 inline const RSPropertyType RSProperty<T>::type_ = RSPropertyType::TYPE_ENUM 1008 #define DECLARE_ANIMATABLE_PROPERTY(T, TYPE_ENUM) DECLARE_PROPERTY(T, TYPE_ENUM) 1009 1010 #include "modifier/rs_property_def.in" 1011 1012 #undef DECLARE_PROPERTY 1013 #undef DECLARE_ANIMATABLE_PROPERTY 1014 1015 } // namespace Rosen 1016 } // namespace OHOS 1017 1018 /** @} */ 1019 #endif // RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_PROPERTY_H 1020