Index: gpu/ipc/service/gpu_command_buffer_stub.cc |
diff --git a/gpu/ipc/service/gpu_command_buffer_stub.cc b/gpu/ipc/service/gpu_command_buffer_stub.cc |
index 3f41a30555095398eacb3ddab053551bfa5bfb3d..92b491e027b1c710fce2e7e3e335852daedb3380 100644 |
--- a/gpu/ipc/service/gpu_command_buffer_stub.cc |
+++ b/gpu/ipc/service/gpu_command_buffer_stub.cc |
@@ -8,12 +8,14 @@ |
#include "base/bind.h" |
#include "base/bind_helpers.h" |
+#include "base/command_line.h" |
#include "base/hash.h" |
#include "base/json/json_writer.h" |
#include "base/macros.h" |
#include "base/memory/memory_pressure_listener.h" |
#include "base/memory/ptr_util.h" |
#include "base/memory/shared_memory.h" |
+#include "base/metrics/field_trial.h" |
#include "base/metrics/histogram_macros.h" |
#include "base/time/time.h" |
#include "base/trace_event/trace_event.h" |
@@ -39,6 +41,7 @@ |
#include "gpu/ipc/service/gpu_memory_buffer_factory.h" |
#include "gpu/ipc/service/gpu_memory_manager.h" |
#include "gpu/ipc/service/gpu_memory_tracking.h" |
+#include "gpu/ipc/service/gpu_vsync_provider.h" |
#include "gpu/ipc/service/gpu_watchdog_thread.h" |
#include "gpu/ipc/service/image_transport_surface.h" |
#include "ui/gl/gl_bindings.h" |
@@ -218,6 +221,20 @@ CommandBufferId GetCommandBufferID(int channel_id, int32_t route_id) { |
(static_cast<uint64_t>(channel_id) << 32) | route_id); |
} |
+bool IsGpuVSyncSignalSupported() { |
+#if defined(OS_WIN) |
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
+ if (command_line->HasSwitch(switches::kUseD3DVSync)) |
+ return true; |
+ |
+ const std::string group_name = |
+ base::FieldTrialList::FindFullName("UseD3DVSync"); |
+ return group_name == "Enabled"; |
+#else |
+ return false; |
+#endif // defined(OS_WIN) |
+} |
+ |
} // namespace |
std::unique_ptr<GpuCommandBufferStub> GpuCommandBufferStub::Create( |
@@ -249,7 +266,8 @@ GpuCommandBufferStub::GpuCommandBufferStub( |
waiting_for_sync_point_(false), |
previous_processed_num_(0), |
active_url_(init_params.active_url), |
- active_url_hash_(base::Hash(active_url_.possibly_invalid_spec())) {} |
+ active_url_hash_(base::Hash(active_url_.possibly_invalid_spec())), |
+ gpu_vsync_signal_supported_(IsGpuVSyncSignalSupported()) {} |
GpuCommandBufferStub::~GpuCommandBufferStub() { |
Destroy(); |
@@ -310,6 +328,7 @@ bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { |
IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyImage, OnDestroyImage); |
IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateStreamTexture, |
OnCreateStreamTexture) |
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_EnableVSync, OnEnableVSync); |
IPC_MESSAGE_UNHANDLED(handled = false) |
IPC_END_MESSAGE_MAP() |
@@ -370,6 +389,35 @@ void GpuCommandBufferStub::SetLatencyInfoCallback( |
void GpuCommandBufferStub::UpdateVSyncParameters(base::TimeTicks timebase, |
base::TimeDelta interval) { |
+#if defined(OS_WIN) |
+ if (gpu_vsync_signal_supported_) { |
+ base::AutoLock lock(vsync_lock_); |
+ vsync_interval_ = interval; |
+ return; |
+ } |
+#endif // defined(OS_WIN) |
+ |
+ SendUpdatedVSyncParameters(timebase, interval); |
+} |
+ |
+void GpuCommandBufferStub::UpdateGpuVSync(base::TimeTicks timestamp) { |
+ DCHECK(gpu_vsync_signal_supported_); |
+ |
+#if defined(OS_WIN) |
+ |
+ base::TimeDelta interval; |
+ { |
+ base::AutoLock lock(vsync_lock_); |
+ interval = vsync_interval_; |
+ } |
+ |
+ SendUpdatedVSyncParameters(timestamp, interval); |
+#endif // defined(OS_WIN) |
+} |
+ |
+void GpuCommandBufferStub::SendUpdatedVSyncParameters( |
+ base::TimeTicks timebase, |
+ base::TimeDelta interval) { |
Send(new GpuCommandBufferMsg_UpdateVSyncParameters(route_id_, timebase, |
interval)); |
} |
@@ -521,6 +569,8 @@ void GpuCommandBufferStub::Destroy() { |
sync_point_client_.reset(); |
+ vsync_provider_.reset(); |
+ |
bool have_context = false; |
if (decoder_ && decoder_->GetGLContext()) { |
// Try to make the context current regardless of whether it was lost, so we |
@@ -634,6 +684,13 @@ bool GpuCommandBufferStub::Initialize( |
} |
} |
+ if (IsGpuVSyncSignalSupported()) { |
+ vsync_provider_ = GpuVSyncProvider::Create( |
+ base::Bind(&GpuCommandBufferStub::UpdateGpuVSync, |
+ base::Unretained(this)), |
+ surface_handle_); |
+ } |
+ |
scoped_refptr<gl::GLContext> context; |
gl::GLShareGroup* gl_share_group = channel_->share_group(); |
if (use_virtualized_gl_context_ && gl_share_group) { |
@@ -770,6 +827,11 @@ void GpuCommandBufferStub::OnSetGetBuffer(int32_t shm_id, |
Send(reply_message); |
} |
+void GpuCommandBufferStub::OnEnableVSync(bool enabled) { |
+ DCHECK(vsync_provider_); |
+ vsync_provider_->EnableVSync(enabled); |
+} |
+ |
void GpuCommandBufferStub::OnTakeFrontBuffer(const Mailbox& mailbox) { |
TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnTakeFrontBuffer"); |
if (!decoder_) { |