https://bugs.webkit.org/show_bug.cgi?id=129298
Reviewed by Simon Fraser.
Create an alternative fast path to RenderTable colToEffCol() and effColToCol()
when there is no colspan or colspan does not exceed the width of table.
Blink merge https://codereview.chromium.org/
154243002 by rhogan
PerformanceTests:
* Layout/large-table-with-collapsed-borders-and-colspans-wider-than-table.html: Added.
* Layout/large-table-with-collapsed-borders-and-colspans.html: Added.
* Layout/large-table-with-collapsed-borders-and-no-colspans.html: Added.
* Layout/resources/large-table-with-collapsed-borders.css: Added.
* Layout/resources/large-table-with-collapsed-borders.js: Added.
Source/WebCore:
* rendering/RenderTable.cpp:
(WebCore::RenderTable::RenderTable):
(WebCore::RenderTable::appendColumn):
(WebCore::RenderTable::recalcSections):
* rendering/RenderTable.h:
(WebCore::RenderTable::colToEffCol):
(WebCore::RenderTable::effColToCol):
(WebCore::RenderTable::hasCellColspanThatDeterminesTableWidth):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@166016
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2014-03-20 Laszlo Vidacs <lvidacs.u-szeged@partner.samsung.com>
+
+ Optimize RenderTable::colToEffCol() for tables without colspans
+ https://bugs.webkit.org/show_bug.cgi?id=129298
+
+ Reviewed by Simon Fraser.
+
+ Create an alternative fast path to RenderTable colToEffCol() and effColToCol()
+ when there is no colspan or colspan does not exceed the width of table.
+ Blink merge https://codereview.chromium.org/154243002 by rhogan
+
+ * Layout/large-table-with-collapsed-borders-and-colspans-wider-than-table.html: Added.
+ * Layout/large-table-with-collapsed-borders-and-colspans.html: Added.
+ * Layout/large-table-with-collapsed-borders-and-no-colspans.html: Added.
+ * Layout/resources/large-table-with-collapsed-borders.css: Added.
+ * Layout/resources/large-table-with-collapsed-borders.js: Added.
+
2014-03-14 Maciej Stachowiak <mjs@apple.com>
Replace "Apple Computer, Inc." with "Apple Inc." in copyright headers
--- /dev/null
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Table layout performance with collapsed borders and a cell with a colspan wider than the other rows in the table.</title>
+ <link rel="stylesheet" href="resources/large-table-with-collapsed-borders.css" TYPE="text/css"></link>
+ <script src="../resources/runner.js"></script>
+ <script src="resources/large-table-with-collapsed-borders.js"></script>
+ </head>
+ <body>
+ <pre id="log"></pre>
+ <script>
+ PerfTestRunner.measureTime({run: createTableTestFunction(400, 100, 500)});
+ </script>
+ </body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Table layout performance with collapsed borders and a cell with a colspan that can be accomodated by the width given by other rows in the table.</title>
+ <link rel="stylesheet" href="resources/large-table-with-collapsed-borders.css" TYPE="text/css"></link>
+ <script src="../resources/runner.js"></script>
+ <script src="resources/large-table-with-collapsed-borders.js"></script>
+ </head>
+ <body>
+ <pre id="log"></pre>
+ <script>
+ PerfTestRunner.measureTime({run: createTableTestFunction(400, 100, 50)});
+ </script>
+ </body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Table layout performance with collapsed borders and no cells with colspan.</title>
+ <link rel="stylesheet" href="resources/large-table-with-collapsed-borders.css" TYPE="text/css"></link>
+ <script src="../resources/runner.js"></script>
+ <script src="resources/large-table-with-collapsed-borders.js"></script>
+ </head>
+ <body>
+ <pre id="log"></pre>
+ <script>
+ PerfTestRunner.measureTime({run: createTableTestFunction(400, 100, 0)});
+ </script>
+ </body>
+</html>
--- /dev/null
+html, body {
+ margin: 0;
+}
+
+table {
+ border-collapse: collapse;
+ border : 1px solid red;
+}
+td {
+ border : 1px solid blue;
+ width: 5px;
+ height: 5px;
+}
+
--- /dev/null
+(function() {
+ function createElement(tag, parent, className, id) {
+ var el = document.createElement(tag);
+ el.className = className;
+ if (id)
+ el.id = id;
+ parent.appendChild(el);
+ return el;
+ }
+
+ function createTable(width, height, colspan) {
+ var table = createElement("table", document.body, "table");
+ for (var y = 0; y < height; ++y) {
+ var tr = createElement("tr", table, "tr");
+ for (var x = 0; x < width; ++x) {
+ var td = createElement("td", tr, "td");
+ if (colspan > 0 && x==10 && y==0)
+ table.rows[y].cells[x].colSpan = colspan;
+ }
+ }
+ return table;
+ }
+
+ function createTestFunction(width, height, colspan) {
+ return function() {
+ var table = createTable(width, height, colspan);
+ table.clientHeight;
+ }
+ }
+
+ window.createTableTestFunction = createTestFunction;
+})();
+2014-03-20 Laszlo Vidacs <lvidacs.u-szeged@partner.samsung.com>
+
+ Optimize RenderTable::colToEffCol() for tables without colspans
+ https://bugs.webkit.org/show_bug.cgi?id=129298
+
+ Reviewed by Simon Fraser.
+
+ Create an alternative fast path to RenderTable colToEffCol() and effColToCol()
+ when there is no colspan or colspan does not exceed the width of table.
+ Blink merge https://codereview.chromium.org/154243002 by rhogan
+
+ * rendering/RenderTable.cpp:
+ (WebCore::RenderTable::RenderTable):
+ (WebCore::RenderTable::appendColumn):
+ (WebCore::RenderTable::recalcSections):
+ * rendering/RenderTable.h:
+ (WebCore::RenderTable::colToEffCol):
+ (WebCore::RenderTable::effColToCol):
+ (WebCore::RenderTable::hasCellColspanThatDeterminesTableWidth):
+
2014-03-20 Simon Fraser <simon.fraser@apple.com>
FrameView::paintContents() is not called for composited content
, m_needsSectionRecalc(false)
, m_columnLogicalWidthChanged(false)
, m_columnRenderersValid(false)
+ , m_hasCellColspanThatDeterminesTableWidth(false)
, m_hSpacing(0)
, m_vSpacing(0)
, m_borderStart(0)
, m_needsSectionRecalc(false)
, m_columnLogicalWidthChanged(false)
, m_columnRenderersValid(false)
+ , m_hasCellColspanThatDeterminesTableWidth(false)
, m_hSpacing(0)
, m_vSpacing(0)
, m_borderStart(0)
unsigned newColumnIndex = m_columns.size();
m_columns.append(ColumnStruct(span));
+ // Unless the table has cell(s) with colspan that exceed the number of columns afforded
+ // by the other rows in the table we can use the fast path when mapping columns to effective columns.
+ m_hasCellColspanThatDeterminesTableWidth = m_hasCellColspanThatDeterminesTableWidth || span > 1;
+
// Propagate the change in our columns representation to the sections that don't need
// cell recalc. If they do, they will be synced up directly with m_columns later.
for (auto& section : childrenOfType<RenderTableSection>(*this)) {
m_foot = 0;
m_firstBody = 0;
m_hasColElements = false;
+ m_hasCellColspanThatDeterminesTableWidth = hasCellColspanThatDeterminesTableWidth();
// We need to get valid pointers to caption, head, foot and first body again
RenderObject* nextSibling;
unsigned colToEffCol(unsigned column) const
{
+ if (!m_hasCellColspanThatDeterminesTableWidth)
+ return column;
+
unsigned effColumn = 0;
unsigned numColumns = numEffCols();
for (unsigned c = 0; effColumn < numColumns && c + m_columns[effColumn].span - 1 < column; ++effColumn)
unsigned effColToCol(unsigned effCol) const
{
+ if (!m_hasCellColspanThatDeterminesTableWidth)
+ return effCol;
+
unsigned c = 0;
for (unsigned i = 0; i < effCol; i++)
c += m_columns[i].span;
bool m_columnLogicalWidthChanged : 1;
mutable bool m_columnRenderersValid: 1;
+ mutable bool m_hasCellColspanThatDeterminesTableWidth : 1;
+
+ bool hasCellColspanThatDeterminesTableWidth() const
+ {
+ for (unsigned c = 0; c < numEffCols(); c++) {
+ if (m_columns[c].span > 1)
+ return true;
+ }
+ return false;
+ }
short m_hSpacing;
short m_vSpacing;