diff options
author | Be <be@mixxx.org> | 2020-05-02 02:52:44 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-02 02:52:44 -0500 |
commit | 8384816758758db6e228e4137990c42e7cefc7c9 (patch) | |
tree | 1b87b59419f5cf5971319fa5abd7ff66276d59d4 /src | |
parent | 48c7fe12dd52ccc5c036a7f3f1fa5b59d57345c8 (diff) | |
parent | e03cb570c3fac30f3e141ee848669d397bec46a8 (diff) |
Merge pull request #2651 from JosepMaJAZ/GL_Qt514_windows-fix
Bugfix for GL waveforms with QT 5.14 on Windows.
Diffstat (limited to 'src')
-rw-r--r-- | src/mixxx.cpp | 13 | ||||
-rw-r--r-- | src/mixxx.h | 2 | ||||
-rw-r--r-- | src/preferences/dialog/dlgprefwaveform.cpp | 8 | ||||
-rw-r--r-- | src/waveform/waveformwidgetfactory.cpp | 85 | ||||
-rw-r--r-- | src/waveform/waveformwidgetfactory.h | 25 | ||||
-rw-r--r-- | src/waveform/widgets/glsimplewaveformwidget.cpp | 3 | ||||
-rw-r--r-- | src/waveform/widgets/glvsynctestwidget.cpp | 3 | ||||
-rw-r--r-- | src/waveform/widgets/qthsvwaveformwidget.cpp | 3 | ||||
-rw-r--r-- | src/waveform/widgets/qtsimplewaveformwidget.cpp | 3 |
9 files changed, 110 insertions, 35 deletions
diff --git a/src/mixxx.cpp b/src/mixxx.cpp index e3e7d1db25..cb2aad1b12 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -447,10 +447,15 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { launchProgress(52); connect(this, - &MixxxMainWindow::newSkinLoaded, + &MixxxMainWindow::skinLoaded, m_pLibrary, &Library::onSkinLoadFinished); + connect(this, + &MixxxMainWindow::skinLoaded, + WaveformWidgetFactory::instance(), + &WaveformWidgetFactory::slotSkinLoaded); + // Inhibit the screensaver if the option is set. (Do it before creating the preferences dialog) int inhibit = pConfig->getValue<int>(ConfigKey("[Config]","InhibitScreensaver"),-1); if (inhibit == -1) { @@ -529,7 +534,7 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { if (args.getStartInFullscreen() || fullscreenPref) { slotViewFullScreen(true); } - emit newSkinLoaded(); + emit skinLoaded(); // Wait until all other ControlObjects are set up before initializing @@ -1097,7 +1102,7 @@ void MixxxMainWindow::createMenuBar() { void MixxxMainWindow::connectMenuBar() { ScopedTimer t("MixxxMainWindow::connectMenuBar"); connect(this, - &MixxxMainWindow::newSkinLoaded, + &MixxxMainWindow::skinLoaded, m_pMenuBar, &WMainMenuBar::onNewSkinLoaded); @@ -1489,7 +1494,7 @@ void MixxxMainWindow::rebootMixxxView() { } qDebug() << "rebootMixxxView DONE"; - emit newSkinLoaded(); + emit skinLoaded(); } bool MixxxMainWindow::eventFilter(QObject* obj, QEvent* event) { diff --git a/src/mixxx.h b/src/mixxx.h index b6790354af..c09a647548 100644 --- a/src/mixxx.h +++ b/src/mixxx.h @@ -105,7 +105,7 @@ class MixxxMainWindow : public QMainWindow { void slotNoVinylControlInputConfigured(); signals: - void newSkinLoaded(); + void skinLoaded(); // used to uncheck the menu when the dialog of develeoper tools is closed void developerToolsDlgClosed(int r); void closeDeveloperToolsDlgChecked(int r); diff --git a/src/preferences/dialog/dlgprefwaveform.cpp b/src/preferences/dialog/dlgprefwaveform.cpp index e2f22bfe8e..f8ff29549f 100644 --- a/src/preferences/dialog/dlgprefwaveform.cpp +++ b/src/preferences/dialog/dlgprefwaveform.cpp @@ -197,6 +197,14 @@ void DlgPrefWaveform::slotSetWaveformType(int index) { return; } WaveformWidgetFactory::instance()->setWidgetTypeFromHandle(index); +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) && defined __WINDOWS__ + // This regenerates the waveforms twice because of a bug found on Windows + // where the first one fails. + // The problem is that the window of the widget thinks that it is not exposed. + // (https://doc.qt.io/qt-5/qwindow.html#exposeEvent ) + // TODO: Remove this when it has been fixed upstream. + WaveformWidgetFactory::instance()->setWidgetTypeFromHandle(index, true); +#endif } void DlgPrefWaveform::slotSetWaveformOverviewType(int index) { diff --git a/src/waveform/waveformwidgetfactory.cpp b/src/waveform/waveformwidgetfactory.cpp index 5dade621b9..0c0c3037c8 100644 --- a/src/waveform/waveformwidgetfactory.cpp +++ b/src/waveform/waveformwidgetfactory.cpp @@ -95,7 +95,10 @@ WaveformWidgetHolder::WaveformWidgetHolder(WaveformWidgetAbstract* waveformWidge /////////////////////////////////////////// WaveformWidgetFactory::WaveformWidgetFactory() - : m_type(WaveformWidgetType::Count_WaveformwidgetType), + // Set an empty waveform initially. We will set the correct one when skin load finishes. + // Concretely, we want to set a non-GL waveform when loading the skin so that the window + // loads correctly. + : m_type(WaveformWidgetType::EmptyWaveform), m_config(0), m_skipRender(false), m_frameRate(30), @@ -311,8 +314,10 @@ bool WaveformWidgetFactory::setConfig(UserSettingsPointer config) { WaveformWidgetType::Type type = static_cast<WaveformWidgetType::Type>( m_config->getValueString(ConfigKey("[Waveform]","WaveformType")).toInt(&ok)); - if (!ok || !setWidgetType(type)) { - setWidgetType(autoChooseWidgetType()); + // Store the widget type on m_configType for later initialization. + // We will initialize the objects later because of a problem with GL on QT 5.14.2 on Windows + if (!ok || !setWidgetType(type, m_configType)) { + setWidgetType(autoChooseWidgetType(), m_configType); } for (int i = 0; i < FilterCount; i++) { @@ -359,6 +364,18 @@ void WaveformWidgetFactory::addTimerListener(QWidget* pWidget) { Qt::DirectConnection); } + +void WaveformWidgetFactory::slotSkinLoaded() { + setWidgetTypeFromConfig(); +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) && defined __WINDOWS__ + // This regenerates the waveforms twice because of a bug found on Windows + // where the first one fails. + // The problem is that the window of the widget thinks that it is not exposed. + // (https://doc.qt.io/qt-5/qwindow.html#exposeEvent ) + setWidgetTypeFromConfig(); +#endif +} + bool WaveformWidgetFactory::setWaveformWidget(WWaveformViewer* viewer, const QDomElement& node, const SkinContext& parentContext) { @@ -390,6 +407,8 @@ bool WaveformWidgetFactory::setWaveformWidget(WWaveformViewer* viewer, viewer->setZoom(m_defaultZoom); viewer->setDisplayBeatGridAlpha(m_beatGridAlpha); viewer->setPlayMarkerPosition(m_playMarkerPosition); + waveformWidget->resize(viewer->width(), viewer->height()); + waveformWidget->getWidget()->show(); viewer->update(); qDebug() << "WaveformWidgetFactory::setWaveformWidget - waveform widget added in factory, index" << index; @@ -430,32 +449,43 @@ int WaveformWidgetFactory::getVSyncType() { } bool WaveformWidgetFactory::setWidgetType(WaveformWidgetType::Type type) { - if (type == m_type) + return setWidgetType(type, m_type); +} + +bool WaveformWidgetFactory::setWidgetType(WaveformWidgetType::Type type, WaveformWidgetType::Type& currentType) { + if (type == currentType) return true; // check if type is acceptable - for (int i = 0; i < m_waveformWidgetHandles.size(); i++) { - WaveformWidgetAbstractHandle& handle = m_waveformWidgetHandles[i]; - if (handle.m_type == type) { - // type is acceptable - m_type = type; - if (m_config) { - m_config->set(ConfigKey("[Waveform]","WaveformType"), ConfigValue((int)m_type)); - } - return true; + int index = findHandleIndexFromType(type); + if (index > -1) { + // type is acceptable + currentType = type; + if (m_config) { + m_config->setValue(ConfigKey("[Waveform]", "WaveformType"), static_cast<int>(currentType)); } + return true; } // fallback - m_type = WaveformWidgetType::EmptyWaveform; + currentType = WaveformWidgetType::EmptyWaveform; if (m_config) { - m_config->set(ConfigKey("[Waveform]","WaveformType"), ConfigValue((int)m_type)); + m_config->setValue(ConfigKey("[Waveform]", "WaveformType"), static_cast<int>(currentType)); } return false; } -bool WaveformWidgetFactory::setWidgetTypeFromHandle(int handleIndex) { - if (handleIndex < 0 || handleIndex >= (int)m_waveformWidgetHandles.size()) { +bool WaveformWidgetFactory::setWidgetTypeFromConfig() { + int empty = findHandleIndexFromType(WaveformWidgetType::EmptyWaveform); + int desired = findHandleIndexFromType(m_configType); + if (desired == -1) { + desired = empty; + } + return setWidgetTypeFromHandle(desired, true); +} + +bool WaveformWidgetFactory::setWidgetTypeFromHandle(int handleIndex, bool force) { + if (handleIndex < 0 || handleIndex >= m_waveformWidgetHandles.size()) { qDebug() << "WaveformWidgetFactory::setWidgetType - invalid handle --> use of 'EmptyWaveform'"; // fallback empty type setWidgetType(WaveformWidgetType::EmptyWaveform); @@ -463,7 +493,7 @@ bool WaveformWidgetFactory::setWidgetTypeFromHandle(int handleIndex) { } WaveformWidgetAbstractHandle& handle = m_waveformWidgetHandles[handleIndex]; - if (handle.m_type == m_type) { + if (handle.m_type == m_type && !force) { qDebug() << "WaveformWidgetFactory::setWidgetType - type already in use"; return true; } @@ -973,3 +1003,22 @@ void WaveformWidgetFactory::startVSync(GuiTick* pGuiTick, VisualsManager* pVisua void WaveformWidgetFactory::getAvailableVSyncTypes(QList<QPair<int, QString > >* pList) { m_vsyncThread->getAvailableVSyncTypes(pList); } + +WaveformWidgetType::Type WaveformWidgetFactory::findTypeFromHandleIndex(int index) { + WaveformWidgetType::Type type = WaveformWidgetType::Count_WaveformwidgetType; + if (index >= 0 && index < m_waveformWidgetHandles.size()) { + type = m_waveformWidgetHandles[index].m_type; + } + return type; +} + +int WaveformWidgetFactory::findHandleIndexFromType(WaveformWidgetType::Type type) { + int index = -1; + for (int i = 0; i < m_waveformWidgetHandles.size(); i++) { + WaveformWidgetAbstractHandle& handle = m_waveformWidgetHandles[i]; + if (handle.m_type == type) { + index = i; + } + } + return index; +} diff --git a/src/waveform/waveformwidgetfactory.h b/src/waveform/waveformwidgetfactory.h index ad00e02c32..83e26c579f 100644 --- a/src/waveform/waveformwidgetfactory.h +++ b/src/waveform/waveformwidgetfactory.h @@ -64,8 +64,9 @@ class WaveformWidgetFactory : public QObject, public Singleton<WaveformWidgetFac bool setConfig(UserSettingsPointer config); - //creates the waveform widget and bind it to the viewer - //clean-up every thing if needed + /// Creates the waveform widget using the type set with setWidgetType + /// and binds it to the viewer. + /// Deletes older widget and resets positions to config defaults. bool setWaveformWidget( WWaveformViewer* viewer, const QDomElement &node, @@ -83,10 +84,21 @@ class WaveformWidgetFactory : public QObject, public Singleton<WaveformWidgetFac bool isOpenGlShaderAvailable() const { return m_openGLShaderAvailable;} + /// Sets the widget type and saves it to configuration. + /// Returns false and sets EmtpyWaveform if type is invalid bool setWidgetType(WaveformWidgetType::Type type); - bool setWidgetTypeFromHandle(int handleIndex); + /// Changes the widget type to that loaded from config and recreates them. + /// Used as a workaround on Windows due to a problem with GL and QT 5.14.2 + bool setWidgetTypeFromConfig(); + /// Changes the widget type and recreates them. Used from the preferences + /// dialog. + bool setWidgetTypeFromHandle(int handleIndex, bool force = false); WaveformWidgetType::Type getType() const { return m_type;} + protected: + bool setWidgetType(WaveformWidgetType::Type type, WaveformWidgetType::Type& currentType); + + public: void setDefaultZoom(double zoom); double getDefaultZoom() const { return m_defaultZoom;} @@ -125,6 +137,9 @@ class WaveformWidgetFactory : public QObject, public Singleton<WaveformWidgetFac void renderSpinnies(VSyncThread*); void swapSpinnies(); + public slots: + void slotSkinLoaded(); + protected: WaveformWidgetFactory(); virtual ~WaveformWidgetFactory(); @@ -140,6 +155,9 @@ class WaveformWidgetFactory : public QObject, public Singleton<WaveformWidgetFac WaveformWidgetAbstract* createWaveformWidget(WaveformWidgetType::Type type, WWaveformViewer* viewer); int findIndexOf(WWaveformViewer* viewer) const; + WaveformWidgetType::Type findTypeFromHandleIndex(int index); + int findHandleIndexFromType(WaveformWidgetType::Type type); + //All type of available widgets QVector<WaveformWidgetAbstractHandle> m_waveformWidgetHandles; @@ -148,6 +166,7 @@ class WaveformWidgetFactory : public QObject, public Singleton<WaveformWidgetFac std::vector<WaveformWidgetHolder> m_waveformWidgetHolders; WaveformWidgetType::Type m_type; + WaveformWidgetType::Type m_configType; UserSettingsPointer m_config; diff --git a/src/waveform/widgets/glsimplewaveformwidget.cpp b/src/waveform/widgets/glsimplewaveformwidget.cpp index 54c4e4fc31..f511e1e9a5 100644 --- a/src/waveform/widgets/glsimplewaveformwidget.cpp +++ b/src/waveform/widgets/glsimplewaveformwidget.cpp @@ -44,9 +44,6 @@ GLSimpleWaveformWidget::GLSimpleWaveformWidget(const char* group, QWidget* paren } GLSimpleWaveformWidget::~GLSimpleWaveformWidget() { - if (QGLContext::currentContext() != context()) { - makeCurrent(); - } } void GLSimpleWaveformWidget::castToQWidget() { diff --git a/src/waveform/widgets/glvsynctestwidget.cpp b/src/waveform/widgets/glvsynctestwidget.cpp index 3a788d1f9b..3f39ef23f3 100644 --- a/src/waveform/widgets/glvsynctestwidget.cpp +++ b/src/waveform/widgets/glvsynctestwidget.cpp @@ -47,9 +47,6 @@ GLVSyncTestWidget::GLVSyncTestWidget(const char* group, QWidget* parent) } GLVSyncTestWidget::~GLVSyncTestWidget() { - if (QGLContext::currentContext() != context()) { - makeCurrent(); - } } void GLVSyncTestWidget::castToQWidget() { diff --git a/src/waveform/widgets/qthsvwaveformwidget.cpp b/src/waveform/widgets/qthsvwaveformwidget.cpp index 01b0df5124..98fadd3c51 100644 --- a/src/waveform/widgets/qthsvwaveformwidget.cpp +++ b/src/waveform/widgets/qthsvwaveformwidget.cpp @@ -16,6 +16,9 @@ QtHSVWaveformWidget::QtHSVWaveformWidget(const char* group, QWidget* parent) : QGLWidget(parent), WaveformWidgetAbstract(group) { + if (QGLContext::currentContext() != context()) { + makeCurrent(); + } addRenderer<WaveformRenderBackground>(); addRenderer<WaveformRendererEndOfTrack>(); addRenderer<WaveformRendererPreroll>(); diff --git a/src/waveform/widgets/qtsimplewaveformwidget.cpp b/src/waveform/widgets/qtsimplewaveformwidget.cpp index 59ca4e9ab5..62cc3741e4 100644 --- a/src/waveform/widgets/qtsimplewaveformwidget.cpp +++ b/src/waveform/widgets/qtsimplewaveformwidget.cpp @@ -42,9 +42,6 @@ QtSimpleWaveformWidget::QtSimpleWaveformWidget(const char* group, QWidget* paren } QtSimpleWaveformWidget::~QtSimpleWaveformWidget() { - if (QGLContext::currentContext() != context()) { - makeCurrent(); - } } void QtSimpleWaveformWidget::castToQWidget() { |