MythTV  master
mythrender_opengl.h
Go to the documentation of this file.
1 #ifndef MYTHRENDER_OPENGL_H_
2 #define MYTHRENDER_OPENGL_H_
3 
4 #include <cstdint>
5 
6 #include <QtGlobal>
7 // The below is commented because it causes raspberry Pi with OpenMAX
8 // to fail. If commenting it out causes problems with other
9 // platforms we can add it back with additional conditions that
10 // will exclude it for Raspberry Pi. With this commented, all
11 // code that depends on USE_OPENGL_QT5 will be bypassed and maybe can
12 // be removed later.
13 #if defined USING_OPENGLES && QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) && defined(ANDROID)
14 #define USE_OPENGL_QT5
15 #include <QOpenGLContext>
16 #else
17 #include <QGLContext>
18 #endif
19 #include <QHash>
20 #include <QMutex>
21 #include <QMatrix4x4>
22 
23 #define GL_GLEXT_PROTOTYPES
24 
25 #ifdef USING_X11
26 #define GLX_GLXEXT_PROTOTYPES
27 #define XMD_H 1
28 #undef GLX_ARB_get_proc_address
29 #endif // USING_X11
30 
31 #ifdef _WIN32
32 #include <GL/glext.h>
33 #endif
34 
35 #ifdef Q_OS_MAC
36 #include "util-osx.h"
37 #import <AGL/agl.h>
38 #endif
39 
40 #include "mythuiexp.h"
41 #include "mythlogging.h"
42 #include "mythrender_base.h"
43 #include "mythrender_opengl_defs.h"
44 
45 #include "mythuianimation.h"
46 
47 typedef enum
48 {
49  kGLFeatNone = 0x0000,
50  kGLMultiTex = 0x0001,
51  kGLExtRect = 0x0002,
52  kGLExtFragProg = 0x0004,
53  kGLExtFBufObj = 0x0008,
54  kGLExtPBufObj = 0x0010,
55  kGLNVFence = 0x0020,
56  kGLAppleFence = 0x0040,
57  kGLMesaYCbCr = 0x0080,
58  kGLAppleYCbCr = 0x0100,
59  kGLMipMaps = 0x0200,
60  kGLSL = 0x0400,
61  kGLVertexArray = 0x0800,
62  kGLExtVBO = 0x1000,
63  kGLExtRGBA16 = 0x2000,
64  kGLMaxFeat = 0x4000,
65 } GLFeatures;
66 
67 #define TEX_OFFSET 8
68 
70 {
71  public:
73  {
74  memset(&m_vertex_data, 0, sizeof(m_vertex_data));
75  }
76 
78  {
79  }
80 
81  GLuint m_type {GL_TEXTURE_2D};
82  unsigned char *m_data {nullptr};
84  GLuint m_data_type {GL_UNSIGNED_BYTE};
85  GLuint m_data_fmt {GL_RGBA};
87  GLuint m_pbo {0};
88  GLuint m_vbo {0};
89  GLuint m_filter {GL_LINEAR};
90  GLuint m_wrap {GL_CLAMP_TO_EDGE};
91  QSize m_size {0,0};
92  QSize m_act_size {0,0};
93  GLfloat m_vertex_data[16];
94 };
95 
96 class MythRenderOpenGL;
97 
99 {
100  public:
101  explicit OpenGLLocker(MythRenderOpenGL *render);
102  ~OpenGLLocker();
103  private:
104  MythRenderOpenGL *m_render {nullptr};
105 };
106 
107 #ifdef USE_OPENGL_QT5
108 typedef class QSurfaceFormat MythRenderFormat;
109 typedef class QOpenGLContext MythRenderContext;
110 class QWindow;
111 #else
112 typedef class QGLFormat MythRenderFormat;
113 typedef class QGLContext MythRenderContext;
114 #endif
115 
116 class QPaintDevice;
117 
119 {
120  public:
121  static MythRenderOpenGL* Create(const QString &painter,
122  QPaintDevice* device = nullptr);
123 
124  MythRenderOpenGL(const MythRenderFormat &format, QPaintDevice* device,
127 
128 #ifdef USE_OPENGL_QT5
129  // These functions are not virtual in the base QOpenGLContext
130  // class, so these are not overrides but new functions.
131  virtual void makeCurrent();
132  virtual void doneCurrent();
133 #else
134  // These functions are virtual in the base QGLContext class, so
135  // these are overrides of those functions.
136  void makeCurrent() override; // MythRenderContext
137  void doneCurrent() override; // MythRenderContext
138 #endif
139  void Release(void) override; // MythRender
140 
141  using MythRenderContext::create;
142 #ifdef USE_OPENGL_QT5
143  virtual void swapBuffers();
144  void setWidget(QWidget *w);
145 #else
146  using MythRenderContext::swapBuffers;
147  void setWidget(QGLWidget *w);
148 #endif
149  bool IsDirectRendering() const;
150 
151  void Init(void);
152 
153  int GetMaxTextureSize(void) { return m_max_tex_size; }
154  uint GetFeatures(void) { return m_exts_used; }
155 
156  bool IsRecommendedRenderer(void);
157 
158  void MoveResizeWindow(const QRect &rect);
159  void SetViewPort(const QRect &rect, bool viewportonly = false);
160  QRect GetViewPort(void) { return m_viewport; }
161  virtual void PushTransformation(const UIEffects &fx, QPointF &center) = 0;
162  virtual void PopTransformation(void) = 0;
163  void Flush(bool use_fence);
164  void SetBlend(bool enable);
165  virtual void SetColor(int /*r*/, int /*g*/, int /*b*/, int /*a*/) { }
166  void SetBackground(int r, int g, int b, int a);
167  void SetFence(void);
168 
169  void* GetTextureBuffer(uint tex, bool create_buffer = true);
170  void UpdateTexture(uint tex, void *buf);
171  int GetTextureType(bool &rect);
172  bool IsRectTexture(uint type);
173  uint CreateHelperTexture(void);
174  uint CreateTexture(QSize act_size, bool use_pbo, uint type,
175  uint data_type = GL_UNSIGNED_BYTE,
176  uint data_fmt = GL_RGBA, uint internal_fmt = GL_RGBA8,
177  uint filter = GL_LINEAR, uint wrap = GL_CLAMP_TO_EDGE);
178  QSize GetTextureSize(uint type, const QSize &size);
179  QSize GetTextureSize(uint tex);
180  int GetTextureDataSize(uint tex);
181  void SetTextureFilters(uint tex, uint filt, uint wrap);
182  void ActiveTexture(int active_tex);
183  void EnableTextures(uint tex, uint tex_type = 0);
184  void DisableTextures(void);
185  void DeleteTexture(uint tex);
186 
187  bool CreateFrameBuffer(uint &fb, uint tex);
188  void DeleteFrameBuffer(uint fb);
189  void BindFramebuffer(uint fb);
190  void ClearFramebuffer(void);
191 
192  virtual uint CreateShaderObject(const QString &vert, const QString &frag) = 0;
193  virtual void DeleteShaderObject(uint obj) = 0;
194  virtual void EnableShaderObject(uint obj) = 0;
195  virtual void SetShaderParams(uint prog, const QMatrix4x4 &m, const char* uniform) = 0;
196 
197  void DrawBitmap(uint tex, uint target, const QRect *src,
198  const QRect *dst, uint prog, int alpha = 255,
199  int red = 255, int green = 255, int blue = 255);
200  void DrawBitmap(uint *textures, uint texture_count, uint target,
201  const QRectF *src, const QRectF *dst, uint prog);
202  void DrawRect(const QRect &area, const QBrush &fillBrush,
203  const QPen &linePen, int alpha);
204  void DrawRoundRect(const QRect &area, int cornerRadius,
205  const QBrush &fillBrush, const QPen &linePen,
206  int alpha);
207  virtual bool RectanglesAreAccelerated(void) { return false; }
208 
209  protected:
210  virtual ~MythRenderOpenGL() = default;
211  virtual void DrawBitmapPriv(uint tex, const QRect *src, const QRect *dst,
212  uint prog, int alpha,
213  int red, int green, int blue) = 0;
214  virtual void DrawBitmapPriv(uint *textures, uint texture_count,
215  const QRectF *src, const QRectF *dst,
216  uint prog) = 0;
217  virtual void DrawRectPriv(const QRect &area, const QBrush &fillBrush,
218  const QPen &linePen, int alpha) = 0;
219  virtual void DrawRoundRectPriv(const QRect &area, int cornerRadius,
220  const QBrush &fillBrush, const QPen &linePen,
221  int alpha) = 0;
222 
223  virtual void Init2DState(void);
224  virtual void InitProcs(void);
225  void* GetProcAddress(const QString &proc) const;
226  virtual bool InitFeatures(void);
227  virtual void ResetVars(void);
228  virtual void ResetProcs(void);
229  virtual void SetMatrixView(void) = 0;
230 
231  uint CreatePBO(uint tex);
232  uint CreateVBO(void);
233  virtual void DeleteOpenGLResources(void);
234  void DeleteTextures(void);
235  virtual void DeleteShaders(void) = 0;
236  void DeleteFrameBuffers(void);
237 
238  bool UpdateTextureVertices(uint tex, const QRect *src, const QRect *dst);
239  bool UpdateTextureVertices(uint tex, const QRectF *src, const QRectF *dst);
240  GLfloat* GetCachedVertices(GLuint type, const QRect &area);
241  void ExpireVertices(uint max = 0);
242  void GetCachedVBO(GLuint type, const QRect &area);
243  void ExpireVBOS(uint max = 0);
244  bool ClearTexture(uint tex);
245  uint GetBufferSize(QSize size, uint fmt, uint type);
246 
247  static void StoreBicubicWeights(float x, float *dst);
248 
249  protected:
250  // Resources
251  QHash<GLuint, MythGLTexture> m_textures;
252  QVector<GLuint> m_framebuffers;
253  GLuint m_fence {0};
254 
255  // Locking
256  QMutex m_lock;
257  int m_lock_level {0};
258 
259  // profile
260  QString m_extensions;
261  uint m_exts_supported {kGLFeatNone};
262  uint m_exts_used {kGLFeatNone};
263  int m_max_tex_size {0};
264  int m_max_units {0};
265  int m_default_texture_type {GL_TEXTURE_2D};
266 
267  // State
268  QRect m_viewport;
269  int m_active_tex {0};
270  int m_active_tex_type {0};
271  int m_active_fb {0};
272  bool m_blend {false};
273  uint32_t m_background {0x00000000};
274 
275  // vertex cache
276  QMap<uint64_t,GLfloat*> m_cachedVertices;
277  QList<uint64_t> m_vertexExpiry;
278  QMap<uint64_t,GLuint> m_cachedVBOS;
279  QList<uint64_t> m_vboExpiry;
280 
281  // For Performance improvement set false to disable glFlush.
282  // Needed for Raspberry pi
283  bool m_flushEnabled {true};
284 
285  // Multi-texturing
286  MYTH_GLACTIVETEXTUREPROC m_glActiveTexture {nullptr};
287 
288  // PixelBuffer Objects
289  MYTH_GLMAPBUFFERPROC m_glMapBuffer {nullptr};
290  MYTH_GLBINDBUFFERPROC m_glBindBuffer {nullptr};
291  MYTH_GLGENBUFFERSPROC m_glGenBuffers {nullptr};
292  MYTH_GLBUFFERDATAPROC m_glBufferData {nullptr};
293  MYTH_GLUNMAPBUFFERPROC m_glUnmapBuffer {nullptr};
294  MYTH_GLDELETEBUFFERSPROC m_glDeleteBuffers {nullptr};
295  // FrameBuffer Objects
296  MYTH_GLGENFRAMEBUFFERSPROC m_glGenFramebuffers {nullptr};
297  MYTH_GLBINDFRAMEBUFFERPROC m_glBindFramebuffer {nullptr};
298  MYTH_GLFRAMEBUFFERTEXTURE2DPROC m_glFramebufferTexture2D {nullptr};
299  MYTH_GLCHECKFRAMEBUFFERSTATUSPROC m_glCheckFramebufferStatus {nullptr};
300  MYTH_GLDELETEFRAMEBUFFERSPROC m_glDeleteFramebuffers {nullptr};
301  // NV_fence
302  MYTH_GLGENFENCESNVPROC m_glGenFencesNV {nullptr};
303  MYTH_GLDELETEFENCESNVPROC m_glDeleteFencesNV {nullptr};
304  MYTH_GLSETFENCENVPROC m_glSetFenceNV {nullptr};
305  MYTH_GLFINISHFENCENVPROC m_glFinishFenceNV {nullptr};
306  // APPLE_fence
307  MYTH_GLGENFENCESAPPLEPROC m_glGenFencesAPPLE {nullptr};
308  MYTH_GLDELETEFENCESAPPLEPROC m_glDeleteFencesAPPLE {nullptr};
309  MYTH_GLSETFENCEAPPLEPROC m_glSetFenceAPPLE {nullptr};
310  MYTH_GLFINISHFENCEAPPLEPROC m_glFinishFenceAPPLE {nullptr};
311 
312 #ifdef USE_OPENGL_QT5
313  private:
314  QWindow *m_window {nullptr};
315 #endif
316 };
317 
332 {
333  public:
334  explicit GLMatrix4x4(const QMatrix4x4 &m)
335  {
336  // Convert from Qt's row-major to GL's column-major order
337  for (int c = 0, i = 0; c < 4; ++c)
338  for (int r = 0; r < 4; ++r)
339  m_v[i++] = m(r, c);
340  }
341 
342  explicit GLMatrix4x4(const GLfloat v[16])
343  {
344  for (int i = 0; i < 16; ++i)
345  m_v[i] = v[i];
346  }
347 
348  operator const GLfloat*() const { return m_v; }
349 
350  operator QMatrix4x4() const
351  {
352  // Convert from GL's column-major order to Qt's row-major
353  QMatrix4x4 m;
354  for (int c = 0, i = 0; c < 4; ++c)
355  for (int r = 0; r < 4; ++r)
356  m(r, c) = m_v[i++];
357  return m;
358  }
359 
360  private:
361  GLfloat m_v[4*4];
362 };
363 
364 #endif
void(APIENTRY * MYTH_GLBUFFERDATAPROC)(GLenum target, MYTH_GLsizeiptr size, const GLvoid *data, GLenum usage)
GLvoid *(APIENTRY * MYTH_GLMAPBUFFERPROC)(GLenum target, GLenum access)
GLMatrix4x4(const QMatrix4x4 &m)
int GetMaxTextureSize(void)
void(* MYTH_GLDELETEFENCESAPPLEPROC)(GLsizei n, const GLuint *fences)
QList< uint64_t > m_vertexExpiry
GLenum(APIENTRY * MYTH_GLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target)
void(APIENTRY * MYTH_GLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint *framebuffers)
void(* MYTH_GLSETFENCEAPPLEPROC)(GLuint fence)
unsigned int uint
Definition: compat.h:140
GLboolean(APIENTRY * MYTH_GLUNMAPBUFFERPROC)(GLenum target)
unsigned char r
Definition: ParseText.cpp:329
GLfloat m_vertex_data[16]
virtual void SetColor(int, int, int, int)
QVector< GLuint > m_framebuffers
unsigned char b
Definition: ParseText.cpp:329
QList< uint64_t > m_vboExpiry
QMap< uint64_t, GLfloat * > m_cachedVertices
void(APIENTRY * MYTH_GLSETFENCENVPROC)(GLuint fence, GLenum condition)
void(APIENTRY * MYTH_GLDELETEFENCESNVPROC)(GLsizei n, const GLuint *fences)
void(APIENTRY * MYTH_GLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
void(APIENTRY * MYTH_GLACTIVETEXTUREPROC)(GLenum texture)
GLFeatures
class QGLFormat MythRenderFormat
void(* MYTH_GLFINISHFENCEAPPLEPROC)(GLuint fence)
QHash< GLuint, MythGLTexture > m_textures
void(APIENTRY * MYTH_GLFINISHFENCENVPROC)(GLuint fence)
QRect GetViewPort(void)
class QGLContext MythRenderContext
void(APIENTRY * MYTH_GLGENFENCESNVPROC)(GLsizei n, GLuint *fences)
#define MUI_PUBLIC
Definition: mythuiexp.h:9
#define GL_RGBA
void(APIENTRY * MYTH_GLBINDBUFFERPROC)(GLenum target, GLuint buffer)
virtual void Release(void)
void(* MYTH_GLGENFENCESAPPLEPROC)(GLsizei n, GLuint *fences)
GLfloat m_v[4 *4]
RenderType
#define GL_RGBA8
void(APIENTRY * MYTH_GLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint *framebuffers)
GLMatrix4x4 is a helper class to convert between QT and GT 4x4 matrices.
unsigned char * m_data
QMap< uint64_t, GLuint > m_cachedVBOS
void(APIENTRY * MYTH_GLGENBUFFERSPROC)(GLsizei n, GLuint *buffers)
void(APIENTRY * MYTH_GLDELETEBUFFERSPROC)(GLsizei n, const GLuint *buffers)
GLMatrix4x4(const GLfloat v[16])
virtual bool RectanglesAreAccelerated(void)
unsigned char g
Definition: ParseText.cpp:329
void(APIENTRY * MYTH_GLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer)