1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_BASE_PREDICTION_PREDICTION_METRICS_HANDLER_H_
#define UI_BASE_PREDICTION_PREDICTION_METRICS_HANDLER_H_
#include <deque>
#include <optional>
#include <string>
#include "base/component_export.h"
#include "base/memory/raw_ref.h"
#include "base/metrics/histogram_base.h"
#include "base/time/time.h"
#include "ui/gfx/geometry/point_f.h"
namespace ui {
namespace test {
class PredictionMetricsHandlerTest;
}
// Class used for evaluating input prediction.
// The basic idea is to buffer predicted and real events to be able to compare
// a predicted position to its corresponding interpolated real position with
// few metrics.
class COMPONENT_EXPORT(UI_BASE_PREDICTION) PredictionMetricsHandler {
public:
explicit PredictionMetricsHandler(std::string histogram_name);
~PredictionMetricsHandler();
// Struct used to store predicted and real event information.
struct EventData {
// Position of the event
gfx::PointF pos;
// Timestamp of the event
base::TimeTicks time_stamp;
// frame_time of the event
base::TimeTicks frame_time;
};
// Buffers a real event.
void AddRealEvent(const gfx::PointF& pos,
const base::TimeTicks& time_stamp,
const base::TimeTicks& frame_time,
bool scrolling = false);
// Buffers a predicted event.
void AddPredictedEvent(const gfx::PointF& pos,
const base::TimeTicks& time_stamp,
const base::TimeTicks& frame_time,
bool scrolling = false);
void EvaluatePrediction();
// Cleans all events buffers
void Reset();
private:
friend class test::PredictionMetricsHandlerTest;
// Computes necessary interpolations used for computing the metrics
void ComputeMetrics();
// Compute the OverUnderPredictionMetric score.
// The score is the amount of pixels the predicted point is ahead of
// the real point. If the score is positive, the prediction is OverPredicting,
// otherwise UnderPredicting.
double ComputeOverUnderPredictionMetric() const;
// The score is the amount of pixels the predicted point is ahead/behind of
// the real input curve. The curve point being an interpolation of the real
// input points at the `frame_time` from the current predicted point.
double ComputeFrameOverUnderPredictionMetric() const;
// Compute the PredictionJitterMetric score.
// The score is the euclidean distance between 2 successive variation of
// prediction and the corresponding real events at the same timestamp. It is
// an indicator of smoothness.
double ComputePredictionJitterMetric();
// Compute the VisualJitterMetric score.
// The score is the euclidean distance between 2 successive variation of
// prediction and the corresponding real events at frame time. It is
// an indicator of smoothness.
double ComputeVisualJitterMetric();
// Get the interpolated position from the real events at a given timestamp.
// Returns the index of the last real event which timestamp is smaller than
// the |interpolation_timestamp|. Returns -1 if not found.
int GetInterpolatedEventForPredictedEvent(
const base::TimeTicks& interpolation_timestamp,
gfx::PointF* interpolated);
// Queues used for buffering real and predicted events.
std::deque<EventData> events_queue_;
std::deque<EventData> predicted_events_queue_;
// Interpolated points of real events.
gfx::PointF interpolated_, frame_interpolated_;
gfx::PointF last_interpolated_, last_frame_interpolated_;
// Last predicted point that pop from predicted_event_queue_. Use for
// computing Jitter metrics.
std::optional<gfx::PointF> last_predicted_ = std::nullopt;
// The first real event position which time is later than the predicted time.
gfx::PointF next_real_;
// The first real event position which time is later than the frame time.
gfx::PointF next_real_point_after_frame_;
// Beginning of the full histogram name. It will have the various metrics'
// names (.OverPrediction, .UnderPrediction, .PredictionJitter, .VisualJitter)
// appended to it when counting the metric in a histogram.
const std::string histogram_name_;
// Histograms are never deleted we leak them at shutdown so it is fine to keep
// a reference here.
const raw_ref<base::HistogramBase> over_prediction_histogram_;
const raw_ref<base::HistogramBase> under_prediction_histogram_;
const raw_ref<base::HistogramBase> prediction_score_histogram_;
const raw_ref<base::HistogramBase> frame_over_prediction_histogram_;
const raw_ref<base::HistogramBase> frame_under_prediction_histogram_;
const raw_ref<base::HistogramBase> frame_prediction_score_histogram_;
const raw_ref<base::HistogramBase> prediction_jitter_histogram_;
const raw_ref<base::HistogramBase> visual_jitter_histogram_;
};
} // namespace ui
#endif // UI_BASE_PREDICTION_PREDICTION_METRICS_HANDLER_H_
|