blob: 62e6c1e33e40346cef1c30823f6de7442917f5c9 [file] [log] [blame]
Mike Reed74065272021-04-12 09:52:07 -04001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SkiaInterpolator_DEFINED
18#define SkiaInterpolator_DEFINED
19
Kevin Lubickd9ccdf62023-01-05 19:07:26 +000020#include <cstddef>
21#include <cstdint>
Mike Reed74065272021-04-12 09:52:07 -040022
23class SkiaInterpolatorBase {
24public:
25 enum Result { kNormal_Result, kFreezeStart_Result, kFreezeEnd_Result };
26
27protected:
28 SkiaInterpolatorBase();
29 ~SkiaInterpolatorBase();
30
31public:
32 void reset(int elemCount, int frameCount);
33
34 /** Return the start and end time for this interpolator.
35 If there are no key frames, return false.
36 @param startTime If not null, returns the time (in milliseconds) of the
37 first keyframe. If there are no keyframes, this param
38 is ignored (left unchanged).
39 @param endTime If not null, returns the time (in milliseconds) of the
40 last keyframe. If there are no keyframes, this parameter
41 is ignored (left unchanged).
42 @return True if there are key frames, or false if there are none.
43 */
44 bool getDuration(uint32_t* startTime, uint32_t* endTime) const;
45
46 /** Set the whether the repeat is mirrored.
47 @param mirror If true, the odd repeats interpolate from the last key
48 frame and the first.
49 */
Kevin Lubickd9ccdf62023-01-05 19:07:26 +000050 void setMirror(bool mirror) {
51 fFlags = static_cast<uint8_t>((fFlags & ~kMirror) | (int)mirror);
52 }
Mike Reed74065272021-04-12 09:52:07 -040053
54 /** Set the repeat count. The repeat count may be fractional.
55 @param repeatCount Multiplies the total time by this scalar.
56 */
57 void setRepeatCount(float repeatCount) { fRepeat = repeatCount; }
58
59 /** Set the whether the repeat is mirrored.
60 @param reset If true, the odd repeats interpolate from the last key
61 frame and the first.
62 */
Kevin Lubickd9ccdf62023-01-05 19:07:26 +000063 void setReset(bool reset) { fFlags = static_cast<uint8_t>((fFlags & ~kReset) | (int)reset); }
Mike Reed74065272021-04-12 09:52:07 -040064
65 Result timeToT(uint32_t time, float* T, int* index, bool* exact) const;
66
67protected:
68 enum Flags { kMirror = 1, kReset = 2, kHasBlend = 4 };
69 static float ComputeRelativeT(uint32_t time, uint32_t prevTime, uint32_t nextTime,
70 const float blend[4] = nullptr);
Mike Reed74065272021-04-12 09:52:07 -040071 struct SkTimeCode {
72 uint32_t fTime;
73 float fBlend[4];
74 };
Kevin Lubick963ce9f2023-02-17 12:51:14 +000075 static int binarySearch(const SkTimeCode* arr, int count, uint32_t target);
76
77 int16_t fFrameCount;
78 uint8_t fElemCount;
79 uint8_t fFlags;
80 float fRepeat;
Mike Reed74065272021-04-12 09:52:07 -040081 SkTimeCode* fTimes; // pointer into fStorage
82 void* fStorage;
Mike Reed74065272021-04-12 09:52:07 -040083};
84
85class SkiaInterpolator : public SkiaInterpolatorBase {
86public:
87 SkiaInterpolator();
88 SkiaInterpolator(int elemCount, int frameCount);
89
90 void reset(int elemCount, int frameCount);
91
92 /** Add or replace a key frame, copying the values[] data into the
93 interpolator.
94 @param index The index of this frame (frames must be ordered by time)
95 @param time The millisecond time for this frame
96 @param values The array of values [elemCount] for this frame. The data
97 is copied into the interpolator.
98 @param blend A positive scalar specifying how to blend between this
99 and the next key frame. [0...1) is a cubic lag/log/lag
100 blend (slow to change at the beginning and end)
101 1 is a linear blend (default)
102 */
103 bool setKeyFrame(int index, uint32_t time, const float values[],
104 const float blend[4] = nullptr);
105
106 /** Return the computed values given the specified time. Return whether
107 those values are the result of pinning to either the first
108 (kFreezeStart) or last (kFreezeEnd), or from interpolated the two
109 nearest key values (kNormal).
110 @param time The time to sample (in milliseconds)
111 @param (may be null) where to write the computed values.
112 */
113 Result timeToValues(uint32_t time, float values[] = nullptr) const;
114
115private:
116 float* fValues; // pointer into fStorage
117
118 using INHERITED = SkiaInterpolatorBase;
119};
120
121#endif