16c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org/*
26c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
36c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org *
46c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org *  Use of this source code is governed by a BSD-style license
56c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org *  that can be found in the LICENSE file in the root of the source
66c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org *  tree. An additional intellectual property rights grant can be found
76c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org *  in the file PATENTS.  All contributing project authors may
86c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org *  be found in the AUTHORS file in the root of the source tree.
96c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org */
106c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
116c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org#include "testing/gmock/include/gmock/gmock.h"
126c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org#include "webrtc/modules/desktop_capture/differ.h"
136c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org#include "webrtc/modules/desktop_capture/differ_block.h"
146c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org#include "webrtc/system_wrappers/interface/scoped_ptr.h"
156c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
166c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgnamespace webrtc {
176c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
186c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org// 96x96 screen gives a 4x4 grid of blocks.
196c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgconst int kScreenWidth= 96;
206c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgconst int kScreenHeight = 96;
216c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
226c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org// To test partial blocks, we need a width and height that are not multiples
236c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org// of 16 (or 32, depending on current block size).
246c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgconst int kPartialScreenWidth = 70;
256c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgconst int kPartialScreenHeight = 70;
266c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
276c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgclass DifferTest : public testing::Test {
286c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org public:
296c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  DifferTest() {
306c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
316c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
326c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org protected:
336c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  void InitDiffer(int width, int height) {
346c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    width_ = width;
356c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    height_ = height;
366c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    bytes_per_pixel_ = kBytesPerPixel;
376c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    stride_ = (kBytesPerPixel * width);
386c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    buffer_size_ = width_ * height_ * bytes_per_pixel_;
396c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
406c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    differ_.reset(new Differ(width_, height_, bytes_per_pixel_, stride_));
416c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
426c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    prev_.reset(new uint8_t[buffer_size_]);
436c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    memset(prev_.get(), 0, buffer_size_);
446c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
456c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    curr_.reset(new uint8_t[buffer_size_]);
466c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    memset(curr_.get(), 0, buffer_size_);
476c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
486c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
496c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  void ClearBuffer(uint8_t* buffer) {
506c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    memset(buffer, 0, buffer_size_);
516c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
526c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
536c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Here in DifferTest so that tests can access private methods of Differ.
546c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  void MarkDirtyBlocks(const void* prev_buffer, const void* curr_buffer) {
556c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    differ_->MarkDirtyBlocks(prev_buffer, curr_buffer);
566c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
576c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
586c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  void MergeBlocks(DesktopRegion* dirty) {
596c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    differ_->MergeBlocks(dirty);
606c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
616c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
626c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Convenience method to count rectangles in a region.
636c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int RegionRectCount(const DesktopRegion& region) {
646c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    int count = 0;
656c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    for (DesktopRegion::Iterator iter(region);
666c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org         !iter.IsAtEnd(); iter.Advance()) {
676c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org      ++count;
686c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    }
696c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    return count;
706c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
716c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
726c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Convenience wrapper for Differ's DiffBlock that calculates the appropriate
736c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // offset to the start of the desired block.
746c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  DiffInfo DiffBlock(int block_x, int block_y) {
756c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    // Offset from upper-left of buffer to upper-left of requested block.
766c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    int block_offset = ((block_y * stride_) + (block_x * bytes_per_pixel_))
776c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org                        * kBlockSize;
786c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    return BlockDifference(prev_.get() + block_offset,
796c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org                           curr_.get() + block_offset,
806c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org                           stride_);
816c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
826c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
836c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Write the pixel |value| into the specified block in the |buffer|.
846c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // This is a convenience wrapper around WritePixel().
856c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  void WriteBlockPixel(uint8_t* buffer, int block_x, int block_y,
866c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org                       int pixel_x, int pixel_y, uint32_t value) {
876c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    WritePixel(buffer, (block_x * kBlockSize) + pixel_x,
886c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org               (block_y * kBlockSize) + pixel_y, value);
896c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
906c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
916c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Write the test pixel |value| into the |buffer| at the specified |x|,|y|
926c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // location.
936c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Only the low-order bytes from |value| are written (assuming little-endian).
946c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // So, for |value| = 0xaabbccdd:
956c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  //   If bytes_per_pixel = 4, then ddccbbaa will be written as the pixel value.
966c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  //   If                 = 3,        ddccbb
976c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  //   If                 = 2,          ddcc
986c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  //   If                 = 1,            dd
996c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  void WritePixel(uint8_t* buffer, int x, int y, uint32_t value) {
1006c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    uint8_t* pixel = reinterpret_cast<uint8_t*>(&value);
1016c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    buffer += (y * stride_) + (x * bytes_per_pixel_);
1026c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    for (int b = bytes_per_pixel_ - 1; b >= 0; b--) {
1036c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org      *buffer++ = pixel[b];
1046c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    }
1056c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
1066c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1076c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // DiffInfo utility routines.
1086c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // These are here so that we don't have to make each DifferText_Xxx_Test
1096c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // class a friend class to Differ.
1106c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1116c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Clear out the entire |diff_info_| buffer.
1126c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  void ClearDiffInfo() {
1136c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    memset(differ_->diff_info_.get(), 0, differ_->diff_info_size_);
1146c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
1156c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1166c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Get the value in the |diff_info_| array at (x,y).
1176c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  DiffInfo GetDiffInfo(int x, int y) {
1186c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    DiffInfo* diff_info = differ_->diff_info_.get();
1196c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    return diff_info[(y * GetDiffInfoWidth()) + x];
1206c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
1216c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1226c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Width of |diff_info_| array.
1236c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int GetDiffInfoWidth() {
1246c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    return differ_->diff_info_width_;
1256c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
1266c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1276c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Height of |diff_info_| array.
1286c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int GetDiffInfoHeight() {
1296c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    return differ_->diff_info_height_;
1306c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
1316c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1326c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Size of |diff_info_| array.
1336c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int GetDiffInfoSize() {
1346c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    return differ_->diff_info_size_;
1356c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
1366c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1376c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  void SetDiffInfo(int x, int y, const DiffInfo& value) {
1386c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    DiffInfo* diff_info = differ_->diff_info_.get();
1396c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    diff_info[(y * GetDiffInfoWidth()) + x] = value;
1406c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
1416c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1426c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Mark the range of blocks specified.
1436c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  void MarkBlocks(int x_origin, int y_origin, int width, int height) {
1446c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    for (int y = 0; y < height; y++) {
1456c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org      for (int x = 0; x < width; x++) {
1466c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org        SetDiffInfo(x_origin + x, y_origin + y, 1);
1476c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org      }
1486c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    }
1496c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
1506c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1516c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Verify that |region| contains a rectangle defined by |x|, |y|, |width| and
1526c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |height|.
1536c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |x|, |y|, |width| and |height| are specified in block (not pixel) units.
1546c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  bool CheckDirtyRegionContainsRect(const DesktopRegion& region,
1556c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org                                    int x, int y,
1566c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org                                    int width, int height) {
1576c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    DesktopRect r =
1586c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org      DesktopRect::MakeXYWH(x * kBlockSize, y * kBlockSize,
1596c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org                                    width * kBlockSize, height * kBlockSize);
1606c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    for (DesktopRegion::Iterator i(region); !i.IsAtEnd(); i.Advance()) {
1616c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org      if (i.rect().equals(r))
1626c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org        return true;
1636c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    }
1646c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    return false;
1656c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
1666c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1676c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Mark the range of blocks specified and then verify that they are
1686c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // merged correctly.
1696c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Only one rectangular region of blocks can be checked with this routine.
1706c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  bool MarkBlocksAndCheckMerge(int x_origin, int y_origin,
1716c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org                               int width, int height) {
1726c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    ClearDiffInfo();
1736c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    MarkBlocks(x_origin, y_origin, width, height);
1746c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1756c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    DesktopRegion dirty;
1766c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    MergeBlocks(&dirty);
1776c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1786c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1796c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    DesktopRect expected_rect = DesktopRect::MakeXYWH(
1806c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org        x_origin * kBlockSize, y_origin * kBlockSize,
1816c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org        width * kBlockSize, height * kBlockSize);
1826c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1836c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    // Verify that the region contains expected_rect and it's the only
1846c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    // rectangle.
1856c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    DesktopRegion::Iterator it(dirty);
1866c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    return !it.IsAtEnd() && expected_rect.equals(it.rect()) &&
1876c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org        (it.Advance(), it.IsAtEnd());
1886c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
1896c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1906c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // The differ class we're testing.
1916c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  scoped_ptr<Differ> differ_;
1926c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1936c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Screen/buffer info.
1946c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int width_;
1956c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int height_;
1966c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int bytes_per_pixel_;
1976c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int stride_;
1986c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
1996c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Size of each screen buffer.
2006c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int buffer_size_;
2016c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
2026c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Previous and current screen buffers.
203ba47616ee5a8d8a4d94e160b64b79a56845e291bandrew@webrtc.org  scoped_ptr<uint8_t[]> prev_;
204ba47616ee5a8d8a4d94e160b64b79a56845e291bandrew@webrtc.org  scoped_ptr<uint8_t[]> curr_;
2056c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
2066c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org private:
2076c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  DISALLOW_COPY_AND_ASSIGN(DifferTest);
2086c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org};
2096c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
2106c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgTEST_F(DifferTest, Setup) {
2116c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  InitDiffer(kScreenWidth, kScreenHeight);
2126c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // 96x96 pixels results in 3x3 array. Add 1 to each dimension as boundary.
2136c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
2146c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | o | o | o | _ |
2156c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+  o = blocks mapped to screen pixels
2166c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | o | o | o | _ |
2176c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+  _ = boundary blocks
2186c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | o | o | o | _ |
2196c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
2206c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
2216c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
2226c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(4, GetDiffInfoWidth());
2236c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(4, GetDiffInfoHeight());
2246c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(16, GetDiffInfoSize());
2256c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org}
2266c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
2276c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgTEST_F(DifferTest, MarkDirtyBlocks_All) {
2286c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  InitDiffer(kScreenWidth, kScreenHeight);
2296c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ClearDiffInfo();
2306c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
2316c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Update a pixel in each block.
2326c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
2336c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
2346c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org      WriteBlockPixel(curr_.get(), x, y, 10, 10, 0xff00ff);
2356c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    }
2366c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
2376c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
2386c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkDirtyBlocks(prev_.get(), curr_.get());
2396c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
2406c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Make sure each block is marked as dirty.
2416c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
2426c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
2436c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org      EXPECT_EQ(1, GetDiffInfo(x, y))
2446c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org          << "when x = " << x << ", and y = " << y;
2456c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    }
2466c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
2476c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org}
2486c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
2496c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgTEST_F(DifferTest, MarkDirtyBlocks_Sampling) {
2506c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  InitDiffer(kScreenWidth, kScreenHeight);
2516c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ClearDiffInfo();
2526c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
2536c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Update some pixels in image.
2546c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  WriteBlockPixel(curr_.get(), 1, 0, 10, 10, 0xff00ff);
2556c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  WriteBlockPixel(curr_.get(), 2, 1, 10, 10, 0xff00ff);
2566c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  WriteBlockPixel(curr_.get(), 0, 2, 10, 10, 0xff00ff);
2576c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
2586c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkDirtyBlocks(prev_.get(), curr_.get());
2596c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
2606c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Make sure corresponding blocks are updated.
2616c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, GetDiffInfo(0, 0));
2626c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, GetDiffInfo(0, 1));
2636c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(1, GetDiffInfo(0, 2));
2646c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(1, GetDiffInfo(1, 0));
2656c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, GetDiffInfo(1, 1));
2666c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, GetDiffInfo(1, 2));
2676c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, GetDiffInfo(2, 0));
2686c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(1, GetDiffInfo(2, 1));
2696c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, GetDiffInfo(2, 2));
2706c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org}
2716c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
2726c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgTEST_F(DifferTest, DiffBlock) {
2736c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  InitDiffer(kScreenWidth, kScreenHeight);
2746c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
2756c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Verify no differences at start.
2766c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, DiffBlock(0, 0));
2776c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, DiffBlock(1, 1));
2786c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
2796c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Write new data into the 4 corners of the middle block and verify that
2806c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // neighboring blocks are not affected.
2816c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int max = kBlockSize - 1;
2826c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  WriteBlockPixel(curr_.get(), 1, 1, 0, 0, 0xffffff);
2836c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  WriteBlockPixel(curr_.get(), 1, 1, 0, max, 0xffffff);
2846c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  WriteBlockPixel(curr_.get(), 1, 1, max, 0, 0xffffff);
2856c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  WriteBlockPixel(curr_.get(), 1, 1, max, max, 0xffffff);
2866c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, DiffBlock(0, 0));
2876c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, DiffBlock(0, 1));
2886c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, DiffBlock(0, 2));
2896c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, DiffBlock(1, 0));
2906c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(1, DiffBlock(1, 1));  // Only this block should change.
2916c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, DiffBlock(1, 2));
2926c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, DiffBlock(2, 0));
2936c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, DiffBlock(2, 1));
2946c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(0, DiffBlock(2, 2));
2956c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org}
2966c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
2976c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgTEST_F(DifferTest, Partial_Setup) {
2986c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  InitDiffer(kPartialScreenWidth, kPartialScreenHeight);
2996c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // 70x70 pixels results in 3x3 array: 2x2 full blocks + partials around
3006c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // the edge. One more is added to each dimension as a boundary.
3016c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
3026c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | o | o | + | _ |
3036c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+  o = blocks mapped to screen pixels
3046c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | o | o | + | _ |
3056c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+  + = partial blocks (top/left mapped to screen pixels)
3066c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | + | + | + | _ |
3076c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+  _ = boundary blocks
3086c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
3096c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
3106c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(4, GetDiffInfoWidth());
3116c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(4, GetDiffInfoHeight());
3126c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_EQ(16, GetDiffInfoSize());
3136c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org}
3146c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
3156c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgTEST_F(DifferTest, Partial_FirstPixel) {
3166c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  InitDiffer(kPartialScreenWidth, kPartialScreenHeight);
3176c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ClearDiffInfo();
3186c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
3196c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Update the first pixel in each block.
3206c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
3216c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
3226c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org      WriteBlockPixel(curr_.get(), x, y, 0, 0, 0xff00ff);
3236c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    }
3246c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
3256c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
3266c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkDirtyBlocks(prev_.get(), curr_.get());
3276c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
3286c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Make sure each block is marked as dirty.
3296c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
3306c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
3316c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org      EXPECT_EQ(1, GetDiffInfo(x, y))
3326c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org          << "when x = " << x << ", and y = " << y;
3336c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    }
3346c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
3356c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org}
3366c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
3376c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgTEST_F(DifferTest, Partial_BorderPixel) {
3386c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  InitDiffer(kPartialScreenWidth, kPartialScreenHeight);
3396c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ClearDiffInfo();
3406c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
3416c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Update the right/bottom border pixels.
3426c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  for (int y = 0; y < height_; y++) {
3436c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    WritePixel(curr_.get(), width_ - 1, y, 0xff00ff);
3446c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
3456c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  for (int x = 0; x < width_; x++) {
3466c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    WritePixel(curr_.get(), x, height_ - 1, 0xff00ff);
3476c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
3486c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
3496c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkDirtyBlocks(prev_.get(), curr_.get());
3506c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
3516c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Make sure last (partial) block in each row/column is marked as dirty.
3526c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int x_last = GetDiffInfoWidth() - 2;
3536c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
3546c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    EXPECT_EQ(1, GetDiffInfo(x_last, y))
3556c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org        << "when x = " << x_last << ", and y = " << y;
3566c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
3576c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  int y_last = GetDiffInfoHeight() - 2;
3586c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
3596c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    EXPECT_EQ(1, GetDiffInfo(x, y_last))
3606c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org        << "when x = " << x << ", and y = " << y_last;
3616c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
3626c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // All other blocks are clean.
3636c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  for (int y = 0; y < GetDiffInfoHeight() - 2; y++) {
3646c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    for (int x = 0; x < GetDiffInfoWidth() - 2; x++) {
3656c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org      EXPECT_EQ(0, GetDiffInfo(x, y)) << "when x = " << x << ", and y = " << y;
3666c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    }
3676c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
3686c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org}
3696c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
3706c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgTEST_F(DifferTest, MergeBlocks_Empty) {
3716c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  InitDiffer(kScreenWidth, kScreenHeight);
3726c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
3736c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // No blocks marked:
3746c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
3756c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   |   | _ |
3766c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
3776c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   |   | _ |
3786c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
3796c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   |   | _ |
3806c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
3816c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
3826c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
3836c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ClearDiffInfo();
3846c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
3856c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  DesktopRegion dirty;
3866c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MergeBlocks(&dirty);
3876c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
3886c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  EXPECT_TRUE(dirty.is_empty());
3896c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org}
3906c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
3916c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgTEST_F(DifferTest, MergeBlocks_SingleBlock) {
3926c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  InitDiffer(kScreenWidth, kScreenHeight);
3936c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // Mark a single block and make sure that there is a single merged
3946c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // rect with the correct bounds.
3956c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  for (int y = 0; y < GetDiffInfoHeight() - 1; y++) {
3966c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    for (int x = 0; x < GetDiffInfoWidth() - 1; x++) {
3976c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org      ASSERT_TRUE(MarkBlocksAndCheckMerge(x, y, 1, 1)) << "x: " << x
3986c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org                                                       << "y: " << y;
3996c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org    }
4006c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  }
4016c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org}
4026c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
4036c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgTEST_F(DifferTest, MergeBlocks_BlockRow) {
4046c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  InitDiffer(kScreenWidth, kScreenHeight);
4056c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
4066c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4076c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X |   | _ |
4086c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4096c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   |   | _ |
4106c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4116c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   |   | _ |
4126c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4136c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
4146c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4156c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 2, 1));
4166c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
4176c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4186c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   |   | _ |
4196c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4206c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X | X | _ |
4216c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4226c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   |   | _ |
4236c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4246c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
4256c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4266c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 1, 3, 1));
4276c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
4286c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4296c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   |   | _ |
4306c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4316c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   |   | _ |
4326c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4336c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   | X | X | _ |
4346c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4356c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
4366c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4376c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 2, 2, 1));
4386c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org}
4396c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
4406c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgTEST_F(DifferTest, MergeBlocks_BlockColumn) {
4416c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  InitDiffer(kScreenWidth, kScreenHeight);
4426c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
4436c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4446c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X |   |   | _ |
4456c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4466c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X |   |   | _ |
4476c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4486c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   |   | _ |
4496c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4506c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
4516c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4526c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 1, 2));
4536c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
4546c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4556c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   |   | _ |
4566c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4576c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   | X |   | _ |
4586c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4596c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   | X |   | _ |
4606c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4616c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
4626c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4636c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 1, 1, 2));
4646c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
4656c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4666c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   | X | _ |
4676c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4686c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   | X | _ |
4696c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4706c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   | X | _ |
4716c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4726c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
4736c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4746c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(MarkBlocksAndCheckMerge(2, 0, 1, 3));
4756c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org}
4766c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
4776c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgTEST_F(DifferTest, MergeBlocks_BlockRect) {
4786c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  InitDiffer(kScreenWidth, kScreenHeight);
4796c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
4806c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4816c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X |   | _ |
4826c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4836c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X |   | _ |
4846c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4856c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   |   | _ |
4866c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4876c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
4886c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4896c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 2, 2));
4906c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
4916c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4926c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   |   | _ |
4936c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4946c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   | X | X | _ |
4956c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4966c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   | X | X | _ |
4976c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
4986c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
4996c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5006c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 1, 2, 2));
5016c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
5026c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5036c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   | X | X | _ |
5046c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5056c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   | X | X | _ |
5066c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5076c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   | X | X | _ |
5086c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5096c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
5106c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5116c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(MarkBlocksAndCheckMerge(1, 0, 2, 3));
5126c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
5136c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5146c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   |   | _ |
5156c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5166c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X | X | _ |
5176c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5186c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X | X | _ |
5196c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5206c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
5216c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5226c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 1, 3, 2));
5236c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
5246c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5256c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X | X | _ |
5266c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5276c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X | X | _ |
5286c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5296c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X | X | _ |
5306c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5316c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
5326c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5336c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(MarkBlocksAndCheckMerge(0, 0, 3, 3));
5346c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org}
5356c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
5366c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org// This tests marked regions that require more than 1 single dirty rect.
5376c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org// The exact rects returned depend on the current implementation, so these
5386c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org// may need to be updated if we modify how we merge blocks.
5396c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.orgTEST_F(DifferTest, MergeBlocks_MultiRect) {
5406c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  InitDiffer(kScreenWidth, kScreenHeight);
5416c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  DesktopRegion dirty;
5426c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
5436c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+      +---+---+---+
5446c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   | X |   | _ |      |   | 0 |   |
5456c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+      +---+---+---+
5466c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X |   |   | _ |      | 1 |   |   |
5476c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+  =>  +---+---+---+
5486c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   | X | _ |      |   |   | 2 |
5496c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+      +---+---+---+
5506c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
5516c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5526c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ClearDiffInfo();
5536c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkBlocks(1, 0, 1, 1);
5546c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkBlocks(0, 1, 1, 1);
5556c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkBlocks(2, 2, 1, 1);
5566c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
5576c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  dirty.Clear();
5586c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MergeBlocks(&dirty);
5596c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
5606c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_EQ(3, RegionRectCount(dirty));
5616c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 0, 1, 1));
5626c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 1, 1));
5636c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 2, 1, 1));
5646c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
5656c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+      +---+---+---+
5666c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   | X | _ |      |   |   | 0 |
5676c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+      +---+---+---+
5686c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X | X | _ |      | 1   1   1 |
5696c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+  =>  +           +
5706c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X | X | _ |      | 1   1   1 |
5716c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+      +---+---+---+
5726c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
5736c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5746c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ClearDiffInfo();
5756c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkBlocks(2, 0, 1, 1);
5766c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkBlocks(0, 1, 3, 2);
5776c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
5786c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  dirty.Clear();
5796c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MergeBlocks(&dirty);
5806c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
5816c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_EQ(2, RegionRectCount(dirty));
5826c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 0, 1, 1));
5836c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 3, 2));
5846c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
5856c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+      +---+---+---+
5866c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   |   |   | _ |      |   |   |   |
5876c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+      +---+---+---+
5886c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X |   | X | _ |      | 0 |   | 1 |
5896c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+  =>  +---+---+---+
5906c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X | X | _ |      | 2   2   2 |
5916c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+      +---+---+---+
5926c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
5936c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
5946c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ClearDiffInfo();
5956c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkBlocks(0, 1, 1, 1);
5966c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkBlocks(2, 1, 1, 1);
5976c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkBlocks(0, 2, 3, 1);
5986c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
5996c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  dirty.Clear();
6006c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MergeBlocks(&dirty);
6016c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
6026c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_EQ(3, RegionRectCount(dirty));
6036c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 1, 1));
6046c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 1, 1, 1));
6056c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 2, 3, 1));
6066c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
6076c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+      +---+---+---+
6086c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X | X | _ |      | 0   0   0 |
6096c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+      +---+---+---+
6106c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X |   | X | _ |      | 1 |   | 2 |
6116c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+  =>  +---+---+---+
6126c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X | X | _ |      | 3   3   3 |
6136c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+      +---+---+---+
6146c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
6156c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
6166c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ClearDiffInfo();
6176c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkBlocks(0, 0, 3, 1);
6186c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkBlocks(0, 1, 1, 1);
6196c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkBlocks(2, 1, 1, 1);
6206c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkBlocks(0, 2, 3, 1);
6216c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
6226c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  dirty.Clear();
6236c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MergeBlocks(&dirty);
6246c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
6256c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_EQ(4, RegionRectCount(dirty));
6266c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 3, 1));
6276c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 1, 1, 1));
6286c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 1, 1, 1));
6296c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 2, 3, 1));
6306c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
6316c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+      +---+---+---+
6326c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X |   | _ |      | 0   0 |   |
6336c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+      +       +---+
6346c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | X | X |   | _ |      | 0   0 |   |
6356c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+  =>  +---+---+---+
6366c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // |   | X |   | _ |      |   | 1 |   |
6376c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+      +---+---+---+
6386c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // | _ | _ | _ | _ |
6396c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  // +---+---+---+---+
6406c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ClearDiffInfo();
6416c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkBlocks(0, 0, 2, 2);
6426c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MarkBlocks(1, 2, 1, 1);
6436c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
6446c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  dirty.Clear();
6456c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  MergeBlocks(&dirty);
6466c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
6476c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_EQ(2, RegionRectCount(dirty));
6486c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 2, 2));
6496c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org  ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 2, 1, 1));
6506c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org}
6516c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org
6526c82a7ea6ea92e8c68b37112186fd928b11ddc49sergeyu@chromium.org}  // namespace webrtc
653