hwui's own impl for interpolator
Bug: 184822190
Test: make
Change-Id: Ib041ad8207417ea5dfa09b50412234e5cf7daf80
diff --git a/libs/hwui/SkiaInterpolator.h b/libs/hwui/SkiaInterpolator.h
new file mode 100644
index 0000000..c03f502
--- /dev/null
+++ b/libs/hwui/SkiaInterpolator.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SkiaInterpolator_DEFINED
+#define SkiaInterpolator_DEFINED
+
+#include "include/private/SkTo.h"
+
+class SkiaInterpolatorBase {
+public:
+ enum Result { kNormal_Result, kFreezeStart_Result, kFreezeEnd_Result };
+
+protected:
+ SkiaInterpolatorBase();
+ ~SkiaInterpolatorBase();
+
+public:
+ void reset(int elemCount, int frameCount);
+
+ /** Return the start and end time for this interpolator.
+ If there are no key frames, return false.
+ @param startTime If not null, returns the time (in milliseconds) of the
+ first keyframe. If there are no keyframes, this param
+ is ignored (left unchanged).
+ @param endTime If not null, returns the time (in milliseconds) of the
+ last keyframe. If there are no keyframes, this parameter
+ is ignored (left unchanged).
+ @return True if there are key frames, or false if there are none.
+ */
+ bool getDuration(uint32_t* startTime, uint32_t* endTime) const;
+
+ /** Set the whether the repeat is mirrored.
+ @param mirror If true, the odd repeats interpolate from the last key
+ frame and the first.
+ */
+ void setMirror(bool mirror) { fFlags = SkToU8((fFlags & ~kMirror) | (int)mirror); }
+
+ /** Set the repeat count. The repeat count may be fractional.
+ @param repeatCount Multiplies the total time by this scalar.
+ */
+ void setRepeatCount(float repeatCount) { fRepeat = repeatCount; }
+
+ /** Set the whether the repeat is mirrored.
+ @param reset If true, the odd repeats interpolate from the last key
+ frame and the first.
+ */
+ void setReset(bool reset) { fFlags = SkToU8((fFlags & ~kReset) | (int)reset); }
+
+ Result timeToT(uint32_t time, float* T, int* index, bool* exact) const;
+
+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];
+ };
+ SkTimeCode* fTimes; // pointer into fStorage
+ void* fStorage;
+#ifdef SK_DEBUG
+ SkTimeCode (*fTimesArray)[10];
+#endif
+};
+
+class SkiaInterpolator : public SkiaInterpolatorBase {
+public:
+ SkiaInterpolator();
+ SkiaInterpolator(int elemCount, int frameCount);
+
+ void reset(int elemCount, int frameCount);
+
+ /** Add or replace a key frame, copying the values[] data into the
+ interpolator.
+ @param index The index of this frame (frames must be ordered by time)
+ @param time The millisecond time for this frame
+ @param values The array of values [elemCount] for this frame. The data
+ is copied into the interpolator.
+ @param blend A positive scalar specifying how to blend between this
+ and the next key frame. [0...1) is a cubic lag/log/lag
+ blend (slow to change at the beginning and end)
+ 1 is a linear blend (default)
+ */
+ bool setKeyFrame(int index, uint32_t time, const float values[],
+ const float blend[4] = nullptr);
+
+ /** Return the computed values given the specified time. Return whether
+ those values are the result of pinning to either the first
+ (kFreezeStart) or last (kFreezeEnd), or from interpolated the two
+ nearest key values (kNormal).
+ @param time The time to sample (in milliseconds)
+ @param (may be null) where to write the computed values.
+ */
+ Result timeToValues(uint32_t time, float values[] = nullptr) const;
+
+private:
+ float* fValues; // pointer into fStorage
+
+ using INHERITED = SkiaInterpolatorBase;
+};
+
+#endif