OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ui/surface/accelerated_surface_win.h" | 5 #include "ui/surface/accelerated_surface_win.h" |
6 | 6 |
7 #include <dwmapi.h> | 7 #include <dwmapi.h> |
8 #include <windows.h> | 8 #include <windows.h> |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 | 262 |
263 // static | 263 // static |
264 scoped_refptr<AcceleratedPresenter> AcceleratedPresenter::GetForWindow( | 264 scoped_refptr<AcceleratedPresenter> AcceleratedPresenter::GetForWindow( |
265 gfx::PluginWindowHandle window) { | 265 gfx::PluginWindowHandle window) { |
266 return g_accelerated_presenter_map.Pointer()->GetPresenter(window); | 266 return g_accelerated_presenter_map.Pointer()->GetPresenter(window); |
267 } | 267 } |
268 | 268 |
269 void AcceleratedPresenter::AsyncPresentAndAcknowledge( | 269 void AcceleratedPresenter::AsyncPresentAndAcknowledge( |
270 const gfx::Size& size, | 270 const gfx::Size& size, |
271 int64 surface_handle, | 271 int64 surface_handle, |
272 const CopyCompletionTask& copy_completion_task, | 272 const CompletionTask& completion_task) { |
273 const PresentCompletionTask& present_completion_task) { | |
274 if (!surface_handle) { | 273 if (!surface_handle) { |
275 TRACE_EVENT1("gpu", "EarlyOut_ZeroSurfaceHandle", | 274 TRACE_EVENT1("gpu", "EarlyOut_ZeroSurfaceHandle", |
276 "surface_handle", surface_handle); | 275 "surface_handle", surface_handle); |
277 copy_completion_task.Run(true); | 276 completion_task.Run(true, base::TimeTicks(), base::TimeDelta()); |
278 present_completion_task.Run(base::TimeTicks(), base::TimeDelta()); | |
279 return; | 277 return; |
280 } | 278 } |
281 | 279 |
282 present_thread_->message_loop()->PostTask( | 280 present_thread_->message_loop()->PostTask( |
283 FROM_HERE, | 281 FROM_HERE, |
284 base::Bind(&AcceleratedPresenter::DoPresentAndAcknowledge, | 282 base::Bind(&AcceleratedPresenter::DoPresentAndAcknowledge, |
285 this, | 283 this, |
286 size, | 284 size, |
287 surface_handle, | 285 surface_handle, |
288 copy_completion_task, | 286 completion_task)); |
289 present_completion_task)); | |
290 } | 287 } |
291 | 288 |
292 void AcceleratedPresenter::Present(HDC dc) { | 289 void AcceleratedPresenter::Present(HDC dc) { |
293 TRACE_EVENT0("gpu", "Present"); | 290 TRACE_EVENT0("gpu", "Present"); |
294 | 291 |
295 base::AutoLock locked(lock_); | 292 base::AutoLock locked(lock_); |
296 | 293 |
297 // If invalidated, do nothing. The window is gone. | 294 // If invalidated, do nothing. The window is gone. |
298 if (!window_) | 295 if (!window_) |
299 return; | 296 return; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 if (cmd_line->HasSwitch(switches::kGpuSwapDelay)) { | 462 if (cmd_line->HasSwitch(switches::kGpuSwapDelay)) { |
466 base::StringToInt(cmd_line->GetSwitchValueNative( | 463 base::StringToInt(cmd_line->GetSwitchValueNative( |
467 switches::kGpuSwapDelay).c_str(), &delay); | 464 switches::kGpuSwapDelay).c_str(), &delay); |
468 } | 465 } |
469 return base::TimeDelta::FromMilliseconds(delay); | 466 return base::TimeDelta::FromMilliseconds(delay); |
470 } | 467 } |
471 | 468 |
472 void AcceleratedPresenter::DoPresentAndAcknowledge( | 469 void AcceleratedPresenter::DoPresentAndAcknowledge( |
473 const gfx::Size& size, | 470 const gfx::Size& size, |
474 int64 surface_handle, | 471 int64 surface_handle, |
475 const CopyCompletionTask& copy_completion_task, | 472 const CompletionTask& completion_task) { |
476 const PresentCompletionTask& present_completion_task) { | |
477 TRACE_EVENT2( | 473 TRACE_EVENT2( |
478 "gpu", "DoPresentAndAcknowledge", | 474 "gpu", "DoPresentAndAcknowledge", |
479 "width", size.width(), | 475 "width", size.width(), |
480 "height", size.height()); | 476 "height", size.height()); |
481 | 477 |
482 HRESULT hr; | 478 HRESULT hr; |
483 | 479 |
484 base::AutoLock locked(lock_); | 480 base::AutoLock locked(lock_); |
485 | 481 |
486 // Initialize the device lazily since calling Direct3D can crash bots. | 482 // Initialize the device lazily since calling Direct3D can crash bots. |
487 present_thread_->InitDevice(); | 483 present_thread_->InitDevice(); |
488 | 484 |
489 if (!present_thread_->device()) { | 485 if (!present_thread_->device()) { |
490 if (!copy_completion_task.is_null()) | 486 if (!completion_task.is_null()) |
491 copy_completion_task.Run(false); | 487 completion_task.Run(false, base::TimeTicks(), base::TimeDelta()); |
492 if (!present_completion_task.is_null()) | |
493 present_completion_task.Run(base::TimeTicks(), base::TimeDelta()); | |
494 TRACE_EVENT0("gpu", "EarlyOut_NoDevice"); | 488 TRACE_EVENT0("gpu", "EarlyOut_NoDevice"); |
495 return; | 489 return; |
496 } | 490 } |
497 | 491 |
498 // Ensure the task is always run and while the lock is taken. | 492 // Ensure the task is always run and while the lock is taken. |
499 base::ScopedClosureRunner scoped_copy_completion_runner( | 493 base::ScopedClosureRunner scoped_completion_runner( |
500 base::Bind(copy_completion_task, true)); | 494 base::Bind(completion_task, true, base::TimeTicks(), base::TimeDelta())); |
501 base::ScopedClosureRunner scoped_present_completion_runner( | |
502 base::Bind(present_completion_task, | |
503 base::TimeTicks(), | |
504 base::TimeDelta())); | |
505 | 495 |
506 // If invalidated, do nothing, the window is gone. | 496 // If invalidated, do nothing, the window is gone. |
507 if (!window_) { | 497 if (!window_) { |
508 TRACE_EVENT0("gpu", "EarlyOut_NoWindow"); | 498 TRACE_EVENT0("gpu", "EarlyOut_NoWindow"); |
509 return; | 499 return; |
510 } | 500 } |
511 | 501 |
512 #if !defined(USE_AURA) | 502 #if !defined(USE_AURA) |
513 // If the window is a different size than the swap chain that is being | 503 // If the window is a different size than the swap chain that is being |
514 // presented then drop the frame. | 504 // presented then drop the frame. |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 bool result = present_thread_->surface_transformer()->CopyInverted( | 587 bool result = present_thread_->surface_transformer()->CopyInverted( |
598 source_texture_, dest_surface, size); | 588 source_texture_, dest_surface, size); |
599 if (!result) | 589 if (!result) |
600 return; | 590 return; |
601 } | 591 } |
602 | 592 |
603 hr = present_thread_->query()->Issue(D3DISSUE_END); | 593 hr = present_thread_->query()->Issue(D3DISSUE_END); |
604 if (FAILED(hr)) | 594 if (FAILED(hr)) |
605 return; | 595 return; |
606 | 596 |
607 // Wait for the StretchRect to complete before notifying the GPU process | |
608 // that it is safe to write to its backing store again. | |
609 { | |
610 TRACE_EVENT0("gpu", "spin"); | |
611 do { | |
612 hr = present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH); | |
613 | |
614 if (hr == S_FALSE) | |
615 Sleep(1); | |
616 } while (hr == S_FALSE); | |
617 } | |
618 | |
619 // Acknowledge that the copy is complete and it is safe to modify the shared | |
620 // texture. | |
621 scoped_copy_completion_runner.Release(); | |
622 copy_completion_task.Run(true); | |
623 | |
624 present_size_ = size; | 597 present_size_ = size; |
625 | 598 |
626 static const base::TimeDelta swap_delay = GetSwapDelay(); | 599 static const base::TimeDelta swap_delay = GetSwapDelay(); |
627 if (swap_delay.ToInternalValue()) | 600 if (swap_delay.ToInternalValue()) |
628 base::PlatformThread::Sleep(swap_delay); | 601 base::PlatformThread::Sleep(swap_delay); |
629 | 602 |
630 // If it is expected that Direct3D cannot be used reliably because the window | 603 // If it is expected that Direct3D cannot be used reliably because the window |
631 // is resizing, fall back to presenting with GDI. | 604 // is resizing, fall back to presenting with GDI. |
632 if (CheckDirect3DWillWork()) { | 605 if (CheckDirect3DWillWork()) { |
633 TRACE_EVENT0("gpu", "PresentD3D"); | 606 TRACE_EVENT0("gpu", "PresentD3D"); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 base::TimeTicks last_vsync_time; | 652 base::TimeTicks last_vsync_time; |
680 base::TimeDelta refresh_period; | 653 base::TimeDelta refresh_period; |
681 if (display_mode.Height) { | 654 if (display_mode.Height) { |
682 last_vsync_time = current_time - | 655 last_vsync_time = current_time - |
683 base::TimeDelta::FromMilliseconds((clamped_scanline * 1000) / | 656 base::TimeDelta::FromMilliseconds((clamped_scanline * 1000) / |
684 (display_mode.RefreshRate * display_mode.Height)); | 657 (display_mode.RefreshRate * display_mode.Height)); |
685 refresh_period = base::TimeDelta::FromMicroseconds( | 658 refresh_period = base::TimeDelta::FromMicroseconds( |
686 1000000 / display_mode.RefreshRate); | 659 1000000 / display_mode.RefreshRate); |
687 } | 660 } |
688 | 661 |
689 scoped_present_completion_runner.Release(); | 662 // Wait for the StretchRect to complete before notifying the GPU process |
690 present_completion_task.Run(last_vsync_time, refresh_period); | 663 // that it is safe to write to its backing store again. |
| 664 { |
| 665 TRACE_EVENT0("gpu", "spin"); |
| 666 do { |
| 667 hr = present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH); |
| 668 |
| 669 if (hr == S_FALSE) |
| 670 Sleep(1); |
| 671 } while (hr == S_FALSE); |
| 672 } |
| 673 |
| 674 scoped_completion_runner.Release(); |
| 675 completion_task.Run(true, last_vsync_time, refresh_period); |
691 } | 676 } |
692 | 677 |
693 void AcceleratedPresenter::DoSuspend() { | 678 void AcceleratedPresenter::DoSuspend() { |
694 base::AutoLock locked(lock_); | 679 base::AutoLock locked(lock_); |
695 swap_chain_ = NULL; | 680 swap_chain_ = NULL; |
696 } | 681 } |
697 | 682 |
698 void AcceleratedPresenter::DoReleaseSurface() { | 683 void AcceleratedPresenter::DoReleaseSurface() { |
699 base::AutoLock locked(lock_); | 684 base::AutoLock locked(lock_); |
700 present_thread_->InitDevice(); | 685 present_thread_->InitDevice(); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 presenter_->AsyncCopyTo(src_subrect, dst_size, buf, callback); | 807 presenter_->AsyncCopyTo(src_subrect, dst_size, buf, callback); |
823 } | 808 } |
824 | 809 |
825 void AcceleratedSurface::Suspend() { | 810 void AcceleratedSurface::Suspend() { |
826 presenter_->Suspend(); | 811 presenter_->Suspend(); |
827 } | 812 } |
828 | 813 |
829 void AcceleratedSurface::WasHidden() { | 814 void AcceleratedSurface::WasHidden() { |
830 presenter_->WasHidden(); | 815 presenter_->WasHidden(); |
831 } | 816 } |
OLD | NEW |