Home | History | Annotate | Download | only in animator
      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(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 
     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, 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 
     67 SkInterpolatorBase::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 
    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 
    160