1 /*
2  * Copyright (c) 2021-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 #include "animation/rs_render_transition.h"
17 
18 #include "pipeline/rs_render_node.h"
19 #include "platform/common/rs_log.h"
20 #include "transaction/rs_marshalling_helper.h"
21 
22 namespace OHOS {
23 namespace Rosen {
RSRenderTransition(AnimationId id,const std::vector<std::shared_ptr<RSRenderTransitionEffect>> & effects,bool isTransitionIn)24 RSRenderTransition::RSRenderTransition(
25     AnimationId id, const std::vector<std::shared_ptr<RSRenderTransitionEffect>>& effects, bool isTransitionIn)
26     : RSRenderAnimation(id), effects_(effects), isTransitionIn_(isTransitionIn)
27 {}
28 
DumpAnimationType(std::string & out) const29 void RSRenderTransition::DumpAnimationType(std::string& out) const
30 {
31     out += "Type:RSRenderTransition";
32 }
33 
Marshalling(Parcel & parcel) const34 bool RSRenderTransition::Marshalling(Parcel& parcel) const
35 {
36     if (!RSRenderAnimation::Marshalling(parcel)) {
37         ROSEN_LOGE("RSRenderTransition::Marshalling, step1 failed");
38         return false;
39     }
40     if (!RSMarshallingHelper::Marshalling(parcel, effects_) ||
41         !RSMarshallingHelper::Marshalling(parcel, isTransitionIn_) || interpolator_ == nullptr ||
42         !interpolator_->Marshalling(parcel)) {
43         ROSEN_LOGE("RSRenderTransition::Marshalling, step2 failed");
44         return false;
45     }
46     return true;
47 }
48 
Unmarshalling(Parcel & parcel)49 RSRenderTransition* RSRenderTransition::Unmarshalling(Parcel& parcel)
50 {
51     RSRenderTransition* renderTransition = new RSRenderTransition();
52     if (!renderTransition->ParseParam(parcel)) {
53         ROSEN_LOGE("RSRenderTransition::Unmarshalling, ParseParam Failed");
54         delete renderTransition;
55         return nullptr;
56     }
57     return renderTransition;
58 }
59 
ParseParam(Parcel & parcel)60 bool RSRenderTransition::ParseParam(Parcel& parcel)
61 {
62     if (!RSRenderAnimation::ParseParam(parcel)) {
63         ROSEN_LOGE("RSRenderTransition::ParseParam, RenderAnimation failed");
64         return false;
65     }
66     if (!RSMarshallingHelper::Unmarshalling(parcel, effects_)) {
67         ROSEN_LOGE("RSRenderTransition::ParseParam, effect failed");
68         return false;
69     }
70     if (!RSMarshallingHelper::Unmarshalling(parcel, isTransitionIn_)) {
71         ROSEN_LOGE("RSRenderTransition::ParseParam, transition direction failed");
72         return false;
73     }
74     std::shared_ptr<RSInterpolator> interpolator(RSInterpolator::Unmarshalling(parcel));
75     if (interpolator == nullptr) {
76         ROSEN_LOGE("RSRenderTransition::ParseParam, interpolator is nullptr");
77         return false;
78     }
79     SetInterpolator(interpolator);
80     return true;
81 }
OnAnimate(float fraction)82 void RSRenderTransition::OnAnimate(float fraction)
83 {
84     float valueFraction = interpolator_->Interpolate(fraction);
85     if (isTransitionIn_) {
86         valueFraction = 1 - valueFraction;
87     }
88     for (auto& effect : effects_) {
89         effect->UpdateFraction(valueFraction);
90     }
91 }
92 
OnAttach()93 void RSRenderTransition::OnAttach()
94 {
95     auto target = GetTarget();
96     if (target == nullptr) {
97         ROSEN_LOGE("RSRenderTransition::OnAttach, target is nullptr");
98         return;
99     }
100     // create "transition" modifier and add it to target
101     for (auto& effect : effects_) {
102         const auto& modifier = effect->GetModifier();
103         if (modifier == nullptr) {
104             // custom effect may not have modifier
105             continue;
106         }
107         target->AddModifier(modifier);
108     }
109     // update number of disappearing transition animation
110     if (!isTransitionIn_) {
111         target->disappearingTransitionCount_++;
112         ROSEN_LOGD("RSRenderTransition::OnAttach, target have %{public}u disappearing Transitions",
113             target->disappearingTransitionCount_);
114     }
115 }
116 
OnDetach()117 void RSRenderTransition::OnDetach()
118 {
119     auto target = GetTarget();
120     if (target == nullptr) {
121         ROSEN_LOGE("RSRenderTransition::OnDetach, target is nullptr");
122         return;
123     }
124     // remove "transition" modifier from target
125     for (auto& effect : effects_) {
126         target->RemoveModifier(effect->GetModifier()->GetPropertyId());
127     }
128     // update number of disappearing transition animation
129     if (!isTransitionIn_) {
130         target->disappearingTransitionCount_--;
131         ROSEN_LOGD("RSRenderTransition::OnDetach, target have %{public}u disappearing Transitions",
132             target->disappearingTransitionCount_);
133         if (target->disappearingTransitionCount_ == 0) {
134             target->InternalRemoveSelfFromDisappearingChildren();
135         }
136     }
137 }
138 } // namespace Rosen
139 } // namespace OHOS
140