Changeset 116538 in webkit
- Timestamp:
- May 9, 2012 10:01:16 AM (12 years ago)
- Location:
- trunk/Source
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r116530 r116538 1 2012-05-09 Dana Jansens <danakj@chromium.org> 2 3 Early-out and avoid any copying when possible for Region operations 4 https://bugs.webkit.org/show_bug.cgi?id=85260 5 6 Reviewed by Anders Carlsson. 7 8 For an empty region, any intersection or subtraction will not modify 9 the region, so we can simply return instead of creating a new Shape 10 and replacing the current empty Shape. 11 12 When a region is united with a region it contains, the orignal 13 containing region is the result. So, if A.unite(B) and A.contains(B) 14 then A does not need to change at all and we can return without making 15 a copy of A's shape. When A is a rect, we can do this test even more 16 simply. 17 18 We also remove redundant checks from trySimpleOperation() methods, where 19 the test is already done in the Region calling site. 20 21 This change improves the performance of the Region overlap testing for 22 composited layers, and allows us to avoid unnecessary copies of the 23 Region during unite. With a layout test (attached to bug #81087), that 24 creates a Region from the union of 225 composited layers, as well as 25 600 overlapping layers above them, this change decreases the running 26 time of the test by 3.2% by avoiding a copy of the entire Region for 27 each insertion that does not change the resulting Region. 28 29 Unit tests: RegionTest.unite 30 31 * platform/graphics/Region.cpp: 32 (WebCore::Region::Shape::UnionOperation::trySimpleOperation): 33 (WebCore::Region::Shape::IntersectOperation::trySimpleOperation): 34 (WebCore::Region::Shape::SubtractOperation::trySimpleOperation): 35 (WebCore::Region::intersect): 36 (WebCore::Region::unite): 37 (WebCore::Region::subtract): 38 * platform/graphics/Region.h: 39 (WebCore::Region::isRect): 40 (WebCore::Region::Shape::isRect): 41 1 42 2012-05-09 Tommy Widenflycht <tommyw@google.com> 2 43 -
trunk/Source/WebCore/platform/graphics/Region.cpp
r116463 r116538 488 488 } 489 489 490 if (shape2.isEmpty()) {491 result = shape1;492 return true;493 }494 495 490 return false; 496 491 } … … 510 505 511 506 struct Region::Shape::IntersectOperation { 512 static bool trySimpleOperation(const Shape& shape1, const Shape& shape2, Shape& result)507 static bool trySimpleOperation(const Shape&, const Shape&, Shape&) 513 508 { 514 if (shape1.isEmpty()) {515 result = Shape();516 return true;517 }518 519 if (shape2.isEmpty()) {520 result = shape1;521 return true;522 }523 524 509 return false; 525 510 } … … 539 524 540 525 struct Region::Shape::SubtractOperation { 541 static bool trySimpleOperation(const Shape& shape1, const Shape& shape2, Region::Shape& result)526 static bool trySimpleOperation(const Shape&, const Shape&, Region::Shape&) 542 527 { 543 544 if (shape1.isEmpty() || shape2.isEmpty()) {545 result = Shape();546 return true;547 }548 549 528 return false; 550 529 } … … 574 553 void Region::intersect(const Region& region) 575 554 { 555 if (m_bounds.isEmpty()) 556 return; 576 557 if (!m_bounds.intersects(region.m_bounds)) { 577 558 m_shape = Shape(); … … 590 571 if (region.isEmpty()) 591 572 return; 573 if (isRect() && m_bounds.contains(region.m_bounds)) 574 return; 575 if (region.isRect() && region.m_bounds.contains(m_bounds)) { 576 m_shape = region.m_shape; 577 m_bounds = region.m_bounds; 578 return; 579 } 580 // FIXME: We may want another way to construct a Region without doing this test when we expect it to be false. 581 if (!isRect() && contains(region)) 582 return; 592 583 593 584 Shape unitedShape = Shape::unionShapes(m_shape, region.m_shape); … … 599 590 void Region::subtract(const Region& region) 600 591 { 592 if (m_bounds.isEmpty()) 593 return; 601 594 if (region.isEmpty()) 602 595 return; -
trunk/Source/WebCore/platform/graphics/Region.h
r116377 r116538 39 39 IntRect bounds() const { return m_bounds; } 40 40 bool isEmpty() const { return m_bounds.isEmpty(); } 41 bool isRect() const { return m_shape.isRect(); } 41 42 42 43 Vector<IntRect> rects() const; … … 80 81 IntRect bounds() const; 81 82 bool isEmpty() const { return m_spans.isEmpty(); } 83 bool isRect() const { return m_spans.size() <= 2 && m_segments.size() <= 2; } 82 84 83 85 typedef const Span* SpanIterator; -
trunk/Source/WebKit/chromium/ChangeLog
r116528 r116538 1 2012-05-09 Dana Jansens <danakj@chromium.org> 2 3 Early-out and avoid any copying when possible for Region operations 4 https://bugs.webkit.org/show_bug.cgi?id=85260 5 6 Reviewed by Anders Carlsson. 7 8 * tests/RegionTest.cpp: 9 (WebCore::TEST): 10 (WebCore): 11 1 12 2012-05-09 Tommy Widenflycht <tommyw@google.com> 2 13 -
trunk/Source/WebKit/chromium/tests/RegionTest.cpp
r116463 r116538 363 363 } 364 364 365 TEST(RegionTest, unite) 366 { 367 Region r; 368 Region r2; 369 370 // A rect uniting a contained rect does not change the region. 371 r2 = r = IntRect(0, 0, 50, 50); 372 r2.unite(IntRect(20, 20, 10, 10)); 373 EXPECT_EQ(r, r2); 374 375 // A rect uniting a containing rect gives back the containing rect. 376 r = IntRect(0, 0, 50, 50); 377 r.unite(IntRect(0, 0, 100, 100)); 378 EXPECT_EQ(Region(IntRect(0, 0, 100, 100)), r); 379 380 // A complex region uniting a contained rect does not change the region. 381 r = IntRect(0, 0, 50, 50); 382 r.unite(IntRect(100, 0, 50, 50)); 383 r2 = r; 384 r2.unite(IntRect(20, 20, 10, 10)); 385 EXPECT_EQ(r, r2); 386 387 // A complex region uniting a containing rect gives back the containing rect. 388 r = IntRect(0, 0, 50, 50); 389 r.unite(IntRect(100, 0, 50, 50)); 390 r. unite(IntRect(0, 0, 500, 500)); 391 EXPECT_EQ(Region(IntRect(0, 0, 500, 500)), r); 392 } 393 365 394 } // namespace
Note: See TracChangeset
for help on using the changeset viewer.