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 return XRRSetCrtcConfig(display_, |
264 RROutput* outputs = NULL; | 268 screen_, |
265 int num_outputs = 0; | 269 crtc, |
266 if (config->output && config->mode) { | 270 CurrentTime, |
267 outputs = &config->output; | 271 x, |
268 num_outputs = 1; | 272 y, |
269 } | 273 mode, |
270 | 274 RR_Rotate_0, |
271 XRRSetCrtcConfig(display_, | 275 (output && mode) ? &output : NULL, |
272 screen_, | 276 (output && mode) ? 1 : 0); |
273 config->crtc, | |
274 CurrentTime, | |
275 config->x, | |
276 config->y, | |
277 config->mode, | |
278 RR_Rotate_0, | |
279 outputs, | |
280 num_outputs); | |
281 } | 277 } |
282 | 278 |
283 void RealOutputConfiguratorDelegate::CreateFrameBuffer( | 279 void RealOutputConfiguratorDelegate::CreateFrameBuffer( |
284 int width, | 280 int width, |
285 int height, | 281 int height, |
286 const std::vector<OutputConfigurator::CrtcConfig>& configs) { | 282 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) { |
287 CHECK(screen_) << "Server not grabbed"; | 283 CHECK(screen_) << "Server not grabbed"; |
288 int current_width = DisplayWidth(display_, DefaultScreen(display_)); | 284 int current_width = DisplayWidth(display_, DefaultScreen(display_)); |
289 int current_height = DisplayHeight(display_, DefaultScreen(display_)); | 285 int current_height = DisplayHeight(display_, DefaultScreen(display_)); |
290 VLOG(1) << "CreateFrameBuffer: new=" << width << "x" << height | 286 VLOG(1) << "CreateFrameBuffer: new=" << width << "x" << height |
291 << " current=" << current_width << "x" << current_height; | 287 << " current=" << current_width << "x" << current_height; |
292 if (width == current_width && height == current_height) | 288 if (width == current_width && height == current_height) |
293 return; | 289 return; |
294 | 290 |
295 DestroyUnusedCrtcs(configs); | 291 DestroyUnusedCrtcs(outputs); |
296 int mm_width = width * kPixelsToMmScale; | 292 int mm_width = width * kPixelsToMmScale; |
297 int mm_height = height * kPixelsToMmScale; | 293 int mm_height = height * kPixelsToMmScale; |
298 XRRSetScreenSize(display_, window_, width, height, mm_width, mm_height); | 294 XRRSetScreenSize(display_, window_, width, height, mm_width, mm_height); |
299 } | 295 } |
300 | 296 |
301 void RealOutputConfiguratorDelegate::ConfigureCTM( | 297 void RealOutputConfiguratorDelegate::ConfigureCTM( |
302 int touch_device_id, | 298 int touch_device_id, |
303 const OutputConfigurator::CoordinateTransformation& ctm) { | 299 const OutputConfigurator::CoordinateTransformation& ctm) { |
304 VLOG(1) << "ConfigureCTM: id=" << touch_device_id | 300 VLOG(1) << "ConfigureCTM: id=" << touch_device_id |
305 << " scale=" << ctm.x_scale << "x" << ctm.y_scale | 301 << " scale=" << ctm.x_scale << "x" << ctm.y_scale |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 XIFreeDeviceInfo(info); | 334 XIFreeDeviceInfo(info); |
339 } | 335 } |
340 | 336 |
341 void RealOutputConfiguratorDelegate::SendProjectingStateToPowerManager( | 337 void RealOutputConfiguratorDelegate::SendProjectingStateToPowerManager( |
342 bool projecting) { | 338 bool projecting) { |
343 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> | 339 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> |
344 SetIsProjecting(projecting); | 340 SetIsProjecting(projecting); |
345 } | 341 } |
346 | 342 |
347 void RealOutputConfiguratorDelegate::DestroyUnusedCrtcs( | 343 void RealOutputConfiguratorDelegate::DestroyUnusedCrtcs( |
348 const std::vector<OutputConfigurator::CrtcConfig>& configs) { | 344 const std::vector<OutputConfigurator::OutputSnapshot>& outputs) { |
349 CHECK(screen_) << "Server not grabbed"; | 345 CHECK(screen_) << "Server not grabbed"; |
350 // Setting the screen size will fail if any CRTC doesn't fit afterwards. | 346 // 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. | 347 // 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: | 348 // 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. | 349 // - 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 | 350 // - We set the new modes on CRTCs, if they fit in both the old and new |
355 // FBs, and park them at (0,0) | 351 // FBs, and park them at (0,0) |
356 // - We disable the CRTCs we will need but don't fit in the old FB. Those | 352 // - We disable the CRTCs we will need but don't fit in the old FB. Those |
357 // will be reenabled after the resize. | 353 // will be reenabled after the resize. |
358 // We don't worry about the cached state of the outputs here since we are | 354 // 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 | 355 // 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. | 356 // out of the way so we can rebuild the frame buffer. |
361 for (int i = 0; i < screen_->ncrtc; ++i) { | 357 for (int i = 0; i < screen_->ncrtc; ++i) { |
362 // Default config is to disable the crtcs. | 358 // Default config is to disable the crtcs. |
363 OutputConfigurator::CrtcConfig config( | 359 RRCrtc crtc = screen_->crtcs[i]; |
364 screen_->crtcs[i], 0, 0, None, None); | 360 RRMode mode = None; |
365 for (std::vector<OutputConfigurator::CrtcConfig>::const_iterator it = | 361 RROutput output = None; |
366 configs.begin(); it != configs.end(); ++it) { | 362 for (std::vector<OutputConfigurator::OutputSnapshot>::const_iterator it = |
367 if (config.crtc == it->crtc) { | 363 outputs.begin(); it != outputs.end(); ++it) { |
368 config.mode = it->mode; | 364 if (crtc == it->crtc) { |
369 config.output = it->output; | 365 mode = it->current_mode; |
| 366 output = it->output; |
370 break; | 367 break; |
371 } | 368 } |
372 } | 369 } |
373 | 370 |
374 if (config.mode != None) { | 371 if (mode != None) { |
375 // In case our CRTC doesn't fit in our current framebuffer, disable it. | 372 // In case our CRTC doesn't fit in our current framebuffer, disable it. |
376 // It'll get reenabled after we resize the framebuffer. | 373 // It'll get reenabled after we resize the framebuffer. |
377 int mode_width = 0, mode_height = 0; | 374 int mode_width = 0, mode_height = 0; |
378 CHECK(GetModeDetails(config.mode, &mode_width, &mode_height, NULL)); | 375 CHECK(GetModeDetails(mode, &mode_width, &mode_height, NULL)); |
379 int current_width = DisplayWidth(display_, DefaultScreen(display_)); | 376 int current_width = DisplayWidth(display_, DefaultScreen(display_)); |
380 int current_height = DisplayHeight(display_, DefaultScreen(display_)); | 377 int current_height = DisplayHeight(display_, DefaultScreen(display_)); |
381 if (mode_width > current_width || mode_height > current_height) { | 378 if (mode_width > current_width || mode_height > current_height) { |
382 config.mode = None; | 379 mode = None; |
383 config.output = None; | 380 output = None; |
384 } | 381 } |
385 } | 382 } |
386 | 383 |
387 ConfigureCrtc(&config); | 384 ConfigureCrtc(crtc, mode, output, 0, 0); |
388 } | 385 } |
389 } | 386 } |
390 | 387 |
391 bool RealOutputConfiguratorDelegate::IsOutputAspectPreservingScaling( | 388 bool RealOutputConfiguratorDelegate::IsOutputAspectPreservingScaling( |
392 RROutput id) { | 389 RROutput id) { |
393 bool ret = false; | 390 bool ret = false; |
394 | 391 |
395 Atom scaling_prop = XInternAtom(display_, "scaling mode", False); | 392 Atom scaling_prop = XInternAtom(display_, "scaling mode", False); |
396 Atom full_aspect_atom = XInternAtom(display_, "Full aspect", False); | 393 Atom full_aspect_atom = XInternAtom(display_, "Full aspect", False); |
397 if (scaling_prop == None || full_aspect_atom == None) | 394 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 | 581 << " id " << info[i].deviceid |
585 << " width " << width | 582 << " width " << width |
586 << " height " << height; | 583 << " height " << height; |
587 } | 584 } |
588 } | 585 } |
589 | 586 |
590 XIFreeDeviceInfo(info); | 587 XIFreeDeviceInfo(info); |
591 } | 588 } |
592 | 589 |
593 } // namespace chromeos | 590 } // namespace chromeos |
OLD | NEW |