MythTV master
mythpainter_d3d9.cpp
Go to the documentation of this file.
1// QT headers
2#include <QApplication>
3#include <QPainter>
4#include <QMutex>
5
6// Mythdb headers
8
9// Mythui headers
10#include "mythpainter_d3d9.h"
11
12#define LOC QString("D3D9 Painter: ")
13
15 MythPainter(), m_render(render)
16{
17 if (m_render)
19}
20
22{
24}
25
26bool MythD3D9Painter::InitD3D9(QPaintDevice *parent)
27{
28 if (m_render)
29 return true;
30
31 QWidget *real_parent = (QWidget*)parent;
32 if (!real_parent)
33 return false;
34
36 if (!m_render)
37 return false;
38
39 if (m_render->Create(real_parent->size(), (HWND)real_parent->winId()))
40 return true;
41
42 Teardown();
43 return false;
44}
45
47{
49 ClearCache();
51
52 m_ImageBitmapMap.clear();
53 m_ImageExpireList.clear();
54 m_bitmapDeleteList.clear();
55
56 if (m_render)
57 {
59 m_render = nullptr;
60 }
61}
62
64{
65 ClearCache();
67}
68
69void MythD3D9Painter::Begin(QPaintDevice *parent)
70{
71 if (!m_render)
72 {
73 if (!InitD3D9(parent))
74 {
75 LOG(VB_GENERAL, LOG_ERR, "Failed to create D3D9 render.");
76 return;
77 }
78 }
79
81
82 if (!m_target)
83 {
84 bool dummy;
85 m_render->Test(dummy); // TODO recreate if necessary
86 }
87 else if (!m_target->SetAsRenderTarget())
88 {
89 LOG(VB_GENERAL, LOG_ERR, "Failed to enable offscreen buffer.");
90 return;
91 }
92
93 if (m_target)
96 m_render->Begin();
97 MythPainter::Begin(parent);
98}
99
101{
102 if (m_render)
103 {
104 if (m_swap_control)
105 {
106 m_render->End();
107 m_render->Present(nullptr);
108 }
109 if (m_target)
110 m_render->SetRenderTarget(nullptr);
111 }
113}
114
116{
117 LOG(VB_GENERAL, LOG_INFO, LOC + "Clearing D3D9 painter cache.");
118
119 QMutexLocker locker(&m_bitmapDeleteLock);
120 QMapIterator<MythImage *, D3D9Image*> it(m_ImageBitmapMap);
121 while (it.hasNext())
122 {
123 it.next();
124 m_bitmapDeleteList.push_back(m_ImageBitmapMap[it.key()]);
125 m_ImageExpireList.remove(it.key());
126 }
127 m_ImageBitmapMap.clear();
128}
129
131{
132 QMutexLocker locker(&m_bitmapDeleteLock);
133 while (!m_bitmapDeleteList.empty())
134 {
135 D3D9Image *img = m_bitmapDeleteList.front();
136 m_bitmapDeleteList.pop_front();
138 delete img;
139 }
140}
141
142void MythD3D9Painter::DrawImage(const QRect r, MythImage *im,
143 const QRect src, int alpha)
144{
145 D3D9Image *image = GetImageFromCache(im);
146 if (image)
147 {
148 image->UpdateVertices(r, src, alpha);
149 image->Draw();
150 }
151}
152
153void MythD3D9Painter::DrawRect(const QRect area, const QBrush &fillBrush,
154 const QPen &linePen, int alpha)
155{
156 int style = fillBrush.style();
157 if (style == Qt::SolidPattern || style == Qt::NoBrush)
158 {
159 if (!m_render)
160 return;
161
162 if (style != Qt::NoBrush)
163 m_render->DrawRect(area, fillBrush.color(), alpha);
164
165 if (linePen.style() != Qt::NoPen)
166 {
167 int lineWidth = linePen.width();
168 QRect top(QPoint(area.x(), area.y()),
169 QSize(area.width(), lineWidth));
170 QRect bot(QPoint(area.x(), area.y() + area.height() - lineWidth),
171 QSize(area.width(), lineWidth));
172 QRect left(QPoint(area.x(), area.y()),
173 QSize(lineWidth, area.height()));
174 QRect right(QPoint(area.x() + area.width() - lineWidth, area.y()),
175 QSize(lineWidth, area.height()));
176 m_render->DrawRect(top, linePen.color(), alpha);
177 m_render->DrawRect(bot, linePen.color(), alpha);
178 m_render->DrawRect(left, linePen.color(), alpha);
179 m_render->DrawRect(right, linePen.color(), alpha);
180 }
181 return;
182 }
183
184 MythPainter::DrawRect(area, fillBrush, linePen, alpha);
185}
186
188{
189 if (m_ImageBitmapMap.contains(im))
190 {
191 QMutexLocker locker(&m_bitmapDeleteLock);
193 m_ImageBitmapMap.remove(im);
194 m_ImageExpireList.remove(im);
195 }
196}
197
199{
200 if (m_ImageBitmapMap.contains(im))
201 {
202 if (!im->IsChanged())
203 {
204 m_ImageExpireList.remove(im);
205 m_ImageExpireList.push_back(im);
206 return m_ImageBitmapMap[im];
207 }
208 else
209 {
211 }
212 }
213
214 im->SetChanged(false);
215 D3D9Image *newimage = nullptr;
216 if (m_render)
217 newimage = new D3D9Image(m_render,im->size());
218
219 if (newimage && newimage->IsValid())
220 {
222 m_hardwareCacheSize += newimage->GetDataSize();
223 newimage->UpdateImage(im);
224 m_ImageBitmapMap[im] = newimage;
225 m_ImageExpireList.push_back(im);
226
228 {
229 MythImage *expiredIm = m_ImageExpireList.front();
230 m_ImageExpireList.pop_front();
231 DeleteFormatImagePriv(expiredIm);
233 }
234 }
235 else
236 {
237 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create D3D9 UI bitmap.");
238 delete newimage;
239 newimage = nullptr;
240 }
241
242 return newimage;
243}
bool UpdateImage(IDirect3DSurface9 *surface)
bool UpdateVertices(const QRect &dvr, const QRect &vr, int alpha=255, bool video=false)
int GetDataSize(void) const
bool SetAsRenderTarget(void)
bool IsValid(void) const
bool Draw(void)
void DrawRect(QRect area, const QBrush &fillBrush, const QPen &linePen, int alpha) override
std::list< MythImage * > m_ImageExpireList
bool InitD3D9(QPaintDevice *parent)
void FreeResources(void) override
void DeleteBitmaps(void)
void End() override
void Teardown(void) override
D3D9Image * m_target
std::list< D3D9Image * > m_bitmapDeleteList
MythD3D9Painter(MythRenderD3D9 *render=nullptr)
MythRenderD3D9 * m_render
void DeleteFormatImagePriv(MythImage *im) override
void DrawImage(QRect dest, MythImage *im, QRect src, int alpha) override
QMap< MythImage *, D3D9Image * > m_ImageBitmapMap
D3D9Image * GetImageFromCache(MythImage *im)
void Begin(QPaintDevice *parent) override
bool IsChanged() const
Definition: mythimage.h:51
virtual void SetChanged(bool change=true)
Definition: mythimage.h:50
virtual void DrawRect(QRect area, const QBrush &fillBrush, const QPen &linePen, int alpha)
int m_hardwareCacheSize
Definition: mythpainter.h:136
void CheckFormatImage(MythImage *im)
virtual void Begin(QPaintDevice *)
Definition: mythpainter.h:54
virtual void End()
Definition: mythpainter.h:55
int m_maxHardwareCacheSize
Definition: mythpainter.h:137
virtual void Teardown(void)
Definition: mythpainter.cpp:27
void DrawRect(const QRect &rect, const QColor &color, int alpha)
bool SetRenderTarget(IDirect3DTexture9 *texture)
bool ClearBuffer(void)
bool Test(bool &reset)
bool Create(QSize size, HWND window)
bool Present(HWND win)
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
virtual int IncrRef(void)
Increments reference count.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
#define LOC