Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-66677

QPainterPath::addPolygon(): forces a re-allocation on every call

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P2: Important
    • Resolution: Done
    • Affects Version/s: 5.9.4, 5.10.1
    • Fix Version/s: None
    • Component/s: GUI: Painting
    • Labels:

      Description

      Hello,

      We noticed that using nice convenience methods to build up QPainterPath takes an unproportionally long time when the number of shapes grows, making them practically unusable for drawing some complex paths. Going back to basic QPainterPath::lineTo() and QPainterPath::moveTo() fixes the issue.

      According to the source [1], the issue is likely that code forces the underlying vector to allocate exact number of elements as it would be after the addition of a shape, and that destroys the vector's exponential re-allocation strategy.

      The similar issue is likely present also for QPainterPath::addRegion(), QPainterPath::addEllipse(), QPainterPath::addRect() and QPainterPath::addRegion().

      A test case is attached for QPainterPath::addPolygon(). On Linux, executing run.sh prints the following:

      ./run.sh 
       + cmake .
       - Configuring done
       - Generating done
       - Build files have been written to: [...]
       + make
       [ 25%] Automatic moc for target aexe
       [ 25%] Built target aexe_automoc
       [100%] Built target aexe
       + echo '--- built-in ---'
       — built-in —
       + ./aexe builtin 5000
      real 0m0,260s
       user 0m0,068s
       sys 0m0,188s
       + ./aexe builtin 10000
      real 0m1,001s
       user 0m0,236s
       sys 0m0,764s
       + ./aexe builtin 20000
      real 0m4,395s
       user 0m1,196s
       sys 0m3,196s
       + echo '--- workaround ---'
       — workaround —
       + ./aexe workaround 5000
      real 0m0,006s
       user 0m0,008s
       sys 0m0,000s
       + ./aexe workaround 10000
      real 0m0,007s
       user 0m0,000s
       sys 0m0,004s
       + ./aexe workaround 20000
      real 0m0,010s
       user 0m0,004s
       sys 0m0,004s
       + ./aexe workaround 10000000
      real 0m3,072s
       user 0m2,268s
       sys 0m0,800s
      

      We can see that, when adding thousands of polygons using the built-in method, the time grows quadractically. It makes a dramatic difference when adding many polygons to a single QPainterPath - adding 10 million polygons is faster using the workaround than adding 20 thousand polygons using the built-in method.

       [1]https://code.qt.io/cgit/qt/qtbase.git/tree/src/gui/painting/qpainterpath.cpp#n1074

        Attachments

          Issue Links

          For Gerrit Dashboard: QTBUG-66677
          # Subject Branch Project Status CR V

            Activity

              People

              Assignee:
              vgt Eirik Aavitsland
              Reporter:
              jive Ievgen Liubymkin
              Votes:
              1 Vote for this issue
              Watchers:
              6 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:

                  Gerrit Reviews

                  There are no open Gerrit changes