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

Side by Side Diff: gpu/ipc/service/gpu_vsync_provider_win.cc

Issue 2846613002: Fix a CHECK when monitor configuration changes (Closed)
Patch Set: Created 3 years, 7 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/ipc/service/gpu_vsync_provider_win.h" 5 #include "gpu/ipc/service/gpu_vsync_provider_win.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/atomicops.h" 9 #include "base/atomicops.h"
10 #include "base/debug/alias.h" 10 #include "base/debug/alias.h"
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 void Reschedule(); 77 void Reschedule();
78 void OpenAdapter(const wchar_t* device_name); 78 void OpenAdapter(const wchar_t* device_name);
79 void CloseAdapter(); 79 void CloseAdapter();
80 NTSTATUS WaitForVBlankEvent(); 80 NTSTATUS WaitForVBlankEvent();
81 81
82 void SendGpuVSyncUpdate(base::TimeTicks now, 82 void SendGpuVSyncUpdate(base::TimeTicks now,
83 base::TimeTicks timestamp, 83 base::TimeTicks timestamp,
84 base::TimeDelta interval); 84 base::TimeDelta interval);
85 void InvokeCallbackAndReschedule(base::TimeTicks timestamp, 85 void InvokeCallbackAndReschedule(base::TimeTicks timestamp,
86 base::TimeDelta interval); 86 base::TimeDelta interval);
87 void UseDelayBasedVSyncOnError();
87 void ScheduleDelayBasedVSync(base::TimeTicks timebase, 88 void ScheduleDelayBasedVSync(base::TimeTicks timebase,
88 base::TimeDelta interval); 89 base::TimeDelta interval);
89 90
90 // Specifies whether background tasks are running. 91 // Specifies whether background tasks are running.
91 // This can be set on background thread only. 92 // This can be set on background thread only.
92 bool running_ = false; 93 bool running_ = false;
93 94
94 // Specified whether the worker is enabled. This is accessed from both 95 // Specified whether the worker is enabled. This is accessed from both
95 // threads but can be changed on the main thread only. 96 // threads but can be changed on the main thread only.
96 base::subtle::AtomicWord enabled_ = false; 97 base::subtle::AtomicWord enabled_ = false;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 } 183 }
183 } 184 }
184 185
185 void GpuVSyncWorker::WaitForVSyncOnThread() { 186 void GpuVSyncWorker::WaitForVSyncOnThread() {
186 DCHECK(BelongsToWorkerThread()); 187 DCHECK(BelongsToWorkerThread());
187 188
188 TRACE_EVENT0("gpu", "GpuVSyncWorker::WaitForVSyncOnThread"); 189 TRACE_EVENT0("gpu", "GpuVSyncWorker::WaitForVSyncOnThread");
189 190
190 HMONITOR monitor = 191 HMONITOR monitor =
191 MonitorFromWindow(surface_handle_, MONITOR_DEFAULTTONEAREST); 192 MonitorFromWindow(surface_handle_, MONITOR_DEFAULTTONEAREST);
192 MONITORINFOEX monitor_info; 193 MONITORINFOEX monitor_info = {};
193 monitor_info.cbSize = sizeof(MONITORINFOEX); 194 monitor_info.cbSize = sizeof(MONITORINFOEX);
194 BOOL success = GetMonitorInfo(monitor, &monitor_info); 195 BOOL success = GetMonitorInfo(monitor, &monitor_info);
195 CHECK(success); 196 if (!success) {
197 // This is possible when a monitor is switched off or disconnected.
198 CloseAdapter();
199 UseDelayBasedVSyncOnError();
200 return;
201 }
196 202
197 if (current_device_name_.compare(monitor_info.szDevice) != 0) { 203 if (current_device_name_.compare(monitor_info.szDevice) != 0) {
198 // Monitor changed. Close the current adapter handle and open a new one. 204 // Monitor changed. Close the current adapter handle and open a new one.
199 CloseAdapter(); 205 CloseAdapter();
200 OpenAdapter(monitor_info.szDevice); 206 OpenAdapter(monitor_info.szDevice);
201 } 207 }
202 208
203 NTSTATUS wait_result = WaitForVBlankEvent(); 209 NTSTATUS wait_result = WaitForVBlankEvent();
204 if (wait_result != STATUS_SUCCESS) { 210 if (wait_result != STATUS_SUCCESS) {
205 if (wait_result == STATUS_GRAPHICS_PRESENT_OCCLUDED) { 211 if (wait_result == STATUS_GRAPHICS_PRESENT_OCCLUDED) {
206 // This may be triggered by the monitor going into sleep. 212 // This may be triggered by the monitor going into sleep.
207 // Use timer based mechanism as a backup, start with getting VSync 213 UseDelayBasedVSyncOnError();
208 // parameters to determine timebase and interval.
209 // TODO(stanisc): Consider a slower v-sync rate in this particular case.
210 vsync_provider_->GetVSyncParameters(base::Bind(
211 &GpuVSyncWorker::ScheduleDelayBasedVSync, base::Unretained(this)));
212 return; 214 return;
213 } else { 215 } else {
214 base::debug::Alias(&wait_result); 216 base::debug::Alias(&wait_result);
215 CHECK(false); 217 CHECK(false);
216 } 218 }
217 } 219 }
218 220
219 vsync_provider_->GetVSyncParameters( 221 vsync_provider_->GetVSyncParameters(
220 base::Bind(&GpuVSyncWorker::SendGpuVSyncUpdate, base::Unretained(this), 222 base::Bind(&GpuVSyncWorker::SendGpuVSyncUpdate, base::Unretained(this),
221 base::TimeTicks::Now())); 223 base::TimeTicks::Now()));
(...skipping 30 matching lines...) Expand all
252 if (base::subtle::NoBarrier_Load(&enabled_)) { 254 if (base::subtle::NoBarrier_Load(&enabled_)) {
253 callback_.Run(timestamp, interval); 255 callback_.Run(timestamp, interval);
254 task_runner()->PostTask(FROM_HERE, 256 task_runner()->PostTask(FROM_HERE,
255 base::Bind(&GpuVSyncWorker::WaitForVSyncOnThread, 257 base::Bind(&GpuVSyncWorker::WaitForVSyncOnThread,
256 base::Unretained(this))); 258 base::Unretained(this)));
257 } else { 259 } else {
258 running_ = false; 260 running_ = false;
259 } 261 }
260 } 262 }
261 263
264 void GpuVSyncWorker::UseDelayBasedVSyncOnError() {
265 // This is called in a case of an error.
266 // Use timer based mechanism as a backup for one v-sync cycle, start with
267 // getting VSync parameters to determine timebase and interval.
268 // TODO(stanisc): Consider a slower v-sync rate in this particular case.
269 vsync_provider_->GetVSyncParameters(base::Bind(
270 &GpuVSyncWorker::ScheduleDelayBasedVSync, base::Unretained(this)));
271 }
272
262 void GpuVSyncWorker::ScheduleDelayBasedVSync(base::TimeTicks timebase, 273 void GpuVSyncWorker::ScheduleDelayBasedVSync(base::TimeTicks timebase,
263 base::TimeDelta interval) { 274 base::TimeDelta interval) {
264 // This is called only when WaitForVBlankEvent fails due to monitor going to 275 // This is called only when WaitForVBlankEvent fails due to monitor going to
265 // sleep. Use a delay based v-sync as a back-up. 276 // sleep. Use a delay based v-sync as a back-up.
266 if (interval.is_zero()) { 277 if (interval.is_zero()) {
267 interval = base::TimeDelta::FromMicroseconds(kDefaultTimerBasedInterval); 278 interval = base::TimeDelta::FromMicroseconds(kDefaultTimerBasedInterval);
268 } 279 }
269 280
270 base::TimeTicks now = base::TimeTicks::Now(); 281 base::TimeTicks now = base::TimeTicks::Now();
271 base::TimeTicks next_vsync = now.SnappedToNextTick(timebase, interval); 282 base::TimeTicks next_vsync = now.SnappedToNextTick(timebase, interval);
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 void GpuVSyncProviderWin::OnVSync(base::TimeTicks timestamp, 433 void GpuVSyncProviderWin::OnVSync(base::TimeTicks timestamp,
423 base::TimeDelta interval) { 434 base::TimeDelta interval) {
424 DCHECK(vsync_worker_->BelongsToWorkerThread()); 435 DCHECK(vsync_worker_->BelongsToWorkerThread());
425 436
426 message_filter_->Send( 437 message_filter_->Send(
427 base::MakeUnique<GpuCommandBufferMsg_UpdateVSyncParameters>( 438 base::MakeUnique<GpuCommandBufferMsg_UpdateVSyncParameters>(
428 message_filter_->route_id(), timestamp, interval)); 439 message_filter_->route_id(), timestamp, interval));
429 } 440 }
430 441
431 } // namespace gpu 442 } // namespace gpu
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698