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

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

Issue 2884843002: Slightly modify sizes of overlays that are larger than the monitor (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
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « gpu/ipc/service/direct_composition_surface_win.h ('k') | gpu/ipc/service/direct_composition_surface_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698