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 #ifndef RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_PROPERTY_H 17 #define RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_PROPERTY_H 18 19 #include <type_traits> 20 #include <unistd.h> 21 22 #include "animation/rs_animation_callback.h" 23 #include "animation/rs_implicit_animator.h" 24 #include "animation/rs_implicit_animator_map.h" 25 #include "animation/rs_motion_path_option.h" 26 #include "command/rs_node_showing_command.h" 27 #include "common/rs_color.h" 28 #include "common/rs_common_def.h" 29 #include "common/rs_macros.h" 30 #include "common/rs_vector2.h" 31 #include "common/rs_vector4.h" 32 #include "modifier/rs_animatable_arithmetic.h" 33 #include "modifier/rs_modifier_type.h" 34 #include "modifier/rs_render_property.h" 35 #include "pipeline/rs_node_map.h" 36 #include "property/rs_properties_def.h" 37 #include "render/rs_border.h" 38 #include "render/rs_filter.h" 39 #include "render/rs_image.h" 40 #include "render/rs_mask.h" 41 #include "render/rs_path.h" 42 #include "render/rs_shader.h" 43 #include "transaction/rs_transaction_proxy.h" 44 #include "ui/rs_node.h" 45 46 #ifdef _WIN32 47 #include <windows.h> 48 #define gettid GetCurrentThreadId 49 #endif 50 51 #ifdef __APPLE__ 52 #define gettid getpid 53 #endif 54 55 #ifdef __gnu_linux__ 56 #include <sys/types.h> 57 #include <sys/syscall.h> 58 #define gettid []() -> int32_t { return static_cast<int32_t>(syscall(SYS_gettid)); } 59 #endif 60 61 namespace OHOS { 62 namespace Rosen { 63 // used to determine when the spring animation ends visually 64 enum class ThresholdType { 65 LAYOUT, // 0.5f for properties like position, as the difference in properties by 0.5 appears visually unchanged 66 COARSE, // 1.0f / 256.0f 67 MEDIUM, // 1.0f / 1000.0f 68 FINE, // 1.0f / 3072.0f 69 COLOR, // 0.0f 70 DEFAULT, // 1.0f / 256.0f 71 ZERO, // 0.0f for noanimatable property 72 }; 73 74 namespace { 75 constexpr float DEFAULT_NEAR_ZERO_THRESHOLD = 1.0f / 256.0f; 76 constexpr float FLOAT_NEAR_ZERO_COARSE_THRESHOLD = 1.0f / 256.0f; 77 constexpr float FLOAT_NEAR_ZERO_MEDIUM_THRESHOLD = 1.0f / 1000.0f; 78 constexpr float FLOAT_NEAR_ZERO_FINE_THRESHOLD = 1.0f / 3072.0f; 79 constexpr float COLOR_NEAR_ZERO_THRESHOLD = 0.0f; 80 constexpr float LAYOUT_NEAR_ZERO_THRESHOLD = 0.5f; 81 constexpr float ZERO = 0.0f; 82 } // namespace 83 84 template<class...> 85 struct make_void { using type = void; }; 86 template<class... T> 87 using void_t = typename make_void<T...>::type; 88 89 template<class T, class = void> 90 struct supports_arithmetic : std::false_type {}; 91 template<class T> 92 struct supports_arithmetic<T, 93 void_t<decltype(std::declval<T>() == std::declval<T>())>> 94 : std::true_type {}; 95 96 template<class T, class = void> 97 struct supports_animatable_arithmetic : std::false_type {}; 98 template<class T> 99 struct supports_animatable_arithmetic<T, 100 void_t<decltype(std::declval<T>() + std::declval<T>()), 101 decltype(std::declval<T>() - std::declval<T>()), 102 decltype(std::declval<T>() * std::declval<float>()), 103 decltype(std::declval<T>() == std::declval<T>())>> 104 : std::true_type {}; 105 106 class RSC_EXPORT RSPropertyBase : public std::enable_shared_from_this<RSPropertyBase> { 107 public: 108 RSPropertyBase(); 109 virtual ~RSPropertyBase() = default; 110 111 PropertyId GetId() const 112 { 113 return id_; 114 } 115 116 virtual void SetThresholdType(ThresholdType thresholdType) {} 117 virtual float GetThreshold() const 118 { 119 return 0.0f; 120 } 121 122 virtual void SetValueFromRender(const std::shared_ptr<const RSRenderPropertyBase>& rsRenderPropertyBase) {}; 123 124 protected: 125 virtual void SetIsCustom(bool isCustom) {} 126 127 virtual bool GetIsCustom() const 128 { 129 return false; 130 } 131 132 virtual void SetValue(const std::shared_ptr<RSPropertyBase>& value) {} 133 134 virtual std::shared_ptr<RSPropertyBase> Clone() const 135 { 136 return std::make_shared<RSPropertyBase>(); 137 } 138 139 virtual void SetMotionPathOption(const std::shared_ptr<RSMotionPathOption>& motionPathOption) {} 140 141 virtual RSRenderPropertyType GetPropertyType() const 142 { 143 return RSRenderPropertyType::INVALID; 144 } 145 146 float GetThresholdByModifierType() const; 147 148 virtual void UpdateOnAllAnimationFinish() {} 149 virtual void UpdateCustomAnimation() {} 150 151 virtual void AddPathAnimation() {} 152 153 virtual void RemovePathAnimation() {} 154 155 virtual void UpdateShowingValue(const std::shared_ptr<const RSRenderPropertyBase>& property) {} 156 157 void AttachModifier(const std::shared_ptr<RSModifier>& modifier) 158 { 159 modifier_ = modifier; 160 } 161 162 void MarkModifierDirty(); 163 164 void UpdateExtendModifierForGeometry(const std::shared_ptr<RSNode>& node); 165 166 virtual std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() 167 { 168 return std::make_shared<RSRenderPropertyBase>(id_); 169 } 170 171 virtual bool GetShowingValueAndCancelAnimation() 172 { 173 return false; 174 } 175 176 float GetThresholdByThresholdType(ThresholdType thresholdType) const; 177 178 PropertyId id_; 179 RSModifierType type_ { RSModifierType::INVALID }; 180 std::weak_ptr<RSNode> target_; 181 std::weak_ptr<RSModifier> modifier_; 182 183 private: 184 virtual std::shared_ptr<RSPropertyBase> Add(const std::shared_ptr<const RSPropertyBase>& value) 185 { 186 return shared_from_this(); 187 } 188 189 virtual std::shared_ptr<RSPropertyBase> Minus(const std::shared_ptr<const RSPropertyBase>& value) 190 { 191 return shared_from_this(); 192 } 193 194 virtual std::shared_ptr<RSPropertyBase> Multiply(const float scale) 195 { 196 return shared_from_this(); 197 } 198 199 virtual bool IsEqual(const std::shared_ptr<const RSPropertyBase>& value) const 200 { 201 return true; 202 } 203 204 friend std::shared_ptr<RSPropertyBase> operator+=( 205 const std::shared_ptr<RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 206 friend std::shared_ptr<RSPropertyBase> operator-=( 207 const std::shared_ptr<RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 208 friend std::shared_ptr<RSPropertyBase> operator*=(const std::shared_ptr<RSPropertyBase>& value, const float scale); 209 friend std::shared_ptr<RSPropertyBase> operator+( 210 const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 211 friend std::shared_ptr<RSPropertyBase> operator-( 212 const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 213 friend std::shared_ptr<RSPropertyBase> operator*( 214 const std::shared_ptr<const RSPropertyBase>& value, const float scale); 215 friend bool operator==( 216 const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 217 friend bool operator!=( 218 const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 219 friend class RSTransition; 220 friend class RSSpringAnimation; 221 friend class RSPropertyAnimation; 222 friend class RSPathAnimation; 223 friend class RSModifier; 224 friend class RSKeyframeAnimation; 225 friend class RSInterpolatingSpringAnimation; 226 friend class RSImplicitTransitionParam; 227 friend class RSImplicitSpringAnimationParam; 228 friend class RSImplicitKeyframeAnimationParam; 229 friend class RSImplicitInterpolatingSpringAnimationParam; 230 friend class RSImplicitCancelAnimationParam; 231 friend class RSImplicitCurveAnimationParam; 232 friend class RSImplicitAnimator; 233 friend class RSGeometryTransModifier; 234 friend class RSExtendedModifier; 235 friend class RSCustomTransitionEffect; 236 friend class RSCurveAnimation; 237 template<typename T1> 238 friend class RSAnimatableProperty; 239 template<uint16_t commandType, uint16_t commandSubType> 240 friend class RSGetShowingValueAndCancelAnimationTask; 241 }; 242 243 template<typename T> 244 class RSProperty : public RSPropertyBase { 245 static_assert(std::is_base_of_v<RSArithmetic<T>, T> || supports_arithmetic<T>::value); 246 247 public: 248 RSProperty() : RSPropertyBase() {} 249 explicit RSProperty(const T& value) : RSPropertyBase() 250 { 251 stagingValue_ = value; 252 } 253 virtual ~RSProperty() = default; 254 255 virtual void Set(const T& value) 256 { 257 if (ROSEN_EQ(value, stagingValue_) || !IsValid(value)) { 258 return; 259 } 260 261 stagingValue_ = value; 262 auto node = target_.lock(); 263 if (node == nullptr) { 264 return; 265 } 266 267 UpdateExtendModifierForGeometry(node); 268 if (isCustom_) { 269 MarkModifierDirty(); 270 } else { 271 UpdateToRender(stagingValue_, UPDATE_TYPE_OVERWRITE); 272 } 273 } 274 275 virtual T Get() const 276 { 277 return stagingValue_; 278 } 279 280 protected: 281 void UpdateToRender(const T& value, PropertyUpdateType type) const 282 {} 283 284 void SetValue(const std::shared_ptr<RSPropertyBase>& value) override 285 { 286 auto property = std::static_pointer_cast<RSProperty<T>>(value); 287 if (property != nullptr) { 288 stagingValue_ = property->stagingValue_; 289 } 290 } 291 292 std::shared_ptr<RSPropertyBase> Clone() const override 293 { 294 return std::make_shared<RSProperty<T>>(stagingValue_); 295 } 296 297 bool IsValid(const T& value) 298 { 299 return true; 300 } 301 302 void SetIsCustom(bool isCustom) override 303 { 304 isCustom_ = isCustom; 305 } 306 307 bool GetIsCustom() const override 308 { 309 return isCustom_; 310 } 311 312 std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() override 313 { 314 return std::make_shared<RSRenderProperty<T>>(stagingValue_, id_); 315 } 316 317 T stagingValue_ {}; 318 bool isCustom_ { false }; 319 320 friend class RSPathAnimation; 321 friend class RSImplicitAnimator; 322 friend class RSExtendedModifier; 323 friend class RSModifier; 324 }; 325 326 template<typename T> 327 class RSAnimatableProperty : public RSProperty<T> { 328 static_assert(std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_same_v<Color, T> || 329 std::is_same_v<Matrix3f, T> || std::is_same_v<Vector2f, T> || std::is_same_v<Vector4f, T> || 330 std::is_same_v<Quaternion, T> || std::is_same_v<std::shared_ptr<RSFilter>, T> || 331 std::is_same_v<Vector4<Color>, T> || std::is_base_of_v<RSAnimatableArithmetic<T>, T> || 332 supports_animatable_arithmetic<T>::value || std::is_same_v<RRect, T>); 333 334 public: 335 RSAnimatableProperty() : RSProperty<T>() {} 336 explicit RSAnimatableProperty(const T& value) : RSProperty<T>(value) 337 { 338 showingValue_ = value; 339 } 340 341 virtual ~RSAnimatableProperty() = default; 342 343 void Set(const T& value) override 344 { 345 if (ROSEN_EQ(value, RSProperty<T>::stagingValue_) || !RSProperty<T>::IsValid(value)) { 346 return; 347 } 348 349 auto node = RSProperty<T>::target_.lock(); 350 if (node == nullptr) { 351 RSProperty<T>::stagingValue_ = value; 352 return; 353 } 354 355 RSProperty<T>::UpdateExtendModifierForGeometry(node); 356 auto implicitAnimator = RSImplicitAnimatorMap::Instance().GetAnimator(gettid()); 357 if (implicitAnimator && implicitAnimator->NeedImplicitAnimation()) { 358 auto startValue = std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_); 359 auto endValue = std::make_shared<RSAnimatableProperty<T>>(value); 360 if (motionPathOption_ != nullptr) { 361 implicitAnimator->BeginImplicitPathAnimation(motionPathOption_); 362 implicitAnimator->CreateImplicitAnimation( 363 node, RSProperty<T>::shared_from_this(), startValue, endValue); 364 implicitAnimator->EndImplicitPathAnimation(); 365 } else { 366 implicitAnimator->CreateImplicitAnimation( 367 node, RSProperty<T>::shared_from_this(), startValue, endValue); 368 } 369 return; 370 } 371 372 if (runningPathNum_ > 0) { 373 return; 374 } 375 376 bool hasPropertyAnimation = node->HasPropertyAnimation(RSProperty<T>::id_); 377 T sendValue = value; 378 if (hasPropertyAnimation) { 379 sendValue = value - RSProperty<T>::stagingValue_; 380 } 381 RSProperty<T>::stagingValue_ = value; 382 if (RSProperty<T>::isCustom_) { 383 UpdateExtendedAnimatableProperty(sendValue, hasPropertyAnimation); 384 } else { 385 RSProperty<T>::UpdateToRender( 386 sendValue, hasPropertyAnimation ? UPDATE_TYPE_INCREMENTAL : UPDATE_TYPE_OVERWRITE); 387 } 388 } 389 390 void RequestCancelAnimation() 391 { 392 auto node = RSProperty<T>::target_.lock(); 393 if (node == nullptr) { 394 return; 395 } 396 auto implicitAnimator = RSImplicitAnimatorMap::Instance().GetAnimator(gettid()); 397 if (implicitAnimator && implicitAnimator->NeedImplicitAnimation()) { 398 implicitAnimator->CancelImplicitAnimation(node, RSProperty<T>::shared_from_this()); 399 } 400 } 401 402 T Get() const override 403 { 404 if (RSProperty<T>::isCustom_) { 405 return showingValue_; 406 } 407 return RSProperty<T>::stagingValue_; 408 } 409 410 T GetStagingValue() const 411 { 412 return RSProperty<T>::stagingValue_; 413 } 414 415 bool GetShowingValueAndCancelAnimation() override 416 { 417 auto node = RSProperty<T>::target_.lock(); 418 if (node == nullptr) { 419 return false; 420 } 421 if (!node->HasPropertyAnimation(this->id_) || this->GetIsCustom()) { 422 return true; 423 } 424 auto task = std::make_shared<RSNodeGetShowingPropertyAndCancelAnimation>(node->GetId(), GetRenderProperty()); 425 RSTransactionProxy::GetInstance()->ExecuteSynchronousTask(task, node->IsRenderServiceNode()); 426 // when task is timeout, the caller need to decide whether to call this function again 427 if (!task || task->IsTimeout()) { 428 return false; 429 } 430 431 // We also need to send a command to cancel animation, cause: 432 // case 1. some new animations have been added, but not flushed to render side, 433 // resulting these animations not canceled in task. 434 // case 2. the node or modifier has not yet been created on the render side, resulting in task failure. 435 node->CancelAnimationByProperty(this->id_, !RSProperty<T>::isCustom_); 436 437 if (!task->IsSuccess()) { 438 // corresponding to case 2, as the new showing value is the same as staging value, 439 // need not to update the value 440 return true; 441 } 442 443 auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(task->GetProperty()); 444 if (!renderProperty) { 445 return false; 446 } 447 RSProperty<T>::stagingValue_ = renderProperty->Get(); 448 return true; 449 } 450 451 void SetValueFromRender(const std::shared_ptr<const RSRenderPropertyBase>& rsRenderPropertyBase) override 452 { 453 auto renderProperty = std::static_pointer_cast<const RSRenderAnimatableProperty<T>>(rsRenderPropertyBase); 454 if (!renderProperty) { 455 return; 456 } 457 RSProperty<T>::stagingValue_ = renderProperty->Get(); 458 } 459 460 void SetUpdateCallback(const std::function<void(T)>& updateCallback) 461 { 462 propertyChangeListener_ = updateCallback; 463 } 464 465 std::vector<std::shared_ptr<RSAnimation>> AnimateWithInitialVelocity( 466 const RSAnimationTimingProtocol& timingProtocol, const RSAnimationTimingCurve& timingCurve, 467 const std::shared_ptr<RSPropertyBase>& targetValue, 468 const std::shared_ptr<RSAnimatableProperty<T>>& velocity = nullptr, 469 const std::function<void()>& finishCallback = nullptr, const std::function<void()>& repeatCallback = nullptr) 470 { 471 auto endValue = std::static_pointer_cast<RSAnimatableProperty<T>>(targetValue); 472 if (!endValue) { 473 return {}; 474 } 475 476 auto node = RSProperty<T>::target_.lock(); 477 if (!node) { 478 RSProperty<T>::stagingValue_ = endValue->Get(); 479 return {}; 480 } 481 482 const auto& implicitAnimator = RSImplicitAnimatorMap::Instance().GetAnimator(gettid()); 483 if (!implicitAnimator) { 484 RSProperty<T>::stagingValue_ = endValue->Get(); 485 return {}; 486 } 487 488 std::shared_ptr<AnimationFinishCallback> animationFinishCallback; 489 if (finishCallback) { 490 animationFinishCallback = 491 std::make_shared<AnimationFinishCallback>(finishCallback, timingProtocol.GetFinishCallbackType()); 492 } 493 494 std::shared_ptr<AnimationRepeatCallback> animationRepeatCallback; 495 if (repeatCallback) { 496 animationRepeatCallback = std::make_shared<AnimationRepeatCallback>(repeatCallback); 497 } 498 499 implicitAnimator->OpenImplicitAnimation( 500 timingProtocol, timingCurve, std::move(animationFinishCallback), std::move(animationRepeatCallback)); 501 auto startValue = std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_); 502 if (velocity) { 503 implicitAnimator->CreateImplicitAnimationWithInitialVelocity( 504 node, RSProperty<T>::shared_from_this(), startValue, endValue, velocity); 505 } else { 506 implicitAnimator->CreateImplicitAnimation(node, RSProperty<T>::shared_from_this(), startValue, endValue); 507 } 508 509 return implicitAnimator->CloseImplicitAnimation(); 510 } 511 512 void SetPropertyUnit(RSPropertyUnit unit) 513 { 514 propertyUnit_ = unit; 515 } 516 517 protected: 518 void UpdateOnAllAnimationFinish() override 519 { 520 RSProperty<T>::UpdateToRender(RSProperty<T>::stagingValue_, UPDATE_TYPE_FORCE_OVERWRITE); 521 } 522 523 void UpdateCustomAnimation() override 524 { 525 if (RSProperty<T>::isCustom_) { 526 UpdateExtendedAnimatableProperty(RSProperty<T>::stagingValue_, false); 527 } 528 } 529 530 void UpdateExtendedAnimatableProperty(const T& value, bool isDelta) 531 { 532 if (isDelta) { 533 if (renderProperty_ != nullptr) { 534 renderProperty_->Set(renderProperty_->Get() + value); 535 } 536 } else { 537 showingValue_ = value; 538 RSProperty<T>::MarkModifierDirty(); 539 if (renderProperty_ != nullptr) { 540 renderProperty_->Set(value); 541 } else { 542 NotifyPropertyChange(); 543 } 544 } 545 } 546 547 void AddPathAnimation() override 548 { 549 runningPathNum_ += 1; 550 } 551 552 void RemovePathAnimation() override 553 { 554 runningPathNum_ -= 1; 555 } 556 557 void UpdateShowingValue(const std::shared_ptr<const RSRenderPropertyBase>& property) override 558 { 559 auto renderProperty = std::static_pointer_cast<const RSRenderProperty<T>>(property); 560 if (renderProperty != nullptr) { 561 showingValue_ = renderProperty->Get(); 562 NotifyPropertyChange(); 563 RSProperty<T>::MarkModifierDirty(); 564 } 565 } 566 567 void SetValue(const std::shared_ptr<RSPropertyBase>& value) override 568 { 569 auto property = std::static_pointer_cast<RSAnimatableProperty<T>>(value); 570 if (property != nullptr && property->GetPropertyType() == GetPropertyType()) { 571 RSProperty<T>::stagingValue_ = property->stagingValue_; 572 } 573 } 574 575 std::shared_ptr<RSPropertyBase> Clone() const override 576 { 577 return std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_); 578 } 579 580 void SetMotionPathOption(const std::shared_ptr<RSMotionPathOption>& motionPathOption) override 581 { 582 motionPathOption_ = motionPathOption; 583 } 584 585 std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() override 586 { 587 if (!RSProperty<T>::isCustom_) { 588 return std::make_shared<RSRenderAnimatableProperty<T>>( 589 RSProperty<T>::stagingValue_, RSProperty<T>::id_, GetPropertyType(), propertyUnit_); 590 } 591 592 if (renderProperty_ == nullptr) { 593 renderProperty_ = std::make_shared<RSRenderAnimatableProperty<T>>( 594 RSProperty<T>::stagingValue_, RSProperty<T>::id_, GetPropertyType(), propertyUnit_); 595 auto weak = RSProperty<T>::weak_from_this(); 596 renderProperty_->SetUpdateUIPropertyFunc( 597 [weak](const std::shared_ptr<RSRenderPropertyBase>& renderProperty) { 598 auto property = weak.lock(); 599 if (property == nullptr) { 600 return; 601 } 602 property->UpdateShowingValue(renderProperty); 603 }); 604 } 605 return renderProperty_; 606 } 607 608 void NotifyPropertyChange() 609 { 610 if (propertyChangeListener_) { 611 propertyChangeListener_(showingValue_); 612 } 613 } 614 615 void SetThresholdType(ThresholdType thresholdType) override 616 { 617 thresholdType_ = thresholdType; 618 } 619 620 float GetThreshold() const override 621 { 622 return RSProperty<T>::GetThresholdByThresholdType(thresholdType_); 623 } 624 625 T showingValue_ {}; 626 std::shared_ptr<RSRenderAnimatableProperty<T>> renderProperty_; 627 int runningPathNum_ { 0 }; 628 std::shared_ptr<RSMotionPathOption> motionPathOption_ {}; 629 std::function<void(T)> propertyChangeListener_; 630 ThresholdType thresholdType_ { ThresholdType::DEFAULT }; 631 RSPropertyUnit propertyUnit_ { RSPropertyUnit::UNKNOWN }; 632 633 private: 634 RSRenderPropertyType GetPropertyType() const override 635 { 636 return RSRenderPropertyType::INVALID; 637 } 638 639 std::shared_ptr<RSPropertyBase> Add(const std::shared_ptr<const RSPropertyBase>& value) override 640 { 641 auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value); 642 if (animatableProperty != nullptr) { 643 RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ + animatableProperty->stagingValue_; 644 } 645 return RSProperty<T>::shared_from_this(); 646 } 647 648 std::shared_ptr<RSPropertyBase> Minus(const std::shared_ptr<const RSPropertyBase>& value) override 649 { 650 auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value); 651 if (animatableProperty != nullptr) { 652 RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ - animatableProperty->stagingValue_; 653 } 654 return RSProperty<T>::shared_from_this(); 655 } 656 657 std::shared_ptr<RSPropertyBase> Multiply(const float scale) override 658 { 659 RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ * scale; 660 return RSProperty<T>::shared_from_this(); 661 } 662 663 bool IsEqual(const std::shared_ptr<const RSPropertyBase>& value) const override 664 { 665 auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value); 666 if (animatableProperty != nullptr) { 667 return RSProperty<T>::stagingValue_ == animatableProperty->stagingValue_; 668 } 669 return true; 670 } 671 672 friend class RSPropertyAnimation; 673 friend class RSPathAnimation; 674 friend class RSExtendedModifier; 675 friend class RSModifier; 676 }; 677 678 template<> 679 RSC_EXPORT void RSProperty<bool>::UpdateToRender(const bool& value, PropertyUpdateType type) const; 680 template<> 681 RSC_EXPORT void RSProperty<float>::UpdateToRender(const float& value, PropertyUpdateType type) const; 682 template<> 683 RSC_EXPORT void RSProperty<int>::UpdateToRender(const int& value, PropertyUpdateType type) const; 684 template<> 685 RSC_EXPORT void RSProperty<Color>::UpdateToRender(const Color& value, PropertyUpdateType type) const; 686 template<> 687 RSC_EXPORT void RSProperty<Gravity>::UpdateToRender(const Gravity& value, PropertyUpdateType type) const; 688 template<> 689 RSC_EXPORT void RSProperty<Matrix3f>::UpdateToRender(const Matrix3f& value, PropertyUpdateType type) const; 690 template<> 691 RSC_EXPORT void RSProperty<Quaternion>::UpdateToRender(const Quaternion& value, PropertyUpdateType type) const; 692 template<> 693 RSC_EXPORT void RSProperty<std::shared_ptr<RSFilter>>::UpdateToRender( 694 const std::shared_ptr<RSFilter>& value, PropertyUpdateType type) const; 695 template<> 696 RSC_EXPORT void RSProperty<std::shared_ptr<RSImage>>::UpdateToRender( 697 const std::shared_ptr<RSImage>& value, PropertyUpdateType type) const; 698 template<> 699 RSC_EXPORT void RSProperty<std::shared_ptr<RSMask>>::UpdateToRender( 700 const std::shared_ptr<RSMask>& value, PropertyUpdateType type) const; 701 template<> 702 RSC_EXPORT void RSProperty<std::shared_ptr<RSPath>>::UpdateToRender( 703 const std::shared_ptr<RSPath>& value, PropertyUpdateType type) const; 704 template<> 705 RSC_EXPORT void RSProperty<std::shared_ptr<RSLinearGradientBlurPara>>::UpdateToRender( 706 const std::shared_ptr<RSLinearGradientBlurPara>& value, PropertyUpdateType type) const; 707 template<> 708 RSC_EXPORT void RSProperty<std::shared_ptr<RSShader>>::UpdateToRender( 709 const std::shared_ptr<RSShader>& value, PropertyUpdateType type) const; 710 template<> 711 RSC_EXPORT void RSProperty<Vector2f>::UpdateToRender(const Vector2f& value, PropertyUpdateType type) const; 712 template<> 713 RSC_EXPORT void RSProperty<Vector4<uint32_t>>::UpdateToRender( 714 const Vector4<uint32_t>& value, PropertyUpdateType type) const; 715 template<> 716 RSC_EXPORT void RSProperty<Vector4<Color>>::UpdateToRender( 717 const Vector4<Color>& value, PropertyUpdateType type) const; 718 template<> 719 RSC_EXPORT void RSProperty<Vector4f>::UpdateToRender(const Vector4f& value, PropertyUpdateType type) const; 720 template<> 721 RSC_EXPORT void RSProperty<RRect>::UpdateToRender(const RRect& value, PropertyUpdateType type) const; 722 723 template<> 724 RSC_EXPORT bool RSProperty<float>::IsValid(const float& value); 725 template<> 726 RSC_EXPORT bool RSProperty<Vector2f>::IsValid(const Vector2f& value); 727 template<> 728 RSC_EXPORT bool RSProperty<Vector4f>::IsValid(const Vector4f& value); 729 730 template<> 731 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<float>::GetPropertyType() const; 732 template<> 733 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Color>::GetPropertyType() const; 734 template<> 735 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Matrix3f>::GetPropertyType() const; 736 template<> 737 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Vector2f>::GetPropertyType() const; 738 template<> 739 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Vector4f>::GetPropertyType() const; 740 template<> 741 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Quaternion>::GetPropertyType() const; 742 template<> 743 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<std::shared_ptr<RSFilter>>::GetPropertyType() const; 744 template<> 745 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Vector4<Color>>::GetPropertyType() const; 746 template<> 747 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<RRect>::GetPropertyType() const; 748 } // namespace Rosen 749 } // namespace OHOS 750 751 #endif // RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_PROPERTY_H 752