• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #include "animation/rs_animation_rate_decider.h"
17 
18 #include <cmath>
19 #include <string>
20 
21 #include "common/rs_optional_trace.h"
22 #include "modifier/rs_render_property.h"
23 
24 namespace OHOS {
25 namespace Rosen {
26 constexpr int32_t DEFAULT_PREFERRED_FPS = 120;
27 
SetScaleReferenceSize(float width,float height)28 void RSAnimationRateDecider::SetScaleReferenceSize(float width, float height)
29 {
30     scaleWidth_ = width;
31     scaleHeight_ = height;
32 }
33 
Reset()34 void RSAnimationRateDecider::Reset()
35 {
36     frameRateRange_.Reset();
37     decisionElements_.clear();
38 }
39 
AddDecisionElement(PropertyId id,const PropertyValue & velocity,FrameRateRange range)40 void RSAnimationRateDecider::AddDecisionElement(PropertyId id, const PropertyValue& velocity, FrameRateRange range)
41 {
42     if (!isEnabled_) {
43         return;
44     }
45     if (!velocity && !range.IsValid()) {
46         return;
47     }
48     PropertyValue data = nullptr;
49     if (velocity != nullptr) {
50         data = velocity->Clone();
51     }
52     if (decisionElements_.find(id) != decisionElements_.end()) {
53         auto& element = decisionElements_[id];
54         if (data != nullptr) {
55             element.first = element.first ? element.first + data : data;
56         }
57         element.second.Merge(range);
58     } else {
59         decisionElements_.emplace(id, std::make_pair(data, range));
60     }
61 }
62 
MakeDecision(const FrameRateGetFunc & func)63 void RSAnimationRateDecider::MakeDecision(const FrameRateGetFunc& func)
64 {
65     if (!isEnabled_) {
66         frameRateRange_.Set(0, RANGE_MAX_REFRESHRATE, DEFAULT_PREFERRED_FPS);
67         return;
68     }
69     for (const auto& [id, element] : decisionElements_) {
70         FrameRateRange propertyRange;
71         RS_OPTIONAL_TRACE_BEGIN("MakeDecision property id: [" + std::to_string(id) + "]");
72         if (element.first != nullptr && func != nullptr) {
73             int32_t preferred = CalculatePreferredRate(element.first, func);
74             if (preferred > 0) {
75                 propertyRange = {0, RANGE_MAX_REFRESHRATE, preferred};
76             }
77         }
78         FrameRateRange finalRange;
79         if (propertyRange.IsValid()) {
80             finalRange = propertyRange;
81             if (element.second.IsValid() && element.second.preferred_ < propertyRange.preferred_) {
82                 finalRange = element.second;
83             }
84         } else {
85             finalRange = element.second;
86         }
87         frameRateRange_.Merge(finalRange);
88         RS_OPTIONAL_TRACE_END();
89     }
90 }
91 
GetFrameRateRange() const92 const FrameRateRange& RSAnimationRateDecider::GetFrameRateRange() const
93 {
94     return frameRateRange_;
95 }
96 
CalculatePreferredRate(const PropertyValue & property,const FrameRateGetFunc & func)97 int32_t RSAnimationRateDecider::CalculatePreferredRate(const PropertyValue& property, const FrameRateGetFunc& func)
98 {
99     switch (property->GetPropertyType()) {
100         case RSRenderPropertyType::PROPERTY_VECTOR4F:
101             return ProcessVector4f(property, func);
102         case RSRenderPropertyType::PROPERTY_VECTOR2F:
103             return ProcessVector2f(property, func);
104         case RSRenderPropertyType::PROPERTY_FLOAT:
105             return func(property->GetPropertyUnit(), property->ToFloat());
106         default:
107             return 0;
108     }
109 }
110 
ProcessVector4f(const PropertyValue & property,const FrameRateGetFunc & func)111 int32_t RSAnimationRateDecider::ProcessVector4f(const PropertyValue& property, const FrameRateGetFunc& func)
112 {
113     auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(property);
114     auto propertyUnit = property->GetPropertyUnit();
115     if (!animatableProperty || propertyUnit != RSPropertyUnit::PIXEL_POSITION) {
116         return 0;
117     }
118     auto data = animatableProperty->Get();
119     // Vector4f data include data[0], data[1], data[2], data[3]
120     int32_t positionRate = func(propertyUnit, sqrt(data[0] * data[0] + data[1] * data[1]));
121     int32_t sizeRate = func(RSPropertyUnit::PIXEL_SIZE, sqrt(data[2] * data[2] + data[3] * data[3]));
122     return std::max(positionRate, sizeRate);
123 }
124 
ProcessVector2f(const PropertyValue & property,const FrameRateGetFunc & func)125 int32_t RSAnimationRateDecider::ProcessVector2f(const PropertyValue& property, const FrameRateGetFunc& func)
126 {
127     float velocity = 0.0f;
128     if (property->GetPropertyUnit() == RSPropertyUnit::RATIO_SCALE) {
129         auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<Vector2f>>(property);
130         if (animatableProperty != nullptr) {
131             auto data = animatableProperty->Get();
132             // Vector2f data include data[0], data[1]
133             float velocityX = data[0] * scaleWidth_;
134             float velocityY = data[1] * scaleHeight_;
135             velocity = sqrt(velocityX * velocityX + velocityY * velocityY);
136         }
137     } else {
138         velocity = property->ToFloat();
139     }
140     return func(property->GetPropertyUnit(), velocity);
141 }
142 } // namespace Rosen
143 } // namespace OHOS
144