vdr-plugin-drmdevice 2.0.0-46418f1
softosd.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-or-later
2
17#include "device.h"
18#include "logger.h"
19#include "softosd.h"
20
30 : cOsd(left, top, level),
31 m_pDevice(device),
32 m_osdLevel(level)
33{
34 LOGDEBUG2(L_OSD, "osd: %s: %dx%d%+d%+d, %d", __FUNCTION__, OsdWidth(), OsdHeight(), left, top, level);
35}
36
41{
42 LOGDEBUG2(L_OSD, "osd: %s: level %d", __FUNCTION__, m_osdLevel);
43
44 SetActive(false); // done by SetActive(): OsdClose();
45}
46
55{
56 LOGDEBUG2(L_OSD, "osd: %s: %d level %d", __FUNCTION__, on, m_osdLevel);
57
58 if (Active() == on)
59 return; // already active, no action
60
61 cOsd::SetActive(on);
62
63 if (on) {
64 m_dirty = true;
65 // only flush here if there are already bitmaps
66 if (GetBitmap(0)) {
67 Flush();
68 }
69 } else
71}
72
77{
78 LOGDEBUG2(L_OSD, "osd: %s: %d areas", __FUNCTION__, n);
79
80 // clear old OSD, when new areas are set
81 if (!IsTrueColor()) {
83 int i;
84
85 for (i = 0; (bitmap = GetBitmap(i)); i++)
86 bitmap->Clean();
87 }
88
89 if (Active()) {
91 m_dirty = true;
92 }
93
94 return cOsd::SetAreas(areas, n);
95}
96
101{
103
104 LOGDEBUG2(L_OSD, "osd: %s: level %d active %d", __FUNCTION__, m_osdLevel,
105 Active());
106
107 if (!Active()) // this osd is not active
108 return;
109
110 if (!IsTrueColor()) {
112 int i;
113
114 static char warned;
115
116 if (!warned) {
117 LOGDEBUG2(L_OSD, "osd: %s: FIXME: should be truecolor", __FUNCTION__);
118 warned = 1;
119 }
120
121 // draw all bitmaps
122 for (i = 0; (bitmap = GetBitmap(i)); ++i) {
123 uint8_t *argb;
124 int xs;
125 int ys;
126 int x;
127 int y;
128 int w;
129 int h;
130 int x1;
131 int y1;
132 int x2;
133 int y2;
134
135 // get dirty bounding box
136 if (m_dirty) { // forced complete update
137 x1 = 0;
138 y1 = 0;
139 x2 = bitmap->Width() - 1;
140 y2 = bitmap->Height() - 1;
141 } else if (!bitmap->Dirty(x1, y1, x2, y2)) {
142 continue; // nothing dirty continue
143 }
144
145 // convert and upload only visible dirty areas
146 xs = bitmap->X0() + Left();
147 ys = bitmap->Y0() + Top();
148
149 // FIXME: negtative position bitmaps
150 w = x2 - x1 + 1;
151 h = y2 - y1 + 1;
152
153 // clip to screen
154 int width;
155 int height;
156 double videoAspect;
157
158 if (xs < 0) {
159 if (xs + x1 < 0) {
160 x1 -= xs + x1;
161 w += xs + x1;
162 if (w <= 0)
163 continue;
164 }
165 xs = 0;
166 }
167
168 if (ys < 0) {
169 if (ys + y1 < 0) {
170 y1 -= ys + y1;
171 h += ys + y1;
172 if (h <= 0)
173 continue;
174 }
175 ys = 0;
176 }
177
178 m_pDevice->GetOsdSize(width, height, videoAspect);
179 if (w > width - xs - x1) {
180 w = width - xs - x1;
181 if (w <= 0)
182 continue;
183 x2 = x1 + w - 1;
184 }
185
186 if (h > height - ys - y1) {
187 h = height - ys - y1;
188 if (h <= 0)
189 continue;
190 y2 = y1 + h - 1;
191 }
192
193 if (w > bitmap->Width() || h > bitmap->Height())
194 LOGDEBUG2(L_OSD, "osd: %s: dirty area too big", __FUNCTION__);
195
196 argb = (uint8_t *) malloc(w * h * sizeof(uint32_t));
197 for (y = y1; y <= y2; ++y) {
198 for (x = x1; x <= x2; ++x) {
199 ((uint32_t *) argb)[x - x1 + (y - y1) * w] =
200 bitmap->GetColor(x, y);
201 }
202 }
203 LOGDEBUG2(L_OSD, "osd: %s: draw %dx%d%+d%+d bm", __FUNCTION__, w, h, xs + x1, ys + y1);
204 m_pDevice->OsdDraw(0, 0, w, h, w * sizeof(uint32_t), argb, xs + x1, ys + y1);
205
206 bitmap->Clean();
207
208 // FIXME: reuse argb
209 free(argb);
210 }
211 m_dirty = false;
212 return;
213 }
214
216 while ((pm = (dynamic_cast < cPixmapMemory * >(RenderPixmaps())))) {
217 int xp;
218 int yp;
219 int stride;
220 int x;
221 int y;
222 int w;
223 int h;
224
225 x = pm->ViewPort().X();
226 y = pm->ViewPort().Y();
227 w = pm->ViewPort().Width();
228 h = pm->ViewPort().Height();
229 stride = w * sizeof(tColor);
230
231 // clip to osd
232 xp = 0;
233 if (x < 0) {
234 xp = -x;
235 w -= xp;
236 x = 0;
237 }
238
239 yp = 0;
240 if (y < 0) {
241 yp = -y;
242 h -= yp;
243 y = 0;
244 }
245
246 if (w > Width() - x)
247 w = Width() - x;
248 if (h > Height() - y)
249 h = Height() - y;
250
251 x += Left();
252 y += Top();
253
254 // clip to screen
255 int width;
256 int height;
257 double videoAspect;
258
259 if (x < 0) {
260 w += x;
261 xp += -x;
262 x = 0;
263 }
264 if (y < 0) {
265 h += y;
266 yp += -y;
267 y = 0;
268 }
269
270 m_pDevice->GetOsdSize(width, height, videoAspect);
271 if (w > width - x)
272 w = width - x;
273 if (h > height - y)
274 h = height - y;
275
276 LOGDEBUG2(L_OSD, "osd: %s: draw %dx%d%+d%+d*%d -> %+d%+d %p", __FUNCTION__, w, h, xp, yp, stride, x, y, pm->Data());
277 m_pDevice->OsdDraw(xp, yp, w, h, stride, pm->Data(), x, y);
278
279 DestroyPixmap(pm);
280 }
281 m_dirty = false;
282}
Output Device Implementation.
Definition device.h:72
void OsdDraw(int, int, int, int, int, const uint8_t *, int, int)
Draw an OSD pixmap.
Definition device.cpp:1185
void OsdClose(void)
Close the OSD.
Definition device.cpp:1165
virtual void GetOsdSize(int &, int &, double &)
Returns the width, height and aspect ratio the OSD should have.
Definition device.cpp:278
virtual void Flush(void)
Actually commit all data to the OSD hardware.
Definition softosd.cpp:100
cSoftOsd(int, int, uint, cOutputDevice *)
Initializes a software based OSD with the given coordinates.
Definition softosd.cpp:29
int m_osdLevel
current osd level
Definition softosd.h:43
virtual ~cSoftOsd(void)
Shut down the OSD.
Definition softosd.cpp:40
virtual eOsdError SetAreas(const tArea *, int)
Set the sub-areas to the given areas.
Definition softosd.cpp:76
cOutputDevice * m_pDevice
pointer to the cOutputDevice object
Definition softosd.h:41
virtual void SetActive(bool)
Sets this OSD to be the active one.
Definition softosd.cpp:54
bool m_dirty
flag to force redrawing everything
Definition softosd.h:42
Output Device Header File.
#define LOGDEBUG2
log to LOG_DEBUG and add a prefix
Definition logger.h:48
@ L_OSD
osd logs
Definition logger.h:63
Logger Header File.
Software OSD Header File.