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