Chromium Code Reviews| Index: chromeos/display/output_configurator.cc |
| diff --git a/chromeos/display/output_configurator.cc b/chromeos/display/output_configurator.cc |
| index bc6124815ce0aeef3a7a47bdcde20e7086602deb..9d3e0f413e307f3ee4614b953f8e4e9b5a0d74f4 100644 |
| --- a/chromeos/display/output_configurator.cc |
| +++ b/chromeos/display/output_configurator.cc |
| @@ -13,9 +13,10 @@ |
| #include "base/strings/stringprintf.h" |
| #include "base/sys_info.h" |
| #include "base/time/time.h" |
| -#include "chromeos/display/native_display_delegate_x11.h" |
| -#include "chromeos/display/output_util.h" |
| #include "chromeos/display/touchscreen_delegate_x11.h" |
| +#include "ui/display/chromeos/display_mode.h" |
| +#include "ui/display/chromeos/display_snapshot.h" |
| +#include "ui/display/chromeos/x11/native_display_delegate_x11.h" |
| namespace chromeos { |
| @@ -59,34 +60,20 @@ std::string OutputStateToString(ui::OutputState state) { |
| return "INVALID"; |
| } |
| -// Returns a string representation of OutputSnapshot. |
| -std::string OutputSnapshotToString( |
| - const OutputConfigurator::OutputSnapshot* output) { |
| - return base::StringPrintf( |
| - "[type=%d, output=%ld, crtc=%ld, mode=%ld, dim=%dx%d]", |
| - output->type, |
| - output->output, |
| - output->crtc, |
| - output->current_mode, |
| - static_cast<int>(output->width_mm), |
| - static_cast<int>(output->height_mm)); |
| -} |
| - |
| -// Returns a string representation of ModeInfo. |
| -std::string ModeInfoToString(const OutputConfigurator::ModeInfo* mode) { |
| +// Returns a string representation of ui::DisplayMode. |
|
Daniel Erat
2014/03/05 01:56:12
nit: maybe add a TODO to move this to DisplayMode
dnicoara
2014/03/05 17:29:25
Done.
|
| +std::string DisplayModeToString(const ui::DisplayMode* mode) { |
| return base::StringPrintf("[%dx%d %srate=%f]", |
| - mode->width, |
| - mode->height, |
| - mode->interlaced ? "interlaced " : "", |
| - mode->refresh_rate); |
| - |
| + mode->size().width(), |
| + mode->size().height(), |
| + mode->is_interlaced() ? "interlaced " : "", |
| + mode->refresh_rate()); |
| } |
| // Returns the number of outputs in |outputs| that should be turned on, per |
| // |state|. If |output_power| is non-NULL, it is updated to contain the |
| // on/off state of each corresponding entry in |outputs|. |
| int GetOutputPower( |
| - const std::vector<OutputConfigurator::OutputSnapshot>& outputs, |
| + const std::vector<OutputConfigurator::InternalDisplayState>& outputs, |
| DisplayPowerState state, |
| std::vector<bool>* output_power) { |
| int num_on_outputs = 0; |
| @@ -94,7 +81,7 @@ int GetOutputPower( |
| output_power->resize(outputs.size()); |
| for (size_t i = 0; i < outputs.size(); ++i) { |
| - bool internal = outputs[i].type == ui::OUTPUT_TYPE_INTERNAL; |
| + bool internal = outputs[i].display->type() == ui::OUTPUT_TYPE_INTERNAL; |
| bool on = state == DISPLAY_POWER_ALL_ON || |
| (state == DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON && !internal) || |
| (state == DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF && internal); |
| @@ -108,46 +95,17 @@ int GetOutputPower( |
| } // namespace |
| -OutputConfigurator::ModeInfo::ModeInfo() |
| - : width(0), |
| - height(0), |
| - interlaced(false), |
| - refresh_rate(0.0) {} |
| - |
| -OutputConfigurator::ModeInfo::ModeInfo(int width, |
| - int height, |
| - bool interlaced, |
| - float refresh_rate) |
| - : width(width), |
| - height(height), |
| - interlaced(interlaced), |
| - refresh_rate(refresh_rate) {} |
| - |
| OutputConfigurator::CoordinateTransformation::CoordinateTransformation() |
| : x_scale(1.0), |
| x_offset(0.0), |
| y_scale(1.0), |
| y_offset(0.0) {} |
| -OutputConfigurator::OutputSnapshot::OutputSnapshot() |
| - : output(None), |
| - crtc(None), |
| - current_mode(None), |
| - native_mode(None), |
| - mirror_mode(None), |
| - selected_mode(None), |
| - x(0), |
| - y(0), |
| - width_mm(0), |
| - height_mm(0), |
| - is_aspect_preserving_scaling(false), |
| - type(ui::OUTPUT_TYPE_UNKNOWN), |
| +OutputConfigurator::InternalDisplayState::InternalDisplayState() |
| + : display(NULL), |
| touch_device_id(0), |
| - display_id(0), |
| - has_display_id(false), |
| - index(0) {} |
| - |
| -OutputConfigurator::OutputSnapshot::~OutputSnapshot() {} |
| + selected_mode(NULL), |
| + mirror_mode(NULL) {} |
| bool OutputConfigurator::TestApi::TriggerConfigureTimeout() { |
| if (configurator_->configure_timer_.get() && |
| @@ -161,53 +119,41 @@ bool OutputConfigurator::TestApi::TriggerConfigureTimeout() { |
| } |
| // static |
| -const OutputConfigurator::ModeInfo* OutputConfigurator::GetModeInfo( |
| - const OutputSnapshot& output, |
| - RRMode mode) { |
| - if (mode == None) |
| - return NULL; |
| - |
| - ModeInfoMap::const_iterator it = output.mode_infos.find(mode); |
| - if (it == output.mode_infos.end()) { |
| - LOG(WARNING) << "Unable to find info about mode " << mode |
| - << " for output " << output.output; |
| - return NULL; |
| - } |
| - return &it->second; |
| -} |
| +const ui::DisplayMode* OutputConfigurator::FindDisplayModeMatchingSize( |
| + const ui::DisplaySnapshot& output, |
| + const gfx::Size& size) { |
| + const ui::DisplayMode* best_mode = NULL; |
| + for (DisplayModeList::const_iterator it = output.modes().begin(); |
| + it != output.modes().end(); |
| + ++it) { |
| + const ui::DisplayMode* mode = *it; |
| -// static |
| -RRMode OutputConfigurator::FindOutputModeMatchingSize( |
| - const OutputSnapshot& output, |
| - int width, |
| - int height) { |
| - RRMode found = None; |
| - float best_rate = 0; |
| - bool non_interlaced_found = false; |
| - for (ModeInfoMap::const_iterator it = output.mode_infos.begin(); |
| - it != output.mode_infos.end(); ++it) { |
| - RRMode mode = it->first; |
| - const ModeInfo& info = it->second; |
| - |
| - if (info.width == width && info.height == height) { |
| - if (info.interlaced) { |
| - if (non_interlaced_found) |
| - continue; |
| - } else { |
| - // Reset the best rate if the non interlaced is |
| - // found the first time. |
| - if (!non_interlaced_found) |
| - best_rate = info.refresh_rate; |
| - non_interlaced_found = true; |
| - } |
| - if (info.refresh_rate < best_rate) |
| - continue; |
| + if (mode->size() != size) |
| + continue; |
| - found = mode; |
| - best_rate = info.refresh_rate; |
| + if (!best_mode) { |
| + best_mode = mode; |
| + continue; |
| + } |
| + |
| + if (mode->is_interlaced()) { |
| + if (!best_mode->is_interlaced()) |
| + continue; |
| + } else { |
| + // Reset the best rate if the non interlaced is |
| + // found the first time. |
| + if (best_mode->is_interlaced()) { |
| + best_mode = mode; |
| + continue; |
| + } |
| } |
| + if (mode->refresh_rate() < best_mode->refresh_rate()) |
| + continue; |
| + |
| + best_mode = mode; |
| } |
| - return found; |
| + |
| + return best_mode; |
| } |
| OutputConfigurator::OutputConfigurator() |
| @@ -225,7 +171,7 @@ OutputConfigurator::~OutputConfigurator() { |
| } |
| void OutputConfigurator::SetNativeDisplayDelegateForTesting( |
| - scoped_ptr<NativeDisplayDelegate> delegate) { |
| + scoped_ptr<ui::NativeDisplayDelegate> delegate) { |
| DCHECK(!native_display_delegate_); |
| native_display_delegate_ = delegate.Pass(); |
| @@ -251,7 +197,7 @@ void OutputConfigurator::Init(bool is_panel_fitting_enabled) { |
| return; |
| if (!native_display_delegate_) { |
| - native_display_delegate_.reset(new NativeDisplayDelegateX11()); |
| + native_display_delegate_.reset(new ui::NativeDisplayDelegateX11()); |
| native_display_delegate_->AddObserver(this); |
| } |
| @@ -281,14 +227,16 @@ void OutputConfigurator::ForceInitialConfigure(uint32 background_color_argb) { |
| } |
| bool OutputConfigurator::ApplyProtections(const DisplayProtections& requests) { |
| - for (std::vector<OutputSnapshot>::const_iterator it = cached_outputs_.begin(); |
| - it != cached_outputs_.end(); ++it) { |
| + for (std::vector<InternalDisplayState>::const_iterator it = |
| + cached_outputs_.begin(); |
| + it != cached_outputs_.end(); |
| + ++it) { |
| uint32_t all_desired = 0; |
| - DisplayProtections::const_iterator request_it = requests.find( |
| - it->display_id); |
| + DisplayProtections::const_iterator request_it = |
| + requests.find(it->display->display_id()); |
| if (request_it != requests.end()) |
| all_desired = request_it->second; |
| - switch (it->type) { |
| + switch (it->display->type()) { |
| case ui::OUTPUT_TYPE_UNKNOWN: |
| return false; |
| // DisplayPort, DVI, and HDMI all support HDCP. |
| @@ -299,7 +247,8 @@ bool OutputConfigurator::ApplyProtections(const DisplayProtections& requests) { |
| (all_desired & ui::OUTPUT_PROTECTION_METHOD_HDCP) |
| ? ui::HDCP_STATE_DESIRED |
| : ui::HDCP_STATE_UNDESIRED; |
| - if (!native_display_delegate_->SetHDCPState(*it, new_desired_state)) |
| + if (!native_display_delegate_->SetHDCPState(*it->display, |
| + new_desired_state)) |
| return false; |
| break; |
| } |
| @@ -354,12 +303,14 @@ bool OutputConfigurator::QueryOutputProtectionStatus( |
| uint32_t enabled = 0; |
| uint32_t unfulfilled = 0; |
| *link_mask = 0; |
| - for (std::vector<OutputSnapshot>::const_iterator it = cached_outputs_.begin(); |
| - it != cached_outputs_.end(); ++it) { |
| - if (it->display_id != display_id) |
| + for (std::vector<InternalDisplayState>::const_iterator it = |
| + cached_outputs_.begin(); |
| + it != cached_outputs_.end(); |
| + ++it) { |
| + if (it->display->display_id() != display_id) |
| continue; |
| - *link_mask |= it->type; |
| - switch (it->type) { |
| + *link_mask |= it->display->type(); |
| + switch (it->display->type()) { |
| case ui::OUTPUT_TYPE_UNKNOWN: |
| return false; |
| // DisplayPort, DVI, and HDMI all support HDCP. |
| @@ -367,7 +318,7 @@ bool OutputConfigurator::QueryOutputProtectionStatus( |
| case ui::OUTPUT_TYPE_DVI: |
| case ui::OUTPUT_TYPE_HDMI: { |
| ui::HDCPState state; |
| - if (!native_display_delegate_->GetHDCPState(*it, &state)) |
| + if (!native_display_delegate_->GetHDCPState(*it->display, &state)) |
| return false; |
| if (state == ui::HDCP_STATE_ENABLED) |
| enabled |= ui::OUTPUT_PROTECTION_METHOD_HDCP; |
| @@ -465,7 +416,7 @@ bool OutputConfigurator::SetDisplayPower(DisplayPowerState power_state, |
| flags & kSetDisplayPowerOnlyIfSingleInternalDisplay; |
| bool single_internal_display = |
| cached_outputs_.size() == 1 && |
| - cached_outputs_[0].type == ui::OUTPUT_TYPE_INTERNAL; |
| + cached_outputs_[0].display->type() == ui::OUTPUT_TYPE_INTERNAL; |
| if (single_internal_display || !only_if_single_internal_display) { |
| success = EnterStateOrFallBackToSoftwareMirroring(new_state, power_state); |
| attempted_change = true; |
| @@ -553,30 +504,40 @@ void OutputConfigurator::ResumeDisplays() { |
| } |
| void OutputConfigurator::UpdateCachedOutputs() { |
| - cached_outputs_ = native_display_delegate_->GetOutputs(); |
| + std::vector<ui::DisplaySnapshot*> snapshots = |
| + native_display_delegate_->GetOutputs(); |
| + |
| + cached_outputs_.clear(); |
| + for (size_t i = 0; i < snapshots.size(); ++i) { |
| + InternalDisplayState display_state; |
| + display_state.display = snapshots[i]; |
| + cached_outputs_.push_back(display_state); |
| + } |
| + |
| touchscreen_delegate_->AssociateTouchscreens(&cached_outputs_); |
| // Set |selected_mode| fields. |
| for (size_t i = 0; i < cached_outputs_.size(); ++i) { |
| - OutputSnapshot* output = &cached_outputs_[i]; |
| - if (output->has_display_id) { |
| - int width = 0, height = 0; |
| - if (state_controller_ && |
| - state_controller_->GetResolutionForDisplayId( |
| - output->display_id, &width, &height)) { |
| + InternalDisplayState* output = &cached_outputs_[i]; |
| + if (output->display->has_proper_display_id()) { |
| + gfx::Size size; |
| + if (state_controller_ && state_controller_->GetResolutionForDisplayId( |
| + output->display->display_id(), &size)) { |
| output->selected_mode = |
| - FindOutputModeMatchingSize(*output, width, height); |
| + FindDisplayModeMatchingSize(*output->display, size); |
| } |
| } |
| // Fall back to native mode. |
| - if (output->selected_mode == None) |
| - output->selected_mode = output->native_mode; |
| + if (!output->selected_mode) |
| + output->selected_mode = output->display->native_mode(); |
| } |
| // Set |mirror_mode| fields. |
| if (cached_outputs_.size() == 2) { |
| - bool one_is_internal = cached_outputs_[0].type == ui::OUTPUT_TYPE_INTERNAL; |
| - bool two_is_internal = cached_outputs_[1].type == ui::OUTPUT_TYPE_INTERNAL; |
| + bool one_is_internal = |
| + cached_outputs_[0].display->type() == ui::OUTPUT_TYPE_INTERNAL; |
| + bool two_is_internal = |
| + cached_outputs_[1].display->type() == ui::OUTPUT_TYPE_INTERNAL; |
| int internal_outputs = (one_is_internal ? 1 : 0) + |
| (two_is_internal ? 1 : 0); |
| DCHECK_LT(internal_outputs, 2); |
| @@ -615,40 +576,42 @@ void OutputConfigurator::UpdateCachedOutputs() { |
| } |
| } |
| -bool OutputConfigurator::FindMirrorMode(OutputSnapshot* internal_output, |
| - OutputSnapshot* external_output, |
| +bool OutputConfigurator::FindMirrorMode(InternalDisplayState* internal_output, |
| + InternalDisplayState* external_output, |
| bool try_panel_fitting, |
| bool preserve_aspect) { |
| - const ModeInfo* internal_native_info = |
| - GetModeInfo(*internal_output, internal_output->native_mode); |
| - const ModeInfo* external_native_info = |
| - GetModeInfo(*external_output, external_output->native_mode); |
| + const ui::DisplayMode* internal_native_info = |
| + internal_output->display->native_mode(); |
| + const ui::DisplayMode* external_native_info = |
| + external_output->display->native_mode(); |
| if (!internal_native_info || !external_native_info) |
| return false; |
| // 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. |
| - for (ModeInfoMap::const_iterator external_it = |
| - external_output->mode_infos.begin(); |
| - external_it != external_output->mode_infos.end(); ++external_it) { |
| - const ModeInfo& external_info = external_it->second; |
| + for (DisplayModeList::const_iterator external_it = |
| + external_output->display->modes().begin(); |
| + external_it != external_output->display->modes().end(); |
| + ++external_it) { |
| + const ui::DisplayMode& external_info = **external_it; |
| bool is_native_aspect_ratio = |
| - external_native_info->width * external_info.height == |
| - external_native_info->height * external_info.width; |
| + external_native_info->size().width() * external_info.size().height() == |
| + external_native_info->size().height() * external_info.size().width(); |
| if (preserve_aspect && !is_native_aspect_ratio) |
| continue; // Allow only aspect ratio preserving modes for mirroring. |
| // Try finding an exact match. |
| - for (ModeInfoMap::const_iterator internal_it = |
| - internal_output->mode_infos.begin(); |
| - internal_it != internal_output->mode_infos.end(); ++internal_it) { |
| - const ModeInfo& internal_info = internal_it->second; |
| - if (internal_info.width == external_info.width && |
| - internal_info.height == external_info.height && |
| - internal_info.interlaced == external_info.interlaced) { |
| - internal_output->mirror_mode = internal_it->first; |
| - external_output->mirror_mode = external_it->first; |
| + for (DisplayModeList::const_iterator internal_it = |
| + internal_output->display->modes().begin(); |
| + internal_it != internal_output->display->modes().end(); |
| + ++internal_it) { |
| + const ui::DisplayMode& internal_info = **internal_it; |
| + if (internal_info.size().width() == external_info.size().width() && |
| + internal_info.size().height() == external_info.size().height() && |
| + internal_info.is_interlaced() == external_info.is_interlaced()) { |
| + internal_output->mirror_mode = *internal_it; |
| + external_output->mirror_mode = *external_it; |
| return true; // Mirror mode found. |
| } |
| } |
| @@ -658,16 +621,17 @@ bool OutputConfigurator::FindMirrorMode(OutputSnapshot* internal_output, |
| // 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_info->width >= external_info.width && |
| - internal_native_info->height >= external_info.height && |
| - !external_info.interlaced; |
| + bool can_fit = internal_native_info->size().width() >= |
| + external_info.size().width() && |
| + internal_native_info->size().height() >= |
| + external_info.size().height() && |
| + !external_info.is_interlaced(); |
| if (can_fit) { |
| - RRMode mode = external_it->first; |
| - native_display_delegate_->AddMode(*internal_output, mode); |
| - internal_output->mode_infos.insert(std::make_pair(mode, external_info)); |
| - internal_output->mirror_mode = mode; |
| - external_output->mirror_mode = mode; |
| + native_display_delegate_->AddMode(*internal_output->display, |
| + *external_it); |
| + internal_output->display->add_mode(*external_it); |
| + internal_output->mirror_mode = *external_it; |
| + external_output->mirror_mode = *external_it; |
| return true; // Mirror mode created. |
| } |
| } |
| @@ -730,84 +694,78 @@ bool OutputConfigurator::EnterState(ui::OutputState output_state, |
| << " power=" << DisplayPowerStateToString(power_state); |
| // Framebuffer dimensions. |
| - int width = 0, height = 0; |
| - std::vector<OutputSnapshot> updated_outputs = cached_outputs_; |
| + gfx::Size size; |
| + |
| + std::vector<gfx::Point> new_origins(cached_outputs_.size(), gfx::Point()); |
| + std::vector<const ui::DisplayMode*> new_mode; |
| + for (size_t i = 0; i < cached_outputs_.size(); ++i) { |
|
Daniel Erat
2014/03/05 01:56:12
nit: remove curly brackets
dnicoara
2014/03/05 17:29:25
Done.
|
| + new_mode.push_back(cached_outputs_[i].display->current_mode()); |
| + } |
| switch (output_state) { |
| case ui::OUTPUT_STATE_INVALID: |
| NOTREACHED() << "Ignoring request to enter invalid state with " |
| - << updated_outputs.size() << " connected output(s)"; |
| + << cached_outputs_.size() << " connected output(s)"; |
| return false; |
| case ui::OUTPUT_STATE_HEADLESS: |
| - if (updated_outputs.size() != 0) { |
| + if (cached_outputs_.size() != 0) { |
| LOG(WARNING) << "Ignoring request to enter headless mode with " |
| - << updated_outputs.size() << " connected output(s)"; |
| + << cached_outputs_.size() << " connected output(s)"; |
| return false; |
| } |
| break; |
| case ui::OUTPUT_STATE_SINGLE: { |
| // If there are multiple outputs connected, only one should be turned on. |
| - if (updated_outputs.size() != 1 && num_on_outputs != 1) { |
| + if (cached_outputs_.size() != 1 && num_on_outputs != 1) { |
| LOG(WARNING) << "Ignoring request to enter single mode with " |
| - << updated_outputs.size() << " connected outputs and " |
| + << cached_outputs_.size() << " connected outputs and " |
| << num_on_outputs << " turned on"; |
| return false; |
| } |
| - for (size_t i = 0; i < updated_outputs.size(); ++i) { |
| - OutputSnapshot* output = &updated_outputs[i]; |
| - output->x = 0; |
| - output->y = 0; |
| - output->current_mode = output_power[i] ? output->selected_mode : None; |
| + for (size_t i = 0; i < cached_outputs_.size(); ++i) { |
| + InternalDisplayState* output = &cached_outputs_[i]; |
| + new_mode[i] = output_power[i] ? output->selected_mode : NULL; |
| - if (output_power[i] || updated_outputs.size() == 1) { |
| - const ModeInfo* mode_info = |
| - GetModeInfo(*output, output->selected_mode); |
| + if (output_power[i] || cached_outputs_.size() == 1) { |
| + const ui::DisplayMode* mode_info = output->selected_mode; |
| if (!mode_info) |
| return false; |
| - if (mode_info->width == 1024 && mode_info->height == 768) { |
| + if (mode_info->size() == gfx::Size(1024, 768)) { |
| VLOG(1) << "Potentially misdetecting display(1024x768):" |
| - << " outputs size=" << updated_outputs.size() |
| + << " outputs size=" << cached_outputs_.size() |
| << ", num_on_outputs=" << num_on_outputs |
| - << ", current size:" << width << "x" << height |
| - << ", i=" << i |
| - << ", output=" << OutputSnapshotToString(output) |
| - << ", mode_info=" << ModeInfoToString(mode_info); |
| + << ", current size:" << size.width() << "x" << size.height() |
| + << ", i=" << i << ", output=" << output->display->ToString() |
| + << ", display_mode=" << DisplayModeToString(mode_info); |
| } |
| - width = mode_info->width; |
| - height = mode_info->height; |
| + size = mode_info->size(); |
| } |
| } |
| break; |
| } |
| case ui::OUTPUT_STATE_DUAL_MIRROR: { |
| - if (updated_outputs.size() != 2 || |
| + if (cached_outputs_.size() != 2 || |
| (num_on_outputs != 0 && num_on_outputs != 2)) { |
| LOG(WARNING) << "Ignoring request to enter mirrored mode with " |
| - << updated_outputs.size() << " connected output(s) and " |
| + << cached_outputs_.size() << " connected output(s) and " |
| << num_on_outputs << " turned on"; |
| return false; |
| } |
| - if (!updated_outputs[0].mirror_mode) |
| - return false; |
| - const ModeInfo* mode_info = |
| - GetModeInfo(updated_outputs[0], updated_outputs[0].mirror_mode); |
| + const ui::DisplayMode* mode_info = cached_outputs_[0].mirror_mode; |
| if (!mode_info) |
| return false; |
| - width = mode_info->width; |
| - height = mode_info->height; |
| - |
| - for (size_t i = 0; i < updated_outputs.size(); ++i) { |
| - OutputSnapshot* output = &updated_outputs[i]; |
| - output->x = 0; |
| - output->y = 0; |
| - output->current_mode = output_power[i] ? output->mirror_mode : None; |
| + size = mode_info->size(); |
| + |
| + for (size_t i = 0; i < cached_outputs_.size(); ++i) { |
| + InternalDisplayState* output = &cached_outputs_[i]; |
| + new_mode[i] = output_power[i] ? output->mirror_mode : NULL; |
| if (output->touch_device_id) { |
| // CTM needs to be calculated if aspect preserving scaling is used. |
| // Otherwise, assume it is full screen, and use identity CTM. |
| - if (output->mirror_mode != output->native_mode && |
| - output->is_aspect_preserving_scaling) { |
| + if (output->mirror_mode != output->display->native_mode() && |
| + output->display->is_aspect_preserving_scaling()) { |
| output->transform = GetMirrorModeCTM(*output); |
| mirrored_display_area_ratio_map_[output->touch_device_id] = |
| GetMirroredDisplayAreaRatio(*output); |
| @@ -817,65 +775,59 @@ bool OutputConfigurator::EnterState(ui::OutputState output_state, |
| break; |
| } |
| case ui::OUTPUT_STATE_DUAL_EXTENDED: { |
| - if (updated_outputs.size() != 2 || |
| + if (cached_outputs_.size() != 2 || |
| (num_on_outputs != 0 && num_on_outputs != 2)) { |
| LOG(WARNING) << "Ignoring request to enter extended mode with " |
| - << updated_outputs.size() << " connected output(s) and " |
| + << cached_outputs_.size() << " connected output(s) and " |
| << num_on_outputs << " turned on"; |
| return false; |
| } |
| - for (size_t i = 0; i < updated_outputs.size(); ++i) { |
| - OutputSnapshot* output = &updated_outputs[i]; |
| - output->x = 0; |
| - output->y = height ? height + kVerticalGap : 0; |
| - output->current_mode = output_power[i] ? output->selected_mode : None; |
| + for (size_t i = 0; i < cached_outputs_.size(); ++i) { |
| + InternalDisplayState* output = &cached_outputs_[i]; |
| + new_origins[i].set_y(size.height() ? size.height() + kVerticalGap : 0); |
| + new_mode[i] = output_power[i] ? output->selected_mode : NULL; |
| // Retain the full screen size even if all outputs are off so the |
| // same desktop configuration can be restored when the outputs are |
| // turned back on. |
| - const ModeInfo* mode_info = |
| - GetModeInfo(updated_outputs[i], updated_outputs[i].selected_mode); |
| + const ui::DisplayMode* mode_info = cached_outputs_[i].selected_mode; |
| if (!mode_info) |
| return false; |
| - width = std::max<int>(width, mode_info->width); |
| - height += (height ? kVerticalGap : 0) + mode_info->height; |
| + |
| + size.set_width(std::max<int>(size.width(), mode_info->size().width())); |
| + size.set_height(size.height() + (size.height() ? kVerticalGap : 0) + |
| + mode_info->size().height()); |
| } |
| - for (size_t i = 0; i < updated_outputs.size(); ++i) { |
| - OutputSnapshot* output = &updated_outputs[i]; |
| + for (size_t i = 0; i < cached_outputs_.size(); ++i) { |
| + InternalDisplayState* output = &cached_outputs_[i]; |
| if (output->touch_device_id) |
| - output->transform = GetExtendedModeCTM(*output, width, height); |
| + output->transform = GetExtendedModeCTM(*output, new_origins[i], size); |
| } |
| break; |
| } |
| } |
| // Finally, apply the desired changes. |
| - DCHECK_EQ(cached_outputs_.size(), updated_outputs.size()); |
| bool all_succeeded = true; |
| - if (!updated_outputs.empty()) { |
| - native_display_delegate_->CreateFrameBuffer(width, height, updated_outputs); |
| - for (size_t i = 0; i < updated_outputs.size(); ++i) { |
| - const OutputSnapshot& output = updated_outputs[i]; |
| - bool configure_succeeded =false; |
| + if (!cached_outputs_.empty()) { |
| + native_display_delegate_->CreateFrameBuffer(size); |
| + for (size_t i = 0; i < cached_outputs_.size(); ++i) { |
| + const InternalDisplayState& output = cached_outputs_[i]; |
| + bool configure_succeeded = false; |
| while (true) { |
| - if (native_display_delegate_->Configure(output, |
| - output.current_mode, |
| - output.x, |
| - output.y)) { |
| + if (native_display_delegate_->Configure( |
| + *output.display, new_mode[i], new_origins[i])) { |
| + output.display->set_current_mode(new_mode[i]); |
| + output.display->set_origin(new_origins[i]); |
| + |
| configure_succeeded = true; |
| break; |
| } |
| - LOG(WARNING) << "Unable to configure CRTC " << output.crtc << ":" |
| - << " mode=" << output.current_mode |
| - << " output=" << output.output |
| - << " x=" << output.x |
| - << " y=" << output.y; |
| - |
| - const ModeInfo* mode_info = GetModeInfo(output, output.current_mode); |
| + const ui::DisplayMode* mode_info = new_mode[i]; |
| if (!mode_info) |
| break; |
| @@ -883,13 +835,15 @@ bool OutputConfigurator::EnterState(ui::OutputState output_state, |
| // be set. |
| int best_mode_pixels = 0; |
| - int current_mode_pixels = mode_info->width * mode_info->height; |
| - for (ModeInfoMap::const_iterator it = output.mode_infos.begin(); |
| - it != output.mode_infos.end(); it++) { |
| - int pixel_count = it->second.width * it->second.height; |
| + int current_mode_pixels = mode_info->size().GetArea(); |
| + for (DisplayModeList::const_iterator it = |
| + output.display->modes().begin(); |
| + it != output.display->modes().end(); |
| + it++) { |
| + int pixel_count = (*it)->size().GetArea(); |
| if ((pixel_count < current_mode_pixels) && |
| (pixel_count > best_mode_pixels)) { |
| - updated_outputs[i].current_mode = it->first; |
| + new_mode[i] = *it; |
| best_mode_pixels = pixel_count; |
| } |
| } |
| @@ -902,7 +856,6 @@ bool OutputConfigurator::EnterState(ui::OutputState output_state, |
| if (output.touch_device_id) |
| touchscreen_delegate_->ConfigureCTM(output.touch_device_id, |
| output.transform); |
| - cached_outputs_[i] = updated_outputs[i]; |
| } else { |
| all_succeeded = false; |
| } |
| @@ -911,7 +864,7 @@ bool OutputConfigurator::EnterState(ui::OutputState output_state, |
| // then the two monitors will be mis-matched. In this case, return |
| // false to let the observers be aware. |
| if (output_state == ui::OUTPUT_STATE_DUAL_MIRROR && output_power[i] && |
| - output.current_mode != output.mirror_mode) |
| + output.display->current_mode() != output.mirror_mode) |
| all_succeeded = false; |
| } |
| @@ -943,9 +896,9 @@ ui::OutputState OutputConfigurator::ChooseOutputState( |
| std::vector<int64> display_ids; |
| for (size_t i = 0; i < cached_outputs_.size(); ++i) { |
| // If display id isn't available, switch to extended mode. |
| - if (!cached_outputs_[i].has_display_id) |
| + if (!cached_outputs_[i].display->has_proper_display_id()) |
| return ui::OUTPUT_STATE_DUAL_EXTENDED; |
| - display_ids.push_back(cached_outputs_[i].display_id); |
| + display_ids.push_back(cached_outputs_[i].display->display_id()); |
| } |
| return state_controller_->GetStateForDisplayIds(display_ids); |
| } |
| @@ -957,21 +910,22 @@ ui::OutputState OutputConfigurator::ChooseOutputState( |
| } |
| OutputConfigurator::CoordinateTransformation |
| -OutputConfigurator::GetMirrorModeCTM( |
| - const OutputConfigurator::OutputSnapshot& output) { |
| +OutputConfigurator::GetMirrorModeCTM(const InternalDisplayState& output) { |
| CoordinateTransformation ctm; // Default to identity |
| - const ModeInfo* native_mode_info = GetModeInfo(output, output.native_mode); |
| - const ModeInfo* mirror_mode_info = GetModeInfo(output, output.mirror_mode); |
| + const ui::DisplayMode* native_mode_info = output.display->native_mode(); |
| + const ui::DisplayMode* mirror_mode_info = output.mirror_mode; |
| if (!native_mode_info || !mirror_mode_info || |
| - native_mode_info->height == 0 || mirror_mode_info->height == 0 || |
| - native_mode_info->width == 0 || mirror_mode_info->width == 0) |
| + native_mode_info->size().height() == 0 || |
| + mirror_mode_info->size().height() == 0 || |
| + native_mode_info->size().width() == 0 || |
| + mirror_mode_info->size().width() == 0) |
| return ctm; |
| - float native_mode_ar = static_cast<float>(native_mode_info->width) / |
| - static_cast<float>(native_mode_info->height); |
| - float mirror_mode_ar = static_cast<float>(mirror_mode_info->width) / |
| - static_cast<float>(mirror_mode_info->height); |
| + float native_mode_ar = static_cast<float>(native_mode_info->size().width()) / |
| + static_cast<float>(native_mode_info->size().height()); |
| + float mirror_mode_ar = static_cast<float>(mirror_mode_info->size().width()) / |
| + static_cast<float>(mirror_mode_info->size().height()); |
| if (mirror_mode_ar > native_mode_ar) { // Letterboxing |
| ctm.x_scale = 1.0; |
| @@ -992,12 +946,11 @@ OutputConfigurator::GetMirrorModeCTM( |
| } |
| OutputConfigurator::CoordinateTransformation |
| -OutputConfigurator::GetExtendedModeCTM( |
| - const OutputConfigurator::OutputSnapshot& output, |
| - int framebuffer_width, |
| - int framebuffer_height) { |
| +OutputConfigurator::GetExtendedModeCTM(const InternalDisplayState& output, |
| + const gfx::Point& new_origin, |
| + const gfx::Size& framebuffer_size) { |
| CoordinateTransformation ctm; // Default to identity |
| - const ModeInfo* mode_info = GetModeInfo(output, output.selected_mode); |
| + const ui::DisplayMode* mode_info = output.selected_mode; |
| DCHECK(mode_info); |
| if (!mode_info) |
| return ctm; |
| @@ -1021,30 +974,34 @@ OutputConfigurator::GetExtendedModeCTM( |
| // y_scale = (1600 - 1) / (2428 - 1) |
| // y_offset = 828 / (2428 -1) |
| // See the unittest OutputConfiguratorTest.CTMForMultiScreens. |
| - ctm.x_scale = |
| - static_cast<float>(mode_info->width - 1) / (framebuffer_width - 1); |
| - ctm.x_offset = static_cast<float>(output.x) / (framebuffer_width - 1); |
| - ctm.y_scale = |
| - static_cast<float>(mode_info->height - 1) / (framebuffer_height - 1); |
| - ctm.y_offset = static_cast<float>(output.y) / (framebuffer_height - 1); |
| + ctm.x_scale = static_cast<float>(mode_info->size().width() - 1) / |
| + (framebuffer_size.width() - 1); |
| + ctm.x_offset = |
| + static_cast<float>(new_origin.x()) / (framebuffer_size.width() - 1); |
| + ctm.y_scale = static_cast<float>(mode_info->size().height() - 1) / |
| + (framebuffer_size.height() - 1); |
| + ctm.y_offset = |
| + static_cast<float>(new_origin.y()) / (framebuffer_size.height() - 1); |
| return ctm; |
| } |
| float OutputConfigurator::GetMirroredDisplayAreaRatio( |
| - const OutputConfigurator::OutputSnapshot& output) { |
| + const InternalDisplayState& output) { |
| float area_ratio = 1.0f; |
| - const ModeInfo* native_mode_info = GetModeInfo(output, output.native_mode); |
| - const ModeInfo* mirror_mode_info = GetModeInfo(output, output.mirror_mode); |
| + const ui::DisplayMode* native_mode_info = output.display->native_mode(); |
| + const ui::DisplayMode* mirror_mode_info = output.mirror_mode; |
| if (!native_mode_info || !mirror_mode_info || |
| - native_mode_info->height == 0 || mirror_mode_info->height == 0 || |
| - native_mode_info->width == 0 || mirror_mode_info->width == 0) |
| + native_mode_info->size().height() == 0 || |
| + mirror_mode_info->size().height() == 0 || |
| + native_mode_info->size().width() == 0 || |
| + mirror_mode_info->size().width() == 0) |
| return area_ratio; |
| - float width_ratio = static_cast<float>(mirror_mode_info->width) / |
| - static_cast<float>(native_mode_info->width); |
| - float height_ratio = static_cast<float>(mirror_mode_info->height) / |
| - static_cast<float>(native_mode_info->height); |
| + float width_ratio = static_cast<float>(mirror_mode_info->size().width()) / |
| + static_cast<float>(native_mode_info->size().width()); |
| + float height_ratio = static_cast<float>(mirror_mode_info->size().height()) / |
| + static_cast<float>(native_mode_info->size().height()); |
| area_ratio = width_ratio * height_ratio; |
| return area_ratio; |