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

Unified Diff: ui/gl/sync_control_vsync_provider.cc

Issue 2411803003: Route DXGI Frame Statistics to VSyncProvider (Closed)
Patch Set: Build error fix Created 4 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/gl/sync_control_vsync_provider.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gl/sync_control_vsync_provider.cc
diff --git a/ui/gl/sync_control_vsync_provider.cc b/ui/gl/sync_control_vsync_provider.cc
index f9dc5c56e47e7e0a0a64eacc06d6f960ab83ea8e..16029e27dc5e4fd33fa6774b4cc7e077ce7dd782 100644
--- a/ui/gl/sync_control_vsync_provider.cc
+++ b/ui/gl/sync_control_vsync_provider.cc
@@ -11,7 +11,7 @@
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_WIN)
// These constants define a reasonable range for a calculated refresh interval.
// Calculating refreshes out of this range will be considered a fatal error.
const int64_t kMinVsyncIntervalUs = base::Time::kMicrosecondsPerSecond / 400;
@@ -21,17 +21,17 @@ const int64_t kMaxVsyncIntervalUs = base::Time::kMicrosecondsPerSecond / 10;
// we think the latest computed interval is invalid (noisey due to
// monitor configuration change, moving a window between monitors, etc.).
const double kRelativeIntervalDifferenceThreshold = 0.05;
-#endif
+#endif // defined(OS_LINUX) || defined(OS_WIN)
namespace gl {
SyncControlVSyncProvider::SyncControlVSyncProvider() : gfx::VSyncProvider() {
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_WIN)
// On platforms where we can't get an accurate reading on the refresh
// rate we fall back to the assumption that we're displaying 60 frames
// per second.
last_good_interval_ = base::TimeDelta::FromSeconds(1) / 60;
-#endif
+#endif // defined(OS_LINUX) || defined(OS_WIN)
}
SyncControlVSyncProvider::~SyncControlVSyncProvider() {}
@@ -39,67 +39,18 @@ SyncControlVSyncProvider::~SyncControlVSyncProvider() {}
void SyncControlVSyncProvider::GetVSyncParameters(
const UpdateVSyncCallback& callback) {
TRACE_EVENT0("gpu", "SyncControlVSyncProvider::GetVSyncParameters");
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_WIN)
base::TimeTicks timebase;
- // The actual clock used for the system time returned by glXGetSyncValuesOML
- // is unspecified. In practice, the clock used is likely to be either
- // CLOCK_REALTIME or CLOCK_MONOTONIC, so we compare the returned time to the
- // current time according to both clocks, and assume that the returned time
- // was produced by the clock whose current time is closest to it, subject
- // to the restriction that the returned time must not be in the future
- // (since it is the time of a vblank that has already occurred).
int64_t system_time;
int64_t media_stream_counter;
int64_t swap_buffer_counter;
if (!GetSyncValues(&system_time, &media_stream_counter, &swap_buffer_counter))
return;
- // Both Intel and Mali drivers will return TRUE for GetSyncValues
- // but a value of 0 for MSC if they cannot access the CRTC data structure
- // associated with the surface. crbug.com/231945
- bool prev_invalid_msc = invalid_msc_;
- invalid_msc_ = (media_stream_counter == 0);
- if (invalid_msc_) {
- LOG_IF(ERROR, !prev_invalid_msc) << "glXGetSyncValuesOML "
- "should not return TRUE with a media stream counter of 0.";
- return;
- }
-
- struct timespec real_time;
- struct timespec monotonic_time;
- clock_gettime(CLOCK_REALTIME, &real_time);
- clock_gettime(CLOCK_MONOTONIC, &monotonic_time);
-
- int64_t real_time_in_microseconds =
- real_time.tv_sec * base::Time::kMicrosecondsPerSecond +
- real_time.tv_nsec / base::Time::kNanosecondsPerMicrosecond;
- int64_t monotonic_time_in_microseconds =
- monotonic_time.tv_sec * base::Time::kMicrosecondsPerSecond +
- monotonic_time.tv_nsec / base::Time::kNanosecondsPerMicrosecond;
-
- // We need the time according to CLOCK_MONOTONIC, so if we've been given
- // a time from CLOCK_REALTIME, we need to convert.
- bool time_conversion_needed =
- llabs(system_time - real_time_in_microseconds) <
- llabs(system_time - monotonic_time_in_microseconds);
-
- if (time_conversion_needed)
- system_time += monotonic_time_in_microseconds - real_time_in_microseconds;
-
- // Return if |system_time| is more than 1 frames in the future.
- int64_t interval_in_microseconds = last_good_interval_.InMicroseconds();
- if (system_time > monotonic_time_in_microseconds + interval_in_microseconds)
- return;
-
- // If |system_time| is slightly in the future, adjust it to the previous
- // frame and use the last frame counter to prevent issues in the callback.
- if (system_time > monotonic_time_in_microseconds) {
- system_time -= interval_in_microseconds;
- media_stream_counter--;
- }
- if (monotonic_time_in_microseconds - system_time >
- base::Time::kMicrosecondsPerSecond)
+ // Perform platform specific adjustment of |system_time| and
+ // |media_stream_counter|.
+ if (!AdjustSyncValues(&system_time, &media_stream_counter))
return;
timebase = base::TimeTicks::FromInternalValue(system_time);
@@ -155,7 +106,99 @@ void SyncControlVSyncProvider::GetVSyncParameters(
last_timebase_ = timebase;
last_media_stream_counter_ = media_stream_counter;
callback.Run(timebase, last_good_interval_);
+#endif // defined(OS_LINUX) || defined(OS_WIN)
+}
+
+#if defined(OS_LINUX)
+bool SyncControlVSyncProvider::AdjustSyncValues(int64_t* system_time,
+ int64_t* media_stream_counter) {
+ // The actual clock used for the system time returned by glXGetSyncValuesOML
+ // is unspecified. In practice, the clock used is likely to be either
+ // CLOCK_REALTIME or CLOCK_MONOTONIC, so we compare the returned time to the
+ // current time according to both clocks, and assume that the returned time
+ // was produced by the clock whose current time is closest to it, subject
+ // to the restriction that the returned time must not be in the future
+ // (since it is the time of a vblank that has already occurred).
+
+ // Both Intel and Mali drivers will return TRUE for GetSyncValues
+ // but a value of 0 for MSC if they cannot access the CRTC data structure
+ // associated with the surface. crbug.com/231945
+ bool prev_invalid_msc = invalid_msc_;
+ invalid_msc_ = (*media_stream_counter == 0);
+ if (invalid_msc_) {
+ LOG_IF(ERROR, !prev_invalid_msc)
+ << "glXGetSyncValuesOML "
+ "should not return TRUE with a media stream counter of 0.";
+ return false;
+ }
+
+ struct timespec real_time;
+ struct timespec monotonic_time;
+ clock_gettime(CLOCK_REALTIME, &real_time);
+ clock_gettime(CLOCK_MONOTONIC, &monotonic_time);
+
+ int64_t real_time_in_microseconds =
+ real_time.tv_sec * base::Time::kMicrosecondsPerSecond +
+ real_time.tv_nsec / base::Time::kNanosecondsPerMicrosecond;
+ int64_t monotonic_time_in_microseconds =
+ monotonic_time.tv_sec * base::Time::kMicrosecondsPerSecond +
+ monotonic_time.tv_nsec / base::Time::kNanosecondsPerMicrosecond;
+
+ // We need the time according to CLOCK_MONOTONIC, so if we've been given
+ // a time from CLOCK_REALTIME, we need to convert.
+ bool time_conversion_needed =
+ llabs(*system_time - real_time_in_microseconds) <
+ llabs(*system_time - monotonic_time_in_microseconds);
+
+ if (time_conversion_needed)
+ *system_time += monotonic_time_in_microseconds - real_time_in_microseconds;
+
+ // Return if |*system_time| is more than 1 frames in the future.
+ int64_t interval_in_microseconds = last_good_interval_.InMicroseconds();
+ if (*system_time > monotonic_time_in_microseconds + interval_in_microseconds)
+ return false;
+
+ // If |system_time| is slightly in the future, adjust it to the previous
+ // frame and use the last frame counter to prevent issues in the callback.
+ if (*system_time > monotonic_time_in_microseconds) {
+ *system_time -= interval_in_microseconds;
+ (*media_stream_counter)--;
+ }
+ if (monotonic_time_in_microseconds - *system_time >
+ base::Time::kMicrosecondsPerSecond)
+ return false;
+
+ return true;
+}
#endif // defined(OS_LINUX)
+
+#if defined(OS_WIN)
+bool SyncControlVSyncProvider::AdjustSyncValues(int64_t* system_time,
+ int64_t* media_stream_counter) {
+ // The actual clock used for the system time returned by glXGetSyncValuesEGL
+ // is unspecified. In practice, the clock comes from QueryPerformanceCounter.
+
+ LARGE_INTEGER perf_counter_now = {};
+ ::QueryPerformanceCounter(&perf_counter_now);
+ int64_t qpc_now =
+ base::TimeDelta::FromQPCValue(perf_counter_now.QuadPart).InMicroseconds();
+
+ // Return if |system_time| is more than 1 frames in the future.
+ int64_t interval_in_microseconds = last_good_interval_.InMicroseconds();
+ if (*system_time > qpc_now + interval_in_microseconds)
+ return false;
+
+ // If |system_time| is slightly in the future, adjust it to the previous
+ // frame and use the last frame counter to prevent issues in the callback.
+ if (*system_time > qpc_now) {
+ *system_time -= interval_in_microseconds;
+ (*media_stream_counter)--;
+ }
+ if (qpc_now - *system_time > base::Time::kMicrosecondsPerSecond)
+ return false;
+
+ return true;
}
+#endif // defined(OS_WIN)
} // namespace gl
« no previous file with comments | « ui/gl/sync_control_vsync_provider.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698