OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/scoped_ptr.h" |
| 6 #include "remoting/host/differ.h" |
| 7 #include "testing/gmock/include/gmock/gmock.h" |
| 8 |
| 9 namespace remoting { |
| 10 |
| 11 // 96x96 screen gives a 3x3 grid of blocks. |
| 12 const int kScreenWidth = 96; |
| 13 const int kScreenHeight = 96; |
| 14 const int kBytesPerPixel = 3; |
| 15 |
| 16 class DifferTest : public testing::Test { |
| 17 public: |
| 18 DifferTest() { |
| 19 } |
| 20 |
| 21 protected: |
| 22 virtual void SetUp() { |
| 23 InitDiffer(kScreenWidth, kScreenHeight, kBytesPerPixel); |
| 24 } |
| 25 |
| 26 void InitDiffer(int width, int height, int bpp) { |
| 27 width_ = width; |
| 28 height_ = height; |
| 29 bytes_per_pixel_ = bpp; |
| 30 |
| 31 stride_ = width_ * bytes_per_pixel_; |
| 32 buffer_size_ = width_ * height_ * bytes_per_pixel_; |
| 33 |
| 34 differ_.reset(new Differ(width_, height_, bytes_per_pixel_)); |
| 35 |
| 36 prev_.reset(new uint8[buffer_size_]); |
| 37 memset(prev_.get(), 0, buffer_size_); |
| 38 |
| 39 curr_.reset(new uint8[buffer_size_]); |
| 40 memset(curr_.get(), 0, buffer_size_); |
| 41 } |
| 42 |
| 43 void ClearBuffer(uint8* buffer) { |
| 44 memset(buffer, 0, buffer_size_); |
| 45 } |
| 46 |
| 47 // Convenience wrapper for Differ's DiffBlock that calculates the appropriate |
| 48 // offset to the start of the desired block. |
| 49 DiffInfo DiffBlock(int block_x, int block_y) { |
| 50 // Offset from upper-left of buffer to upper-left of requested block. |
| 51 int block_offset = ((block_y * stride_) + (block_x * bytes_per_pixel_)) |
| 52 * kBlockSize; |
| 53 differ_->DiffBlock(prev_.get() + block_offset, |
| 54 curr_.get() + block_offset, |
| 55 stride_); |
| 56 } |
| 57 |
| 58 // Write the pixel |value| into the specified block in the |buffer|. |
| 59 // This is a convenience wrapper around WritePixel(). |
| 60 void WriteBlockPixel(uint8* buffer, int block_x, int block_y, |
| 61 int pixel_x, int pixel_y, uint32 value) { |
| 62 WritePixel(buffer, (block_x * kBlockSize) + pixel_x, |
| 63 (block_y * kBlockSize) + pixel_y, value); |
| 64 } |
| 65 |
| 66 // Write the test pixel |value| into the |buffer| at the specified |x|,|y| |
| 67 // location. |
| 68 // Only the low-order bytes from |value| are written (assuming little-endian). |
| 69 // So, for |value| = 0xaabbccdd: |
| 70 // If bytes_per_pixel = 4, then ddccbbaa will be written as the pixel value. |
| 71 // If = 3, ddccbb |
| 72 // If = 2, ddcc |
| 73 // If = 1, dd |
| 74 void WritePixel(uint8* buffer, int x, int y, uint32 value) { |
| 75 uint8* pixel = reinterpret_cast<uint8*>(&value); |
| 76 buffer += (y * stride_) + (x * bytes_per_pixel_); |
| 77 for (int b = bytes_per_pixel_ - 1; b >= 0; b--) { |
| 78 *buffer++ = pixel[b]; |
| 79 } |
| 80 } |
| 81 |
| 82 // DiffInfo utility routines. |
| 83 // These are here so that we don't have to make each DifferText_Xxx_Test |
| 84 // class a friend class to Differ. |
| 85 |
| 86 // Clear out the entire |diff_info_| buffer. |
| 87 void ClearDiffInfo() { |
| 88 memset(differ_->diff_info_.get(), 0, differ_->diff_info_size_); |
| 89 } |
| 90 |
| 91 // Get the value in the |diff_info_| array at (x,y). |
| 92 DiffInfo GetDiffInfo(int x, int y) { |
| 93 DiffInfo* diff_info = differ_->diff_info_.get(); |
| 94 return diff_info[(y * GetDiffInfoWidth()) + x]; |
| 95 } |
| 96 |
| 97 // Width of |diff_info_| array. |
| 98 int GetDiffInfoWidth() { |
| 99 return differ_->diff_info_width_; |
| 100 } |
| 101 |
| 102 // Height of |diff_info_| array. |
| 103 int GetDiffInfoHeight() { |
| 104 return differ_->diff_info_height_; |
| 105 } |
| 106 |
| 107 // Size of |diff_info_| array. |
| 108 int GetDiffInfoSize() { |
| 109 return differ_->diff_info_size_; |
| 110 } |
| 111 |
| 112 void SetDiffInfo(int x, int y, const DiffInfo& value) { |
| 113 DiffInfo* diff_info = differ_->diff_info_.get(); |
| 114 diff_info[(y * GetDiffInfoWidth()) + x] = value; |
| 115 } |
| 116 |
| 117 // Mark the range of blocks specified. |
| 118 void MarkBlocks(int x_origin, int y_origin, int width, int height) { |
| 119 for (int y = 0; y < height; y++) { |
| 120 for (int x = 0; x < width; x++) { |
| 121 SetDiffInfo(x_origin + x, y_origin + y, 1); |
| 122 } |
| 123 } |
| 124 } |
| 125 |
| 126 // Verify that the given dirty rect matches the expected |x|, |y|, |width| |
| 127 // and |height|. |
| 128 // |x|, |y|, |width| and |height| are specified in block (not pixel) units. |
| 129 void CheckDirtyRect(const gfx::Rect& rect, int x, int y, |
| 130 int width, int height) { |
| 131 EXPECT_EQ(x * kBlockSize, rect.x()); |
| 132 EXPECT_EQ(y * kBlockSize, rect.y()); |
| 133 EXPECT_EQ(width * kBlockSize, rect.width()); |
| 134 EXPECT_EQ(height * kBlockSize, rect.height()); |
| 135 } |
| 136 |
| 137 // Mark the range of blocks specified and then verify that they are |
| 138 // merged correctly. |
| 139 // Only one rectangular region of blocks can be checked with this routine. |
| 140 void MarkBlocksAndCheckMerge(int x_origin, int y_origin, |
| 141 int width, int height) { |
| 142 ClearDiffInfo(); |
| 143 MarkBlocks(x_origin, y_origin, width, height); |
| 144 |
| 145 DirtyRects* dirty = new DirtyRects(); |
| 146 differ_->MergeBlocks(dirty); |
| 147 |
| 148 ASSERT_EQ(1, dirty->size()); |
| 149 CheckDirtyRect(dirty->at(0), x_origin, y_origin, width, height); |
| 150 } |
| 151 |
| 152 // The differ class we're testing. |
| 153 scoped_ptr<Differ> differ_; |
| 154 |
| 155 // Screen/buffer info. |
| 156 int width_; |
| 157 int height_; |
| 158 int bytes_per_pixel_; |
| 159 int stride_; |
| 160 |
| 161 // Size of each screen buffer. |
| 162 int buffer_size_; |
| 163 |
| 164 // Previous and current screen buffers. |
| 165 scoped_ptr<uint8> prev_; |
| 166 scoped_ptr<uint8> curr_; |
| 167 |
| 168 private: |
| 169 DISALLOW_COPY_AND_ASSIGN(DifferTest); |
| 170 }; |
| 171 |
| 172 TEST_F(DifferTest, Setup) { |
| 173 // 96x96 pixels results in 3x3 array. Add 1 to each dimension as boundary. |
| 174 // +---+---+---+---+ |
| 175 // | o | o | o | _ | |
| 176 // +---+---+---+---+ o = blocks mapped to screen pixels |
| 177 // | o | o | o | _ | |
| 178 // +---+---+---+---+ _ = boundary blocks |
| 179 // | o | o | o | _ | |
| 180 // +---+---+---+---+ |
| 181 // | _ | _ | _ | _ | |
| 182 // +---+---+---+---+ |
| 183 EXPECT_EQ(4, GetDiffInfoWidth()); |
| 184 EXPECT_EQ(4, GetDiffInfoHeight()); |
| 185 EXPECT_EQ(16, GetDiffInfoSize()); |
| 186 } |
| 187 |
| 188 TEST_F(DifferTest, MarkDirtyBlocks_All) { |
| 189 ClearDiffInfo(); |
| 190 |
| 191 // Update a pixel in each block. |
| 192 for (int y = 0; y < GetDiffInfoHeight() - 1; y++) { |
| 193 for (int x = 0; x < GetDiffInfoWidth() - 1; x++) { |
| 194 WriteBlockPixel(curr_.get(), x, y, 10, 10, 0xff00ff); |
| 195 } |
| 196 } |
| 197 |
| 198 differ_->MarkDirtyBlocks(prev_.get(), curr_.get()); |
| 199 |
| 200 // Make sure each block is marked as dirty. |
| 201 for (int y = 0; y < GetDiffInfoHeight() - 1; y++) { |
| 202 for (int x = 0; x < GetDiffInfoWidth() - 1; x++) { |
| 203 EXPECT_EQ(1, GetDiffInfo(x, y)) |
| 204 << "when x = " << x << ", and y = " << y; |
| 205 } |
| 206 } |
| 207 } |
| 208 |
| 209 TEST_F(DifferTest, MarkDirtyBlocks_Sampling) { |
| 210 ClearDiffInfo(); |
| 211 |
| 212 // Update some pixels in image. |
| 213 WriteBlockPixel(curr_.get(), 1, 0, 10, 10, 0xff00ff); |
| 214 WriteBlockPixel(curr_.get(), 2, 1, 10, 10, 0xff00ff); |
| 215 WriteBlockPixel(curr_.get(), 0, 2, 10, 10, 0xff00ff); |
| 216 |
| 217 differ_->MarkDirtyBlocks(prev_.get(), curr_.get()); |
| 218 |
| 219 // Make sure corresponding blocks are updated. |
| 220 EXPECT_EQ(0, GetDiffInfo(0, 0)); |
| 221 EXPECT_EQ(0, GetDiffInfo(0, 1)); |
| 222 EXPECT_EQ(1, GetDiffInfo(0, 2)); |
| 223 EXPECT_EQ(1, GetDiffInfo(1, 0)); |
| 224 EXPECT_EQ(0, GetDiffInfo(1, 1)); |
| 225 EXPECT_EQ(0, GetDiffInfo(1, 2)); |
| 226 EXPECT_EQ(0, GetDiffInfo(2, 0)); |
| 227 EXPECT_EQ(1, GetDiffInfo(2, 1)); |
| 228 EXPECT_EQ(0, GetDiffInfo(2, 2)); |
| 229 } |
| 230 |
| 231 TEST_F(DifferTest, DiffBlock) { |
| 232 // Verify no differences at start. |
| 233 EXPECT_EQ(0, DiffBlock(0, 0)); |
| 234 EXPECT_EQ(0, DiffBlock(1, 1)); |
| 235 |
| 236 // Write new data into the 4 corners of the middle block and verify that |
| 237 // neighboring blocks are not affected. |
| 238 int max = kBlockSize - 1; |
| 239 WriteBlockPixel(curr_.get(), 1, 1, 0, 0, 0xffffff); |
| 240 WriteBlockPixel(curr_.get(), 1, 1, 0, max, 0xffffff); |
| 241 WriteBlockPixel(curr_.get(), 1, 1, max, 0, 0xffffff); |
| 242 WriteBlockPixel(curr_.get(), 1, 1, max, max, 0xffffff); |
| 243 EXPECT_EQ(0, DiffBlock(0, 0)); |
| 244 EXPECT_EQ(0, DiffBlock(0, 1)); |
| 245 EXPECT_EQ(0, DiffBlock(0, 2)); |
| 246 EXPECT_EQ(0, DiffBlock(1, 0)); |
| 247 EXPECT_EQ(1, DiffBlock(1, 1)); // Only this block should change. |
| 248 EXPECT_EQ(0, DiffBlock(1, 2)); |
| 249 EXPECT_EQ(0, DiffBlock(2, 0)); |
| 250 EXPECT_EQ(0, DiffBlock(2, 1)); |
| 251 EXPECT_EQ(0, DiffBlock(2, 2)); |
| 252 } |
| 253 |
| 254 TEST_F(DifferTest, DiffPartialBlocks) { |
| 255 // TODO(garykac): Add tests for DiffPartialBlock |
| 256 } |
| 257 |
| 258 |
| 259 TEST_F(DifferTest, MergeBlocks_Empty) { |
| 260 // No blocks marked: |
| 261 // +---+---+---+---+ |
| 262 // | | | | _ | |
| 263 // +---+---+---+---+ |
| 264 // | | | | _ | |
| 265 // +---+---+---+---+ |
| 266 // | | | | _ | |
| 267 // +---+---+---+---+ |
| 268 // | _ | _ | _ | _ | |
| 269 // +---+---+---+---+ |
| 270 ClearDiffInfo(); |
| 271 |
| 272 DirtyRects* dirty = new DirtyRects(); |
| 273 differ_->MergeBlocks(dirty); |
| 274 |
| 275 EXPECT_EQ(0, dirty->size()); |
| 276 } |
| 277 |
| 278 TEST_F(DifferTest, MergeBlocks_SingleBlock) { |
| 279 // Mark a single block and make sure that there is a single merged |
| 280 // rect with the correct bounds. |
| 281 for (int y = 0; y < GetDiffInfoHeight() - 1; y++) { |
| 282 for (int x = 0; x < GetDiffInfoWidth() - 1; x++) { |
| 283 MarkBlocksAndCheckMerge(x, y, 1, 1); |
| 284 } |
| 285 } |
| 286 } |
| 287 |
| 288 TEST_F(DifferTest, MergeBlocks_BlockRow) { |
| 289 // +---+---+---+---+ |
| 290 // | X | X | | _ | |
| 291 // +---+---+---+---+ |
| 292 // | | | | _ | |
| 293 // +---+---+---+---+ |
| 294 // | | | | _ | |
| 295 // +---+---+---+---+ |
| 296 // | _ | _ | _ | _ | |
| 297 // +---+---+---+---+ |
| 298 MarkBlocksAndCheckMerge(0, 0, 2, 1); |
| 299 |
| 300 // +---+---+---+---+ |
| 301 // | | | | _ | |
| 302 // +---+---+---+---+ |
| 303 // | X | X | X | _ | |
| 304 // +---+---+---+---+ |
| 305 // | | | | _ | |
| 306 // +---+---+---+---+ |
| 307 // | _ | _ | _ | _ | |
| 308 // +---+---+---+---+ |
| 309 MarkBlocksAndCheckMerge(0, 1, 3, 1); |
| 310 |
| 311 // +---+---+---+---+ |
| 312 // | | | | _ | |
| 313 // +---+---+---+---+ |
| 314 // | | | | _ | |
| 315 // +---+---+---+---+ |
| 316 // | | X | X | _ | |
| 317 // +---+---+---+---+ |
| 318 // | _ | _ | _ | _ | |
| 319 // +---+---+---+---+ |
| 320 MarkBlocksAndCheckMerge(1, 2, 2, 1); |
| 321 } |
| 322 |
| 323 TEST_F(DifferTest, MergeBlocks_BlockColumn) { |
| 324 // +---+---+---+---+ |
| 325 // | X | | | _ | |
| 326 // +---+---+---+---+ |
| 327 // | X | | | _ | |
| 328 // +---+---+---+---+ |
| 329 // | | | | _ | |
| 330 // +---+---+---+---+ |
| 331 // | _ | _ | _ | _ | |
| 332 // +---+---+---+---+ |
| 333 MarkBlocksAndCheckMerge(0, 0, 1, 2); |
| 334 |
| 335 // +---+---+---+---+ |
| 336 // | | | | _ | |
| 337 // +---+---+---+---+ |
| 338 // | | X | | _ | |
| 339 // +---+---+---+---+ |
| 340 // | | X | | _ | |
| 341 // +---+---+---+---+ |
| 342 // | _ | _ | _ | _ | |
| 343 // +---+---+---+---+ |
| 344 MarkBlocksAndCheckMerge(1, 1, 1, 2); |
| 345 |
| 346 // +---+---+---+---+ |
| 347 // | | | X | _ | |
| 348 // +---+---+---+---+ |
| 349 // | | | X | _ | |
| 350 // +---+---+---+---+ |
| 351 // | | | X | _ | |
| 352 // +---+---+---+---+ |
| 353 // | _ | _ | _ | _ | |
| 354 // +---+---+---+---+ |
| 355 MarkBlocksAndCheckMerge(2, 0, 1, 3); |
| 356 } |
| 357 |
| 358 TEST_F(DifferTest, MergeBlocks_BlockRect) { |
| 359 // +---+---+---+---+ |
| 360 // | X | X | | _ | |
| 361 // +---+---+---+---+ |
| 362 // | X | X | | _ | |
| 363 // +---+---+---+---+ |
| 364 // | | | | _ | |
| 365 // +---+---+---+---+ |
| 366 // | _ | _ | _ | _ | |
| 367 // +---+---+---+---+ |
| 368 MarkBlocksAndCheckMerge(0, 0, 2, 2); |
| 369 |
| 370 // +---+---+---+---+ |
| 371 // | | | | _ | |
| 372 // +---+---+---+---+ |
| 373 // | | X | X | _ | |
| 374 // +---+---+---+---+ |
| 375 // | | X | X | _ | |
| 376 // +---+---+---+---+ |
| 377 // | _ | _ | _ | _ | |
| 378 // +---+---+---+---+ |
| 379 MarkBlocksAndCheckMerge(1, 1, 2, 2); |
| 380 |
| 381 // +---+---+---+---+ |
| 382 // | | X | X | _ | |
| 383 // +---+---+---+---+ |
| 384 // | | X | X | _ | |
| 385 // +---+---+---+---+ |
| 386 // | | X | X | _ | |
| 387 // +---+---+---+---+ |
| 388 // | _ | _ | _ | _ | |
| 389 // +---+---+---+---+ |
| 390 MarkBlocksAndCheckMerge(1, 0, 2, 3); |
| 391 |
| 392 // +---+---+---+---+ |
| 393 // | | | | _ | |
| 394 // +---+---+---+---+ |
| 395 // | X | X | X | _ | |
| 396 // +---+---+---+---+ |
| 397 // | X | X | X | _ | |
| 398 // +---+---+---+---+ |
| 399 // | _ | _ | _ | _ | |
| 400 // +---+---+---+---+ |
| 401 MarkBlocksAndCheckMerge(0, 1, 3, 2); |
| 402 |
| 403 // +---+---+---+---+ |
| 404 // | X | X | X | _ | |
| 405 // +---+---+---+---+ |
| 406 // | X | X | X | _ | |
| 407 // +---+---+---+---+ |
| 408 // | X | X | X | _ | |
| 409 // +---+---+---+---+ |
| 410 // | _ | _ | _ | _ | |
| 411 // +---+---+---+---+ |
| 412 MarkBlocksAndCheckMerge(0, 0, 3, 3); |
| 413 } |
| 414 |
| 415 // This tests marked regions that require more than 1 single dirty rect. |
| 416 // The exact rects returned depend on the current implementation, so these |
| 417 // may need to be updated if we modify how we merge blocks. |
| 418 TEST_F(DifferTest, MergeBlocks_MultiRect) { |
| 419 DirtyRects* dirty; |
| 420 |
| 421 // +---+---+---+---+ +---+---+---+ |
| 422 // | | X | | _ | | | 0 | | |
| 423 // +---+---+---+---+ +---+---+---+ |
| 424 // | X | | | _ | | 1 | | | |
| 425 // +---+---+---+---+ => +---+---+---+ |
| 426 // | | | X | _ | | | | 2 | |
| 427 // +---+---+---+---+ +---+---+---+ |
| 428 // | _ | _ | _ | _ | |
| 429 // +---+---+---+---+ |
| 430 ClearDiffInfo(); |
| 431 MarkBlocks(1, 0, 1, 1); |
| 432 MarkBlocks(0, 1, 1, 1); |
| 433 MarkBlocks(2, 2, 1, 1); |
| 434 |
| 435 dirty = new DirtyRects(); |
| 436 differ_->MergeBlocks(dirty); |
| 437 |
| 438 ASSERT_EQ(3, dirty->size()); |
| 439 CheckDirtyRect(dirty->at(0), 1, 0, 1, 1); |
| 440 CheckDirtyRect(dirty->at(1), 0, 1, 1, 1); |
| 441 CheckDirtyRect(dirty->at(2), 2, 2, 1, 1); |
| 442 |
| 443 // +---+---+---+---+ +---+---+---+ |
| 444 // | | | X | _ | | | | 0 | |
| 445 // +---+---+---+---+ +---+---+ + |
| 446 // | X | X | X | _ | | 1 1 | 0 | |
| 447 // +---+---+---+---+ => + + + |
| 448 // | X | X | X | _ | | 1 1 | 0 | |
| 449 // +---+---+---+---+ +---+---+---+ |
| 450 // | _ | _ | _ | _ | |
| 451 // +---+---+---+---+ |
| 452 ClearDiffInfo(); |
| 453 MarkBlocks(2, 0, 1, 3); |
| 454 MarkBlocks(0, 1, 2, 2); |
| 455 |
| 456 dirty = new DirtyRects(); |
| 457 differ_->MergeBlocks(dirty); |
| 458 |
| 459 ASSERT_EQ(2, dirty->size()); |
| 460 CheckDirtyRect(dirty->at(0), 2, 0, 1, 3); |
| 461 CheckDirtyRect(dirty->at(1), 0, 1, 2, 2); |
| 462 |
| 463 // +---+---+---+---+ +---+---+---+ |
| 464 // | | | | _ | | | | | |
| 465 // +---+---+---+---+ +---+---+---+ |
| 466 // | X | | X | _ | | 0 | | 1 | |
| 467 // +---+---+---+---+ => + +---+ + |
| 468 // | X | X | X | _ | | 0 | 2 | 1 | |
| 469 // +---+---+---+---+ +---+---+---+ |
| 470 // | _ | _ | _ | _ | |
| 471 // +---+---+---+---+ |
| 472 ClearDiffInfo(); |
| 473 MarkBlocks(0, 1, 1, 1); |
| 474 MarkBlocks(2, 1, 1, 1); |
| 475 MarkBlocks(0, 2, 3, 1); |
| 476 |
| 477 dirty = new DirtyRects(); |
| 478 differ_->MergeBlocks(dirty); |
| 479 |
| 480 ASSERT_EQ(3, dirty->size()); |
| 481 CheckDirtyRect(dirty->at(0), 0, 1, 1, 2); |
| 482 CheckDirtyRect(dirty->at(1), 2, 1, 1, 2); |
| 483 CheckDirtyRect(dirty->at(2), 1, 2, 1, 1); |
| 484 |
| 485 // +---+---+---+---+ +---+---+---+ |
| 486 // | X | X | X | _ | | 0 0 0 | |
| 487 // +---+---+---+---+ +---+---+---+ |
| 488 // | X | | X | _ | | 1 | | 2 | |
| 489 // +---+---+---+---+ => + +---+ + |
| 490 // | X | X | X | _ | | 1 | 3 | 2 | |
| 491 // +---+---+---+---+ +---+---+---+ |
| 492 // | _ | _ | _ | _ | |
| 493 // +---+---+---+---+ |
| 494 ClearDiffInfo(); |
| 495 MarkBlocks(0, 0, 3, 1); |
| 496 MarkBlocks(0, 1, 1, 1); |
| 497 MarkBlocks(2, 1, 1, 1); |
| 498 MarkBlocks(0, 2, 3, 1); |
| 499 |
| 500 dirty = new DirtyRects(); |
| 501 differ_->MergeBlocks(dirty); |
| 502 |
| 503 ASSERT_EQ(4, dirty->size()); |
| 504 CheckDirtyRect(dirty->at(0), 0, 0, 3, 1); |
| 505 CheckDirtyRect(dirty->at(1), 0, 1, 1, 2); |
| 506 CheckDirtyRect(dirty->at(2), 2, 1, 1, 2); |
| 507 CheckDirtyRect(dirty->at(3), 1, 2, 1, 1); |
| 508 |
| 509 // +---+---+---+---+ +---+---+---+ |
| 510 // | X | X | | _ | | 0 0 | | |
| 511 // +---+---+---+---+ + +---+ |
| 512 // | X | X | | _ | | 0 0 | | |
| 513 // +---+---+---+---+ => +---+---+---+ |
| 514 // | | X | | _ | | | 1 | | |
| 515 // +---+---+---+---+ +---+---+---+ |
| 516 // | _ | _ | _ | _ | |
| 517 // +---+---+---+---+ |
| 518 ClearDiffInfo(); |
| 519 MarkBlocks(0, 0, 2, 2); |
| 520 MarkBlocks(1, 2, 1, 1); |
| 521 |
| 522 dirty = new DirtyRects(); |
| 523 differ_->MergeBlocks(dirty); |
| 524 |
| 525 ASSERT_EQ(2, dirty->size()); |
| 526 CheckDirtyRect(dirty->at(0), 0, 0, 2, 2); |
| 527 CheckDirtyRect(dirty->at(1), 1, 2, 1, 1); |
| 528 } |
| 529 |
| 530 } // namespace remoting |
OLD | NEW |