Chromium Code Reviews| 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 "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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |