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

Side by Side Diff: ui/gfx/screen_win.cc

Issue 1813493002: COMPLETED PREVIEW Migrate to Display Placement (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@gfxmove
Patch Set: Created 4 years, 9 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
« no previous file with comments | « ui/gfx/gfx_tests.gyp ('k') | ui/gfx/screen_win_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/gfx/screen_win.h" 5 #include "ui/gfx/screen_win.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "ui/gfx/display.h" 11 #include "ui/gfx/display.h"
12 #include "ui/gfx/display_layout.h"
13 #include "ui/gfx/display_layout_builder.h"
12 #include "ui/gfx/geometry/point.h" 14 #include "ui/gfx/geometry/point.h"
13 #include "ui/gfx/geometry/point_conversions.h" 15 #include "ui/gfx/geometry/point_conversions.h"
14 #include "ui/gfx/geometry/rect.h" 16 #include "ui/gfx/geometry/rect.h"
15 #include "ui/gfx/geometry/size.h" 17 #include "ui/gfx/geometry/size.h"
16 #include "ui/gfx/geometry/vector2d.h" 18 #include "ui/gfx/geometry/vector2d.h"
17 #include "ui/gfx/win/display_info.h" 19 #include "ui/gfx/win/display_info.h"
18 #include "ui/gfx/win/dpi.h" 20 #include "ui/gfx/win/dpi.h"
19 #include "ui/gfx/win/rect_util.h" 21 #include "ui/gfx/win/scaling_util.h"
20 #include "ui/gfx/win/screen_win_display.h" 22 #include "ui/gfx/win/screen_win_display.h"
21 23
22 namespace { 24 namespace {
23 25
24 gfx::ScreenWin* g_screen_win_instance = nullptr; 26 gfx::ScreenWin* g_screen_win_instance = nullptr;
25 27
26 std::vector<gfx::win::DisplayInfo>::const_iterator FindTouchingDisplayInfo( 28 std::vector<gfx::win::DisplayInfo>::const_iterator FindTouchingDisplayInfo(
27 const gfx::win::ScreenWinDisplay& screen_win_display, 29 const gfx::win::DisplayInfo& display_info,
28 const std::vector<gfx::win::DisplayInfo>& display_infos) { 30 const std::vector<gfx::win::DisplayInfo>& display_infos) {
29 auto end = display_infos.end(); 31 auto end = display_infos.end();
30 for (auto display_info_iter = display_infos.begin(); 32 for (auto display_info_iter = display_infos.begin();
31 display_info_iter != end; 33 display_info_iter != end;
32 display_info_iter++) { 34 display_info_iter++) {
33 gfx::win::RectEdge edge = 35 if (gfx::win::DisplayInfosTouch(display_info, *display_info_iter))
34 gfx::win::FindTouchingRectEdge(screen_win_display.pixel_bounds(),
35 display_info_iter->screen_rect());
36 if (edge != gfx::win::RectEdge::NONE)
37 return display_info_iter; 36 return display_info_iter;
38 } 37 }
39 return end; 38 return end;
40 } 39 }
41 40
41 gfx::Display CreateDisplayFromDisplayInfo(
42 const gfx::win::DisplayInfo& display_info) {
43 gfx::Display display(display_info.id());
44 float scale_factor = display_info.device_scale_factor();
45 display.set_device_scale_factor(scale_factor);
46 display.set_work_area(
47 gfx::ScaleToEnclosingRect(display_info.screen_work_rect(),
48 1.0f / scale_factor));
49 display.set_bounds(gfx::ScaleToEnclosingRect(display_info.screen_rect(),
50 1.0f / scale_factor));
51 display.set_rotation(display_info.rotation());
52 return display;
53 }
54
42 // Windows historically has had a hard time handling displays of DPIs higher 55 // Windows historically has had a hard time handling displays of DPIs higher
43 // than 96. Handling multiple DPI displays means we have to deal with Windows' 56 // than 96. Handling multiple DPI displays means we have to deal with Windows'
44 // monitor physical coordinates and map into Chrome's DIP coordinates. 57 // monitor physical coordinates and map into Chrome's DIP coordinates.
45 // 58 //
46 // To do this, DisplayInfosToScreenWinDisplays reasons over monitors as a tree 59 // To do this, DisplayInfosToScreenWinDisplays reasons over monitors as a tree
47 // using the primary monitor as the root. Any monitor touching this root is 60 // using the primary monitor as the root. Any monitor touching this root is
48 // considered a child. Subsequent generations are formed similarly, having 61 // considered a child. Subsequent generations are formed similarly, having
49 // preferring parents that are discovered earlier. As a result, if there is a 62 // preferring parents that are discovered earlier. As a result, if there is a
50 // monitor that touches two other monitors, the earliest discovered monitor is 63 // monitor that touches two other monitors, the earliest discovered monitor is
51 // the parent. 64 // the parent.
52 // 65 //
53 // This also presumes that all monitors are connected components. Windows, by UI 66 // This also presumes that all monitors are connected components. Windows, by UI
54 // construction restricts the layout of monitors to connected components except 67 // construction restricts the layout of monitors to connected components except
55 // when DPI virtualization is happening. When this happens, we scale relative 68 // when DPI virtualization is happening. When this happens, we scale relative
56 // to (0, 0) like before. 69 // to (0, 0) like before.
57 // 70 //
58 // All subsequent scaling transformations are performed with respect to the 71 // All subsequent scaling transformations are performed with respect to the
59 // calculated physical-DIP mapping on ScreenWinDisplay. 72 // calculated physical-DIP mapping on ScreenWinDisplay.
60 // 73 //
61 // Note that this does not handle cases where a scaled display may have 74 // Note that this does not handle cases where a scaled display may have
62 // insufficient room to lay out its children. In these cases, a DIP point could 75 // insufficient room to lay out its children. In these cases, a DIP point could
63 // map to multiple screen points due to overlap. The first discovered screen 76 // map to multiple screen points due to overlap. The first discovered screen
64 // will take precedence. 77 // will take precedence.
65 std::vector<gfx::win::ScreenWinDisplay> DisplayInfosToScreenWinDisplays( 78 std::vector<gfx::win::ScreenWinDisplay> DisplayInfosToScreenWinDisplays(
66 const std::vector<gfx::win::DisplayInfo>& display_infos) { 79 const std::vector<gfx::win::DisplayInfo>& display_infos) {
67 std::vector<gfx::win::DisplayInfo> display_infos_remaining = display_infos;
68 80
69 // Seed the primary display to layout all the other displays. 81 // DisplayLayout reasons over gfx::Displays and we need to add on pixel info
70 std::vector<gfx::win::ScreenWinDisplay> screen_win_displays; 82 // after it finishes its layout. As a result, create a vector of displays now
71 for (auto current = display_infos_remaining.begin(); 83 // for mutation to maintain this gfx::Display - gfx::win::DisplayInfo
72 current != display_infos_remaining.end(); 84 // correspondence to construct a ScreenWinDisplay.
73 current++) { 85
74 if (current->screen_rect().origin().IsOrigin()) { 86 // Stage 1: display_infos <--> displays
75 screen_win_displays.push_back(gfx::win::ScreenWinDisplay(*current)); 87 // Stage 2: Layout
76 display_infos_remaining.erase(current); 88 // Stage 3: display_infos + displays -> ScreenWinDisplay
89
90 // Find and extract the primary display.
91 size_t primary_display_index = 0;
92 int64_t primary_display_id = 0;
93 const size_t num_displays = display_infos.size();
94 for (size_t i = 0; i < num_displays; ++i) {
95 if (display_infos[i].screen_rect().origin().IsOrigin()) {
96 primary_display_index = i;
77 break; 97 break;
78 } 98 }
79 } 99 }
80 100
81 // Scale touching display_infos relative to each other. 101 std::vector<gfx::win::DisplayInfo> display_infos_remaining = display_infos;
82 // If the DisplayInfo count doesn't change through one cycle of the loop, it 102 display_infos_remaining.erase(
83 // either means we're done or we have non-touching DisplayInfos in the vector. 103 display_infos_remaining.begin() + primary_display_id);
104 std::vector<gfx::win::DisplayInfo> rooted_display_infos;
105 rooted_display_infos.push_back(display_infos[primary_display_index]);
106 gfx::DisplayLayoutBuilder builder(display_infos[primary_display_id].id());
107
84 size_t display_infos_at_cycle_start = 0; 108 size_t display_infos_at_cycle_start = 0;
85 while ((display_infos_remaining.size() > 0) && 109 while ((display_infos_remaining.size() > 0) &&
86 (display_infos_remaining.size() != display_infos_at_cycle_start)) { 110 (display_infos_remaining.size() != display_infos_at_cycle_start)) {
87 display_infos_at_cycle_start = display_infos_remaining.size(); 111 display_infos_at_cycle_start = display_infos_remaining.size();
88 for (const auto& screen_win_display : screen_win_displays) { 112 for (const auto& rooted_display_info : rooted_display_infos) {
89 auto display_info = FindTouchingDisplayInfo(screen_win_display, 113 auto display_info_iter = FindTouchingDisplayInfo(rooted_display_info,
90 display_infos_remaining); 114 display_infos_remaining);
91 if (display_info != display_infos_remaining.end()) { 115 if (display_info_iter != display_infos_remaining.end()) {
92 screen_win_displays.push_back( 116 builder.AddDisplayPlacement(
93 gfx::win::ScreenWinDisplay(screen_win_display, *display_info)); 117 gfx::win::CalculateDisplayPlacement(rooted_display_info,
94 display_infos_remaining.erase(display_info); 118 *display_info_iter));
119 rooted_display_infos.push_back(*display_info_iter);
120 display_infos_remaining.erase(display_info_iter);
95 break; 121 break;
96 } 122 }
97 } 123 }
98 } 124 }
99 125
100 // Under Windows DPI virtualization, not all display_infos touch, so scale 126 std::vector<gfx::Display> displays;
101 // the remaining display infos relative to the origin. 127 for (const auto& display_info : display_infos)
102 for (const auto& display_info : display_infos_remaining) 128 displays.push_back(CreateDisplayFromDisplayInfo(display_info));
103 screen_win_displays.push_back(gfx::win::ScreenWinDisplay(display_info)); 129
130 scoped_ptr<gfx::DisplayLayout> layout(builder.Build());
131 layout->ApplyToDisplayList(&displays, nullptr, 0);
132
133 std::vector<gfx::win::ScreenWinDisplay> screen_win_displays;
134 for (size_t i = 0; i < num_displays; ++i)
135 screen_win_displays.emplace_back(displays[i], display_infos[i]);
104 136
105 return screen_win_displays; 137 return screen_win_displays;
106 } 138 }
107 139
108 std::vector<gfx::Display> ScreenWinDisplaysToDisplays( 140 std::vector<gfx::Display> ScreenWinDisplaysToDisplays(
109 const std::vector<gfx::win::ScreenWinDisplay>& screen_win_displays) { 141 const std::vector<gfx::win::ScreenWinDisplay>& screen_win_displays) {
110 std::vector<gfx::Display> displays; 142 std::vector<gfx::Display> displays;
111 for (const auto& screen_win_display : screen_win_displays) 143 for (const auto& screen_win_display : screen_win_displays)
112 displays.push_back(screen_win_display.display()); 144 displays.push_back(screen_win_display.display());
113 145
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 template <typename Getter, typename GetterType> 516 template <typename Getter, typename GetterType>
485 gfx::win::ScreenWinDisplay ScreenWin::GetScreenWinDisplayVia(Getter getter, 517 gfx::win::ScreenWinDisplay ScreenWin::GetScreenWinDisplayVia(Getter getter,
486 GetterType value) { 518 GetterType value) {
487 if (!g_screen_win_instance) 519 if (!g_screen_win_instance)
488 return gfx::win::ScreenWinDisplay(); 520 return gfx::win::ScreenWinDisplay();
489 521
490 return (g_screen_win_instance->*getter)(value); 522 return (g_screen_win_instance->*getter)(value);
491 } 523 }
492 524
493 } // namespace gfx 525 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/gfx_tests.gyp ('k') | ui/gfx/screen_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698