Index: webrtc/modules/desktop_capture/differ_unittest.cc |
diff --git a/webrtc/modules/desktop_capture/differ_unittest.cc b/webrtc/modules/desktop_capture/differ_unittest.cc |
index 543910de289c7d4a378a03c0b2f669a558e96ea4..d331d0bf88a682b3be6f7b34b0d6d2a2291c65c6 100644 |
--- a/webrtc/modules/desktop_capture/differ_unittest.cc |
+++ b/webrtc/modules/desktop_capture/differ_unittest.cc |
@@ -12,6 +12,8 @@ |
#include "testing/gmock/include/gmock/gmock.h" |
#include "webrtc/base/constructormagic.h" |
+#include "webrtc/modules/desktop_capture/desktop_region.h" |
+#include "webrtc/modules/desktop_capture/desktop_geometry.h" |
#include "webrtc/modules/desktop_capture/differ.h" |
#include "webrtc/modules/desktop_capture/differ_block.h" |
@@ -54,7 +56,8 @@ class DifferTest : public testing::Test { |
// 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); |
+ differ_->MarkDirtyBlocks(prev_buffer, curr_buffer, |
+ DesktopRect::MakeWH(width_, height_)); |
} |
void MergeBlocks(DesktopRegion* dirty) { |
@@ -158,7 +161,7 @@ class DifferTest : public testing::Test { |
int width, int height) { |
DesktopRect r = |
DesktopRect::MakeXYWH(x * kBlockSize, y * kBlockSize, |
- width * kBlockSize, height * kBlockSize); |
+ width * kBlockSize, height * kBlockSize); |
for (DesktopRegion::Iterator i(region); !i.IsAtEnd(); i.Advance()) { |
if (i.rect().equals(r)) |
return true; |
@@ -166,6 +169,19 @@ class DifferTest : public testing::Test { |
return false; |
} |
+ bool CheckDirtyRegionContainsPartialRect(const DesktopRegion& region, |
Jamie
2016/08/03 23:52:26
"Partial" is used in the differ to refer to sub-kB
Hzj_jie
2016/08/04 02:28:07
The "partial" here means one of the dirty regions
|
+ 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 (r.ContainsRect(i.rect())) |
+ 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. |
@@ -651,4 +667,217 @@ TEST_F(DifferTest, MergeBlocks_MultiRect) { |
ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 2, 1, 1)); |
} |
+TEST_F(DifferTest, ScreenSizeWithEmptyHints) { |
+ InitDiffer(kScreenWidth, kScreenHeight); |
+ DesktopRegion dirty; |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), DesktopRegion(), |
+ &dirty); |
+ ASSERT_EQ(0, RegionRectCount(dirty)); |
+} |
+ |
+TEST_F(DifferTest, OneDirtyBlockWithHints) { |
+ // Initialize a 3 x 3 screen. |
+ // +---+---+---+ |
+ // | | | | |
+ // +---+---+---+ |
+ // | | X | | |
+ // +---+---+---+ |
+ // | | | | |
+ // +---+---+---+ |
+ InitDiffer(kScreenWidth, kScreenHeight); |
+ WritePixel(curr_.get(), kBlockSize, kBlockSize, 0x11223344); |
+ DesktopRegion dirty; |
+ dirty.AddRect( |
+ DesktopRect::MakeXYWH(kBlockSize, kBlockSize, kBlockSize, kBlockSize)); |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(1, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 1, 1, 1)); |
+ |
+ dirty.Clear(); |
+ dirty.AddRect(DesktopRect::MakeXYWH(kBlockSize >> 1, kBlockSize >> 1, |
+ kBlockSize, kBlockSize)); |
+ dirty.AddRect(DesktopRect::MakeXYWH(kBlockSize * 1.5, kBlockSize * 1.5, |
+ kBlockSize >> 1, kBlockSize >> 1)); |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(1, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 1, 1, 1)); |
+} |
+ |
+TEST_F(DifferTest, MultipleDirtyBlocksWithHints) { |
+ // Initialize a 3 x 3 screen. |
+ // +---+---+---+ |
+ // | | | | |
+ // +---+---+---+ |
+ // | | X | | |
+ // +---+---+---+ |
+ // | | | X | |
+ // +---+---+---+ |
+ InitDiffer(kScreenWidth, kScreenHeight); |
+ WritePixel(curr_.get(), kBlockSize, kBlockSize, 0x11223344); |
+ WritePixel(curr_.get(), kBlockSize * 2, kBlockSize * 2, 0x11223344); |
+ DesktopRegion dirty; |
+ dirty.AddRect(DesktopRect::MakeXYWH(kBlockSize, kBlockSize, |
+ kBlockSize * 2, kBlockSize * 2)); |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(2, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 1, 1, 1)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 2, 1, 1)); |
+ |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(2, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 1, 1, 1)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 2, 1, 1)); |
+ |
+ dirty.Clear(); |
+ dirty.AddRect(DesktopRect::MakeXYWH(0, 0, kBlockSize * 2, kBlockSize * 2)); |
+ dirty.AddRect( |
+ DesktopRect::MakeXYWH(0, kBlockSize * 2, kBlockSize * 3, kBlockSize)); |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(2, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 1, 1, 1)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 2, 1, 1)); |
+ |
+ dirty.Clear(); |
+ dirty.AddRect(DesktopRect::MakeXYWH(0, 0, kBlockSize, kBlockSize)); |
+ dirty.AddRect( |
+ DesktopRect::MakeXYWH(0, kBlockSize, kBlockSize * 2, kBlockSize)); |
+ dirty.AddRect( |
+ DesktopRect::MakeXYWH(0, kBlockSize * 2, kBlockSize * 3, kBlockSize)); |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(2, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 1, 1, 1)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 2, 1, 1)); |
+ |
+ dirty.Clear(); |
+ dirty.AddRect(DesktopRect::MakeXYWH(kBlockSize >> 1, kBlockSize >> 1, |
+ kBlockSize, kBlockSize)); |
+ dirty.AddRect(DesktopRect::MakeXYWH(kBlockSize * 1.5, kBlockSize, |
+ kBlockSize * 1.5, kBlockSize * 2)); |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(2, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 1, 1, 1, 1)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 2, 2, 1, 1)); |
+} |
+ |
+TEST_F(DifferTest, MultipleDirtyBlocksWithHints2) { |
+ // Initialize a 4 x 4 screen. |
+ // +---+---+---+---+ |
+ // | X | | | | |
+ // +---+---+---+---+ |
+ // | | | | | |
+ // +---+---+---+---+ |
+ // | | | | | |
+ // +---+---+---+---+ |
+ // | | | | X | |
+ // +---+---+---+---+ |
+ InitDiffer(4 * kBlockSize, 4 * kBlockSize); |
+ WritePixel(curr_.get(), 0, 0, 0x11223344); |
+ WritePixel(curr_.get(), kBlockSize * 3, kBlockSize * 3, 0x11223344); |
+ DesktopRegion dirty; |
+ dirty.AddRect( |
+ DesktopRect::MakeXYWH(0, 0, kBlockSize * 4, kBlockSize * 4)); |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(2, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 1, 1)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 3, 3, 1, 1)); |
+ |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(2, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 1, 1)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 3, 3, 1, 1)); |
+ |
+ dirty.Clear(); |
+ dirty.AddRect(DesktopRect::MakeXYWH(0, 0, kBlockSize, kBlockSize)); |
+ dirty.AddRect( |
+ DesktopRect::MakeXYWH(kBlockSize, kBlockSize, kBlockSize, kBlockSize)); |
+ dirty.AddRect(DesktopRect::MakeXYWH(kBlockSize * 3, kBlockSize * 3, |
+ kBlockSize, kBlockSize)); |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(2, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 1, 1)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 3, 3, 1, 1)); |
+ |
+ dirty.Clear(); |
+ dirty.AddRect(DesktopRect::MakeXYWH(0, 0, kBlockSize * 2, kBlockSize * 2)); |
+ dirty.AddRect(DesktopRect::MakeXYWH(kBlockSize * 2, kBlockSize * 2, |
+ kBlockSize * 2, kBlockSize * 2)); |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(2, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 1, 1)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 3, 3, 1, 1)); |
+ |
+ dirty.Clear(); |
+ // Note, even the hints does not cover entire block, we should still be able |
+ // to detect it. |
+ dirty.AddRect(DesktopRect::MakeXYWH(0, 0, kBlockSize >> 1, kBlockSize >> 1)); |
+ dirty.AddRect(DesktopRect::MakeXYWH(kBlockSize * 2.5, kBlockSize * 2.5, |
+ kBlockSize, kBlockSize)); |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(2, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 1, 1)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 3, 3, 1, 1)); |
+} |
+ |
+TEST_F(DifferTest, PartialScreenSizeWithHints) { |
+ // Initialize a 4 x 4 screen, the right and bottom blocks do not have a |
+ // kBlockSize size. |
+ // +---+---+---+---+ |
+ // | X | | | | |
+ // +---+---+---+---+ |
+ // | | | | | |
+ // +---+---+---+---+ |
+ // | | | | | |
+ // +---+---+---+---+ |
+ // | | | | X | |
+ // +---+---+---+---+ |
+ InitDiffer(4 * kBlockSize - (kBlockSize >> 1), |
+ 4 * kBlockSize - (kBlockSize >> 1)); |
+ WritePixel(curr_.get(), 0, 0, 0x11223344); |
+ WritePixel(curr_.get(), kBlockSize * 3, kBlockSize * 3, 0x11223344); |
+ DesktopRegion dirty; |
+ dirty.AddRect(DesktopRect::MakeXYWH(0, 0, |
+ 4 * kBlockSize - (kBlockSize >> 1), |
+ 4 * kBlockSize - (kBlockSize >> 1))); |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(2, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 1, 1)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsPartialRect(dirty, 3, 3, 1, 1)); |
+ |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(2, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 1, 1)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsPartialRect(dirty, 3, 3, 1, 1)); |
+ |
+ dirty.Clear(); |
+ dirty.AddRect(DesktopRect::MakeXYWH(0, 0, kBlockSize, kBlockSize)); |
+ dirty.AddRect( |
+ DesktopRect::MakeXYWH(kBlockSize, kBlockSize, kBlockSize, kBlockSize)); |
+ dirty.AddRect(DesktopRect::MakeXYWH(kBlockSize * 3, kBlockSize * 3, |
+ kBlockSize, kBlockSize)); |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(2, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 1, 1)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsPartialRect(dirty, 3, 3, 1, 1)); |
+ |
+ dirty.Clear(); |
+ dirty.AddRect(DesktopRect::MakeXYWH(0, 0, kBlockSize * 2, kBlockSize * 2)); |
+ dirty.AddRect(DesktopRect::MakeXYWH(kBlockSize * 2, kBlockSize * 2, |
+ kBlockSize * 1.5, kBlockSize * 1.5)); |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(2, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 1, 1)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsPartialRect(dirty, 3, 3, 1, 1)); |
+ |
+ dirty.Clear(); |
+ // Note, even the hints does not cover entire block, we should still be able |
+ // to detect it. |
+ dirty.AddRect(DesktopRect::MakeXYWH(0, 0, kBlockSize >> 1, kBlockSize >> 1)); |
+ dirty.AddRect(DesktopRect::MakeXYWH(kBlockSize * 2.5, kBlockSize * 2.5, |
+ kBlockSize, kBlockSize)); |
+ differ_->CalcDirtyRegionWithHints(prev_.get(), curr_.get(), dirty, &dirty); |
+ ASSERT_EQ(2, RegionRectCount(dirty)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsRect(dirty, 0, 0, 1, 1)); |
+ ASSERT_TRUE(CheckDirtyRegionContainsPartialRect(dirty, 3, 3, 1, 1)); |
+} |
+ |
} // namespace webrtc |