1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkOperandInterpolator.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkScript.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkOperandInterpolator::SkOperandInterpolator() { 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com INHERITED::reset(0, 0); 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fType = SkType_Unknown; 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comSkOperandInterpolator::SkOperandInterpolator(int elemCount, int frameCount, 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayTypes type) 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->reset(elemCount, frameCount, type); 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkOperandInterpolator::reset(int elemCount, int frameCount, SkDisplayTypes type) 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// SkASSERT(type == SkType_String || type == SkType_Float || type == SkType_Int || 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// type == SkType_Displayable || type == SkType_Drawable); 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com INHERITED::reset(elemCount, frameCount); 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fType = type; 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStorage = sk_malloc_throw((sizeof(SkOperand) * elemCount + sizeof(SkTimeCode)) * frameCount); 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTimes = (SkTimeCode*) fStorage; 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fValues = (SkOperand*) ((char*) fStorage + sizeof(SkTimeCode) * frameCount); 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTimesArray = (SkTimeCode(*)[10]) fTimes; 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fValuesArray = (SkOperand(*)[10]) fValues; 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkOperandInterpolator::setKeyFrame(int index, SkMSec time, const SkOperand values[], SkScalar blend) 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(values != NULL); 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com blend = SkScalarPin(blend, 0, SK_Scalar1); 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool success = ~index == SkTSearch<SkMSec>(&fTimes->fTime, index, time, sizeof(SkTimeCode)); 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(success); 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (success) { 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTimeCode* timeCode = &fTimes[index]; 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com timeCode->fTime = time; 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com timeCode->fBlend[0] = SK_Scalar1 - blend; 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com timeCode->fBlend[1] = 0; 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com timeCode->fBlend[2] = 0; 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com timeCode->fBlend[3] = SK_Scalar1 - blend; 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkOperand* dst = &fValues[fElemCount * index]; 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(dst, values, fElemCount * sizeof(SkOperand)); 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return success; 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkInterpolatorBase::Result SkOperandInterpolator::timeToValues(SkMSec time, SkOperand values[]) const 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar T; 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int index; 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool exact; 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Result result = timeToT(time, &T, &index, &exact); 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (values) 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkOperand* nextSrc = &fValues[index * fElemCount]; 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (exact) 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(values, nextSrc, fElemCount * sizeof(SkScalar)); 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com else 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(index > 0); 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkOperand* prevSrc = nextSrc - fElemCount; 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fType == SkType_Float || fType == SkType_3D_Point) { 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = fElemCount - 1; i >= 0; --i) 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com values[i].fScalar = SkScalarInterp(prevSrc[i].fScalar, nextSrc[i].fScalar, T); 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else if (fType == SkType_Int || fType == SkType_MSec) { 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = fElemCount - 1; i >= 0; --i) { 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32_t a = prevSrc[i].fS32; 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32_t b = nextSrc[i].fS32; 84e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com values[i].fS32 = a + SkScalarRoundToInt((b - a) * T); 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(values, prevSrc, sizeof(SkOperand) * fElemCount); 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return result; 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////////////// 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////////////// 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_SUPPORT_UNITTEST 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static SkOperand* iset(SkOperand array[3], int a, int b, int c) 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com array[0].fScalar = SkIntToScalar(a); 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com array[1].fScalar = SkIntToScalar(b); 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com array[2].fScalar = SkIntToScalar(c); 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return array; 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkOperandInterpolator::UnitTest() 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_SUPPORT_UNITTEST 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkOperandInterpolator inter(3, 2, SkType_Float); 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkOperand v1[3], v2[3], v[3], vv[3]; 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Result result; 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inter.setKeyFrame(0, 100, iset(v1, 10, 20, 30), 0); 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inter.setKeyFrame(1, 200, iset(v2, 110, 220, 330)); 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com result = inter.timeToValues(0, v); 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(result == kFreezeStart_Result); 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(memcmp(v, v1, sizeof(v)) == 0); 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com result = inter.timeToValues(99, v); 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(result == kFreezeStart_Result); 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(memcmp(v, v1, sizeof(v)) == 0); 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com result = inter.timeToValues(100, v); 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(result == kNormal_Result); 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(memcmp(v, v1, sizeof(v)) == 0); 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com result = inter.timeToValues(200, v); 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(result == kNormal_Result); 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(memcmp(v, v2, sizeof(v)) == 0); 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com result = inter.timeToValues(201, v); 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(result == kFreezeEnd_Result); 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(memcmp(v, v2, sizeof(v)) == 0); 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com result = inter.timeToValues(150, v); 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(result == kNormal_Result); 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(memcmp(v, iset(vv, 60, 120, 180), sizeof(v)) == 0); 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com result = inter.timeToValues(125, v); 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(result == kNormal_Result); 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com result = inter.timeToValues(175, v); 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(result == kNormal_Result); 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 150