diff --git a/src/preferences/configobject.h b/src/preferences/configobject.h index c277295ed945..3849108d60bd 100644 --- a/src/preferences/configobject.h +++ b/src/preferences/configobject.h @@ -154,16 +154,27 @@ template class ConfigObject { // returns QString(). QString getValueString(const ConfigKey& key) const; + template + struct is_qflags : std::false_type {}; + template + struct is_qflags> : std::true_type {}; + // Sets the value for key to ValueType(value), over-writing pre-existing // values. ResultType is serialized to string on a per-type basis. - template + template + requires(!std::is_enum_v && !is_qflags::value) void setValue(const ConfigKey& key, const ResultType& value); template - requires std::is_enum_v + requires(std::is_enum_v && !is_qflags::value) // we need to take value as const ref otherwise the overload is ambiguous void setValue(const ConfigKey& key, const EnumType& value) { setValue(key, static_cast(value)); }; + template + requires(is_qflags::value) + void setValue(const ConfigKey& key, const QFlagsType& value) { + setValue(key, value.toInt()); + } // Returns the value for key, converted to ResultType. If key is not present // or the value cannot be converted to ResultType, returns ResultType(). @@ -177,15 +188,21 @@ template class ConfigObject { // Returns the value for key, converted to ResultType. If key is not present // or the value cannot be converted to ResultType, returns default_value. - template + template + requires(!std::is_enum_v && !is_qflags::value) ResultType getValue(const ConfigKey& key, const ResultType& default_value) const; QString getValue(const ConfigKey& key, const char* default_value) const; template - requires std::is_enum_v + requires(std::is_enum_v && !is_qflags::value) EnumType getValue(const ConfigKey& key, const EnumType& default_value) const { // we need to take default_value as const ref otherwise the overload is ambiguous return static_cast(getValue(key, static_cast(default_value))); } + template + requires(is_qflags::value) + QFlagsType getValue(const ConfigKey& key, const QFlagsType& default_value) const { + return QFlagsType::fromInt(getValue(key, default_value.toInt())); + } QMultiHash transpose() const; diff --git a/src/preferences/dialog/dlgprefwaveform.cpp b/src/preferences/dialog/dlgprefwaveform.cpp index 06ae477e8a8d..87576b204e96 100644 --- a/src/preferences/dialog/dlgprefwaveform.cpp +++ b/src/preferences/dialog/dlgprefwaveform.cpp @@ -16,10 +16,6 @@ namespace { const QString kWaveformGroup(QStringLiteral("[Waveform]")); const ConfigKey kOverviewTypeCfgKey(kWaveformGroup, QStringLiteral("WaveformOverviewType")); -const ConfigKey kWaveformOptionsKey(kWaveformGroup, - QStringLiteral("waveform_options")); -const ConfigKey kHardwareAccelerationKey(kWaveformGroup, - QStringLiteral("use_hardware_acceleration")); } // namespace // for OverviewType @@ -59,11 +55,11 @@ DlgPrefWaveform::DlgPrefWaveform( m_pTypeControl->forceSet(cfgTypeIndex); // Populate waveform options. - WaveformWidgetFactory* factory = WaveformWidgetFactory::instance(); + auto* pFactory = WaveformWidgetFactory::instance(); // We assume that the original type list order remains constant. // We will use the type index later on to set waveform types and to // update the combobox. - QVector types = factory->getAvailableTypes(); + QVector types = pFactory->getAvailableTypes(); for (int i = 0; i < types.size(); ++i) { if (types[i].getType() == WaveformWidgetType::Empty) { continue; @@ -197,7 +193,7 @@ DlgPrefWaveform::DlgPrefWaveform( this, &DlgPrefWaveform::slotSetOverviewMinuteMarkers); - connect(factory, + connect(pFactory, &WaveformWidgetFactory::waveformMeasured, this, &DlgPrefWaveform::slotWaveformMeasured); @@ -253,106 +249,76 @@ DlgPrefWaveform::DlgPrefWaveform( setScrollSafeGuardForAllInputWidgets(this); } -DlgPrefWaveform::~DlgPrefWaveform() { -} - void DlgPrefWaveform::slotSetWaveformOptions( allshader::WaveformRendererSignalBase::Option option, bool enabled) { - auto type = static_cast(waveformTypeComboBox->currentData().toInt()); - allshader::WaveformRendererSignalBase::Options supportedOptions = - allshader::WaveformRendererSignalBase::Option::None; - -#ifdef MIXXX_USE_QOPENGL auto* pFactory = WaveformWidgetFactory::instance(); - auto backend = m_pConfig->getValue(kHardwareAccelerationKey, pFactory->preferredBackend()); - int handleIdx = pFactory->findHandleIndexFromType(type); - if (handleIdx >= 0 && handleIdx < pFactory->getAvailableTypes().size()) { - supportedOptions = pFactory->getAvailableTypes()[handleIdx].supportedOptions(backend); - } -#endif - - allshader::WaveformRendererSignalBase::Options currentOption = m_pConfig->getValue( - kWaveformOptionsKey, - allshader::WaveformRendererSignalBase::Option::None); - currentOption.setFlag(option, enabled); - // clear unsupported options - currentOption &= supportedOptions; - m_pConfig->setValue(kWaveformOptionsKey, currentOption); - - auto* factory = WaveformWidgetFactory::instance(); - factory->setWidgetTypeFromHandle( - factory->findHandleIndexFromType(type), true); + auto type = static_cast( + waveformTypeComboBox->currentData().toInt()); + pFactory->setWaveformOption(option, enabled, type); + pFactory->setWidgetTypeFromHandle( + pFactory->findHandleIndexFromType(type), true); } void DlgPrefWaveform::slotUpdate() { - WaveformWidgetFactory* factory = WaveformWidgetFactory::instance(); - - bool isAccelerationEnabled = false; - if (factory->isOpenGlAvailable() || factory->isOpenGlesAvailable()) { - openGlStatusData->setText(factory->getOpenGLVersion()); + auto* pFactory = WaveformWidgetFactory::instance(); + if (pFactory->isOpenGlAvailable() || pFactory->isOpenGlesAvailable()) { + openGlStatusData->setText(pFactory->getOpenGLVersion()); useAccelerationCheckBox->setEnabled(true); - isAccelerationEnabled = m_pConfig->getValue( - kHardwareAccelerationKey, - factory->preferredBackend()) != - WaveformWidgetBackend::None; + bool isAccelerationEnabled = + pFactory->getBackendFromConfig() != WaveformWidgetBackend::None; useAccelerationCheckBox->setChecked(isAccelerationEnabled); } else { - openGlStatusData->setText(tr("OpenGL not available") + ": " + factory->getOpenGLVersion()); + openGlStatusData->setText(tr("OpenGL not available") + ": " + pFactory->getOpenGLVersion()); useAccelerationCheckBox->setEnabled(false); useAccelerationCheckBox->setChecked(false); } // The combobox holds a list of [handle name, handle index] - int currentIndex = waveformTypeComboBox->findData(factory->getType()); - if (currentIndex != -1 && waveformTypeComboBox->currentIndex() != currentIndex) { - waveformTypeComboBox->setCurrentIndex(currentIndex); + int indexOfCurrentType = waveformTypeComboBox->findData(pFactory->getType()); + if (indexOfCurrentType != -1 && waveformTypeComboBox->currentIndex() != indexOfCurrentType) { + waveformTypeComboBox->setCurrentIndex(indexOfCurrentType); } - bool useWaveform = factory->getType() != WaveformWidgetType::Empty; + auto type = pFactory->getType(); + bool useWaveform = type != WaveformWidgetType::Empty; useWaveformCheckBox->setChecked(useWaveform); - allshader::WaveformRendererSignalBase::Options currentOptions = m_pConfig->getValue( - kWaveformOptionsKey, - allshader::WaveformRendererSignalBase::Option::None); - WaveformWidgetBackend backend = m_pConfig->getValue( - kHardwareAccelerationKey, - factory->preferredBackend()); - updateWaveformAcceleration(factory->getType(), backend); - updateWaveformTypeOptions(useWaveform, backend, currentOptions); + updateWaveformAcceleration(type); + updateWaveformTypeOptions(useWaveform); waveformTypeComboBox->setEnabled(useWaveform); updateEnableUntilMark(); updateWaveformGeneralOptionsEnabled(); updateStemOptionsEnabled(); - frameRateSpinBox->setValue(factory->getFrameRate()); - frameRateSlider->setValue(factory->getFrameRate()); - endOfTrackWarningTimeSpinBox->setValue(factory->getEndOfTrackWarningTime()); - endOfTrackWarningTimeSlider->setValue(factory->getEndOfTrackWarningTime()); - synchronizeZoomCheckBox->setChecked(factory->isZoomSync()); - allVisualGain->setValue(factory->getVisualGain(BandIndex::AllBand)); - lowVisualGain->setValue(factory->getVisualGain(BandIndex::Low)); - midVisualGain->setValue(factory->getVisualGain(BandIndex::Mid)); - highVisualGain->setValue(factory->getVisualGain(BandIndex::High)); + frameRateSpinBox->setValue(pFactory->getFrameRate()); + frameRateSlider->setValue(pFactory->getFrameRate()); + endOfTrackWarningTimeSpinBox->setValue(pFactory->getEndOfTrackWarningTime()); + endOfTrackWarningTimeSlider->setValue(pFactory->getEndOfTrackWarningTime()); + synchronizeZoomCheckBox->setChecked(pFactory->isZoomSync()); + allVisualGain->setValue(pFactory->getVisualGain(BandIndex::AllBand)); + lowVisualGain->setValue(pFactory->getVisualGain(BandIndex::Low)); + midVisualGain->setValue(pFactory->getVisualGain(BandIndex::Mid)); + highVisualGain->setValue(pFactory->getVisualGain(BandIndex::High)); // Round zoom to int to get a default zoom index. - defaultZoomComboBox->setCurrentIndex(static_cast(factory->getDefaultZoom()) - 1); - playMarkerPositionSlider->setValue(static_cast(factory->getPlayMarkerPosition() * 100)); - beatGridAlphaSpinBox->setValue(factory->getBeatGridAlpha()); - beatGridAlphaSlider->setValue(factory->getBeatGridAlpha()); + defaultZoomComboBox->setCurrentIndex(static_cast(pFactory->getDefaultZoom()) - 1); + playMarkerPositionSlider->setValue(static_cast(pFactory->getPlayMarkerPosition() * 100)); + beatGridAlphaSpinBox->setValue(pFactory->getBeatGridAlpha()); + beatGridAlphaSlider->setValue(pFactory->getBeatGridAlpha()); - untilMarkShowBeatsCheckBox->setChecked(factory->getUntilMarkShowBeats()); - untilMarkShowTimeCheckBox->setChecked(factory->getUntilMarkShowTime()); + untilMarkShowBeatsCheckBox->setChecked(pFactory->getUntilMarkShowBeats()); + untilMarkShowTimeCheckBox->setChecked(pFactory->getUntilMarkShowTime()); untilMarkAlignComboBox->setCurrentIndex( WaveformWidgetFactory::toUntilMarkAlignIndex( - factory->getUntilMarkAlign())); - untilMarkTextPointSizeSpinBox->setValue(factory->getUntilMarkTextPointSize()); + pFactory->getUntilMarkAlign())); + untilMarkTextPointSizeSpinBox->setValue(pFactory->getUntilMarkTextPointSize()); untilMarkTextHeightLimitComboBox->setCurrentIndex( WaveformWidgetFactory::toUntilMarkTextHeightLimitIndex( - factory->getUntilMarkTextHeightLimit())); + pFactory->getUntilMarkTextHeightLimit())); - stemReorderLayerOnChangedCheckBox->setChecked(factory->isStemReorderOnChange()); - stemOpacitySpinBox->setValue(factory->getStemOpacity()); - stemOutlineOpacitySpinBox->setValue(factory->getStemOutlineOpacity()); - stemDisplayModeComboBox->setCurrentIndex(factory->isStemSplitTracks() ? 1 : 0); + stemReorderLayerOnChangedCheckBox->setChecked(pFactory->isStemReorderOnChange()); + stemOpacitySpinBox->setValue(pFactory->getStemOpacity()); + stemOutlineOpacitySpinBox->setValue(pFactory->getStemOutlineOpacity()); + stemDisplayModeComboBox->setCurrentIndex(pFactory->isStemSplitTracks() ? 1 : 0); OverviewType cfgOverviewType = m_pConfig->getValue(kOverviewTypeCfgKey, OverviewType::RGB); @@ -363,7 +329,7 @@ void DlgPrefWaveform::slotUpdate() { waveformOverviewComboBox->setCurrentIndex(cfgOverviewTypeIndex); } - if (factory->isOverviewNormalized()) { + if (pFactory->isOverviewNormalized()) { overview_scale_normalize->setChecked(true); } else { overview_scale_allReplayGain->setChecked(true); @@ -390,27 +356,23 @@ void DlgPrefWaveform::slotApply() { } void DlgPrefWaveform::slotResetToDefaults() { - WaveformWidgetFactory* factory = WaveformWidgetFactory::instance(); + auto* pFactory = WaveformWidgetFactory::instance(); int defaultIndex = waveformTypeComboBox->findData( WaveformWidgetFactory::defaultType()); if (defaultIndex != -1 && waveformTypeComboBox->currentIndex() != defaultIndex) { waveformTypeComboBox->setCurrentIndex(defaultIndex); } - auto defaultBackend = factory->preferredBackend(); + pFactory->setDefaultBackend(); useWaveformCheckBox->setChecked(true); waveformTypeComboBox->setEnabled(true); - updateWaveformAcceleration(WaveformWidgetFactory::defaultType(), defaultBackend); - updateWaveformTypeOptions(true, - defaultBackend, - allshader::WaveformRendererSignalBase::Option::None); + updateWaveformAcceleration(pFactory->defaultType()); // Restore waveform backend and option setting instantly - m_pConfig->setValue(kWaveformOptionsKey, - allshader::WaveformRendererSignalBase::Option::None); - m_pConfig->setValue(kHardwareAccelerationKey, defaultBackend); - factory->setWidgetTypeFromHandle( - factory->findHandleIndexFromType( + pFactory->resetWaveformOptions(); + updateWaveformTypeOptions(true); + pFactory->setWidgetTypeFromHandle( + pFactory->findHandleIndexFromType( WaveformWidgetFactory::defaultType()), true); @@ -467,88 +429,57 @@ void DlgPrefWaveform::slotSetWaveformType(int index) { } auto type = static_cast( waveformTypeComboBox->itemData(index).toInt()); - auto* factory = WaveformWidgetFactory::instance(); + auto* pFactory = WaveformWidgetFactory::instance(); - auto backend = m_pConfig->getValue(kHardwareAccelerationKey, factory->preferredBackend()); // When setting the type, factory uses current 'use acceleration' state, // which may currently be off. However, with QOpenGL there are Simple and Stacked // which require acceleration and auto-enable it if possible. // FIXME Find a better solution? // See https://github.com/mixxxdj/mixxx/pull/15277 for details. - updateWaveformAcceleration(type, backend); + updateWaveformAcceleration(type); // Store the value so it's available in factory. Same as // slotSetWaveformAcceleration(useAccelerationCheckBox->isChecked()) just // without the redundant actions - if (useAccelerationCheckBox->isChecked()) { - backend = -#ifdef MIXXX_USE_QOPENGL - WaveformWidgetBackend::AllShader -#else - WaveformWidgetBackend::GL -#endif - ; - } - m_pConfig->setValue(kHardwareAccelerationKey, backend); + pFactory->setAcceleration(useAccelerationCheckBox->isChecked()); // Now set the new type - factory->setWidgetTypeFromHandle(factory->findHandleIndexFromType(type)); + pFactory->setWidgetTypeFromHandle(pFactory->findHandleIndexFromType(type)); - allshader::WaveformRendererSignalBase::Options currentOptions = m_pConfig->getValue( - kWaveformOptionsKey, - allshader::WaveformRendererSignalBase::Option::None); - updateWaveformTypeOptions(true, backend, currentOptions); + updateWaveformTypeOptions(true); updateEnableUntilMark(); updateStemOptionsEnabled(); } void DlgPrefWaveform::slotSetWaveformEnabled(bool checked) { - auto* factory = WaveformWidgetFactory::instance(); + auto* pFactory = WaveformWidgetFactory::instance(); if (!checked) { - factory->setWidgetTypeFromHandle( - factory->findHandleIndexFromType(WaveformWidgetType::Empty), + pFactory->setWidgetTypeFromHandle( + pFactory->findHandleIndexFromType(WaveformWidgetType::Empty), true); } else { auto type = static_cast( waveformTypeComboBox->currentData().toInt()); - factory->setWidgetTypeFromHandle(factory->findHandleIndexFromType(type), true); + pFactory->setWidgetTypeFromHandle(pFactory->findHandleIndexFromType(type), true); } slotUpdate(); } void DlgPrefWaveform::slotSetWaveformAcceleration(bool checked) { - WaveformWidgetBackend backend = WaveformWidgetBackend::None; - if (checked) { - backend = -#ifdef MIXXX_USE_QOPENGL - WaveformWidgetBackend::AllShader -#else - WaveformWidgetBackend::GL -#endif - ; - } - m_pConfig->setValue(kHardwareAccelerationKey, backend); + auto* pFactory = WaveformWidgetFactory::instance(); + pFactory->setAcceleration(checked); auto type = static_cast(waveformTypeComboBox->currentData().toInt()); - auto* factory = WaveformWidgetFactory::instance(); - factory->setWidgetTypeFromHandle(factory->findHandleIndexFromType(type), true); - allshader::WaveformRendererSignalBase::Options currentOptions = m_pConfig->getValue( - kWaveformOptionsKey, - allshader::WaveformRendererSignalBase::Option::None); - updateWaveformTypeOptions(true, backend, currentOptions); + pFactory->setWidgetTypeFromHandle(pFactory->findHandleIndexFromType(type), true); + updateWaveformTypeOptions(true); updateEnableUntilMark(); updateStemOptionsEnabled(); } -void DlgPrefWaveform::updateWaveformAcceleration( - WaveformWidgetType::Type type, WaveformWidgetBackend backend) { - auto* factory = WaveformWidgetFactory::instance(); - int handleIdx = factory->findHandleIndexFromType(type); +void DlgPrefWaveform::updateWaveformAcceleration(WaveformWidgetType::Type type) { + auto* pFactory = WaveformWidgetFactory::instance(); + auto backend = pFactory->getBackendFromConfig(); - bool supportAcceleration = false, supportSoftware = true; - if (handleIdx != -1) { - const auto& handle = factory->getAvailableTypes()[handleIdx]; - supportAcceleration = handle.supportAcceleration(); - supportSoftware = handle.supportSoftware(); - } + bool supportAcceleration = pFactory->widgetTypeSupportsAcceleration(type); + bool supportSoftware = pFactory->widgetTypeSupportsSoftware(type); useAccelerationCheckBox->blockSignals(true); @@ -566,22 +497,18 @@ void DlgPrefWaveform::updateWaveformAcceleration( useAccelerationCheckBox->blockSignals(false); } -void DlgPrefWaveform::updateWaveformTypeOptions(bool useWaveform, - WaveformWidgetBackend backend, - allshader::WaveformRendererSignalBase::Options currentOptions) { +void DlgPrefWaveform::updateWaveformTypeOptions(bool useWaveform) { splitLeftRightCheckBox->blockSignals(true); highDetailCheckBox->blockSignals(true); #ifdef MIXXX_USE_QOPENGL - WaveformWidgetFactory* factory = WaveformWidgetFactory::instance(); - allshader::WaveformRendererSignalBase::Options supportedOptions = - allshader::WaveformRendererSignalBase::Option::None; + auto* pFactory = WaveformWidgetFactory::instance(); auto type = static_cast(waveformTypeComboBox->currentData().toInt()); - int handleIdx = factory->findHandleIndexFromType(type); - if (handleIdx >= 0 && handleIdx < factory->getAvailableTypes().size()) { - supportedOptions = factory->getAvailableTypes()[handleIdx].supportedOptions(backend); - } + WaveformWidgetBackend backend = pFactory->getBackendFromConfig(); + allshader::WaveformRendererSignalBase::Options currentOptions = pFactory->getWaveformOptions(); + allshader::WaveformRendererSignalBase::Options supportedOptions = + pFactory->getWaveformOptionsSupportedByType(type, backend); splitLeftRightCheckBox->setEnabled(useWaveform && (supportedOptions & @@ -607,12 +534,10 @@ void DlgPrefWaveform::updateEnableUntilMark() { #ifndef MIXXX_USE_QOPENGL const bool enabled = false; #else - WaveformWidgetFactory* factory = WaveformWidgetFactory::instance(); + auto* pFactory = WaveformWidgetFactory::instance(); const bool enabled = - WaveformWidgetFactory::instance()->widgetTypeSupportsUntilMark() && - m_pConfig->getValue(kHardwareAccelerationKey, - factory->preferredBackend()) != - WaveformWidgetBackend::None; + pFactory->widgetTypeSupportsUntilMark() && + pFactory->getBackendFromConfig() != WaveformWidgetBackend::None; #endif untilMarkShowBeatsCheckBox->setEnabled(enabled); untilMarkShowTimeCheckBox->setEnabled(enabled); @@ -647,10 +572,10 @@ void DlgPrefWaveform::updateStemOptionsEnabled() { #ifndef MIXXX_USE_QOPENGL const bool stemsSupported = false; #else - WaveformWidgetFactory* factory = WaveformWidgetFactory::instance(); + auto* pFactory = WaveformWidgetFactory::instance(); const bool stemsSupported = - factory->widgetTypeSupportsStems() && - factory->getBackendFromConfig() == WaveformWidgetBackend::AllShader; + pFactory->widgetTypeSupportsStems() && + pFactory->getBackendFromConfig() == WaveformWidgetBackend::AllShader; #endif bool enabled = useWaveformCheckBox->isChecked(); stemOpacityMainLabel->setEnabled(stemsSupported && enabled); @@ -733,9 +658,6 @@ void DlgPrefWaveform::slotClearCachedWaveforms() { } void DlgPrefWaveform::slotSetBeatGridAlpha(int alpha) { - // TODO(xxx) For consistency set this in WaveformWidgetFactory like - // the other waveform controls. - m_pConfig->setValue(ConfigKey(kWaveformGroup, QStringLiteral("beatGridAlpha")), alpha); WaveformWidgetFactory::instance()->setDisplayBeatGridAlpha(alpha); } diff --git a/src/preferences/dialog/dlgprefwaveform.h b/src/preferences/dialog/dlgprefwaveform.h index f0aef9c9c69a..72fd35f26540 100644 --- a/src/preferences/dialog/dlgprefwaveform.h +++ b/src/preferences/dialog/dlgprefwaveform.h @@ -21,7 +21,6 @@ class DlgPrefWaveform : public DlgPreferencePage, public Ui::DlgPrefWaveformDlg QWidget* pParent, UserSettingsPointer pConfig, std::shared_ptr pLibrary); - virtual ~DlgPrefWaveform(); public slots: void slotUpdate() override; @@ -74,11 +73,8 @@ class DlgPrefWaveform : public DlgPreferencePage, public Ui::DlgPrefWaveformDlg void calculateCachedWaveformDiskUsage(); void notifyRebootNecessary(); void updateEnableUntilMark(); - void updateWaveformTypeOptions(bool useWaveform, - WaveformWidgetBackend backend, - allshader::WaveformRendererSignalBase::Options currentOption); - void updateWaveformAcceleration( - WaveformWidgetType::Type type, WaveformWidgetBackend backend); + void updateWaveformTypeOptions(bool useWaveform); + void updateWaveformAcceleration(WaveformWidgetType::Type type); void updateWaveformGeneralOptionsEnabled(); void updateWaveformGainEnabled(); void updateStemOptionsEnabled(); diff --git a/src/waveform/waveformwidgetfactory.cpp b/src/waveform/waveformwidgetfactory.cpp index 1a029798b1ed..26bd3663780d 100644 --- a/src/waveform/waveformwidgetfactory.cpp +++ b/src/waveform/waveformwidgetfactory.cpp @@ -74,6 +74,8 @@ const ConfigKey kWaveformTypeKey = ConfigKey(kWaveformGroup, QStringLiteral("WaveformType")); const ConfigKey kHardwareAccelerationKey = ConfigKey(kWaveformGroup, QStringLiteral("use_hardware_acceleration")); +const ConfigKey kWaveformOptionsKey(kWaveformGroup, + QStringLiteral("waveform_options")); const ConfigKey kZoomSyncKey = ConfigKey( kWaveformGroup, QStringLiteral("ZoomSynchronization")); const ConfigKey kEndOfTrackWarningKey = ConfigKey( @@ -83,6 +85,7 @@ const ConfigKey kDefaultZoomKey = const ConfigKey kFrameRateKey = ConfigKey(kWaveformGroup, QStringLiteral("FrameRate")); const ConfigKey kVSyncKey = ConfigKey(kWaveformGroup, QStringLiteral("VSync")); +const ConfigKey kBeatGridAlpha = ConfigKey(kWaveformGroup, QStringLiteral("beatGridAlpha")); ConfigKey visualGainKey(int index) { return ConfigKey(kWaveformGroup, QStringLiteral("VisualGain_") + QString::number(index)); @@ -404,9 +407,7 @@ bool WaveformWidgetFactory::setConfig(UserSettingsPointer config) { bool zoomSync = m_config->getValue(kZoomSyncKey, m_zoomSync); setZoomSync(zoomSync); - int beatGridAlpha = - m_config->getValue(ConfigKey(kWaveformGroup, QStringLiteral("beatGridAlpha")), - m_beatGridAlpha); + int beatGridAlpha = m_config->getValue(kBeatGridAlpha, m_beatGridAlpha); setDisplayBeatGridAlpha(beatGridAlpha); WaveformWidgetType::Type type = static_cast( @@ -714,6 +715,19 @@ bool WaveformWidgetFactory::setWidgetTypeFromHandle(int handleIndex, bool force) return true; } +WaveformWidgetBackend WaveformWidgetFactory::setAcceleration(bool enabled) { + WaveformWidgetBackend backend = WaveformWidgetBackend::None; + if (enabled && (isOpenGlAvailable() || isOpenGlesAvailable())) { +#ifdef MIXXX_USE_QOPENGL + backend = WaveformWidgetBackend::AllShader; +#else + backend = WaveformWidgetBackend::GL; +#endif + } + m_config->setValue(kHardwareAccelerationKey, backend); + return backend; +} + void WaveformWidgetFactory::setDefaultZoom(double zoom) { m_defaultZoom = math_clamp(zoom, WaveformWidgetRenderer::s_waveformMinZoom, WaveformWidgetRenderer::s_waveformMaxZoom); @@ -751,6 +765,7 @@ void WaveformWidgetFactory::setDisplayBeatGridAlpha(int alpha) { for (const auto& holder : std::as_const(m_waveformWidgetHolders)) { holder.m_waveformWidget->setDisplayBeatGridAlpha(m_beatGridAlpha); } + m_config->setValue(kBeatGridAlpha, alpha); } void WaveformWidgetFactory::setVisualGain(BandIndex index, double gain) { @@ -1108,9 +1123,10 @@ void WaveformWidgetFactory::evaluateWidgets() { WaveformWidgetAbstract* WaveformWidgetFactory::createAllshaderWaveformWidget( WaveformWidgetType::Type type, WWaveformViewer* viewer) { - allshader::WaveformRendererSignalBase::Options options = - m_config->getValue(ConfigKey("[Waveform]", "waveform_options"), - allshader::WaveformRendererSignalBase::Option::None); + allshader::WaveformRendererSignalBase::Options options = m_config->getValue( + ConfigKey("[Waveform]", "waveform_options"), + allshader::WaveformRendererSignalBase::Options( + allshader::WaveformRendererSignalBase::Option::None)); return new allshader::WaveformWidget(viewer, type, viewer->getGroup(), options); } @@ -1119,11 +1135,13 @@ WaveformWidgetAbstract* WaveformWidgetFactory::createFilteredWaveformWidget( WaveformWidgetBackend backend = getBackendFromConfig(); switch (backend) { + case WaveformWidgetBackend::AllShader: #ifdef MIXXX_USE_QOPENGL - case WaveformWidgetBackend::AllShader: { return createAllshaderWaveformWidget(WaveformWidgetType::Type::Filtered, viewer); - } #endif + case WaveformWidgetBackend::None: + case WaveformWidgetBackend::GL: + case WaveformWidgetBackend::GLSL: default: return new SoftwareWaveformWidget(viewer->getGroup(), viewer); } @@ -1133,10 +1151,13 @@ WaveformWidgetAbstract* WaveformWidgetFactory::createHSVWaveformWidget(WWaveform WaveformWidgetBackend backend = getBackendFromConfig(); switch (backend) { -#ifdef MIXXX_USE_QOPENGL case WaveformWidgetBackend::AllShader: +#ifdef MIXXX_USE_QOPENGL return createAllshaderWaveformWidget(WaveformWidgetType::HSV, viewer); #endif + case WaveformWidgetBackend::None: + case WaveformWidgetBackend::GL: + case WaveformWidgetBackend::GLSL: default: return new HSVWaveformWidget(viewer->getGroup(), viewer); } @@ -1146,10 +1167,13 @@ WaveformWidgetAbstract* WaveformWidgetFactory::createRGBWaveformWidget(WWaveform WaveformWidgetBackend backend = getBackendFromConfig(); switch (backend) { -#ifdef MIXXX_USE_QOPENGL case WaveformWidgetBackend::AllShader: +#ifdef MIXXX_USE_QOPENGL return createAllshaderWaveformWidget(WaveformWidgetType::Type::RGB, viewer); #endif + case WaveformWidgetBackend::None: + case WaveformWidgetBackend::GL: + case WaveformWidgetBackend::GLSL: default: return new RGBWaveformWidget(viewer->getGroup(), viewer); } @@ -1157,12 +1181,16 @@ WaveformWidgetAbstract* WaveformWidgetFactory::createRGBWaveformWidget(WWaveform WaveformWidgetAbstract* WaveformWidgetFactory::createStackedWaveformWidget( WWaveformViewer* viewer) { -#ifdef MIXXX_USE_QOPENGL WaveformWidgetBackend backend = getBackendFromConfig(); + switch (backend) { case WaveformWidgetBackend::AllShader: +#ifdef MIXXX_USE_QOPENGL return createAllshaderWaveformWidget(WaveformWidgetType::Type::Stacked, viewer); #endif + case WaveformWidgetBackend::None: + case WaveformWidgetBackend::GL: + case WaveformWidgetBackend::GLSL: default: return new EmptyWaveformWidget(viewer->getGroup(), viewer); } @@ -1172,10 +1200,13 @@ WaveformWidgetAbstract* WaveformWidgetFactory::createSimpleWaveformWidget(WWavef WaveformWidgetBackend backend = getBackendFromConfig(); switch (backend) { -#ifdef MIXXX_USE_QOPENGL case WaveformWidgetBackend::AllShader: +#ifdef MIXXX_USE_QOPENGL return createAllshaderWaveformWidget(WaveformWidgetType::Type::Simple, viewer); #endif + case WaveformWidgetBackend::None: + case WaveformWidgetBackend::GL: + case WaveformWidgetBackend::GLSL: default: return new SimpleSignalWaveformWidget(viewer->getGroup(), viewer); } @@ -1334,10 +1365,32 @@ WaveformWidgetBackend WaveformWidgetFactory::getBackendFromConfig() const { // in case of issue when we release, we can communicate workaround on // editing the INI file to target a specific rendering backend. If no // complains come back, we can convert this safely to a backend eventually. - return m_config->getValue( - ConfigKey(QStringLiteral("[Waveform]"), QStringLiteral("use_hardware_acceleration")), + WaveformWidgetBackend backend = m_config->getValue( + kHardwareAccelerationKey, preferredBackend()); -} + switch (backend) { + case WaveformWidgetBackend::None: + break; + case WaveformWidgetBackend::GL: + if (!m_openGlAvailable) { + backend = WaveformWidgetBackend::None; + } + break; + case WaveformWidgetBackend::GLSL: + if (!m_openGlAvailable || !m_openGLShaderAvailable) { + backend = WaveformWidgetBackend::None; + } + break; + case WaveformWidgetBackend::AllShader: +#ifdef MIXXX_USE_QOPENGL + if (!m_openGlAvailable && !m_openGlesAvailable) { + backend = WaveformWidgetBackend::None; + } +#endif + break; + } + return backend; +}; WaveformWidgetBackend WaveformWidgetFactory::preferredBackend() const { #ifdef MIXXX_USE_QOPENGL @@ -1357,6 +1410,45 @@ void WaveformWidgetFactory::setDefaultBackend() { m_config->setValue(kHardwareAccelerationKey, preferredBackend()); } +allshader::WaveformRendererSignalBase::Options WaveformWidgetFactory::getWaveformOptions() { + auto options = m_config->getValue(kWaveformOptionsKey, + allshader::WaveformRendererSignalBase::Options( + allshader::WaveformRendererSignalBase::Option::None)); + return options; +} + +allshader::WaveformRendererSignalBase::Options +WaveformWidgetFactory::getWaveformOptionsSupportedByType( + WaveformWidgetType::Type type, WaveformWidgetBackend backend) { + allshader::WaveformRendererSignalBase::Options supportedOptions = + allshader::WaveformRendererSignalBase::Option::None; + int handleIdx = findHandleIndexFromType(type); + if (handleIdx != -1) { + supportedOptions = getAvailableTypes()[handleIdx].supportedOptions(backend); + } + return supportedOptions; +} + +void WaveformWidgetFactory::setWaveformOption( + allshader::WaveformRendererSignalBase::Option option, + bool enabled, + WaveformWidgetType::Type type) { + WaveformWidgetBackend backend = getBackendFromConfig(); + allshader::WaveformRendererSignalBase::Options currentOptions = getWaveformOptions(); + allshader::WaveformRendererSignalBase::Options supportedOptions = + getWaveformOptionsSupportedByType(type, backend); + + currentOptions.setFlag(option, enabled); + // clear unsupported options + currentOptions &= supportedOptions; + m_config->setValue(kWaveformOptionsKey, currentOptions); +} + +void WaveformWidgetFactory::resetWaveformOptions() { + m_config->setValue(kWaveformOptionsKey, + allshader::WaveformRendererSignalBase::Option::None); +} + QString WaveformWidgetAbstractHandle::getDisplayName() const { return getDisplayName(m_type); } diff --git a/src/waveform/waveformwidgetfactory.h b/src/waveform/waveformwidgetfactory.h index 1868775544ff..796e05d6d88e 100644 --- a/src/waveform/waveformwidgetfactory.h +++ b/src/waveform/waveformwidgetfactory.h @@ -239,6 +239,16 @@ class WaveformWidgetFactory : public QObject, } static bool isOverviewNormalizedDefault(); + WaveformWidgetBackend setAcceleration(bool enabled); + + allshader::WaveformRendererSignalBase::Options getWaveformOptions(); + allshader::WaveformRendererSignalBase::Options getWaveformOptionsSupportedByType( + WaveformWidgetType::Type type, WaveformWidgetBackend backend); + void setWaveformOption(allshader::WaveformRendererSignalBase::Option option, + bool enabled, + WaveformWidgetType::Type type); + void resetWaveformOptions(); + const QVector& getAvailableTypes() const { return m_waveformWidgetHandles; } diff --git a/src/waveform/widgets/waveformwidgettype.h b/src/waveform/widgets/waveformwidgettype.h index 6ed90df786e8..7d65677366b4 100644 --- a/src/waveform/widgets/waveformwidgettype.h +++ b/src/waveform/widgets/waveformwidgettype.h @@ -35,7 +35,5 @@ enum class WaveformWidgetBackend { None = 0, GL, GLSL, -#ifdef MIXXX_USE_QOPENGL AllShader, -#endif };