Index: ui/display/chromeos/x11/native_display_delegate_x11.cc |
diff --git a/ui/display/chromeos/x11/native_display_delegate_x11.cc b/ui/display/chromeos/x11/native_display_delegate_x11.cc |
index fb965d996459181babab8e054b7145ef1cd22a27..6e71cdd36f3e0a3386852e1302c10550590ba2aa 100644 |
--- a/ui/display/chromeos/x11/native_display_delegate_x11.cc |
+++ b/ui/display/chromeos/x11/native_display_delegate_x11.cc |
@@ -22,6 +22,7 @@ |
#include "ui/display/util/x11/edid_parser_x11.h" |
#include "ui/events/platform/platform_event_observer.h" |
#include "ui/events/platform/platform_event_source.h" |
+#include "ui/gfx/geometry/rect.h" |
#include "ui/gfx/x/x11_error_tracker.h" |
#include "ui/gfx/x/x11_types.h" |
@@ -292,16 +293,22 @@ bool NativeDisplayDelegateX11::ConfigureCrtc(RRCrtc crtc, |
void NativeDisplayDelegateX11::CreateFrameBuffer(const gfx::Size& size) { |
CHECK(screen_) << "Server not grabbed"; |
- int current_width = DisplayWidth(display_, DefaultScreen(display_)); |
- int current_height = DisplayHeight(display_, DefaultScreen(display_)); |
- VLOG(1) << "CreateFrameBuffer: new=" << size.width() << "x" << size.height() |
- << " current=" << current_width << "x" << current_height; |
+ gfx::Size current_screen_size( |
+ DisplayWidth(display_, DefaultScreen(display_)), |
+ DisplayHeight(display_, DefaultScreen(display_))); |
- DestroyUnusedCrtcs(size); |
+ VLOG(1) << "CreateFrameBuffer: new=" << size.ToString() |
+ << " current=" << current_screen_size.ToString(); |
- if (size.width() == current_width && size.height() == current_height) |
+ DestroyUnusedCrtcs(); |
+ |
+ if (size == current_screen_size) |
return; |
+ gfx::Size min_screen_size(current_screen_size); |
+ min_screen_size.SetToMin(size); |
+ UpdateCrtcsForNewFramebuffer(min_screen_size); |
+ |
int mm_width = size.width() * kPixelsToMmScale; |
int mm_height = size.height() * kPixelsToMmScale; |
XRRSetScreenSize( |
@@ -522,12 +529,33 @@ bool NativeDisplayDelegateX11::SetHDCPState(const DisplaySnapshot& output, |
} |
} |
-void NativeDisplayDelegateX11::DestroyUnusedCrtcs(const gfx::Size& new_size) { |
+void NativeDisplayDelegateX11::DestroyUnusedCrtcs() { |
+ CHECK(screen_) << "Server not grabbed"; |
+ |
+ for (int i = 0; i < screen_->ncrtc; ++i) { |
+ bool in_use = false; |
+ for (ScopedVector<DisplaySnapshot>::const_iterator it = |
+ cached_outputs_.begin(); |
+ it != cached_outputs_.end(); |
+ ++it) { |
+ DisplaySnapshotX11* x11_output = static_cast<DisplaySnapshotX11*>(*it); |
+ if (screen_->crtcs[i] == x11_output->crtc()) { |
+ in_use = true; |
+ break; |
+ } |
+ } |
+ |
+ if (!in_use) |
+ ConfigureCrtc(screen_->crtcs[i], None, None, 0, 0); |
+ } |
+} |
+ |
+void NativeDisplayDelegateX11::UpdateCrtcsForNewFramebuffer( |
+ const gfx::Size& min_screen_size) { |
CHECK(screen_) << "Server not grabbed"; |
// Setting the screen size will fail if any CRTC doesn't fit afterwards. |
// At the same time, turning CRTCs off and back on uses up a lot of time. |
// This function tries to be smart to avoid too many off/on cycles: |
- // - We disable all the CRTCs we won't need after the FB resize. |
// - We set the new modes on CRTCs, if they fit in both the old and new |
// FBs, and park them at (0,0) |
// - We disable the CRTCs we will need but don't fit in the old FB. Those |
@@ -535,42 +563,30 @@ void NativeDisplayDelegateX11::DestroyUnusedCrtcs(const gfx::Size& new_size) { |
// We don't worry about the cached state of the outputs here since we are |
// not interested in the state we are setting - we just try to get the CRTCs |
// out of the way so we can rebuild the frame buffer. |
- for (int i = 0; i < screen_->ncrtc; ++i) { |
- // Default config is to disable the crtcs. |
- RRCrtc crtc = screen_->crtcs[i]; |
+ gfx::Rect fb_rect(min_screen_size); |
+ for (ScopedVector<DisplaySnapshot>::const_iterator it = |
+ cached_outputs_.begin(); |
+ it != cached_outputs_.end(); |
+ ++it) { |
+ DisplaySnapshotX11* x11_output = static_cast<DisplaySnapshotX11*>(*it); |
+ const DisplayMode* mode_info = x11_output->current_mode(); |
+ RROutput output = x11_output->output(); |
RRMode mode = None; |
- RROutput output = None; |
- const DisplayMode* mode_info = NULL; |
- for (ScopedVector<DisplaySnapshot>::const_iterator it = |
- cached_outputs_.begin(); |
- it != cached_outputs_.end(); |
- ++it) { |
- DisplaySnapshotX11* x11_output = static_cast<DisplaySnapshotX11*>(*it); |
- if (crtc == x11_output->crtc()) { |
- mode_info = x11_output->current_mode(); |
- output = x11_output->output(); |
- break; |
- } |
- } |
if (mode_info) { |
mode = static_cast<const DisplayModeX11*>(mode_info)->mode_id(); |
- // In case our CRTC doesn't fit in common area of our current and about |
- // to be resized framebuffer, disable it. |
- // It'll get reenabled after we resize the framebuffer. |
- int max_width = std::min(DisplayWidth(display_, |
- DefaultScreen(display_)), new_size.width()); |
- int max_height = std::min(DisplayHeight(display_, |
- DefaultScreen(display_)), new_size.height()); |
- if (mode_info->size().width() > max_width || |
- mode_info->size().height() > max_height) { |
+ |
+ if (!fb_rect.Contains(gfx::Rect(mode_info->size()))) { |
+ // In case our CRTC doesn't fit in common area of our current and about |
+ // to be resized framebuffer, disable it. |
+ // It'll get reenabled after we resize the framebuffer. |
mode = None; |
output = None; |
mode_info = NULL; |
} |
} |
- ConfigureCrtc(crtc, mode, output, 0, 0); |
+ ConfigureCrtc(x11_output->crtc(), mode, output, 0, 0); |
Daniel Kurtz
2014/06/06 08:29:43
When plugging an external monitor, the framebuffer
dnicoara
2014/06/06 14:25:30
My understanding from ynovikov@'s explanation is t
|
} |
} |