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 
35 class QOpenGLFunctions_3_2_Core;
36 class QOpenGLTexture;
37 class QmlFilter;
38 class QmlMetadata;
39 
40 namespace Mlt {
41 
42 class Filter;
43 class RenderThread;
44 class FrameRenderer;
45 
46 typedef void *( *thread_function_t )( void * );
47 
48 class 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 
57 public:
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 
126 public 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 
136 signals:
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 
152 private:
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 
188 private 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 
195 protected:
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 
204 class RenderThread : public QThread
205 {
206  Q_OBJECT
207 public:
208  RenderThread(thread_function_t function, void *data, QOpenGLContext *context, QSurface *surface);
209 
210 protected:
211  void run();
212 
213 private:
214  thread_function_t m_function;
215  void *m_data;
216  QOpenGLContext *m_context;
217  QSurface *m_surface;
218 };
219 
220 class FrameRenderer : public QThread
221 {
222  Q_OBJECT
223 public:
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 
242 public slots:
243  void cleanup();
244 
245 signals:
246  void textureReady(GLuint yName, GLuint uName = 0, GLuint vName = 0);
247  void frameDisplayed(const SharedFrame &frame);
248  void imageReady();
249 
250 private:
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 
259 public:
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