OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/direct_composition_surface_win.h" | 5 #include "gpu/ipc/service/direct_composition_surface_win.h" |
6 | 6 |
7 #include <d3d11_1.h> | 7 #include <d3d11_1.h> |
8 #include <dcomptypes.h> | 8 #include <dcomptypes.h> |
9 | 9 |
10 #include <deque> | 10 #include <deque> |
11 | 11 |
12 #include "base/feature_list.h" | 12 #include "base/feature_list.h" |
13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
14 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
15 #include "base/optional.h" | 15 #include "base/optional.h" |
16 #include "base/synchronization/waitable_event.h" | 16 #include "base/synchronization/waitable_event.h" |
17 #include "base/trace_event/trace_event.h" | 17 #include "base/trace_event/trace_event.h" |
18 #include "base/win/scoped_handle.h" | 18 #include "base/win/scoped_handle.h" |
19 #include "base/win/windows_version.h" | 19 #include "base/win/windows_version.h" |
20 #include "gpu/command_buffer/service/feature_info.h" | |
20 #include "gpu/ipc/service/gpu_channel_manager.h" | 21 #include "gpu/ipc/service/gpu_channel_manager.h" |
21 #include "gpu/ipc/service/gpu_channel_manager_delegate.h" | 22 #include "gpu/ipc/service/gpu_channel_manager_delegate.h" |
22 #include "gpu/ipc/service/switches.h" | 23 #include "gpu/ipc/service/switches.h" |
23 #include "ui/display/display_switches.h" | 24 #include "ui/display/display_switches.h" |
24 #include "ui/gfx/color_space_win.h" | 25 #include "ui/gfx/color_space_win.h" |
25 #include "ui/gfx/geometry/size_conversions.h" | 26 #include "ui/gfx/geometry/size_conversions.h" |
26 #include "ui/gfx/native_widget_types.h" | 27 #include "ui/gfx/native_widget_types.h" |
27 #include "ui/gfx/transform.h" | 28 #include "ui/gfx/transform.h" |
28 #include "ui/gl/dc_renderer_layer_params.h" | 29 #include "ui/gl/dc_renderer_layer_params.h" |
29 #include "ui/gl/egl_util.h" | 30 #include "ui/gl/egl_util.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
98 bool valid() const { return presents_.size() >= kPresentsToStore; } | 99 bool valid() const { return presents_.size() >= kPresentsToStore; } |
99 int composed_count() const { return composed_count_; } | 100 int composed_count() const { return composed_count_; } |
100 | 101 |
101 private: | 102 private: |
102 std::deque<DXGI_FRAME_PRESENTATION_MODE> presents_; | 103 std::deque<DXGI_FRAME_PRESENTATION_MODE> presents_; |
103 int composed_count_ = 0; | 104 int composed_count_ = 0; |
104 | 105 |
105 DISALLOW_COPY_AND_ASSIGN(PresentationHistory); | 106 DISALLOW_COPY_AND_ASSIGN(PresentationHistory); |
106 }; | 107 }; |
107 | 108 |
109 gfx::Size g_overlay_monitor_size; | |
110 | |
108 // This is the raw support info, which shouldn't depend on field trial state. | 111 // This is the raw support info, which shouldn't depend on field trial state. |
109 bool HardwareSupportsOverlays() { | 112 bool HardwareSupportsOverlays() { |
110 if (!gl::GLSurfaceEGL::IsDirectCompositionSupported()) | 113 if (!gl::GLSurfaceEGL::IsDirectCompositionSupported()) |
111 return false; | 114 return false; |
112 | 115 |
113 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 116 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
114 if (command_line->HasSwitch(switches::kEnableDirectCompositionLayers)) | 117 if (command_line->HasSwitch(switches::kEnableDirectCompositionLayers)) |
115 return true; | 118 return true; |
116 if (command_line->HasSwitch(switches::kDisableDirectCompositionLayers)) | 119 if (command_line->HasSwitch(switches::kDisableDirectCompositionLayers)) |
117 return false; | 120 return false; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
150 | 153 |
151 UMA_HISTOGRAM_SPARSE_SLOWLY("GPU.DirectComposition.OverlaySupportFlags", | 154 UMA_HISTOGRAM_SPARSE_SLOWLY("GPU.DirectComposition.OverlaySupportFlags", |
152 flags); | 155 flags); |
153 | 156 |
154 // Some new Intel drivers only claim to support unscaled overlays, but | 157 // Some new Intel drivers only claim to support unscaled overlays, but |
155 // scaled overlays still work. Even when scaled overlays aren't actually | 158 // scaled overlays still work. Even when scaled overlays aren't actually |
156 // supported, presentation using the overlay path should be relatively | 159 // supported, presentation using the overlay path should be relatively |
157 // efficient. | 160 // efficient. |
158 if (flags & (DXGI_OVERLAY_SUPPORT_FLAG_SCALING | | 161 if (flags & (DXGI_OVERLAY_SUPPORT_FLAG_SCALING | |
159 DXGI_OVERLAY_SUPPORT_FLAG_DIRECT)) { | 162 DXGI_OVERLAY_SUPPORT_FLAG_DIRECT)) { |
163 DXGI_OUTPUT_DESC monitor_desc = {}; | |
164 if (FAILED(output3->GetDesc(&monitor_desc))) | |
165 continue; | |
166 g_overlay_monitor_size = | |
167 gfx::Rect(monitor_desc.DesktopCoordinates).size(); | |
160 return true; | 168 return true; |
161 } | 169 } |
162 } | 170 } |
163 return false; | 171 return false; |
164 } | 172 } |
165 | 173 |
166 // Only one DirectComposition surface can be rendered into at a time. Track | 174 // Only one DirectComposition surface can be rendered into at a time. Track |
167 // here which IDCompositionSurface is being rendered into. If another context | 175 // here which IDCompositionSurface is being rendered into. If another context |
168 // is made current, then this surface will be suspended. | 176 // is made current, then this surface will be suspended. |
169 IDCompositionSurface* g_current_surface; | 177 IDCompositionSurface* g_current_surface; |
(...skipping 18 matching lines...) Expand all Loading... | |
188 const base::win::ScopedComPtr<ID3D11VideoProcessor>& video_processor() const { | 196 const base::win::ScopedComPtr<ID3D11VideoProcessor>& video_processor() const { |
189 return video_processor_; | 197 return video_processor_; |
190 } | 198 } |
191 const base::win::ScopedComPtr<ID3D11VideoProcessorEnumerator>& | 199 const base::win::ScopedComPtr<ID3D11VideoProcessorEnumerator>& |
192 video_processor_enumerator() const { | 200 video_processor_enumerator() const { |
193 return video_processor_enumerator_; | 201 return video_processor_enumerator_; |
194 } | 202 } |
195 base::win::ScopedComPtr<IDXGISwapChain1> GetLayerSwapChainForTesting( | 203 base::win::ScopedComPtr<IDXGISwapChain1> GetLayerSwapChainForTesting( |
196 size_t index) const; | 204 size_t index) const; |
197 | 205 |
206 const GpuDriverBugWorkarounds& workarounds() const { | |
207 return surface_->workarounds(); | |
208 } | |
209 | |
198 private: | 210 private: |
199 class SwapChainPresenter; | 211 class SwapChainPresenter; |
200 | 212 |
201 // This struct is used to cache information about what visuals are currently | 213 // This struct is used to cache information about what visuals are currently |
202 // being presented so that properties that aren't changed aren't sent to | 214 // being presented so that properties that aren't changed aren't sent to |
203 // DirectComposition. | 215 // DirectComposition. |
204 struct VisualInfo { | 216 struct VisualInfo { |
205 base::win::ScopedComPtr<IDCompositionVisual2> content_visual; | 217 base::win::ScopedComPtr<IDCompositionVisual2> content_visual; |
206 base::win::ScopedComPtr<IDCompositionVisual2> clip_visual; | 218 base::win::ScopedComPtr<IDCompositionVisual2> clip_visual; |
207 | 219 |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
621 TRUE, &source_rect); | 633 TRUE, &source_rect); |
622 | 634 |
623 video_context_->VideoProcessorSetStreamAutoProcessingMode( | 635 video_context_->VideoProcessorSetStreamAutoProcessingMode( |
624 video_processor_.Get(), 0, FALSE); | 636 video_processor_.Get(), 0, FALSE); |
625 | 637 |
626 hr = video_context_->VideoProcessorBlt(video_processor_.Get(), | 638 hr = video_context_->VideoProcessorBlt(video_processor_.Get(), |
627 out_view_.Get(), 0, 1, &stream); | 639 out_view_.Get(), 0, 1, &stream); |
628 CHECK(SUCCEEDED(hr)); | 640 CHECK(SUCCEEDED(hr)); |
629 } | 641 } |
630 | 642 |
643 if (surface_->workarounds().disable_larger_than_screen_overlays) { | |
644 // Because of the rounding when converting between pixels and DIPs, a | |
645 // fullscreen video can become slightly larger than the monitor - e.g. on | |
646 // a 3000x2000 monitor with a scale factor of 1.75 a 1920x1079 video can | |
647 // become 3002x1689. | |
648 // On older Intel drivers, swapchains that are bigger than the monitor | |
649 // won't be put into overlays, which will hurt power usage a lot. On those | |
650 // systems, the scaling can be adjusted very slightly so that it's less | |
651 // than the monitor size. This should be close to imperceptible. | |
652 // TODO(jbauman): Remove when http://crbug.com/668278 is fixed. | |
653 const int kOversizeMargin = 3; | |
654 | |
655 if ((bounds_rect.x() >= 0) && | |
sunnyps
2017/05/16 00:00:44
nit: what's the reason for the x/y checks? instead
| |
656 (bounds_rect.width() > g_overlay_monitor_size.width()) && | |
657 (bounds_rect.width() <= | |
658 g_overlay_monitor_size.width() + kOversizeMargin)) { | |
659 bounds_rect.set_width(g_overlay_monitor_size.width()); | |
660 } | |
661 | |
662 if ((bounds_rect.y() >= 0) && | |
663 (bounds_rect.height() > g_overlay_monitor_size.height()) && | |
664 (bounds_rect.height() <= | |
665 g_overlay_monitor_size.height() + kOversizeMargin)) { | |
666 bounds_rect.set_height(g_overlay_monitor_size.height()); | |
667 } | |
668 } | |
669 | |
631 swap_chain_scale_x_ = bounds_rect.width() * 1.0f / swap_chain_size.width(); | 670 swap_chain_scale_x_ = bounds_rect.width() * 1.0f / swap_chain_size.width(); |
632 swap_chain_scale_y_ = bounds_rect.height() * 1.0f / swap_chain_size.height(); | 671 swap_chain_scale_y_ = bounds_rect.height() * 1.0f / swap_chain_size.height(); |
633 | 672 |
634 if (first_present) { | 673 if (first_present) { |
635 swap_chain_->Present(0, 0); | 674 swap_chain_->Present(0, 0); |
636 | 675 |
637 // DirectComposition can display black for a swapchain between the first | 676 // DirectComposition can display black for a swapchain between the first |
638 // and second time it's presented to - maybe the first Present can get | 677 // and second time it's presented to - maybe the first Present can get |
639 // lost somehow and it shows the wrong buffer. In that case copy the | 678 // lost somehow and it shows the wrong buffer. In that case copy the |
640 // buffers so both have the correct contents, which seems to help. The | 679 // buffers so both have the correct contents, which seems to help. The |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
941 base::MakeUnique<ui::DCRendererLayerParams>(params)); | 980 base::MakeUnique<ui::DCRendererLayerParams>(params)); |
942 return true; | 981 return true; |
943 } | 982 } |
944 | 983 |
945 DirectCompositionSurfaceWin::DirectCompositionSurfaceWin( | 984 DirectCompositionSurfaceWin::DirectCompositionSurfaceWin( |
946 std::unique_ptr<gfx::VSyncProvider> vsync_provider, | 985 std::unique_ptr<gfx::VSyncProvider> vsync_provider, |
947 base::WeakPtr<ImageTransportSurfaceDelegate> delegate, | 986 base::WeakPtr<ImageTransportSurfaceDelegate> delegate, |
948 HWND parent_window) | 987 HWND parent_window) |
949 : gl::GLSurfaceEGL(), | 988 : gl::GLSurfaceEGL(), |
950 child_window_(delegate, parent_window), | 989 child_window_(delegate, parent_window), |
990 workarounds_(delegate->GetFeatureInfo()->workarounds()), | |
951 vsync_provider_(std::move(vsync_provider)) {} | 991 vsync_provider_(std::move(vsync_provider)) {} |
952 | 992 |
953 DirectCompositionSurfaceWin::~DirectCompositionSurfaceWin() { | 993 DirectCompositionSurfaceWin::~DirectCompositionSurfaceWin() { |
954 Destroy(); | 994 Destroy(); |
955 } | 995 } |
956 | 996 |
957 // static | 997 // static |
958 bool DirectCompositionSurfaceWin::AreOverlaysSupported() { | 998 bool DirectCompositionSurfaceWin::AreOverlaysSupported() { |
959 if (!HardwareSupportsOverlays()) | 999 if (!HardwareSupportsOverlays()) |
960 return false; | 1000 return false; |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1280 DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() { | 1320 DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() { |
1281 return child_window_.GetTaskRunnerForTesting(); | 1321 return child_window_.GetTaskRunnerForTesting(); |
1282 } | 1322 } |
1283 | 1323 |
1284 base::win::ScopedComPtr<IDXGISwapChain1> | 1324 base::win::ScopedComPtr<IDXGISwapChain1> |
1285 DirectCompositionSurfaceWin::GetLayerSwapChainForTesting(size_t index) const { | 1325 DirectCompositionSurfaceWin::GetLayerSwapChainForTesting(size_t index) const { |
1286 return layer_tree_->GetLayerSwapChainForTesting(index); | 1326 return layer_tree_->GetLayerSwapChainForTesting(index); |
1287 } | 1327 } |
1288 | 1328 |
1289 } // namespace gpu | 1329 } // namespace gpu |
OLD | NEW |