VirtualBox

Changeset 108410 in vbox


Ignore:
Timestamp:
Feb 27, 2025 11:14:17 AM (7 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167778
Message:

FE/Qt: bugref:10450: Runtime UI: Fixing fractional scaling issue introduced with Qt6; Caching smallest dpr denominator to avoid calculating it on every paint call; So that on paint calls we are rounding rectangles to nearest denominator up or down if necessary and that's it.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.cpp

    r108394 r108410  
    144144    double devicePixelRatio() const { return m_dDevicePixelRatio; }
    145145    /** Defines device-pixel-ratio set for HiDPI frame-buffer. */
    146     void setDevicePixelRatio(double dDevicePixelRatio) { m_dDevicePixelRatio = dDevicePixelRatio; }
     146    void setDevicePixelRatio(double dDevicePixelRatio);
     147
     148    /** Returns smallest device-pixel-ratio denominator. */
     149    int smallestDenominator() const { return m_iSmallestDenominator; }
    147150
    148151    /** Returns whether frame-buffer should use unscaled HiDPI output. */
     
    289292    /** Finds greatest common divisor for @a a and @a b. */
    290293    static int greatestCommonDivisor(int a, int b);
    291     /** Finds multiple of @a fScaleFactor which is @a fLarger than @a iNumber. */
    292     static int findMultipleOfScaleFactor(double fScaleFactor, int iNumber, bool fLarger);
     294    /** Rounds passed iNumber up to @a iNearest @a fUp. */
     295    static int roundNumberUpToNearest(int iNumber, int iNearest, bool fUp);
    293296
    294297    /** Holds the screen-id. */
     
    360363    /** Holds device-pixel-ratio set for HiDPI frame-buffer. */
    361364    double  m_dDevicePixelRatio;
     365    /** Holds the smallest device-pixel-ratio denominator. */
     366    int     m_iSmallestDenominator;
    362367    /** Holds whether frame-buffer should use unscaled HiDPI output. */
    363368    bool    m_fUseUnscaledHiDPIOutput;
     
    394399    , m_enmScalingOptimizationType(ScalingOptimizationType_None)
    395400    , m_dDevicePixelRatio(1.0)
     401    , m_iSmallestDenominator(-1)
    396402    , m_fUseUnscaledHiDPIOutput(false)
    397403{
     
    488494    m_fUnused = fUnused;
    489495    unlock();
     496}
     497
     498void UIFrameBufferPrivate::setDevicePixelRatio(double dDevicePixelRatio)
     499{
     500    /* Make sure something changed: */
     501    if (devicePixelRatio() == dDevicePixelRatio)
     502        return;
     503
     504    /* Cache device-pixel-ratio (dpr): */
     505    m_dDevicePixelRatio = dDevicePixelRatio;
     506
     507    /* For 100% host OS scale-factor we don't need denominator: */
     508    if (devicePixelRatio() == 1.0)
     509        m_iSmallestDenominator = -1;
     510    else
     511    {
     512        /* Recalculate smallest dpr denominator: */
     513        const int iDenominator = 100; // precision, cause scale-factor is percentage
     514        const int iNumerator = static_cast<int>(devicePixelRatio() * iDenominator);
     515        const int iGreatestCommonDivisor = greatestCommonDivisor(iNumerator, iDenominator);
     516        /* We need smallest denominator after all: */
     517        m_iSmallestDenominator = iDenominator / iGreatestCommonDivisor;
     518    }
     519    //printf("m_iSmallestDenominator = %d\n", m_iSmallestDenominator);
    490520}
    491521
     
    12731303    QRect paintRect = pEvent->rect();
    12741304    /* Adjust original rectangle the way that it can be fractionally upscaled to int values: */
    1275     if (devicePixelRatio() != 1.0)
    1276     {
    1277         paintRect.setLeft(findMultipleOfScaleFactor(devicePixelRatio(), paintRect.left(), false));
    1278         paintRect.setTop(findMultipleOfScaleFactor(devicePixelRatio(), paintRect.top(), false));
    1279         paintRect.setWidth(findMultipleOfScaleFactor(devicePixelRatio(), paintRect.width(), true));
    1280         paintRect.setHeight(findMultipleOfScaleFactor(devicePixelRatio(), paintRect.height(), true));
     1305    if (smallestDenominator() != -1)
     1306    {
     1307        paintRect.setLeft(roundNumberUpToNearest(paintRect.left(), smallestDenominator(), false /* up */));
     1308        paintRect.setTop(roundNumberUpToNearest(paintRect.top(), smallestDenominator(), false /* up */));
     1309        paintRect.setWidth(roundNumberUpToNearest(paintRect.width(), smallestDenominator(), true /* up */));
     1310        paintRect.setHeight(roundNumberUpToNearest(paintRect.height(), smallestDenominator(), true /* up */));
    12811311    }
    12821312    QRect paintRectHiDPI = paintRect;
     
    14521482
    14531483/* static */
    1454 int UIFrameBufferPrivate::findMultipleOfScaleFactor(double fScaleFactor, int iNumber, bool fLarger)
    1455 {
    1456     /* Approximate scale-factor as a fraction: */
    1457     int iDenominator = 100; // precision, scale-factor is percentage
    1458     int iNumerator = static_cast<int>(fScaleFactor * iDenominator);
    1459     int iCommonDivisor = greatestCommonDivisor(iNumerator, iDenominator);
    1460     /* We need smallest denominator after all: */
    1461     iDenominator /= iCommonDivisor;
    1462 
    1463     /* Find the largest/smallest multiple
    1464      * of the denominator <=/>= iNumber: */
    1465     int iResult = (iNumber / iDenominator) * iDenominator;
    1466     /* Append denominator if requested: */
    1467     if (fLarger && iResult < iNumber)
    1468         iResult += iDenominator;
     1484int UIFrameBufferPrivate::roundNumberUpToNearest(int iNumber, int iNearest, bool fUp)
     1485{
     1486    /* Round passed iNumber up to iNearest: */
     1487    int iResult = (iNumber / iNearest) * iNearest;
     1488    /* Append iNearest if requested: */
     1489    if (fUp && iResult < iNumber)
     1490        iResult += iNearest;
    14691491    return iResult;
    14701492}
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette