CuteLogger
Fast and simple logging solution for Qt based applications
glwidget.h
1/*
2 * Copyright (c) 2011-2022 Meltytech, LLC
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef GLWIDGET_H
19#define GLWIDGET_H
20
21#include <QSemaphore>
22#include <QQuickWidget>
23#include <QOpenGLFunctions>
24#include <QOpenGLShaderProgram>
25#include <QOpenGLFramebufferObject>
26#include <QOpenGLContext>
27#include <QOffscreenSurface>
28#include <QMutex>
29#include <QThread>
30#include <QRectF>
31#include <QTimer>
32#include "mltcontroller.h"
33#include "sharedframe.h"
34
35class QOpenGLFunctions_3_2_Core;
36class QOpenGLTexture;
37class QmlFilter;
38class QmlMetadata;
39
40namespace Mlt {
41
42class Filter;
43class RenderThread;
44class FrameRenderer;
45
46typedef void *( *thread_function_t )( void * );
47
48class GLWidget : public QQuickWidget, public Controller, protected QOpenGLFunctions
49{
50 Q_OBJECT
51 Q_PROPERTY(QRectF rect READ rect NOTIFY rectChanged)
52 Q_PROPERTY(int grid READ grid NOTIFY gridChanged)
53 Q_PROPERTY(bool snapToGrid READ snapToGrid NOTIFY snapToGridChanged)
54 Q_PROPERTY(float zoom READ zoom NOTIFY zoomChanged)
55 Q_PROPERTY(QPoint offset READ offset NOTIFY offsetChanged)
56
57public:
58 GLWidget(QObject *parent = 0);
59 ~GLWidget();
60
61 void createThread(RenderThread **thread, thread_function_t function, void *data);
62 void startGlsl();
63 void stopGlsl();
64 int setProducer(Mlt::Producer *, bool isMulti = false);
65 int reconfigure(bool isMulti);
66
67 void play(double speed = 1.0)
68 {
69 Controller::play(speed);
70 if (speed == 0) emit paused();
71 else emit playing();
72 }
73 void seek(int position)
74 {
75 Controller::seek(position);
76 emit paused();
77 }
78 void refreshConsumer(bool scrubAudio = false);
79 void pause()
80 {
81 Controller::pause();
82 emit paused();
83 }
84 int displayWidth() const
85 {
86 return m_rect.width();
87 }
88 int displayHeight() const
89 {
90 return m_rect.height();
91 }
92
93 QObject *videoWidget()
94 {
95 return this;
96 }
97 Filter *glslManager() const
98 {
99 return m_glslManager;
100 }
101 QRectF rect() const
102 {
103 return m_rect;
104 }
105 int grid() const
106 {
107 return m_grid;
108 }
109 float zoom() const
110 {
111 return m_zoom * MLT.profile().width() / m_rect.width();
112 }
113 QPoint offset() const;
114 QImage image() const;
115 bool imageIsProxy() const;
116 void requestImage() const;
117 bool snapToGrid() const
118 {
119 return m_snapToGrid;
120 }
121 int maxTextureSize() const
122 {
123 return m_maxTextureSize;
124 }
125
126public slots:
127 void onFrameDisplayed(const SharedFrame &frame);
128 void setGrid(int grid);
129 void setZoom(float zoom);
130 void setOffsetX(int x);
131 void setOffsetY(int y);
132 void setBlankScene();
133 void setCurrentFilter(QmlFilter *filter, QmlMetadata *meta);
134 void setSnapToGrid(bool snap);
135
136signals:
137 void frameDisplayed(const SharedFrame &frame);
138 void dragStarted();
139 void seekTo(int x);
140 void gpuNotSupported();
141 void started();
142 void paused();
143 void playing();
144 void rectChanged();
145 void gridChanged();
146 void zoomChanged();
147 void offsetChanged(const QPoint &offset = QPoint());
148 void imageReady();
149 void snapToGridChanged();
150 void toggleZoom(bool);
151
152private:
153 QRectF m_rect;
154 int m_grid;
155 GLuint m_texture[3];
156 QOpenGLShaderProgram *m_shader;
157 QPoint m_dragStart;
158 Filter *m_glslManager;
159 QSemaphore m_initSem;
160 bool m_isInitialized;
161 Event *m_threadStartEvent;
162 Event *m_threadStopEvent;
163 Event *m_threadCreateEvent;
164 Event *m_threadJoinEvent;
165 FrameRenderer *m_frameRenderer;
166 int m_projectionLocation;
167 int m_modelViewLocation;
168 int m_vertexLocation;
169 int m_texCoordLocation;
170 int m_colorspaceLocation;
171 int m_textureLocation[3];
172 float m_zoom;
173 QPoint m_offset;
174 QOffscreenSurface m_offscreenSurface;
175 QOpenGLContext *m_shareContext;
176 SharedFrame m_sharedFrame;
177 QMutex m_mutex;
178 QUrl m_savedQmlSource;
179 bool m_snapToGrid;
180 QTimer m_refreshTimer;
181 bool m_scrubAudio;
182 GLint m_maxTextureSize;
183 QPoint m_mousePosition;
184
185
186 static void on_frame_show(mlt_consumer, GLWidget *widget, mlt_event_data);
187
188private slots:
189 void initializeGL();
190 void resizeGL(int width, int height);
191 void updateTexture(GLuint yName, GLuint uName, GLuint vName);
192 void paintGL();
193 void onRefreshTimeout();
194
195protected:
196 void resizeEvent(QResizeEvent *event);
197 void mousePressEvent(QMouseEvent *);
198 void mouseMoveEvent(QMouseEvent *);
199 void keyPressEvent(QKeyEvent *event);
200 bool event(QEvent *event);
201 void createShader();
202};
203
204class RenderThread : public QThread
205{
206 Q_OBJECT
207public:
208 RenderThread(thread_function_t function, void *data, QOpenGLContext *context, QSurface *surface);
209
210protected:
211 void run();
212
213private:
214 thread_function_t m_function;
215 void *m_data;
216 QOpenGLContext *m_context;
217 QSurface *m_surface;
218};
219
220class FrameRenderer : public QThread
221{
222 Q_OBJECT
223public:
224 FrameRenderer(QOpenGLContext *shareContext, QSurface *surface);
225 ~FrameRenderer();
226 QSemaphore *semaphore()
227 {
228 return &m_semaphore;
229 }
230 QOpenGLContext *context() const
231 {
232 return m_context;
233 }
234 SharedFrame getDisplayFrame();
235 Q_INVOKABLE void showFrame(Mlt::Frame frame);
236 void requestImage();
237 QImage image() const
238 {
239 return m_image;
240 }
241
242public slots:
243 void cleanup();
244
245signals:
246 void textureReady(GLuint yName, GLuint uName = 0, GLuint vName = 0);
247 void frameDisplayed(const SharedFrame &frame);
248 void imageReady();
249
250private:
251 QSemaphore m_semaphore;
252 SharedFrame m_displayFrame;
253 QOpenGLContext *m_context;
254 QSurface *m_surface;
255 qint64 m_previousMSecs;
256 bool m_imageRequested;
257 QImage m_image;
258
259public:
260 GLuint m_renderTexture[3];
261 GLuint m_displayTexture[3];
262 QOpenGLFunctions_3_2_Core *m_gl32;
263};
264
265} // namespace
266
267#endif
The SharedFrame provides thread safe access to Mlt::Frame data.
Definition: sharedframe.h:49