Remove differ from ScreenCapturer implementations

We can use ScreenCapturerDifferWrapper if needed, otherwise ScreenCapturer does
not need to calculate updated region itself, setting to entire screen is enough.

BUG=633802

Review-Url: https://codereview.webrtc.org/2348803003
Cr-Commit-Position: refs/heads/master@{#14377}
diff --git a/webrtc/modules/BUILD.gn b/webrtc/modules/BUILD.gn
index fe8124d..6f7f189 100644
--- a/webrtc/modules/BUILD.gn
+++ b/webrtc/modules/BUILD.gn
@@ -525,7 +525,6 @@
       sources += [
         "desktop_capture/desktop_region_unittest.cc",
         "desktop_capture/differ_block_unittest.cc",
-        "desktop_capture/differ_unittest.cc",
       ]
     }
 
diff --git a/webrtc/modules/desktop_capture/BUILD.gn b/webrtc/modules/desktop_capture/BUILD.gn
index 46a768a..e763056 100644
--- a/webrtc/modules/desktop_capture/BUILD.gn
+++ b/webrtc/modules/desktop_capture/BUILD.gn
@@ -124,8 +124,6 @@
 
   if (!is_ios) {
     sources += [
-      "differ.cc",
-      "differ.h",
       "differ_block.cc",
       "differ_block.h",
       "screen_capturer_differ_wrapper.cc",
diff --git a/webrtc/modules/desktop_capture/desktop_capture.gypi b/webrtc/modules/desktop_capture/desktop_capture.gypi
index 521ef27..48bafdf 100644
--- a/webrtc/modules/desktop_capture/desktop_capture.gypi
+++ b/webrtc/modules/desktop_capture/desktop_capture.gypi
@@ -140,8 +140,6 @@
         }],
         ['OS!="ios" ', {
           'sources': [
-            'differ.cc',
-            'differ.h',
             'differ_block.cc',
             'differ_block.h',
             'screen_capturer_differ_wrapper.cc',
diff --git a/webrtc/modules/desktop_capture/differ.cc b/webrtc/modules/desktop_capture/differ.cc
deleted file mode 100644
index 8140e61..0000000
--- a/webrtc/modules/desktop_capture/differ.cc
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "webrtc/modules/desktop_capture/differ.h"
-
-#include "string.h"
-
-#include "webrtc/modules/desktop_capture/differ_block.h"
-#include "webrtc/system_wrappers/include/logging.h"
-
-namespace webrtc {
-
-Differ::Differ(int width, int height, int bpp, int stride) {
-  // Dimensions of screen.
-  width_ = width;
-  height_ = height;
-  bytes_per_pixel_ = bpp;
-  bytes_per_row_ = stride;
-
-  // Calc number of blocks (full and partial) required to cover entire image.
-  // One additional row/column is added as a boundary on the right & bottom.
-  diff_info_width_ = ((width_ + kBlockSize - 1) / kBlockSize) + 1;
-  diff_info_height_ = ((height_ + kBlockSize - 1) / kBlockSize) + 1;
-  diff_info_size_ = diff_info_width_ * diff_info_height_ * sizeof(bool);
-  diff_info_.reset(new bool[diff_info_size_]);
-}
-
-Differ::~Differ() {}
-
-void Differ::CalcDirtyRegion(const uint8_t* prev_buffer,
-                             const uint8_t* curr_buffer,
-                             DesktopRegion* region) {
-  // Identify all the blocks that contain changed pixels.
-  MarkDirtyBlocks(prev_buffer, curr_buffer);
-
-  // Now that we've identified the blocks that have changed, merge adjacent
-  // blocks to minimize the number of rects that we return.
-  MergeBlocks(region);
-}
-
-void Differ::MarkDirtyBlocks(const uint8_t* prev_buffer,
-                             const uint8_t* curr_buffer) {
-  memset(diff_info_.get(), 0, diff_info_size_);
-
-  // Calc number of full blocks.
-  int x_full_blocks = width_ / kBlockSize;
-  int y_full_blocks = height_ / kBlockSize;
-
-  // Calc size of partial blocks which may be present on right and bottom edge.
-  int partial_column_width = width_ - (x_full_blocks * kBlockSize);
-  int partial_row_height = height_ - (y_full_blocks * kBlockSize);
-
-  // Offset from the start of one block-column to the next.
-  int block_x_offset = bytes_per_pixel_ * kBlockSize;
-  // Offset from the start of one block-row to the next.
-  int block_y_stride = (width_ * bytes_per_pixel_) * kBlockSize;
-  // Offset from the start of one diff_info row to the next.
-  int diff_info_stride = diff_info_width_ * sizeof(bool);
-
-  const uint8_t* prev_block_row_start = prev_buffer;
-  const uint8_t* curr_block_row_start = curr_buffer;
-  bool* diff_info_row_start = diff_info_.get();
-
-  for (int y = 0; y < y_full_blocks; y++) {
-    const uint8_t* prev_block = prev_block_row_start;
-    const uint8_t* curr_block = curr_block_row_start;
-    bool* diff_info = diff_info_row_start;
-
-    for (int x = 0; x < x_full_blocks; x++) {
-      // Mark this block as being modified so that it gets incorporated into
-      // a dirty rect.
-      *diff_info = BlockDifference(prev_block, curr_block, bytes_per_row_);
-      prev_block += block_x_offset;
-      curr_block += block_x_offset;
-      diff_info += sizeof(bool);
-    }
-
-    // If there is a partial column at the end, handle it.
-    // This condition should rarely, if ever, occur.
-    if (partial_column_width != 0) {
-      *diff_info = !PartialBlocksEqual(prev_block, curr_block, bytes_per_row_,
-                                       partial_column_width, kBlockSize);
-      diff_info += sizeof(bool);
-    }
-
-    // Update pointers for next row.
-    prev_block_row_start += block_y_stride;
-    curr_block_row_start += block_y_stride;
-    diff_info_row_start += diff_info_stride;
-  }
-
-  // If the screen height is not a multiple of the block size, then this
-  // handles the last partial row. This situation is far more common than the
-  // 'partial column' case.
-  if (partial_row_height != 0) {
-    const uint8_t* prev_block = prev_block_row_start;
-    const uint8_t* curr_block = curr_block_row_start;
-    bool* diff_info = diff_info_row_start;
-    for (int x = 0; x < x_full_blocks; x++) {
-      *diff_info = !PartialBlocksEqual(prev_block, curr_block,
-                                       bytes_per_row_,
-                                       kBlockSize, partial_row_height);
-      prev_block += block_x_offset;
-      curr_block += block_x_offset;
-      diff_info += sizeof(bool);
-    }
-    if (partial_column_width != 0) {
-      *diff_info = !PartialBlocksEqual(prev_block, curr_block, bytes_per_row_,
-                                       partial_column_width,
-                                       partial_row_height);
-      diff_info += sizeof(bool);
-    }
-  }
-}
-
-bool Differ::PartialBlocksEqual(const uint8_t* prev_buffer,
-                                const uint8_t* curr_buffer,
-                                int stride, int width, int height) {
-  int width_bytes = width * bytes_per_pixel_;
-  for (int y = 0; y < height; y++) {
-    if (memcmp(prev_buffer, curr_buffer, width_bytes) != 0)
-      return false;
-    prev_buffer += bytes_per_row_;
-    curr_buffer += bytes_per_row_;
-  }
-  return true;
-}
-
-void Differ::MergeBlocks(DesktopRegion* region) {
-  region->Clear();
-
-  bool* diff_info_row_start = diff_info_.get();
-  int diff_info_stride = diff_info_width_ * sizeof(bool);
-
-  for (int y = 0; y < diff_info_height_; y++) {
-    bool* diff_info = diff_info_row_start;
-    for (int x = 0; x < diff_info_width_; x++) {
-      if (*diff_info) {
-        // We've found a modified block. Look at blocks to the right and below
-        // to group this block with as many others as we can.
-        int left = x * kBlockSize;
-        int top = y * kBlockSize;
-        int width = 1;
-        int height = 1;
-        *diff_info = false;
-
-        // Group with blocks to the right.
-        // We can keep looking until we find an unchanged block because we
-        // have a boundary block which is never marked as having diffs.
-        bool* right = diff_info + 1;
-        while (*right) {
-          *right++ = false;
-          width++;
-        }
-
-        // Group with blocks below.
-        // The entire width of blocks that we matched above much match for
-        // each row that we add.
-        bool* bottom = diff_info;
-        bool found_new_row;
-        do {
-          found_new_row = true;
-          bottom += diff_info_stride;
-          right = bottom;
-          for (int x2 = 0; x2 < width; x2++) {
-            if (!*right++) {
-              found_new_row = false;
-            }
-          }
-
-          if (found_new_row) {
-            height++;
-
-            // We need to go back and erase the diff markers so that we don't
-            // try to add these blocks a second time.
-            right = bottom;
-            for (int x2 = 0; x2 < width; x2++) {
-              *right++ = false;
-            }
-          }
-        } while (found_new_row);
-
-        // Add rect to list of dirty rects.
-        width *= kBlockSize;
-        if (left + width > width_) {
-          width = width_ - left;
-        }
-        height *= kBlockSize;
-        if (top + height > height_) {
-          height = height_ - top;
-        }
-        region->AddRect(DesktopRect::MakeXYWH(left, top, width, height));
-      }
-
-      // Increment to next block in this row.
-      diff_info++;
-    }
-
-    // Go to start of next row.
-    diff_info_row_start += diff_info_stride;
-  }
-}
-
-}  // namespace webrtc
diff --git a/webrtc/modules/desktop_capture/differ.h b/webrtc/modules/desktop_capture/differ.h
deleted file mode 100644
index 9ab059b..0000000
--- a/webrtc/modules/desktop_capture/differ.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_DIFFER_H_
-#define WEBRTC_MODULES_DESKTOP_CAPTURE_DIFFER_H_
-
-#include <memory>
-#include <vector>
-
-#include "webrtc/base/constructormagic.h"
-#include "webrtc/modules/desktop_capture/desktop_region.h"
-
-namespace webrtc {
-
-// TODO(sergeyu): Simplify differ now that we are working with DesktopRegion.
-// diff_info_ should no longer be needed, as we can put our data directly into
-// the region that we are calculating.
-// http://crbug.com/92379
-// TODO(sergeyu): Rename this class to something more sensible, e.g.
-// ScreenCaptureFrameDifferencer.
-class Differ {
- public:
-  // Create a differ that operates on bitmaps with the specified width, height
-  // and bytes_per_pixel.
-  Differ(int width, int height, int bytes_per_pixel, int stride);
-  ~Differ();
-
-  int width() { return width_; }
-  int height() { return height_; }
-  int bytes_per_pixel() { return bytes_per_pixel_; }
-  int bytes_per_row() { return bytes_per_row_; }
-
-  // Given the previous and current screen buffer, calculate the dirty region
-  // that encloses all of the changed pixels in the new screen.
-  void CalcDirtyRegion(const uint8_t* prev_buffer, const uint8_t* curr_buffer,
-                       DesktopRegion* region);
-
- private:
-  // Allow tests to access our private parts.
-  friend class DifferTest;
-
-  // Identify all of the blocks that contain changed pixels.
-  void MarkDirtyBlocks(const uint8_t* prev_buffer, const uint8_t* curr_buffer);
-
-  // After the dirty blocks have been identified, this routine merges adjacent
-  // blocks into a region.
-  // The goal is to minimize the region that covers the dirty blocks.
-  void MergeBlocks(DesktopRegion* region);
-
-  // Checks whether the upper-left portions of the buffers are equal. The size
-  // of the portion to check is specified by the |width| and |height| values.
-  // Note that if we force the capturer to always return images whose width and
-  // height are multiples of kBlockSize, then this will never be called.
-  bool PartialBlocksEqual(const uint8_t* prev_buffer,
-                          const uint8_t* curr_buffer,
-                          int stride,
-                          int width, int height);
-
-  // Dimensions of screen.
-  int width_;
-  int height_;
-
-  // Number of bytes for each pixel in source and dest bitmap.
-  // (Yes, they must match.)
-  int bytes_per_pixel_;
-
-  // Number of bytes in each row of the image (AKA: stride).
-  int bytes_per_row_;
-
-  // Diff information for each block in the image.
-  std::unique_ptr<bool[]> diff_info_;
-
-  // Dimensions and total size of diff info array.
-  int diff_info_width_;
-  int diff_info_height_;
-  int diff_info_size_;
-
-  RTC_DISALLOW_COPY_AND_ASSIGN(Differ);
-};
-
-}  // namespace webrtc
-
-#endif  // WEBRTC_MODULES_DESKTOP_CAPTURE_DIFFER_H_
diff --git a/webrtc/modules/desktop_capture/differ_unittest.cc b/webrtc/modules/desktop_capture/differ_unittest.cc
deleted file mode 100644
index 543910d..0000000
--- a/webrtc/modules/desktop_capture/differ_unittest.cc
+++ /dev/null
@@ -1,654 +0,0 @@
-/*
- *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include <memory>
-
-#include "testing/gmock/include/gmock/gmock.h"
-#include "webrtc/base/constructormagic.h"
-#include "webrtc/modules/desktop_capture/differ.h"
-#include "webrtc/modules/desktop_capture/differ_block.h"
-
-namespace webrtc {
-
-// 96x96 screen gives a 4x4 grid of blocks.
-const int kScreenWidth= 96;
-const int kScreenHeight = 96;
-
-// To test partial blocks, we need a width and height that are not multiples
-// of 16 (or 32, depending on current block size).
-const int kPartialScreenWidth = 70;
-const int kPartialScreenHeight = 70;
-
-class DifferTest : public testing::Test {
- public:
-  DifferTest() {
-  }
-
- protected:
-  void InitDiffer(int width, int height) {
-    width_ = width;
-    height_ = height;
-    bytes_per_pixel_ = kBytesPerPixel;
-    stride_ = (kBytesPerPixel * width);
-    buffer_size_ = width_ * height_ * bytes_per_pixel_;
-
-    differ_.reset(new Differ(width_, height_, bytes_per_pixel_, stride_));
-
-    prev_.reset(new uint8_t[buffer_size_]);
-    memset(prev_.get(), 0, buffer_size_);
-
-    curr_.reset(new uint8_t[buffer_size_]);
-    memset(curr_.get(), 0, buffer_size_);
-  }
-
-  void ClearBuffer(uint8_t* buffer) {
-    memset(buffer, 0, buffer_size_);
-  }
-
-  // Here in DifferTest so that tests can access private methods of Differ.
-  void MarkDirtyBlocks(const uint8_t* prev_buffer, const uint8_t* curr_buffer) {
-    differ_->MarkDirtyBlocks(prev_buffer, curr_buffer);
-  }
-
-  void MergeBlocks(DesktopRegion* dirty) {
-    differ_->MergeBlocks(dirty);
-  }
-
-  // Convenience method to count rectangles in a region.
-  int RegionRectCount(const DesktopRegion& region) {
-    int count = 0;
-    for (DesktopRegion::Iterator iter(region);
-         !iter.IsAtEnd(); iter.Advance()) {
-      ++count;
-    }
-    return count;
-  }
-
-  // Convenience wrapper for Differ's DiffBlock that calculates the appropriate
-  // offset to the start of the desired block.
-  bool DiffBlock(int block_x, int block_y) {
-    // Offset from upper-left of buffer to upper-left of requested block.
-    int block_offset = ((block_y * stride_) + (block_x * bytes_per_pixel_))
-                        * kBlockSize;
-    return BlockDifference(prev_.get() + block_offset,
-                           curr_.get() + block_offset,
-                           stride_);
-  }
-
-  // Write the pixel |value| into the specified block in the |buffer|.
-  // This is a convenience wrapper around WritePixel().
-  void WriteBlockPixel(uint8_t* buffer, int block_x, int block_y,
-                       int pixel_x, int pixel_y, uint32_t value) {
-    WritePixel(buffer, (block_x * kBlockSize) + pixel_x,
-               (block_y * kBlockSize) + pixel_y, value);
-  }
-
-  // Write the test pixel |value| into the |buffer| at the specified |x|,|y|
-  // location.
-  // Only the low-order bytes from |value| are written (assuming little-endian).
-  // So, for |value| = 0xaabbccdd:
-  //   If bytes_per_pixel = 4, then ddccbbaa will be written as the pixel value.
-  //   If                 = 3,        ddccbb
-  //   If                 = 2,          ddcc
-  //   If                 = 1,            dd
-  void WritePixel(uint8_t* buffer, int x, int y, uint32_t value) {
-    uint8_t* pixel = reinterpret_cast<uint8_t*>(&value);
-    buffer += (y * stride_) + (x * bytes_per_pixel_);
-    for (int b = bytes_per_pixel_ - 1; b >= 0; b--) {
-      *buffer++ = pixel[b];
-    }
-  }
-
-  // DiffInfo utility routines.
-  // These are here so that we don't have to make each DifferText_Xxx_Test
-  // class a friend class to Differ.
-
-  // Clear out the entire |diff_info_| buffer.
-  void ClearDiffInfo() {
-    memset(differ_->diff_info_.get(), 0, differ_->diff_info_size_);
-  }
-
-  // Get the value in the |diff_info_| array at (x,y).
-  bool GetDiffInfo(int x, int y) {
-    bool* diff_info = differ_->diff_info_.get();
-    return diff_info[(y * GetDiffInfoWidth()) + x];
-  }
-
-  // Width of |diff_info_| array.
-  int GetDiffInfoWidth() {
-    return differ_->diff_info_width_;
-  }
-
-  // Height of |diff_info_| array.
-  int GetDiffInfoHeight() {
-    return differ_->diff_info_height_;
-  }
-
-  // Size of |diff_info_| array.
-  int GetDiffInfoSize() {
-    return differ_->diff_info_size_;
-  }
-
-  void SetDiffInfo(int x, int y, bool value) {
-    bool* diff_info = differ_->diff_info_.get();
-    diff_info[(y * GetDiffInfoWidth()) + x] = value;
-  }
-
-  // Mark the range of blocks specified.
-  void MarkBlocks(int x_origin, int y_origin, int width, int height) {
-    for (int y = 0; y < height; y++) {
-      for (int x = 0; x < width; x++) {
-        SetDiffInfo(x_origin + x, y_origin + y, true);
-      }
-    }
-  }
-
-  // Verify that |region| contains a rectangle defined by |x|, |y|, |width| and
-  // |height|.
-  // |x|, |y|, |width| and |height| are specified in block (not pixel) units.
-  bool CheckDirtyRegionContainsRect(const DesktopRegion& region,
-                                    int x, int y,
-                                    int width, int height) {
-    DesktopRect r =
-      DesktopRect::MakeXYWH(x * kBlockSize, y * kBlockSize,
-                                    width * kBlockSize, height * kBlockSize);
-    for (DesktopRegion::Iterator i(region); !i.IsAtEnd(); i.Advance()) {
-      if (i.rect().equals(r))
-        return true;
-    }
-    return false;
-  }
-
-  // Mark the range of blocks specified and then verify that they are
-  // merged correctly.
-  // Only one rectangular region of blocks can be checked with this routine.
-  bool MarkBlocksAndCheckMerge(int x_origin, int y_origin,
-                               int width, int height) {
-    ClearDiffInfo();
-    MarkBlocks(x_origin, y_origin, width, height);
-
-    DesktopRegion dirty;
-    MergeBlocks(&dirty);
-
-
-    DesktopRect expected_rect = DesktopRect::MakeXYWH(
-        x_origin * kBlockSize, y_origin * kBlockSize,
-        width * kBlockSize, height * kBlockSize);
-
-    // Verify that the region contains expected_rect and it's the only
-    // rectangle.
-    DesktopRegion::Iterator it(dirty);
-    return !it.IsAtEnd() && expected_rect.equals(it.rect()) &&
-        (it.Advance(), it.IsAtEnd());
-  }
-
-  // The differ class we're testing.
-  std::unique_ptr<Differ> differ_;
-
-  // Screen/buffer info.
-  int width_;
-  int height_;
-  int bytes_per_pixel_;
-  int stride_;
-
-  // Size of each screen buffer.
-  int buffer_size_;
-
-  // Previous and current screen buffers.
-  std::unique_ptr<uint8_t[]> prev_;
-  std::unique_ptr<uint8_t[]> curr_;
-
- private:
-  RTC_DISALLOW_COPY_AND_ASSIGN(DifferTest);
-};
-
-TEST_F(DifferTest, Setup) {
-  InitDiffer(kScreenWidth, kScreenHeight);
-  // 96x96 pixels results in 3x3 array. Add 1 to each dimension as boundary.
-  // +---+---+---+---+
-  // | o | o | o | _ |
-  // +---+---+---+---+  o = blocks mapped to screen pixels
-  // | o | o | o | _ |
-  // +---+---+---+---+  _ = boundary blocks
-  // | o | o | o | _ |
-  // +---+---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  EXPECT_EQ(4, GetDiffInfoWidth());
-  EXPECT_EQ(4, GetDiffInfoHeight());
-  EXPECT_EQ(16, GetDiffInfoSize());
-}
-
-TEST_F(DifferTest, MarkDirtyBlocks_All) {
-  InitDiffer(kScreenWidth, kScreenHeight);
-  ClearDiffInfo();
-
-  // Update a pixel in each block.
-  for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
-    for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
-      WriteBlockPixel(curr_.get(), x, y, 10, 10, 0xff00ff);
-    }
-  }
-
-  MarkDirtyBlocks(prev_.get(), curr_.get());
-
-  // Make sure each block is marked as dirty.
-  for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
-    for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
-      EXPECT_TRUE(GetDiffInfo(x, y))
-          << "when x = " << x << ", and y = " << y;
-    }
-  }
-}
-
-TEST_F(DifferTest, MarkDirtyBlocks_Sampling) {
-  InitDiffer(kScreenWidth, kScreenHeight);
-  ClearDiffInfo();
-
-  // Update some pixels in image.
-  WriteBlockPixel(curr_.get(), 1, 0, 10, 10, 0xff00ff);
-  WriteBlockPixel(curr_.get(), 2, 1, 10, 10, 0xff00ff);
-  WriteBlockPixel(curr_.get(), 0, 2, 10, 10, 0xff00ff);
-
-  MarkDirtyBlocks(prev_.get(), curr_.get());
-
-  // Make sure corresponding blocks are updated.
-  EXPECT_FALSE(GetDiffInfo(0, 0));
-  EXPECT_FALSE(GetDiffInfo(0, 1));
-  EXPECT_TRUE(GetDiffInfo(0, 2));
-  EXPECT_TRUE(GetDiffInfo(1, 0));
-  EXPECT_FALSE(GetDiffInfo(1, 1));
-  EXPECT_FALSE(GetDiffInfo(1, 2));
-  EXPECT_FALSE(GetDiffInfo(2, 0));
-  EXPECT_TRUE(GetDiffInfo(2, 1));
-  EXPECT_FALSE(GetDiffInfo(2, 2));
-}
-
-TEST_F(DifferTest, DiffBlock) {
-  InitDiffer(kScreenWidth, kScreenHeight);
-
-  // Verify no differences at start.
-  EXPECT_FALSE(DiffBlock(0, 0));
-  EXPECT_FALSE(DiffBlock(1, 1));
-
-  // Write new data into the 4 corners of the middle block and verify that
-  // neighboring blocks are not affected.
-  int max = kBlockSize - 1;
-  WriteBlockPixel(curr_.get(), 1, 1, 0, 0, 0xffffff);
-  WriteBlockPixel(curr_.get(), 1, 1, 0, max, 0xffffff);
-  WriteBlockPixel(curr_.get(), 1, 1, max, 0, 0xffffff);
-  WriteBlockPixel(curr_.get(), 1, 1, max, max, 0xffffff);
-  EXPECT_FALSE(DiffBlock(0, 0));
-  EXPECT_FALSE(DiffBlock(0, 1));
-  EXPECT_FALSE(DiffBlock(0, 2));
-  EXPECT_FALSE(DiffBlock(1, 0));
-  EXPECT_TRUE(DiffBlock(1, 1));  // Only this block should change.
-  EXPECT_FALSE(DiffBlock(1, 2));
-  EXPECT_FALSE(DiffBlock(2, 0));
-  EXPECT_FALSE(DiffBlock(2, 1));
-  EXPECT_FALSE(DiffBlock(2, 2));
-}
-
-TEST_F(DifferTest, Partial_Setup) {
-  InitDiffer(kPartialScreenWidth, kPartialScreenHeight);
-  // 70x70 pixels results in 3x3 array: 2x2 full blocks + partials around
-  // the edge. One more is added to each dimension as a boundary.
-  // +---+---+---+---+
-  // | o | o | + | _ |
-  // +---+---+---+---+  o = blocks mapped to screen pixels
-  // | o | o | + | _ |
-  // +---+---+---+---+  + = partial blocks (top/left mapped to screen pixels)
-  // | + | + | + | _ |
-  // +---+---+---+---+  _ = boundary blocks
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  EXPECT_EQ(4, GetDiffInfoWidth());
-  EXPECT_EQ(4, GetDiffInfoHeight());
-  EXPECT_EQ(16, GetDiffInfoSize());
-}
-
-TEST_F(DifferTest, Partial_FirstPixel) {
-  InitDiffer(kPartialScreenWidth, kPartialScreenHeight);
-  ClearDiffInfo();
-
-  // Update the first pixel in each block.
-  for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
-    for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
-      WriteBlockPixel(curr_.get(), x, y, 0, 0, 0xff00ff);
-    }
-  }
-
-  MarkDirtyBlocks(prev_.get(), curr_.get());
-
-  // Make sure each block is marked as dirty.
-  for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
-    for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
-      EXPECT_TRUE(GetDiffInfo(x, y))
-          << "when x = " << x << ", and y = " << y;
-    }
-  }
-}
-
-TEST_F(DifferTest, Partial_BorderPixel) {
-  InitDiffer(kPartialScreenWidth, kPartialScreenHeight);
-  ClearDiffInfo();
-
-  // Update the right/bottom border pixels.
-  for (int y = 0; y < height_; y++) {
-    WritePixel(curr_.get(), width_ - 1, y, 0xff00ff);
-  }
-  for (int x = 0; x < width_; x++) {
-    WritePixel(curr_.get(), x, height_ - 1, 0xff00ff);
-  }
-
-  MarkDirtyBlocks(prev_.get(), curr_.get());
-
-  // Make sure last (partial) block in each row/column is marked as dirty.
-  int x_last = GetDiffInfoWidth() - 2;
-  for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
-    EXPECT_TRUE(GetDiffInfo(x_last, y))
-        << "when x = " << x_last << ", and y = " << y;
-  }
-  int y_last = GetDiffInfoHeight() - 2;
-  for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
-    EXPECT_TRUE(GetDiffInfo(x, y_last))
-        << "when x = " << x << ", and y = " << y_last;
-  }
-  // All other blocks are clean.
-  for (int y = 0; y < GetDiffInfoHeight() - 2; y++) {
-    for (int x = 0; x < GetDiffInfoWidth() - 2; x++) {
-      EXPECT_FALSE(GetDiffInfo(x, y)) << "when x = " << x << ", and y = " << y;
-    }
-  }
-}
-
-TEST_F(DifferTest, MergeBlocks_Empty) {
-  InitDiffer(kScreenWidth, kScreenHeight);
-
-  // No blocks marked:
-  // +---+---+---+---+
-  // |   |   |   | _ |
-  // +---+---+---+---+
-  // |   |   |   | _ |
-  // +---+---+---+---+
-  // |   |   |   | _ |
-  // +---+---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ClearDiffInfo();
-
-  DesktopRegion dirty;
-  MergeBlocks(&dirty);
-
-  EXPECT_TRUE(dirty.is_empty());
-}
-
-TEST_F(DifferTest, MergeBlocks_SingleBlock) {
-  InitDiffer(kScreenWidth, kScreenHeight);
-  // Mark a single block and make sure that there is a single merged
-  // rect with the correct bounds.
-  for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
-    for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
-      ASSERT_TRUE(MarkBlocksAndCheckMerge(x, y, 1, 1)) << "x: " << x
-                                                       << "y: " << y;
-    }
-  }
-}
-
-TEST_F(DifferTest, MergeBlocks_BlockRow) {
-  InitDiffer(kScreenWidth, kScreenHeight);
-
-  // +---+---+---+---+
-  // | X | X |   | _ |
-  // +---+---+---+---+
-  // |   |   |   | _ |
-  // +---+---+---+---+
-  // |   |   |   | _ |
-  // +---+---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 2, 1));
-
-  // +---+---+---+---+
-  // |   |   |   | _ |
-  // +---+---+---+---+
-  // | X | X | X | _ |
-  // +---+---+---+---+
-  // |   |   |   | _ |
-  // +---+---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 1, 3, 1));
-
-  // +---+---+---+---+
-  // |   |   |   | _ |
-  // +---+---+---+---+
-  // |   |   |   | _ |
-  // +---+---+---+---+
-  // |   | X | X | _ |
-  // +---+---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 2, 2, 1));
-}
-
-TEST_F(DifferTest, MergeBlocks_BlockColumn) {
-  InitDiffer(kScreenWidth, kScreenHeight);
-
-  // +---+---+---+---+
-  // | X |   |   | _ |
-  // +---+---+---+---+
-  // | X |   |   | _ |
-  // +---+---+---+---+
-  // |   |   |   | _ |
-  // +---+---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 1, 2));
-
-  // +---+---+---+---+
-  // |   |   |   | _ |
-  // +---+---+---+---+
-  // |   | X |   | _ |
-  // +---+---+---+---+
-  // |   | X |   | _ |
-  // +---+---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 1, 1, 2));
-
-  // +---+---+---+---+
-  // |   |   | X | _ |
-  // +---+---+---+---+
-  // |   |   | X | _ |
-  // +---+---+---+---+
-  // |   |   | X | _ |
-  // +---+---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ASSERT_TRUE(MarkBlocksAndCheckMerge(2, 0, 1, 3));
-}
-
-TEST_F(DifferTest, MergeBlocks_BlockRect) {
-  InitDiffer(kScreenWidth, kScreenHeight);
-
-  // +---+---+---+---+
-  // | X | X |   | _ |
-  // +---+---+---+---+
-  // | X | X |   | _ |
-  // +---+---+---+---+
-  // |   |   |   | _ |
-  // +---+---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 2, 2));
-
-  // +---+---+---+---+
-  // |   |   |   | _ |
-  // +---+---+---+---+
-  // |   | X | X | _ |
-  // +---+---+---+---+
-  // |   | X | X | _ |
-  // +---+---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 1, 2, 2));
-
-  // +---+---+---+---+
-  // |   | X | X | _ |
-  // +---+---+---+---+
-  // |   | X | X | _ |
-  // +---+---+---+---+
-  // |   | X | X | _ |
-  // +---+---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 0, 2, 3));
-
-  // +---+---+---+---+
-  // |   |   |   | _ |
-  // +---+---+---+---+
-  // | X | X | X | _ |
-  // +---+---+---+---+
-  // | X | X | X | _ |
-  // +---+---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 1, 3, 2));
-
-  // +---+---+---+---+
-  // | X | X | X | _ |
-  // +---+---+---+---+
-  // | X | X | X | _ |
-  // +---+---+---+---+
-  // | X | X | X | _ |
-  // +---+---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 3, 3));
-}
-
-// This tests marked regions that require more than 1 single dirty rect.
-// The exact rects returned depend on the current implementation, so these
-// may need to be updated if we modify how we merge blocks.
-TEST_F(DifferTest, MergeBlocks_MultiRect) {
-  InitDiffer(kScreenWidth, kScreenHeight);
-  DesktopRegion dirty;
-
-  // +---+---+---+---+      +---+---+---+
-  // |   | X |   | _ |      |   | 0 |   |
-  // +---+---+---+---+      +---+---+---+
-  // | X |   |   | _ |      | 1 |   |   |
-  // +---+---+---+---+  =>  +---+---+---+
-  // |   |   | X | _ |      |   |   | 2 |
-  // +---+---+---+---+      +---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ClearDiffInfo();
-  MarkBlocks(1, 0, 1, 1);
-  MarkBlocks(0, 1, 1, 1);
-  MarkBlocks(2, 2, 1, 1);
-
-  dirty.Clear();
-  MergeBlocks(&dirty);
-
-  ASSERT_EQ(3, RegionRectCount(dirty));
-  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 0, 1, 1));
-  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 1, 1));
-  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 2, 1, 1));
-
-  // +---+---+---+---+      +---+---+---+
-  // |   |   | X | _ |      |   |   | 0 |
-  // +---+---+---+---+      +---+---+---+
-  // | X | X | X | _ |      | 1   1   1 |
-  // +---+---+---+---+  =>  +           +
-  // | X | X | X | _ |      | 1   1   1 |
-  // +---+---+---+---+      +---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ClearDiffInfo();
-  MarkBlocks(2, 0, 1, 1);
-  MarkBlocks(0, 1, 3, 2);
-
-  dirty.Clear();
-  MergeBlocks(&dirty);
-
-  ASSERT_EQ(2, RegionRectCount(dirty));
-  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 0, 1, 1));
-  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 3, 2));
-
-  // +---+---+---+---+      +---+---+---+
-  // |   |   |   | _ |      |   |   |   |
-  // +---+---+---+---+      +---+---+---+
-  // | X |   | X | _ |      | 0 |   | 1 |
-  // +---+---+---+---+  =>  +---+---+---+
-  // | X | X | X | _ |      | 2   2   2 |
-  // +---+---+---+---+      +---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ClearDiffInfo();
-  MarkBlocks(0, 1, 1, 1);
-  MarkBlocks(2, 1, 1, 1);
-  MarkBlocks(0, 2, 3, 1);
-
-  dirty.Clear();
-  MergeBlocks(&dirty);
-
-  ASSERT_EQ(3, RegionRectCount(dirty));
-  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 1, 1));
-  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 1, 1, 1));
-  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 2, 3, 1));
-
-  // +---+---+---+---+      +---+---+---+
-  // | X | X | X | _ |      | 0   0   0 |
-  // +---+---+---+---+      +---+---+---+
-  // | X |   | X | _ |      | 1 |   | 2 |
-  // +---+---+---+---+  =>  +---+---+---+
-  // | X | X | X | _ |      | 3   3   3 |
-  // +---+---+---+---+      +---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ClearDiffInfo();
-  MarkBlocks(0, 0, 3, 1);
-  MarkBlocks(0, 1, 1, 1);
-  MarkBlocks(2, 1, 1, 1);
-  MarkBlocks(0, 2, 3, 1);
-
-  dirty.Clear();
-  MergeBlocks(&dirty);
-
-  ASSERT_EQ(4, RegionRectCount(dirty));
-  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 3, 1));
-  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 1, 1));
-  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 1, 1, 1));
-  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 2, 3, 1));
-
-  // +---+---+---+---+      +---+---+---+
-  // | X | X |   | _ |      | 0   0 |   |
-  // +---+---+---+---+      +       +---+
-  // | X | X |   | _ |      | 0   0 |   |
-  // +---+---+---+---+  =>  +---+---+---+
-  // |   | X |   | _ |      |   | 1 |   |
-  // +---+---+---+---+      +---+---+---+
-  // | _ | _ | _ | _ |
-  // +---+---+---+---+
-  ClearDiffInfo();
-  MarkBlocks(0, 0, 2, 2);
-  MarkBlocks(1, 2, 1, 1);
-
-  dirty.Clear();
-  MergeBlocks(&dirty);
-
-  ASSERT_EQ(2, RegionRectCount(dirty));
-  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 2, 2));
-  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 2, 1, 1));
-}
-
-}  // namespace webrtc
diff --git a/webrtc/modules/desktop_capture/screen_capturer_x11.cc b/webrtc/modules/desktop_capture/screen_capturer_x11.cc
index d274140..6f5e520 100644
--- a/webrtc/modules/desktop_capture/screen_capturer_x11.cc
+++ b/webrtc/modules/desktop_capture/screen_capturer_x11.cc
@@ -26,7 +26,6 @@
 #include "webrtc/base/timeutils.h"
 #include "webrtc/modules/desktop_capture/desktop_capture_options.h"
 #include "webrtc/modules/desktop_capture/desktop_frame.h"
-#include "webrtc/modules/desktop_capture/differ.h"
 #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h"
 #include "webrtc/modules/desktop_capture/screen_capturer_differ_wrapper.h"
 #include "webrtc/modules/desktop_capture/screen_capturer_helper.h"
@@ -38,6 +37,12 @@
 namespace {
 
 // A class to perform video frame capturing for Linux.
+//
+// If XDamage is used, this class sets DesktopFrame::updated_region() according
+// to the areas reported by XDamage. Otherwise this class does not detect
+// DesktopFrame::updated_region(), the field is always set to the entire frame
+// rectangle. ScreenCapturerDifferWrapper should be used if that functionality
+// is necessary.
 class ScreenCapturerLinux : public ScreenCapturer,
                             public SharedXDisplay::XEventHandler {
  public:
@@ -116,9 +121,6 @@
   // current with the last buffer used.
   DesktopRegion last_invalid_region_;
 
-  // |Differ| for use when polling for changes.
-  std::unique_ptr<Differ> differ_;
-
   RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerLinux);
 };
 
@@ -253,16 +255,6 @@
             new BasicDesktopFrame(x_server_pixel_buffer_.window_size()))));
   }
 
-  // Refresh the Differ helper used by CaptureFrame(), if needed.
-  DesktopFrame* frame = queue_.current_frame();
-  if (!use_damage_ &&
-      (!differ_ || (differ_->width() != frame->size().width()) ||
-       (differ_->height() != frame->size().height()) ||
-       (differ_->bytes_per_row() != frame->stride()))) {
-    differ_.reset(new Differ(frame->size().width(), frame->size().height(),
-                             DesktopFrame::kBytesPerPixel, frame->stride()));
-  }
-
   std::unique_ptr<DesktopFrame> result = CaptureScreen();
   last_invalid_region_ = result->updated_region();
   result->set_capture_time_ms((rtc::TimeNanos() - capture_start_time_nanos) /
@@ -349,21 +341,7 @@
     // screen-resolution change.  In either case, need a full-screen capture.
     DesktopRect screen_rect = DesktopRect::MakeSize(frame->size());
     x_server_pixel_buffer_.CaptureRect(screen_rect, frame.get());
-
-    if (queue_.previous_frame()) {
-      // Full-screen polling, so calculate the invalid rects here, based on the
-      // changed pixels between current and previous buffers.
-      RTC_DCHECK(differ_);
-      RTC_DCHECK(queue_.previous_frame()->data());
-      differ_->CalcDirtyRegion(queue_.previous_frame()->data(),
-                               frame->data(), updated_region);
-    } else {
-      // No previous buffer, so always invalidate the whole screen, whether
-      // or not DAMAGE is being used.  DAMAGE doesn't necessarily send a
-      // full-screen notification after a screen-resolution change, so
-      // this is done here.
-      updated_region->SetRect(screen_rect);
-    }
+    updated_region->SetRect(screen_rect);
   }
 
   return std::move(frame);
diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc b/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc
index 80d2da5..2c2178d 100644
--- a/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc
+++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc
@@ -20,7 +20,6 @@
 #include "webrtc/modules/desktop_capture/desktop_frame.h"
 #include "webrtc/modules/desktop_capture/desktop_frame_win.h"
 #include "webrtc/modules/desktop_capture/desktop_region.h"
-#include "webrtc/modules/desktop_capture/differ.h"
 #include "webrtc/modules/desktop_capture/mouse_cursor.h"
 #include "webrtc/modules/desktop_capture/win/cursor.h"
 #include "webrtc/modules/desktop_capture/win/desktop.h"
@@ -86,41 +85,13 @@
     return;
   }
 
-  const DesktopFrame* current_frame = queue_.current_frame();
-  const DesktopFrame* last_frame = queue_.previous_frame();
-  if (last_frame && last_frame->size().equals(current_frame->size())) {
-    // Make sure the differencer is set up correctly for these previous and
-    // current screens.
-    if (!differ_.get() ||
-        (differ_->width() != current_frame->size().width()) ||
-        (differ_->height() != current_frame->size().height()) ||
-        (differ_->bytes_per_row() != current_frame->stride())) {
-      differ_.reset(new Differ(current_frame->size().width(),
-                               current_frame->size().height(),
-                               DesktopFrame::kBytesPerPixel,
-                               current_frame->stride()));
-    }
-
-    // Calculate difference between the two last captured frames.
-    DesktopRegion region;
-    differ_->CalcDirtyRegion(last_frame->data(), current_frame->data(),
-                             &region);
-    helper_.InvalidateRegion(region);
-  } else {
-    // No previous frame is available, or the screen is resized. Invalidate the
-    // whole screen.
-    helper_.InvalidateScreen(current_frame->size());
-  }
-
-  helper_.set_size_most_recent(current_frame->size());
-
   // Emit the current frame.
   std::unique_ptr<DesktopFrame> frame = queue_.current_frame()->Share();
   frame->set_dpi(DesktopVector(
       GetDeviceCaps(desktop_dc_, LOGPIXELSX),
       GetDeviceCaps(desktop_dc_, LOGPIXELSY)));
-  frame->mutable_updated_region()->Clear();
-  helper_.TakeInvalidRegion(frame->mutable_updated_region());
+  frame->mutable_updated_region()->SetRect(
+      DesktopRect::MakeSize(frame->size()));
   frame->set_capture_time_ms(
       (rtc::TimeNanos() - capture_start_time_nanos) /
       rtc::kNumNanosecsPerMillisec);
@@ -212,8 +183,6 @@
 
     // Make sure the frame buffers will be reallocated.
     queue_.Reset();
-
-    helper_.ClearInvalidRegion();
   }
 }
 
diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.h b/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.h
index d1b6395..01a5991 100644
--- a/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.h
+++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.h
@@ -19,17 +19,17 @@
 
 #include "webrtc/base/constructormagic.h"
 #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h"
-#include "webrtc/modules/desktop_capture/screen_capturer_helper.h"
 #include "webrtc/modules/desktop_capture/shared_desktop_frame.h"
 #include "webrtc/modules/desktop_capture/win/scoped_thread_desktop.h"
 
 namespace webrtc {
 
-class Differ;
-
 // ScreenCapturerWinGdi captures 32bit RGB using GDI.
 //
 // ScreenCapturerWinGdi is double-buffered as required by ScreenCapturer.
+// This class does not detect DesktopFrame::updated_region(), the field is
+// always set to the entire frame rectangle. ScreenCapturerDifferWrapper should
+// be used if that functionality is necessary.
 class ScreenCapturerWinGdi : public ScreenCapturer {
  public:
   explicit ScreenCapturerWinGdi(const DesktopCaptureOptions& options);
@@ -61,10 +61,6 @@
   ScreenId current_screen_id_ = kFullDesktopScreenId;
   std::wstring current_device_key_;
 
-  // A thread-safe list of invalid rectangles, and the size of the most
-  // recently captured screen.
-  ScreenCapturerHelper helper_;
-
   ScopedThreadDesktop desktop_;
 
   // GDI resources used for screen capture.
@@ -78,9 +74,6 @@
   // the primary display's top-left.
   DesktopRect desktop_dc_rect_;
 
-  // Class to calculate the difference between two screen bitmaps.
-  std::unique_ptr<Differ> differ_;
-
   HMODULE dwmapi_library_ = NULL;
   DwmEnableCompositionFunc composition_func_ = nullptr;
 
diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc b/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc
index e22b272..e5a37c9 100644
--- a/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc
+++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc
@@ -18,7 +18,6 @@
 #include "webrtc/modules/desktop_capture/desktop_frame.h"
 #include "webrtc/modules/desktop_capture/desktop_frame_win.h"
 #include "webrtc/modules/desktop_capture/desktop_region.h"
-#include "webrtc/modules/desktop_capture/differ.h"
 #include "webrtc/modules/desktop_capture/mouse_cursor.h"
 #include "webrtc/modules/desktop_capture/win/cursor.h"
 #include "webrtc/modules/desktop_capture/win/desktop.h"
@@ -116,33 +115,12 @@
     return;
   }
 
-  const DesktopFrame* current_frame = queue_.current_frame();
-  const DesktopFrame* last_frame = queue_.previous_frame();
-  DesktopRegion updated_region;
-  if (last_frame && last_frame->size().equals(current_frame->size())) {
-    // Make sure the differencer is set up correctly for these previous and
-    // current screens.
-    if (!differ_.get() || (differ_->width() != current_frame->size().width()) ||
-        (differ_->height() != current_frame->size().height()) ||
-        (differ_->bytes_per_row() != current_frame->stride())) {
-      differ_.reset(new Differ(current_frame->size().width(),
-                               current_frame->size().height(),
-                               DesktopFrame::kBytesPerPixel,
-                               current_frame->stride()));
-    }
-
-    // Calculate difference between the two last captured frames.
-    differ_->CalcDirtyRegion(
-        last_frame->data(), current_frame->data(), &updated_region);
-  } else {
-    updated_region.SetRect(DesktopRect::MakeSize(current_frame->size()));
-  }
-
   // Emit the current frame.
   std::unique_ptr<DesktopFrame> frame = queue_.current_frame()->Share();
   frame->set_dpi(DesktopVector(GetDeviceCaps(desktop_dc_, LOGPIXELSX),
                                GetDeviceCaps(desktop_dc_, LOGPIXELSY)));
-  frame->mutable_updated_region()->Swap(&updated_region);
+  frame->mutable_updated_region()->SetRect(
+      DesktopRect::MakeSize(frame->size()));
   frame->set_capture_time_ms((rtc::TimeNanos() - capture_start_time_nanos) /
                              rtc::kNumNanosecsPerMillisec);
   callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h b/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h
index 969cb83..080a57c 100644
--- a/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h
+++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h
@@ -29,12 +29,15 @@
 
 class DesktopFrame;
 class DesktopRect;
-class Differ;
 
 // Captures the screen using the Magnification API to support window exclusion.
 // Each capturer must run on a dedicated thread because it uses thread local
 // storage for redirecting the library callback. Also the thread must have a UI
 // message loop to handle the window messages for the magnifier window.
+//
+// This class does not detect DesktopFrame::updated_region(), the field is
+// always set to the entire frame rectangle. ScreenCapturerDifferWrapper should
+// be used if that functionality is necessary.
 class ScreenCapturerWinMagnifier : public ScreenCapturer {
  public:
   // |fallback_capturer| will be used to capture the screen if a non-primary
@@ -116,9 +119,6 @@
   // Queue of the frames buffers.
   ScreenCaptureFrameQueue<SharedDesktopFrame> queue_;
 
-  // Class to calculate the difference between two screen bitmaps.
-  std::unique_ptr<Differ> differ_;
-
   ScopedThreadDesktop desktop_;
 
   // Used for getting the screen dpi.