Skip to content

Commit

Permalink
globalsettings: Add back a 'Paint engine' setting
Browse files Browse the repository at this point in the history
- needed again to select Vulkan or OpenGL
- the Qt painter is never presented as an option but can be selected via
the command line again to try and get an app working (e.g. mythfrontend
-O PaintEngine=Qt) when there are OpenGL/Vulkan problems
- the setting is not displayed if there is no choice to be made (i.e.
vulkan support is not currently compiled in by default - so only OpenGL
will be available - so no setting is presented)
- the setting name is PaintEngine (the old ThemePainter setting will
likely have a value of 'auto' which is no longer supported) and avoids
hardcoded a workaround or performing a DB updateButton
- the code now builds a list of possible painters to try - with Qt as
the last option (unless overriden). This allows for better future
expansion.
  • Loading branch information
mark-kendall committed Aug 28, 2020
1 parent c6af3b7 commit ccf15e7
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 34 deletions.
124 changes: 95 additions & 29 deletions mythtv/libs/libmythui/mythpainterwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,111 @@
#include "vulkan/mythpaintervulkan.h"
#endif

QString MythPainterWindow::CreatePainters(MythMainWindow *MainWindow,
#define MYTH_PAINTER_QT QString("Qt")

using TryPainter = bool(*)(MythMainWindow*, MythPainterWindow*&, MythPainter*&, bool&);

QString MythPainterWindow::GetDefaultPainter()
{
#ifdef USING_OPENGL
return MYTH_PAINTER_OPENGL;
#elif USING_VULKAN
return MYTH_PAINTER_VULKAN;
#else
return MYTH_PAINTER_QT;
#endif
}

const QStringList MythPainterWindow::GetPainters()
{
QStringList result;
#ifdef USING_OPENGL
result.append(MYTH_PAINTER_OPENGL);
#endif
#ifdef USING_VULKAN
result.append(MYTH_PAINTER_VULKAN);
#endif
return result;
}

QString MythPainterWindow::CreatePainters(MythMainWindow *MainWin,
MythPainterWindow *&PaintWin,
MythPainter *&Painter)
MythPainter *&Paint)
{
bool warn = false;
QString painter = GetMythDB()->GetSetting("PaintEngine", GetDefaultPainter());

#ifdef USING_VULKAN
auto *vulkan = new MythPainterWindowVulkan(MainWindow);
if (vulkan && vulkan->IsValid())
// build a prioritised list of painters to try
QVector<TryPainter> painterstotry;

#ifdef USING_OPENGL
auto TryOpenGL = [](MythMainWindow *MainWindow, MythPainterWindow *&PaintWindow,
MythPainter *&Painter, bool&)
{
PaintWin = vulkan;
auto *render = dynamic_cast<MythRenderVulkan*>(vulkan->GetRenderDevice());
auto *window = dynamic_cast<MythWindowVulkan*>(vulkan->GetVulkanWindow());
Painter = new MythPainterVulkan(render, window);
return QString();
}
delete vulkan;
auto* glwindow = new MythPainterWindowOpenGL(MainWindow);
if (glwindow && glwindow->IsValid())
{
PaintWindow = glwindow;
auto *render = dynamic_cast<MythRenderOpenGL*>(glwindow->GetRenderDevice());
Painter = new MythOpenGLPainter(render, MainWindow);
return true;
}
delete glwindow;
return false;
};

if (painter.contains(MYTH_PAINTER_OPENGL, Qt::CaseInsensitive))
painterstotry.prepend(TryOpenGL);
else
painterstotry.append(TryOpenGL);
#endif

// only OpenGL provides video playback
#ifdef USING_OPENGL
auto* glwindow = new MythPainterWindowOpenGL(MainWindow);
if (glwindow && glwindow->IsValid())
#ifdef USING_VULKAN
auto TryVulkan = [](MythMainWindow *MainWindow, MythPainterWindow *&PaintWindow,
MythPainter *&Painter, bool&)
{
PaintWin = glwindow;
auto *render = dynamic_cast<MythRenderOpenGL*>(glwindow->GetRenderDevice());
Painter = new MythOpenGLPainter(render, MainWindow);
return QString();
}
delete glwindow;
auto *vulkan = new MythPainterWindowVulkan(MainWindow);
if (vulkan && vulkan->IsValid())
{
PaintWindow = vulkan;
auto *render = dynamic_cast<MythRenderVulkan*>(vulkan->GetRenderDevice());
auto *window = dynamic_cast<MythWindowVulkan*>(vulkan->GetVulkanWindow());
Painter = new MythPainterVulkan(render, window);
return true;
}
delete vulkan;
return false;
};

if (painter.contains(MYTH_PAINTER_VULKAN, Qt::CaseInsensitive))
painterstotry.prepend(TryVulkan);
else
painterstotry.append(TryVulkan);
#endif

