Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3f88f20 authored by Kevin Lubick's avatar Kevin Lubick Committed by Android (Google) Code Review
Browse files

Merge "Remove SkTSearch and SkFixed uses from SkiaInterpolator"

parents 991fc631 963ce9f0
Loading
Loading
Loading
Loading
+48 −23
Original line number Diff line number Diff line
@@ -18,9 +18,8 @@

#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "include/private/SkFixed.h"
#include "src/core/SkTSearch.h"

#include <cstdlib>
#include <log/log.h>

typedef int Dot14;
@@ -41,18 +40,18 @@ static inline Dot14 pin_and_convert(float x) {
    if (x <= 0) {
        return 0;
    }
    if (x >= SK_Scalar1) {
    if (x >= 1.0f) {
        return Dot14_ONE;
    }
    return SkScalarToFixed(x) >> 2;
    return static_cast<Dot14>(x * Dot14_ONE);
}

static float SkUnitCubicInterp(float value, float bx, float by, float cx, float cy) {
    // pin to the unit-square, and convert to 2.14
    Dot14 x = pin_and_convert(value);

    if (x == 0) return 0;
    if (x == Dot14_ONE) return SK_Scalar1;
    if (x == 0) return 0.0f;
    if (x == Dot14_ONE) return 1.0f;

    Dot14 b = pin_and_convert(bx);
    Dot14 c = pin_and_convert(cx);
@@ -84,7 +83,7 @@ static float SkUnitCubicInterp(float value, float bx, float by, float cx, float
    A = 3 * b;
    B = 3 * (c - 2 * b);
    C = 3 * (b - c) + Dot14_ONE;
    return SkFixedToScalar(eval_cubic(t, A, B, C) << 2);
    return Dot14ToFloat(eval_cubic(t, A, B, C));
}

///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -104,7 +103,7 @@ void SkiaInterpolatorBase::reset(int elemCount, int frameCount) {
    fFlags = 0;
    fElemCount = static_cast<uint8_t>(elemCount);
    fFrameCount = static_cast<int16_t>(frameCount);
    fRepeat = SK_Scalar1;
    fRepeat = 1.0f;
    if (fStorage) {
        free(fStorage);
        fStorage = nullptr;
@@ -136,17 +135,46 @@ bool SkiaInterpolatorBase::getDuration(SkMSec* startTime, SkMSec* endTime) const

float SkiaInterpolatorBase::ComputeRelativeT(SkMSec time, SkMSec prevTime, SkMSec nextTime,
                                             const float blend[4]) {
    SkASSERT(time > prevTime && time < nextTime);
    LOG_FATAL_IF(time < prevTime || time > nextTime);

    float t = (float)(time - prevTime) / (float)(nextTime - prevTime);
    return blend ? SkUnitCubicInterp(t, blend[0], blend[1], blend[2], blend[3]) : t;
}

// Returns the index of where the item is or the bit not of the index
// where the item should go in order to keep arr sorted in ascending order.
int SkiaInterpolatorBase::binarySearch(const SkTimeCode* arr, int count, SkMSec target) {
    if (count <= 0) {
        return ~0;
    }

    int lo = 0;
    int hi = count - 1;

    while (lo < hi) {
        int mid = (hi + lo) / 2;
        SkMSec elem = arr[mid].fTime;
        if (elem == target) {
            return mid;
        } else if (elem < target) {
            lo = mid + 1;
        } else {
            hi = mid;
        }
    }
    // Check to see if target is greater or less than where we stopped
    if (target < arr[lo].fTime) {
        return ~lo;
    }
    // e.g. it should go at the end.
    return ~(lo + 1);
}

SkiaInterpolatorBase::Result SkiaInterpolatorBase::timeToT(SkMSec time, float* T, int* indexPtr,
                                                           bool* exactPtr) const {
    SkASSERT(fFrameCount > 0);
    LOG_FATAL_IF(fFrameCount <= 0);
    Result result = kNormal_Result;
    if (fRepeat != SK_Scalar1) {
    if (fRepeat != 1.0f) {
        SkMSec startTime = 0, endTime = 0;  // initialize to avoid warning
        this->getDuration(&startTime, &endTime);
        SkMSec totalTime = endTime - startTime;
@@ -168,10 +196,8 @@ SkiaInterpolatorBase::Result SkiaInterpolatorBase::timeToT(SkMSec time, float* T
        time = offsetTime + startTime;
    }

    int index = SkTSearch<SkMSec>(&fTimes[0].fTime, fFrameCount, time, sizeof(SkTimeCode));

    int index = SkiaInterpolatorBase::binarySearch(fTimes, fFrameCount, time);
    bool exact = true;

    if (index < 0) {
        index = ~index;
        if (index == 0) {
@@ -184,10 +210,11 @@ SkiaInterpolatorBase::Result SkiaInterpolatorBase::timeToT(SkMSec time, float* T
            }
            result = kFreezeEnd_Result;
        } else {
            // Need to interpolate between two frames.
            exact = false;
        }
    }
    SkASSERT(index < fFrameCount);
    LOG_FATAL_IF(index >= fFrameCount);
    const SkTimeCode* nextTime = &fTimes[index];
    SkMSec nextT = nextTime[0].fTime;
    if (exact) {
@@ -207,7 +234,7 @@ SkiaInterpolator::SkiaInterpolator() {
}

SkiaInterpolator::SkiaInterpolator(int elemCount, int frameCount) {
    SkASSERT(elemCount > 0);
    LOG_FATAL_IF(elemCount <= 0);
    this->reset(elemCount, frameCount);
}

@@ -221,21 +248,19 @@ void SkiaInterpolator::reset(int elemCount, int frameCount) {
    fValues = (float*)((char*)fStorage + sizeof(SkTimeCode) * frameCount);
}

#define SK_Fixed1Third (SK_Fixed1 / 3)
#define SK_Fixed2Third (SK_Fixed1 * 2 / 3)

static const float gIdentityBlend[4] = {0.33333333f, 0.33333333f, 0.66666667f, 0.66666667f};

bool SkiaInterpolator::setKeyFrame(int index, SkMSec time, const float values[],
                                   const float blend[4]) {
    SkASSERT(values != nullptr);
    LOG_FATAL_IF(values == nullptr);

    if (blend == nullptr) {
        blend = gIdentityBlend;
    }

    bool success = ~index == SkTSearch<SkMSec>(&fTimes->fTime, index, time, sizeof(SkTimeCode));
    SkASSERT(success);
    // Verify the time should go after all the frames before index
    bool success = ~index == SkiaInterpolatorBase::binarySearch(fTimes, index, time);
    LOG_FATAL_IF(!success);
    if (success) {
        SkTimeCode* timeCode = &fTimes[index];
        timeCode->fTime = time;
@@ -257,7 +282,7 @@ SkiaInterpolator::Result SkiaInterpolator::timeToValues(SkMSec time, float value
        if (exact) {
            memcpy(values, nextSrc, fElemCount * sizeof(float));
        } else {
            SkASSERT(index > 0);
            LOG_FATAL_IF(index <= 0);

            const float* prevSrc = nextSrc - fElemCount;

+6 −4
Original line number Diff line number Diff line
@@ -68,14 +68,16 @@ protected:
    enum Flags { kMirror = 1, kReset = 2, kHasBlend = 4 };
    static float ComputeRelativeT(uint32_t time, uint32_t prevTime, uint32_t nextTime,
                                  const float blend[4] = nullptr);
    int16_t fFrameCount;
    uint8_t fElemCount;
    uint8_t fFlags;
    float fRepeat;
    struct SkTimeCode {
        uint32_t fTime;
        float fBlend[4];
    };
    static int binarySearch(const SkTimeCode* arr, int count, uint32_t target);

    int16_t fFrameCount;
    uint8_t fElemCount;
    uint8_t fFlags;
    float fRepeat;
    SkTimeCode* fTimes;  // pointer into fStorage
    void* fStorage;
};