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 <joedow@google.com>
Reviewed-by: Jamie Walch <jamiewalch@chromium.org>
Cr-Commit-Position: refs/heads/master@{#32065}
This commit is contained in:
Joe Downing 2020-09-09 11:18:34 -07:00 committed by Commit Bot
parent 7a73c772e2
commit 7f509e1313

View File

@ -10,6 +10,7 @@
#include "modules/desktop_capture/win/window_capturer_win_gdi.h"
#include <cmath>
#include <map>
#include <memory>
#include <utility>
@ -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<double>(window_dc_size.width()) / original_rect.width();
vertical_scale =
static_cast<double>(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<int>(std::round(
(cropped_rect.left() - original_rect.left()) * (horizontal_scale - 1)));
int translate_top = static_cast<int>(std::round(
(cropped_rect.top() - original_rect.top()) * (vertical_scale - 1)));
cropped_rect.Translate(translate_left, translate_top);
}
std::unique_ptr<DesktopFrameWin> frame(