Index: content/common/inter_process_time_ticks_converter.h |
diff --git a/content/common/inter_process_time_ticks_converter.h b/content/common/inter_process_time_ticks_converter.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..0377764e040dcfa6bbaa512d8aa70750875643c5 |
--- /dev/null |
+++ b/content/common/inter_process_time_ticks_converter.h |
@@ -0,0 +1,144 @@ |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef CONTENT_COMMON_INTER_PROCESS_TIME_TICKS_CONVERTER_H_ |
+#define CONTENT_COMMON_INTER_PROCESS_TIME_TICKS_CONVERTER_H_ |
+ |
+#include "base/time.h" |
+ |
+namespace content { |
+ |
+class LocalTimeDelta; |
+class LocalTimeTicks; |
+class RemoteTimeDelta; |
+class RemoteTimeTicks; |
+ |
+// On Windows, TimeTicks are not consistent between processes. Often, the values |
+// on one process have a static offset relative to another. Occasionally, these |
+// offsets shift while running. |
+// |
+// To combat this, any TimeTicks values sent from the remote process to the |
+// local process must be tweaked in order to appear monotonic. |
+// |
+// In order to properly tweak ticks, we need 4 reference points: |
+// |
+// - |local_lower_bound|: A known point, recorded on the local process, that |
+// occurs before any remote values that will be |
+// converted. |
+// - |remote_lower_bound|: The equivalent point on the remote process. This |
+// should be recorded immediately after |
+// |local_lower_bound|. |
+// - |local_upper_bound|: A known point, recorded on the local process, that |
+// occurs after any remote values that will be |
+// converted. |
+// - |remote_upper_bound|: The equivalent point on the remote process. This |
+// should be recorded immediately before |
+// |local_upper_bound|. |
+// |
+// Once these bounds are determined, values within the remote process's range |
+// can be converted to the local process's range. The values are converted as |
+// follows: |
+// |
+// 1. If the remote's range exceeds the local's range, it is scaled to fit. |
+// Any values converted will have the same scale factor applied. |
+// |
+// 2. The remote's range is shifted so that it is centered within the |
+// local's range. Any values converted will be shifted the same amount. |
+class InterProcessTimeTicksConverter { |
+ public: |
+ InterProcessTimeTicksConverter(const LocalTimeTicks& local_lower_bound, |
+ const LocalTimeTicks& local_upper_bound, |
+ const RemoteTimeTicks& remote_lower_bound, |
+ const RemoteTimeTicks& remote_upper_bound); |
+ |
+ // Returns the value within the local's bounds that correlates to |
+ // |remote_ms|. |
+ LocalTimeTicks ToLocalTimeTicks(const RemoteTimeTicks& remote_ms); |
+ |
+ // Returns the equivalent delta after applying remote-to-local scaling to |
+ // |remote_delta|. |
+ LocalTimeDelta ToLocalTimeDelta(const RemoteTimeDelta& remote_delta); |
+ |
+ private: |
+ int64 Convert(int64 value); |
+ |
+ int64 offset_; |
+ int64 numerator_; |
+ int64 denominator_; |
+ |
+ int64 remote_lower_bound_; |
+ int64 remote_upper_bound_; |
+}; |
+ |
+class LocalTimeDelta { |
+ public: |
+ int ToInt32() const { return value_; } |
+ |
+ private: |
+ friend class InterProcessTimeTicksConverter; |
+ friend class LocalTimeTicks; |
+ |
+ LocalTimeDelta(int value) : value_(value) {} |
+ |
+ int value_; |
+}; |
+ |
+class LocalTimeTicks { |
+ public: |
+ static LocalTimeTicks FromTimeTicks(const base::TimeTicks& value) { |
+ return LocalTimeTicks(value.ToInternalValue()); |
+ } |
+ |
+ base::TimeTicks ToTimeTicks() { |
+ return base::TimeTicks::FromInternalValue(value_); |
+ } |
+ |
+ LocalTimeTicks operator+(const LocalTimeDelta& delta) { |
+ return LocalTimeTicks(value_ + delta.value_); |
+ } |
+ |
+ private: |
+ friend class InterProcessTimeTicksConverter; |
+ |
+ LocalTimeTicks(int64 value) : value_(value) {} |
+ |
+ int64 value_; |
+}; |
+ |
+class RemoteTimeDelta { |
+ public: |
+ static RemoteTimeDelta FromRawDelta(int delta) { |
+ return RemoteTimeDelta(delta); |
+ } |
+ |
+ private: |
+ friend class InterProcessTimeTicksConverter; |
+ friend class RemoteTimeTicks; |
+ |
+ RemoteTimeDelta(int value) : value_(value) {} |
+ |
+ int value_; |
+}; |
+ |
+class RemoteTimeTicks { |
+ public: |
+ static RemoteTimeTicks FromTimeTicks(const base::TimeTicks& ticks) { |
+ return RemoteTimeTicks(ticks.ToInternalValue()); |
+ } |
+ |
+ RemoteTimeDelta operator-(const RemoteTimeTicks& rhs) const { |
+ return RemoteTimeDelta(value_ - rhs.value_); |
+ } |
+ |
+ private: |
+ friend class InterProcessTimeTicksConverter; |
+ |
+ RemoteTimeTicks(int64 value) : value_(value) {} |
+ |
+ int64 value_; |
+}; |
+ |
+} // namespace content |
+ |
+#endif // CONTENT_COMMON_INTER_PROCESS_TIME_TICKS_CONVERTER_H_ |