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 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 } | 425 } |
426 | 426 |
427 scoped_refptr<AcceleratedPresenter> AcceleratedPresenter::GetForWindow( | 427 scoped_refptr<AcceleratedPresenter> AcceleratedPresenter::GetForWindow( |
428 gfx::NativeWindow window) { | 428 gfx::NativeWindow window) { |
429 return g_accelerated_presenter_map.Pointer()->GetPresenter(window); | 429 return g_accelerated_presenter_map.Pointer()->GetPresenter(window); |
430 } | 430 } |
431 | 431 |
432 void AcceleratedPresenter::AsyncPresentAndAcknowledge( | 432 void AcceleratedPresenter::AsyncPresentAndAcknowledge( |
433 const gfx::Size& size, | 433 const gfx::Size& size, |
434 int64 surface_handle, | 434 int64 surface_handle, |
435 const base::Callback<void(bool)>& completion_task) { | 435 const CompletionTask& completion_task) { |
436 if (!surface_handle) { | 436 if (!surface_handle) { |
437 TRACE_EVENT1("gpu", "EarlyOut_ZeroSurfaceHandle", | 437 TRACE_EVENT1("gpu", "EarlyOut_ZeroSurfaceHandle", |
438 "surface_handle", surface_handle); | 438 "surface_handle", surface_handle); |
439 completion_task.Run(true); | 439 completion_task.Run(true, base::TimeTicks(), base::TimeDelta()); |
440 return; | 440 return; |
441 } | 441 } |
442 | 442 |
443 present_thread_->message_loop()->PostTask( | 443 present_thread_->message_loop()->PostTask( |
444 FROM_HERE, | 444 FROM_HERE, |
445 base::Bind(&AcceleratedPresenter::DoPresentAndAcknowledge, | 445 base::Bind(&AcceleratedPresenter::DoPresentAndAcknowledge, |
446 this, | 446 this, |
447 size, | 447 size, |
448 surface_handle, | 448 surface_handle, |
449 completion_task)); | 449 completion_task)); |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 if (cmd_line->HasSwitch(switches::kGpuSwapDelay)) { | 668 if (cmd_line->HasSwitch(switches::kGpuSwapDelay)) { |
669 base::StringToInt(cmd_line->GetSwitchValueNative( | 669 base::StringToInt(cmd_line->GetSwitchValueNative( |
670 switches::kGpuSwapDelay).c_str(), &delay); | 670 switches::kGpuSwapDelay).c_str(), &delay); |
671 } | 671 } |
672 return base::TimeDelta::FromMilliseconds(delay); | 672 return base::TimeDelta::FromMilliseconds(delay); |
673 } | 673 } |
674 | 674 |
675 void AcceleratedPresenter::DoPresentAndAcknowledge( | 675 void AcceleratedPresenter::DoPresentAndAcknowledge( |
676 const gfx::Size& size, | 676 const gfx::Size& size, |
677 int64 surface_handle, | 677 int64 surface_handle, |
678 const base::Callback<void(bool)>& completion_task) { | 678 const CompletionTask& completion_task) { |
679 TRACE_EVENT1( | 679 TRACE_EVENT1( |
680 "gpu", "DoPresentAndAcknowledge", "surface_handle", surface_handle); | 680 "gpu", "DoPresentAndAcknowledge", "surface_handle", surface_handle); |
681 | 681 |
682 HRESULT hr; | 682 HRESULT hr; |
683 | 683 |
684 base::AutoLock locked(lock_); | 684 base::AutoLock locked(lock_); |
685 | 685 |
686 // Initialize the device lazily since calling Direct3D can crash bots. | 686 // Initialize the device lazily since calling Direct3D can crash bots. |
687 present_thread_->InitDevice(); | 687 present_thread_->InitDevice(); |
688 | 688 |
689 if (!present_thread_->device()) { | 689 if (!present_thread_->device()) { |
690 if (!completion_task.is_null()) | 690 if (!completion_task.is_null()) |
691 completion_task.Run(false); | 691 completion_task.Run(false, base::TimeTicks(), base::TimeDelta()); |
692 return; | 692 return; |
693 } | 693 } |
694 | 694 |
695 // Ensure the task is always run and while the lock is taken. | 695 // Ensure the task is always run and while the lock is taken. |
696 base::ScopedClosureRunner scoped_completion_runner(base::Bind(completion_task, | 696 base::ScopedClosureRunner scoped_completion_runner( |
697 true)); | 697 base::Bind(completion_task, true, base::TimeTicks(), base::TimeDelta())); |
698 | 698 |
699 // If invalidated, do nothing, the window is gone. | 699 // If invalidated, do nothing, the window is gone. |
700 if (!window_) | 700 if (!window_) |
701 return; | 701 return; |
702 | 702 |
703 // If the window is a different size than the swap chain that is being | 703 // If the window is a different size than the swap chain that is being |
704 // presented then drop the frame. | 704 // presented then drop the frame. |
705 RECT window_rect; | 705 RECT window_rect; |
706 GetClientRect(window_, &window_rect); | 706 GetClientRect(window_, &window_rect); |
707 if (hidden_ && (window_rect.right != size.width() || | 707 if (hidden_ && (window_rect.right != size.width() || |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 TRACE_EVENT0("gpu", "Present"); | 842 TRACE_EVENT0("gpu", "Present"); |
843 hr = swap_chain_->Present(&rect, &rect, window_, NULL, 0); | 843 hr = swap_chain_->Present(&rect, &rect, window_, NULL, 0); |
844 // For latency_tests.cc: | 844 // For latency_tests.cc: |
845 UNSHIPPED_TRACE_EVENT_INSTANT0("test_gpu", "CompositorSwapBuffersComplete"); | 845 UNSHIPPED_TRACE_EVENT_INSTANT0("test_gpu", "CompositorSwapBuffersComplete"); |
846 if (FAILED(hr) && | 846 if (FAILED(hr) && |
847 FAILED(present_thread_->device()->CheckDeviceState(window_))) { | 847 FAILED(present_thread_->device()->CheckDeviceState(window_))) { |
848 present_thread_->ResetDevice(); | 848 present_thread_->ResetDevice(); |
849 } | 849 } |
850 } | 850 } |
851 | 851 |
| 852 { |
| 853 TRACE_EVENT0("gpu", "GetPresentationStats"); |
| 854 base::TimeTicks timebase; |
| 855 base::TimeDelta interval; |
| 856 uint32 numerator = 0, denominator = 0; |
| 857 if (GetPresentationStats(&timebase, &numerator, &denominator) && |
| 858 numerator > 0 && denominator > 0) { |
| 859 int64 interval_micros = |
| 860 static_cast<int64>(1000000 * numerator) / denominator; |
| 861 interval = base::TimeDelta::FromMicroseconds(interval_micros); |
| 862 } |
| 863 scoped_completion_runner.Release(); |
| 864 completion_task.Run(true, timebase, interval); |
| 865 TRACE_EVENT2("gpu", "GetPresentationStats", |
| 866 "timebase", timebase.ToInternalValue(), |
| 867 "interval", interval.ToInternalValue()); |
| 868 } |
| 869 |
852 hidden_ = false; | 870 hidden_ = false; |
853 } | 871 } |
854 | 872 |
855 void AcceleratedPresenter::DoSuspend() { | 873 void AcceleratedPresenter::DoSuspend() { |
856 base::AutoLock locked(lock_); | 874 base::AutoLock locked(lock_); |
857 swap_chain_ = NULL; | 875 swap_chain_ = NULL; |
858 } | 876 } |
859 | 877 |
860 void AcceleratedPresenter::DoReleaseSurface() { | 878 void AcceleratedPresenter::DoReleaseSurface() { |
861 base::AutoLock locked(lock_); | 879 base::AutoLock locked(lock_); |
862 source_texture_.Release(); | 880 source_texture_.Release(); |
863 } | 881 } |
864 | 882 |
865 void AcceleratedPresenter::GetPresentationStats(base::TimeTicks* timebase, | 883 bool AcceleratedPresenter::GetPresentationStats(base::TimeTicks* timebase, |
866 uint32* interval_numerator, | 884 uint32* interval_numerator, |
867 uint32* interval_denominator) { | 885 uint32* interval_denominator) { |
868 lock_.AssertAcquired(); | 886 lock_.AssertAcquired(); |
869 | 887 |
870 DWM_TIMING_INFO timing_info; | 888 DWM_TIMING_INFO timing_info; |
871 timing_info.cbSize = sizeof(timing_info); | 889 timing_info.cbSize = sizeof(timing_info); |
872 HRESULT result = DwmGetCompositionTimingInfo(window_, &timing_info); | 890 HRESULT result = DwmGetCompositionTimingInfo(window_, &timing_info); |
873 if (result != S_OK) | 891 if (result != S_OK) |
874 return; | 892 return false; |
875 | 893 |
876 *timebase = base::TimeTicks::FromQPCValue( | 894 *timebase = base::TimeTicks::FromQPCValue( |
877 static_cast<LONGLONG>(timing_info.qpcVBlank)); | 895 static_cast<LONGLONG>(timing_info.qpcVBlank)); |
| 896 // Offset from QPC-space to TimeTicks::Now-space. |
| 897 *timebase += (base::TimeTicks::Now() - base::TimeTicks::HighResNow()); |
| 898 |
878 // Swap the numerator/denominator to convert frequency to period. | 899 // Swap the numerator/denominator to convert frequency to period. |
879 *interval_numerator = timing_info.rateRefresh.uiDenominator; | 900 *interval_numerator = timing_info.rateRefresh.uiDenominator; |
880 *interval_denominator = timing_info.rateRefresh.uiNumerator; | 901 *interval_denominator = timing_info.rateRefresh.uiNumerator; |
| 902 |
| 903 return true; |
881 } | 904 } |
882 | 905 |
883 AcceleratedSurface::AcceleratedSurface(gfx::NativeWindow window) | 906 AcceleratedSurface::AcceleratedSurface(gfx::NativeWindow window) |
884 : presenter_(g_accelerated_presenter_map.Pointer()->CreatePresenter( | 907 : presenter_(g_accelerated_presenter_map.Pointer()->CreatePresenter( |
885 window)) { | 908 window)) { |
886 } | 909 } |
887 | 910 |
888 AcceleratedSurface::~AcceleratedSurface() { | 911 AcceleratedSurface::~AcceleratedSurface() { |
889 g_accelerated_presenter_map.Pointer()->RemovePresenter(presenter_); | 912 g_accelerated_presenter_map.Pointer()->RemovePresenter(presenter_); |
890 presenter_->Invalidate(); | 913 presenter_->Invalidate(); |
891 } | 914 } |
892 | 915 |
893 bool AcceleratedSurface::Present(HDC dc) { | 916 bool AcceleratedSurface::Present(HDC dc) { |
894 return presenter_->Present(dc); | 917 return presenter_->Present(dc); |
895 } | 918 } |
896 | 919 |
897 bool AcceleratedSurface::CopyTo(const gfx::Rect& src_subrect, | 920 bool AcceleratedSurface::CopyTo(const gfx::Rect& src_subrect, |
898 const gfx::Size& dst_size, | 921 const gfx::Size& dst_size, |
899 void* buf) { | 922 void* buf) { |
900 return presenter_->CopyTo(src_subrect, dst_size, buf); | 923 return presenter_->CopyTo(src_subrect, dst_size, buf); |
901 } | 924 } |
902 | 925 |
903 void AcceleratedSurface::Suspend() { | 926 void AcceleratedSurface::Suspend() { |
904 presenter_->Suspend(); | 927 presenter_->Suspend(); |
905 } | 928 } |
906 | 929 |
907 void AcceleratedSurface::WasHidden() { | 930 void AcceleratedSurface::WasHidden() { |
908 presenter_->WasHidden(); | 931 presenter_->WasHidden(); |
909 } | 932 } |
OLD | NEW |