|
1 |
|
2 /* |
|
3 * Copyright 2006 The Android Open Source Project |
|
4 * |
|
5 * Use of this source code is governed by a BSD-style license that can be |
|
6 * found in the LICENSE file. |
|
7 */ |
|
8 |
|
9 |
|
10 #include "SkOperandInterpolator.h" |
|
11 #include "SkScript.h" |
|
12 |
|
13 SkOperandInterpolator::SkOperandInterpolator() { |
|
14 INHERITED::reset(0, 0); |
|
15 fType = SkType_Unknown; |
|
16 } |
|
17 |
|
18 SkOperandInterpolator::SkOperandInterpolator(int elemCount, int frameCount, |
|
19 SkDisplayTypes type) |
|
20 { |
|
21 this->reset(elemCount, frameCount, type); |
|
22 } |
|
23 |
|
24 void SkOperandInterpolator::reset(int elemCount, int frameCount, SkDisplayTypes type) |
|
25 { |
|
26 // SkASSERT(type == SkType_String || type == SkType_Float || type == SkType_Int || |
|
27 // type == SkType_Displayable || type == SkType_Drawable); |
|
28 INHERITED::reset(elemCount, frameCount); |
|
29 fType = type; |
|
30 fStorage = sk_malloc_throw((sizeof(SkOperand) * elemCount + sizeof(SkTimeCode)) * frameCount); |
|
31 fTimes = (SkTimeCode*) fStorage; |
|
32 fValues = (SkOperand*) ((char*) fStorage + sizeof(SkTimeCode) * frameCount); |
|
33 #ifdef SK_DEBUG |
|
34 fTimesArray = (SkTimeCode(*)[10]) fTimes; |
|
35 fValuesArray = (SkOperand(*)[10]) fValues; |
|
36 #endif |
|
37 } |
|
38 |
|
39 bool SkOperandInterpolator::setKeyFrame(int index, SkMSec time, const SkOperand values[], SkScalar blend) |
|
40 { |
|
41 SkASSERT(values != NULL); |
|
42 blend = SkScalarPin(blend, 0, SK_Scalar1); |
|
43 |
|
44 bool success = ~index == SkTSearch<SkMSec>(&fTimes->fTime, index, time, sizeof(SkTimeCode)); |
|
45 SkASSERT(success); |
|
46 if (success) { |
|
47 SkTimeCode* timeCode = &fTimes[index]; |
|
48 timeCode->fTime = time; |
|
49 timeCode->fBlend[0] = SK_Scalar1 - blend; |
|
50 timeCode->fBlend[1] = 0; |
|
51 timeCode->fBlend[2] = 0; |
|
52 timeCode->fBlend[3] = SK_Scalar1 - blend; |
|
53 SkOperand* dst = &fValues[fElemCount * index]; |
|
54 memcpy(dst, values, fElemCount * sizeof(SkOperand)); |
|
55 } |
|
56 return success; |
|
57 } |
|
58 |
|
59 SkInterpolatorBase::Result SkOperandInterpolator::timeToValues(SkMSec time, SkOperand values[]) const |
|
60 { |
|
61 SkScalar T; |
|
62 int index; |
|
63 SkBool exact; |
|
64 Result result = timeToT(time, &T, &index, &exact); |
|
65 if (values) |
|
66 { |
|
67 const SkOperand* nextSrc = &fValues[index * fElemCount]; |
|
68 |
|
69 if (exact) |
|
70 memcpy(values, nextSrc, fElemCount * sizeof(SkScalar)); |
|
71 else |
|
72 { |
|
73 SkASSERT(index > 0); |
|
74 |
|
75 const SkOperand* prevSrc = nextSrc - fElemCount; |
|
76 |
|
77 if (fType == SkType_Float || fType == SkType_3D_Point) { |
|
78 for (int i = fElemCount - 1; i >= 0; --i) |
|
79 values[i].fScalar = SkScalarInterp(prevSrc[i].fScalar, nextSrc[i].fScalar, T); |
|
80 } else if (fType == SkType_Int || fType == SkType_MSec) { |
|
81 for (int i = fElemCount - 1; i >= 0; --i) { |
|
82 int32_t a = prevSrc[i].fS32; |
|
83 int32_t b = nextSrc[i].fS32; |
|
84 values[i].fS32 = a + SkScalarRoundToInt((b - a) * T); |
|
85 } |
|
86 } else |
|
87 memcpy(values, prevSrc, sizeof(SkOperand) * fElemCount); |
|
88 } |
|
89 } |
|
90 return result; |
|
91 } |
|
92 |
|
93 /////////////////////////////////////////////////////////////////////////////////////// |
|
94 /////////////////////////////////////////////////////////////////////////////////////// |
|
95 |
|
96 #ifdef SK_DEBUG |
|
97 |
|
98 #ifdef SK_SUPPORT_UNITTEST |
|
99 static SkOperand* iset(SkOperand array[3], int a, int b, int c) |
|
100 { |
|
101 array[0].fScalar = SkIntToScalar(a); |
|
102 array[1].fScalar = SkIntToScalar(b); |
|
103 array[2].fScalar = SkIntToScalar(c); |
|
104 return array; |
|
105 } |
|
106 #endif |
|
107 |
|
108 void SkOperandInterpolator::UnitTest() |
|
109 { |
|
110 #ifdef SK_SUPPORT_UNITTEST |
|
111 SkOperandInterpolator inter(3, 2, SkType_Float); |
|
112 SkOperand v1[3], v2[3], v[3], vv[3]; |
|
113 Result result; |
|
114 |
|
115 inter.setKeyFrame(0, 100, iset(v1, 10, 20, 30), 0); |
|
116 inter.setKeyFrame(1, 200, iset(v2, 110, 220, 330)); |
|
117 |
|
118 result = inter.timeToValues(0, v); |
|
119 SkASSERT(result == kFreezeStart_Result); |
|
120 SkASSERT(memcmp(v, v1, sizeof(v)) == 0); |
|
121 |
|
122 result = inter.timeToValues(99, v); |
|
123 SkASSERT(result == kFreezeStart_Result); |
|
124 SkASSERT(memcmp(v, v1, sizeof(v)) == 0); |
|
125 |
|
126 result = inter.timeToValues(100, v); |
|
127 SkASSERT(result == kNormal_Result); |
|
128 SkASSERT(memcmp(v, v1, sizeof(v)) == 0); |
|
129 |
|
130 result = inter.timeToValues(200, v); |
|
131 SkASSERT(result == kNormal_Result); |
|
132 SkASSERT(memcmp(v, v2, sizeof(v)) == 0); |
|
133 |
|
134 result = inter.timeToValues(201, v); |
|
135 SkASSERT(result == kFreezeEnd_Result); |
|
136 SkASSERT(memcmp(v, v2, sizeof(v)) == 0); |
|
137 |
|
138 result = inter.timeToValues(150, v); |
|
139 SkASSERT(result == kNormal_Result); |
|
140 SkASSERT(memcmp(v, iset(vv, 60, 120, 180), sizeof(v)) == 0); |
|
141 |
|
142 result = inter.timeToValues(125, v); |
|
143 SkASSERT(result == kNormal_Result); |
|
144 result = inter.timeToValues(175, v); |
|
145 SkASSERT(result == kNormal_Result); |
|
146 #endif |
|
147 } |
|
148 |
|
149 #endif |