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_implicit_animator.h" 23 #include "animation/rs_implicit_animator_map.h" 24 #include "animation/rs_motion_path_option.h" 25 #include "command/rs_node_showing_command.h" 26 #include "common/rs_color.h" 27 #include "common/rs_common_def.h" 28 #include "common/rs_macros.h" 29 #include "common/rs_vector2.h" 30 #include "common/rs_vector4.h" 31 #include "modifier/rs_animatable_arithmetic.h" 32 #include "modifier/rs_modifier_type.h" 33 #include "modifier/rs_render_property.h" 34 #include "pipeline/rs_node_map.h" 35 #include "property/rs_properties_def.h" 36 #include "render/rs_border.h" 37 #include "render/rs_filter.h" 38 #include "render/rs_image.h" 39 #include "render/rs_mask.h" 40 #include "render/rs_path.h" 41 #include "render/rs_shader.h" 42 #include "transaction/rs_transaction_proxy.h" 43 #include "ui/rs_node.h" 44 45 #ifdef _WIN32 46 #include <windows.h> 47 #define gettid GetCurrentThreadId 48 #endif 49 50 #ifdef __APPLE__ 51 #define gettid getpid 52 #endif 53 54 #ifdef __gnu_linux__ 55 #include <sys/types.h> 56 #include <sys/syscall.h> 57 #define gettid []() -> int32_t { return static_cast<int32_t>(syscall(SYS_gettid)); } 58 #endif 59 60 namespace OHOS { 61 namespace Rosen { 62 template<class...> 63 struct make_void { using type = void; }; 64 template<class... T> 65 using void_t = typename make_void<T...>::type; 66 67 template<class T, class = void> 68 struct supports_arithmetic : std::false_type {}; 69 template<class T> 70 struct supports_arithmetic<T, 71 void_t<decltype(std::declval<T>() == std::declval<T>())>> 72 : std::true_type {}; 73 74 template<class T, class = void> 75 struct supports_animatable_arithmetic : std::false_type {}; 76 template<class T> 77 struct supports_animatable_arithmetic<T, 78 void_t<decltype(std::declval<T>() + std::declval<T>()), 79 decltype(std::declval<T>() - std::declval<T>()), 80 decltype(std::declval<T>() * std::declval<float>()), 81 decltype(std::declval<T>() == std::declval<T>())>> 82 : std::true_type {}; 83 84 class RSC_EXPORT RSPropertyBase : public std::enable_shared_from_this<RSPropertyBase> { 85 public: 86 RSPropertyBase(); 87 virtual ~RSPropertyBase() = default; 88 89 PropertyId GetId() const 90 { 91 return id_; 92 } 93 94 protected: 95 virtual void SetIsCustom(bool isCustom) {} 96 97 virtual bool GetIsCustom() const 98 { 99 return false; 100 } 101 102 virtual void SetValue(const std::shared_ptr<RSPropertyBase>& value) {} 103 104 virtual std::shared_ptr<RSPropertyBase> Clone() const 105 { 106 return std::make_shared<RSPropertyBase>(); 107 } 108 109 virtual void SetMotionPathOption(const std::shared_ptr<RSMotionPathOption>& motionPathOption) {} 110 111 virtual RSRenderPropertyType GetPropertyType() const 112 { 113 return RSRenderPropertyType::INVALID; 114 } 115 116 virtual void UpdateOnAllAnimationFinish() {} 117 118 virtual void AddPathAnimation() {} 119 120 virtual void RemovePathAnimation() {} 121 122 virtual void UpdateShowingValue(const std::shared_ptr<const RSRenderPropertyBase>& property) {} 123 124 void AttachModifier(const std::shared_ptr<RSModifier>& modifier) 125 { 126 modifier_ = modifier; 127 } 128 129 void MarkModifierDirty(); 130 131 void UpdateExtendModifierForGeometry(const std::shared_ptr<RSNode>& node); 132 133 virtual std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() 134 { 135 return std::make_shared<RSRenderPropertyBase>(id_); 136 } 137 138 virtual bool GetShowingValueAndCancelAnimation() 139 { 140 return false; 141 } 142 143 PropertyId id_; 144 RSModifierType type_ { RSModifierType::INVALID }; 145 std::weak_ptr<RSNode> target_; 146 std::weak_ptr<RSModifier> modifier_; 147 148 private: 149 virtual std::shared_ptr<RSPropertyBase> Add(const std::shared_ptr<const RSPropertyBase>& value) 150 { 151 return shared_from_this(); 152 } 153 154 virtual std::shared_ptr<RSPropertyBase> Minus(const std::shared_ptr<const RSPropertyBase>& value) 155 { 156 return shared_from_this(); 157 } 158 159 virtual std::shared_ptr<RSPropertyBase> Multiply(const float scale) 160 { 161 return shared_from_this(); 162 } 163 164 virtual bool IsEqual(const std::shared_ptr<const RSPropertyBase>& value) const 165 { 166 return true; 167 } 168 169 friend std::shared_ptr<RSPropertyBase> operator+=( 170 const std::shared_ptr<RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 171 friend std::shared_ptr<RSPropertyBase> operator-=( 172 const std::shared_ptr<RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 173 friend std::shared_ptr<RSPropertyBase> operator*=(const std::shared_ptr<RSPropertyBase>& value, const float scale); 174 friend std::shared_ptr<RSPropertyBase> operator+( 175 const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 176 friend std::shared_ptr<RSPropertyBase> operator-( 177 const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 178 friend std::shared_ptr<RSPropertyBase> operator*( 179 const std::shared_ptr<const RSPropertyBase>& value, const float scale); 180 friend bool operator==( 181 const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 182 friend bool operator!=( 183 const std::shared_ptr<const RSPropertyBase>& a, const std::shared_ptr<const RSPropertyBase>& b); 184 friend class RSCurveAnimation; 185 friend class RSCustomTransitionEffect; 186 friend class RSExtendedModifier; 187 friend class RSGeometryTransModifier; 188 friend class RSImplicitAnimator; 189 friend class RSImplicitCurveAnimationParam; 190 friend class RSImplicitInterpolatingSpringAnimationParam; 191 friend class RSImplicitKeyframeAnimationParam; 192 friend class RSImplicitSpringAnimationParam; 193 friend class RSImplicitTransitionParam; 194 friend class RSModifier; 195 friend class RSPropertyAnimation; 196 friend class RSPathAnimation; 197 friend class RSKeyframeAnimation; 198 friend class RSSpringAnimation; 199 friend class RSInterpolatingSpringAnimation; 200 friend class RSTransition; 201 template<typename T1> 202 friend class RSAnimatableProperty; 203 template<uint16_t commandType, uint16_t commandSubType> 204 friend class RSGetShowingValueAndCancelAnimationTask; 205 }; 206 207 template<typename T> 208 class RSProperty : public RSPropertyBase { 209 static_assert(std::is_base_of_v<RSArithmetic<T>, T> || supports_arithmetic<T>::value); 210 211 public: 212 RSProperty() : RSPropertyBase() {} 213 explicit RSProperty(const T& value) : RSPropertyBase() 214 { 215 stagingValue_ = value; 216 } 217 virtual ~RSProperty() = default; 218 219 virtual void Set(const T& value) 220 { 221 if (ROSEN_EQ(value, stagingValue_) || !IsValid(value)) { 222 return; 223 } 224 225 stagingValue_ = value; 226 auto node = target_.lock(); 227 if (node == nullptr) { 228 return; 229 } 230 231 UpdateExtendModifierForGeometry(node); 232 if (isCustom_) { 233 MarkModifierDirty(); 234 } else { 235 UpdateToRender(stagingValue_, false); 236 } 237 } 238 239 virtual T Get() const 240 { 241 return stagingValue_; 242 } 243 244 protected: 245 void UpdateToRender(const T& value, bool isDelta, bool forceUpdate = false) const 246 {} 247 248 void SetValue(const std::shared_ptr<RSPropertyBase>& value) override 249 { 250 auto property = std::static_pointer_cast<RSProperty<T>>(value); 251 if (property != nullptr) { 252 stagingValue_ = property->stagingValue_; 253 } 254 } 255 256 std::shared_ptr<RSPropertyBase> Clone() const override 257 { 258 return std::make_shared<RSProperty<T>>(stagingValue_); 259 } 260 261 bool IsValid(const T& value) 262 { 263 return true; 264 } 265 266 void SetIsCustom(bool isCustom) override 267 { 268 isCustom_ = isCustom; 269 } 270 271 bool GetIsCustom() const override 272 { 273 return isCustom_; 274 } 275 276 std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() override 277 { 278 return std::make_shared<RSRenderProperty<T>>(stagingValue_, id_); 279 } 280 281 T stagingValue_ {}; 282 bool isCustom_ { false }; 283 284 friend class RSPathAnimation; 285 friend class RSImplicitAnimator; 286 friend class RSExtendedModifier; 287 friend class RSModifier; 288 }; 289 290 template<typename T> 291 class RSAnimatableProperty : public RSProperty<T> { 292 static_assert(std::is_integral_v<T> || std::is_floating_point_v<T> || std::is_same_v<Color, T> || 293 std::is_same_v<Matrix3f, T> || std::is_same_v<Vector2f, T> || std::is_same_v<Vector4f, T> || 294 std::is_same_v<Quaternion, T> || std::is_same_v<std::shared_ptr<RSFilter>, T> || 295 std::is_same_v<Vector4<Color>, T> || std::is_base_of_v<RSAnimatableArithmetic<T>, T> || 296 supports_animatable_arithmetic<T>::value || std::is_same_v<RRect, T>); 297 298 public: 299 RSAnimatableProperty() : RSProperty<T>() {} 300 explicit RSAnimatableProperty(const T& value) : RSProperty<T>(value) 301 { 302 showingValue_ = value; 303 } 304 305 virtual ~RSAnimatableProperty() = default; 306 307 void Set(const T& value) override 308 { 309 if (ROSEN_EQ(value, RSProperty<T>::stagingValue_) || !RSProperty<T>::IsValid(value)) { 310 return; 311 } 312 313 auto node = RSProperty<T>::target_.lock(); 314 if (node == nullptr) { 315 RSProperty<T>::stagingValue_ = value; 316 return; 317 } 318 319 RSProperty<T>::UpdateExtendModifierForGeometry(node); 320 auto implicitAnimator = RSImplicitAnimatorMap::Instance().GetAnimator(gettid()); 321 if (implicitAnimator && implicitAnimator->NeedImplicitAnimation()) { 322 auto startValue = std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_); 323 auto endValue = std::make_shared<RSAnimatableProperty<T>>(value); 324 if (motionPathOption_ != nullptr) { 325 implicitAnimator->BeginImplicitPathAnimation(motionPathOption_); 326 implicitAnimator->CreateImplicitAnimation( 327 node, RSProperty<T>::shared_from_this(), startValue, endValue); 328 implicitAnimator->EndImplicitPathAnimation(); 329 } else { 330 implicitAnimator->CreateImplicitAnimation( 331 node, RSProperty<T>::shared_from_this(), startValue, endValue); 332 } 333 return; 334 } 335 336 if (runningPathNum_ > 0) { 337 return; 338 } 339 340 bool hasPropertyAnimation = node->HasPropertyAnimation(RSProperty<T>::id_); 341 T sendValue = value; 342 if (hasPropertyAnimation) { 343 sendValue = value - RSProperty<T>::stagingValue_; 344 } 345 RSProperty<T>::stagingValue_ = value; 346 if (RSProperty<T>::isCustom_) { 347 UpdateExtendedAnimatableProperty(sendValue, hasPropertyAnimation); 348 } else { 349 RSProperty<T>::UpdateToRender(sendValue, hasPropertyAnimation); 350 } 351 } 352 353 T Get() const override 354 { 355 if (RSProperty<T>::isCustom_) { 356 return showingValue_; 357 } 358 return RSProperty<T>::stagingValue_; 359 } 360 361 T GetStagingValue() const 362 { 363 return RSProperty<T>::stagingValue_; 364 } 365 366 bool GetShowingValueAndCancelAnimation() override 367 { 368 auto node = RSProperty<T>::target_.lock(); 369 if (node == nullptr) { 370 return false; 371 } 372 if (!node->HasPropertyAnimation(this->id_) || this->GetIsCustom()) { 373 return true; 374 } 375 auto task = std::make_shared<RSNodeGetShowingPropertyAndCancelAnimation>(node->GetId(), GetRenderProperty()); 376 RSTransactionProxy::GetInstance()->ExecuteSynchronousTask(task, node->IsRenderServiceNode()); 377 if (!task || !task->GetResult()) { 378 return false; 379 } 380 auto renderProperty = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(task->GetProperty()); 381 if (!renderProperty) { 382 return false; 383 } 384 node->CancelAnimationByProperty(this->id_); 385 RSProperty<T>::stagingValue_ = renderProperty->Get(); 386 return true; 387 } 388 389 void SetUpdateCallback(const std::function<void(T)>& updateCallback) 390 { 391 propertyChangeListener_ = updateCallback; 392 } 393 394 protected: 395 void UpdateOnAllAnimationFinish() override 396 { 397 RSProperty<T>::UpdateToRender(RSProperty<T>::stagingValue_, false, true); 398 } 399 400 void UpdateExtendedAnimatableProperty(const T& value, bool isDelta) 401 { 402 if (isDelta) { 403 if (renderProperty_ != nullptr) { 404 renderProperty_->Set(renderProperty_->Get() + value); 405 } 406 } else { 407 showingValue_ = value; 408 RSProperty<T>::MarkModifierDirty(); 409 if (renderProperty_ != nullptr) { 410 renderProperty_->Set(value); 411 } else { 412 NotifyPropertyChange(); 413 } 414 } 415 } 416 417 void AddPathAnimation() override 418 { 419 runningPathNum_ += 1; 420 } 421 422 void RemovePathAnimation() override 423 { 424 runningPathNum_ -= 1; 425 } 426 427 void UpdateShowingValue(const std::shared_ptr<const RSRenderPropertyBase>& property) override 428 { 429 auto renderProperty = std::static_pointer_cast<const RSRenderProperty<T>>(property); 430 if (renderProperty != nullptr) { 431 showingValue_ = renderProperty->Get(); 432 NotifyPropertyChange(); 433 RSProperty<T>::MarkModifierDirty(); 434 } 435 } 436 437 void SetValue(const std::shared_ptr<RSPropertyBase>& value) override 438 { 439 auto property = std::static_pointer_cast<RSAnimatableProperty<T>>(value); 440 if (property != nullptr && property->GetPropertyType() == GetPropertyType()) { 441 RSProperty<T>::stagingValue_ = property->stagingValue_; 442 } 443 } 444 445 std::shared_ptr<RSPropertyBase> Clone() const override 446 { 447 return std::make_shared<RSAnimatableProperty<T>>(RSProperty<T>::stagingValue_); 448 } 449 450 void SetMotionPathOption(const std::shared_ptr<RSMotionPathOption>& motionPathOption) override 451 { 452 motionPathOption_ = motionPathOption; 453 } 454 455 std::shared_ptr<RSRenderPropertyBase> GetRenderProperty() override 456 { 457 if (!RSProperty<T>::isCustom_) { 458 return std::make_shared<RSRenderAnimatableProperty<T>>( 459 RSProperty<T>::stagingValue_, RSProperty<T>::id_, GetPropertyType()); 460 } 461 462 if (renderProperty_ == nullptr) { 463 renderProperty_ = std::make_shared<RSRenderAnimatableProperty<T>>( 464 RSProperty<T>::stagingValue_, RSProperty<T>::id_, GetPropertyType()); 465 auto weak = RSProperty<T>::weak_from_this(); 466 renderProperty_->SetUpdateUIPropertyFunc( 467 [weak](const std::shared_ptr<RSRenderPropertyBase>& renderProperty) { 468 auto property = weak.lock(); 469 if (property == nullptr) { 470 return; 471 } 472 property->UpdateShowingValue(renderProperty); 473 }); 474 } 475 return renderProperty_; 476 } 477 478 void NotifyPropertyChange() 479 { 480 if (propertyChangeListener_) { 481 propertyChangeListener_(showingValue_); 482 } 483 } 484 485 T showingValue_ {}; 486 std::shared_ptr<RSRenderAnimatableProperty<T>> renderProperty_; 487 int runningPathNum_ { 0 }; 488 std::shared_ptr<RSMotionPathOption> motionPathOption_ {}; 489 std::function<void(T)> propertyChangeListener_; 490 491 private: 492 RSRenderPropertyType GetPropertyType() const override 493 { 494 return RSRenderPropertyType::INVALID; 495 } 496 497 std::shared_ptr<RSPropertyBase> Add(const std::shared_ptr<const RSPropertyBase>& value) override 498 { 499 auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value); 500 if (animatableProperty != nullptr) { 501 RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ + animatableProperty->stagingValue_; 502 } 503 return RSProperty<T>::shared_from_this(); 504 } 505 506 std::shared_ptr<RSPropertyBase> Minus(const std::shared_ptr<const RSPropertyBase>& value) override 507 { 508 auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value); 509 if (animatableProperty != nullptr) { 510 RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ - animatableProperty->stagingValue_; 511 } 512 return RSProperty<T>::shared_from_this(); 513 } 514 515 std::shared_ptr<RSPropertyBase> Multiply(const float scale) override 516 { 517 RSProperty<T>::stagingValue_ = RSProperty<T>::stagingValue_ * scale; 518 return RSProperty<T>::shared_from_this(); 519 } 520 521 bool IsEqual(const std::shared_ptr<const RSPropertyBase>& value) const override 522 { 523 auto animatableProperty = std::static_pointer_cast<const RSAnimatableProperty<T>>(value); 524 if (animatableProperty != nullptr) { 525 return RSProperty<T>::stagingValue_ == animatableProperty->stagingValue_; 526 } 527 return true; 528 } 529 530 friend class RSPropertyAnimation; 531 friend class RSPathAnimation; 532 friend class RSExtendedModifier; 533 friend class RSModifier; 534 }; 535 536 template<> 537 RSC_EXPORT void RSProperty<bool>::UpdateToRender(const bool& value, bool isDelta, bool forceUpdate) const; 538 template<> 539 RSC_EXPORT void RSProperty<float>::UpdateToRender(const float& value, bool isDelta, bool forceUpdate) const; 540 template<> 541 RSC_EXPORT void RSProperty<int>::UpdateToRender(const int& value, bool isDelta, bool forceUpdate) const; 542 template<> 543 RSC_EXPORT void RSProperty<Color>::UpdateToRender(const Color& value, bool isDelta, bool forceUpdate) const; 544 template<> 545 RSC_EXPORT void RSProperty<Gravity>::UpdateToRender(const Gravity& value, bool isDelta, bool forceUpdate) const; 546 template<> 547 RSC_EXPORT void RSProperty<Matrix3f>::UpdateToRender(const Matrix3f& value, bool isDelta, bool forceUpdate) const; 548 template<> 549 RSC_EXPORT void RSProperty<Quaternion>::UpdateToRender(const Quaternion& value, bool isDelta, bool forceUpdate) const; 550 template<> 551 RSC_EXPORT void RSProperty<std::shared_ptr<RSFilter>>::UpdateToRender( 552 const std::shared_ptr<RSFilter>& value, bool isDelta, bool forceUpdate) const; 553 template<> 554 RSC_EXPORT void RSProperty<std::shared_ptr<RSImage>>::UpdateToRender( 555 const std::shared_ptr<RSImage>& value, bool isDelta, bool forceUpdate) const; 556 template<> 557 RSC_EXPORT void RSProperty<std::shared_ptr<RSMask>>::UpdateToRender( 558 const std::shared_ptr<RSMask>& value, bool isDelta, bool forceUpdate) const; 559 template<> 560 RSC_EXPORT void RSProperty<std::shared_ptr<RSPath>>::UpdateToRender( 561 const std::shared_ptr<RSPath>& value, bool isDelta, bool forceUpdate) const; 562 template<> 563 RSC_EXPORT void RSProperty<std::shared_ptr<RSLinearGradientBlurPara>>::UpdateToRender( 564 const std::shared_ptr<RSLinearGradientBlurPara>& value, bool isDelta, bool forceUpdate) const; 565 template<> 566 RSC_EXPORT void RSProperty<std::shared_ptr<RSShader>>::UpdateToRender( 567 const std::shared_ptr<RSShader>& value, bool isDelta, bool forceUpdate) const; 568 template<> 569 RSC_EXPORT void RSProperty<Vector2f>::UpdateToRender(const Vector2f& value, bool isDelta, bool forceUpdate) const; 570 template<> 571 RSC_EXPORT void RSProperty<Vector4<uint32_t>>::UpdateToRender( 572 const Vector4<uint32_t>& value, bool isDelta, bool forceUpdate) const; 573 template<> 574 RSC_EXPORT void RSProperty<Vector4<Color>>::UpdateToRender( 575 const Vector4<Color>& value, bool isDelta, bool forceUpdate) const; 576 template<> 577 RSC_EXPORT void RSProperty<Vector4f>::UpdateToRender(const Vector4f& value, bool isDelta, bool forceUpdate) const; 578 template<> 579 RSC_EXPORT void RSProperty<RRect>::UpdateToRender(const RRect& value, bool isDelta, bool forceUpdate) const; 580 581 template<> 582 RSC_EXPORT bool RSProperty<float>::IsValid(const float& value); 583 template<> 584 RSC_EXPORT bool RSProperty<Vector2f>::IsValid(const Vector2f& value); 585 template<> 586 RSC_EXPORT bool RSProperty<Vector4f>::IsValid(const Vector4f& value); 587 588 template<> 589 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<float>::GetPropertyType() const; 590 template<> 591 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Color>::GetPropertyType() const; 592 template<> 593 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Matrix3f>::GetPropertyType() const; 594 template<> 595 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Vector2f>::GetPropertyType() const; 596 template<> 597 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Vector4f>::GetPropertyType() const; 598 template<> 599 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Quaternion>::GetPropertyType() const; 600 template<> 601 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<std::shared_ptr<RSFilter>>::GetPropertyType() const; 602 template<> 603 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<Vector4<Color>>::GetPropertyType() const; 604 template<> 605 RSC_EXPORT RSRenderPropertyType RSAnimatableProperty<RRect>::GetPropertyType() const; 606 } // namespace Rosen 607 } // namespace OHOS 608 609 #endif // RENDER_SERVICE_CLIENT_CORE_MODIFIER_RS_PROPERTY_H 610