Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Side by Side Diff: ui/events/gesture_detection/velocity_tracker.cc

Issue 233433005: Remove static-initializeres from VelocityTracker (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: git cl format Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/events/gesture_detection/velocity_tracker.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/events/gesture_detection/velocity_tracker.h" 5 #include "ui/events/gesture_detection/velocity_tracker.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "ui/events/gesture_detection/motion_event.h" 10 #include "ui/events/gesture_detection/motion_event.h"
(...skipping 16 matching lines...) Expand all
27 virtual bool GetEstimator(uint32_t id, Estimator* out_estimator) const = 0; 27 virtual bool GetEstimator(uint32_t id, Estimator* out_estimator) const = 0;
28 28
29 protected: 29 protected:
30 VelocityTrackerStrategy() {} 30 VelocityTrackerStrategy() {}
31 }; 31 };
32 32
33 namespace { 33 namespace {
34 34
35 COMPILE_ASSERT(MotionEvent::MAX_POINTER_ID < 32, max_pointer_id_too_large); 35 COMPILE_ASSERT(MotionEvent::MAX_POINTER_ID < 32, max_pointer_id_too_large);
36 36
37 // Threshold for determining that a pointer has stopped moving.
38 // Some input devices do not send ACTION_MOVE events in the case where a pointer
39 // hasstopped. We need to detect this case so that we can accurately predict
tdresser 2014/04/14 18:22:21 Might as well fix hasstopped while you're here.
jdduke (slow) 2014/04/14 18:40:38 Done.
40 // the velocity after the pointer starts moving again.
41 const int kAssumePointerStoppedTimeMs = 40;
42
37 struct Position { 43 struct Position {
38 float x, y; 44 float x, y;
39 }; 45 };
40 46
41 struct Estimator { 47 struct Estimator {
42 enum { MAX_DEGREE = 4 }; 48 enum { MAX_DEGREE = 4 };
43 49
44 // Estimator time base. 50 // Estimator time base.
45 TimeTicks time; 51 TimeTicks time;
46 52
(...skipping 12 matching lines...) Expand all
59 time = TimeTicks(); 65 time = TimeTicks();
60 degree = 0; 66 degree = 0;
61 confidence = 0; 67 confidence = 0;
62 for (size_t i = 0; i <= MAX_DEGREE; i++) { 68 for (size_t i = 0; i <= MAX_DEGREE; i++) {
63 xcoeff[i] = 0; 69 xcoeff[i] = 0;
64 ycoeff[i] = 0; 70 ycoeff[i] = 0;
65 } 71 }
66 } 72 }
67 }; 73 };
68 74
69 // Threshold for determining that a pointer has stopped moving. 75 float VectorDot(const float* a, const float* b, uint32_t m) {
70 // Some input devices do not send ACTION_MOVE events in the case where a pointer
71 // hasstopped. We need to detect this case so that we can accurately predict
72 // the velocity after the pointer starts moving again.
73 const TimeDelta ASSUME_POINTER_STOPPED_TIME = TimeDelta::FromMilliseconds(40);
74
75 static float VectorDot(const float* a, const float* b, uint32_t m) {
76 float r = 0; 76 float r = 0;
77 while (m--) { 77 while (m--) {
78 r += *(a++) * *(b++); 78 r += *(a++) * *(b++);
79 } 79 }
80 return r; 80 return r;
81 } 81 }
82 82
83 static float VectorNorm(const float* a, uint32_t m) { 83 float VectorNorm(const float* a, uint32_t m) {
84 float r = 0; 84 float r = 0;
85 while (m--) { 85 while (m--) {
86 float t = *(a++); 86 float t = *(a++);
87 r += t * t; 87 r += t * t;
88 } 88 }
89 return sqrtf(r); 89 return sqrtf(r);
90 } 90 }
91 91
92 // Velocity tracker algorithm based on least-squares linear regression. 92 // Velocity tracker algorithm based on least-squares linear regression.
93 class LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy { 93 class LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy {
94 public: 94 public:
95 enum Weighting { 95 enum Weighting {
96 // No weights applied. All data points are equally reliable. 96 // No weights applied. All data points are equally reliable.
97 WEIGHTING_NONE, 97 WEIGHTING_NONE,
98 98
99 // Weight by time delta. Data points clustered together are weighted less. 99 // Weight by time delta. Data points clustered together are weighted less.
100 WEIGHTING_DELTA, 100 WEIGHTING_DELTA,
101 101
102 // Weight such that points within a certain horizon are weighed more than 102 // Weight such that points within a certain horizon are weighed more than
103 // those outside of that horizon. 103 // those outside of that horizon.
104 WEIGHTING_CENTRAL, 104 WEIGHTING_CENTRAL,
105 105
106 // Weight such that points older than a certain amount are weighed less. 106 // Weight such that points older than a certain amount are weighed less.
107 WEIGHTING_RECENT, 107 WEIGHTING_RECENT,
108 }; 108 };
109 109
110 // Number of samples to keep.
111 enum { HISTORY_SIZE = 20 };
112
113 // Degree must be no greater than Estimator::MAX_DEGREE. 110 // Degree must be no greater than Estimator::MAX_DEGREE.
114 LeastSquaresVelocityTrackerStrategy(uint32_t degree, 111 LeastSquaresVelocityTrackerStrategy(uint32_t degree,
115 Weighting weighting = WEIGHTING_NONE); 112 Weighting weighting = WEIGHTING_NONE);
116 virtual ~LeastSquaresVelocityTrackerStrategy(); 113 virtual ~LeastSquaresVelocityTrackerStrategy();
117 114
118 virtual void Clear() OVERRIDE; 115 virtual void Clear() OVERRIDE;
119 virtual void ClearPointers(BitSet32 id_bits) OVERRIDE; 116 virtual void ClearPointers(BitSet32 id_bits) OVERRIDE;
120 virtual void AddMovement(const TimeTicks& event_time, 117 virtual void AddMovement(const TimeTicks& event_time,
121 BitSet32 id_bits, 118 BitSet32 id_bits,
122 const Position* positions) OVERRIDE; 119 const Position* positions) OVERRIDE;
123 virtual bool GetEstimator(uint32_t id, 120 virtual bool GetEstimator(uint32_t id,
124 Estimator* out_estimator) const OVERRIDE; 121 Estimator* out_estimator) const OVERRIDE;
125 122
126 private: 123 private:
124 // Number of samples to keep.
125 enum { HISTORY_SIZE = 20 };
126
127 // Sample horizon. 127 // Sample horizon.
128 // We don't use too much history by default since we want to react to quick 128 // We don't use too much history by default since we want to react to quick
129 // changes in direction. 129 // changes in direction.
130 static const TimeDelta HORIZON; 130 enum { HORIZON_MS = 100 };
131 131
132 struct Movement { 132 struct Movement {
133 TimeTicks event_time; 133 TimeTicks event_time;
134 BitSet32 id_bits; 134 BitSet32 id_bits;
135 Position positions[VelocityTracker::MAX_POINTERS]; 135 Position positions[VelocityTracker::MAX_POINTERS];
136 136
137 inline const Position& GetPosition(uint32_t id) const { 137 inline const Position& GetPosition(uint32_t id) const {
138 return positions[id_bits.get_index_of_bit(id)]; 138 return positions[id_bits.get_index_of_bit(id)];
139 } 139 }
140 }; 140 };
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 strategy_->ClearPointers(id_bits); 248 strategy_->ClearPointers(id_bits);
249 } 249 }
250 250
251 void VelocityTracker::AddMovement(const TimeTicks& event_time, 251 void VelocityTracker::AddMovement(const TimeTicks& event_time,
252 BitSet32 id_bits, 252 BitSet32 id_bits,
253 const Position* positions) { 253 const Position* positions) {
254 while (id_bits.count() > MAX_POINTERS) 254 while (id_bits.count() > MAX_POINTERS)
255 id_bits.clear_last_marked_bit(); 255 id_bits.clear_last_marked_bit();
256 256
257 if ((current_pointer_id_bits_.value & id_bits.value) && 257 if ((current_pointer_id_bits_.value & id_bits.value) &&
258 event_time >= (last_event_time_ + ASSUME_POINTER_STOPPED_TIME)) { 258 event_time >= (last_event_time_ + base::TimeDelta::FromMilliseconds(
259 kAssumePointerStoppedTimeMs))) {
tdresser 2014/04/14 18:22:21 Is this indentation correct?
jdduke (slow) 2014/04/14 18:40:38 According to "git cl format", yes =/
259 // We have not received any movements for too long. Assume that all 260 // We have not received any movements for too long. Assume that all
260 // pointers 261 // pointers
261 // have stopped. 262 // have stopped.
262 strategy_->Clear(); 263 strategy_->Clear();
263 } 264 }
264 last_event_time_ = event_time; 265 last_event_time_ = event_time;
265 266
266 current_pointer_id_bits_ = id_bits; 267 current_pointer_id_bits_ = id_bits;
267 if (active_pointer_id_ < 0 || !id_bits.has_bit(active_pointer_id_)) 268 if (active_pointer_id_ < 0 || !id_bits.has_bit(active_pointer_id_))
268 active_pointer_id_ = id_bits.is_empty() ? -1 : id_bits.first_marked_bit(); 269 active_pointer_id_ = id_bits.is_empty() ? -1 : id_bits.first_marked_bit();
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 } 371 }
371 } 372 }
372 373
373 bool VelocityTracker::GetEstimator(uint32_t id, 374 bool VelocityTracker::GetEstimator(uint32_t id,
374 Estimator* out_estimator) const { 375 Estimator* out_estimator) const {
375 return strategy_->GetEstimator(id, out_estimator); 376 return strategy_->GetEstimator(id, out_estimator);
376 } 377 }
377 378
378 // --- LeastSquaresVelocityTrackerStrategy --- 379 // --- LeastSquaresVelocityTrackerStrategy ---
379 380
380 const TimeDelta LeastSquaresVelocityTrackerStrategy::HORIZON =
381 TimeDelta::FromMilliseconds(100);
382
383 LeastSquaresVelocityTrackerStrategy::LeastSquaresVelocityTrackerStrategy( 381 LeastSquaresVelocityTrackerStrategy::LeastSquaresVelocityTrackerStrategy(
384 uint32_t degree, 382 uint32_t degree,
385 Weighting weighting) 383 Weighting weighting)
386 : degree_(degree), weighting_(weighting) { 384 : degree_(degree), weighting_(weighting) {
387 DCHECK_LT(degree_, static_cast<uint32_t>(Estimator::MAX_DEGREE)); 385 DCHECK_LT(degree_, static_cast<uint32_t>(Estimator::MAX_DEGREE));
388 Clear(); 386 Clear();
389 } 387 }
390 388
391 LeastSquaresVelocityTrackerStrategy::~LeastSquaresVelocityTrackerStrategy() {} 389 LeastSquaresVelocityTrackerStrategy::~LeastSquaresVelocityTrackerStrategy() {}
392 390
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 Estimator* out_estimator) const { 559 Estimator* out_estimator) const {
562 out_estimator->Clear(); 560 out_estimator->Clear();
563 561
564 // Iterate over movement samples in reverse time order and collect samples. 562 // Iterate over movement samples in reverse time order and collect samples.
565 float x[HISTORY_SIZE]; 563 float x[HISTORY_SIZE];
566 float y[HISTORY_SIZE]; 564 float y[HISTORY_SIZE];
567 float w[HISTORY_SIZE]; 565 float w[HISTORY_SIZE];
568 float time[HISTORY_SIZE]; 566 float time[HISTORY_SIZE];
569 uint32_t m = 0; 567 uint32_t m = 0;
570 uint32_t index = index_; 568 uint32_t index = index_;
569 const base::TimeDelta horizon = base::TimeDelta::FromMilliseconds(HORIZON_MS);
571 const Movement& newest_movement = movements_[index_]; 570 const Movement& newest_movement = movements_[index_];
572 do { 571 do {
573 const Movement& movement = movements_[index]; 572 const Movement& movement = movements_[index];
574 if (!movement.id_bits.has_bit(id)) 573 if (!movement.id_bits.has_bit(id))
575 break; 574 break;
576 575
577 TimeDelta age = newest_movement.event_time - movement.event_time; 576 TimeDelta age = newest_movement.event_time - movement.event_time;
578 if (age > HORIZON) 577 if (age > horizon)
579 break; 578 break;
580 579
581 const Position& position = movement.GetPosition(id); 580 const Position& position = movement.GetPosition(id);
582 x[m] = position.x; 581 x[m] = position.x;
583 y[m] = position.y; 582 y[m] = position.y;
584 w[m] = ChooseWeight(index); 583 w[m] = ChooseWeight(index);
585 time[m] = -age.InSecondsF(); 584 time[m] = -age.InSecondsF();
586 index = (index == 0 ? HISTORY_SIZE : index) - 1; 585 index = (index == 0 ? HISTORY_SIZE : index) - 1;
587 } while (++m < HISTORY_SIZE); 586 } while (++m < HISTORY_SIZE);
588 587
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 out_estimator->degree = state.degree; 796 out_estimator->degree = state.degree;
798 out_estimator->xcoeff[0] = state.xpos; 797 out_estimator->xcoeff[0] = state.xpos;
799 out_estimator->xcoeff[1] = state.xvel; 798 out_estimator->xcoeff[1] = state.xvel;
800 out_estimator->xcoeff[2] = state.xaccel / 2; 799 out_estimator->xcoeff[2] = state.xaccel / 2;
801 out_estimator->ycoeff[0] = state.ypos; 800 out_estimator->ycoeff[0] = state.ypos;
802 out_estimator->ycoeff[1] = state.yvel; 801 out_estimator->ycoeff[1] = state.yvel;
803 out_estimator->ycoeff[2] = state.yaccel / 2; 802 out_estimator->ycoeff[2] = state.yaccel / 2;
804 } 803 }
805 804
806 } // namespace ui 805 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/gesture_detection/velocity_tracker.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698