• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* libs/graphics/animator/SkOperandIterpolator.cpp
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #include "SkOperandInterpolator.h"
19 #include "SkScript.h"
20 
SkOperandInterpolator()21 SkOperandInterpolator::SkOperandInterpolator() {
22     INHERITED::reset(0, 0);
23     fType = SkType_Unknown;
24 }
25 
SkOperandInterpolator(int elemCount,int frameCount,SkDisplayTypes type)26 SkOperandInterpolator::SkOperandInterpolator(int elemCount, int frameCount,
27                                              SkDisplayTypes type)
28 {
29     this->reset(elemCount, frameCount, type);
30 }
31 
reset(int elemCount,int frameCount,SkDisplayTypes type)32 void SkOperandInterpolator::reset(int elemCount, int frameCount, SkDisplayTypes type)
33 {
34 //  SkASSERT(type == SkType_String || type == SkType_Float || type == SkType_Int ||
35 //      type == SkType_Displayable || type == SkType_Drawable);
36     INHERITED::reset(elemCount, frameCount);
37     fType = type;
38     fStorage = sk_malloc_throw((sizeof(SkOperand) * elemCount + sizeof(SkTimeCode)) * frameCount);
39     fTimes = (SkTimeCode*) fStorage;
40     fValues = (SkOperand*) ((char*) fStorage + sizeof(SkTimeCode) * frameCount);
41 #ifdef SK_DEBUG
42     fTimesArray = (SkTimeCode(*)[10]) fTimes;
43     fValuesArray = (SkOperand(*)[10]) fValues;
44 #endif
45 }
46 
setKeyFrame(int index,SkMSec time,const SkOperand values[],SkScalar blend)47 bool SkOperandInterpolator::setKeyFrame(int index, SkMSec time, const SkOperand values[], SkScalar blend)
48 {
49     SkASSERT(values != NULL);
50     blend = SkScalarPin(blend, 0, SK_Scalar1);
51 
52     bool success = ~index == SkTSearch<SkMSec>(&fTimes->fTime, index, time, sizeof(SkTimeCode));
53     SkASSERT(success);
54     if (success) {
55         SkTimeCode* timeCode = &fTimes[index];
56         timeCode->fTime = time;
57         timeCode->fBlend[0] = SK_Scalar1 - blend;
58         timeCode->fBlend[1] = 0;
59         timeCode->fBlend[2] = 0;
60         timeCode->fBlend[3] = SK_Scalar1 - blend;
61         SkOperand* dst = &fValues[fElemCount * index];
62         memcpy(dst, values, fElemCount * sizeof(SkOperand));
63     }
64     return success;
65 }
66 
timeToValues(SkMSec time,SkOperand values[]) const67 SkInterpolatorBase::Result SkOperandInterpolator::timeToValues(SkMSec time, SkOperand values[]) const
68 {
69     SkScalar T;
70     int index;
71     SkBool exact;
72     Result result = timeToT(time, &T, &index, &exact);
73     if (values)
74     {
75         const SkOperand* nextSrc = &fValues[index * fElemCount];
76 
77         if (exact)
78             memcpy(values, nextSrc, fElemCount * sizeof(SkScalar));
79         else
80         {
81             SkASSERT(index > 0);
82 
83             const SkOperand* prevSrc = nextSrc - fElemCount;
84 
85             if (fType == SkType_Float || fType == SkType_3D_Point) {
86                 for (int i = fElemCount - 1; i >= 0; --i)
87                     values[i].fScalar = SkScalarInterp(prevSrc[i].fScalar, nextSrc[i].fScalar, T);
88             } else if (fType == SkType_Int || fType == SkType_MSec) {
89                 for (int i = fElemCount - 1; i >= 0; --i) {
90                     int32_t a = prevSrc[i].fS32;
91                     int32_t b = nextSrc[i].fS32;
92                     values[i].fS32 = a + SkScalarRound((b - a) * T);
93                 }
94             } else
95                 memcpy(values, prevSrc, sizeof(SkOperand) * fElemCount);
96         }
97     }
98     return result;
99 }
100 
101 ///////////////////////////////////////////////////////////////////////////////////////
102 ///////////////////////////////////////////////////////////////////////////////////////
103 
104 #ifdef SK_DEBUG
105 
106 #ifdef SK_SUPPORT_UNITTEST
iset(SkOperand array[3],int a,int b,int c)107     static SkOperand* iset(SkOperand array[3], int a, int b, int c)
108     {
109         array[0].fScalar = SkIntToScalar(a);
110         array[1].fScalar = SkIntToScalar(b);
111         array[2].fScalar = SkIntToScalar(c);
112         return array;
113     }
114 #endif
115 
UnitTest()116 void SkOperandInterpolator::UnitTest()
117 {
118 #ifdef SK_SUPPORT_UNITTEST
119     SkOperandInterpolator   inter(3, 2, SkType_Float);
120     SkOperand       v1[3], v2[3], v[3], vv[3];
121     Result          result;
122 
123     inter.setKeyFrame(0, 100, iset(v1, 10, 20, 30), 0);
124     inter.setKeyFrame(1, 200, iset(v2, 110, 220, 330));
125 
126     result = inter.timeToValues(0, v);
127     SkASSERT(result == kFreezeStart_Result);
128     SkASSERT(memcmp(v, v1, sizeof(v)) == 0);
129 
130     result = inter.timeToValues(99, v);
131     SkASSERT(result == kFreezeStart_Result);
132     SkASSERT(memcmp(v, v1, sizeof(v)) == 0);
133 
134     result = inter.timeToValues(100, v);
135     SkASSERT(result == kNormal_Result);
136     SkASSERT(memcmp(v, v1, sizeof(v)) == 0);
137 
138     result = inter.timeToValues(200, v);
139     SkASSERT(result == kNormal_Result);
140     SkASSERT(memcmp(v, v2, sizeof(v)) == 0);
141 
142     result = inter.timeToValues(201, v);
143     SkASSERT(result == kFreezeEnd_Result);
144     SkASSERT(memcmp(v, v2, sizeof(v)) == 0);
145 
146     result = inter.timeToValues(150, v);
147     SkASSERT(result == kNormal_Result);
148     SkASSERT(memcmp(v, iset(vv, 60, 120, 180), sizeof(v)) == 0);
149 
150     result = inter.timeToValues(125, v);
151     SkASSERT(result == kNormal_Result);
152     result = inter.timeToValues(175, v);
153     SkASSERT(result == kNormal_Result);
154 #endif
155 }
156 
157 #endif
158 
159 
160