forked from mixxxdj/mixxx
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathwaveformwidgetfactory.h
More file actions
362 lines (304 loc) · 11.9 KB
/
Copy pathwaveformwidgetfactory.h
File metadata and controls
362 lines (304 loc) · 11.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
#pragma once
#include <QObject>
#include <QSurfaceFormat>
#include <QVector>
#include <vector>
#include "preferences/usersettings.h"
#include "skin/legacy/skincontext.h"
#include "util/performancetimer.h"
#include "util/singleton.h"
#include "waveform/renderers/allshader/waveformrenderersignalbase.h"
#include "waveform/widgets/waveformwidgettype.h"
#include "waveform/widgets/waveformwidgetvars.h"
class WVuMeterLegacy;
class WVuMeterBase;
class WWaveformViewer;
class WaveformWidgetAbstract;
class VSyncThread;
class GuiTick;
class VisualsManager;
class WaveformWidgetAbstractHandle {
public:
WaveformWidgetAbstractHandle();
WaveformWidgetAbstractHandle(WaveformWidgetType::Type type,
QList<WaveformWidgetBackend> backends
#ifdef MIXXX_USE_QOPENGL
,
int supportedOptions
#endif
)
: m_type(type), m_backends(std::move(backends))
#ifdef MIXXX_USE_QOPENGL
,
m_supportedOption(supportedOptions)
#endif
{
}
WaveformWidgetType::Type getType() const { return m_type;}
const QList<WaveformWidgetBackend>& getBackend() const {
return m_backends;
}
bool supportAcceleration() const {
for (auto backend : m_backends) {
if (backend == WaveformWidgetBackend::GL ||
backend == WaveformWidgetBackend::GLSL
#ifdef MIXXX_USE_QOPENGL
|| backend == WaveformWidgetBackend::AllShader
#endif
) {
return true;
}
}
return false;
}
bool supportSoftware() const {
return m_backends.contains(WaveformWidgetBackend::None);
}
#ifdef MIXXX_USE_QOPENGL
allshader::WaveformRendererSignalBase::Options supportedOptions(
WaveformWidgetBackend backend) const {
return backend == WaveformWidgetBackend::AllShader
? m_supportedOption
: allshader::WaveformRendererSignalBase::Option::None;
}
#endif
QString getDisplayName() const;
static QString getDisplayName(WaveformWidgetType::Type type);
private:
WaveformWidgetType::Type m_type;
QList<WaveformWidgetBackend> m_backends;
#ifdef MIXXX_USE_QOPENGL
// Only relevant for Allshader (accelerated) backend. Other backends don't implement options
allshader::WaveformRendererSignalBase::Options m_supportedOption;
#endif
friend class WaveformWidgetFactory;
};
class WaveformWidgetHolder {
public:
WaveformWidgetHolder();
WaveformWidgetHolder(WaveformWidgetHolder&&) = default;
WaveformWidgetHolder& operator=(WaveformWidgetHolder&&) = default;
private:
WaveformWidgetHolder(
WaveformWidgetAbstract* waveformWidget,
WWaveformViewer* waveformViewer,
const QDomNode& skinNode,
const SkinContext& parentContext);
WaveformWidgetAbstract* m_waveformWidget;
WWaveformViewer* m_waveformViewer;
QDomNode m_skinNodeCache;
SkinContext m_skinContextCache;
friend class WaveformWidgetFactory;
};
//########################################
class WaveformWidgetFactory : public QObject,
public Singleton<WaveformWidgetFactory> {
Q_OBJECT
public:
bool setConfig(UserSettingsPointer config);
/// 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,
const SkinContext& parentContext);
void setFrameRate(int frameRate);
int getFrameRate() const { return m_frameRate;}
// bool getVSync() const { return m_vSyncType;}
void setEndOfTrackWarningTime(int endTime);
int getEndOfTrackWarningTime() const { return m_endOfTrackWarningTime;}
/// Returns whether Mixxx has started with Open GL support. In this case
/// isOpenGlesAvailable() returns false.
/// Note: The Macro MIXXX_USE_QOPENGL selects the Qt6 openGL implementation
/// Of Qt inside the Mixxx source.
bool isOpenGlAvailable() const { return m_openGlAvailable;}
/// Returns whether Mixxx has started with Open GLES support. In this case
/// isOpenGlAvailable() returns false. It may also happen that
bool isOpenGlesAvailable() const { return m_openGlesAvailable;}
QString getOpenGLVersion() const { return m_openGLVersion;}
bool isOpenGlShaderAvailable() const { return m_openGLShaderAvailable;}
WaveformWidgetBackend getBackendFromConfig() const;
WaveformWidgetBackend preferredBackend() const;
static WaveformWidgetType::Type defaultType() {
return WaveformWidgetType::RGB;
}
void setDefaultBackend();
/// Sets the widget type and saves it to configuration.
/// Returns false and sets EmtpyWaveform if type is invalid
bool setWidgetType(WaveformWidgetType::Type type);
/// 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;}
QString getTypeDisplayName() const {
return WaveformWidgetAbstractHandle::getDisplayName(m_type);
}
int getHandleIndex() {
return findHandleIndexFromType(m_type);
}
int findHandleIndexFromType(WaveformWidgetType::Type type);
bool widgetTypeSupportsAcceleration(WaveformWidgetType::Type type);
bool widgetTypeSupportsSoftware(WaveformWidgetType::Type type);
bool widgetTypeSupportsUntilMark() const;
bool widgetTypeSupportsStems() const;
void setUntilMarkShowBeats(bool value);
void setUntilMarkShowTime(bool value);
void setUntilMarkAlign(Qt::Alignment align);
void setUntilMarkTextPointSize(int value);
void setUntilMarkTextHeightLimit(float value);
void setStemReorderOnChange(bool value);
void setStemOutlineOpacity(float value);
void setStemOpacity(float value);
bool getUntilMarkShowBeats() const {
return m_untilMarkShowBeats;
}
bool getUntilMarkShowTime() const {
return m_untilMarkShowTime;
}
Qt::Alignment getUntilMarkAlign() const {
return m_untilMarkAlign;
}
int getUntilMarkTextPointSize() const {
return m_untilMarkTextPointSize;
}
float getUntilMarkTextHeightLimit() const {
return m_untilMarkTextHeightLimit;
}
bool isStemReorderOnChange() const {
return m_stemReorderOnChange;
}
float getStemOutlineOpacity() const {
return m_stemOutlineOpacity;
}
float getStemOpacity() const {
return m_stemOpacity;
}
static Qt::Alignment toUntilMarkAlign(int index);
static int toUntilMarkAlignIndex(Qt::Alignment align);
static float toUntilMarkTextHeightLimit(int index);
static int toUntilMarkTextHeightLimitIndex(float value);
/// Returns the desired surface format for the OpenGLWindow
static QSurfaceFormat getSurfaceFormat(UserSettingsPointer pConfig = nullptr);
protected:
bool setWidgetType(
WaveformWidgetType::Type type,
WaveformWidgetType::Type* pCurrentType);
public:
void setDefaultZoom(double zoom);
double getDefaultZoom() const { return m_defaultZoom;}
void setZoomSync(bool sync);
int isZoomSync() const { return m_zoomSync;}
void setDisplayBeatGridAlpha(int alpha);
int getBeatGridAlpha() const { return m_beatGridAlpha; }
void setVisualGain(BandIndex index, double gain);
double getVisualGain(BandIndex index) const;
static double getVisualGainDefault(BandIndex index);
void setOverviewNormalized(bool normalize);
bool isOverviewNormalized() const {
return m_overviewNormalized;
}
static bool isOverviewNormalizedDefault();
const QVector<WaveformWidgetAbstractHandle>& getAvailableTypes() const {
return m_waveformWidgetHandles;
}
void getAvailableVSyncTypes(QList<QPair<int, QString>>* list);
void destroyWidgets();
void addVuMeter(WVuMeterLegacy* pWidget);
void addVuMeter(WVuMeterBase* pWidget);
void startVSync(GuiTick* pGuiTick, VisualsManager* pVisualsManager, bool useQML);
void setPlayMarkerPosition(double position);
double getPlayMarkerPosition() const { return m_playMarkerPosition; }
void notifyZoomChange(WWaveformViewer *viewer);
signals:
void waveformUpdateTick();
void waveformMeasured(float frameRate, int droppedFrames);
void renderSpinnies(VSyncThread*);
void swapSpinnies();
void renderVuMeters(VSyncThread*);
void swapVuMeters();
void overviewScalingChanged();
void visualGainChanged(double allChannelGain, double lowGain, double midGain, double highGain);
void untilMarkShowBeatsChanged(bool value);
void untilMarkShowTimeChanged(bool value);
void untilMarkAlignChanged(Qt::Alignment align);
void untilMarkTextPointSizeChanged(int value);
void untilMarkTextHeightLimitChanged(float value);
void stemReorderOnChangeChanged(bool value);
void stemOutlineOpacityChanged(float value);
void stemOpacityChanged(float value);
public slots:
void slotSkinLoaded();
protected:
WaveformWidgetFactory();
virtual ~WaveformWidgetFactory();
friend class Singleton<WaveformWidgetFactory>;
private slots:
void render();
void swap();
void swapAndRender();
void slotFrameSwapped();
private:
void renderSelf();
void swapSelf();
void addHandle(
QHash<WaveformWidgetType::Type, QList<WaveformWidgetBackend>>&
collectedHandles,
WaveformWidgetType::Type type,
const WaveformWidgetVars& vars) const;
void evaluateWidgets();
template<typename WaveformT>
QString buildWidgetDisplayName() const;
WaveformWidgetAbstract* createAllshaderWaveformWidget(
WaveformWidgetType::Type type, WWaveformViewer* viewer);
WaveformWidgetAbstract* createWaveformWidget(
WaveformWidgetType::Type type, WWaveformViewer* pViewer);
int findIndexOf(WWaveformViewer* viewer) const;
WaveformWidgetType::Type findTypeFromHandleIndex(int index);
//All type of available widgets
QVector<WaveformWidgetAbstractHandle> m_waveformWidgetHandles;
//Currently in use widgets/visual/node
std::vector<WaveformWidgetHolder> m_waveformWidgetHolders;
WaveformWidgetType::Type m_type;
WaveformWidgetType::Type m_configType;
UserSettingsPointer m_config;
bool m_skipRender;
int m_frameRate;
int m_endOfTrackWarningTime;
double m_defaultZoom;
bool m_zoomSync;
double m_visualGain[BandCount];
bool m_overviewNormalized;
bool m_untilMarkShowBeats;
bool m_untilMarkShowTime;
Qt::Alignment m_untilMarkAlign;
int m_untilMarkTextPointSize;
float m_untilMarkTextHeightLimit;
bool m_stemReorderOnChange;
float m_stemOutlineOpacity;
float m_stemOpacity;
bool m_openGlAvailable;
bool m_openGlesAvailable;
QString m_openGLVersion;
bool m_openGLShaderAvailable;
int m_beatGridAlpha;
VSyncThread* m_vsyncThread;
GuiTick* m_pGuiTick; // not owned
VisualsManager* m_pVisualsManager; // not owned
// TODO(#13245): Migrate the following methods to smart pointer.
WaveformWidgetAbstract* createFilteredWaveformWidget(WWaveformViewer* viewer);
WaveformWidgetAbstract* createHSVWaveformWidget(WWaveformViewer* viewer);
WaveformWidgetAbstract* createRGBWaveformWidget(WWaveformViewer* viewer);
WaveformWidgetAbstract* createStackedWaveformWidget(WWaveformViewer* viewer);
WaveformWidgetAbstract* createSimpleWaveformWidget(WWaveformViewer* viewer);
WaveformWidgetAbstract* createVSyncTestWaveformWidget(WWaveformViewer* viewer);
//Debug
PerformanceTimer m_time;
float m_frameCnt;
double m_actualFrameRate;
int m_vSyncType;
double m_playMarkerPosition;
};