Ticket #13618: dpi8_master.diff

File dpi8_master.diff, 17.2 KB (added by Mark Kendall, 4 years ago)

Commit candidate - master/v32

  • mythtv/libs/libmythtv/mythvideoout.cpp

    diff --git a/mythtv/libs/libmythtv/mythvideoout.cpp b/mythtv/libs/libmythtv/mythvideoout.cpp
    index 8eb608b53e..79b408aaf0 100644
    a b void MythVideoOutput::InitDisplayMeasurements(void) 
    10191019        .arg(displayaspect).arg(source));
    10201020
    10211021    // Get the window and screen resolutions
    1022     QSize window = m_window.GetWindowRect().size();
     1022    QSize window = m_window.GetRawWindowRect().size();
    10231023    QSize screen = m_display->GetResolution();
    10241024
    10251025    // If not running fullscreen, adjust for window size and ignore any video
  • mythtv/libs/libmythtv/videooutwindow.cpp

    diff --git a/mythtv/libs/libmythtv/videooutwindow.cpp b/mythtv/libs/libmythtv/videooutwindow.cpp
    index cba4327174..8aca6995cb 100644
    a b  
    3838
    3939#define LOC QString("VideoWin: ")
    4040
     41#define SCALED_RECT(SRC, SCALE) QRect{ static_cast<int>(SRC.left()   * SCALE), \
     42                                       static_cast<int>(SRC.top()    * SCALE), \
     43                                       static_cast<int>(SRC.width()  * SCALE), \
     44                                       static_cast<int>(SRC.height() * SCALE) }
     45
    4146static float fix_aspect(float raw);
    4247static float snap(float value, float snapto, float diff);
    4348
    void VideoOutWindow::ScreenChanged(QScreen */*screen*/) 
    6267    MoveResize();
    6368}
    6469
     70void VideoOutWindow::PhysicalDPIChanged(qreal /*DPI*/)
     71{
     72    // PopulateGeometry will update m_devicePixelRatio
     73    PopulateGeometry();
     74    m_windowRect = m_displayVisibleRect = SCALED_RECT(m_rawWindowRect, m_devicePixelRatio);
     75    MoveResize();
     76}
     77
    6578void VideoOutWindow::PopulateGeometry(void)
    6679{
    6780    if (!m_display)
    void VideoOutWindow::PopulateGeometry(void) 
    7184    if (!screen)
    7285        return;
    7386
     87#ifdef Q_OS_MACOS
     88    m_devicePixelRatio = screen->devicePixelRatio();
     89#endif
     90
    7491    if (MythDisplay::SpanAllScreens() && MythDisplay::GetScreenCount() > 1)
    7592    {
    7693        m_screenGeometry = screen->virtualGeometry();
    bool VideoOutWindow::Init(const QSize &VideoDim, const QSize &VideoDispDim, 
    415432    {
    416433        m_display = Display;
    417434        connect(m_display, &MythDisplay::CurrentScreenChanged, this, &VideoOutWindow::ScreenChanged);
     435#ifdef Q_OS_MACOS
     436        connect(m_display, &MythDisplay::PhysicalDPIChanged,   this, &VideoOutWindow::PhysicalDPIChanged);
     437#endif
    418438    }
    419439
    420440    if (m_display)
    bool VideoOutWindow::Init(const QSize &VideoDim, const QSize &VideoDispDim, 
    428448
    429449    // N.B. we are always confined to the window size so use that for the initial
    430450    // displayVisibleRect
    431     m_windowRect = m_displayVisibleRect = WindowRect;
     451    m_rawWindowRect = WindowRect;
     452    m_windowRect = m_displayVisibleRect = SCALED_RECT(WindowRect, m_devicePixelRatio);
    432453
    433454    int pbp_width = m_displayVisibleRect.width() / 2;
    434455    if (m_pipState == kPBPLeft || m_pipState == kPBPRight)
    void VideoOutWindow::SetDisplayAspect(float DisplayAspect) 
    612633
    613634void VideoOutWindow::SetWindowSize(QSize Size)
    614635{
    615     if (Size != m_windowRect.size())
     636    if (Size != m_rawWindowRect.size())
    616637    {
    617         QRect rect(m_windowRect.topLeft(), Size);
     638        QRect rect(m_rawWindowRect.topLeft(), Size);
    618639        LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("New window rect: %1x%2+%3+%4")
    619640            .arg(rect.width()).arg(rect.height()).arg(rect.left()).arg(rect.top()));
    620         m_windowRect = m_displayVisibleRect = rect;
     641        m_rawWindowRect = rect;
     642        m_windowRect = m_displayVisibleRect = SCALED_RECT(rect, m_devicePixelRatio);
    621643        MoveResize();
    622644    }
    623645}
  • mythtv/libs/libmythtv/videooutwindow.h

    diff --git a/mythtv/libs/libmythtv/videooutwindow.h b/mythtv/libs/libmythtv/videooutwindow.h
    index b5e3ab579e..50ee9428cb 100644
    a b class VideoOutWindow : public QObject 
    4545
    4646  public slots:
    4747    void ScreenChanged          (QScreen *screen);
     48    void PhysicalDPIChanged     (qreal  /*DPI*/);
    4849
    4950    // Sets
    5051    void InputChanged           (const QSize &VideoDim, const QSize &VideoDispDim, float Aspect);
    class VideoOutWindow : public QObject 
    7475    float    GetOverridenVideoAspect(void) const { return m_videoAspectOverride;}
    7576    QRect    GetDisplayVisibleRect(void)   const { return m_displayVisibleRect; }
    7677    QRect    GetWindowRect(void)           const { return m_windowRect; }
     78    QRect    GetRawWindowRect(void)        const { return m_rawWindowRect; }
    7779    QRect    GetScreenGeometry(void)       const { return m_screenGeometry; }
    7880    QRect    GetVideoRect(void)            const { return m_videoRect; }
    7981    QRect    GetDisplayVideoRect(void)     const { return m_displayVideoRect; }
    class VideoOutWindow : public QObject 
    113115    bool    m_dbScalingAllowed {true};  ///< disable this to prevent overscan/underscan
    114116    bool    m_dbUseGUISize     {false}; ///< Use the gui size for video window
    115117    QRect   m_screenGeometry   {0,0,1024,768}; ///< Full screen geometry
     118    qreal   m_devicePixelRatio {1.0};
    116119
    117120    // Manual Zoom
    118121    float   m_manualVertScale  {1.0F}; ///< Manually applied vertical scaling.
    class VideoOutWindow : public QObject 
    145148    QRect   m_displayVisibleRect {0,0,0,0};
    146149    /// Rectangle describing QWidget bounds.
    147150    QRect   m_windowRect {0,0,0,0};
     151    /// Rectangle describing QWidget bounds - not adjusted for high DPI scaling (macos)
     152    QRect   m_rawWindowRect {0,0,0,0};
    148153    /// Used to save the display_visible_rect for
    149154    /// restoration after video embedding ends.
    150155    QRect   m_tmpDisplayVisibleRect {0,0,0,0};
  • mythtv/libs/libmythui/mythpainter.h

    diff --git a/mythtv/libs/libmythui/mythpainter.h b/mythtv/libs/libmythui/mythpainter.h
    index 5612456997..d7367fb877 100644
    a b class UIEffects; 
    2929using LayoutVector = QVector<QTextLayout *>;
    3030using FormatVector = QVector<QTextLayout::FormatRange>;
    3131
    32 class MUI_PUBLIC MythPainter
     32class MUI_PUBLIC MythPainter : public QObject
    3333{
     34    Q_OBJECT
     35
    3436  public:
    3537    MythPainter();
    3638    /** MythPainter destructor.
  • mythtv/libs/libmythui/opengl/mythpainteropengl.cpp

    diff --git a/mythtv/libs/libmythui/opengl/mythpainteropengl.cpp b/mythtv/libs/libmythui/opengl/mythpainteropengl.cpp
    index 01759fdc9d..fbaa601507 100644
    a b MythOpenGLPainter::MythOpenGLPainter(MythRenderOpenGL *Render, QWidget *Parent) 
    1919
    2020    if (!m_render)
    2121        LOG(VB_GENERAL, LOG_ERR, "OpenGL painter has no render device");
     22
     23#ifdef Q_OS_MACOS
     24     m_display = MythDisplay::AcquireRelease();
     25     CurrentDPIChanged(m_widget->devicePixelRatioF());
     26     connect(m_display, &MythDisplay::CurrentDPIChanged, this, &MythOpenGLPainter::CurrentDPIChanged);
     27#endif
    2228}
    2329
    2430MythOpenGLPainter::~MythOpenGLPainter()
    2531{
     32#ifdef Q_OS_MACOS
     33    MythDisplay::AcquireRelease(false);
     34#endif
     35
    2636    if (!m_render)
    2737        return;
    2838    if (!m_render->IsReady())
    void MythOpenGLPainter::ClearCache(void) 
    8595    m_imageToTextureMap.clear();
    8696}
    8797
     98void MythOpenGLPainter::CurrentDPIChanged(qreal DPI)
     99{
     100    m_pixelRatio = DPI;
     101    m_usingHighDPI = !qFuzzyCompare(m_pixelRatio, 1.0);
     102    LOG(VB_GENERAL, LOG_INFO, QString("High DPI scaling %1").arg(m_usingHighDPI ? "enabled" : "disabled"));
     103}
     104
    88105void MythOpenGLPainter::Begin(QPaintDevice *Parent)
    89106{
    90107    MythPainter::Begin(Parent);
    void MythOpenGLPainter::Begin(QPaintDevice *Parent) 
    110127            buf = m_render->CreateVBO(static_cast<int>(MythRenderOpenGL::kVertexSize));
    111128    }
    112129
     130    QSize currentsize = m_widget->size();
     131
    113132    // check if we need to adjust cache sizes
    114     if (m_lastSize != m_widget->size())
     133    // NOTE - don't use the scaled size if using high DPI. Our images are at the lower
     134    // resolution
     135    if (m_lastSize != currentsize)
    115136    {
    116137        // This will scale the cache depending on the resolution in use
    117138        static const int s_onehd = 1920 * 1080;
    118139        static const int s_basesize = 64;
    119         m_lastSize = m_widget->size();
     140        m_lastSize = currentsize;
    120141        float hdscreens = (static_cast<float>(m_lastSize.width() + 1) * m_lastSize.height()) / s_onehd;
    121142        int cpu = qMax(static_cast<int>(hdscreens * s_basesize), s_basesize);
    122143        int gpu = cpu * 3 / 2;
    void MythOpenGLPainter::Begin(QPaintDevice *Parent) 
    131152
    132153    if (m_target || m_swapControl)
    133154    {
     155        // If we are master and using high DPI then scale the viewport
     156        if (m_swapControl && m_usingHighDPI)
     157            currentsize *= m_pixelRatio;
    134158        m_render->BindFramebuffer(m_target);
    135         m_render->SetViewPort(QRect(0, 0, m_widget->width(), m_widget->height()));
     159        m_render->SetViewPort(QRect(0, 0, currentsize.width(), currentsize.height()));
    136160        m_render->SetBackground(0, 0, 0, 0);
    137161        m_render->ClearFramebuffer();
    138162    }
    MythGLTexture* MythOpenGLPainter::GetTextureFromCache(MythImage *Image) 
    222246    return texture;
    223247}
    224248
     249#ifdef Q_OS_MACOS
     250#define DEST dest
     251#else
     252#define DEST Dest
     253#endif
     254
    225255void MythOpenGLPainter::DrawImage(const QRect &Dest, MythImage *Image,
    226256                                  const QRect &Source, int Alpha)
    227257{
    228258    if (m_render)
    229259    {
    230         // Drawing an image  multiple times with the same VBO will stall most GPUs as
     260#ifdef Q_OS_MACOS
     261        QRect dest = QRect(static_cast<int>(Dest.left()   * m_pixelRatio),
     262                           static_cast<int>(Dest.top()    * m_pixelRatio),
     263                           static_cast<int>(Dest.width()  * m_pixelRatio),
     264                           static_cast<int>(Dest.height() * m_pixelRatio));
     265#endif
     266
     267        // Drawing an image multiple times with the same VBO will stall most GPUs as
    231268        // the VBO is re-mapped whilst still in use. Use a pooled VBO instead.
    232269        MythGLTexture *texture = GetTextureFromCache(Image);
    233270        if (texture && m_mappedTextures.contains(texture))
    void MythOpenGLPainter::DrawImage(const QRect &Dest, MythImage *Image, 
    235272            QOpenGLBuffer *vbo = texture->m_vbo;
    236273            texture->m_vbo = m_mappedBufferPool[m_mappedBufferPoolIdx];
    237274            texture->m_destination = QRect();
    238             m_render->DrawBitmap(texture, m_target, Source, Dest, nullptr, Alpha);
     275            m_render->DrawBitmap(texture, m_target, Source, DEST, nullptr, Alpha, m_pixelRatio);
    239276            texture->m_destination = QRect();
    240277            texture->m_vbo = vbo;
    241278            if (++m_mappedBufferPoolIdx >= MAX_BUFFER_POOL)
    void MythOpenGLPainter::DrawImage(const QRect &Dest, MythImage *Image, 
    243280        }
    244281        else
    245282        {
    246             m_render->DrawBitmap(texture, m_target, Source, Dest, nullptr, Alpha);
     283            m_render->DrawBitmap(texture, m_target, Source, DEST, nullptr, Alpha, m_pixelRatio);
    247284            m_mappedTextures.append(texture);
    248285        }
    249286    }
    250287}
    251288
     289/*! \brief Draw a rectangle
     290 *
     291 * If it is a simple rectangle, then use our own shaders for rendering (which
     292 * saves texture memory but may not be as accurate as Qt rendering) otherwise
     293 * fallback to Qt painting to a QImage, which is uploaded as a texture.
     294 *
     295 * \note If high DPI scaling is in use, just use Qt painting rather than
     296 * handling all of the adjustments required for pen width etc etc.
     297*/
    252298void MythOpenGLPainter::DrawRect(const QRect &Area, const QBrush &FillBrush,
    253299                                 const QPen &LinePen, int Alpha)
    254300{
    255301    if ((FillBrush.style() == Qt::SolidPattern ||
    256          FillBrush.style() == Qt::NoBrush) && m_render)
     302         FillBrush.style() == Qt::NoBrush) && m_render && !m_usingHighDPI)
    257303    {
    258304        m_render->DrawRect(m_target, Area, FillBrush, LinePen, Alpha);
    259305        return;
    void MythOpenGLPainter::DrawRoundRect(const QRect &Area, int CornerRadius, 
    266312                                      const QPen &LinePen, int Alpha)
    267313{
    268314    if ((FillBrush.style() == Qt::SolidPattern ||
    269          FillBrush.style() == Qt::NoBrush) && m_render)
     315         FillBrush.style() == Qt::NoBrush) && m_render && !m_usingHighDPI)
    270316    {
    271317        m_render->DrawRoundRect(m_target, Area, CornerRadius, FillBrush,
    272318                                  LinePen, Alpha);
  • mythtv/libs/libmythui/opengl/mythpainteropengl.h

    diff --git a/mythtv/libs/libmythui/opengl/mythpainteropengl.h b/mythtv/libs/libmythui/opengl/mythpainteropengl.h
    index e1cc830ca1..a633e107ca 100644
    a b  
    66#include <QQueue>
    77
    88// MythTV
     9#include "mythdisplay.h"
    910#include "mythpainter.h"
    1011#include "mythimage.h"
    1112
    class QOpenGLFramebufferObject; 
    2223
    2324class MUI_PUBLIC MythOpenGLPainter : public MythPainter
    2425{
     26    Q_OBJECT
     27
    2528  public:
    2629    explicit MythOpenGLPainter(MythRenderOpenGL *Render = nullptr, QWidget *Parent = nullptr);
    2730   ~MythOpenGLPainter() override;
    class MUI_PUBLIC MythOpenGLPainter : public MythPainter 
    4649    void PushTransformation(const UIEffects &Fx, QPointF Center = QPointF()) override;
    4750    void PopTransformation(void) override;
    4851
     52  public slots:
     53    void CurrentDPIChanged(qreal DPI);
     54
    4955  protected:
    5056    void  ClearCache(void);
    5157    MythGLTexture* GetTextureFromCache(MythImage *Image);
    class MUI_PUBLIC MythOpenGLPainter : public MythPainter 
    6066    QOpenGLFramebufferObject* m_target { nullptr };
    6167    bool              m_swapControl { true };
    6268    QSize             m_lastSize { };
     69    qreal             m_pixelRatio   { 1.0     };
     70    MythDisplay*      m_display      { nullptr };
     71    bool              m_usingHighDPI { false   };
    6372
    6473    QMap<MythImage *, MythGLTexture*> m_imageToTextureMap;
    6574    std::list<MythImage *>     m_ImageExpireList;
  • mythtv/libs/libmythui/opengl/mythrenderopengl.cpp

    diff --git a/mythtv/libs/libmythui/opengl/mythrenderopengl.cpp b/mythtv/libs/libmythui/opengl/mythrenderopengl.cpp
    index bd3891afd5..dbfb1c1c75 100644
    a b void MythRenderOpenGL::ClearFramebuffer(void) 
    802802
    803803void MythRenderOpenGL::DrawBitmap(MythGLTexture *Texture, QOpenGLFramebufferObject *Target,
    804804                                  const QRect &Source, const QRect &Destination,
    805                                   QOpenGLShaderProgram *Program, int Alpha)
     805                                  QOpenGLShaderProgram *Program, int Alpha, qreal Scale)
    806806{
    807807    makeCurrent();
    808808
    void MythRenderOpenGL::DrawBitmap(MythGLTexture *Texture, QOpenGLFramebufferObje 
    825825
    826826    QOpenGLBuffer* buffer = Texture->m_vbo;
    827827    buffer->bind();
    828     if (UpdateTextureVertices(Texture, Source, Destination, 0))
     828    if (UpdateTextureVertices(Texture, Source, Destination, 0, Scale))
    829829    {
    830830        if (m_extraFeaturesUsed & kGLBufferMap)
    831831        {
    QStringList MythRenderOpenGL::GetDescription(void) 
    12601260}
    12611261
    12621262bool MythRenderOpenGL::UpdateTextureVertices(MythGLTexture *Texture, const QRect &Source,
    1263                                              const QRect &Destination, int Rotation)
     1263                                             const QRect &Destination, int Rotation, qreal Scale)
    12641264{
    12651265    if (!Texture || (Texture && Texture->m_size.isEmpty()))
    12661266        return false;
    bool MythRenderOpenGL::UpdateTextureVertices(MythGLTexture *Texture, const QRect 
    12991299    data[4 + TEX_OFFSET] = data[6 + TEX_OFFSET];
    13001300    data[5 + TEX_OFFSET] = data[1 + TEX_OFFSET];
    13011301
    1302     width  = Texture->m_crop ? min(width, Destination.width())   : Destination.width();
    1303     height = Texture->m_crop ? min(height, Destination.height()) : Destination.height();
     1302    width  = Texture->m_crop ? min(static_cast<int>(width * Scale), Destination.width())   : Destination.width();
     1303    height = Texture->m_crop ? min(static_cast<int>(height * Scale), Destination.height()) : Destination.height();
    13041304
    13051305    data[2] = data[0] = Destination.left();
    13061306    data[5] = data[1] = Destination.top();
  • mythtv/libs/libmythui/opengl/mythrenderopengl.h

    diff --git a/mythtv/libs/libmythui/opengl/mythrenderopengl.h b/mythtv/libs/libmythui/opengl/mythrenderopengl.h
    index 199f0d642b..2ccb9a60d5 100644
    a b class MUI_PUBLIC MythRenderOpenGL : public QOpenGLContext, public QOpenGLFunctio 
    143143
    144144    void  DrawBitmap(MythGLTexture *Texture, QOpenGLFramebufferObject *Target,
    145145                     const QRect &Source, const QRect &Destination,
    146                      QOpenGLShaderProgram *Program, int Alpha = 255);
     146                     QOpenGLShaderProgram *Program, int Alpha = 255, qreal Scale = 1.0);
    147147    void  DrawBitmap(MythGLTexture **Textures, uint TextureCount,
    148148                     QOpenGLFramebufferObject *Target,
    149149                     const QRect &Source, const QRect &Destination,
    class MUI_PUBLIC MythRenderOpenGL : public QOpenGLContext, public QOpenGLFunctio 
    171171    void  SetMatrixView(void);
    172172    void  DeleteFramebuffers(void);
    173173    static bool UpdateTextureVertices(MythGLTexture *Texture, const QRect &Source,
    174                                       const QRect &Destination, int Rotation);
     174                                      const QRect &Destination, int Rotation, qreal Scale = 1.0);
    175175    GLfloat* GetCachedVertices(GLuint Type, const QRect &Area);
    176176    void  ExpireVertices(int Max = 0);
    177177    void  GetCachedVBO(GLuint Type, const QRect &Area);