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

Unified Diff: chromeos/display/real_output_configurator_delegate.cc

Issue 24081004: chromeos: Fix display failures when going to mirrored mode. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix DisplayChangeObserverTest Created 7 years, 3 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/real_output_configurator_delegate.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chromeos/display/real_output_configurator_delegate.cc
diff --git a/chromeos/display/real_output_configurator_delegate.cc b/chromeos/display/real_output_configurator_delegate.cc
index 2788bd332addd6381addca2f8bd5ee0e71ad642f..43b4cdb5636b5f88746204f87bf902b538af3d27 100644
--- a/chromeos/display/real_output_configurator_delegate.cc
+++ b/chromeos/display/real_output_configurator_delegate.cc
@@ -43,17 +43,12 @@ RRMode GetOutputNativeMode(const XRROutputInfo* output_info) {
RealOutputConfiguratorDelegate::RealOutputConfiguratorDelegate()
: display_(base::MessagePumpX11::GetDefaultXDisplay()),
window_(DefaultRootWindow(display_)),
- screen_(NULL),
- is_panel_fitting_enabled_(false) {
+ screen_(NULL) {
}
RealOutputConfiguratorDelegate::~RealOutputConfiguratorDelegate() {
}
-void RealOutputConfiguratorDelegate::SetPanelFittingEnabled(bool enabled) {
- is_panel_fitting_enabled_ = enabled;
-}
-
void RealOutputConfiguratorDelegate::InitXRandRExtension(int* event_base) {
int error_base_ignored = 0;
XRRQueryExtension(display_, event_base, &error_base_ignored);
@@ -107,99 +102,38 @@ void RealOutputConfiguratorDelegate::ForceDPMSOn() {
}
std::vector<OutputConfigurator::OutputSnapshot>
-RealOutputConfiguratorDelegate::GetOutputs(
- const OutputConfigurator::StateController* state_controller) {
+RealOutputConfiguratorDelegate::GetOutputs() {
CHECK(screen_) << "Server not grabbed";
std::vector<OutputConfigurator::OutputSnapshot> outputs;
- XRROutputInfo* one_info = NULL;
- XRROutputInfo* two_info = NULL;
RRCrtc last_used_crtc = None;
for (int i = 0; i < screen_->noutput && outputs.size() < 2; ++i) {
RROutput output_id = screen_->outputs[i];
XRROutputInfo* output_info = XRRGetOutputInfo(display_, screen_, output_id);
- bool is_connected = (output_info->connection == RR_Connected);
-
- if (!is_connected) {
- XRRFreeOutputInfo(output_info);
- continue;
- }
-
- (outputs.empty() ? one_info : two_info) = output_info;
-
- OutputConfigurator::OutputSnapshot output = InitOutputSnapshot(
- output_id, output_info, &last_used_crtc, i);
-
- if (output.has_display_id) {
- int width = 0, height = 0;
- if (state_controller &&
- state_controller->GetResolutionForDisplayId(
- output.display_id, &width, &height)) {
- output.selected_mode =
- FindOutputModeMatchingSize(screen_, output_info, width, height);
- }
- }
- // Fall back to native mode.
- if (output.selected_mode == None)
- output.selected_mode = output.native_mode;
-
- VLOG(2) << "Found display " << outputs.size() << ":"
- << " output=" << output.output
- << " crtc=" << output.crtc
- << " current_mode=" << output.current_mode;
- outputs.push_back(output);
- }
-
- if (outputs.size() == 2) {
- bool one_is_internal = IsInternalOutput(one_info);
- bool two_is_internal = IsInternalOutput(two_info);
- int internal_outputs = (one_is_internal ? 1 : 0) +
- (two_is_internal ? 1 : 0);
- DCHECK_LT(internal_outputs, 2);
- LOG_IF(WARNING, internal_outputs == 2)
- << "Two internal outputs detected.";
-
- bool can_mirror = false;
- for (int attempt = 0; !can_mirror && attempt < 2; ++attempt) {
- // Try preserving external output's aspect ratio on the first attempt.
- // If that fails, fall back to the highest matching resolution.
- bool preserve_aspect = attempt == 0;
-
- if (internal_outputs == 1) {
- if (one_is_internal) {
- can_mirror = FindOrCreateMirrorMode(one_info, two_info,
- outputs[0].output, is_panel_fitting_enabled_, preserve_aspect,
- &outputs[0].mirror_mode, &outputs[1].mirror_mode);
- } else { // if (two_is_internal)
- can_mirror = FindOrCreateMirrorMode(two_info, one_info,
- outputs[1].output, is_panel_fitting_enabled_, preserve_aspect,
- &outputs[1].mirror_mode, &outputs[0].mirror_mode);
- }
- } else { // if (internal_outputs == 0)
- // No panel fitting for external outputs, so fall back to exact match.
- can_mirror = FindOrCreateMirrorMode(one_info, two_info,
- outputs[0].output, false, preserve_aspect,
- &outputs[0].mirror_mode, &outputs[1].mirror_mode);
- if (!can_mirror && preserve_aspect) {
- // FindOrCreateMirrorMode will try to preserve aspect ratio of
- // what it thinks is external display, so if it didn't succeed
- // with one, maybe it will succeed with the other. This way we
- // will have correct aspect ratio on at least one of them.
- can_mirror = FindOrCreateMirrorMode(two_info, one_info,
- outputs[1].output, false, preserve_aspect,
- &outputs[1].mirror_mode, &outputs[0].mirror_mode);
- }
- }
+ if (output_info->connection == RR_Connected) {
+ OutputConfigurator::OutputSnapshot output = InitOutputSnapshot(
+ output_id, output_info, &last_used_crtc, i);
+ VLOG(2) << "Found display " << outputs.size() << ":"
+ << " output=" << output.output
+ << " crtc=" << output.crtc
+ << " current_mode=" << output.current_mode;
+ outputs.push_back(output);
}
+ XRRFreeOutputInfo(output_info);
}
GetTouchscreens(&outputs);
- XRRFreeOutputInfo(one_info);
- XRRFreeOutputInfo(two_info);
return outputs;
}
+void RealOutputConfiguratorDelegate::AddOutputMode(RROutput output,
+ RRMode mode) {
+ CHECK(screen_) << "Server not grabbed";
+ VLOG(1) << "AddOutputMode: output=" << output << " mode=" << mode;
+ XRRAddOutputMode(display_, output, mode);
+}
+
bool RealOutputConfiguratorDelegate::ConfigureCrtc(
RRCrtc crtc,
RRMode mode,
@@ -291,10 +225,10 @@ void RealOutputConfiguratorDelegate::SendProjectingStateToPowerManager(
SetIsProjecting(projecting);
}
-bool RealOutputConfiguratorDelegate::GetModeDetails(RRMode mode,
- int* width,
- int* height,
- bool* interlaced) {
+bool RealOutputConfiguratorDelegate::InitModeInfo(
+ RRMode mode,
+ OutputConfigurator::ModeInfo* mode_info) {
+ DCHECK(mode_info);
CHECK(screen_) << "Server not grabbed";
// TODO: Determine if we need to organize modes in a way which provides
// better than O(n) lookup time. In many call sites, for example, the
@@ -303,12 +237,16 @@ bool RealOutputConfiguratorDelegate::GetModeDetails(RRMode mode,
for (int i = 0; i < screen_->nmode; ++i) {
if (mode == screen_->modes[i].id) {
const XRRModeInfo& info = screen_->modes[i];
- if (width)
- *width = info.width;
- if (height)
- *height = info.height;
- if (interlaced)
- *interlaced = info.modeFlags & RR_Interlace;
+ mode_info->width = info.width;
+ mode_info->height = info.height;
+ mode_info->interlaced = info.modeFlags & RR_Interlace;
+ if (info.hTotal && info.vTotal) {
+ mode_info->refresh_rate = static_cast<float>(info.dotClock) /
+ (static_cast<float>(info.hTotal) *
+ static_cast<float>(info.vTotal));
+ } else {
+ mode_info->refresh_rate = 0.0f;
+ }
return true;
}
}
@@ -359,12 +297,10 @@ RealOutputConfiguratorDelegate::InitOutputSnapshot(
for (int i = 0; i < info->nmode; ++i) {
const RRMode mode = info->modes[i];
OutputConfigurator::ModeInfo mode_info;
- if (GetModeDetails(mode, &mode_info.width, &mode_info.height,
- &mode_info.interlaced)) {
+ if (InitModeInfo(mode, &mode_info))
output.mode_infos.insert(std::make_pair(mode, mode_info));
- } else {
+ else
LOG(WARNING) << "Unable to find XRRModeInfo for mode " << mode;
- }
}
return output;
@@ -458,80 +394,6 @@ bool RealOutputConfiguratorDelegate::IsOutputAspectPreservingScaling(
return ret;
}
-bool RealOutputConfiguratorDelegate::FindOrCreateMirrorMode(
- XRROutputInfo* internal_info,
- XRROutputInfo* external_info,
- RROutput internal_output_id,
- bool try_creating,
- bool preserve_aspect,
- RRMode* internal_mirror_mode,
- RRMode* external_mirror_mode) {
- RRMode internal_mode_id = GetOutputNativeMode(internal_info);
- RRMode external_mode_id = GetOutputNativeMode(external_info);
-
- if (internal_mode_id == None || external_mode_id == None)
- return false;
-
- int internal_native_width = 0, internal_native_height = 0;
- int external_native_width = 0, external_native_height = 0;
- CHECK(GetModeDetails(internal_mode_id, &internal_native_width,
- &internal_native_height, NULL));
- CHECK(GetModeDetails(external_mode_id, &external_native_width,
- &external_native_height, NULL));
-
- // Check if some external output resolution can be mirrored on internal.
- // Prefer the modes in the order that X sorts them,
- // assuming this is the order in which they look better on the monitor.
- // If X's order is not satisfactory, we can either fix X's sorting,
- // or implement our sorting here.
- for (int i = 0; i < external_info->nmode; i++) {
- external_mode_id = external_info->modes[i];
- int external_width = 0, external_height = 0;
- bool is_external_interlaced = false;
- CHECK(GetModeDetails(external_mode_id, &external_width, &external_height,
- &is_external_interlaced));
- bool is_native_aspect_ratio =
- external_native_width * external_height ==
- external_native_height * external_width;
- if (preserve_aspect && !is_native_aspect_ratio)
- continue; // Allow only aspect ratio preserving modes for mirroring
-
- // Try finding exact match
- for (int j = 0; j < internal_info->nmode; j++) {
- internal_mode_id = internal_info->modes[j];
- int internal_width = 0, internal_height = 0;
- bool is_internal_interlaced = false;
- CHECK(GetModeDetails(internal_mode_id, &internal_width,
- &internal_height, &is_internal_interlaced));
- if (internal_width == external_width &&
- internal_height == external_height &&
- is_internal_interlaced == is_external_interlaced) {
- *internal_mirror_mode = internal_mode_id;
- *external_mirror_mode = external_mode_id;
- return true; // Mirror mode found
- }
- }
-
- // Try to create a matching internal output mode by panel fitting
- if (try_creating) {
- // We can downscale by 1.125, and upscale indefinitely
- // Downscaling looks ugly, so, can fit == can upscale
- // Also, internal panels don't support fitting interlaced modes
- bool can_fit =
- internal_native_width >= external_width &&
- internal_native_height >= external_height &&
- !is_external_interlaced;
- if (can_fit) {
- XRRAddOutputMode(display_, internal_output_id, external_mode_id);
- *internal_mirror_mode = *external_mirror_mode = external_mode_id;
- return true; // Mirror mode created
- }
- }
- }
-
- return false;
-}
-
void RealOutputConfiguratorDelegate::GetTouchscreens(
std::vector<OutputConfigurator::OutputSnapshot>* outputs) {
int ndevices = 0;
« no previous file with comments | « chromeos/display/real_output_configurator_delegate.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698