OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "platform/graphics/paint/DisplayItemList.h" | 6 #include "platform/graphics/paint/DisplayItemList.h" |
7 | 7 |
8 #include "platform/RuntimeEnabledFeatures.h" | 8 #include "platform/RuntimeEnabledFeatures.h" |
9 #include "platform/graphics/GraphicsContext.h" | 9 #include "platform/graphics/GraphicsContext.h" |
10 #include "platform/graphics/paint/ClipPathRecorder.h" | 10 #include "platform/graphics/paint/ClipPathRecorder.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 | 50 |
51 DisplayItemClient displayItemClient() const { return toDisplayItemClient(thi
s); } | 51 DisplayItemClient displayItemClient() const { return toDisplayItemClient(thi
s); } |
52 String debugName() const { return m_name; } | 52 String debugName() const { return m_name; } |
53 | 53 |
54 private: | 54 private: |
55 String m_name; | 55 String m_name; |
56 }; | 56 }; |
57 | 57 |
58 class TestDisplayItem : public DisplayItem { | 58 class TestDisplayItem : public DisplayItem { |
59 public: | 59 public: |
60 TestDisplayItem(const DisplayItemClientWrapper& client, Type type) : Display
Item(client, type) { } | 60 TestDisplayItem(const TestDisplayItemClient& client, Type type) : DisplayIte
m(client, type) { } |
61 | 61 |
62 virtual void replay(GraphicsContext&) override final { ASSERT_NOT_REACHED();
} | 62 virtual void replay(GraphicsContext&) override final { ASSERT_NOT_REACHED();
} |
63 virtual void appendToWebDisplayItemList(WebDisplayItemList*) const override
final { ASSERT_NOT_REACHED(); } | 63 virtual void appendToWebDisplayItemList(WebDisplayItemList*) const override
final { ASSERT_NOT_REACHED(); } |
64 }; | 64 }; |
65 | 65 |
66 #ifndef NDEBUG | 66 #ifndef NDEBUG |
67 #define TRACE_DISPLAY_ITEMS(i, expected, actual) \ | 67 #define TRACE_DISPLAY_ITEMS(i, expected, actual) \ |
68 String trace = String::format("%d: ", (int)i) + "Expected: " + (expected).as
DebugString() + " Actual: " + (actual).asDebugString(); \ | 68 String trace = String::format("%d: ", (int)i) + "Expected: " + (expected).as
DebugString() + " Actual: " + (actual).asDebugString(); \ |
69 SCOPED_TRACE(trace.utf8().data()); | 69 SCOPED_TRACE(trace.utf8().data()); |
70 #else | 70 #else |
71 #define TRACE_DISPLAY_ITEMS(i, expected, actual) | 71 #define TRACE_DISPLAY_ITEMS(i, expected, actual) |
72 #endif | 72 #endif |
73 | 73 |
74 #define EXPECT_DISPLAY_LIST(actual, expectedSize, ...) \ | 74 #define EXPECT_DISPLAY_LIST(actual, expectedSize, ...) \ |
75 do { \ | 75 do { \ |
76 EXPECT_EQ((size_t)expectedSize, actual.size()); \ | 76 EXPECT_EQ((size_t)expectedSize, actual.size()); \ |
77 if (expectedSize != actual.size()) \ | 77 if (expectedSize != actual.size()) \ |
78 break; \ | 78 break; \ |
79 const TestDisplayItem expected[] = { __VA_ARGS__ }; \ | 79 const TestDisplayItem expected[] = { __VA_ARGS__ }; \ |
80 for (size_t index = 0; index < std::min<size_t>(actual.size(), expectedS
ize); index++) { \ | 80 for (size_t index = 0; index < std::min<size_t>(actual.size(), expectedS
ize); index++) { \ |
81 TRACE_DISPLAY_ITEMS(index, expected[index], actual[index]); \ | 81 TRACE_DISPLAY_ITEMS(index, expected[index], *actual.elementAt(index)
); \ |
82 EXPECT_EQ(expected[index].client(), actual[index].client()); \ | 82 EXPECT_EQ(expected[index].client(), actual.elementAt(index)->client(
)); \ |
83 EXPECT_EQ(expected[index].type(), actual[index].type()); \ | 83 EXPECT_EQ(expected[index].type(), actual.elementAt(index)->type());
\ |
84 } \ | 84 } \ |
85 } while (false); | 85 } while (false); |
86 | 86 |
87 void drawRect(GraphicsContext& context, const TestDisplayItemClient& client, Dis
playItem::Type type, const FloatRect& bound) | 87 void drawRect(GraphicsContext& context, const TestDisplayItemClient& client, Dis
playItem::Type type, const FloatRect& bound) |
88 { | 88 { |
89 DrawingRecorder drawingRecorder(context, client, type, bound); | 89 DrawingRecorder drawingRecorder(context, client, type, bound); |
90 if (drawingRecorder.canUseCachedDrawing()) | 90 if (drawingRecorder.canUseCachedDrawing()) |
91 return; | 91 return; |
92 IntRect rect(0, 0, 10, 10); | 92 IntRect rect(0, 0, 10, 10); |
93 context.drawRect(rect); | 93 context.drawRect(rect); |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 | 364 |
365 drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150
)); | 365 drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150
)); |
366 drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 150, 15
0)); | 366 drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 150, 15
0)); |
367 displayItemList().commitNewDisplayItems(); | 367 displayItemList().commitNewDisplayItems(); |
368 | 368 |
369 EXPECT_DISPLAY_LIST(displayItemList().displayItems(), 2, | 369 EXPECT_DISPLAY_LIST(displayItemList().displayItems(), 2, |
370 TestDisplayItem(first, backgroundDrawingType), | 370 TestDisplayItem(first, backgroundDrawingType), |
371 TestDisplayItem(second, backgroundDrawingType)); | 371 TestDisplayItem(second, backgroundDrawingType)); |
372 EXPECT_TRUE(displayItemList().clientCacheIsValid(first.displayItemClient()))
; | 372 EXPECT_TRUE(displayItemList().clientCacheIsValid(first.displayItemClient()))
; |
373 EXPECT_TRUE(displayItemList().clientCacheIsValid(second.displayItemClient())
); | 373 EXPECT_TRUE(displayItemList().clientCacheIsValid(second.displayItemClient())
); |
374 const SkPicture* firstPicture = displayItemList().displayItems()[0].picture(
); | 374 const SkPicture* firstPicture = static_cast<const DrawingDisplayItem*>(displ
ayItemList().displayItems().elementAt(0))->picture(); |
375 const SkPicture* secondPicture = displayItemList().displayItems()[1].picture
(); | 375 const SkPicture* secondPicture = static_cast<const DrawingDisplayItem*>(disp
layItemList().displayItems().elementAt(1))->picture(); |
376 | 376 |
377 displayItemList().invalidate(first.displayItemClient()); | 377 displayItemList().invalidate(first.displayItemClient()); |
378 EXPECT_FALSE(displayItemList().clientCacheIsValid(first.displayItemClient())
); | 378 EXPECT_FALSE(displayItemList().clientCacheIsValid(first.displayItemClient())
); |
379 EXPECT_TRUE(displayItemList().clientCacheIsValid(second.displayItemClient())
); | 379 EXPECT_TRUE(displayItemList().clientCacheIsValid(second.displayItemClient())
); |
380 | 380 |
381 drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150
)); | 381 drawRect(context, first, backgroundDrawingType, FloatRect(100, 100, 150, 150
)); |
382 drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 150, 15
0)); | 382 drawRect(context, second, backgroundDrawingType, FloatRect(100, 100, 150, 15
0)); |
383 displayItemList().commitNewDisplayItems(); | 383 displayItemList().commitNewDisplayItems(); |
384 | 384 |
385 EXPECT_DISPLAY_LIST(displayItemList().displayItems(), 2, | 385 EXPECT_DISPLAY_LIST(displayItemList().displayItems(), 2, |
386 TestDisplayItem(first, backgroundDrawingType), | 386 TestDisplayItem(first, backgroundDrawingType), |
387 TestDisplayItem(second, backgroundDrawingType)); | 387 TestDisplayItem(second, backgroundDrawingType)); |
388 // The first display item should be updated. | 388 // The first display item should be updated. |
389 EXPECT_NE(firstPicture, displayItemList().displayItems()[0].picture()); | 389 EXPECT_NE(firstPicture, static_cast<const DrawingDisplayItem*>(displayItemLi
st().displayItems().elementAt(0))->picture()); |
390 // The second display item should be cached. | 390 // The second display item should be cached. |
391 EXPECT_EQ(secondPicture, displayItemList().displayItems()[1].picture()); | 391 EXPECT_EQ(secondPicture, static_cast<const DrawingDisplayItem*>(displayItemL
ist().displayItems().elementAt(1))->picture()); |
392 EXPECT_TRUE(displayItemList().clientCacheIsValid(first.displayItemClient()))
; | 392 EXPECT_TRUE(displayItemList().clientCacheIsValid(first.displayItemClient()))
; |
393 EXPECT_TRUE(displayItemList().clientCacheIsValid(second.displayItemClient())
); | 393 EXPECT_TRUE(displayItemList().clientCacheIsValid(second.displayItemClient())
); |
394 | 394 |
395 displayItemList().invalidateAll(); | 395 displayItemList().invalidateAll(); |
396 EXPECT_FALSE(displayItemList().clientCacheIsValid(first.displayItemClient())
); | 396 EXPECT_FALSE(displayItemList().clientCacheIsValid(first.displayItemClient())
); |
397 EXPECT_FALSE(displayItemList().clientCacheIsValid(second.displayItemClient()
)); | 397 EXPECT_FALSE(displayItemList().clientCacheIsValid(second.displayItemClient()
)); |
398 } | 398 } |
399 | 399 |
400 TEST_F(DisplayItemListTest, ComplexUpdateSwapOrder) | 400 TEST_F(DisplayItemListTest, ComplexUpdateSwapOrder) |
401 { | 401 { |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 TestDisplayItem(content1, backgroundDrawingType), | 546 TestDisplayItem(content1, backgroundDrawingType), |
547 TestDisplayItem(container1, DisplayItem::paintPhaseToEndSubtreeType(back
groundDrawingType)), | 547 TestDisplayItem(container1, DisplayItem::paintPhaseToEndSubtreeType(back
groundDrawingType)), |
548 | 548 |
549 TestDisplayItem(container1, DisplayItem::paintPhaseToBeginSubtreeType(fo
regroundDrawingType)), | 549 TestDisplayItem(container1, DisplayItem::paintPhaseToBeginSubtreeType(fo
regroundDrawingType)), |
550 TestDisplayItem(content1, foregroundDrawingType), | 550 TestDisplayItem(content1, foregroundDrawingType), |
551 TestDisplayItem(container1, foregroundDrawingType), | 551 TestDisplayItem(container1, foregroundDrawingType), |
552 TestDisplayItem(container1, DisplayItem::paintPhaseToEndSubtreeType(fore
groundDrawingType))); | 552 TestDisplayItem(container1, DisplayItem::paintPhaseToEndSubtreeType(fore
groundDrawingType))); |
553 } | 553 } |
554 #endif | 554 #endif |
555 | 555 |
556 static bool isDrawing(const DisplayItems::ItemHandle& item) | 556 static bool isDrawing(const DisplayItem& item) |
557 { | 557 { |
558 return DisplayItem::isDrawingType(item.type()); | 558 return DisplayItem::isDrawingType(item.type()); |
559 } | 559 } |
560 | 560 |
561 static bool isCached(const DisplayItems::ItemHandle& item) | 561 static bool isCached(const DisplayItem& item) |
562 { | 562 { |
563 return DisplayItem::isCachedType(item.type()); | 563 return DisplayItem::isCachedType(item.type()); |
564 } | 564 } |
565 | 565 |
566 TEST_F(DisplayItemListTest, Scope) | 566 TEST_F(DisplayItemListTest, Scope) |
567 { | 567 { |
568 TestDisplayItemClient multicol("multicol"); | 568 TestDisplayItemClient multicol("multicol"); |
569 TestDisplayItemClient content("content"); | 569 TestDisplayItemClient content("content"); |
570 GraphicsContext context(&displayItemList()); | 570 GraphicsContext context(&displayItemList()); |
571 | 571 |
572 FloatRect rect1(100, 100, 50, 50); | 572 FloatRect rect1(100, 100, 50, 50); |
573 FloatRect rect2(150, 100, 50, 50); | 573 FloatRect rect2(150, 100, 50, 50); |
574 FloatRect rect3(200, 100, 50, 50); | 574 FloatRect rect3(200, 100, 50, 50); |
575 | 575 |
576 drawRect(context, multicol, backgroundDrawingType, FloatRect(100, 200, 100,
100)); | 576 drawRect(context, multicol, backgroundDrawingType, FloatRect(100, 200, 100,
100)); |
577 | 577 |
578 displayItemList().beginScope(multicol.displayItemClient()); | 578 displayItemList().beginScope(multicol.displayItemClient()); |
579 drawRect(context, content, foregroundDrawingType, rect1); | 579 drawRect(context, content, foregroundDrawingType, rect1); |
580 displayItemList().endScope(multicol.displayItemClient()); | 580 displayItemList().endScope(multicol.displayItemClient()); |
581 | 581 |
582 displayItemList().beginScope(multicol.displayItemClient()); | 582 displayItemList().beginScope(multicol.displayItemClient()); |
583 drawRect(context, content, foregroundDrawingType, rect2); | 583 drawRect(context, content, foregroundDrawingType, rect2); |
584 displayItemList().endScope(multicol.displayItemClient()); | 584 displayItemList().endScope(multicol.displayItemClient()); |
585 displayItemList().commitNewDisplayItems(); | 585 displayItemList().commitNewDisplayItems(); |
586 | 586 |
587 EXPECT_DISPLAY_LIST(displayItemList().displayItems(), 3, | 587 EXPECT_DISPLAY_LIST(displayItemList().displayItems(), 3, |
588 TestDisplayItem(multicol, backgroundDrawingType), | 588 TestDisplayItem(multicol, backgroundDrawingType), |
589 TestDisplayItem(content, foregroundDrawingType), | 589 TestDisplayItem(content, foregroundDrawingType), |
590 TestDisplayItem(content, foregroundDrawingType)); | 590 TestDisplayItem(content, foregroundDrawingType)); |
591 RefPtr<const SkPicture> picture1 = displayItemList().displayItems()[1].pictu
re(); | 591 RefPtr<const SkPicture> picture1 = static_cast<const DrawingDisplayItem*>(di
splayItemList().displayItems().elementAt(1))->picture(); |
592 RefPtr<const SkPicture> picture2 = displayItemList().displayItems()[2].pictu
re(); | 592 RefPtr<const SkPicture> picture2 = static_cast<const DrawingDisplayItem*>(di
splayItemList().displayItems().elementAt(2))->picture(); |
593 EXPECT_NE(picture1, picture2); | 593 EXPECT_NE(picture1, picture2); |
594 | 594 |
595 // Draw again with nothing invalidated. | 595 // Draw again with nothing invalidated. |
596 EXPECT_TRUE(displayItemList().clientCacheIsValid(multicol.displayItemClient(
))); | 596 EXPECT_TRUE(displayItemList().clientCacheIsValid(multicol.displayItemClient(
))); |
597 drawRect(context, multicol, backgroundDrawingType, FloatRect(100, 200, 100,
100)); | 597 drawRect(context, multicol, backgroundDrawingType, FloatRect(100, 200, 100,
100)); |
598 displayItemList().beginScope(multicol.displayItemClient()); | 598 displayItemList().beginScope(multicol.displayItemClient()); |
599 drawRect(context, content, foregroundDrawingType, rect1); | 599 drawRect(context, content, foregroundDrawingType, rect1); |
600 displayItemList().endScope(multicol.displayItemClient()); | 600 displayItemList().endScope(multicol.displayItemClient()); |
601 | 601 |
602 displayItemList().beginScope(multicol.displayItemClient()); | 602 displayItemList().beginScope(multicol.displayItemClient()); |
603 drawRect(context, content, foregroundDrawingType, rect2); | 603 drawRect(context, content, foregroundDrawingType, rect2); |
604 displayItemList().endScope(multicol.displayItemClient()); | 604 displayItemList().endScope(multicol.displayItemClient()); |
605 | 605 |
606 EXPECT_TRUE(isCached(newPaintListBeforeUpdate()[0])); | 606 EXPECT_TRUE(isCached(*newPaintListBeforeUpdate().elementAt(0))); |
607 EXPECT_TRUE(isDrawing(newPaintListBeforeUpdate()[1])); | 607 EXPECT_TRUE(isDrawing(*newPaintListBeforeUpdate().elementAt(1))); |
608 EXPECT_TRUE(isDrawing(newPaintListBeforeUpdate()[2])); | 608 EXPECT_TRUE(isDrawing(*newPaintListBeforeUpdate().elementAt(2))); |
609 displayItemList().commitNewDisplayItems(); | 609 displayItemList().commitNewDisplayItems(); |
610 | 610 |
611 EXPECT_DISPLAY_LIST(displayItemList().displayItems(), 3, | 611 EXPECT_DISPLAY_LIST(displayItemList().displayItems(), 3, |
612 TestDisplayItem(multicol, backgroundDrawingType), | 612 TestDisplayItem(multicol, backgroundDrawingType), |
613 TestDisplayItem(content, foregroundDrawingType), | 613 TestDisplayItem(content, foregroundDrawingType), |
614 TestDisplayItem(content, foregroundDrawingType)); | 614 TestDisplayItem(content, foregroundDrawingType)); |
615 EXPECT_NE(picture1, displayItemList().displayItems()[1].picture()); | 615 EXPECT_NE(picture1, static_cast<const DrawingDisplayItem*>(displayItemList()
.displayItems().elementAt(1))->picture()); |
616 EXPECT_NE(picture2, displayItemList().displayItems()[2].picture()); | 616 EXPECT_NE(picture2, static_cast<const DrawingDisplayItem*>(displayItemList()
.displayItems().elementAt(2))->picture()); |
617 | 617 |
618 // Now the multicol becomes 3 columns and repaints. | 618 // Now the multicol becomes 3 columns and repaints. |
619 displayItemList().invalidate(multicol.displayItemClient()); | 619 displayItemList().invalidate(multicol.displayItemClient()); |
620 drawRect(context, multicol, backgroundDrawingType, FloatRect(100, 100, 100,
100)); | 620 drawRect(context, multicol, backgroundDrawingType, FloatRect(100, 100, 100,
100)); |
621 | 621 |
622 displayItemList().beginScope(multicol.displayItemClient()); | 622 displayItemList().beginScope(multicol.displayItemClient()); |
623 drawRect(context, content, foregroundDrawingType, rect1); | 623 drawRect(context, content, foregroundDrawingType, rect1); |
624 displayItemList().endScope(multicol.displayItemClient()); | 624 displayItemList().endScope(multicol.displayItemClient()); |
625 | 625 |
626 displayItemList().beginScope(multicol.displayItemClient()); | 626 displayItemList().beginScope(multicol.displayItemClient()); |
627 drawRect(context, content, foregroundDrawingType, rect2); | 627 drawRect(context, content, foregroundDrawingType, rect2); |
628 displayItemList().endScope(multicol.displayItemClient()); | 628 displayItemList().endScope(multicol.displayItemClient()); |
629 | 629 |
630 displayItemList().beginScope(multicol.displayItemClient()); | 630 displayItemList().beginScope(multicol.displayItemClient()); |
631 drawRect(context, content, foregroundDrawingType, rect3); | 631 drawRect(context, content, foregroundDrawingType, rect3); |
632 displayItemList().endScope(multicol.displayItemClient()); | 632 displayItemList().endScope(multicol.displayItemClient()); |
633 | 633 |
634 // We should repaint everything on invalidation of the scope container. | 634 // We should repaint everything on invalidation of the scope container. |
635 EXPECT_TRUE(isDrawing(newPaintListBeforeUpdate()[0])); | 635 EXPECT_TRUE(isDrawing(*newPaintListBeforeUpdate().elementAt(0))); |
636 EXPECT_TRUE(isDrawing(newPaintListBeforeUpdate()[1])); | 636 EXPECT_TRUE(isDrawing(*newPaintListBeforeUpdate().elementAt(1))); |
637 EXPECT_TRUE(isDrawing(newPaintListBeforeUpdate()[2])); | 637 EXPECT_TRUE(isDrawing(*newPaintListBeforeUpdate().elementAt(2))); |
638 EXPECT_TRUE(isDrawing(newPaintListBeforeUpdate()[3])); | 638 EXPECT_TRUE(isDrawing(*newPaintListBeforeUpdate().elementAt(3))); |
639 displayItemList().commitNewDisplayItems(); | 639 displayItemList().commitNewDisplayItems(); |
640 | 640 |
641 EXPECT_DISPLAY_LIST(displayItemList().displayItems(), 4, | 641 EXPECT_DISPLAY_LIST(displayItemList().displayItems(), 4, |
642 TestDisplayItem(multicol, backgroundDrawingType), | 642 TestDisplayItem(multicol, backgroundDrawingType), |
643 TestDisplayItem(content, foregroundDrawingType), | 643 TestDisplayItem(content, foregroundDrawingType), |
644 TestDisplayItem(content, foregroundDrawingType), | 644 TestDisplayItem(content, foregroundDrawingType), |
645 TestDisplayItem(content, foregroundDrawingType)); | 645 TestDisplayItem(content, foregroundDrawingType)); |
646 EXPECT_NE(picture1, displayItemList().displayItems()[1].picture()); | 646 EXPECT_NE(picture1, static_cast<const DrawingDisplayItem*>(displayItemList()
.displayItems().elementAt(1))->picture()); |
647 EXPECT_NE(picture2, displayItemList().displayItems()[2].picture()); | 647 EXPECT_NE(picture2, static_cast<const DrawingDisplayItem*>(displayItemList()
.displayItems().elementAt(2))->picture()); |
648 } | 648 } |
649 | 649 |
650 TEST_F(DisplayItemListTest, OptimizeNoopPairs) | 650 TEST_F(DisplayItemListTest, OptimizeNoopPairs) |
651 { | 651 { |
652 TestDisplayItemClient first("first"); | 652 TestDisplayItemClient first("first"); |
653 TestDisplayItemClient second("second"); | 653 TestDisplayItemClient second("second"); |
654 TestDisplayItemClient third("third"); | 654 TestDisplayItemClient third("third"); |
655 | 655 |
656 GraphicsContext context(&displayItemList()); | 656 GraphicsContext context(&displayItemList()); |
657 drawRect(context, first, backgroundDrawingType, FloatRect(0, 0, 100, 100)); | 657 drawRect(context, first, backgroundDrawingType, FloatRect(0, 0, 100, 100)); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 drawRect(context, third, backgroundDrawingType, FloatRect(0, 0, 100, 100)); | 695 drawRect(context, third, backgroundDrawingType, FloatRect(0, 0, 100, 100)); |
696 displayItemList().commitNewDisplayItems(); | 696 displayItemList().commitNewDisplayItems(); |
697 | 697 |
698 // Empty clips should have been optimized out. | 698 // Empty clips should have been optimized out. |
699 EXPECT_DISPLAY_LIST(displayItemList().displayItems(), 2, | 699 EXPECT_DISPLAY_LIST(displayItemList().displayItems(), 2, |
700 TestDisplayItem(first, backgroundDrawingType), | 700 TestDisplayItem(first, backgroundDrawingType), |
701 TestDisplayItem(third, backgroundDrawingType)); | 701 TestDisplayItem(third, backgroundDrawingType)); |
702 } | 702 } |
703 | 703 |
704 } // namespace blink | 704 } // namespace blink |
OLD | NEW |