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 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 } | 383 } |
384 | 384 |
385 scoped_refptr<AcceleratedPresenter> AcceleratedPresenter::GetForWindow( | 385 scoped_refptr<AcceleratedPresenter> AcceleratedPresenter::GetForWindow( |
386 gfx::PluginWindowHandle window) { | 386 gfx::PluginWindowHandle window) { |
387 return g_accelerated_presenter_map.Pointer()->GetPresenter(window); | 387 return g_accelerated_presenter_map.Pointer()->GetPresenter(window); |
388 } | 388 } |
389 | 389 |
390 void AcceleratedPresenter::AsyncPresentAndAcknowledge( | 390 void AcceleratedPresenter::AsyncPresentAndAcknowledge( |
391 const gfx::Size& size, | 391 const gfx::Size& size, |
392 int64 surface_handle, | 392 int64 surface_handle, |
393 const CompletionTask& completion_task) { | 393 const CopyCompletionTask& copy_completion_task, |
| 394 const PresentCompletionTask& present_completion_task) { |
394 if (!surface_handle) { | 395 if (!surface_handle) { |
395 TRACE_EVENT1("gpu", "EarlyOut_ZeroSurfaceHandle", | 396 TRACE_EVENT1("gpu", "EarlyOut_ZeroSurfaceHandle", |
396 "surface_handle", surface_handle); | 397 "surface_handle", surface_handle); |
397 completion_task.Run(true, base::TimeTicks(), base::TimeDelta()); | 398 copy_completion_task.Run(true); |
| 399 present_completion_task.Run(base::TimeTicks(), base::TimeDelta()); |
398 return; | 400 return; |
399 } | 401 } |
400 | 402 |
401 present_thread_->message_loop()->PostTask( | 403 present_thread_->message_loop()->PostTask( |
402 FROM_HERE, | 404 FROM_HERE, |
403 base::Bind(&AcceleratedPresenter::DoPresentAndAcknowledge, | 405 base::Bind(&AcceleratedPresenter::DoPresentAndAcknowledge, |
404 this, | 406 this, |
405 size, | 407 size, |
406 surface_handle, | 408 surface_handle, |
407 completion_task)); | 409 copy_completion_task, |
| 410 present_completion_task)); |
408 } | 411 } |
409 | 412 |
410 void AcceleratedPresenter::Present(HDC dc) { | 413 void AcceleratedPresenter::Present(HDC dc) { |
411 TRACE_EVENT0("gpu", "Present"); | 414 TRACE_EVENT0("gpu", "Present"); |
412 | 415 |
413 base::AutoLock locked(lock_); | 416 base::AutoLock locked(lock_); |
414 | 417 |
415 // If invalidated, do nothing. The window is gone. | 418 // If invalidated, do nothing. The window is gone. |
416 if (!window_) | 419 if (!window_) |
417 return; | 420 return; |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 if (cmd_line->HasSwitch(switches::kGpuSwapDelay)) { | 625 if (cmd_line->HasSwitch(switches::kGpuSwapDelay)) { |
623 base::StringToInt(cmd_line->GetSwitchValueNative( | 626 base::StringToInt(cmd_line->GetSwitchValueNative( |
624 switches::kGpuSwapDelay).c_str(), &delay); | 627 switches::kGpuSwapDelay).c_str(), &delay); |
625 } | 628 } |
626 return base::TimeDelta::FromMilliseconds(delay); | 629 return base::TimeDelta::FromMilliseconds(delay); |
627 } | 630 } |
628 | 631 |
629 void AcceleratedPresenter::DoPresentAndAcknowledge( | 632 void AcceleratedPresenter::DoPresentAndAcknowledge( |
630 const gfx::Size& size, | 633 const gfx::Size& size, |
631 int64 surface_handle, | 634 int64 surface_handle, |
632 const CompletionTask& completion_task) { | 635 const CopyCompletionTask& copy_completion_task, |
| 636 const PresentCompletionTask& present_completion_task) { |
633 TRACE_EVENT2( | 637 TRACE_EVENT2( |
634 "gpu", "DoPresentAndAcknowledge", | 638 "gpu", "DoPresentAndAcknowledge", |
635 "width", size.width(), | 639 "width", size.width(), |
636 "height", size.height()); | 640 "height", size.height()); |
637 | 641 |
638 HRESULT hr; | 642 HRESULT hr; |
639 | 643 |
640 base::AutoLock locked(lock_); | 644 base::AutoLock locked(lock_); |
641 | 645 |
642 // Initialize the device lazily since calling Direct3D can crash bots. | 646 // Initialize the device lazily since calling Direct3D can crash bots. |
643 present_thread_->InitDevice(); | 647 present_thread_->InitDevice(); |
644 | 648 |
645 if (!present_thread_->device()) { | 649 if (!present_thread_->device()) { |
646 if (!completion_task.is_null()) | 650 if (!copy_completion_task.is_null()) |
647 completion_task.Run(false, base::TimeTicks(), base::TimeDelta()); | 651 copy_completion_task.Run(false); |
| 652 if (!present_completion_task.is_null()) |
| 653 present_completion_task.Run(base::TimeTicks(), base::TimeDelta()); |
648 TRACE_EVENT0("gpu", "EarlyOut_NoDevice"); | 654 TRACE_EVENT0("gpu", "EarlyOut_NoDevice"); |
649 return; | 655 return; |
650 } | 656 } |
651 | 657 |
652 // Ensure the task is always run and while the lock is taken. | 658 // Ensure the task is always run and while the lock is taken. |
653 base::ScopedClosureRunner scoped_completion_runner( | 659 base::ScopedClosureRunner scoped_copy_completion_runner( |
654 base::Bind(completion_task, true, base::TimeTicks(), base::TimeDelta())); | 660 base::Bind(copy_completion_task, true)); |
| 661 base::ScopedClosureRunner scoped_present_completion_runner( |
| 662 base::Bind(present_completion_task, |
| 663 base::TimeTicks(), |
| 664 base::TimeDelta())); |
655 | 665 |
656 // If invalidated, do nothing, the window is gone. | 666 // If invalidated, do nothing, the window is gone. |
657 if (!window_) { | 667 if (!window_) { |
658 TRACE_EVENT0("gpu", "EarlyOut_NoWindow"); | 668 TRACE_EVENT0("gpu", "EarlyOut_NoWindow"); |
659 return; | 669 return; |
660 } | 670 } |
661 | 671 |
662 #if !defined(USE_AURA) | 672 #if !defined(USE_AURA) |
663 // If the window is a different size than the swap chain that is being | 673 // If the window is a different size than the swap chain that is being |
664 // presented then drop the frame. | 674 // presented then drop the frame. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
781 | 791 |
782 present_thread_->device()->SetTexture(0, NULL); | 792 present_thread_->device()->SetTexture(0, NULL); |
783 present_thread_->device()->SetRenderTarget(0, default_render_target); | 793 present_thread_->device()->SetRenderTarget(0, default_render_target); |
784 default_render_target->Release(); | 794 default_render_target->Release(); |
785 } | 795 } |
786 | 796 |
787 hr = present_thread_->query()->Issue(D3DISSUE_END); | 797 hr = present_thread_->query()->Issue(D3DISSUE_END); |
788 if (FAILED(hr)) | 798 if (FAILED(hr)) |
789 return; | 799 return; |
790 | 800 |
| 801 // Wait for the StretchRect to complete before notifying the GPU process |
| 802 // that it is safe to write to its backing store again. |
| 803 { |
| 804 TRACE_EVENT0("gpu", "spin"); |
| 805 do { |
| 806 hr = present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH); |
| 807 |
| 808 if (hr == S_FALSE) |
| 809 Sleep(1); |
| 810 } while (hr == S_FALSE); |
| 811 } |
| 812 |
| 813 // Acknowledge that the copy is complete and it is safe to modify the shared |
| 814 // texture. |
| 815 scoped_copy_completion_runner.Release(); |
| 816 copy_completion_task.Run(true); |
| 817 |
791 present_size_ = size; | 818 present_size_ = size; |
792 | 819 |
793 static const base::TimeDelta swap_delay = GetSwapDelay(); | 820 static const base::TimeDelta swap_delay = GetSwapDelay(); |
794 if (swap_delay.ToInternalValue()) | 821 if (swap_delay.ToInternalValue()) |
795 base::PlatformThread::Sleep(swap_delay); | 822 base::PlatformThread::Sleep(swap_delay); |
796 | 823 |
797 // If it is expected that Direct3D cannot be used reliably because the window | 824 // If it is expected that Direct3D cannot be used reliably because the window |
798 // is resizing, fall back to presenting with GDI. | 825 // is resizing, fall back to presenting with GDI. |
799 if (CheckDirect3DWillWork()) { | 826 if (CheckDirect3DWillWork()) { |
800 TRACE_EVENT0("gpu", "PresentD3D"); | 827 TRACE_EVENT0("gpu", "PresentD3D"); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
846 base::TimeTicks last_vsync_time; | 873 base::TimeTicks last_vsync_time; |
847 base::TimeDelta refresh_period; | 874 base::TimeDelta refresh_period; |
848 if (display_mode.Height) { | 875 if (display_mode.Height) { |
849 last_vsync_time = current_time - | 876 last_vsync_time = current_time - |
850 base::TimeDelta::FromMilliseconds((clamped_scanline * 1000) / | 877 base::TimeDelta::FromMilliseconds((clamped_scanline * 1000) / |
851 (display_mode.RefreshRate * display_mode.Height)); | 878 (display_mode.RefreshRate * display_mode.Height)); |
852 refresh_period = base::TimeDelta::FromMicroseconds( | 879 refresh_period = base::TimeDelta::FromMicroseconds( |
853 1000000 / display_mode.RefreshRate); | 880 1000000 / display_mode.RefreshRate); |
854 } | 881 } |
855 | 882 |
856 // Wait for the StretchRect to complete before notifying the GPU process | 883 scoped_present_completion_runner.Release(); |
857 // that it is safe to write to its backing store again. | 884 present_completion_task.Run(last_vsync_time, refresh_period); |
858 { | |
859 TRACE_EVENT0("gpu", "spin"); | |
860 do { | |
861 hr = present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH); | |
862 | |
863 if (hr == S_FALSE) | |
864 Sleep(1); | |
865 } while (hr == S_FALSE); | |
866 } | |
867 | |
868 scoped_completion_runner.Release(); | |
869 completion_task.Run(true, last_vsync_time, refresh_period); | |
870 } | 885 } |
871 | 886 |
872 void AcceleratedPresenter::DoSuspend() { | 887 void AcceleratedPresenter::DoSuspend() { |
873 base::AutoLock locked(lock_); | 888 base::AutoLock locked(lock_); |
874 swap_chain_ = NULL; | 889 swap_chain_ = NULL; |
875 } | 890 } |
876 | 891 |
877 void AcceleratedPresenter::DoReleaseSurface() { | 892 void AcceleratedPresenter::DoReleaseSurface() { |
878 base::AutoLock locked(lock_); | 893 base::AutoLock locked(lock_); |
879 present_thread_->InitDevice(); | 894 present_thread_->InitDevice(); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1001 presenter_->AsyncCopyTo(src_subrect, dst_size, buf, callback); | 1016 presenter_->AsyncCopyTo(src_subrect, dst_size, buf, callback); |
1002 } | 1017 } |
1003 | 1018 |
1004 void AcceleratedSurface::Suspend() { | 1019 void AcceleratedSurface::Suspend() { |
1005 presenter_->Suspend(); | 1020 presenter_->Suspend(); |
1006 } | 1021 } |
1007 | 1022 |
1008 void AcceleratedSurface::WasHidden() { | 1023 void AcceleratedSurface::WasHidden() { |
1009 presenter_->WasHidden(); | 1024 presenter_->WasHidden(); |
1010 } | 1025 } |
OLD | NEW |