desktopCapture: copy whole screen region when screen is zoomed on OSX

When screen is zoomed in/out, OSX only updates the parts of Rects currently
displayed on screen, with relative location to current top-left on screen.
This will cause problems when we copy the dirty regions to the captured
frame. So we invalidate the whole screen to copy all the screen contents.

- With CGI method, the zooming will be ignored and the whole screen contents
will be captured as before.
- With IOSurface method, the zoomed screen contents will be captured.

Since we can't know the zooming level and focusing location, so we have
to copy the whole screen region for each frame during rooming. And this
will impact peformance a bit (with IOSurface capturer about 5-10 fps
down on MBP.)

Bug: chromium:911862
Change-Id: Icf123cde4d686ab7ce28fa731bc8dac6925492c8
Reviewed-on: https://webrtc-review.googlesource.com/c/113101
Reviewed-by: Jamie Walch <jamiewalch@chromium.org>
Commit-Queue: Brave Yao <braveyao@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25936}
diff --git a/modules/desktop_capture/mac/screen_capturer_mac.mm b/modules/desktop_capture/mac/screen_capturer_mac.mm
index 542d1c5..9f50673 100644
--- a/modules/desktop_capture/mac/screen_capturer_mac.mm
+++ b/modules/desktop_capture/mac/screen_capturer_mac.mm
@@ -218,6 +218,17 @@
     ScreenConfigurationChanged();
   }
 
+  // When screen is zoomed in/out, OSX only updates the part of Rects currently
+  // displayed on screen, with relative location to current top-left on screen.
+  // This will cause problems when we copy the dirty regions to the captured
+  // image. So we invalidate the whole screen to copy all the screen contents.
+  // With CGI method, the zooming will be ignored and the whole screen contents
+  // will be captured as before.
+  // With IOSurface method, the zoomed screen contents will be captured.
+  if (UAZoomEnabled()) {
+    helper_.InvalidateScreen(screen_pixel_bounds_.size());
+  }
+
   DesktopRegion region;
   helper_.TakeInvalidRegion(&region);
 
@@ -285,10 +296,9 @@
 }
 
 bool ScreenCapturerMac::CgBlit(const DesktopFrame& frame, const DesktopRegion& region) {
-  // Copy the entire contents of the previous capture buffer, to capture over.
-  // TODO(wez): Get rid of this as per crbug.com/145064, or implement
-  // crbug.com/92354.
-  if (queue_.previous_frame()) {
+  // If not all screen region is dirty, copy the entire contents of the previous capture buffer,
+  // to capture over.
+  if (queue_.previous_frame() && !region.Equals(DesktopRegion(screen_pixel_bounds_))) {
     memcpy(frame.data(), queue_.previous_frame()->data(), frame.stride() * frame.size().height());
   }