blob: 7822ee286e94468c7217733d90d8f8f761d985ed [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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
reed@android.com8a1c16f2008-12-17 15:59:43 +00009
10#include "SkOperandInterpolator.h"
11#include "SkScript.h"
12
13SkOperandInterpolator::SkOperandInterpolator() {
14 INHERITED::reset(0, 0);
15 fType = SkType_Unknown;
16}
17
rmistry@google.comd6176b02012-08-23 18:14:13 +000018SkOperandInterpolator::SkOperandInterpolator(int elemCount, int frameCount,
reed@android.com8a1c16f2008-12-17 15:59:43 +000019 SkDisplayTypes type)
20{
21 this->reset(elemCount, frameCount, type);
22}
23
24void 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
39bool 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
59SkInterpolatorBase::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 + SkScalarRound((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
108void 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