From c5609a9247b965ea57db98607ad498a216e179d6 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Thu, 15 Oct 2009 15:25:03 -0300 Subject: QGAL: Add anchor layout vs nested linear layouts benchmark Adding a benchmark to compare the use of three nested linear layouts versus the use of a single anchor layout. We also test two different anchor layout setups to achieve the same visual result. In the first one we use the addCornerAnchors API that, in the way it was used, adds reduntant anchors. The second uses the basic addAnchor API to create only the essential anchors. Currently the first setup is way slower than the second. That happens because the redundant anchors create "zero-sized knots" in the graph, that are not eaten by the simplification algorithm, thus requiring the usage of the simplex solver. Zero-sized knots are groups of three or more vertices that are linked together by zero-sized anchors. In pratice, these vertices represent the same place in the graph (remember, the distance between them is zero), but to the simplification mechanism, they look like three distinct ones. Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- .../tst_qgraphicsanchorlayout.cpp | 111 +++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 000ab6e..43dff93 100644 --- a/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -41,6 +41,7 @@ #include #include +#include #include #include @@ -54,6 +55,9 @@ public: private slots: void s60_hard_complex_data(); void s60_hard_complex(); + void linearVsAnchorNested_data(); + void linearVsAnchorNested(); + }; @@ -192,6 +196,113 @@ void tst_QGraphicsAnchorLayout::s60_hard_complex() } } +void tst_QGraphicsAnchorLayout::linearVsAnchorNested_data() +{ + QTest::addColumn("whichLayout"); + QTest::newRow("LinearLayout") + << 0; + QTest::newRow("AnchorLayout setup with null-anchors knot") + << 1; + QTest::newRow("AnchorLayout setup easy to simplificate") + << 2; +} + +void tst_QGraphicsAnchorLayout::linearVsAnchorNested() +{ + QFETCH(int, whichLayout); + + QSizeF min(10, 10); + QSizeF pref(80, 80); + QSizeF max(150, 150); + + QGraphicsWidget *a = createItem(min, pref, max, "a"); + QGraphicsWidget *b = createItem(min, pref, max, "b"); + QGraphicsWidget *c = createItem(min, pref, max, "c"); + QGraphicsWidget *d = createItem(min, pref, max, "d"); + + QGraphicsLayout *layout; + + if (whichLayout == 0) { + QGraphicsLinearLayout *linear1 = new QGraphicsLinearLayout; + QGraphicsLinearLayout *linear2 = new QGraphicsLinearLayout(Qt::Vertical); + QGraphicsLinearLayout *linear3 = new QGraphicsLinearLayout; + + linear1->addItem(a); + linear1->addItem(linear2); + linear2->addItem(b); + linear2->addItem(linear3); + linear3->addItem(c); + linear3->addItem(d); + + layout = linear1; + } else if (whichLayout == 1) { + QGraphicsAnchorLayout *anchor = new QGraphicsAnchorLayout; + + // A + anchor->addCornerAnchors(a, Qt::TopLeftCorner, anchor, Qt::TopLeftCorner); + anchor->addCornerAnchors(a, Qt::TopRightCorner, b, Qt::TopLeftCorner); + anchor->addCornerAnchors(a, Qt::BottomLeftCorner, anchor, Qt::BottomLeftCorner); + anchor->addCornerAnchors(a, Qt::BottomRightCorner, c, Qt::BottomLeftCorner); + + // B + anchor->addCornerAnchors(b, Qt::TopRightCorner, anchor, Qt::TopRightCorner); + anchor->addCornerAnchors(b, Qt::BottomLeftCorner, c, Qt::TopLeftCorner); + anchor->addCornerAnchors(b, Qt::BottomRightCorner, d, Qt::TopRightCorner); + + // C + anchor->addCornerAnchors(c, Qt::TopRightCorner, d, Qt::TopLeftCorner); + anchor->addCornerAnchors(c, Qt::BottomRightCorner, d, Qt::BottomLeftCorner); + + // D + anchor->addCornerAnchors(d, Qt::BottomRightCorner, anchor, Qt::BottomRightCorner); + + layout = anchor; + } else { + QGraphicsAnchorLayout *anchor = new QGraphicsAnchorLayout; + + // A + anchor->addAnchor(a, Qt::AnchorLeft, anchor, Qt::AnchorLeft); + anchor->addAnchors(a, anchor, Qt::Vertical); + anchor->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft); + anchor->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft); + + // B + anchor->addAnchor(b, Qt::AnchorTop, anchor, Qt::AnchorTop); + anchor->addAnchor(b, Qt::AnchorRight, anchor, Qt::AnchorRight); + anchor->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop); + anchor->addAnchor(b, Qt::AnchorBottom, d, Qt::AnchorTop); + + // C + anchor->addAnchor(c, Qt::AnchorRight, d, Qt::AnchorLeft); + anchor->addAnchor(c, Qt::AnchorBottom, anchor, Qt::AnchorBottom); + + // D + anchor->addAnchor(d, Qt::AnchorRight, anchor, Qt::AnchorRight); + anchor->addAnchor(d, Qt::AnchorBottom, anchor, Qt::AnchorBottom); + + layout = anchor; + } + + QSizeF sizeHint; + // warm up instruction cache + layout->invalidate(); + sizeHint = layout->effectiveSizeHint(Qt::PreferredSize); + + // ...then measure... + QBENCHMARK { + // To ensure that all sizeHints caches are invalidated in + // the LinearLayout setup, we must call updateGeometry on the + // children. If we didn't, only the top level layout would be + // re-calculated. + static_cast(a)->updateGeometry(); + static_cast(b)->updateGeometry(); + static_cast(c)->updateGeometry(); + static_cast(d)->updateGeometry(); + layout->invalidate(); + sizeHint = layout->effectiveSizeHint(Qt::PreferredSize); + } +} + QTEST_MAIN(tst_QGraphicsAnchorLayout) #include "tst_qgraphicsanchorlayout.moc" -- cgit v0.12