| Index: chromeos/display/output_configurator.cc
|
| diff --git a/chromeos/display/output_configurator.cc b/chromeos/display/output_configurator.cc
|
| index c1d2b30a654be1ce9207aefb29794d9f9914cb1d..a8c16813524c24cdd2c2cd52eac6bbeed1fe00c8 100644
|
| --- a/chromeos/display/output_configurator.cc
|
| +++ b/chromeos/display/output_configurator.cc
|
| @@ -98,6 +98,12 @@ bool IsProjecting(
|
|
|
| } // namespace
|
|
|
| +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),
|
| @@ -105,37 +111,14 @@ OutputConfigurator::OutputSnapshot::OutputSnapshot()
|
| native_mode(None),
|
| mirror_mode(None),
|
| selected_mode(None),
|
| + x(0),
|
| y(0),
|
| - height(0),
|
| is_internal(false),
|
| is_aspect_preserving_scaling(false),
|
| touch_device_id(0),
|
| display_id(0),
|
| has_display_id(false) {}
|
|
|
| -OutputConfigurator::CoordinateTransformation::CoordinateTransformation()
|
| - : x_scale(1.0),
|
| - x_offset(0.0),
|
| - y_scale(1.0),
|
| - y_offset(0.0) {}
|
| -
|
| -OutputConfigurator::CrtcConfig::CrtcConfig()
|
| - : crtc(None),
|
| - x(0),
|
| - y(0),
|
| - mode(None),
|
| - output(None) {}
|
| -
|
| -OutputConfigurator::CrtcConfig::CrtcConfig(RRCrtc crtc,
|
| - int x, int y,
|
| - RRMode mode,
|
| - RROutput output)
|
| - : crtc(crtc),
|
| - x(x),
|
| - y(y),
|
| - mode(mode),
|
| - output(output) {}
|
| -
|
| bool OutputConfigurator::TestApi::SendOutputChangeEvents(bool connected) {
|
| XRRScreenChangeNotifyEvent screen_event;
|
| memset(&screen_event, 0, sizeof(screen_event));
|
| @@ -418,7 +401,16 @@ bool OutputConfigurator::EnterState(
|
| int num_on_outputs = GetOutputPower(outputs, power_state, &output_power);
|
| VLOG(1) << "EnterState: output=" << OutputStateToString(output_state)
|
| << " power=" << DisplayPowerStateToString(power_state);
|
| +
|
| + // Framebuffer dimensions.
|
| + int width = 0, height = 0;
|
| + std::vector<OutputSnapshot> updated_outputs = outputs;
|
| +
|
| switch (output_state) {
|
| + case STATE_INVALID:
|
| + NOTREACHED() << "Ignoring request to enter invalid state with "
|
| + << outputs.size() << " connected output(s)";
|
| + return false;
|
| case STATE_HEADLESS:
|
| if (outputs.size() != 0) {
|
| LOG(WARNING) << "Ignoring request to enter headless mode with "
|
| @@ -435,28 +427,16 @@ bool OutputConfigurator::EnterState(
|
| return false;
|
| }
|
|
|
| - // Determine which output to use.
|
| - const OutputSnapshot& output = outputs.size() == 1 ? outputs[0] :
|
| - (output_power[0] ? outputs[0] : outputs[1]);
|
| - int width = 0, height = 0;
|
| - if (!delegate_->GetModeDetails(
|
| - output.selected_mode, &width, &height, NULL))
|
| - return false;
|
| -
|
| - std::vector<CrtcConfig> configs(outputs.size());
|
| - for (size_t i = 0; i < outputs.size(); ++i) {
|
| - configs[i] = CrtcConfig(
|
| - outputs[i].crtc, 0, 0,
|
| - output_power[i] ? outputs[i].selected_mode : None,
|
| - outputs[i].output);
|
| - }
|
| - delegate_->CreateFrameBuffer(width, height, configs);
|
| + 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 < outputs.size(); ++i) {
|
| - delegate_->ConfigureCrtc(&configs[i]);
|
| - if (outputs[i].touch_device_id) {
|
| - delegate_->ConfigureCTM(outputs[i].touch_device_id,
|
| - CoordinateTransformation());
|
| + if (output_power[i] || outputs.size() == 1) {
|
| + if (!delegate_->GetModeDetails(
|
| + output->selected_mode, &width, &height, NULL))
|
| + return false;
|
| }
|
| }
|
| break;
|
| @@ -469,34 +449,24 @@ bool OutputConfigurator::EnterState(
|
| return false;
|
| }
|
|
|
| - int width = 0, height = 0;
|
| if (!delegate_->GetModeDetails(
|
| - outputs[0].mirror_mode, &width, &height, NULL)) {
|
| + outputs[0].mirror_mode, &width, &height, NULL))
|
| return false;
|
| - }
|
|
|
| - std::vector<CrtcConfig> configs(outputs.size());
|
| for (size_t i = 0; i < outputs.size(); ++i) {
|
| - configs[i] = CrtcConfig(
|
| - outputs[i].crtc, 0, 0,
|
| - output_power[i] ? outputs[i].mirror_mode : None,
|
| - outputs[i].output);
|
| - }
|
| - delegate_->CreateFrameBuffer(width, height, configs);
|
| -
|
| - for (size_t i = 0; i < outputs.size(); ++i) {
|
| - delegate_->ConfigureCrtc(&configs[i]);
|
| - if (outputs[i].touch_device_id) {
|
| - CoordinateTransformation ctm;
|
| + OutputSnapshot* output = &updated_outputs[i];
|
| + output->x = 0;
|
| + output->y = 0;
|
| + output->current_mode = output_power[i] ? output->mirror_mode : None;
|
| + 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 (outputs[i].mirror_mode != outputs[i].native_mode &&
|
| - outputs[i].is_aspect_preserving_scaling) {
|
| - ctm = GetMirrorModeCTM(&outputs[i]);
|
| - mirrored_display_area_ratio_map_[outputs[i].touch_device_id] =
|
| - GetMirroredDisplayAreaRatio(&outputs[i]);
|
| + if (output->mirror_mode != output->native_mode &&
|
| + output->is_aspect_preserving_scaling) {
|
| + output->transform = GetMirrorModeCTM(output);
|
| + mirrored_display_area_ratio_map_[output->touch_device_id] =
|
| + GetMirroredDisplayAreaRatio(output);
|
| }
|
| - delegate_->ConfigureCTM(outputs[i].touch_device_id, ctm);
|
| }
|
| }
|
| break;
|
| @@ -511,8 +481,6 @@ bool OutputConfigurator::EnterState(
|
|
|
| // Pairs are [width, height] corresponding to the given output's mode.
|
| std::vector<std::pair<int, int> > mode_sizes(outputs.size());
|
| - std::vector<CrtcConfig> configs(outputs.size());
|
| - int width = 0, height = 0;
|
|
|
| for (size_t i = 0; i < outputs.size(); ++i) {
|
| if (!delegate_->GetModeDetails(outputs[i].selected_mode,
|
| @@ -520,10 +488,10 @@ bool OutputConfigurator::EnterState(
|
| return false;
|
| }
|
|
|
| - configs[i] = CrtcConfig(
|
| - outputs[i].crtc, 0, (height ? height + kVerticalGap : 0),
|
| - output_power[i] ? outputs[i].selected_mode : None,
|
| - outputs[i].output);
|
| + OutputSnapshot* output = &updated_outputs[i];
|
| + output->x = 0;
|
| + output->y = height ? height + kVerticalGap : 0;
|
| + output->current_mode = output_power[i] ? output->selected_mode : None;
|
|
|
| // Retain the full screen size even if all outputs are off so the
|
| // same desktop configuration can be restored when the outputs are
|
| @@ -532,29 +500,44 @@ bool OutputConfigurator::EnterState(
|
| height += (height ? kVerticalGap : 0) + mode_sizes[i].second;
|
| }
|
|
|
| - delegate_->CreateFrameBuffer(width, height, configs);
|
| -
|
| for (size_t i = 0; i < outputs.size(); ++i) {
|
| - delegate_->ConfigureCrtc(&configs[i]);
|
| - if (outputs[i].touch_device_id) {
|
| - CoordinateTransformation ctm;
|
| - ctm.x_scale = static_cast<float>(mode_sizes[i].first) / width;
|
| - ctm.x_offset = static_cast<float>(configs[i].x) / width;
|
| - ctm.y_scale = static_cast<float>(mode_sizes[i].second) / height;
|
| - ctm.y_offset = static_cast<float>(configs[i].y) / height;
|
| - delegate_->ConfigureCTM(outputs[i].touch_device_id, ctm);
|
| + OutputSnapshot* output = &updated_outputs[i];
|
| + if (output->touch_device_id) {
|
| + CoordinateTransformation* ctm = &(output->transform);
|
| + ctm->x_scale = static_cast<float>(mode_sizes[i].first) / width;
|
| + ctm->x_offset = static_cast<float>(output->x) / width;
|
| + ctm->y_scale = static_cast<float>(mode_sizes[i].second) / height;
|
| + ctm->y_offset = static_cast<float>(output->y) / height;
|
| }
|
| }
|
| break;
|
| }
|
| - default:
|
| - NOTREACHED() << "Got request to enter output state " << output_state
|
| - << " with " << outputs.size() << " output(s)";
|
| - return false;
|
| + }
|
| +
|
| + // Finally, apply the desired changes.
|
| + DCHECK_EQ(outputs.size(), updated_outputs.size());
|
| + if (!outputs.empty()) {
|
| + delegate_->CreateFrameBuffer(width, height, updated_outputs);
|
| + for (size_t i = 0; i < outputs.size(); ++i) {
|
| + const OutputSnapshot& output = updated_outputs[i];
|
| + if (delegate_->ConfigureCrtc(output.crtc, output.current_mode,
|
| + output.output, output.x, output.y)) {
|
| + if (output.touch_device_id)
|
| + delegate_->ConfigureCTM(output.touch_device_id, output.transform);
|
| + } else {
|
| + LOG(WARNING) << "Unable to configure CRTC " << output.crtc << ":"
|
| + << " mode=" << output.current_mode
|
| + << " output=" << output.output
|
| + << " x=" << output.x
|
| + << " y=" << output.y;
|
| + updated_outputs[i] = outputs[i];
|
| + }
|
| + }
|
| }
|
|
|
| output_state_ = output_state;
|
| power_state_ = power_state;
|
| + cached_outputs_ = updated_outputs;
|
| return true;
|
| }
|
|
|
|
|