Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(206)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutTable.cpp

Issue 2805103003: Optimize collapsed border calculation (step 2) (Closed)
Patch Set: - Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org)
3 * (C) 1997 Torben Weis (weis@kde.org) 3 * (C) 1997 Torben Weis (weis@kde.org)
4 * (C) 1998 Waldo Bastian (bastian@kde.org) 4 * (C) 1998 Waldo Bastian (bastian@kde.org)
5 * (C) 1999 Lars Knoll (knoll@kde.org) 5 * (C) 1999 Lars Knoll (knoll@kde.org)
6 * (C) 1999 Antti Koivisto (koivisto@kde.org) 6 * (C) 1999 Antti Koivisto (koivisto@kde.org)
7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc.
8 * All rights reserved. 8 * All rights reserved.
9 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) 9 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
10 * 10 *
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 // layout. 96 // layout.
97 if (Style()->IsFixedTableLayout()) 97 if (Style()->IsFixedTableLayout())
98 table_layout_ = WTF::MakeUnique<TableLayoutAlgorithmFixed>(this); 98 table_layout_ = WTF::MakeUnique<TableLayoutAlgorithmFixed>(this);
99 else 99 else
100 table_layout_ = WTF::MakeUnique<TableLayoutAlgorithmAuto>(this); 100 table_layout_ = WTF::MakeUnique<TableLayoutAlgorithmAuto>(this);
101 } 101 }
102 102
103 if (!old_style) 103 if (!old_style)
104 return; 104 return;
105 105
106 if (old_style->BorderCollapse() != StyleRef().BorderCollapse()) { 106 if (old_style->BorderCollapse() != StyleRef().BorderCollapse())
107 InvalidateCollapsedBorders(); 107 SetNeedsInvalidateCollapsedBordersForAllCells();
108 } else { 108 else if (LayoutTableBoxComponent::
109 LayoutTableBoxComponent::InvalidateCollapsedBordersOnStyleChange( 109 NeedsInvalidateCollapsedBordersOnStyleChange(*this, *this, diff,
110 *this, *this, diff, *old_style); 110 *old_style))
111 } 111 InvalidateCollapsedBordersOfAffectedCells();
112 112
113 if (LayoutTableBoxComponent::DoCellsHaveDirtyWidth(*this, *this, diff, 113 if (LayoutTableBoxComponent::DoCellsHaveDirtyWidth(*this, *this, diff,
114 *old_style)) 114 *old_style))
115 MarkAllCellsWidthsDirtyAndOrNeedsLayout(kMarkDirtyAndNeedsLayout); 115 MarkAllCellsWidthsDirtyAndOrNeedsLayout(kMarkDirtyAndNeedsLayout);
116 } 116 }
117 117
118 static inline void ResetSectionPointerIfNotBefore(LayoutTableSection*& ptr, 118 static inline void ResetSectionPointerIfNotBefore(LayoutTableSection*& ptr,
119 LayoutObject* before) { 119 LayoutObject* before) {
120 if (!before || !ptr) 120 if (!before || !ptr)
121 return; 121 return;
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 row = row->NextRow()) { 800 row = row->NextRow()) {
801 for (LayoutTableCell* cell = row->FirstCell(); cell; 801 for (LayoutTableCell* cell = row->FirstCell(); cell;
802 cell = cell->NextCell()) { 802 cell = cell->NextCell()) {
803 DCHECK_EQ(cell->Table(), this); 803 DCHECK_EQ(cell->Table(), this);
804 cell->InvalidateCollapsedBorderValues(); 804 cell->InvalidateCollapsedBorderValues();
805 } 805 }
806 } 806 }
807 } 807 }
808 } 808 }
809 809
810 void LayoutTable::InvalidateCollapsedBordersOfAffectedCells() {
811 DCHECK(CollapseBorders());
812 if (NeedsInvalidateCollapsedBordersForAllCells())
813 return;
814
815 RecalcSectionsIfNeeded();
816 InvalidateCollapsedBorders();
817
818 auto* top_section = TopNonEmptySection();
819 if (!top_section)
820 return;
821
822 // Invalidate cells in the top row.
823 top_section->InvalidateCellCollapsedBordersIntersectingRow(0);
824
825 LayoutTableSection* bottom_section = nullptr;
826 for (auto* section = top_section; section;
827 section = SectionBelow(section, kSkipEmptySections)) {
828 auto num_effective_columns = section->NumEffectiveColumns();
829 for (unsigned r = 0; r < section->NumRows(); ++r) {
830 if (auto* cell = section->PrimaryCellAt(r, 0))
831 cell->InvalidateCollapsedBorderValues();
832 if (auto* cell = section->PrimaryCellAt(r, num_effective_columns - 1))
833 cell->InvalidateCollapsedBorderValues();
834 }
835 bottom_section = section;
836 }
837
838 if (bottom_section != top_section || bottom_section->NumRows() > 1) {
839 bottom_section->InvalidateCellCollapsedBordersIntersectingRow(
840 bottom_section->NumRows() - 1);
841 }
842 }
843
810 // Collect all the unique border values that we want to paint in a sorted list. 844 // Collect all the unique border values that we want to paint in a sorted list.
811 // During the collection, each cell saves its recalculated borders into the 845 // During the collection, each cell saves its recalculated borders into the
812 // cache of its containing section, and invalidates itself if any border 846 // cache of its containing section, and invalidates itself if any border
813 // changes. This method doesn't affect layout. 847 // changes. This method doesn't affect layout.
814 void LayoutTable::RecalcCollapsedBordersIfNeeded() { 848 void LayoutTable::RecalcCollapsedBordersIfNeeded() {
815 if (collapsed_borders_valid_ || !CollapseBorders()) 849 if (collapsed_borders_valid_ || !CollapseBorders())
816 return; 850 return;
817 collapsed_borders_valid_ = true; 851 collapsed_borders_valid_ = true;
818 collapsed_borders_.clear(); 852 collapsed_borders_.clear();
819 for (LayoutObject* section = FirstChild(); section; 853 for (LayoutObject* section = FirstChild(); section;
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
1488 child = child->PreviousSibling()) { 1522 child = child->PreviousSibling()) {
1489 if (child->IsTableSection()) 1523 if (child->IsTableSection())
1490 return ToLayoutTableSection(child); 1524 return ToLayoutTableSection(child);
1491 } 1525 }
1492 1526
1493 return nullptr; 1527 return nullptr;
1494 } 1528 }
1495 1529
1496 LayoutTableCell* LayoutTable::CellAbove(const LayoutTableCell* cell) const { 1530 LayoutTableCell* LayoutTable::CellAbove(const LayoutTableCell* cell) const {
1497 RecalcSectionsIfNeeded(); 1531 RecalcSectionsIfNeeded();
1498 1532 return cell->Section()->PrimaryCellAboveInTable(
1499 // Find the section and row to look in 1533 cell->RowIndex(),
wkorman 2017/04/27 22:05:36 Is the simplified logic here and in CellBelow bene
1500 unsigned r = cell->RowIndex(); 1534 AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex()));
1501 LayoutTableSection* section = nullptr;
1502 unsigned r_above = 0;
1503 if (r > 0) {
1504 // cell is not in the first row, so use the above row in its own section
1505 section = cell->Section();
1506 r_above = r - 1;
1507 } else {
1508 section = SectionAbove(cell->Section(), kSkipEmptySections);
1509 if (section) {
1510 DCHECK(section->NumRows());
1511 r_above = section->NumRows() - 1;
1512 }
1513 }
1514
1515 // Look up the cell in the section's grid, which requires effective col index
1516 if (section) {
1517 unsigned eff_col =
1518 AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex());
1519 return section->PrimaryCellAt(r_above, eff_col);
1520 }
1521 return nullptr;
1522 } 1535 }
1523 1536
1524 LayoutTableCell* LayoutTable::CellBelow(const LayoutTableCell* cell) const { 1537 LayoutTableCell* LayoutTable::CellBelow(const LayoutTableCell* cell) const {
1525 RecalcSectionsIfNeeded(); 1538 RecalcSectionsIfNeeded();
1526 1539 return cell->Section()->PrimaryCellBelowInTable(
1527 // Find the section and row to look in 1540 cell->RowIndex(),
1528 unsigned r = cell->RowIndex() + cell->RowSpan() - 1; 1541 AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex()));
1529 LayoutTableSection* section = nullptr;
1530 unsigned r_below = 0;
1531 if (r < cell->Section()->NumRows() - 1) {
1532 // The cell is not in the last row, so use the next row in the section.
1533 section = cell->Section();
1534 r_below = r + 1;
1535 } else {
1536 section = SectionBelow(cell->Section(), kSkipEmptySections);
1537 if (section)
1538 r_below = 0;
1539 }
1540
1541 // Look up the cell in the section's grid, which requires effective col index
1542 if (section) {
1543 unsigned eff_col =
1544 AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex());
1545 return section->PrimaryCellAt(r_below, eff_col);
1546 }
1547 return nullptr;
1548 } 1542 }
1549 1543
1550 LayoutTableCell* LayoutTable::CellBefore(const LayoutTableCell* cell) const { 1544 LayoutTableCell* LayoutTable::CellBefore(const LayoutTableCell* cell) const {
1551 RecalcSectionsIfNeeded(); 1545 RecalcSectionsIfNeeded();
1552 1546
1553 LayoutTableSection* section = cell->Section(); 1547 LayoutTableSection* section = cell->Section();
1554 unsigned eff_col = 1548 unsigned eff_col =
1555 AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex()); 1549 AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex());
1556 if (!eff_col) 1550 if (!eff_col)
1557 return nullptr; 1551 return nullptr;
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
1762 } 1756 }
1763 1757
1764 LayoutUnit LayoutTable::PaddingRight() const { 1758 LayoutUnit LayoutTable::PaddingRight() const {
1765 if (CollapseBorders()) 1759 if (CollapseBorders())
1766 return LayoutUnit(); 1760 return LayoutUnit();
1767 1761
1768 return LayoutBlock::PaddingRight(); 1762 return LayoutBlock::PaddingRight();
1769 } 1763 }
1770 1764
1771 } // namespace blink 1765 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698