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 + 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 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 150 151 152