| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "services/ui/display/platform_screen_ozone.h" | 5 #include "services/ui/display/platform_screen_ozone.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/sys_info.h" | 12 #include "base/sys_info.h" |
| 13 #include "base/threading/thread_task_runner_handle.h" | 13 #include "base/threading/thread_task_runner_handle.h" |
| 14 #include "services/shell/public/cpp/interface_registry.h" | 14 #include "services/shell/public/cpp/interface_registry.h" |
| 15 #include "third_party/skia/include/core/SkColor.h" | 15 #include "third_party/skia/include/core/SkColor.h" |
| 16 #include "ui/display/types/display_constants.h" | 16 #include "ui/display/types/display_constants.h" |
| 17 #include "ui/display/types/display_snapshot.h" | 17 #include "ui/display/types/display_snapshot.h" |
| 18 #include "ui/display/types/native_display_delegate.h" | 18 #include "ui/display/types/native_display_delegate.h" |
| 19 #include "ui/gfx/geometry/rect.h" | 19 #include "ui/gfx/geometry/rect.h" |
| 20 #include "ui/ozone/public/ozone_platform.h" | 20 #include "ui/ozone/public/ozone_platform.h" |
| 21 | 21 |
| 22 namespace display { | 22 namespace display { |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 // Needed for DisplayConfigurator::ForceInitialConfigure. | 25 // Needed for DisplayConfigurator::ForceInitialConfigure. |
| 26 const SkColor kChromeOsBootColor = SkColorSetRGB(0xfe, 0xfe, 0xfe); | 26 const SkColor kChromeOsBootColor = SkColorSetRGB(0xfe, 0xfe, 0xfe); |
| 27 | 27 |
| 28 const float kInchInMm = 25.4f; |
| 29 |
| 30 float ComputeDisplayDPI(const gfx::Size& pixel_size, |
| 31 const gfx::Size& physical_size) { |
| 32 DCHECK(!physical_size.IsEmpty()); |
| 33 return (pixel_size.width() / static_cast<float>(physical_size.width())) * |
| 34 kInchInMm; |
| 35 } |
| 36 |
| 37 // Finds the device scale factor based on the display DPI. Will use forced |
| 38 // device scale factor if provided via command line. |
| 39 float FindDeviceScaleFactor(float dpi) { |
| 40 if (Display::HasForceDeviceScaleFactor()) |
| 41 return Display::GetForcedDeviceScaleFactor(); |
| 42 |
| 43 // TODO(kylechar): If dpi > 150 then ash uses 1.25 now. Ignoring that for now. |
| 44 if (dpi > 200.0) |
| 45 return 2.0f; |
| 46 else |
| 47 return 1.0f; |
| 48 } |
| 49 |
| 28 } // namespace | 50 } // namespace |
| 29 | 51 |
| 30 // static | 52 // static |
| 31 std::unique_ptr<PlatformScreen> PlatformScreen::Create() { | 53 std::unique_ptr<PlatformScreen> PlatformScreen::Create() { |
| 32 return base::MakeUnique<PlatformScreenOzone>(); | 54 return base::MakeUnique<PlatformScreenOzone>(); |
| 33 } | 55 } |
| 34 | 56 |
| 35 PlatformScreenOzone::PlatformScreenOzone() {} | 57 PlatformScreenOzone::PlatformScreenOzone() {} |
| 36 | 58 |
| 37 PlatformScreenOzone::~PlatformScreenOzone() { | 59 PlatformScreenOzone::~PlatformScreenOzone() { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 | 101 |
| 80 int64_t PlatformScreenOzone::GetPrimaryDisplayId() const { | 102 int64_t PlatformScreenOzone::GetPrimaryDisplayId() const { |
| 81 return primary_display_id_; | 103 return primary_display_id_; |
| 82 } | 104 } |
| 83 | 105 |
| 84 void PlatformScreenOzone::ToggleVirtualDisplay() { | 106 void PlatformScreenOzone::ToggleVirtualDisplay() { |
| 85 if (!fake_display_controller_ || wait_for_display_config_update_) | 107 if (!fake_display_controller_ || wait_for_display_config_update_) |
| 86 return; | 108 return; |
| 87 | 109 |
| 88 if (cached_displays_.size() == 1) { | 110 if (cached_displays_.size() == 1) { |
| 89 const gfx::Size& display_size = cached_displays_[0].bounds.size(); | 111 const gfx::Size& pixel_size = cached_displays_[0].pixel_size; |
| 90 wait_for_display_config_update_ = | 112 wait_for_display_config_update_ = |
| 91 fake_display_controller_->AddDisplay(display_size) != | 113 fake_display_controller_->AddDisplay(pixel_size) != |
| 92 Display::kInvalidDisplayID; | 114 Display::kInvalidDisplayID; |
| 93 } else if (cached_displays_.size() > 1) { | 115 } else if (cached_displays_.size() > 1) { |
| 94 wait_for_display_config_update_ = | 116 wait_for_display_config_update_ = |
| 95 fake_display_controller_->RemoveDisplay(cached_displays_.back().id); | 117 fake_display_controller_->RemoveDisplay(cached_displays_.back().id); |
| 96 } else { | 118 } else { |
| 97 NOTREACHED(); | 119 NOTREACHED(); |
| 98 } | 120 } |
| 99 } | 121 } |
| 100 | 122 |
| 101 void PlatformScreenOzone::ProcessRemovedDisplays( | 123 void PlatformScreenOzone::ProcessRemovedDisplays( |
| 102 const ui::DisplayConfigurator::DisplayStateList& snapshots) { | 124 const ui::DisplayConfigurator::DisplayStateList& snapshots) { |
| 103 std::vector<int64_t> current_ids; | 125 std::vector<int64_t> current_ids; |
| 104 for (ui::DisplaySnapshot* snapshot : snapshots) | 126 for (ui::DisplaySnapshot* snapshot : snapshots) |
| 105 current_ids.push_back(snapshot->display_id()); | 127 current_ids.push_back(snapshot->display_id()); |
| 106 | 128 |
| 107 // Find cached displays with no matching snapshot and mark as removed. | 129 // Find cached displays with no matching snapshot and mark as removed. |
| 108 for (DisplayInfo& display : cached_displays_) { | 130 for (DisplayInfo& display : cached_displays_) { |
| 109 if (std::find(current_ids.begin(), current_ids.end(), display.id) == | 131 if (std::find(current_ids.begin(), current_ids.end(), display.id) == |
| 110 current_ids.end()) { | 132 current_ids.end()) { |
| 111 display.removed = true; | 133 display.removed = true; |
| 112 if (primary_display_id_ == display.id) | 134 if (primary_display_id_ == display.id) |
| 113 primary_display_id_ = display::Display::kInvalidDisplayID; | 135 primary_display_id_ = Display::kInvalidDisplayID; |
| 114 } | 136 } |
| 115 } | 137 } |
| 116 | 138 |
| 117 // If the primary display was removed find a new primary display id. | 139 // If the primary display was removed find a new primary display id. |
| 118 if (primary_display_id_ == display::Display::kInvalidDisplayID) { | 140 if (primary_display_id_ == Display::kInvalidDisplayID) { |
| 119 for (const DisplayInfo& display : cached_displays_) { | 141 for (const DisplayInfo& display : cached_displays_) { |
| 120 if (!display.removed) { | 142 if (!display.removed) { |
| 121 primary_display_id_ = display.id; | 143 primary_display_id_ = display.id; |
| 122 break; | 144 break; |
| 123 } | 145 } |
| 124 } | 146 } |
| 125 } | 147 } |
| 126 } | 148 } |
| 127 | 149 |
| 128 void PlatformScreenOzone::ProcessModifiedDisplays( | 150 void PlatformScreenOzone::ProcessModifiedDisplays( |
| 129 const ui::DisplayConfigurator::DisplayStateList& snapshots) { | 151 const ui::DisplayConfigurator::DisplayStateList& snapshots) { |
| 130 for (ui::DisplaySnapshot* snapshot : snapshots) { | 152 for (ui::DisplaySnapshot* snapshot : snapshots) { |
| 131 auto iter = GetCachedDisplayIterator(snapshot->display_id()); | 153 auto iter = GetCachedDisplayIterator(snapshot->display_id()); |
| 132 if (iter != cached_displays_.end()) { | 154 if (iter != cached_displays_.end()) { |
| 133 DisplayInfo& display_info = *iter; | 155 DisplayInfo& display_info = *iter; |
| 134 const ui::DisplayMode* current_mode = snapshot->current_mode(); | 156 DisplayInfo new_info = DisplayInfoFromSnapshot(*snapshot); |
| 135 if (current_mode->size() != display_info.bounds.size()) { | 157 |
| 136 display_info.bounds.set_size(current_mode->size()); | 158 if (new_info.bounds.size() != display_info.bounds.size() || |
| 159 new_info.device_scale_factor != display_info.device_scale_factor) { |
| 160 display_info = new_info; |
| 137 display_info.modified = true; | 161 display_info.modified = true; |
| 138 } | 162 } |
| 139 } | 163 } |
| 140 } | 164 } |
| 141 } | 165 } |
| 142 | 166 |
| 143 void PlatformScreenOzone::UpdateCachedDisplays() { | 167 void PlatformScreenOzone::UpdateCachedDisplays() { |
| 144 // Walk through cached displays after processing the snapshots to find any | 168 // Walk through cached displays after processing the snapshots to find any |
| 145 // removed or modified displays. This ensures that we only send one update per | 169 // removed or modified displays. This ensures that we only send one update per |
| 146 // display to the delegate. | 170 // display to the delegate. |
| 147 next_display_origin_.SetPoint(0, 0); | 171 next_display_origin_.SetPoint(0, 0); |
| 148 for (auto iter = cached_displays_.begin(); iter != cached_displays_.end();) { | 172 for (auto iter = cached_displays_.begin(); iter != cached_displays_.end();) { |
| 149 DisplayInfo& display_info = *iter; | 173 DisplayInfo& display_info = *iter; |
| 150 if (display_info.removed) { | 174 if (display_info.removed) { |
| 151 // Update delegate and remove from cache. | 175 // Update delegate and remove from cache. |
| 152 delegate_->OnDisplayRemoved(display_info.id); | 176 delegate_->OnDisplayRemoved(display_info.id); |
| 153 iter = cached_displays_.erase(iter); | 177 iter = cached_displays_.erase(iter); |
| 154 } else { | 178 } else { |
| 155 // Check if the display origin needs to be updated. | 179 // Check if the display origin needs to be updated. |
| 156 if (next_display_origin_ != display_info.bounds.origin()) { | 180 if (next_display_origin_ != display_info.bounds.origin()) { |
| 157 display_info.bounds.set_origin(next_display_origin_); | 181 display_info.bounds.set_origin(next_display_origin_); |
| 158 display_info.modified = true; | 182 display_info.modified = true; |
| 159 } | 183 } |
| 160 next_display_origin_.Offset(display_info.bounds.width(), 0); | 184 next_display_origin_.Offset(display_info.bounds.width(), 0); |
| 161 | 185 |
| 162 // Check if the window bounds have changed and update delegate. | 186 // Check if the window bounds have changed and update delegate. |
| 163 if (display_info.modified) { | 187 if (display_info.modified) { |
| 164 display_info.modified = false; | 188 display_info.modified = false; |
| 165 delegate_->OnDisplayModified(display_info.id, display_info.bounds); | 189 delegate_->OnDisplayModified(display_info.id, display_info.bounds, |
| 190 display_info.pixel_size, |
| 191 display_info.device_scale_factor); |
| 166 } | 192 } |
| 167 ++iter; | 193 ++iter; |
| 168 } | 194 } |
| 169 } | 195 } |
| 170 } | 196 } |
| 171 | 197 |
| 172 void PlatformScreenOzone::AddNewDisplays( | 198 void PlatformScreenOzone::AddNewDisplays( |
| 173 const ui::DisplayConfigurator::DisplayStateList& snapshots) { | 199 const ui::DisplayConfigurator::DisplayStateList& snapshots) { |
| 174 for (ui::DisplaySnapshot* snapshot : snapshots) { | 200 for (ui::DisplaySnapshot* snapshot : snapshots) { |
| 175 const int64_t id = snapshot->display_id(); | 201 const int64_t id = snapshot->display_id(); |
| 176 | 202 |
| 177 // Check if display already exists and skip. | 203 // Check if display already exists and skip. |
| 178 if (GetCachedDisplayIterator(id) != cached_displays_.end()) | 204 if (GetCachedDisplayIterator(id) != cached_displays_.end()) |
| 179 continue; | 205 continue; |
| 180 | 206 |
| 181 const ui::DisplayMode* current_mode = snapshot->current_mode(); | 207 // If we have no primary display then this one should be it. |
| 182 gfx::Rect bounds(next_display_origin_, current_mode->size()); | 208 if (primary_display_id_ == Display::kInvalidDisplayID) |
| 209 primary_display_id_ = id; |
| 210 |
| 211 DisplayInfo display_info = DisplayInfoFromSnapshot(*snapshot); |
| 183 | 212 |
| 184 // Move the origin so that next display is to the right of current display. | 213 // Move the origin so that next display is to the right of current display. |
| 185 next_display_origin_.Offset(current_mode->size().width(), 0); | 214 next_display_origin_.Offset(display_info.bounds.width(), 0); |
| 186 | 215 |
| 187 // If we have no primary display then this one should be it. | 216 cached_displays_.push_back(display_info); |
| 188 if (primary_display_id_ == display::Display::kInvalidDisplayID) | 217 delegate_->OnDisplayAdded(display_info.id, display_info.bounds, |
| 189 primary_display_id_ = id; | 218 display_info.pixel_size, |
| 190 | 219 display_info.device_scale_factor); |
| 191 cached_displays_.push_back(DisplayInfo(id, bounds)); | |
| 192 delegate_->OnDisplayAdded(id, bounds); | |
| 193 } | 220 } |
| 194 } | 221 } |
| 195 | 222 |
| 196 PlatformScreenOzone::CachedDisplayIterator | 223 PlatformScreenOzone::CachedDisplayIterator |
| 197 PlatformScreenOzone::GetCachedDisplayIterator(int64_t display_id) { | 224 PlatformScreenOzone::GetCachedDisplayIterator(int64_t display_id) { |
| 198 return std::find_if(cached_displays_.begin(), cached_displays_.end(), | 225 return std::find_if(cached_displays_.begin(), cached_displays_.end(), |
| 199 [display_id](const DisplayInfo& display_info) { | 226 [display_id](const DisplayInfo& display_info) { |
| 200 return display_info.id == display_id; | 227 return display_info.id == display_id; |
| 201 }); | 228 }); |
| 202 } | 229 } |
| 203 | 230 |
| 231 PlatformScreenOzone::DisplayInfo PlatformScreenOzone::DisplayInfoFromSnapshot( |
| 232 const ui::DisplaySnapshot& snapshot) { |
| 233 const ui::DisplayMode* current_mode = snapshot.current_mode(); |
| 234 DCHECK(current_mode); |
| 235 |
| 236 DisplayInfo display_info; |
| 237 display_info.id = snapshot.display_id(); |
| 238 display_info.pixel_size = current_mode->size(); |
| 239 display_info.device_scale_factor = FindDeviceScaleFactor( |
| 240 ComputeDisplayDPI(current_mode->size(), snapshot.physical_size())); |
| 241 // Get DIP size based on device scale factor. We are assuming the |
| 242 // ui scale factor is always 1.0 here for now. |
| 243 gfx::Size scaled_size = gfx::ScaleToRoundedSize( |
| 244 current_mode->size(), 1.0f / display_info.device_scale_factor); |
| 245 display_info.bounds = gfx::Rect(next_display_origin_, scaled_size); |
| 246 return display_info; |
| 247 } |
| 248 |
| 204 void PlatformScreenOzone::OnDisplayModeChanged( | 249 void PlatformScreenOzone::OnDisplayModeChanged( |
| 205 const ui::DisplayConfigurator::DisplayStateList& displays) { | 250 const ui::DisplayConfigurator::DisplayStateList& displays) { |
| 206 ProcessRemovedDisplays(displays); | 251 ProcessRemovedDisplays(displays); |
| 207 ProcessModifiedDisplays(displays); | 252 ProcessModifiedDisplays(displays); |
| 208 UpdateCachedDisplays(); | 253 UpdateCachedDisplays(); |
| 209 AddNewDisplays(displays); | 254 AddNewDisplays(displays); |
| 210 wait_for_display_config_update_ = false; | 255 wait_for_display_config_update_ = false; |
| 211 } | 256 } |
| 212 | 257 |
| 213 void PlatformScreenOzone::OnDisplayModeChangeFailed( | 258 void PlatformScreenOzone::OnDisplayModeChangeFailed( |
| 214 const ui::DisplayConfigurator::DisplayStateList& displays, | 259 const ui::DisplayConfigurator::DisplayStateList& displays, |
| 215 ui::MultipleDisplayState failed_new_state) { | 260 ui::MultipleDisplayState failed_new_state) { |
| 216 LOG(ERROR) << "OnDisplayModeChangeFailed from DisplayConfigurator"; | 261 LOG(ERROR) << "OnDisplayModeChangeFailed from DisplayConfigurator"; |
| 217 wait_for_display_config_update_ = false; | 262 wait_for_display_config_update_ = false; |
| 218 } | 263 } |
| 219 | 264 |
| 220 void PlatformScreenOzone::Create(const shell::Identity& remote_identity, | 265 void PlatformScreenOzone::Create(const shell::Identity& remote_identity, |
| 221 mojom::DisplayControllerRequest request) { | 266 mojom::DisplayControllerRequest request) { |
| 222 bindings_.AddBinding(this, std::move(request)); | 267 bindings_.AddBinding(this, std::move(request)); |
| 223 } | 268 } |
| 224 | 269 |
| 225 } // namespace display | 270 } // namespace display |
| OLD | NEW |