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

QT_SCALE_FACTOR_ROUNDING_POLICY=PassThrough sometimes causes 1 pixel missmatch between painted area and flushed area.

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • 5.15.1
    • 5.14.0
    • GUI: High-DPI
    • Visual Studio v16.4.5
    • Windows
    • b4aee30692c166025b4e2283c19dbc1247bcce54 (qt/qtbase/dev) 5de4b9b1e5eb1ae8d922ee96d88eb6bba05b2b45 (qt/qtbase/5.15)

    Description

      This is a separation of one of the issues in QTBUG-80228.

      As you can see in the gif by pklaffert, the off by one artifacts are not completely consistent. I managed to figure out where it goes wrong but not quite why:

       

      Using this rectangle as a test case:

      { x = 1, y = 1, width = 773, height = 510 } 

      With the scaling value 1.5.

       

      When running QBackingStore::beginPaint we transform the paint region with QHighDpi::toNativeLocalRegion which rounds the scaled values to integers resulting in:

      { x = 2, y = 2, width = 1160, height = 765 }

      The width value was rounded up as per qRound policy 773 * 1.5 = 1159.5 -> 1160

       

      Later when setting the systemClip region in QPaintEngine::updateSystemClip the region is transformed again, but this time using QTransform::map which was updated recently to use the QRectF::toRect rounding. This however results in:

      { x = 2, y = 2, width = 1159, height = 765 }

      Stepping through the map calculation and this line:

      QRect nr = mapRect(QRectF(rect)).toRect();

      Everything looks good, until toRect retuns and suddenly width is 1159 instead of 1160 that the debugger showed me inside toRect... I would assume that I need to train my asm skills to actually understand whats going wrong here. Maybe it is a bug in msvc? Update: The natvis for QRect and that I forgot QRects width is -1 got me confused, its doing the correct thing, just differently than the highdpiscaling.

       

      To reduce the very glaring issues as seen in the gif, even though the painting is not always updating all pxels, I tried changing the highdpi QRect scaling method to use the same rounding through QRectF::toRect, see attached patch.

       

      Attachments

        1. example.cpp
          3 kB
        2. QTBUG-82601.diff
          0.6 kB
        3. scaling-issue.gif
          scaling-issue.gif
          750 kB

        Issue Links

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

          Activity

            People

              sorvig Morten Sørvig
              cyriuz Viktor Arvidsson
              Votes:
              5 Vote for this issue
              Watchers:
              11 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes