| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #ifndef UI_DISPLAY_CHROMEOS_OUTPUT_CONFIGURATOR_H_ | 5 #ifndef UI_DISPLAY_CHROMEOS_OUTPUT_CONFIGURATOR_H_ |
| 6 #define UI_DISPLAY_CHROMEOS_OUTPUT_CONFIGURATOR_H_ | 6 #define UI_DISPLAY_CHROMEOS_OUTPUT_CONFIGURATOR_H_ |
| 7 | 7 |
| 8 #include <map> | 8 #include <map> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/event_types.h" | 13 #include "base/event_types.h" |
| 14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/observer_list.h" | 15 #include "base/observer_list.h" |
| 16 #include "base/timer/timer.h" | 16 #include "base/timer/timer.h" |
| 17 #include "third_party/cros_system_api/dbus/service_constants.h" | 17 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 18 #include "ui/display/chromeos/native_display_observer.h" | 18 #include "ui/display/chromeos/native_display_observer.h" |
| 19 #include "ui/display/display_constants.h" | 19 #include "ui/display/display_constants.h" |
| 20 #include "ui/display/display_export.h" | 20 #include "ui/display/display_export.h" |
| 21 | 21 |
| 22 // Forward declarations for Xlib and Xrandr. | 22 namespace gfx { |
| 23 // This is so unused X definitions don't pollute the namespace. | 23 class Point; |
| 24 typedef unsigned long XID; | 24 class Size; |
| 25 typedef XID RROutput; | 25 } |
| 26 typedef XID RRCrtc; | |
| 27 typedef XID RRMode; | |
| 28 | 26 |
| 29 namespace ui { | 27 namespace ui { |
| 30 | 28 class DisplayMode; |
| 29 class DisplaySnapshot; |
| 31 class NativeDisplayDelegate; | 30 class NativeDisplayDelegate; |
| 32 | 31 |
| 33 // This class interacts directly with the underlying Xrandr API to manipulate | 32 // This class interacts directly with the system display configurator. |
| 34 // CTRCs and Outputs. | |
| 35 class DISPLAY_EXPORT OutputConfigurator : public NativeDisplayObserver { | 33 class DISPLAY_EXPORT OutputConfigurator : public NativeDisplayObserver { |
| 36 public: | 34 public: |
| 37 typedef uint64_t OutputProtectionClientId; | 35 typedef uint64_t OutputProtectionClientId; |
| 38 static const OutputProtectionClientId kInvalidClientId = 0; | 36 static const OutputProtectionClientId kInvalidClientId = 0; |
| 39 | 37 |
| 40 struct ModeInfo { | |
| 41 ModeInfo(); | |
| 42 ModeInfo(int width, int height, bool interlaced, float refresh_rate); | |
| 43 | |
| 44 int width; | |
| 45 int height; | |
| 46 bool interlaced; | |
| 47 float refresh_rate; | |
| 48 }; | |
| 49 | |
| 50 typedef std::map<RRMode, ModeInfo> ModeInfoMap; | |
| 51 | |
| 52 struct CoordinateTransformation { | 38 struct CoordinateTransformation { |
| 53 // Initialized to the identity transformation. | 39 // Initialized to the identity transformation. |
| 54 CoordinateTransformation(); | 40 CoordinateTransformation(); |
| 55 | 41 |
| 56 float x_scale; | 42 float x_scale; |
| 57 float x_offset; | 43 float x_offset; |
| 58 float y_scale; | 44 float y_scale; |
| 59 float y_offset; | 45 float y_offset; |
| 60 }; | 46 }; |
| 61 | 47 |
| 62 // Information about an output's current state. | 48 struct DisplayState { |
| 63 struct OutputSnapshot { | 49 DisplayState(); |
| 64 OutputSnapshot(); | |
| 65 ~OutputSnapshot(); | |
| 66 | 50 |
| 67 RROutput output; | 51 DisplaySnapshot* display; // Not owned. |
| 68 | |
| 69 // CRTC that should be used for this output. Not necessarily the CRTC | |
| 70 // that XRandR reports is currently being used. | |
| 71 RRCrtc crtc; | |
| 72 | |
| 73 // Mode currently being used by the output. | |
| 74 RRMode current_mode; | |
| 75 | |
| 76 // "Best" mode supported by the output. | |
| 77 RRMode native_mode; | |
| 78 | |
| 79 // Mode used when displaying the same desktop on multiple outputs. | |
| 80 RRMode mirror_mode; | |
| 81 | |
| 82 // User-selected mode for the output. | |
| 83 RRMode selected_mode; | |
| 84 | |
| 85 // Output's origin on the framebuffer. | |
| 86 int x; | |
| 87 int y; | |
| 88 | |
| 89 // Output's physical dimensions. | |
| 90 uint64 width_mm; | |
| 91 uint64 height_mm; | |
| 92 | |
| 93 bool is_aspect_preserving_scaling; | |
| 94 | |
| 95 // The type of output. | |
| 96 OutputType type; | |
| 97 | |
| 98 // Map from mode IDs to details about the corresponding modes. | |
| 99 ModeInfoMap mode_infos; | |
| 100 | 52 |
| 101 // XInput device ID or 0 if this output isn't a touchscreen. | 53 // XInput device ID or 0 if this output isn't a touchscreen. |
| 102 int touch_device_id; | 54 int touch_device_id; |
| 103 | 55 |
| 104 CoordinateTransformation transform; | 56 CoordinateTransformation transform; |
| 105 | 57 |
| 106 // Display id for this output. | 58 // User-selected mode for the output. |
| 107 int64 display_id; | 59 const DisplayMode* selected_mode; |
| 108 | 60 |
| 109 bool has_display_id; | 61 // Mode used when displaying the same desktop on multiple outputs. |
| 62 const DisplayMode* mirror_mode; |
| 63 }; |
| 110 | 64 |
| 111 // This output's index in the array returned by XRandR. Stable even as | 65 typedef std::vector<DisplayState> DisplayStateList; |
| 112 // outputs are connected or disconnected. | |
| 113 int index; | |
| 114 }; | |
| 115 | 66 |
| 116 class Observer { | 67 class Observer { |
| 117 public: | 68 public: |
| 118 virtual ~Observer() {} | 69 virtual ~Observer() {} |
| 119 | 70 |
| 120 // Called after the display mode has been changed. |output| contains the | 71 // Called after the display mode has been changed. |output| contains the |
| 121 // just-applied configuration. Note that the X server is no longer grabbed | 72 // just-applied configuration. Note that the X server is no longer grabbed |
| 122 // when this method is called, so the actual configuration could've changed | 73 // when this method is called, so the actual configuration could've changed |
| 123 // already. | 74 // already. |
| 124 virtual void OnDisplayModeChanged( | 75 virtual void OnDisplayModeChanged( |
| 125 const std::vector<OutputSnapshot>& outputs) {} | 76 const std::vector<DisplayState>& outputs) {} |
| 126 | 77 |
| 127 // Called after a display mode change attempt failed. |failed_new_state| is | 78 // Called after a display mode change attempt failed. |failed_new_state| is |
| 128 // the new state which the system failed to enter. | 79 // the new state which the system failed to enter. |
| 129 virtual void OnDisplayModeChangeFailed(OutputState failed_new_state) {} | 80 virtual void OnDisplayModeChangeFailed(OutputState failed_new_state) {} |
| 130 }; | 81 }; |
| 131 | 82 |
| 132 // Interface for classes that make decisions about which output state | 83 // Interface for classes that make decisions about which output state |
| 133 // should be used. | 84 // should be used. |
| 134 class StateController { | 85 class StateController { |
| 135 public: | 86 public: |
| 136 virtual ~StateController() {} | 87 virtual ~StateController() {} |
| 137 | 88 |
| 138 // Called when displays are detected. | 89 // Called when displays are detected. |
| 139 virtual OutputState GetStateForDisplayIds( | 90 virtual OutputState GetStateForDisplayIds( |
| 140 const std::vector<int64>& display_ids) const = 0; | 91 const std::vector<int64>& display_ids) const = 0; |
| 141 | 92 |
| 142 // Queries the resolution (|width|x|height|) in pixels | 93 // Queries the resolution (|size|) in pixels to select output mode for the |
| 143 // to select output mode for the given display id. | 94 // given display id. |
| 144 virtual bool GetResolutionForDisplayId(int64 display_id, | 95 virtual bool GetResolutionForDisplayId(int64 display_id, |
| 145 int* width, | 96 gfx::Size* size) const = 0; |
| 146 int* height) const = 0; | |
| 147 }; | 97 }; |
| 148 | 98 |
| 149 // Interface for classes that implement software based mirroring. | 99 // Interface for classes that implement software based mirroring. |
| 150 class SoftwareMirroringController { | 100 class SoftwareMirroringController { |
| 151 public: | 101 public: |
| 152 virtual ~SoftwareMirroringController() {} | 102 virtual ~SoftwareMirroringController() {} |
| 153 | 103 |
| 154 // Called when the hardware mirroring failed. | 104 // Called when the hardware mirroring failed. |
| 155 virtual void SetSoftwareMirroring(bool enabled) = 0; | 105 virtual void SetSoftwareMirroring(bool enabled) = 0; |
| 156 }; | 106 }; |
| 157 | 107 |
| 158 class TouchscreenDelegate { | 108 class TouchscreenDelegate { |
| 159 public: | 109 public: |
| 160 virtual ~TouchscreenDelegate() {} | 110 virtual ~TouchscreenDelegate() {} |
| 161 | 111 |
| 162 // Searches for touchscreens among input devices, | 112 // Searches for touchscreens among input devices, |
| 163 // and tries to match them up to screens in |outputs|. | 113 // and tries to match them up to screens in |outputs|. |
| 164 // |outputs| is an array of detected screens. | 114 // |outputs| is an array of detected screens. |
| 165 // If a touchscreen with same resolution as an output's native mode | 115 // If a touchscreen with same resolution as an output's native mode |
| 166 // is detected, its id will be stored in this output. | 116 // is detected, its id will be stored in this output. |
| 167 virtual void AssociateTouchscreens( | 117 virtual void AssociateTouchscreens(std::vector<DisplayState>* outputs) = 0; |
| 168 std::vector<OutputSnapshot>* outputs) = 0; | |
| 169 | 118 |
| 170 // Configures XInput's Coordinate Transformation Matrix property. | 119 // Configures XInput's Coordinate Transformation Matrix property. |
| 171 // |touch_device_id| the ID of the touchscreen device to configure. | 120 // |touch_device_id| the ID of the touchscreen device to configure. |
| 172 // |ctm| contains the desired transformation parameters. The offsets | 121 // |ctm| contains the desired transformation parameters. The offsets |
| 173 // in it should be normalized so that 1 corresponds to the X or Y axis | 122 // in it should be normalized so that 1 corresponds to the X or Y axis |
| 174 // size for the corresponding offset. | 123 // size for the corresponding offset. |
| 175 virtual void ConfigureCTM(int touch_device_id, | 124 virtual void ConfigureCTM(int touch_device_id, |
| 176 const CoordinateTransformation& ctm) = 0; | 125 const CoordinateTransformation& ctm) = 0; |
| 177 }; | 126 }; |
| 178 | 127 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 202 | 151 |
| 203 // Gap between screens so cursor at bottom of active display doesn't | 152 // Gap between screens so cursor at bottom of active display doesn't |
| 204 // partially appear on top of inactive display. Higher numbers guard | 153 // partially appear on top of inactive display. Higher numbers guard |
| 205 // against larger cursors, but also waste more memory. | 154 // against larger cursors, but also waste more memory. |
| 206 // For simplicity, this is hard-coded to avoid the complexity of always | 155 // For simplicity, this is hard-coded to avoid the complexity of always |
| 207 // determining the DPI of the screen and rationalizing which screen we | 156 // determining the DPI of the screen and rationalizing which screen we |
| 208 // need to use for the DPI calculation. | 157 // need to use for the DPI calculation. |
| 209 // See crbug.com/130188 for initial discussion. | 158 // See crbug.com/130188 for initial discussion. |
| 210 static const int kVerticalGap = 60; | 159 static const int kVerticalGap = 60; |
| 211 | 160 |
| 212 // Returns a pointer to the ModeInfo struct in |output| corresponding to | |
| 213 // |mode|, or NULL if the struct isn't present. | |
| 214 static const ModeInfo* GetModeInfo(const OutputSnapshot& output, RRMode mode); | |
| 215 | |
| 216 // Returns the mode within |output| that matches the given size with highest | 161 // Returns the mode within |output| that matches the given size with highest |
| 217 // refresh rate. Returns None if no matching output was found. | 162 // refresh rate. Returns None if no matching output was found. |
| 218 static RRMode FindOutputModeMatchingSize(const OutputSnapshot& output, | 163 static const DisplayMode* FindDisplayModeMatchingSize( |
| 219 int width, | 164 const DisplaySnapshot& output, |
| 220 int height); | 165 const gfx::Size& size); |
| 221 | 166 |
| 222 OutputConfigurator(); | 167 OutputConfigurator(); |
| 223 virtual ~OutputConfigurator(); | 168 virtual ~OutputConfigurator(); |
| 224 | 169 |
| 225 OutputState output_state() const { return output_state_; } | 170 OutputState output_state() const { return output_state_; } |
| 226 chromeos::DisplayPowerState power_state() const { return power_state_; } | 171 chromeos::DisplayPowerState power_state() const { return power_state_; } |
| 227 const std::vector<OutputSnapshot>& cached_outputs() const { | 172 const std::vector<DisplayState>& cached_outputs() const { |
| 228 return cached_outputs_; | 173 return cached_outputs_; |
| 229 } | 174 } |
| 230 | 175 |
| 231 void set_state_controller(StateController* controller) { | 176 void set_state_controller(StateController* controller) { |
| 232 state_controller_ = controller; | 177 state_controller_ = controller; |
| 233 } | 178 } |
| 234 void set_mirroring_controller(SoftwareMirroringController* controller) { | 179 void set_mirroring_controller(SoftwareMirroringController* controller) { |
| 235 mirroring_controller_ = controller; | 180 mirroring_controller_ = controller; |
| 236 } | 181 } |
| 237 | 182 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 // outputs' |mirror_mode| fields by looking for a mode in |internal_output| | 276 // outputs' |mirror_mode| fields by looking for a mode in |internal_output| |
| 332 // and |external_output| having the same resolution. Returns false if a shared | 277 // and |external_output| having the same resolution. Returns false if a shared |
| 333 // mode wasn't found or created. | 278 // mode wasn't found or created. |
| 334 // | 279 // |
| 335 // |try_panel_fitting| allows creating a panel-fitting mode for | 280 // |try_panel_fitting| allows creating a panel-fitting mode for |
| 336 // |internal_output| instead of only searching for a matching mode (note that | 281 // |internal_output| instead of only searching for a matching mode (note that |
| 337 // it may lead to a crash if |internal_info| is not capable of panel fitting). | 282 // it may lead to a crash if |internal_info| is not capable of panel fitting). |
| 338 // | 283 // |
| 339 // |preserve_aspect| limits the search/creation only to the modes having the | 284 // |preserve_aspect| limits the search/creation only to the modes having the |
| 340 // native aspect ratio of |external_output|. | 285 // native aspect ratio of |external_output|. |
| 341 bool FindMirrorMode(OutputSnapshot* internal_output, | 286 bool FindMirrorMode(DisplayState* internal_output, |
| 342 OutputSnapshot* external_output, | 287 DisplayState* external_output, |
| 343 bool try_panel_fitting, | 288 bool try_panel_fitting, |
| 344 bool preserve_aspect); | 289 bool preserve_aspect); |
| 345 | 290 |
| 346 // Configures outputs. | 291 // Configures outputs. |
| 347 void ConfigureOutputs(); | 292 void ConfigureOutputs(); |
| 348 | 293 |
| 349 // Notifies observers about an attempted state change. | 294 // Notifies observers about an attempted state change. |
| 350 void NotifyObservers(bool success, OutputState attempted_state); | 295 void NotifyObservers(bool success, OutputState attempted_state); |
| 351 | 296 |
| 352 // Switches to the state specified in |output_state| and |power_state|. | 297 // Switches to the state specified in |output_state| and |power_state|. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 365 bool EnterState(OutputState output_state, | 310 bool EnterState(OutputState output_state, |
| 366 chromeos::DisplayPowerState power_state); | 311 chromeos::DisplayPowerState power_state); |
| 367 | 312 |
| 368 // Returns the output state that should be used with |cached_outputs_| while | 313 // Returns the output state that should be used with |cached_outputs_| while |
| 369 // in |power_state|. | 314 // in |power_state|. |
| 370 OutputState ChooseOutputState(chromeos::DisplayPowerState power_state) const; | 315 OutputState ChooseOutputState(chromeos::DisplayPowerState power_state) const; |
| 371 | 316 |
| 372 // Computes the relevant transformation for mirror mode. | 317 // Computes the relevant transformation for mirror mode. |
| 373 // |output| is the output on which mirror mode is being applied. | 318 // |output| is the output on which mirror mode is being applied. |
| 374 // Returns the transformation or identity if computations fail. | 319 // Returns the transformation or identity if computations fail. |
| 375 CoordinateTransformation GetMirrorModeCTM( | 320 CoordinateTransformation GetMirrorModeCTM(const DisplayState& output); |
| 376 const OutputConfigurator::OutputSnapshot& output); | |
| 377 | 321 |
| 378 // Computes the relevant transformation for extended mode. | 322 // Computes the relevant transformation for extended mode. |output| is the |
| 379 // |output| is the output on which extended mode is being applied. | 323 // output on which extended mode is being applied. |new_origin| is the |
| 380 // |width| and |height| are the width and height of the combined framebuffer. | 324 // position of the output on the framebuffer. |framebuffer_size| is the |
| 325 // size of the combined framebuffer. |
| 381 // Returns the transformation or identity if computations fail. | 326 // Returns the transformation or identity if computations fail. |
| 382 CoordinateTransformation GetExtendedModeCTM( | 327 CoordinateTransformation GetExtendedModeCTM( |
| 383 const OutputConfigurator::OutputSnapshot& output, | 328 const DisplayState& output, |
| 384 int framebuffer_width, | 329 const gfx::Point& new_origin, |
| 385 int frame_buffer_height); | 330 const gfx::Size& framebuffer_size); |
| 386 | 331 |
| 387 // Returns the ratio between mirrored mode area and native mode area: | 332 // Returns the ratio between mirrored mode area and native mode area: |
| 388 // (mirror_mode_width * mirrow_mode_height) / (native_width * native_height) | 333 // (mirror_mode_width * mirrow_mode_height) / (native_width * native_height) |
| 389 float GetMirroredDisplayAreaRatio( | 334 float GetMirroredDisplayAreaRatio(const DisplayState& output); |
| 390 const OutputConfigurator::OutputSnapshot& output); | |
| 391 | 335 |
| 392 // Applies output protections according to requests. | 336 // Applies output protections according to requests. |
| 393 bool ApplyProtections(const DisplayProtections& requests); | 337 bool ApplyProtections(const DisplayProtections& requests); |
| 394 | 338 |
| 395 StateController* state_controller_; | 339 StateController* state_controller_; |
| 396 SoftwareMirroringController* mirroring_controller_; | 340 SoftwareMirroringController* mirroring_controller_; |
| 397 scoped_ptr<NativeDisplayDelegate> native_display_delegate_; | 341 scoped_ptr<NativeDisplayDelegate> native_display_delegate_; |
| 398 scoped_ptr<TouchscreenDelegate> touchscreen_delegate_; | 342 scoped_ptr<TouchscreenDelegate> touchscreen_delegate_; |
| 399 | 343 |
| 400 // Used to enable modes which rely on panel fitting. | 344 // Used to enable modes which rely on panel fitting. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 416 bool configure_display_; | 360 bool configure_display_; |
| 417 | 361 |
| 418 // The current display state. | 362 // The current display state. |
| 419 OutputState output_state_; | 363 OutputState output_state_; |
| 420 | 364 |
| 421 // The current power state. | 365 // The current power state. |
| 422 chromeos::DisplayPowerState power_state_; | 366 chromeos::DisplayPowerState power_state_; |
| 423 | 367 |
| 424 // Most-recently-used output configuration. Note that the actual | 368 // Most-recently-used output configuration. Note that the actual |
| 425 // configuration changes asynchronously. | 369 // configuration changes asynchronously. |
| 426 std::vector<OutputSnapshot> cached_outputs_; | 370 DisplayStateList cached_outputs_; |
| 427 | 371 |
| 428 ObserverList<Observer> observers_; | 372 ObserverList<Observer> observers_; |
| 429 | 373 |
| 430 // The timer to delay configuring outputs. See also the comments in | 374 // The timer to delay configuring outputs. See also the comments in |
| 431 // Dispatch(). | 375 // Dispatch(). |
| 432 scoped_ptr<base::OneShotTimer<OutputConfigurator> > configure_timer_; | 376 scoped_ptr<base::OneShotTimer<OutputConfigurator> > configure_timer_; |
| 433 | 377 |
| 434 // Id for next output protection client. | 378 // Id for next output protection client. |
| 435 OutputProtectionClientId next_output_protection_client_id_; | 379 OutputProtectionClientId next_output_protection_client_id_; |
| 436 | 380 |
| 437 // Output protection requests of each client. | 381 // Output protection requests of each client. |
| 438 ProtectionRequests client_protection_requests_; | 382 ProtectionRequests client_protection_requests_; |
| 439 | 383 |
| 440 DISALLOW_COPY_AND_ASSIGN(OutputConfigurator); | 384 DISALLOW_COPY_AND_ASSIGN(OutputConfigurator); |
| 441 }; | 385 }; |
| 442 | 386 |
| 443 typedef std::vector<OutputConfigurator::OutputSnapshot> OutputSnapshotList; | |
| 444 | |
| 445 } // namespace ui | 387 } // namespace ui |
| 446 | 388 |
| 447 #endif // UI_DISPLAY_CHROMEOS_OUTPUT_CONFIGURATOR_H_ | 389 #endif // UI_DISPLAY_CHROMEOS_OUTPUT_CONFIGURATOR_H_ |
| OLD | NEW |