vdr-plugin-softhddevice-drm-gles 1.5.9-20e15de
softhdosd.cpp
Go to the documentation of this file.
1
26#include "dummyosd.h"
27#include "logger.h"
28#ifdef USE_GLES
29#include "openglosd.h"
30#endif
31#include "softhddevice.h"
32#include "softhdosd.h"
33
34/*****************************************************************************
35 * OSD (software)
36 ****************************************************************************/
37
48cSoftOsd::cSoftOsd(int left, int top, uint level, cSoftHdDevice *device)
49 : cOsd(left, top, level),
50 m_pDevice(device),
51 m_osdLevel(level)
52{
53 LOGDEBUG2(L_OSD, "osd: %s: %dx%d%+d%+d, %d", __FUNCTION__, OsdWidth(), OsdHeight(), left, top, level);
54}
55
62{
63 LOGDEBUG2(L_OSD, "osd: %s: level %d", __FUNCTION__, m_osdLevel);
64
65 SetActive(false); // done by SetActive(): OsdClose();
66}
67
77{
78 LOGDEBUG2(L_OSD, "osd: %s: %d level %d", __FUNCTION__, on, m_osdLevel);
79
80 if (Active() == on)
81 return; // already active, no action
82
83 cOsd::SetActive(on);
84
85 if (on) {
86 m_dirty = true;
87 // only flush here if there are already bitmaps
88 if (GetBitmap(0)) {
89 Flush();
90 }
91 } else
93}
94
98eOsdError cSoftOsd::SetAreas(const tArea * areas, int n)
99{
100 LOGDEBUG2(L_OSD, "osd: %s: %d areas", __FUNCTION__, n);
101
102 // clear old OSD, when new areas are set
103 if (!IsTrueColor()) {
104 cBitmap *bitmap;
105 int i;
106
107 for (i = 0; (bitmap = GetBitmap(i)); i++)
108 bitmap->Clean();
109 }
110
111 if (Active()) {
113 m_dirty = true;
114 }
115
116 return cOsd::SetAreas(areas, n);
117}
118
123{
124 cPixmapMemory *pm;
125
126 LOGDEBUG2(L_OSD, "osd: %s: level %d active %d", __FUNCTION__, m_osdLevel,
127 Active());
128
129 if (!Active()) // this osd is not active
130 return;
131
132 if (!IsTrueColor()) {
133 cBitmap *bitmap;
134 int i;
135
136 static char warned;
137
138 if (!warned) {
139 LOGDEBUG2(L_OSD, "osd: %s: FIXME: should be truecolor", __FUNCTION__);
140 warned = 1;
141 }
142
143 // draw all bitmaps
144 for (i = 0; (bitmap = GetBitmap(i)); ++i) {
145 uint8_t *argb;
146 int xs;
147 int ys;
148 int x;
149 int y;
150 int w;
151 int h;
152 int x1;
153 int y1;
154 int x2;
155 int y2;
156
157 // get dirty bounding box
158 if (m_dirty) { // forced complete update
159 x1 = 0;
160 y1 = 0;
161 x2 = bitmap->Width() - 1;
162 y2 = bitmap->Height() - 1;
163 } else if (!bitmap->Dirty(x1, y1, x2, y2)) {
164 continue; // nothing dirty continue
165 }
166
167 // convert and upload only visible dirty areas
168 xs = bitmap->X0() + Left();
169 ys = bitmap->Y0() + Top();
170
171 // FIXME: negtative position bitmaps
172 w = x2 - x1 + 1;
173 h = y2 - y1 + 1;
174
175 // clip to screen
176 int width;
177 int height;
178 double videoAspect;
179
180 if (xs < 0) {
181 if (xs + x1 < 0) {
182 x1 -= xs + x1;
183 w += xs + x1;
184 if (w <= 0)
185 continue;
186 }
187 xs = 0;
188 }
189
190 if (ys < 0) {
191 if (ys + y1 < 0) {
192 y1 -= ys + y1;
193 h += ys + y1;
194 if (h <= 0)
195 continue;
196 }
197 ys = 0;
198 }
199
200 m_pDevice->GetOsdSize(width, height, videoAspect);
201 if (w > width - xs - x1) {
202 w = width - xs - x1;
203 if (w <= 0)
204 continue;
205 x2 = x1 + w - 1;
206 }
207
208 if (h > height - ys - y1) {
209 h = height - ys - y1;
210 if (h <= 0)
211 continue;
212 y2 = y1 + h - 1;
213 }
214
215 if (w > bitmap->Width() || h > bitmap->Height())
216 LOGDEBUG2(L_OSD, "osd: %s: dirty area too big", __FUNCTION__);
217
218 argb = (uint8_t *) malloc(w * h * sizeof(uint32_t));
219 for (y = y1; y <= y2; ++y) {
220 for (x = x1; x <= x2; ++x) {
221 ((uint32_t *) argb)[x - x1 + (y - y1) * w] =
222 bitmap->GetColor(x, y);
223 }
224 }
225 LOGDEBUG2(L_OSD, "osd: %s: draw %dx%d%+d%+d bm", __FUNCTION__, w, h, xs + x1, ys + y1);
226 m_pDevice->OsdDrawARGB(0, 0, w, h, w * sizeof(uint32_t), argb, xs + x1, ys + y1);
227
228 bitmap->Clean();
229
230 // FIXME: reuse argb
231 free(argb);
232 }
233 m_dirty = false;
234 return;
235 }
236
237 LOCK_PIXMAPS;
238 while ((pm = (dynamic_cast < cPixmapMemory * >(RenderPixmaps())))) {
239 int xp;
240 int yp;
241 int stride;
242 int x;
243 int y;
244 int w;
245 int h;
246
247 x = pm->ViewPort().X();
248 y = pm->ViewPort().Y();
249 w = pm->ViewPort().Width();
250 h = pm->ViewPort().Height();
251 stride = w * sizeof(tColor);
252
253 // clip to osd
254 xp = 0;
255 if (x < 0) {
256 xp = -x;
257 w -= xp;
258 x = 0;
259 }
260
261 yp = 0;
262 if (y < 0) {
263 yp = -y;
264 h -= yp;
265 y = 0;
266 }
267
268 if (w > Width() - x)
269 w = Width() - x;
270 if (h > Height() - y)
271 h = Height() - y;
272
273 x += Left();
274 y += Top();
275
276 // clip to screen
277 int width;
278 int height;
279 double videoAspect;
280
281 if (x < 0) {
282 w += x;
283 xp += -x;
284 x = 0;
285 }
286 if (y < 0) {
287 h += y;
288 yp += -y;
289 y = 0;
290 }
291
292 m_pDevice->GetOsdSize(width, height, videoAspect);
293 if (w > width - x)
294 w = width - x;
295 if (h > height - y)
296 h = height - y;
297
298 LOGDEBUG2(L_OSD, "osd: %s: draw %dx%d%+d%+d*%d -> %+d%+d %p", __FUNCTION__, w, h, xp, yp, stride, x, y, pm->Data());
299 m_pDevice->OsdDrawARGB(xp, yp, w, h, stride, pm->Data(), x, y);
300
301 DestroyPixmap(pm);
302 }
303 m_dirty = false;
304}
305
306/*****************************************************************************
307 * OSD provider
308 ****************************************************************************/
309
314 : cOsdProvider(),
315 m_pDevice(device)
316{
317 LOGDEBUG2(L_OSD, "osdprovider: %s:", __FUNCTION__);
318}
319
324{
325 LOGDEBUG2(L_OSD, "osdprovider %s:", __FUNCTION__);
326
329#ifdef USE_GLES
330 if (!m_pDevice->OglOsdIsDisabled())
331 StopOpenGlThread();
332#endif
333 }
334}
335
345cOsd *cSoftOsdProvider::CreateOsd(int left, int top, uint level)
346{
347#ifdef USE_GLES
348 if (m_pDevice->IsDetached()) {
349 LOGDEBUG("osdprovider: %s: %d, %d, %d, device detached, using dummy osd", __FUNCTION__, left, top, level);
350 return m_pOsd = new cDummyOsd(left, top, level);
351 }
352
353 if (m_pDevice->OglOsdIsDisabled()) {
354 LOGDEBUG("osdprovider: %s: %d, %d, %d, OpenGL disabled, using software rendering", __FUNCTION__, left, top, level);
355 return m_pOsd = new cSoftOsd(left, top, level, m_pDevice);
356 }
357
358 if (StartOpenGlThread()) {
359 LOGDEBUG2(L_OSD, "osdprovider: %s: %d, %d, %d, using OpenGL OSD support", __FUNCTION__, left, top, level);
360 return m_pOsd = new cOglOsd(left, top, level, m_pOglThread, m_pDevice);
361 }
362
363 LOGDEBUG("osdprovider: %s: %d, %d, %d, OpenGL failed, using software rendering", __FUNCTION__, left, top, 999);
364 m_pDevice->SetDisableOglOsd();
365 return m_pOsd = new cSoftOsd(left, top, 999, m_pDevice);
366#else
367 if (m_pDevice->IsDetached()) {
368 LOGDEBUG("osdprovider: %s: %d, %d, %d, device detached, using dummy osd", __FUNCTION__, left, top, level);
369 return m_pOsd = new cDummyOsd(left, top, level);
370 }
371
372 LOGDEBUG2(L_OSD, "osdprovider: %s: %d, %d, %d", __FUNCTION__, left, top, level);
373 return m_pOsd = new cSoftOsd(left, top, level, m_pDevice);
374#endif
375}
376
383{
384 return true;
385}
386
387#ifdef USE_GLES
391void cSoftOsdProvider::OsdSizeChanged(void) {
392 // cleanup OpenGL context
393 if (!m_pDevice->OglOsdIsDisabled())
394 cSoftOsdProvider::StopOpenGlThread();
395 cSoftOsdProvider::UpdateOsdSize();
396}
397
401bool cSoftOsdProvider::StartOpenGlThread(void) {
402 if (m_pDevice->OglOsdIsDisabled()) {
403 LOGDEBUG2(L_OPENGL, "osdprovider: %s: OpenGL OSD disabled, OpenGL worker thread NOT started", __FUNCTION__);
404 return false;
405 }
406
407 if (m_pOglThread.get()) {
408 if (m_pOglThread->Active()) {
409 return true;
410 }
411 m_pOglThread.reset();
412 }
413 cCondWait wait;
414 LOGDEBUG2(L_OPENGL, "osdprovider: %s: Trying to start OpenGL worker thread", __FUNCTION__);
415 m_pOglThread.reset(new cOglThread(&wait, m_pDevice->MaxSizeGPUImageCache(), m_pDevice));
416 wait.Wait();
417
418 if (m_pOglThread->Active()) {
419 LOGINFO("OpenGL worker thread started");
420 return true;
421 }
422
423 LOGDEBUG2(L_OPENGL, "osdprovider: %s: OpenGL worker thread NOT started", __FUNCTION__);
424 return false;
425}
426
430void cSoftOsdProvider::StopOpenGlThread(void) {
431 if (m_pOglThread) {
432 LOGDEBUG2(L_OPENGL, "osdprovider: %s: stopping OpenGL worker thread", __FUNCTION__);
433 m_pOglThread->Stop();
434 LOGINFO("OpenGL worker thread stopped");
435 }
436 m_pOglThread.reset();
437}
438
442int cSoftOsdProvider::StoreImageData(const cImage &Image)
443{
444 if (StartOpenGlThread()) {
445 int imgHandle = m_pOglThread->StoreImage(Image);
446 return imgHandle;
447 }
448 return 0;
449}
450
454const cImage *cSoftOsdProvider::GetImageData(int ImageHandle) {
455 return cOsdProvider::GetImageData(ImageHandle);
456}
457
461void cSoftOsdProvider::DropImageData(int imgHandle)
462{
463 if (StartOpenGlThread())
464 m_pOglThread->DropImageData(imgHandle);
465}
466#endif
cDummyOsd - dummy osd class
Definition dummyosd.h:65
void OsdDrawARGB(int, int, int, int, int, const uint8_t *, int, int)
Draw an OSD pixmap.
bool IsOsdProviderSet(void) const
virtual void GetOsdSize(int &, int &, double &)
Returns the width, height and aspect ratio the OSD.
void ResetOsdProvider(void)
bool IsDetached(void) const
Returns true, if the device is detached.
void OsdClose(void)
Close the OSD.
virtual cOsd * CreateOsd(int, int, uint)
Create a new OSD.
virtual ~cSoftOsdProvider()
cOsdProvider destructor
cOsd * m_pOsd
pointer to single OSD (currently not really used in cSoftOsdProvider?)
Definition softhdosd.h:81
virtual bool ProvidesTrueColor(void)
Check if this OSD provider is able to handle a true color OSD.
cSoftOsdProvider(cSoftHdDevice *)
cOsdProvider constructor
cSoftHdDevice * m_pDevice
pointer to the cSoftHdDevice object
Definition softhdosd.h:82
cSoftOsd - SoftHdDevice plugin software OSD class
Definition softhdosd.h:44
virtual void Flush(void)
Actually commit all data to the OSD hardware.
int m_osdLevel
current osd level
Definition softhdosd.h:56
virtual ~cSoftOsd(void)
cSoftOsd destructor
Definition softhdosd.cpp:61
virtual eOsdError SetAreas(const tArea *, int)
Set the sub-areas to the given areas.
Definition softhdosd.cpp:98
cSoftHdDevice * m_pDevice
pointer to the cSoftHdDevice object
Definition softhdosd.h:54
virtual void SetActive(bool)
Sets this OSD to be the active one.
Definition softhdosd.cpp:76
bool m_dirty
flag to force redrawing everything
Definition softhdosd.h:55
cSoftOsd(int, int, uint, cSoftHdDevice *)
cSoftOsd constructor
Definition softhdosd.cpp:48
Dummy osd class.
Logger class header file.
#define LOGDEBUG2
Definition logger.h:45
#define LOGDEBUG
Definition logger.h:44
#define L_OPENGL
Definition logger.h:62
#define LOGINFO
Definition logger.h:43
#define L_OSD
Definition logger.h:56
Osd class - hardware accelerated (OpenGL/ES) - header file.
Device class header file.
Softhddevice osd header file.