mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-24 16:17:29 +09:00
Issue #1355 - Hit testing in large tables has become extremely slow
Add dirty rect intersection checks so that we don't build unnecessary table part display items.
This commit is contained in:
parent
57809c759f
commit
012bac1934
1 changed files with 30 additions and 7 deletions
|
|
@ -1192,6 +1192,7 @@ PaintRowBackground(nsTableRowFrame* aRow,
|
||||||
nsIFrame* aFrame,
|
nsIFrame* aFrame,
|
||||||
nsDisplayListBuilder* aBuilder,
|
nsDisplayListBuilder* aBuilder,
|
||||||
const nsDisplayListSet& aLists,
|
const nsDisplayListSet& aLists,
|
||||||
|
const nsRect& aDirtyRect,
|
||||||
const nsPoint& aOffset = nsPoint())
|
const nsPoint& aOffset = nsPoint())
|
||||||
{
|
{
|
||||||
// Compute background rect by iterating over all cell frames.
|
// Compute background rect by iterating over all cell frames.
|
||||||
|
|
@ -1201,6 +1202,9 @@ PaintRowBackground(nsTableRowFrame* aRow,
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cellRect = cell->GetRectRelativeToSelf() + cell->GetNormalPosition() + aOffset;
|
auto cellRect = cell->GetRectRelativeToSelf() + cell->GetNormalPosition() + aOffset;
|
||||||
|
if (!aDirtyRect.Intersects(cellRect)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame, cellRect,
|
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame, cellRect,
|
||||||
aLists.BorderBackground(),
|
aLists.BorderBackground(),
|
||||||
true, nullptr,
|
true, nullptr,
|
||||||
|
|
@ -1213,10 +1217,14 @@ static void
|
||||||
PaintRowGroupBackground(nsTableRowGroupFrame* aRowGroup,
|
PaintRowGroupBackground(nsTableRowGroupFrame* aRowGroup,
|
||||||
nsIFrame* aFrame,
|
nsIFrame* aFrame,
|
||||||
nsDisplayListBuilder* aBuilder,
|
nsDisplayListBuilder* aBuilder,
|
||||||
const nsDisplayListSet& aLists)
|
const nsDisplayListSet& aLists,
|
||||||
|
const nsRect& aDirtyRect)
|
||||||
{
|
{
|
||||||
for (nsTableRowFrame* row = aRowGroup->GetFirstRow(); row; row = row->GetNextRow()) {
|
for (nsTableRowFrame* row = aRowGroup->GetFirstRow(); row; row = row->GetNextRow()) {
|
||||||
PaintRowBackground(row, aFrame, aBuilder, aLists, row->GetNormalPosition());
|
if (!aDirtyRect.Intersects(nsRect(row->GetNormalPosition(), row->GetSize()))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
PaintRowBackground(row, aFrame, aBuilder, aLists, aDirtyRect, row->GetNormalPosition());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1225,10 +1233,15 @@ PaintRowGroupBackgroundByColIdx(nsTableRowGroupFrame* aRowGroup,
|
||||||
nsIFrame* aFrame,
|
nsIFrame* aFrame,
|
||||||
nsDisplayListBuilder* aBuilder,
|
nsDisplayListBuilder* aBuilder,
|
||||||
const nsDisplayListSet& aLists,
|
const nsDisplayListSet& aLists,
|
||||||
|
const nsRect& aDirtyRect,
|
||||||
const nsTArray<int32_t>& aColIdx,
|
const nsTArray<int32_t>& aColIdx,
|
||||||
const nsPoint& aOffset)
|
const nsPoint& aOffset)
|
||||||
{
|
{
|
||||||
for (nsTableRowFrame* row = aRowGroup->GetFirstRow(); row; row = row->GetNextRow()) {
|
for (nsTableRowFrame* row = aRowGroup->GetFirstRow(); row; row = row->GetNextRow()) {
|
||||||
|
auto rowPos = row->GetNormalPosition() + aOffset;
|
||||||
|
if (!aDirtyRect.Intersects(nsRect(rowPos, row->GetSize()))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (nsTableCellFrame* cell = row->GetFirstCell(); cell; cell = cell->GetNextCell()) {
|
for (nsTableCellFrame* cell = row->GetFirstCell(); cell; cell = cell->GetNextCell()) {
|
||||||
if (!cell->ShouldPaintBackground(aBuilder)) {
|
if (!cell->ShouldPaintBackground(aBuilder)) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1237,7 +1250,11 @@ PaintRowGroupBackgroundByColIdx(nsTableRowGroupFrame* aRowGroup,
|
||||||
int32_t curColIdx;
|
int32_t curColIdx;
|
||||||
cell->GetColIndex(curColIdx);
|
cell->GetColIndex(curColIdx);
|
||||||
if (aColIdx.Contains(curColIdx)) {
|
if (aColIdx.Contains(curColIdx)) {
|
||||||
auto cellRect = cell->GetRectRelativeToSelf() + cell->GetNormalPosition() + row->GetNormalPosition() + aOffset;
|
auto cellPos = cell->GetNormalPosition() + rowPos;
|
||||||
|
auto cellRect = nsRect(cellPos, cell->GetSize());
|
||||||
|
if (!aDirtyRect.Intersects(cellRect)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame, cellRect,
|
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame, cellRect,
|
||||||
aLists.BorderBackground(),
|
aLists.BorderBackground(),
|
||||||
true, nullptr,
|
true, nullptr,
|
||||||
|
|
@ -1284,10 +1301,10 @@ nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
|
||||||
// See spec at https://drafts.csswg.org/css-tables-3/#drawing-cell-backgrounds
|
// See spec at https://drafts.csswg.org/css-tables-3/#drawing-cell-backgrounds
|
||||||
if (aFrame->GetType() == nsGkAtoms::tableRowGroupFrame) {
|
if (aFrame->GetType() == nsGkAtoms::tableRowGroupFrame) {
|
||||||
nsTableRowGroupFrame* rowGroup = static_cast<nsTableRowGroupFrame*>(aFrame);
|
nsTableRowGroupFrame* rowGroup = static_cast<nsTableRowGroupFrame*>(aFrame);
|
||||||
PaintRowGroupBackground(rowGroup, aFrame, aBuilder, aLists);
|
PaintRowGroupBackground(rowGroup, aFrame, aBuilder, aLists, aDirtyRect);
|
||||||
} else if (aFrame->GetType() == nsGkAtoms::tableRowFrame) {
|
} else if (aFrame->GetType() == nsGkAtoms::tableRowFrame) {
|
||||||
nsTableRowFrame* row = static_cast<nsTableRowFrame*>(aFrame);
|
nsTableRowFrame* row = static_cast<nsTableRowFrame*>(aFrame);
|
||||||
PaintRowBackground(row, aFrame, aBuilder, aLists);
|
PaintRowBackground(row, aFrame, aBuilder, aLists, aDirtyRect);
|
||||||
} else if (aFrame->GetType() == nsGkAtoms::tableColGroupFrame) {
|
} else if (aFrame->GetType() == nsGkAtoms::tableColGroupFrame) {
|
||||||
// Compute background rect by iterating all cell frame.
|
// Compute background rect by iterating all cell frame.
|
||||||
nsTableColGroupFrame* colGroup = static_cast<nsTableColGroupFrame*>(aFrame);
|
nsTableColGroupFrame* colGroup = static_cast<nsTableColGroupFrame*>(aFrame);
|
||||||
|
|
@ -1302,7 +1319,10 @@ nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
|
||||||
table->OrderRowGroups(rowGroups);
|
table->OrderRowGroups(rowGroups);
|
||||||
for (nsTableRowGroupFrame* rowGroup : rowGroups) {
|
for (nsTableRowGroupFrame* rowGroup : rowGroups) {
|
||||||
auto offset = rowGroup->GetNormalPosition() - colGroup->GetNormalPosition();
|
auto offset = rowGroup->GetNormalPosition() - colGroup->GetNormalPosition();
|
||||||
PaintRowGroupBackgroundByColIdx(rowGroup, aFrame, aBuilder, aLists, colIdx, offset);
|
if (!aDirtyRect.Intersects(nsRect(offset, rowGroup->GetSize()))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
PaintRowGroupBackgroundByColIdx(rowGroup, aFrame, aBuilder, aLists, aDirtyRect, colIdx, offset);
|
||||||
}
|
}
|
||||||
} else if (aFrame->GetType() == nsGkAtoms::tableColFrame) {
|
} else if (aFrame->GetType() == nsGkAtoms::tableColFrame) {
|
||||||
// Compute background rect by iterating all cell frame.
|
// Compute background rect by iterating all cell frame.
|
||||||
|
|
@ -1317,7 +1337,10 @@ nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
|
||||||
auto offset = rowGroup->GetNormalPosition() -
|
auto offset = rowGroup->GetNormalPosition() -
|
||||||
col->GetNormalPosition() -
|
col->GetNormalPosition() -
|
||||||
col->GetTableColGroupFrame()->GetNormalPosition();
|
col->GetTableColGroupFrame()->GetNormalPosition();
|
||||||
PaintRowGroupBackgroundByColIdx(rowGroup, aFrame, aBuilder, aLists, colIdx, offset);
|
if (!aDirtyRect.Intersects(nsRect(offset, rowGroup->GetSize()))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
PaintRowGroupBackgroundByColIdx(rowGroup, aFrame, aBuilder, aLists, aDirtyRect, colIdx, offset);
|
||||||
}
|
}
|
||||||
} else if (isVisible) {
|
} else if (isVisible) {
|
||||||
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame,
|
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue