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..2e35fe2bd8ede5c064742ff6d9f07de9643a30a3 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, |
@@ -294,7 +228,8 @@ void RealOutputConfiguratorDelegate::SendProjectingStateToPowerManager( |
bool RealOutputConfiguratorDelegate::GetModeDetails(RRMode mode, |
int* width, |
int* height, |
- bool* interlaced) { |
+ bool* interlaced, |
+ float* refresh_rate) { |
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 |
@@ -309,6 +244,15 @@ bool RealOutputConfiguratorDelegate::GetModeDetails(RRMode mode, |
*height = info.height; |
if (interlaced) |
*interlaced = info.modeFlags & RR_Interlace; |
+ if (refresh_rate) { |
+ if (info.hTotal && info.vTotal) { |
+ *refresh_rate = static_cast<float>(info.dotClock) / |
+ (static_cast<float>(info.hTotal) * |
+ static_cast<float>(info.vTotal)); |
+ } else { |
+ *refresh_rate = 0.0f; |
+ } |
+ } |
return true; |
} |
} |
@@ -360,7 +304,7 @@ RealOutputConfiguratorDelegate::InitOutputSnapshot( |
const RRMode mode = info->modes[i]; |
OutputConfigurator::ModeInfo mode_info; |
if (GetModeDetails(mode, &mode_info.width, &mode_info.height, |
- &mode_info.interlaced)) { |
+ &mode_info.interlaced, &mode_info.refresh_rate)) { |
output.mode_infos.insert(std::make_pair(mode, mode_info)); |
} else { |
LOG(WARNING) << "Unable to find XRRModeInfo for mode " << mode; |
@@ -458,80 +402,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; |