xref: /aosp_15_r20/frameworks/base/libs/hwui/PropertyValuesHolder.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker #include "PropertyValuesHolder.h"
18*d57664e9SAndroid Build Coastguard Worker 
19*d57664e9SAndroid Build Coastguard Worker #include "utils/Color.h"
20*d57664e9SAndroid Build Coastguard Worker #include "utils/VectorDrawableUtils.h"
21*d57664e9SAndroid Build Coastguard Worker 
22*d57664e9SAndroid Build Coastguard Worker #include <utils/Log.h>
23*d57664e9SAndroid Build Coastguard Worker 
24*d57664e9SAndroid Build Coastguard Worker namespace android {
25*d57664e9SAndroid Build Coastguard Worker namespace uirenderer {
26*d57664e9SAndroid Build Coastguard Worker 
27*d57664e9SAndroid Build Coastguard Worker using namespace VectorDrawable;
28*d57664e9SAndroid Build Coastguard Worker 
lerp(float fromValue,float toValue,float fraction)29*d57664e9SAndroid Build Coastguard Worker inline constexpr float lerp(float fromValue, float toValue, float fraction) {
30*d57664e9SAndroid Build Coastguard Worker     return float(fromValue * (1 - fraction) + toValue * fraction);
31*d57664e9SAndroid Build Coastguard Worker }
32*d57664e9SAndroid Build Coastguard Worker 
linearize(U8CPU component)33*d57664e9SAndroid Build Coastguard Worker inline constexpr float linearize(U8CPU component) {
34*d57664e9SAndroid Build Coastguard Worker     return EOCF_sRGB(component / 255.0f);
35*d57664e9SAndroid Build Coastguard Worker }
36*d57664e9SAndroid Build Coastguard Worker 
37*d57664e9SAndroid Build Coastguard Worker // TODO: Add a test for this
evaluate(SkColor * outColor,const SkColor & fromColor,const SkColor & toColor,float fraction) const38*d57664e9SAndroid Build Coastguard Worker void ColorEvaluator::evaluate(SkColor* outColor, const SkColor& fromColor, const SkColor& toColor,
39*d57664e9SAndroid Build Coastguard Worker                               float fraction) const {
40*d57664e9SAndroid Build Coastguard Worker     float a = lerp(SkColorGetA(fromColor) / 255.0f, SkColorGetA(toColor) / 255.0f, fraction);
41*d57664e9SAndroid Build Coastguard Worker     float r = lerp(linearize(SkColorGetR(fromColor)), linearize(SkColorGetR(toColor)), fraction);
42*d57664e9SAndroid Build Coastguard Worker     float g = lerp(linearize(SkColorGetG(fromColor)), linearize(SkColorGetG(toColor)), fraction);
43*d57664e9SAndroid Build Coastguard Worker     float b = lerp(linearize(SkColorGetB(fromColor)), linearize(SkColorGetB(toColor)), fraction);
44*d57664e9SAndroid Build Coastguard Worker     *outColor = SkColorSetARGB((U8CPU)roundf(a * 255.0f), (U8CPU)roundf(OECF_sRGB(r) * 255.0f),
45*d57664e9SAndroid Build Coastguard Worker                                (U8CPU)roundf(OECF_sRGB(g) * 255.0f),
46*d57664e9SAndroid Build Coastguard Worker                                (U8CPU)roundf(OECF_sRGB(b) * 255.0f));
47*d57664e9SAndroid Build Coastguard Worker }
48*d57664e9SAndroid Build Coastguard Worker 
evaluate(PathData * out,const PathData & from,const PathData & to,float fraction) const49*d57664e9SAndroid Build Coastguard Worker void PathEvaluator::evaluate(PathData* out, const PathData& from, const PathData& to,
50*d57664e9SAndroid Build Coastguard Worker                              float fraction) const {
51*d57664e9SAndroid Build Coastguard Worker     VectorDrawableUtils::interpolatePaths(out, from, to, fraction);
52*d57664e9SAndroid Build Coastguard Worker }
53*d57664e9SAndroid Build Coastguard Worker 
54*d57664e9SAndroid Build Coastguard Worker template <typename T>
getValueFromData(float fraction) const55*d57664e9SAndroid Build Coastguard Worker const T PropertyValuesHolderImpl<T>::getValueFromData(float fraction) const {
56*d57664e9SAndroid Build Coastguard Worker     if (mDataSource.size() == 0) {
57*d57664e9SAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("No data source is defined");
58*d57664e9SAndroid Build Coastguard Worker         return 0;
59*d57664e9SAndroid Build Coastguard Worker     }
60*d57664e9SAndroid Build Coastguard Worker     if (fraction <= 0.0f) {
61*d57664e9SAndroid Build Coastguard Worker         return mDataSource.front();
62*d57664e9SAndroid Build Coastguard Worker     }
63*d57664e9SAndroid Build Coastguard Worker     if (fraction >= 1.0f) {
64*d57664e9SAndroid Build Coastguard Worker         return mDataSource.back();
65*d57664e9SAndroid Build Coastguard Worker     }
66*d57664e9SAndroid Build Coastguard Worker 
67*d57664e9SAndroid Build Coastguard Worker     fraction *= mDataSource.size() - 1;
68*d57664e9SAndroid Build Coastguard Worker     int lowIndex = floor(fraction);
69*d57664e9SAndroid Build Coastguard Worker     fraction -= lowIndex;
70*d57664e9SAndroid Build Coastguard Worker 
71*d57664e9SAndroid Build Coastguard Worker     T value;
72*d57664e9SAndroid Build Coastguard Worker     mEvaluator->evaluate(&value, mDataSource[lowIndex], mDataSource[lowIndex + 1], fraction);
73*d57664e9SAndroid Build Coastguard Worker     return value;
74*d57664e9SAndroid Build Coastguard Worker }
75*d57664e9SAndroid Build Coastguard Worker 
76*d57664e9SAndroid Build Coastguard Worker template <typename T>
calculateAnimatedValue(float fraction) const77*d57664e9SAndroid Build Coastguard Worker const T PropertyValuesHolderImpl<T>::calculateAnimatedValue(float fraction) const {
78*d57664e9SAndroid Build Coastguard Worker     if (mDataSource.size() > 0) {
79*d57664e9SAndroid Build Coastguard Worker         return getValueFromData(fraction);
80*d57664e9SAndroid Build Coastguard Worker     } else {
81*d57664e9SAndroid Build Coastguard Worker         T value;
82*d57664e9SAndroid Build Coastguard Worker         mEvaluator->evaluate(&value, mStartValue, mEndValue, fraction);
83*d57664e9SAndroid Build Coastguard Worker         return value;
84*d57664e9SAndroid Build Coastguard Worker     }
85*d57664e9SAndroid Build Coastguard Worker }
86*d57664e9SAndroid Build Coastguard Worker 
setFraction(float fraction)87*d57664e9SAndroid Build Coastguard Worker void GroupPropertyValuesHolder::setFraction(float fraction) {
88*d57664e9SAndroid Build Coastguard Worker     float animatedValue = calculateAnimatedValue(fraction);
89*d57664e9SAndroid Build Coastguard Worker     mGroup->mutateProperties()->setPropertyValue(mPropertyId, animatedValue);
90*d57664e9SAndroid Build Coastguard Worker }
91*d57664e9SAndroid Build Coastguard Worker 
setFraction(float fraction)92*d57664e9SAndroid Build Coastguard Worker void FullPathColorPropertyValuesHolder::setFraction(float fraction) {
93*d57664e9SAndroid Build Coastguard Worker     SkColor animatedValue = calculateAnimatedValue(fraction);
94*d57664e9SAndroid Build Coastguard Worker     mFullPath->mutateProperties()->setColorPropertyValue(mPropertyId, animatedValue);
95*d57664e9SAndroid Build Coastguard Worker }
96*d57664e9SAndroid Build Coastguard Worker 
setFraction(float fraction)97*d57664e9SAndroid Build Coastguard Worker void FullPathPropertyValuesHolder::setFraction(float fraction) {
98*d57664e9SAndroid Build Coastguard Worker     float animatedValue = calculateAnimatedValue(fraction);
99*d57664e9SAndroid Build Coastguard Worker     mFullPath->mutateProperties()->setPropertyValue(mPropertyId, animatedValue);
100*d57664e9SAndroid Build Coastguard Worker }
101*d57664e9SAndroid Build Coastguard Worker 
setFraction(float fraction)102*d57664e9SAndroid Build Coastguard Worker void PathDataPropertyValuesHolder::setFraction(float fraction) {
103*d57664e9SAndroid Build Coastguard Worker     mEvaluator->evaluate(&mPathData, mStartValue, mEndValue, fraction);
104*d57664e9SAndroid Build Coastguard Worker     mPath->mutateProperties()->setData(mPathData);
105*d57664e9SAndroid Build Coastguard Worker }
106*d57664e9SAndroid Build Coastguard Worker 
setFraction(float fraction)107*d57664e9SAndroid Build Coastguard Worker void RootAlphaPropertyValuesHolder::setFraction(float fraction) {
108*d57664e9SAndroid Build Coastguard Worker     float animatedValue = calculateAnimatedValue(fraction);
109*d57664e9SAndroid Build Coastguard Worker     mTree->mutateProperties()->setRootAlpha(animatedValue);
110*d57664e9SAndroid Build Coastguard Worker }
111*d57664e9SAndroid Build Coastguard Worker 
112*d57664e9SAndroid Build Coastguard Worker }  // namepace uirenderer
113*d57664e9SAndroid Build Coastguard Worker }  // namespace android
114