cOsd::RenderPixmaps() now returns a pointer to cPixmap instead of cPixmapMemory; a cPixmap with a negative layer no longer marks any portion of the OSD's view port as "dirty"; Added a missing initialization of "panning" to the constructor of cPixmapMemory

This commit is contained in:
Klaus Schmidinger 2015-02-11 09:48:02 +01:00
parent 89f5244007
commit 22106f6dd3
5 changed files with 81 additions and 31 deletions

View File

@ -3308,6 +3308,8 @@ Thomas Reufer <thomas@reufer.ch>
for adding cOsdProvider::OsdSizeChanged() for adding cOsdProvider::OsdSizeChanged()
for suggesting to change the German translations if the texts related to "binary for suggesting to change the German translations if the texts related to "binary
skipping" skipping"
for suggesting to change the return value of cOsd::RenderPixmaps() from cPixmapMemory
to cPixmap
Eike Sauer <EikeSauer@t-online.de> Eike Sauer <EikeSauer@t-online.de>
for reporting a problem with channels that need more than 5 TS packets for detecting for reporting a problem with channels that need more than 5 TS packets for detecting

16
HISTORY
View File

@ -8523,7 +8523,7 @@ Video Disk Recorder Revision History
copy process has been successful (problem reported by Christoph Haubrich). copy process has been successful (problem reported by Christoph Haubrich).
- Added the UPDATE-2.2.0 file. - Added the UPDATE-2.2.0 file.
2015-02-10: Version 2.1.10 2015-02-11: Version 2.1.10
- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg). - Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
- Updated the Macedonian OSD texts (thanks to Dimitar Petrovski). - Updated the Macedonian OSD texts (thanks to Dimitar Petrovski).
@ -8551,3 +8551,17 @@ Video Disk Recorder Revision History
of using the environment variable VDR_CHARSET_OVERRIDE still works, but is now of using the environment variable VDR_CHARSET_OVERRIDE still works, but is now
deprecated and may be removed in a future version. The value given in the --chartab deprecated and may be removed in a future version. The value given in the --chartab
option takes precedence over that in VDR_CHARSET_OVERRIDE. option takes precedence over that in VDR_CHARSET_OVERRIDE.
- cOsd::RenderPixmaps() now returns a pointer to cPixmap instead of cPixmapMemory
(suggested by Thomas Reufer). This is necessary to allow plugins with derived
cPixmap implementations to use this function. Plugins that use this function
with cPixmapMemory now need to add a dynamic cast to the call, as in
cPixmapMemory *pm = dynamic_cast<cPixmapMemory *>(RenderPixmaps()));
They also need to call DestroyPixmap(pm) instead of "delete pm" to properly release
the resulting pixmap after use.
The dvbhddevice plugin has been modified accordingly.
- A cPixmap with a negative layer no longer marks any portion of the OSD's view port
as "dirty" when drawing on it. This may improve performance when drawing on a
hidden pixmap, because it avoids unnecessary refreshes of the OSD.
- Added a missing initialization of "panning" to the constructor of cPixmapMemory.

View File

@ -127,6 +127,15 @@ Plugins:
- Added cOsdProvider::OsdSizeChanged(), which plugins that implement an output device - Added cOsdProvider::OsdSizeChanged(), which plugins that implement an output device
can call to signal a change in the OSD that requires a redraw of the currently can call to signal a change in the OSD that requires a redraw of the currently
displayed object. displayed object.
- cOsd::RenderPixmaps() now returns a pointer to cPixmap instead of cPixmapMemory
This is necessary to allow plugins with derived cPixmap implementations to use this
function. Plugins that use this function with cPixmapMemory now need to add
a dynamic cast to the call, as in
cPixmapMemory *pm = dynamic_cast<cPixmapMemory *>(RenderPixmaps()));
They also need to call DestroyPixmap(pm) instead of "delete pm" to properly release
the resulting pixmap after use.
Skins: Skins:
@ -220,6 +229,15 @@ OSD:
is unexpected at this point. You can still navigate to is unexpected at this point. You can still navigate to
the last replayed recording (if any) by pressing Ok repeatedly in the Recordings the last replayed recording (if any) by pressing Ok repeatedly in the Recordings
menu. menu.
- cOsd::RenderPixmaps() now returns a pointer to cPixmap instead of cPixmapMemory
This is necessary to allow plugins with derived cPixmap implementations to use this
function. Plugins that use this function with cPixmapMemory now need to add
a dynamic cast to the call, as in
cPixmapMemory *pm = dynamic_cast<cPixmapMemory *>(RenderPixmaps()));
They also need to call DestroyPixmap(pm) instead of "delete pm" to properly release
the resulting pixmap after use.
Channels: Channels:

