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

Side by Side Diff: ash/display/display_manager.cc

Issue 1845723002: Allow unified desktop for 3+ displays (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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 | « no previous file | ash/display/display_manager_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 "ash/display/display_manager.h" 5 #include "ash/display/display_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
(...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 DisplayInfo* info = &display_info_[gfx::Display::InternalDisplayId()]; 1073 DisplayInfo* info = &display_info_[gfx::Display::InternalDisplayId()];
1074 SetInternalDisplayModeList(info); 1074 SetInternalDisplayModeList(info);
1075 } 1075 }
1076 1076
1077 void DisplayManager::CreateSoftwareMirroringDisplayInfo( 1077 void DisplayManager::CreateSoftwareMirroringDisplayInfo(
1078 DisplayInfoList* display_info_list) { 1078 DisplayInfoList* display_info_list) {
1079 // Use the internal display or 1st as the mirror source, then scale 1079 // Use the internal display or 1st as the mirror source, then scale
1080 // the root window so that it matches the external display's 1080 // the root window so that it matches the external display's
1081 // resolution. This is necessary in order for scaling to work while 1081 // resolution. This is necessary in order for scaling to work while
1082 // mirrored. 1082 // mirrored.
1083 if (display_info_list->size() == 2) { 1083 switch (multi_display_mode_) {
1084 switch (multi_display_mode_) { 1084 case MIRRORING: {
1085 case MIRRORING: { 1085 DCHECK_EQ(2u, display_info_list->size());
oshima 2016/03/30 22:01:32 This check does not work when hard ware mirroring
1086 bool zero_is_source = 1086 if (display_info_list->size() != 2)
1087 first_display_id_ == (*display_info_list)[0].id() || 1087 return;
oshima 2016/03/30 21:00:05 This CL just moved this change from 1083. The rest
1088 gfx::Display::IsInternalDisplayId((*display_info_list)[0].id()); 1088 bool zero_is_source =
1089 DCHECK_EQ(MIRRORING, multi_display_mode_); 1089 first_display_id_ == (*display_info_list)[0].id() ||
1090 mirroring_display_id_ = 1090 gfx::Display::IsInternalDisplayId((*display_info_list)[0].id());
1091 (*display_info_list)[zero_is_source ? 1 : 0].id(); 1091 DCHECK_EQ(MIRRORING, multi_display_mode_);
1092 mirroring_display_id_ = (*display_info_list)[zero_is_source ? 1 : 0].id();
1092 1093
1093 int64_t display_id = mirroring_display_id_; 1094 int64_t display_id = mirroring_display_id_;
1094 auto iter = 1095 auto iter =
1095 std::find_if(display_info_list->begin(), display_info_list->end(), 1096 std::find_if(display_info_list->begin(), display_info_list->end(),
1096 [display_id](const DisplayInfo& info) { 1097 [display_id](const DisplayInfo& info) {
1097 return info.id() == display_id; 1098 return info.id() == display_id;
1098 }); 1099 });
1099 DCHECK(iter != display_info_list->end()); 1100 DCHECK(iter != display_info_list->end());
1100 1101
1101 DisplayInfo info = *iter; 1102 DisplayInfo info = *iter;
1102 info.SetOverscanInsets(gfx::Insets()); 1103 info.SetOverscanInsets(gfx::Insets());
1104 InsertAndUpdateDisplayInfo(info);
1105 software_mirroring_display_list_.push_back(
1106 CreateMirroringDisplayFromDisplayInfoById(mirroring_display_id_,
1107 gfx::Point(), 1.0f));
1108 display_info_list->erase(iter);
1109 break;
1110 }
1111 case UNIFIED: {
1112 // TODO(oshima): Currently, all displays are laid out horizontally,
1113 // from left to right. Allow more flexible layouts, such as
1114 // right to left, or vertical layouts.
1115 gfx::Rect unified_bounds;
1116 software_mirroring_display_list_.clear();
1117 // 1st Pass. Find the max size.
1118 int max_height = std::numeric_limits<int>::min();
1119
1120 int default_height = 0;
1121 float default_device_scale_factor = 1.0f;
1122 for (auto& info : *display_info_list) {
1123 max_height = std::max(max_height, info.size_in_pixel().height());
1124 if (!default_height || gfx::Display::IsInternalDisplayId(info.id())) {
1125 default_height = info.size_in_pixel().height();
1126 default_device_scale_factor = info.device_scale_factor();
1127 }
1128 }
1129
1130 std::vector<DisplayMode> display_mode_list;
1131 std::set<std::pair<float, float>> dsf_scale_list;
1132
1133 // 2nd Pass. Compute the unified display size.
1134 for (auto& info : *display_info_list) {
1103 InsertAndUpdateDisplayInfo(info); 1135 InsertAndUpdateDisplayInfo(info);
1104 software_mirroring_display_list_.push_back( 1136 gfx::Point origin(unified_bounds.right(), 0);
1105 CreateMirroringDisplayFromDisplayInfoById(mirroring_display_id_, 1137 float scale =
1106 gfx::Point(), 1.0f)); 1138 info.size_in_pixel().height() / static_cast<float>(max_height);
1107 display_info_list->erase(iter); 1139 // The display is scaled to fit the unified desktop size.
1108 break; 1140 gfx::Display display = CreateMirroringDisplayFromDisplayInfoById(
1141 info.id(), origin, 1.0f / scale);
1142 unified_bounds.Union(display.bounds());
1143
1144 dsf_scale_list.insert(
1145 std::make_pair(info.device_scale_factor(), scale));
1109 } 1146 }
1110 case UNIFIED: {
1111 // TODO(oshima): Currently, all displays are laid out horizontally,
1112 // from left to right. Allow more flexible layouts, such as
1113 // right to left, or vertical layouts.
1114 gfx::Rect unified_bounds;
1115 software_mirroring_display_list_.clear();
1116 1147
1117 // 1st Pass. Find the max size. 1148 DisplayInfo info(kUnifiedDisplayId, "Unified Desktop", false);
1118 int max_height = std::numeric_limits<int>::min();
1119 1149
1120 int default_height = 0; 1150 DisplayMode native_mode(unified_bounds.size(), 60.0f, false, true);
1121 float default_device_scale_factor = 1.0f; 1151 std::vector<DisplayMode> modes =
1122 for (auto& info : *display_info_list) { 1152 CreateUnifiedDisplayModeList(native_mode, dsf_scale_list);
1123 max_height = std::max(max_height, info.size_in_pixel().height());
1124 if (!default_height || gfx::Display::IsInternalDisplayId(info.id())) {
1125 default_height = info.size_in_pixel().height();
1126 default_device_scale_factor = info.device_scale_factor();
1127 }
1128 }
1129 1153
1130 std::vector<DisplayMode> display_mode_list; 1154 // Find the default mode.
1131 std::set<std::pair<float, float>> dsf_scale_list; 1155 auto iter = std::find_if(
1156 modes.begin(), modes.end(),
1157 [default_height,
1158 default_device_scale_factor](const DisplayMode& mode) {
1159 return mode.size.height() == default_height &&
1160 mode.device_scale_factor == default_device_scale_factor;
1161 });
1162 iter->native = true;
1163 info.SetDisplayModes(modes);
1164 info.set_device_scale_factor(iter->device_scale_factor);
1165 info.SetBounds(gfx::Rect(iter->size));
1132 1166
1133 // 2nd Pass. Compute the unified display size. 1167 // Forget the configured resolution if the original unified
1134 for (auto& info : *display_info_list) { 1168 // desktop resolution has changed.
1135 InsertAndUpdateDisplayInfo(info); 1169 if (display_info_.count(kUnifiedDisplayId) != 0 &&
1136 gfx::Point origin(unified_bounds.right(), 0); 1170 GetMaxNativeSize(display_info_[kUnifiedDisplayId]) !=
1137 float scale = 1171 unified_bounds.size()) {
1138 info.size_in_pixel().height() / static_cast<float>(max_height); 1172 display_modes_.erase(kUnifiedDisplayId);
1139 // The display is scaled to fit the unified desktop size. 1173 }
1140 gfx::Display display = CreateMirroringDisplayFromDisplayInfoById(
1141 info.id(), origin, 1.0f / scale);
1142 unified_bounds.Union(display.bounds());
1143 1174
1144 dsf_scale_list.insert( 1175 // 3rd Pass. Set the selected mode, then recompute the mirroring
1145 std::make_pair(info.device_scale_factor(), scale)); 1176 // display size.
1146 } 1177 DisplayMode mode;
1178 if (GetSelectedModeForDisplayId(kUnifiedDisplayId, &mode) &&
1179 FindDisplayMode(info, mode) != info.display_modes().end()) {
1180 info.set_device_scale_factor(mode.device_scale_factor);
1181 info.SetBounds(gfx::Rect(mode.size));
1182 } else {
1183 display_modes_.erase(kUnifiedDisplayId);
1184 }
1147 1185
1148 DisplayInfo info(kUnifiedDisplayId, "Unified Desktop", false); 1186 int unified_display_height = info.size_in_pixel().height();
1187 gfx::Point origin;
1188 for (auto& info : *display_info_list) {
1189 float display_scale = info.size_in_pixel().height() /
1190 static_cast<float>(unified_display_height);
1191 gfx::Display display = CreateMirroringDisplayFromDisplayInfoById(
1192 info.id(), origin, 1.0f / display_scale);
1193 origin.Offset(display.size().width(), 0);
1194 display.UpdateWorkAreaFromInsets(gfx::Insets());
1195 software_mirroring_display_list_.push_back(display);
1196 }
1149 1197
1150 DisplayMode native_mode(unified_bounds.size(), 60.0f, false, true); 1198 display_info_list->clear();
1151 std::vector<DisplayMode> modes = 1199 display_info_list->push_back(info);
1152 CreateUnifiedDisplayModeList(native_mode, dsf_scale_list); 1200 InsertAndUpdateDisplayInfo(info);
1153 1201 break;
1154 // Find the default mode.
1155 auto iter = std::find_if(
1156 modes.begin(), modes.end(),
1157 [default_height,
1158 default_device_scale_factor](const DisplayMode& mode) {
1159 return mode.size.height() == default_height &&
1160 mode.device_scale_factor == default_device_scale_factor;
1161 });
1162 iter->native = true;
1163 info.SetDisplayModes(modes);
1164 info.set_device_scale_factor(iter->device_scale_factor);
1165 info.SetBounds(gfx::Rect(iter->size));
1166
1167 // Forget the configured resolution if the original unified
1168 // desktop resolution has changed.
1169 if (display_info_.count(kUnifiedDisplayId) != 0 &&
1170 GetMaxNativeSize(display_info_[kUnifiedDisplayId]) !=
1171 unified_bounds.size()) {
1172 display_modes_.erase(kUnifiedDisplayId);
1173 }
1174
1175 // 3rd Pass. Set the selected mode, then recompute the mirroring
1176 // display size.
1177 DisplayMode mode;
1178 if (GetSelectedModeForDisplayId(kUnifiedDisplayId, &mode) &&
1179 FindDisplayMode(info, mode) != info.display_modes().end()) {
1180 info.set_device_scale_factor(mode.device_scale_factor);
1181 info.SetBounds(gfx::Rect(mode.size));
1182 } else {
1183 display_modes_.erase(kUnifiedDisplayId);
1184 }
1185
1186 int unified_display_height = info.size_in_pixel().height();
1187 gfx::Point origin;
1188 for (auto& info : *display_info_list) {
1189 float display_scale = info.size_in_pixel().height() /
1190 static_cast<float>(unified_display_height);
1191 gfx::Display display = CreateMirroringDisplayFromDisplayInfoById(
1192 info.id(), origin, 1.0f / display_scale);
1193 origin.Offset(display.size().width(), 0);
1194 display.UpdateWorkAreaFromInsets(gfx::Insets());
1195 software_mirroring_display_list_.push_back(display);
1196 }
1197
1198 display_info_list->clear();
1199 display_info_list->push_back(info);
1200 InsertAndUpdateDisplayInfo(info);
1201 break;
1202 }
1203 case EXTENDED:
1204 break;
1205 } 1202 }
1206 } 1203 case EXTENDED:
1204 break;
1205 }
1207 } 1206 }
1208 1207
1209 gfx::Display* DisplayManager::FindDisplayForId(int64_t id) { 1208 gfx::Display* DisplayManager::FindDisplayForId(int64_t id) {
1210 auto iter = std::find_if( 1209 auto iter = std::find_if(
1211 active_display_list_.begin(), active_display_list_.end(), 1210 active_display_list_.begin(), active_display_list_.end(),
1212 [id](const gfx::Display& display) { return display.id() == id; }); 1211 [id](const gfx::Display& display) { return display.id() == id; });
1213 if (iter != active_display_list_.end()) 1212 if (iter != active_display_list_.end())
1214 return &(*iter); 1213 return &(*iter);
1215 // TODO(oshima): This happens when a windows in unified desktop have 1214 // TODO(oshima): This happens when a windows in unified desktop have
1216 // been moved to normal window. Fix this. 1215 // been moved to normal window. Fix this.
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1395 1394
1396 return old_bounds != target_display->bounds(); 1395 return old_bounds != target_display->bounds();
1397 } 1396 }
1398 1397
1399 void DisplayManager::RunPendingTasksForTest() { 1398 void DisplayManager::RunPendingTasksForTest() {
1400 if (!software_mirroring_display_list_.empty()) 1399 if (!software_mirroring_display_list_.empty())
1401 base::RunLoop().RunUntilIdle(); 1400 base::RunLoop().RunUntilIdle();
1402 } 1401 }
1403 1402
1404 } // namespace ash 1403 } // namespace ash
OLDNEW
« no previous file with comments | « no previous file | ash/display/display_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698