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

QScreen class does not support properly iPhone 6S Plus

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P2: Important
    • Resolution: Done
    • Affects Version/s: 5.6.0 Beta, 5.6.0 RC, 5.6.0
    • Fix Version/s: None
    • Labels:
      None
    • Environment:
      Qt 5.6.0, iPhone 6S Plus
    • Platform/s:
      iOS/tvOS/watchOS
    • Commits:
      8badbd5040fd41ad258d90edacb7b28b9a0ef870

      Description

      In iOS all the units are provided in points, what is fine. The problems appear when you're working with devices on which Apple does some additional transformation (downsampling\upsampling), currently these are iPhone 6 (only in Display Zoom mode) and iPhone 6 Plus.
      Look at this scheme: http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions
      I'm talking now about that Rendered Pixels -> Physical Pixels step.

      Simple example:
      1) Use Qt 5.6.0 Beta (high dpi is not supported properly in 5.5.1)
      2) Create a rectangle in QML and set it's width and height to 50 * Screen.pixelDensity (so you make it have physical size of 5cm in both directions)
      3) Run the app on iPhone 6S Plus and use ruler to measure the physical size of displayed rectangle, it will be less than 5cm.
      4) If you run it on any Android smartphone you will see that it's geometry is 5cm sharp.

      Now if you multiply the width and height by 1.15 (if you use iPhone 6s Plus and Display Zoom mode is off), you will see that at this time it works as it should.

      More complicated (and real) example is when you are using dp in your calculations like this:

      property real dp: Screen.pixelDensity * 25.4 / 160

      Now, this will work fine on any Android smartphone, iPhone 3G/3GS/4/4S/5/5S/6, but on iPhone 6S with enabled Display Zoom mode or iPhone 6S Plus you'll get the wrong result. I hope it's clear for you now why it's happening: Qt provides us the resolution in points, let's say it is 414 for width. Also we have devicePixelRatio, which is 3. Then 414 * 3 = 1242, but the real width of iPhone 6S plus in pixels is 1080. 1242 / 1080 = 1.15. Voila.

      The possible solution:
      I checked the interface of QScreen class, there's nothing currently gives us the real pixel size of iOS device (all values are provided in point units). So, I guess, we have not that many options. I'd add a new property which would expose the value of that transformation to Qt/QML. I checked iOS API, UIScreen class provides the real size of iPhone in pixels by nativeBounds property, so the expression would be like

      return [UIScreen mainScreen].fixedCoordinateSpace.bounds.size.width * [[UIScreen mainScreen] scale] / [[UIScreen mainScreen] nativeBounds].size.width;

      (this is the first Objective C code I've written)

      It is important, because using of dp units is a very common approach for mobile apps.

      Here are some useful articles if you are not familiar with all these calculations:
      > Dot vs Pixel: https://99designs.com/designer-blog/2013/02/26/ppi-vs-dpi-whats-the-difference/
      > DP: http://developer.android.com/guide/practices/screens_support.html
      > iPhone resolutions: http://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions

      03/11/2016 UPDATE:
      I just found that it's even more serious than I thought. QScreen returns wrong physical size with the same error as this transformation in 5.6 Release Candidate!

      Sample code:

      QQuickWindow window = qobject_cast<QQuickWindow>(engine.rootObjects().first());
      qDebug() << window->screen()->physicalSize();

      Here are results of the test I've done oniPhone 6S Plus:

      Display zoom off: QSizeF(78.6703, 139.858)
      Display zoom on: QSizeF(71.2594, 126.747)

      The real physical size of iPhone 6S Plus screen is about 69x122mm (I just measured it with a ruler). Now, again:
      69 * 1.15 = 79.35
      122 * 1.15 = 140.3

      69 / 0.96 = 81.875
      122 / 0.96 = 127.08

      See also https://github.com/qtproject/qtbase/blob/dev/src/plugins/platforms/ios/qiosscreen.mm#L263

      So, resuming, there are two things need to be done:
      1) Add a new property which would expose the coefficient of downsampling/upsampling transformation on iPhone 6S Plus and it would return 1.0 on any other platform/device (see the expression above);
      2) The result of physicalSize() method needs to be multiplied by that new property.

        Attachments

          Issue Links

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

            Activity

              People

              Assignee:
              vestbo Tor Arne Vestbø
              Reporter:
              olegyadrov Oleg
              Votes:
              2 Vote for this issue
              Watchers:
              10 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:

                  Gerrit Reviews

                  There are no open Gerrit changes