62
osd.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: osd.c 3.4 2015/01/15 11:20:56 kls Exp $ * $Id: osd.c 3.5 2015/02/11 09:48:02 kls Exp $
*/ */
#include "osd.h" #include "osd.h"
@ -984,12 +984,13 @@ cPixmap::cPixmap(int Layer, const cRect &ViewPort, const cRect &DrawPort)
void cPixmap::MarkViewPortDirty(const cRect &Rect) void cPixmap::MarkViewPortDirty(const cRect &Rect)
{ {
dirtyViewPort.Combine(Rect.Intersected(viewPort)); if (layer >= 0)
dirtyViewPort.Combine(Rect.Intersected(viewPort));
} }
void cPixmap::MarkViewPortDirty(const cPoint &Point) void cPixmap::MarkViewPortDirty(const cPoint &Point)
{ {
if (viewPort.Contains(Point)) if (layer >= 0 && viewPort.Contains(Point))
dirtyViewPort.Combine(Point); dirtyViewPort.Combine(Point);
} }
@ -1025,11 +1026,18 @@ void cPixmap::SetLayer(int Layer)
esyslog("ERROR: pixmap layer %d limited to %d", Layer, MAXPIXMAPLAYERS - 1); esyslog("ERROR: pixmap layer %d limited to %d", Layer, MAXPIXMAPLAYERS - 1);
Layer = MAXPIXMAPLAYERS - 1; Layer = MAXPIXMAPLAYERS - 1;
} }
if (Layer != layer) { // The sequence here is important, because the view port is only marked as dirty
if (Layer > 0 || layer > 0) // if the layer is >= 0:
MarkViewPortDirty(viewPort); if (layer >= 0) {
MarkViewPortDirty(viewPort); // the pixmap is visible and may or may not become invisible
layer = Layer; layer = Layer;
} }
else if (Layer >= 0) {
layer = Layer;
MarkViewPortDirty(viewPort); // the pixmap was invisible and has become visible
}
else
layer = Layer; // the pixmap was invisible and remains so
Unlock(); Unlock();
} }
@ -1141,6 +1149,7 @@ cPixmapMemory::cPixmapMemory(int Layer, const cRect &ViewPort, const cRect &Draw
:cPixmap(Layer, ViewPort, DrawPort) :cPixmap(Layer, ViewPort, DrawPort)
{ {
data = MALLOC(tColor, this->DrawPort().Width() * this->DrawPort().Height()); data = MALLOC(tColor, this->DrawPort().Width() * this->DrawPort().Height());
panning = false;
} }
cPixmapMemory::~cPixmapMemory() cPixmapMemory::~cPixmapMemory()
@ -1714,7 +1723,8 @@ void cOsd::DestroyPixmap(cPixmap *Pixmap)
LOCK_PIXMAPS; LOCK_PIXMAPS;
for (int i = 1; i < pixmaps.Size(); i++) { // begin at 1 - don't let the background pixmap be destroyed! for (int i = 1; i < pixmaps.Size(); i++) { // begin at 1 - don't let the background pixmap be destroyed!
if (pixmaps[i] == Pixmap) { if (pixmaps[i] == Pixmap) {
pixmaps[0]->MarkViewPortDirty(Pixmap->ViewPort()); if (Pixmap->Layer() >= 0)
pixmaps[0]->MarkViewPortDirty(Pixmap->ViewPort());
delete Pixmap; delete Pixmap;
pixmaps[i] = NULL; pixmaps[i] = NULL;
return; return;
@ -1737,9 +1747,9 @@ cPixmap *cOsd::AddPixmap(cPixmap *Pixmap)
return Pixmap; return Pixmap;
} }
cPixmapMemory *cOsd::RenderPixmaps(void) cPixmap *cOsd::RenderPixmaps(void)
{ {
cPixmapMemory *Pixmap = NULL; cPixmap *Pixmap = NULL;
if (isTrueColor) { if (isTrueColor) {
LOCK_PIXMAPS; LOCK_PIXMAPS;
// Collect overlapping dirty rectangles: // Collect overlapping dirty rectangles:
@ -1762,25 +1772,27 @@ cPixmapMemory *cOsd::RenderPixmaps(void)
d.Combine(OldDirty); d.Combine(OldDirty);
OldDirty = NewDirty; OldDirty = NewDirty;
#endif #endif
Pixmap = new cPixmapMemory(0, d); Pixmap = CreatePixmap(-1, d);
Pixmap->Clear(); if (Pixmap) {
// Render the individual pixmaps into the resulting pixmap: Pixmap->Clear();
for (int Layer = 0; Layer < MAXPIXMAPLAYERS; Layer++) { // Render the individual pixmaps into the resulting pixmap:
for (int i = 0; i < pixmaps.Size(); i++) { for (int Layer = 0; Layer < MAXPIXMAPLAYERS; Layer++) {
if (cPixmap *pm = pixmaps[i]) { for (int i = 0; i < pixmaps.Size(); i++) {
if (pm->Layer() == Layer) if (cPixmap *pm = pixmaps[i]) {
Pixmap->DrawPixmap(pm, d); if (pm->Layer() == Layer)
Pixmap->DrawPixmap(pm, d);
}
} }
} }
}
#ifdef DebugDirty #ifdef DebugDirty
cPixmapMemory DirtyIndicator(7, NewDirty); cPixmapMemory DirtyIndicator(7, NewDirty);
static tColor DirtyIndicatorColors[] = { 0x7FFFFF00, 0x7F00FFFF }; static tColor DirtyIndicatorColors[] = { 0x7FFFFF00, 0x7F00FFFF };
static int DirtyIndicatorIndex = 0; static int DirtyIndicatorIndex = 0;
DirtyIndicator.Fill(DirtyIndicatorColors[DirtyIndicatorIndex]); DirtyIndicator.Fill(DirtyIndicatorColors[DirtyIndicatorIndex]);
DirtyIndicatorIndex = 1 - DirtyIndicatorIndex; DirtyIndicatorIndex = 1 - DirtyIndicatorIndex;
Pixmap->Render(&DirtyIndicator, DirtyIndicator.DrawPort(), DirtyIndicator.ViewPort().Point().Shifted(-Pixmap->ViewPort().Point())); Pixmap->Render(&DirtyIndicator, DirtyIndicator.DrawPort(), DirtyIndicator.ViewPort().Point().Shifted(-Pixmap->ViewPort().Point()));
#endif #endif
}
} }
} }
return Pixmap; return Pixmap;

14
osd.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: osd.h 3.5 2015/01/15 11:23:52 kls Exp $ * $Id: osd.h 3.6 2015/02/11 09:48:02 kls Exp $
*/ */
#ifndef __OSD_H #ifndef __OSD_H
@ -763,12 +763,13 @@ protected:
///< the pixmap could not be added to the list. ///< the pixmap could not be added to the list.
///< A derived class that implements its own cPixmap class must call AddPixmap() ///< A derived class that implements its own cPixmap class must call AddPixmap()
///< in order to add a newly created pixmap to the OSD's list of pixmaps. ///< in order to add a newly created pixmap to the OSD's list of pixmaps.
cPixmapMemory *RenderPixmaps(void); cPixmap *RenderPixmaps(void);
///< Renders the dirty part of all pixmaps into a resulting pixmap that ///< Renders the dirty part of all pixmaps into a resulting pixmap that
///< shall be displayed on the OSD. The returned pixmap's view port is ///< shall be displayed on the OSD. The returned pixmap's view port is
///< set to the location of the rectangle on the OSD that needs to be ///< set to the location of the rectangle on the OSD that needs to be
///< refreshed; its draw port's origin is at (0, 0), and it has the same ///< refreshed; its draw port's origin is at (0, 0), and it has the same
///< size as the view port. ///< size as the view port.
///< Only pixmaps with a non-negative layer value are rendered.
///< If there are several non-overlapping dirty rectangles from different pixmaps, ///< If there are several non-overlapping dirty rectangles from different pixmaps,
///< they are returned separately in order to avoid re-rendering large parts ///< they are returned separately in order to avoid re-rendering large parts
///< of the OSD that haven't changed at all. The caller must therefore call ///< of the OSD that haven't changed at all. The caller must therefore call
@ -778,7 +779,7 @@ protected:
///< by putting a LOCK_PIXMAPS into the scope of the operation). ///< by putting a LOCK_PIXMAPS into the scope of the operation).
///< If there are no dirty pixmaps, or if this is not a true color OSD, ///< If there are no dirty pixmaps, or if this is not a true color OSD,
///< this function returns NULL. ///< this function returns NULL.
///< The caller must delete the returned pixmap after use. ///< The caller must call DestroyPixmap() for the returned pixmap after use.
public: public:
virtual ~cOsd(); virtual ~cOsd();
///< Shuts down the OSD. ///< Shuts down the OSD.
@ -930,13 +931,16 @@ public:
///< pixmaps, the Flush() function should basically do something like this: ///< pixmaps, the Flush() function should basically do something like this:
///< ///<
///< LOCK_PIXMAPS; ///< LOCK_PIXMAPS;
///< while (cPixmapMemory *pm = RenderPixmaps()) { ///< while (cPixmapMemory *pm = dynamic_cast<cPixmapMemory *>(RenderPixmaps())) {
///< int w = pm->ViewPort().Width(); ///< int w = pm->ViewPort().Width();
///< int h = pm->ViewPort().Height(); ///< int h = pm->ViewPort().Height();
///< int d = w * sizeof(tColor); ///< int d = w * sizeof(tColor);
///< MyOsdDrawPixmap(Left() + pm->ViewPort().X(), Top() + pm->ViewPort().Y(), pm->Data(), w, h, h * d); ///< MyOsdDrawPixmap(Left() + pm->ViewPort().X(), Top() + pm->ViewPort().Y(), pm->Data(), w, h, h * d);
///< delete pm; ///< DestroyPixmap(pm);
///< } ///< }
///<
///< If a plugin uses a derived cPixmap implementation, it needs to use that
///< type instead of cPixmapMemory.
}; };
#define MAXOSDIMAGES 64 #define MAXOSDIMAGES 64