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

Unified Diff: chromeos/monitor/output_configurator.cc

Issue 10532053: Detect output state at startup to avoid changes (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 6 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/monitor/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/monitor/output_configurator.cc
diff --git a/chromeos/monitor/output_configurator.cc b/chromeos/monitor/output_configurator.cc
index cda21a7331b2c93f96f0288b165c2ffcb61c98c3..01fbfaf1a7ca1baa1b6061206ed8a8ccbb88eaf9 100644
--- a/chromeos/monitor/output_configurator.cc
+++ b/chromeos/monitor/output_configurator.cc
@@ -158,6 +158,26 @@ static void CreateFrameBuffer(Display* display,
int mm_height = height * kPixelsToMmScale;
XRRSetScreenSize(display, window, width, height, mm_width, mm_height);
}
+
+// A helper to get the current CRTC, Mode, and height for a given output. This
+// is read from the XRandR configuration and not any of our caches.
+static void GetOutputConfiguration(Display* display,
+ XRRScreenResources* screen,
+ RROutput output,
+ RRCrtc* crtc,
+ RRMode* mode,
+ int* height) {
+ XRROutputInfo* output_info = XRRGetOutputInfo(display, screen, output);
+ CHECK(output_info != NULL);
+ *crtc = output_info->crtc;
+ XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(display, screen, *crtc);
+ if (crtc_info != NULL) {
+ *mode = crtc_info->mode;
+ *height = crtc_info->height;
+ XRRFreeCrtcInfo(crtc_info);
+ }
+ XRRFreeOutputInfo(output_info);
+}
} // namespace
bool OutputConfigurator::TryRecacheOutputs(Display* display,
@@ -320,8 +340,15 @@ OutputConfigurator::OutputConfigurator()
CHECK(screen != NULL);
bool did_detect_outputs = TryRecacheOutputs(display, screen);
CHECK(did_detect_outputs);
- State state = GetDefaultState();
- UpdateCacheAndXrandrToState(display, screen, window, state);
+ State current_state = InferCurrentState(display, screen);
+ if (current_state == STATE_INVALID) {
+ // Unknown state. Transition into the default state.
+ State state = GetDefaultState();
+ UpdateCacheAndXrandrToState(display, screen, window, state);
+ } else {
+ // This is a valid state so just save it to |output_state_|.
+ output_state_ = current_state;
+ }
// Find xrandr_event_base_ since we need it to interpret events, later.
int error_base_ignored = 0;
XRRQueryExtension(display, &xrandr_event_base_, &error_base_ignored);
@@ -473,6 +500,85 @@ State OutputConfigurator::GetDefaultState() const {
return state;
}
+State OutputConfigurator::InferCurrentState(Display* display,
+ XRRScreenResources* screen) const {
+ // STATE_INVALID will be our default or "unknown" state.
+ State state = STATE_INVALID;
+ // First step: count the number of connected outputs.
+ if (secondary_output_index_ == -1) {
+ // No secondary display.
+ if (primary_output_index_ == -1) {
+ // No primary display implies HEADLESS.
+ state = STATE_HEADLESS;
+ } else {
+ // The common case of primary-only.
+ // The only sanity check we require in this case is that the current mode
+ // of the output's CRTC is the ideal mode we determined for it.
+ RRCrtc primary_crtc = None;
+ RRMode primary_mode = None;
+ int primary_height = 0;
+ GetOutputConfiguration(display,
+ screen,
+ output_cache_[primary_output_index_].output,
+ &primary_crtc,
+ &primary_mode,
+ &primary_height);
+ if (primary_mode == output_cache_[primary_output_index_].ideal_mode) {
Daniel Erat 2012/06/07 19:17:40 nit: remove curly braces
disher 2012/06/07 19:40:23 Done.
+ state = STATE_SINGLE;
+ }
+ }
+ } else {
+ // We have two displays attached so we need to look at their configuration.
+ // Note that, for simplicity, we will only detect the states that we would
+ // have used and will assume anything unexpected is INVALID (which should
+ // not happen in any expected usage scenario).
+ RRCrtc primary_crtc = None;
+ RRMode primary_mode = None;
+ int primary_height = 0;
+ GetOutputConfiguration(display,
+ screen,
+ output_cache_[primary_output_index_].output,
+ &primary_crtc,
+ &primary_mode,
+ &primary_height);
+ RRCrtc secondary_crtc = None;
+ RRMode secondary_mode = None;
+ int secondary_height = 0;
+ GetOutputConfiguration(display,
+ screen,
+ output_cache_[secondary_output_index_].output,
+ &secondary_crtc,
+ &secondary_mode,
+ &secondary_height);
+ // Make sure the CRTCs are matched to the expected outputs.
+ if ((output_cache_[primary_output_index_].crtc == primary_crtc) &&
+ (output_cache_[secondary_output_index_].crtc == secondary_crtc)) {
+ // Check the mode matching: either both mirror or both ideal.
+ if ((output_cache_[primary_output_index_].mirror_mode == primary_mode) &&
+ (output_cache_[secondary_output_index_].mirror_mode ==
+ secondary_mode)) {
+ // We are already in mirror mode.
+ state = STATE_DUAL_MIRROR;
+ } else if ((output_cache_[primary_output_index_].ideal_mode ==
+ primary_mode) &&
+ (output_cache_[secondary_output_index_].ideal_mode ==
+ secondary_mode)) {
+ // Both outputs are in their "ideal" mode so check their Y-offsets to
+ // see which "ideal" configuration this is.
+ if (primary_height == output_cache_[secondary_output_index_].y) {
+ // Secondary is tiled first.
+ state = STATE_DUAL_SECONDARY_ONLY;
+ } else if (secondary_height == output_cache_[primary_output_index_].y) {
+ // Primary is tiled first.
+ state = STATE_DUAL_PRIMARY_ONLY;
+ }
+ }
+ }
+ }
+
+ return state;
+}
+
bool OutputConfigurator::CycleDisplayMode() {
VLOG(1) << "CycleDisplayMode";
bool did_change = false;
« no previous file with comments | « chromeos/monitor/output_configurator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698