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

Unified Diff: chromeos/display/output_configurator.cc

Issue 12391004: chromeos: Add DisplayPowerServiceProvider. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ugh, TrayDisplay was including output_configurator.h on windows Created 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chromeos/display/output_configurator.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chromeos/display/output_configurator.cc
diff --git a/chromeos/display/output_configurator.cc b/chromeos/display/output_configurator.cc
index c460114699a15093dfb11e3d4149b48f833c0531..cb8210fd828028b2e200b618562fc052bb0234b0 100644
--- a/chromeos/display/output_configurator.cc
+++ b/chromeos/display/output_configurator.cc
@@ -538,6 +538,7 @@ OutputConfigurator::OutputConfigurator()
connected_output_count_(0),
xrandr_event_base_(0),
output_state_(STATE_INVALID),
+ power_state_(DISPLAY_POWER_ALL_ON),
mirror_mode_will_preserve_aspect_(false),
mirror_mode_preserved_aspect_(false),
last_enter_state_time_() {
@@ -594,10 +595,7 @@ void OutputConfigurator::Init(bool is_panel_fitting_enabled,
STATE_INVALID,
outputs);
if (output_state_ != starting_state &&
- EnterState(display,
- screen,
- window,
- starting_state,
+ EnterState(display, screen, window, starting_state, power_state_,
outputs)) {
output_state_ = starting_state;
}
@@ -643,7 +641,7 @@ bool OutputConfigurator::CycleDisplayMode() {
OutputState original = InferCurrentState(display, screen, outputs);
OutputState next_state = GetNextState(display, screen, original, outputs);
if (original != next_state &&
- EnterState(display, screen, window, next_state, outputs)) {
+ EnterState(display, screen, window, next_state, power_state_, outputs)) {
did_change = true;
}
// We have seen cases where the XRandR data can get out of sync with our own
@@ -663,77 +661,41 @@ bool OutputConfigurator::CycleDisplayMode() {
return did_change;
}
-bool OutputConfigurator::ScreenPowerSet(bool power_on, bool all_displays) {
- TRACE_EVENT0("chromeos", "OutputConfigurator::ScreenPowerSet");
- VLOG(1) << "OutputConfigurator::SetScreensOn " << power_on
- << " all displays " << all_displays;
+bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state,
+ bool force_probe) {
+ TRACE_EVENT0("chromeos", "OutputConfigurator::SetDisplayPower");
+ VLOG(1) << "OutputConfigurator::SetDisplayPower: power_state=" << power_state
+ << " force_probe=" << force_probe;
+
if (!configure_display_)
return false;
+ if (power_state == power_state_ && !force_probe)
+ return true;
- bool success = false;
Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay();
- CHECK(display != NULL);
+ CHECK(display);
XGrabServer(display);
Window window = DefaultRootWindow(display);
XRRScreenResources* screen = GetScreenResourcesAndRecordUMA(display, window);
- CHECK(screen != NULL);
-
+ CHECK(screen);
std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen);
connected_output_count_ = outputs.size();
- if (all_displays && power_on) {
- // Resume all displays using the current state.
- if (EnterState(display, screen, window, output_state_, outputs)) {
- // Force the DPMS on since the driver doesn't always detect that it should
- // turn on. This is needed when coming back from idle suspend.
+ if (EnterState(display, screen, window, output_state_, power_state,
+ outputs)) {
+ power_state_ = power_state;
+ if (power_state != DISPLAY_POWER_ALL_OFF) {
+ // Force the DPMS on since the driver doesn't always detect that it
+ // should turn on. This is needed when coming back from idle suspend.
CHECK(DPMSEnable(display));
CHECK(DPMSForceLevel(display, DPMSModeOn));
-
- XRRFreeScreenResources(screen);
- XUngrabServer(display);
- return true;
}
}
- CrtcConfig config;
- config.crtc = None;
- // Set the CRTCs based on whether we want to turn the power on or off and
- // select the outputs to operate on by name or all_displays.
- for (int i = 0; i < connected_output_count_; ++i) {
- if (all_displays || outputs[i].is_internal || power_on) {
- config.x = 0;
- config.y = outputs[i].y;
- config.output = outputs[i].output;
- config.mode = None;
- if (power_on) {
- config.mode = (output_state_ == STATE_DUAL_MIRROR) ?
- outputs[i].mirror_mode : outputs[i].native_mode;
- } else if (connected_output_count_ > 1 && !all_displays &&
- outputs[i].is_internal) {
- // Workaround for crbug.com/148365: leave internal display in native
- // mode so user can move cursor (and hence windows) onto internal
- // display even when dimmed
- config.mode = outputs[i].native_mode;
- }
- config.crtc = GetNextCrtcAfter(display, screen, config.output,
- config.crtc);
-
- ConfigureCrtc(display, screen, &config);
- success = true;
- }
- }
-
- // Force the DPMS on since the driver doesn't always detect that it should
- // turn on. This is needed when coming back from idle suspend.
- if (power_on) {
- CHECK(DPMSEnable(display));
- CHECK(DPMSForceLevel(display, DPMSModeOn));
- }
-
XRRFreeScreenResources(screen);
XUngrabServer(display);
- return success;
+ return true;
}
bool OutputConfigurator::SetDisplayMode(OutputState new_state) {
@@ -755,7 +717,7 @@ bool OutputConfigurator::SetDisplayMode(OutputState new_state) {
std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen);
connected_output_count_ = outputs.size();
- if (EnterState(display, screen, window, new_state, outputs))
+ if (EnterState(display, screen, window, new_state, power_state_, outputs))
output_state_ = new_state;
XRRFreeScreenResources(screen);
@@ -829,7 +791,8 @@ void OutputConfigurator::ConfigureOutputs() {
// When a display was swapped, the state moves from
// STATE_DUAL_EXTENDED to STATE_DUAL_EXTENDED, so don't rely on
// the state chagne to tell if it was successful.
- bool success = EnterState(display, screen, window, new_state, outputs);
+ bool success =
+ EnterState(display, screen, window, new_state, power_state_, outputs);
bool is_projecting = IsProjecting(outputs);
XRRFreeScreenResources(screen);
XUngrabServer(display);
@@ -859,16 +822,23 @@ bool OutputConfigurator::IsInternalOutputName(const std::string& name) {
}
void OutputConfigurator::SuspendDisplays() {
- // Turn displays on before suspend. At this point, the backlight is off,
- // so we turn on the internal display so that we can resume directly into
- // "on" state. This greatly reduces resume times.
- ScreenPowerSet(true, true);
+ // Turn internal displays on before suspend. At this point, the backlight
+ // is off, so we turn on the internal display so that we can resume
+ // directly into "on" state. This greatly reduces resume times.
+ SetDisplayPower(DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF, false);
+
// We need to make sure that the monitor configuration we just did actually
// completes before we return, because otherwise the X message could be
// racing with the HandleSuspendReadiness message.
XSync(base::MessagePumpAuraX11::GetDefaultXDisplay(), 0);
}
+void OutputConfigurator::ResumeDisplays() {
+ // Force probing to ensure that we pick up any changes that were made
+ // while the system was suspended.
+ SetDisplayPower(DISPLAY_POWER_ALL_ON, true);
+}
+
void OutputConfigurator::NotifyOnDisplayChanged() {
TRACE_EVENT0("chromeos", "OutputConfigurator::NotifyOnDisplayChanged");
FOR_EACH_OBSERVER(Observer, observers_, OnDisplayModeChanged());
@@ -1192,7 +1162,8 @@ bool OutputConfigurator::EnterState(
Display* display,
XRRScreenResources* screen,
Window window,
- OutputState new_state,
+ OutputState output_state,
+ DisplayPowerState power_state,
const std::vector<OutputSnapshot>& outputs) {
TRACE_EVENT0("chromeos", "OutputConfigurator::EnterState");
switch (outputs.size()) {
@@ -1207,16 +1178,20 @@ bool OutputConfigurator::EnterState(
return false;
}
+ bool power_on = power_state == DISPLAY_POWER_ALL_ON ||
+ (power_state == DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON &&
+ !outputs[0].is_internal) ||
+ (power_state == DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF &&
+ outputs[0].is_internal);
CrtcConfig config(
GetNextCrtcAfter(display, screen, outputs[0].output, None),
- 0, 0, outputs[0].native_mode, outputs[0].output);
+ 0, 0, power_on ? outputs[0].native_mode : None, outputs[0].output);
- int width = mode_info->width;
- int height = mode_info->height;
- CreateFrameBuffer(display, screen, window, width, height, &config, NULL);
+ CreateFrameBuffer(display, screen, window, mode_info->width,
+ mode_info->height, &config, NULL);
- // Re-attach native mode for the CRTC.
ConfigureCrtc(display, screen, &config);
+
// Restore identity transformation for single monitor in native mode.
if (outputs[0].touch_device_id != None) {
CoordinateTransformation ctm; // Defaults to identity
@@ -1230,25 +1205,36 @@ bool OutputConfigurator::EnterState(
RRCrtc secondary_crtc =
GetNextCrtcAfter(display, screen, outputs[1].output, primary_crtc);
- if (new_state == STATE_DUAL_MIRROR) {
+ // Workaround for crbug.com/148365: leave internal display on for
+ // internal-off, external-on so user can move cursor (and hence
+ // windows) onto internal display even when it's off.
+ bool primary_power_on = power_state == DISPLAY_POWER_ALL_ON ||
+ (power_state == DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF &&
+ outputs[0].is_internal);
+ bool secondary_power_on = power_state == DISPLAY_POWER_ALL_ON ||
+ (power_state == DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF &&
+ outputs[1].is_internal);
+
+ if (output_state == STATE_DUAL_MIRROR) {
XRRModeInfo* mode_info = ModeInfoForID(screen, outputs[0].mirror_mode);
if (mode_info == NULL) {
UMA_HISTOGRAM_COUNTS("Display.EnterState.mirror_failures", 1);
return false;
}
- CrtcConfig config1(primary_crtc, 0, 0, outputs[0].mirror_mode,
+ CrtcConfig config1(primary_crtc, 0, 0,
+ primary_power_on ? outputs[0].mirror_mode : None,
outputs[0].output);
- CrtcConfig config2(secondary_crtc, 0, 0, outputs[1].mirror_mode,
+ CrtcConfig config2(secondary_crtc, 0, 0,
+ secondary_power_on ? outputs[1].mirror_mode : None,
outputs[1].output);
- int width = mode_info->width;
- int height = mode_info->height;
- CreateFrameBuffer(display, screen, window, width, height,
- &config1, &config2);
+ CreateFrameBuffer(display, screen, window, mode_info->width,
+ mode_info->height, &config1, &config2);
ConfigureCrtc(display, screen, &config1);
ConfigureCrtc(display, screen, &config2);
+
for (size_t i = 0; i < outputs.size(); i++) {
if (outputs[i].touch_device_id == None)
continue;
@@ -1274,19 +1260,20 @@ bool OutputConfigurator::EnterState(
int primary_height = primary_mode_info->height;
int secondary_height = secondary_mode_info->height;
- CrtcConfig config1(primary_crtc, 0, 0, outputs[0].native_mode,
+ CrtcConfig config1(primary_crtc, 0, 0,
+ primary_power_on ? outputs[0].native_mode : None,
outputs[0].output);
- CrtcConfig config2(secondary_crtc, 0, 0, outputs[1].native_mode,
+ CrtcConfig config2(secondary_crtc, 0, 0,
+ secondary_power_on ? outputs[1].native_mode : None,
outputs[1].output);
- if (new_state == STATE_DUAL_EXTENDED)
+ if (output_state == STATE_DUAL_EXTENDED)
config2.y = primary_height + kVerticalGap;
else
config1.y = secondary_height + kVerticalGap;
-
- int width =
- std::max<int>(primary_mode_info->width, secondary_mode_info->width);
+ int width = std::max<int>(
+ primary_mode_info->width, secondary_mode_info->width);
int height = primary_height + secondary_height + kVerticalGap;
CreateFrameBuffer(display, screen, window, width, height, &config1,
@@ -1305,7 +1292,8 @@ bool OutputConfigurator::EnterState(
}
if (outputs[1].touch_device_id != None) {
CoordinateTransformation ctm;
- ctm.x_scale = static_cast<float>(secondary_mode_info->width) / width;
+ ctm.x_scale = static_cast<float>(secondary_mode_info->width) /
+ width;
ctm.x_offset = static_cast<float>(config2.x) / width;
ctm.y_scale = static_cast<float>(secondary_height) / height;
ctm.y_offset = static_cast<float>(config2.y) / height;
« no previous file with comments | « chromeos/display/output_configurator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698