OLD | NEW |
| (Empty) |
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 | |
21 SkOperandInterpolator::SkOperandInterpolator() { | |
22 INHERITED::reset(0, 0); | |
23 fType = SkType_Unknown; | |
24 } | |
25 | |
26 SkOperandInterpolator::SkOperandInterpolator(int elemCount, int frameCount, | |
27 SkDisplayTypes type) | |
28 { | |
29 this->reset(elemCount, frameCount, type); | |
30 } | |
31 | |
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(SkTimeCod
e)) * 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 | |
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, size
of(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 | |
67 SkInterpolatorBase::Result SkOperandInterpolator::timeToValues(SkMSec time, SkOp
erand 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, nextS
rc[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 | |
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 | |
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 | |
OLD | NEW |