// Fallback to Qt painter as the last resort.
LOG(VB_GENERAL, LOG_INFO, "Using the Qt painter. Video playback will not work!");
Painter = new MythQtPainter();
PaintWin = new MythPainterWindowQt(MainWindow);
warn = QCoreApplication::applicationName() == MYTH_APPNAME_MYTHFRONTEND;
auto TryQt = [](MythMainWindow *MainWindow, MythPainterWindow *&PaintWindow,
MythPainter *&Painter, bool& Warn)
{
LOG(VB_GENERAL, LOG_INFO, "Using the Qt painter. Video playback will not work!");
Painter = new MythQtPainter();
PaintWindow = new MythPainterWindowQt(MainWindow);
Warn = QCoreApplication::applicationName() == MYTH_APPNAME_MYTHFRONTEND;
return true;
};

// N.B. this won't be selectable as a painter in the UI but can be forced
// from the command line again (-O ThemePainter=Qt)
if (painter.contains(MYTH_PAINTER_QT, Qt::CaseInsensitive))
painterstotry.prepend(TryQt);
else
painterstotry.append(TryQt);

for (auto & trypainter : painterstotry)
if (trypainter(MainWin, PaintWin, Paint, warn))
break;

return warn ? tr("Warning: OpenGL is not available.") : QString();
return warn ? tr("Warning: No GPU acceleration") : QString();
}

void MythPainterWindow::DestroyPainters(MythPainterWindow *&PaintWin, MythPainter *&Painter)
Expand All @@ -69,12 +135,12 @@ MythPainterWindow::MythPainterWindow(MythMainWindow *MainWin)
{
}

MythRender* MythPainterWindow::GetRenderDevice(void)
MythRender* MythPainterWindow::GetRenderDevice()
{
return m_render;
}

bool MythPainterWindow::RenderIsShared(void)
bool MythPainterWindow::RenderIsShared()
{
return m_render && m_render->IsShared();
}
13 changes: 8 additions & 5 deletions mythtv/libs/libmythui/mythpainterwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <QWidget>

// MythTV
#include "mythuiexp.h"
#include "mythrender_base.h"

class MythMainWindow;
Expand All @@ -13,17 +14,19 @@ class MythPainter;
class MythPainterWindow : public QWidget
{
public:
static QString CreatePainters(MythMainWindow* MainWindow,
static MUI_PUBLIC QString GetDefaultPainter();
static MUI_PUBLIC const QStringList GetPainters();
static QString CreatePainters(MythMainWindow* MainWin,
MythPainterWindow*& PaintWin,
MythPainter*& Painter);
MythPainter*& Paint);
static void DestroyPainters(MythPainterWindow*& PaintWin,
MythPainter*& Painter);

MythRender* GetRenderDevice(void);
bool RenderIsShared (void);
MythRender* GetRenderDevice();
bool RenderIsShared ();

protected:
explicit MythPainterWindow(MythMainWindow *MainWin);
explicit MythPainterWindow(MythMainWindow* MainWin);
~MythPainterWindow() override = default;

MythRender* m_render { nullptr };
Expand Down
2 changes: 2 additions & 0 deletions mythtv/libs/libmythui/opengl/mythpainterwindowopengl.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

class MythMainWindow;

#define MYTH_PAINTER_OPENGL QString("OpenGL")

class MythPainterWindowOpenGL : public MythPainterWindow
{
Q_OBJECT
Expand Down
2 changes: 2 additions & 0 deletions mythtv/libs/libmythui/vulkan/mythpainterwindowvulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
class QVulkanInstance;
class MythWindowVulkan;

#define MYTH_PAINTER_VULKAN QString("Vulkan")

class MythPainterWindowVulkan : public MythPainterWindow
{
public:
Expand Down
24 changes: 24 additions & 0 deletions mythtv/programs/mythfrontend/globalsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "decoders/mythvaapicontext.h"
#endif
#include "mythpower.h"
#include "mythpainterwindow.h"

//Use for playBackGroup, to be remove at one point
#include "playgroup.h"
Expand Down Expand Up @@ -1468,6 +1469,28 @@ static HostCheckBoxSetting *FFRewReverse()
return gc;
}

static void AddPaintEngine(GroupSetting* Group)
{
if (!Group)
return;

const QStringList options = MythPainterWindow::GetPainters();

// Don't show an option if there is no choice. Do not offer Qt painter (but
// MythPainterWindow will accept 'Qt' if overriden from the command line)
if (options.size() <= 1)
return;

QString pref = GetMythDB()->GetSetting("PaintEngine", MythPainterWindow::GetDefaultPainter());
HostComboBoxSetting* paint = new HostComboBoxSetting("PaintEngine");
paint->setLabel(AppearanceSettings::tr("Paint engine"));
for (auto & option : options)
paint->addSelection(option, option, option == pref);

paint->setHelpText(AppearanceSettings::tr("This selects what MythTV uses to draw. "));
Group->addChild(paint);
}

static HostComboBoxSetting *MenuTheme()
{
auto *gc = new HostComboBoxSetting("MenuTheme");
Expand Down Expand Up @@ -4578,6 +4601,7 @@ AppearanceSettings::AppearanceSettings()
screen->setLabel(tr("Theme / Screen Settings"));
addChild(screen);

AddPaintEngine(screen);
screen->addChild(MenuTheme());
screen->addChild(GUIRGBLevels());

Expand Down

0 comments on commit ccf15e7

Please sign in to comment.