MythTV  master
mythpainter_ogl.cpp
Go to the documentation of this file.
1 // Config header generated in base directory by configure
2 #include "config.h"
3 
4 // Own header
5 #include "mythpainter_ogl.h"
6 
7 // QT headers
8 #include <QCoreApplication>
9 #include <QPainter>
10 #include <QGLWidget>
11 
12 // libmythbase headers
13 #include "mythlogging.h"
14 
15 // Mythui headers
16 #include "mythrender_opengl.h"
17 
18 using namespace std;
19 
21  QWidget *parent) :
22  realParent(parent), realRender(render)
23 {
24  if (realRender)
25  LOG(VB_GENERAL, LOG_INFO,
26  "OpenGL painter using existing OpenGL context.");
27  if (realParent)
28  LOG(VB_GENERAL, LOG_INFO, "OpenGL painter using existing QWidget.");
29 }
30 
32 {
33  Teardown();
35 }
36 
38 {
39  ClearCache();
41 }
42 
44 {
45  if (!realRender || m_textureDeleteList.empty())
46  return;
47 
48  QMutexLocker locker(&m_textureDeleteLock);
49  while (!m_textureDeleteList.empty())
50  {
51  uint tex = m_textureDeleteList.front();
54  m_textureDeleteList.pop_front();
55  }
56  realRender->Flush(true);
57 }
58 
60 {
61  LOG(VB_GENERAL, LOG_INFO, "Clearing OpenGL painter cache.");
62 
63  QMutexLocker locker(&m_textureDeleteLock);
64  QMapIterator<MythImage *, unsigned int> it(m_ImageIntMap);
65  while (it.hasNext())
66  {
67  it.next();
68  m_textureDeleteList.push_back(m_ImageIntMap[it.key()]);
69  m_ImageExpireList.remove(it.key());
70  }
71  m_ImageIntMap.clear();
72 }
73 
74 void MythOpenGLPainter::Begin(QPaintDevice *parent)
75 {
76  MythPainter::Begin(parent);
77 
78  if (!realParent)
79  realParent = dynamic_cast<QWidget *>(parent);
80 
81  if (!realRender)
82  {
83  QGLWidget *glw = dynamic_cast<QGLWidget *>(realParent);
84  if (!glw)
85  glw = dynamic_cast<QGLWidget *>(parent);
86 
87  if (!glw)
88  {
89  LOG(VB_GENERAL, LOG_ERR,
90  "FATAL ERROR: Failed to cast parent to QGLWidget");
91  return;
92  }
93 
94  realRender = (MythRenderOpenGL*)(glw->context());
95  if (!realRender)
96  {
97  LOG(VB_GENERAL, LOG_ERR,
98  "FATAL ERROR: Failed to get MythRenderOpenGL");
99  return;
100  }
101  }
102 
103  DeleteTextures();
105 
106  if (target || swapControl)
107  {
109  if (realParent)
110  realRender->SetViewPort(QRect(0, 0, realParent->width(), realParent->height()));
111  realRender->SetColor(255, 255, 255, 255);
112  realRender->SetBackground(0, 0, 0, 0);
114  }
115 }
116 
118 {
119  if (!realRender)
120  {
121  LOG(VB_GENERAL, LOG_ERR, "FATAL ERROR: No render device in 'End'");
122  return;
123  }
124 
125  realRender->Flush(false);
126  if (target == 0 && swapControl)
127  realRender->swapBuffers();
129 
131 }
132 
134 {
135  if (!realRender)
136  return 0;
137 
138  if (m_ImageIntMap.contains(im))
139  {
140  if (!im->IsChanged())
141  {
142  m_ImageExpireList.remove(im);
143  m_ImageExpireList.push_back(im);
144  return m_ImageIntMap[im];
145  }
147  }
148 
149  im->SetChanged(false);
150 
151  QImage tx = QGLWidget::convertToGLFormat(*im);
152  GLuint tx_id = 0;
153  for (;;)
154  {
155  tx_id = realRender->CreateTexture(tx.size(), false, 0,
156  GL_UNSIGNED_BYTE, GL_RGBA, GL_RGBA8,
157  GL_LINEAR_MIPMAP_LINEAR);
158  if (tx_id)
159  break;
160 
161  // This can happen if the cached textures are too big for GPU memory
162  if (m_HardwareCacheSize <= 8 * 1024 * 1024)
163  {
164  LOG(VB_GENERAL, LOG_ERR, "Failed to create OpenGL texture.");
165  return 0;
166  }
167 
168  // Shrink the cache size
170  LOG(VB_GENERAL, LOG_NOTICE, QString(
171  "Shrinking UIPainterMaxCacheHW to %1KB")
172  .arg(m_MaxHardwareCacheSize / 1024));
173 
175  {
176  MythImage *expiredIm = m_ImageExpireList.front();
177  m_ImageExpireList.pop_front();
178  DeleteFormatImagePriv(expiredIm);
179  DeleteTextures();
180  }
181  }
182 
183  CheckFormatImage(im);
185  realRender->GetTextureBuffer(tx_id, false);
186  realRender->UpdateTexture(tx_id, tx.bits());
187 
188  m_ImageIntMap[im] = tx_id;
189  m_ImageExpireList.push_back(im);
190 
192  {
193  MythImage *expiredIm = m_ImageExpireList.front();
194  m_ImageExpireList.pop_front();
195  DeleteFormatImagePriv(expiredIm);
196  DeleteTextures();
197  }
198 
199  return tx_id;
200 }
201 
202 void MythOpenGLPainter::DrawImage(const QRect &r, MythImage *im,
203  const QRect &src, int alpha)
204 {
205  if (realRender)
207  &src, &r, 0, alpha);
208 }
209 
210 void MythOpenGLPainter::DrawRect(const QRect &area, const QBrush &fillBrush,
211  const QPen &linePen, int alpha)
212 {
213  if ((fillBrush.style() == Qt::SolidPattern ||
214  fillBrush.style() == Qt::NoBrush) && realRender)
215  {
216  realRender->DrawRect(area, fillBrush, linePen, alpha);
217  return;
218  }
219  MythPainter::DrawRect(area, fillBrush, linePen, alpha);
220 }
221 
222 void MythOpenGLPainter::DrawRoundRect(const QRect &area, int cornerRadius,
223  const QBrush &fillBrush,
224  const QPen &linePen, int alpha)
225 {
227  {
228  if (fillBrush.style() == Qt::SolidPattern ||
229  fillBrush.style() == Qt::NoBrush)
230  {
231  realRender->DrawRoundRect(area, cornerRadius, fillBrush,
232  linePen, alpha);
233  return;
234  }
235  }
236  MythPainter::DrawRoundRect(area, cornerRadius, fillBrush, linePen, alpha);
237 }
238 
240 {
241  if (m_ImageIntMap.contains(im))
242  {
243  QMutexLocker locker(&m_textureDeleteLock);
244  m_textureDeleteList.push_back(m_ImageIntMap[im]);
245  m_ImageIntMap.remove(im);
246  m_ImageExpireList.remove(im);
247  }
248 }
249 
250 void MythOpenGLPainter::PushTransformation(const UIEffects &fx, QPointF center)
251 {
252  if (realRender)
253  realRender->PushTransformation(fx, center);
254 }
255 
257 {
258  if (realRender)
260 }
void DrawRoundRect(const QRect &area, int cornerRadius, const QBrush &fillBrush, const QPen &linePen, int alpha)
void FreeResources(void) override
virtual void Teardown(void)
Definition: mythpainter.cpp:29
void DrawRect(const QRect &area, const QBrush &fillBrush, const QPen &linePen, int alpha) override
void End() override
void DeleteTexture(uint tex)
void Begin(QPaintDevice *parent) override
virtual void SetChanged(bool change=true)
Definition: mythimage.h:45
int GetTextureDataSize(uint tex)
void DeleteTextures(void)
std::list< uint > m_textureDeleteList
unsigned int uint
Definition: compat.h:140
virtual void DrawRoundRect(const QRect &area, int cornerRadius, const QBrush &fillBrush, const QPen &linePen, int alpha)
virtual void PopTransformation(void)=0
unsigned char r
Definition: ParseText.cpp:329
virtual void SetColor(int, int, int, int)
int m_HardwareCacheSize
Definition: mythpainter.h:129
void SetBackground(int r, int g, int b, int a)
void DrawBitmap(uint tex, uint target, const QRect *src, const QRect *dst, uint prog, int alpha=255, int red=255, int green=255, int blue=255)
virtual void End()
Definition: mythpainter.h:51
void DrawImage(const QRect &r, MythImage *im, const QRect &src, int alpha) override
virtual void PushTransformation(const UIEffects &fx, QPointF &center)=0
std::list< MythImage * > m_ImageExpireList
void Flush(bool use_fence)
void PopTransformation(void) override
void doneCurrent() override
virtual void DrawRect(const QRect &area, const QBrush &fillBrush, const QPen &linePen, int alpha)
void DrawRect(const QRect &area, const QBrush &fillBrush, const QPen &linePen, int alpha)
void UpdateTexture(uint tex, void *buf)
int GetTextureFromCache(MythImage *im)
void * GetTextureBuffer(uint tex, bool create_buffer=true)
void makeCurrent() override
void SetViewPort(const QRect &rect, bool viewportonly=false)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
MythOpenGLPainter(MythRenderOpenGL *render=nullptr, QWidget *parent=nullptr)
#define GL_RGBA
void CheckFormatImage(MythImage *im)
void DeleteFormatImagePriv(MythImage *im) override
bool IsChanged() const
Definition: mythimage.h:46
#define GL_RGBA8
void DrawRoundRect(const QRect &area, int cornerRadius, const QBrush &fillBrush, const QPen &linePen, int alpha) override
uint CreateTexture(QSize act_size, bool use_pbo, uint type, uint data_type=GL_UNSIGNED_BYTE, uint data_fmt=GL_RGBA, uint internal_fmt=GL_RGBA8, uint filter=GL_LINEAR, uint wrap=GL_CLAMP_TO_EDGE)
MythRenderOpenGL * realRender
virtual void Begin(QPaintDevice *parent)
Definition: mythpainter.h:50
void BindFramebuffer(uint fb)
void PushTransformation(const UIEffects &fx, QPointF center=QPointF()) override
QMap< MythImage *, uint > m_ImageIntMap
virtual bool RectanglesAreAccelerated(void)
int m_MaxHardwareCacheSize
Definition: mythpainter.h:130