Commit 2a21fca5 authored by Jonathan Backer's avatar Jonathan Backer Committed by Commit Bot

Call GetVSyncParameters to minimize vsync_timebase_ skew

We often do not know the vsync_interval_ accurately, so call
GetVSyncParameters to minimize clock skew between predicted vblank and
actual vblank. This more accurate timebase gets plumbed up into
DisplayScheduler and will give us more time to draw a frame.

Change-Id: I30fe04eb36149c0cfb715a55dd523c8b5e20ecb6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1808151Reviewed-by: default avatarPeng Huang <penghuang@chromium.org>
Commit-Queue: Jonathan Backer <backer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#697993}
parent 486d0b09
...@@ -275,7 +275,6 @@ void GLSurfacePresentationHelper::CheckPendingFrames() { ...@@ -275,7 +275,6 @@ void GLSurfacePresentationHelper::CheckPendingFrames() {
return; return;
} }
bool need_update_vsync = false;
bool disjoint_occurred = bool disjoint_occurred =
gpu_timing_client_ && gpu_timing_client_->CheckAndResetTimerErrors(); gpu_timing_client_ && gpu_timing_client_->CheckAndResetTimerErrors();
if (disjoint_occurred || if (disjoint_occurred ||
...@@ -299,13 +298,6 @@ void GLSurfacePresentationHelper::CheckPendingFrames() { ...@@ -299,13 +298,6 @@ void GLSurfacePresentationHelper::CheckPendingFrames() {
std::move(frame.callback).Run(gfx::PresentationFeedback::Failure()); std::move(frame.callback).Run(gfx::PresentationFeedback::Failure());
} }
pending_frames_.clear(); pending_frames_.clear();
// We want to update VSync, if we can not get VSync parameters
// synchronously. Otherwise we will update the VSync parameters with the
// next SwapBuffers.
if (vsync_provider_ &&
!vsync_provider_->SupportGetVSyncParametersIfAvailable()) {
need_update_vsync = true;
}
} }
while (!pending_frames_.empty()) { while (!pending_frames_.empty()) {
...@@ -337,9 +329,8 @@ void GLSurfacePresentationHelper::CheckPendingFrames() { ...@@ -337,9 +329,8 @@ void GLSurfacePresentationHelper::CheckPendingFrames() {
gfx::PresentationFeedback(timestamp, interval, flags)); gfx::PresentationFeedback(timestamp, interval, flags));
} }
if (pending_frames_.empty() && !need_update_vsync) if (!pending_frames_.empty())
return; ScheduleCheckPendingFrames(true /* align_with_next_vsync */);
ScheduleCheckPendingFrames(true /* align_with_next_vsync */);
} }
void GLSurfacePresentationHelper::CheckPendingFramesCallback() { void GLSurfacePresentationHelper::CheckPendingFramesCallback() {
...@@ -349,21 +340,42 @@ void GLSurfacePresentationHelper::CheckPendingFramesCallback() { ...@@ -349,21 +340,42 @@ void GLSurfacePresentationHelper::CheckPendingFramesCallback() {
} }
void GLSurfacePresentationHelper::UpdateVSyncCallback( void GLSurfacePresentationHelper::UpdateVSyncCallback(
bool should_check_pending_frames,
const base::TimeTicks timebase, const base::TimeTicks timebase,
const base::TimeDelta interval) { const base::TimeDelta interval) {
DCHECK(check_pending_frame_scheduled_); DCHECK(update_vsync_pending_);
check_pending_frame_scheduled_ = false; update_vsync_pending_ = false;
vsync_timebase_ = timebase; vsync_timebase_ = timebase;
vsync_interval_ = interval; vsync_interval_ = interval;
CheckPendingFrames(); if (should_check_pending_frames) {
DCHECK(check_pending_frame_scheduled_);
check_pending_frame_scheduled_ = false;
CheckPendingFrames();
}
} }
void GLSurfacePresentationHelper::ScheduleCheckPendingFrames( void GLSurfacePresentationHelper::ScheduleCheckPendingFrames(
bool align_with_next_vsync) { bool align_with_next_vsync) {
// Always GetVSyncParameters to minimize clock-skew in vsync_timebase_.
bool vsync_provider_schedules_check = false;
if (vsync_provider_ &&
!vsync_provider_->SupportGetVSyncParametersIfAvailable() &&
!update_vsync_pending_) {
update_vsync_pending_ = true;
vsync_provider_schedules_check =
!check_pending_frame_scheduled_ && !align_with_next_vsync;
vsync_provider_->GetVSyncParameters(base::BindOnce(
&GLSurfacePresentationHelper::UpdateVSyncCallback,
weak_ptr_factory_.GetWeakPtr(), vsync_provider_schedules_check));
}
if (check_pending_frame_scheduled_) if (check_pending_frame_scheduled_)
return; return;
check_pending_frame_scheduled_ = true; check_pending_frame_scheduled_ = true;
if (vsync_provider_schedules_check)
return;
if (!align_with_next_vsync) { if (!align_with_next_vsync) {
base::ThreadTaskRunnerHandle::Get()->PostTask( base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, FROM_HERE,
...@@ -372,16 +384,6 @@ void GLSurfacePresentationHelper::ScheduleCheckPendingFrames( ...@@ -372,16 +384,6 @@ void GLSurfacePresentationHelper::ScheduleCheckPendingFrames(
return; return;
} }
if (vsync_provider_ &&
!vsync_provider_->SupportGetVSyncParametersIfAvailable()) {
// In this case, the |vsync_provider_| will call the callback when the next
// VSync is received.
vsync_provider_->GetVSyncParameters(
base::BindRepeating(&GLSurfacePresentationHelper::UpdateVSyncCallback,
weak_ptr_factory_.GetWeakPtr()));
return;
}
// If the |vsync_provider_| can not notify us for the next VSync // If the |vsync_provider_| can not notify us for the next VSync
// asynchronically, we have to compute the next VSync time and post a delayed // asynchronically, we have to compute the next VSync time and post a delayed
// task so we can check the VSync later. // task so we can check the VSync later.
......
...@@ -91,7 +91,8 @@ class GL_EXPORT GLSurfacePresentationHelper { ...@@ -91,7 +91,8 @@ class GL_EXPORT GLSurfacePresentationHelper {
// Callback used by PostDelayedTask for running CheckPendingFrames(). // Callback used by PostDelayedTask for running CheckPendingFrames().
void CheckPendingFramesCallback(); void CheckPendingFramesCallback();
void UpdateVSyncCallback(const base::TimeTicks timebase, void UpdateVSyncCallback(bool should_check_pending_frames,
const base::TimeTicks timebase,
const base::TimeDelta interval); const base::TimeDelta interval);
void ScheduleCheckPendingFrames(bool align_with_next_vsync); void ScheduleCheckPendingFrames(bool align_with_next_vsync);
...@@ -106,6 +107,7 @@ class GL_EXPORT GLSurfacePresentationHelper { ...@@ -106,6 +107,7 @@ class GL_EXPORT GLSurfacePresentationHelper {
bool check_pending_frame_scheduled_ = false; bool check_pending_frame_scheduled_ = false;
bool gl_fence_supported_ = false; bool gl_fence_supported_ = false;
EGLTimestampClient* egl_timestamp_client_ = nullptr; EGLTimestampClient* egl_timestamp_client_ = nullptr;
bool update_vsync_pending_ = false;
base::WeakPtrFactory<GLSurfacePresentationHelper> weak_ptr_factory_{this}; base::WeakPtrFactory<GLSurfacePresentationHelper> weak_ptr_factory_{this};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment