SkOperandIterpolator.cpp revision 0910916c0f7b951ee55c4b7c6358295b9bca0565
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 21SkOperandInterpolator::SkOperandInterpolator() { 22 INHERITED::reset(0, 0); 23 fType = SkType_Unknown; 24} 25 26SkOperandInterpolator::SkOperandInterpolator(int elemCount, int frameCount, 27 SkDisplayTypes type) 28{ 29 this->reset(elemCount, frameCount, type); 30} 31 32void 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 47bool 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 67SkInterpolatorBase::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 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 116void 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