OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromeos/display/real_output_configurator_delegate.h" | 5 #include "chromeos/display/real_output_configurator_delegate.h" |
6 | 6 |
7 #include <X11/Xatom.h> | 7 #include <X11/Xatom.h> |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 #include <X11/extensions/dpms.h> | 9 #include <X11/extensions/dpms.h> |
10 #include <X11/extensions/XInput.h> | 10 #include <X11/extensions/XInput.h> |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 if (!to_populate.has_display_id && to_populate.is_internal) | 131 if (!to_populate.has_display_id && to_populate.is_internal) |
132 to_populate.has_display_id = true; | 132 to_populate.has_display_id = true; |
133 | 133 |
134 (outputs.empty() ? one_info : two_info) = output_info; | 134 (outputs.empty() ? one_info : two_info) = output_info; |
135 | 135 |
136 // Now, look up the current CRTC and any related info. | 136 // Now, look up the current CRTC and any related info. |
137 if (output_info->crtc) { | 137 if (output_info->crtc) { |
138 XRRCrtcInfo* crtc_info = XRRGetCrtcInfo( | 138 XRRCrtcInfo* crtc_info = XRRGetCrtcInfo( |
139 display_, screen_, output_info->crtc); | 139 display_, screen_, output_info->crtc); |
140 to_populate.current_mode = crtc_info->mode; | 140 to_populate.current_mode = crtc_info->mode; |
141 to_populate.height = crtc_info->height; | 141 to_populate.x = crtc_info->x; |
142 to_populate.y = crtc_info->y; | 142 to_populate.y = crtc_info->y; |
143 XRRFreeCrtcInfo(crtc_info); | 143 XRRFreeCrtcInfo(crtc_info); |
144 } | 144 } |
145 | 145 |
146 // Assign a CRTC that isn't already in use. | 146 // Assign a CRTC that isn't already in use. |
147 for (int j = 0; j < output_info->ncrtc; ++j) { | 147 for (int j = 0; j < output_info->ncrtc; ++j) { |
148 if (output_info->crtcs[j] != last_used_crtc) { | 148 if (output_info->crtcs[j] != last_used_crtc) { |
149 to_populate.crtc = output_info->crtcs[j]; | 149 to_populate.crtc = output_info->crtcs[j]; |
150 last_used_crtc = to_populate.crtc; | 150 last_used_crtc = to_populate.crtc; |
151 break; | 151 break; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 if (height) | 245 if (height) |
246 *height = info.height; | 246 *height = info.height; |
247 if (interlaced) | 247 if (interlaced) |
248 *interlaced = info.modeFlags & RR_Interlace; | 248 *interlaced = info.modeFlags & RR_Interlace; |
249 return true; | 249 return true; |
250 } | 250 } |
251 } | 251 } |
252 return false; | 252 return false; |
253 } | 253 } |
254 | 254 |
255 void RealOutputConfiguratorDelegate::ConfigureCrtc( | 255 bool RealOutputConfiguratorDelegate::ConfigureCrtc( |
256 OutputConfigurator::CrtcConfig* config) { | 256 RRCrtc crtc, |
| 257 RRMode mode, |
| 258 RROutput output, |
| 259 int x, |
| 260 int y) { |
257 CHECK(screen_) << "Server not grabbed"; | 261 CHECK(screen_) << "Server not grabbed"; |
258 VLOG(1) << "ConfigureCrtc: crtc=" << config->crtc | 262 VLOG(1) << "ConfigureCrtc: crtc=" << crtc |
259 << " mode=" << config->mode | 263 << " mode=" << mode |
260 << " output=" << config->output | 264 << " output=" << output |
261 << " x=" << config->x | 265 << " x=" << x |
262 << " y=" << config->y; | 266 << " y=" << y; |
263 | 267 // Xrandr.h is full of lies. XRRSetCrtcConfig() is defined as returning a |
264 RROutput* outputs = NULL; | 268 // Status, which is typically 0 for failure and 1 for success. In |
265 int num_outputs = 0; | 269 // actuality it returns a RRCONFIGSTATUS, which uses 0 for success. |
266 if (config->output && config->mode) { | 270 return XRRSetCrtcConfig(display_, |
267 outputs = &config->output; | 271 screen_, |
268 num_outputs = 1; | 272 crtc, |
269 } | 273 CurrentTime, |
270 | 274 x, |
271 XRRSetCrtcConfig(display_, | 275 y, |
272 screen_, | 276 mode, |
273 config->crtc, | 277 RR_Rotate_0, |
274 CurrentTime, | 278 (output && mode) ? &output : NULL, |
275 config->x, | 279 (output && mode) ? 1 : 0) == RRSetConfigSuccess; |
276 config->y, | |
277 config->mode, | |
278 RR_Rotate_0, | |
279 outputs, | |
280 num_outputs); | |
281 } | 280 } |
282 | 281 |
283 void RealOutputConfiguratorDelegate::CreateFrameBuffer( | 282 void RealOutputConfiguratorDelegate::CreateFrameBuffer( |
284 int width, | 283 int width, |
285 int height, | 284 int height, |
286 const std::vector<OutputConfigurator::CrtcConfig>& configs) { | 285 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) { |
287 CHECK(screen_) << "Server not grabbed"; | 286 CHECK(screen_) << "Server not grabbed"; |
288 int current_width = DisplayWidth(display_, DefaultScreen(display_)); | 287 int current_width = DisplayWidth(display_, DefaultScreen(display_)); |
289 int current_height = DisplayHeight(display_, DefaultScreen(display_)); | 288 int current_height = DisplayHeight(display_, DefaultScreen(display_)); |
290 VLOG(1) << "CreateFrameBuffer: new=" << width << "x" << height | 289 VLOG(1) << "CreateFrameBuffer: new=" << width << "x" << height |
291 << " current=" << current_width << "x" << current_height; | 290 << " current=" << current_width << "x" << current_height; |
292 if (width == current_width && height == current_height) | 291 if (width == current_width && height == current_height) |
293 return; | 292 return; |
294 | 293 |
295 DestroyUnusedCrtcs(configs); | 294 DestroyUnusedCrtcs(outputs); |
296 int mm_width = width * kPixelsToMmScale; | 295 int mm_width = width * kPixelsToMmScale; |
297 int mm_height = height * kPixelsToMmScale; | 296 int mm_height = height * kPixelsToMmScale; |
298 XRRSetScreenSize(display_, window_, width, height, mm_width, mm_height); | 297 XRRSetScreenSize(display_, window_, width, height, mm_width, mm_height); |
299 } | 298 } |
300 | 299 |
301 void RealOutputConfiguratorDelegate::ConfigureCTM( | 300 void RealOutputConfiguratorDelegate::ConfigureCTM( |
302 int touch_device_id, | 301 int touch_device_id, |
303 const OutputConfigurator::CoordinateTransformation& ctm) { | 302 const OutputConfigurator::CoordinateTransformation& ctm) { |
304 VLOG(1) << "ConfigureCTM: id=" << touch_device_id | 303 VLOG(1) << "ConfigureCTM: id=" << touch_device_id |
305 << " scale=" << ctm.x_scale << "x" << ctm.y_scale | 304 << " scale=" << ctm.x_scale << "x" << ctm.y_scale |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 XIFreeDeviceInfo(info); | 337 XIFreeDeviceInfo(info); |
339 } | 338 } |
340 | 339 |
341 void RealOutputConfiguratorDelegate::SendProjectingStateToPowerManager( | 340 void RealOutputConfiguratorDelegate::SendProjectingStateToPowerManager( |
342 bool projecting) { | 341 bool projecting) { |
343 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> | 342 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> |
344 SetIsProjecting(projecting); | 343 SetIsProjecting(projecting); |
345 } | 344 } |
346 | 345 |
347 void RealOutputConfiguratorDelegate::DestroyUnusedCrtcs( | 346 void RealOutputConfiguratorDelegate::DestroyUnusedCrtcs( |
348 const std::vector<OutputConfigurator::CrtcConfig>& configs) { | 347 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) { |
349 CHECK(screen_) << "Server not grabbed"; | 348 CHECK(screen_) << "Server not grabbed"; |
350 // Setting the screen size will fail if any CRTC doesn't fit afterwards. | 349 // Setting the screen size will fail if any CRTC doesn't fit afterwards. |
351 // At the same time, turning CRTCs off and back on uses up a lot of time. | 350 // At the same time, turning CRTCs off and back on uses up a lot of time. |
352 // This function tries to be smart to avoid too many off/on cycles: | 351 // This function tries to be smart to avoid too many off/on cycles: |
353 // - We disable all the CRTCs we won't need after the FB resize. | 352 // - We disable all the CRTCs we won't need after the FB resize. |
354 // - We set the new modes on CRTCs, if they fit in both the old and new | 353 // - We set the new modes on CRTCs, if they fit in both the old and new |
355 // FBs, and park them at (0,0) | 354 // FBs, and park them at (0,0) |
356 // - We disable the CRTCs we will need but don't fit in the old FB. Those | 355 // - We disable the CRTCs we will need but don't fit in the old FB. Those |
357 // will be reenabled after the resize. | 356 // will be reenabled after the resize. |
358 // We don't worry about the cached state of the outputs here since we are | 357 // We don't worry about the cached state of the outputs here since we are |
359 // not interested in the state we are setting - we just try to get the CRTCs | 358 // not interested in the state we are setting - we just try to get the CRTCs |
360 // out of the way so we can rebuild the frame buffer. | 359 // out of the way so we can rebuild the frame buffer. |
361 for (int i = 0; i < screen_->ncrtc; ++i) { | 360 for (int i = 0; i < screen_->ncrtc; ++i) { |
362 // Default config is to disable the crtcs. | 361 // Default config is to disable the crtcs. |
363 OutputConfigurator::CrtcConfig config( | 362 RRCrtc crtc = screen_->crtcs[i]; |
364 screen_->crtcs[i], 0, 0, None, None); | 363 RRMode mode = None; |
365 for (std::vector<OutputConfigurator::CrtcConfig>::const_iterator it = | 364 RROutput output = None; |
366 configs.begin(); it != configs.end(); ++it) { | 365 for (std::vector<OutputConfigurator::OutputSnapshot>::const_iterator it = |
367 if (config.crtc == it->crtc) { | 366 outputs.begin(); it != outputs.end(); ++it) { |
368 config.mode = it->mode; | 367 if (crtc == it->crtc) { |
369 config.output = it->output; | 368 mode = it->current_mode; |
| 369 output = it->output; |
370 break; | 370 break; |
371 } | 371 } |
372 } | 372 } |
373 | 373 |
374 if (config.mode != None) { | 374 if (mode != None) { |
375 // In case our CRTC doesn't fit in our current framebuffer, disable it. | 375 // In case our CRTC doesn't fit in our current framebuffer, disable it. |
376 // It'll get reenabled after we resize the framebuffer. | 376 // It'll get reenabled after we resize the framebuffer. |
377 int mode_width = 0, mode_height = 0; | 377 int mode_width = 0, mode_height = 0; |
378 CHECK(GetModeDetails(config.mode, &mode_width, &mode_height, NULL)); | 378 CHECK(GetModeDetails(mode, &mode_width, &mode_height, NULL)); |
379 int current_width = DisplayWidth(display_, DefaultScreen(display_)); | 379 int current_width = DisplayWidth(display_, DefaultScreen(display_)); |
380 int current_height = DisplayHeight(display_, DefaultScreen(display_)); | 380 int current_height = DisplayHeight(display_, DefaultScreen(display_)); |
381 if (mode_width > current_width || mode_height > current_height) { | 381 if (mode_width > current_width || mode_height > current_height) { |
382 config.mode = None; | 382 mode = None; |
383 config.output = None; | 383 output = None; |
384 } | 384 } |
385 } | 385 } |
386 | 386 |
387 ConfigureCrtc(&config); | 387 ConfigureCrtc(crtc, mode, output, 0, 0); |
388 } | 388 } |
389 } | 389 } |
390 | 390 |
391 bool RealOutputConfiguratorDelegate::IsOutputAspectPreservingScaling( | 391 bool RealOutputConfiguratorDelegate::IsOutputAspectPreservingScaling( |
392 RROutput id) { | 392 RROutput id) { |
393 bool ret = false; | 393 bool ret = false; |
394 | 394 |
395 Atom scaling_prop = XInternAtom(display_, "scaling mode", False); | 395 Atom scaling_prop = XInternAtom(display_, "scaling mode", False); |
396 Atom full_aspect_atom = XInternAtom(display_, "Full aspect", False); | 396 Atom full_aspect_atom = XInternAtom(display_, "Full aspect", False); |
397 if (scaling_prop == None || full_aspect_atom == None) | 397 if (scaling_prop == None || full_aspect_atom == None) |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 << " id " << info[i].deviceid | 584 << " id " << info[i].deviceid |
585 << " width " << width | 585 << " width " << width |
586 << " height " << height; | 586 << " height " << height; |
587 } | 587 } |
588 } | 588 } |
589 | 589 |
590 XIFreeDeviceInfo(info); | 590 XIFreeDeviceInfo(info); |
591 } | 591 } |
592 | 592 |
593 } // namespace chromeos | 593 } // namespace chromeos |
OLD | NEW |