• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "core/event/resample_algo.h"
16 
17 namespace OHOS::Ace {
GetAvgPoint(const std::vector<PointerEvent> && events,bool isScreen)18 AvgPoint ResampleAlgo::GetAvgPoint(const std::vector<PointerEvent>&& events,
19     bool isScreen)
20 {
21     float avgX = 0.0f;
22     float avgY = 0.0f;
23     uint64_t avgTime = 0;
24     int32_t i = 0;
25     uint64_t lastTime = 0;
26     for (auto iter = events.begin(); iter != events.end(); iter++) {
27         if (lastTime == 0 || static_cast<uint64_t>(iter->time.time_since_epoch().count()) != lastTime) {
28             if (!isScreen) {
29                 avgX += iter->x;
30                 avgY += iter->y;
31             } else {
32                 avgX += iter->screenX;
33                 avgY += iter->screenY;
34             }
35             avgTime += static_cast<uint64_t>(iter->time.time_since_epoch().count());
36             i++;
37             lastTime = static_cast<uint64_t>(iter->time.time_since_epoch().count());
38         }
39     }
40     if (i > 0) {
41         avgX /= i;
42         avgY /= i;
43         avgTime /= static_cast<uint64_t>(i);
44     }
45     return {
46         avgX,
47         avgY,
48         avgTime,
49         0.0f,
50         0.0f
51     };
52 }
53 
LinearInterpolation(const AvgPoint & history,const AvgPoint & current,uint64_t nanoTimeStamp)54 ResamplePoint ResampleAlgo::LinearInterpolation(const AvgPoint& history, const AvgPoint& current,
55     uint64_t nanoTimeStamp)
56 {
57     if ((nanoTimeStamp == history.time || nanoTimeStamp == current.time) ||
58         (current.time <= history.time) ||
59         (current.time - history.time > INTERPOLATION_THRESHOLD) ||
60         (nanoTimeStamp < history.time)) {
61         return {};
62     }
63     auto inputXDeltaSlope = (current.x - history.x) * ONE_S_IN_NS /
64                         (float)(current.time - history.time);
65     auto inputYDeltaSlope = (current.y - history.y) * ONE_S_IN_NS /
66                         (float)(current.time - history.time);
67     if (nanoTimeStamp < current.time) {
68         float alpha = (float)(nanoTimeStamp - history.time) /
69                 (float)(current.time - history.time);
70         float x = history.x + alpha * (current.x - history.x);
71         float y = history.y + alpha * (current.y - history.y);
72         return {
73             x,
74             y,
75             inputXDeltaSlope,
76             inputYDeltaSlope
77         };
78     } else if (nanoTimeStamp > current.time) {
79         float alpha = (float)(nanoTimeStamp - current.time) /
80                 (float)(current.time - history.time);
81         float x = current.x + alpha * (current.x - history.x);
82         float y = current.y + alpha * (current.y - history.y);
83         return {
84             x,
85             y,
86             inputXDeltaSlope,
87             inputYDeltaSlope
88         };
89     }
90     return {};
91 }
92 
GetResampleCoord(const std::vector<PointerEvent> && history,const std::vector<PointerEvent> && current,uint64_t nanoTimeStamp,bool isScreen)93 ResamplePoint ResampleAlgo::GetResampleCoord(const std::vector<PointerEvent>&& history,
94     const std::vector<PointerEvent>&& current, uint64_t nanoTimeStamp,
95     bool isScreen)
96 {
97     if (history.empty() || current.empty()) {
98         return {};
99     }
100     uint64_t lastNanoTime = 0;
101     float x = 0.0f;
102     float y = 0.0f;
103     for (const auto& item : current) {
104         uint64_t currentNanoTime = static_cast<uint64_t>(item.time.time_since_epoch().count());
105         if (lastNanoTime < currentNanoTime) {
106             lastNanoTime = currentNanoTime;
107             x = item.x;
108             y = item.y;
109         }
110     }
111     if (nanoTimeStamp > RESAMPLE_COORD_TIME_THRESHOLD + lastNanoTime) {
112         return {
113             x,
114             y,
115             0.0f,
116             0.0f
117         };
118     }
119     auto historyPoint = GetAvgPoint(std::move(history), isScreen);
120     auto currentPoint = GetAvgPoint(std::move(current), isScreen);
121     return LinearInterpolation(historyPoint, currentPoint, nanoTimeStamp);
122 }
123 } // namespace OHOS::Ace