From 7f509e13139a9683b2fd548a2e5270e9da057763 Mon Sep 17 00:00:00 2001 From: Joe Downing Date: Wed, 9 Sep 2020 11:18:34 -0700 Subject: [PATCH] Fixing a crash when capturing non-DPI aware windows at high DPIs For Non-DPI aware windows, we need to figure out the current DPI and scale the content accordingly, the current behavior works ok for until the clipped region pushes the content outside of the frame and then the capture will fail. When this happens, the captured frame may be blank or it could cause the browser to crash. The issue is that the left and top clipped regions are not being scaled along with the content (the captured window region is contained within a larger window frame). When the clipped window and window frame are scaled, the original offset for left and top are not adjusted so after a certain DPI, this offset causes the clipped region to get pushed outside of the frame which is why the capture fails. The fix is to scale the left and top clipped regions and translate the clipped region accordingly. This change will only affect non-DPI aware windows. Bug: chromium:1083527 Change-Id: I893c2cb362cbaa01170d1e58465e43c3517139ad Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/183660 Commit-Queue: Joe Downing Reviewed-by: Jamie Walch Cr-Commit-Position: refs/heads/master@{#32065} --- .../desktop_capture/win/window_capturer_win_gdi.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/modules/desktop_capture/win/window_capturer_win_gdi.cc b/modules/desktop_capture/win/window_capturer_win_gdi.cc index 82a8551831..04cd7f667d 100644 --- a/modules/desktop_capture/win/window_capturer_win_gdi.cc +++ b/modules/desktop_capture/win/window_capturer_win_gdi.cc @@ -10,6 +10,7 @@ #include "modules/desktop_capture/win/window_capturer_win_gdi.h" +#include #include #include #include @@ -222,12 +223,22 @@ WindowCapturerWinGdi::CaptureResults WindowCapturerWinGdi::CaptureFrame( // If |window_dc_size| is smaller than |window_rect|, let's resize both // |original_rect| and |cropped_rect| according to the scaling factor. + // This will adjust the width and height of the two rects. horizontal_scale = static_cast(window_dc_size.width()) / original_rect.width(); vertical_scale = static_cast(window_dc_size.height()) / original_rect.height(); original_rect.Scale(horizontal_scale, vertical_scale); cropped_rect.Scale(horizontal_scale, vertical_scale); + + // Translate |cropped_rect| to the left so that its position within + // |original_rect| remains accurate after scaling. + // See crbug.com/1083527 for more info. + int translate_left = static_cast(std::round( + (cropped_rect.left() - original_rect.left()) * (horizontal_scale - 1))); + int translate_top = static_cast(std::round( + (cropped_rect.top() - original_rect.top()) * (vertical_scale - 1))); + cropped_rect.Translate(translate_left, translate_top); } std::unique_ptr frame(